summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk6
-rw-r--r--api/current.xml2942
-rw-r--r--camera/libcameraservice/CameraService.cpp9
-rw-r--r--cmds/installd/commands.c99
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java2
-rw-r--r--common/java/com/android/common/Base64.java705
-rw-r--r--common/java/com/android/common/Patterns.java51
-rw-r--r--common/java/com/android/common/speech/Recognition.java36
-rw-r--r--common/java/com/android/common/ui/PointerLocationView.java337
-rw-r--r--common/tests/src/com/android/common/PatternsTest.java13
-rwxr-xr-xcommon/tools/make-iana-tld-pattern.py32
-rw-r--r--core/java/android/app/BackupAgent.java24
-rw-r--r--core/java/android/app/ContextImpl.java96
-rw-r--r--core/java/android/app/SearchDialog.java6
-rw-r--r--core/java/android/backup/AbsoluteFileBackupHelper.java12
-rw-r--r--core/java/android/backup/BackupDataInput.java46
-rw-r--r--core/java/android/backup/BackupDataInputStream.java6
-rw-r--r--core/java/android/backup/BackupDataOutput.java23
-rw-r--r--core/java/android/backup/BackupHelper.java14
-rw-r--r--core/java/android/backup/BackupHelperAgent.java28
-rw-r--r--core/java/android/backup/BackupHelperDispatcher.java2
-rw-r--r--core/java/android/backup/BackupManager.java15
-rw-r--r--core/java/android/backup/FileBackupHelper.java14
-rw-r--r--core/java/android/backup/FileBackupHelperBase.java11
-rw-r--r--core/java/android/backup/RestoreObserver.java1
-rw-r--r--core/java/android/backup/RestoreSession.java5
-rw-r--r--core/java/android/backup/SharedPreferencesBackupHelper.java18
-rw-r--r--core/java/android/content/Intent.java2
-rw-r--r--core/java/android/content/pm/PackageManager.java34
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java26
-rw-r--r--core/java/android/net/ConnectivityManager.java45
-rw-r--r--core/java/android/net/Downloads.java645
-rw-r--r--core/java/android/net/IConnectivityManager.aidl6
-rw-r--r--core/java/android/net/SSLCertificateSocketFactory.java57
-rw-r--r--core/java/android/net/WebAddress.java7
-rw-r--r--core/java/android/os/ICheckinService.aidl35
-rw-r--r--core/java/android/os/IParentalControlCallback.aidl27
-rw-r--r--core/java/android/os/storage/IMountService.aidl8
-rw-r--r--core/java/android/pim/vcard/VCardComposer.java60
-rw-r--r--core/java/android/pim/vcard/VCardEntry.java25
-rw-r--r--core/java/android/provider/Checkin.java269
-rw-r--r--core/java/android/provider/Settings.java77
-rw-r--r--core/java/android/speech/RecognizerIntent.java6
-rw-r--r--core/java/android/text/AndroidCharacter.java39
-rw-r--r--core/java/android/text/util/Rfc822Tokenizer.java4
-rw-r--r--core/java/android/util/base64/Base64.java741
-rw-r--r--core/java/android/util/base64/Base64InputStream.java (renamed from common/java/com/android/common/Base64InputStream.java)66
-rw-r--r--core/java/android/util/base64/Base64OutputStream.java (renamed from common/java/com/android/common/Base64OutputStream.java)66
-rw-r--r--core/java/android/view/GestureDetector.java8
-rw-r--r--core/java/android/view/HapticFeedbackConstants.java7
-rw-r--r--core/java/android/view/MotionEvent.java100
-rw-r--r--core/java/android/view/VelocityTracker.java59
-rw-r--r--core/java/android/view/ViewGroup.java2
-rw-r--r--core/java/android/view/WindowManagerPolicy.java5
-rw-r--r--core/java/android/webkit/WebTextView.java2
-rw-r--r--core/java/android/webkit/WebView.java4
-rw-r--r--core/java/android/widget/EditText.java8
-rw-r--r--core/java/android/widget/GridView.java14
-rw-r--r--core/java/android/widget/HorizontalScrollView.java9
-rw-r--r--core/java/android/widget/LinearLayout.java20
-rw-r--r--core/java/android/widget/ScrollView.java9
-rw-r--r--core/java/android/widget/TabHost.java6
-rw-r--r--core/java/android/widget/TableLayout.java10
-rw-r--r--core/java/android/widget/TableRow.java2
-rwxr-xr-xcore/java/com/android/internal/app/IMediaContainerService.aidl1
-rw-r--r--core/java/com/android/internal/app/TetherActivity.java62
-rw-r--r--core/java/com/android/internal/content/PackageHelper.java182
-rw-r--r--core/java/com/android/internal/os/RuntimeInit.java1
-rw-r--r--core/java/com/android/internal/util/HierarchicalStateMachine.java2
-rw-r--r--core/java/com/google/android/net/ParentalControl.java73
-rw-r--r--core/java/com/google/android/net/ParentalControlState.aidl18
-rw-r--r--core/java/com/google/android/net/ParentalControlState.java56
-rw-r--r--core/jni/android/graphics/YuvToJpegEncoder.cpp7
-rw-r--r--core/jni/android_text_AndroidCharacter.cpp103
-rw-r--r--core/jni/android_text_format_Time.cpp4
-rw-r--r--core/res/AndroidManifest.xml16
-rw-r--r--core/res/res/anim/cycle_interpolator.xml21
-rw-r--r--core/res/res/values/attrs.xml2
-rw-r--r--core/res/res/values/config.xml21
-rw-r--r--core/res/res/values/public.xml3
-rw-r--r--core/res/res/values/strings.xml5
-rw-r--r--core/res/res/values/styles.xml11
-rw-r--r--core/res/res/values/themes.xml1
-rw-r--r--core/tests/coretests/src/android/app/SearchManagerTest.java3
-rw-r--r--core/tests/coretests/src/android/os/MemoryFileTest.java35
-rw-r--r--core/tests/coretests/src/android/util/base64/Base64Test.java (renamed from common/tests/src/com/android/common/Base64Test.java)106
-rw-r--r--core/tests/coretests/src/com/google/android/net/ParentalControlTest.java57
-rw-r--r--data/sounds/AudioPackage2.mk5
-rw-r--r--data/sounds/AudioPackage3.mk6
-rw-r--r--data/sounds/AudioPackage4.mk5
-rw-r--r--data/sounds/effects/Dock.aifbin0 -> 44154 bytes
-rw-r--r--data/sounds/effects/Dock.oggbin0 -> 6019 bytes
-rw-r--r--data/sounds/effects/Lock.aiffbin0 -> 19002 bytes
-rw-r--r--data/sounds/effects/Lock.oggbin0 -> 5128 bytes
-rw-r--r--data/sounds/effects/LowBattery.aifbin0 -> 88902 bytes
-rw-r--r--data/sounds/effects/LowBattery.oggbin0 -> 6585 bytes
-rw-r--r--data/sounds/effects/Undock.aifbin0 -> 44154 bytes
-rw-r--r--data/sounds/effects/Undock.oggbin0 -> 6016 bytes
-rw-r--r--data/sounds/effects/Unlock.aiffbin0 -> 23570 bytes
-rw-r--r--data/sounds/effects/Unlock.oggbin0 -> 5866 bytes
-rw-r--r--docs/html/sitemap.txt128
-rw-r--r--include/media/IMediaPlayer.h2
-rw-r--r--include/media/MediaPlayerInterface.h3
-rw-r--r--include/media/mediaplayer.h2
-rw-r--r--include/ui/PixelFormat.h26
-rw-r--r--include/utils/AndroidUnicode.h255
-rw-r--r--libs/rs/java/ImageProcessing/res/raw/threshold.rs28
-rw-r--r--libs/rs/rs.spec2
-rw-r--r--libs/rs/rsContext.cpp8
-rw-r--r--libs/rs/rsContext.h7
-rw-r--r--libs/surfaceflinger/Layer.cpp18
-rw-r--r--libs/surfaceflinger/LayerBase.cpp37
-rw-r--r--libs/surfaceflinger/LayerBase.h1
-rw-r--r--libs/surfaceflinger/LayerBuffer.cpp27
-rw-r--r--libs/surfaceflinger/LayerBuffer.h1
-rw-r--r--libs/ui/PixelFormat.cpp42
-rw-r--r--libs/utils/Android.mk1
-rw-r--r--libs/utils/CharacterData.h730
-rw-r--r--libs/utils/Unicode.cpp193
-rw-r--r--media/java/android/media/AudioManager.java9
-rw-r--r--media/java/android/media/AudioService.java20
-rw-r--r--media/java/android/media/DecoderCapabilities.java84
-rw-r--r--media/java/android/media/MediaPlayer.java47
-rw-r--r--media/java/android/media/SoundPool.java22
-rw-r--r--media/jni/android_media_MediaPlayer.cpp14
-rw-r--r--media/jni/android_media_MediaProfiles.cpp71
-rw-r--r--media/jni/soundpool/SoundPool.cpp43
-rw-r--r--media/jni/soundpool/SoundPool.h8
-rw-r--r--media/jni/soundpool/android_media_SoundPool.cpp26
-rw-r--r--media/libmedia/IMediaPlayer.cpp32
-rw-r--r--media/libmedia/mediaplayer.cpp10
-rw-r--r--media/libmediaplayerservice/Android.mk9
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp14
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h2
-rw-r--r--media/libmediaplayerservice/StagefrightPlayer.cpp10
-rw-r--r--media/libmediaplayerservice/StagefrightPlayer.h2
-rw-r--r--media/libstagefright/AMRExtractor.cpp17
-rw-r--r--media/libstagefright/Android.mk9
-rw-r--r--media/libstagefright/AwesomePlayer.cpp246
-rw-r--r--media/libstagefright/HTTPDataSource.cpp15
-rw-r--r--media/libstagefright/HTTPStream.cpp4
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp14
-rw-r--r--media/libstagefright/Prefetcher.cpp100
-rw-r--r--media/libstagefright/include/AwesomePlayer.h41
-rw-r--r--media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java45
-rw-r--r--mms-common/java/com/android/mmscommon/mms/pdu/Base64.java167
-rw-r--r--mms-common/java/com/android/mmscommon/mms/pdu/PduParser.java5
-rw-r--r--opengl/libagl/copybit.cpp15
-rwxr-xr-xpackages/DefaultContainerService/AndroidManifest.xml1
-rw-r--r--packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java288
-rw-r--r--packages/SettingsProvider/AndroidManifest.xml2
-rw-r--r--packages/SettingsProvider/res/values/defaults.xml12
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java67
-rw-r--r--services/java/com/android/server/BackupManagerService.java27
-rw-r--r--services/java/com/android/server/ConnectivityService.java46
-rw-r--r--services/java/com/android/server/DockObserver.java52
-rw-r--r--services/java/com/android/server/FallbackCheckinService.java48
-rw-r--r--services/java/com/android/server/InputDevice.java4
-rw-r--r--services/java/com/android/server/MasterClearReceiver.java2
-rw-r--r--services/java/com/android/server/MountService.java26
-rw-r--r--services/java/com/android/server/PackageManagerService.java416
-rw-r--r--services/java/com/android/server/SystemServer.java22
-rw-r--r--services/java/com/android/server/WindowManagerService.java54
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java28
-rw-r--r--services/java/com/android/server/connectivity/Tethering.java1355
-rw-r--r--services/java/com/android/server/status/StatusBarPolicy.java22
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java29
-rw-r--r--test-runner/android/test/mock/MockPackageManager.java8
-rwxr-xr-xtests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java251
-rw-r--r--tests/backup/AndroidManifest.xml1
170 files changed, 7516 insertions, 5726 deletions
diff --git a/Android.mk b/Android.mk
index 4ecf5bd65197..a48ef45ac312 100644
--- a/Android.mk
+++ b/Android.mk
@@ -116,13 +116,11 @@ LOCAL_SRC_FILES += \
core/java/android/hardware/ISensorService.aidl \
core/java/android/net/IConnectivityManager.aidl \
core/java/android/net/INetworkManagementEventObserver.aidl \
- core/java/android/os/ICheckinService.aidl \
core/java/android/os/IMessenger.aidl \
core/java/android/os/storage/IMountService.aidl \
core/java/android/os/storage/IMountServiceListener.aidl \
core/java/android/os/INetworkManagementService.aidl \
core/java/android/os/INetStatService.aidl \
- core/java/android/os/IParentalControlCallback.aidl \
core/java/android/os/IPermissionController.aidl \
core/java/android/os/IPowerManager.aidl \
core/java/android/os/IRemoteCallback.aidl \
@@ -409,7 +407,9 @@ web_docs_sample_code_flags := \
-samplecode $(sample_dir)/Wiktionary \
resources/samples/Wiktionary "Wiktionary" \
-samplecode $(sample_dir)/WiktionarySimple \
- resources/samples/WiktionarySimple "Wiktionary (Simplified)"
+ resources/samples/WiktionarySimple "Wiktionary (Simplified)" \
+ -samplecode $(sample_dir)/VoiceRecognitionService \
+ resources/samples/VoiceRecognitionService "Voice Recognition Service"
## SDK version identifiers used in the published docs
# major[.minor] version for current SDK. (full releases only)
diff --git a/api/current.xml b/api/current.xml
index 08de47402c02..e5177efa650b 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -1537,6 +1537,17 @@
visibility="public"
>
</field>
+<field name="cycle_interpolator"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="17432588"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="decelerate_interpolator"
type="int"
transient="false"
@@ -9062,6 +9073,17 @@
visibility="public"
>
</field>
+<field name="webTextViewStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843450"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="webViewStyle"
type="int"
transient="false"
@@ -19839,6 +19861,83 @@
>
</method>
</class>
+<class name="BackupAgent"
+ extends="android.content.ContextWrapper"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="BackupAgent"
+ type="android.app.BackupAgent"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="onBackup"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="oldState" type="android.os.ParcelFileDescriptor">
+</parameter>
+<parameter name="data" type="android.backup.BackupDataOutput">
+</parameter>
+<parameter name="newState" type="android.os.ParcelFileDescriptor">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="onCreate"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="onDestroy"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="onRestore"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="android.backup.BackupDataInput">
+</parameter>
+<parameter name="appVersionCode" type="int">
+</parameter>
+<parameter name="newState" type="android.os.ParcelFileDescriptor">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+</class>
<class name="DatePickerDialog"
extends="android.app.AlertDialog"
abstract="false"
@@ -27388,6 +27487,615 @@
</field>
</class>
</package>
+<package name="android.backup"
+>
+<class name="AbsoluteFileBackupHelper"
+ extends="android.backup.FileBackupHelperBase"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.backup.BackupHelper">
+</implements>
+<constructor name="AbsoluteFileBackupHelper"
+ type="android.backup.AbsoluteFileBackupHelper"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="files" type="java.lang.String...">
+</parameter>
+</constructor>
+<method name="performBackup"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="oldState" type="android.os.ParcelFileDescriptor">
+</parameter>
+<parameter name="data" type="android.backup.BackupDataOutput">
+</parameter>
+<parameter name="newState" type="android.os.ParcelFileDescriptor">
+</parameter>
+</method>
+<method name="restoreEntity"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="android.backup.BackupDataInputStream">
+</parameter>
+</method>
+</class>
+<class name="BackupDataInput"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="getDataSize"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getKey"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="readEntityData"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<parameter name="offset" type="int">
+</parameter>
+<parameter name="size" type="int">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="readNextHeader"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="skipEntityData"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+</class>
+<class name="BackupDataInputStream"
+ extends="java.io.InputStream"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="getKey"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="read"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="size"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</class>
+<class name="BackupDataOutput"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="setKeyPrefix"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="keyPrefix" type="java.lang.String">
+</parameter>
+</method>
+<method name="writeEntityData"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<parameter name="size" type="int">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="writeEntityHeader"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="key" type="java.lang.String">
+</parameter>
+<parameter name="dataSize" type="int">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<field name="OP_DELETE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="OP_UPDATE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<interface name="BackupHelper"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="performBackup"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="oldState" type="android.os.ParcelFileDescriptor">
+</parameter>
+<parameter name="data" type="android.backup.BackupDataOutput">
+</parameter>
+<parameter name="newState" type="android.os.ParcelFileDescriptor">
+</parameter>
+</method>
+<method name="restoreEntity"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="android.backup.BackupDataInputStream">
+</parameter>
+</method>
+<method name="writeNewStateDescription"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fd" type="android.os.ParcelFileDescriptor">
+</parameter>
+</method>
+</interface>
+<class name="BackupHelperAgent"
+ extends="android.app.BackupAgent"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="BackupHelperAgent"
+ type="android.backup.BackupHelperAgent"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="addHelper"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="keyPrefix" type="java.lang.String">
+</parameter>
+<parameter name="helper" type="android.backup.BackupHelper">
+</parameter>
+</method>
+<method name="onBackup"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="oldState" type="android.os.ParcelFileDescriptor">
+</parameter>
+<parameter name="data" type="android.backup.BackupDataOutput">
+</parameter>
+<parameter name="newState" type="android.os.ParcelFileDescriptor">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="onRestore"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="android.backup.BackupDataInput">
+</parameter>
+<parameter name="appVersionCode" type="int">
+</parameter>
+<parameter name="newState" type="android.os.ParcelFileDescriptor">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+</class>
+<class name="BackupManager"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="BackupManager"
+ type="android.backup.BackupManager"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</constructor>
+<method name="beginRestoreSession"
+ return="android.backup.RestoreSession"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="dataChanged"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="dataChanged"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="packageName" type="java.lang.String">
+</parameter>
+</method>
+</class>
+<class name="FileBackupHelper"
+ extends="android.backup.FileBackupHelperBase"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.backup.BackupHelper">
+</implements>
+<constructor name="FileBackupHelper"
+ type="android.backup.FileBackupHelper"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="files" type="java.lang.String...">
+</parameter>
+</constructor>
+<method name="performBackup"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="oldState" type="android.os.ParcelFileDescriptor">
+</parameter>
+<parameter name="data" type="android.backup.BackupDataOutput">
+</parameter>
+<parameter name="newState" type="android.os.ParcelFileDescriptor">
+</parameter>
+</method>
+<method name="restoreEntity"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="android.backup.BackupDataInputStream">
+</parameter>
+</method>
+</class>
+<class name="FileBackupHelperBase"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility=""
+>
+<method name="writeNewStateDescription"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fd" type="android.os.ParcelFileDescriptor">
+</parameter>
+</method>
+</class>
+<class name="RestoreObserver"
+ extends="java.lang.Object"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="RestoreObserver"
+ type="android.backup.RestoreObserver"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+</class>
+<class name="RestoreSession"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="endRestoreSession"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="restorePackage"
+ return="int"
+ 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="observer" type="android.backup.RestoreObserver">
+</parameter>
+</method>
+</class>
+<class name="SharedPreferencesBackupHelper"
+ extends="android.backup.FileBackupHelperBase"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.backup.BackupHelper">
+</implements>
+<constructor name="SharedPreferencesBackupHelper"
+ type="android.backup.SharedPreferencesBackupHelper"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="prefGroups" type="java.lang.String...">
+</parameter>
+</constructor>
+<method name="performBackup"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="oldState" type="android.os.ParcelFileDescriptor">
+</parameter>
+<parameter name="data" type="android.backup.BackupDataOutput">
+</parameter>
+<parameter name="newState" type="android.os.ParcelFileDescriptor">
+</parameter>
+</method>
+<method name="restoreEntity"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="android.backup.BackupDataInputStream">
+</parameter>
+</method>
+</class>
+</package>
<package name="android.bluetooth"
>
<class name="BluetoothAdapter"
@@ -85749,6 +86457,509 @@
>
</field>
</class>
+<class name="Downloads"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="isStatusError"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="status" type="int">
+</parameter>
+</method>
+<method name="isStatusSuccess"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="status" type="int">
+</parameter>
+</method>
+<field name="ACTION_DOWNLOAD_COMPLETED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.intent.action.DOWNLOAD_COMPLETED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="COLUMN_NOTIFICATION_EXTRAS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;notificationextras&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DOWNLOAD_DESTINATION_CACHE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DOWNLOAD_DESTINATION_CACHE_PURGEABLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DOWNLOAD_DESTINATION_EXTERNAL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DOWNLOAD_ID_INVALID"
+ type="long"
+ transient="false"
+ volatile="false"
+ value="-1L"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_DEVICE_NOT_FOUND_ERROR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="499"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_INSUFFICIENT_SPACE_ERROR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="498"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_NOT_ACCEPTABLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="406"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_PENDING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="190"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_RUNNING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="192"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_SUCCESS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="200"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_UNHANDLED_REDIRECT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="493"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_UNKNOWN_ERROR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="491"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="Downloads.ById"
+ extends="android.net.Downloads.DownloadBase"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="deleteDownload"
+ return="void"
+ 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="downloadId" type="long">
+</parameter>
+</method>
+<method name="getMimeTypeForId"
+ return="java.lang.String"
+ 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="downloadId" type="long">
+</parameter>
+</method>
+<method name="getStatus"
+ return="android.net.Downloads.StatusInfo"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="downloadId" type="long">
+</parameter>
+</method>
+<method name="openDownload"
+ return="android.os.ParcelFileDescriptor"
+ 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="downloadId" type="long">
+</parameter>
+<parameter name="mode" type="java.lang.String">
+</parameter>
+<exception name="FileNotFoundException" type="java.io.FileNotFoundException">
+</exception>
+</method>
+<method name="openDownloadStream"
+ return="java.io.InputStream"
+ 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="downloadId" type="long">
+</parameter>
+<exception name="FileNotFoundException" type="java.io.FileNotFoundException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+</class>
+<class name="Downloads.ByUri"
+ extends="android.net.Downloads.DownloadBase"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="getProgressColumnCurrentBytes"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getProgressColumnId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getProgressColumnTotalBytes"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getProgressCursor"
+ return="android.database.Cursor"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="id" type="long">
+</parameter>
+</method>
+<method name="getStatus"
+ return="android.net.Downloads.StatusInfo"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="url" type="java.lang.String">
+</parameter>
+<parameter name="redownload_threshold" type="long">
+</parameter>
+</method>
+<method name="removeAllDownloadsByPackage"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="notification_package" type="java.lang.String">
+</parameter>
+<parameter name="notification_class" type="java.lang.String">
+</parameter>
+</method>
+</class>
+<class name="Downloads.DownloadBase"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="private"
+>
+<method name="startDownloadByUri"
+ return="long"
+ 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="url" type="java.lang.String">
+</parameter>
+<parameter name="cookieData" type="java.lang.String">
+</parameter>
+<parameter name="showDownload" type="boolean">
+</parameter>
+<parameter name="downloadDestination" type="int">
+</parameter>
+<parameter name="allowRoaming" type="boolean">
+</parameter>
+<parameter name="skipIntegrityCheck" type="boolean">
+</parameter>
+<parameter name="title" type="java.lang.String">
+</parameter>
+<parameter name="notification_package" type="java.lang.String">
+</parameter>
+<parameter name="notification_class" type="java.lang.String">
+</parameter>
+<parameter name="notification_extras" type="java.lang.String">
+</parameter>
+</method>
+</class>
+<class name="Downloads.StatusInfo"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="Downloads.StatusInfo"
+ type="android.net.Downloads.StatusInfo"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="isComplete"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isSuccessful"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<field name="bytesSoFar"
+ type="long"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="completed"
+ type="boolean"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="filename"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="id"
+ type="long"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="statusCode"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
<class name="LocalServerSocket"
extends="java.lang.Object"
abstract="false"
@@ -86829,7 +88040,7 @@
</parameter>
</method>
<method name="getDefault"
- return="javax.net.SocketFactory"
+ return="javax.net.ssl.SSLSocketFactory"
abstract="false"
native="false"
synchronized="false"
@@ -86869,6 +88080,21 @@
<parameter name="cache" type="android.net.SSLSessionCache">
</parameter>
</method>
+<method name="getInsecure"
+ return="javax.net.ssl.SSLSocketFactory"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="handshakeTimeoutMillis" type="int">
+</parameter>
+<parameter name="cache" type="android.net.SSLSessionCache">
+</parameter>
+</method>
<method name="getSupportedCipherSuites"
return="java.lang.String[]"
abstract="false"
@@ -136110,17 +137336,6 @@
visibility="public"
>
</field>
-<field name="ACTION_VOICE_SEARCH_SETTINGS"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.speech.action.VOICE_SEARCH_SETTINGS&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="ACTION_WEB_SEARCH"
type="java.lang.String"
transient="false"
@@ -139884,7 +141099,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="bundleWithValues" type="android.os.Bundle">
+<parameter name="bundle" type="android.os.Bundle">
</parameter>
</constructor>
<method name="fillInNotifierBundle"
@@ -147323,6 +148538,38 @@
<parameter name="count" type="int">
</parameter>
</method>
+<method name="getEastAsianWidth"
+ return="int"
+ abstract="false"
+ native="true"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="input" type="char">
+</parameter>
+</method>
+<method name="getEastAsianWidths"
+ return="void"
+ abstract="false"
+ native="true"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="src" type="char[]">
+</parameter>
+<parameter name="start" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="dest" type="byte[]">
+</parameter>
+</method>
<method name="getMirror"
return="char"
abstract="false"
@@ -147353,6 +148600,72 @@
<parameter name="count" type="int">
</parameter>
</method>
+<field name="EAST_ASIAN_WIDTH_AMBIGUOUS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EAST_ASIAN_WIDTH_FULL_WIDTH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EAST_ASIAN_WIDTH_HALF_WIDTH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EAST_ASIAN_WIDTH_NARROW"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EAST_ASIAN_WIDTH_NEUTRAL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EAST_ASIAN_WIDTH_WIDE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="5"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="Annotation"
extends="java.lang.Object"
@@ -163514,6 +164827,243 @@
</method>
</class>
</package>
+<package name="android.util.base64"
+>
+<class name="Base64"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="decode"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="str" type="java.lang.String">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<method name="decode"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="input" type="byte[]">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<method name="decode"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="input" type="byte[]">
+</parameter>
+<parameter name="offset" type="int">
+</parameter>
+<parameter name="len" type="int">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<method name="encode"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="input" type="byte[]">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<method name="encode"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="input" type="byte[]">
+</parameter>
+<parameter name="offset" type="int">
+</parameter>
+<parameter name="len" type="int">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<method name="encodeToString"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="input" type="byte[]">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<method name="encodeToString"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="input" type="byte[]">
+</parameter>
+<parameter name="offset" type="int">
+</parameter>
+<parameter name="len" type="int">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<field name="CRLF"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DEFAULT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NO_CLOSE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NO_PADDING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NO_WRAP"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="URL_SAFE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="Base64InputStream"
+ extends="java.io.FilterInputStream"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="Base64InputStream"
+ type="android.util.base64.Base64InputStream"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="in" type="java.io.InputStream">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</constructor>
+</class>
+<class name="Base64OutputStream"
+ extends="java.io.FilterOutputStream"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="Base64OutputStream"
+ type="android.util.base64.Base64OutputStream"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="out" type="java.io.OutputStream">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</constructor>
+</class>
+</package>
<package name="android.view"
>
<class name="AbsSavedState"
@@ -164725,6 +166275,17 @@
visibility="public"
>
</field>
+<field name="KEYBOARD_TAP"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="LONG_PRESS"
type="int"
transient="false"
@@ -168389,6 +169950,28 @@
visibility="public"
>
</method>
+<method name="getActionIndex"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getActionMasked"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getDeviceId"
return="int"
abstract="false"
@@ -169009,7 +170592,7 @@
value="5"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -169020,7 +170603,7 @@
value="6"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -169031,7 +170614,7 @@
value="261"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -169042,7 +170625,7 @@
value="262"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -169053,7 +170636,7 @@
value="517"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -169064,7 +170647,7 @@
value="518"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -169086,7 +170669,7 @@
value="65280"
static="true"
final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
</field>
@@ -169097,6 +170680,28 @@
value="8"
static="true"
final="true"
+ deprecated="deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_POINTER_INDEX_MASK"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="65280"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_POINTER_INDEX_SHIFT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8"
+ static="true"
+ final="true"
deprecated="not deprecated"
visibility="public"
>
@@ -384397,648 +386002,6 @@
</field>
</interface>
</package>
-<package name="org.w3c.dom.events"
->
-<interface name="DocumentEvent"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="createEvent"
- return="org.w3c.dom.events.Event"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="eventType" type="java.lang.String">
-</parameter>
-<exception name="DOMException" type="org.w3c.dom.DOMException">
-</exception>
-</method>
-</interface>
-<interface name="Event"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="getBubbles"
- return="boolean"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getCancelable"
- return="boolean"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getCurrentTarget"
- return="org.w3c.dom.events.EventTarget"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getEventPhase"
- return="short"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getTarget"
- return="org.w3c.dom.events.EventTarget"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getTimeStamp"
- return="long"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getType"
- return="java.lang.String"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="initEvent"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="eventTypeArg" type="java.lang.String">
-</parameter>
-<parameter name="canBubbleArg" type="boolean">
-</parameter>
-<parameter name="cancelableArg" type="boolean">
-</parameter>
-</method>
-<method name="preventDefault"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="stopPropagation"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<field name="AT_TARGET"
- type="short"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="BUBBLING_PHASE"
- type="short"
- transient="false"
- volatile="false"
- value="3"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="CAPTURING_PHASE"
- type="short"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</interface>
-<class name="EventException"
- extends="java.lang.RuntimeException"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="EventException"
- type="org.w3c.dom.events.EventException"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="code" type="short">
-</parameter>
-<parameter name="message" type="java.lang.String">
-</parameter>
-</constructor>
-<field name="UNSPECIFIED_EVENT_TYPE_ERR"
- type="short"
- transient="false"
- volatile="false"
- value="0"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="code"
- type="short"
- transient="false"
- volatile="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
-<interface name="EventListener"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="handleEvent"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="evt" type="org.w3c.dom.events.Event">
-</parameter>
-</method>
-</interface>
-<interface name="EventTarget"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="addEventListener"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="type" type="java.lang.String">
-</parameter>
-<parameter name="listener" type="org.w3c.dom.events.EventListener">
-</parameter>
-<parameter name="useCapture" type="boolean">
-</parameter>
-</method>
-<method name="dispatchEvent"
- return="boolean"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="evt" type="org.w3c.dom.events.Event">
-</parameter>
-<exception name="EventException" type="org.w3c.dom.events.EventException">
-</exception>
-</method>
-<method name="removeEventListener"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="type" type="java.lang.String">
-</parameter>
-<parameter name="listener" type="org.w3c.dom.events.EventListener">
-</parameter>
-<parameter name="useCapture" type="boolean">
-</parameter>
-</method>
-</interface>
-<interface name="MouseEvent"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="org.w3c.dom.events.UIEvent">
-</implements>
-<method name="getAltKey"
- return="boolean"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getButton"
- return="short"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getClientX"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getClientY"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getCtrlKey"
- return="boolean"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getMetaKey"
- return="boolean"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getRelatedTarget"
- return="org.w3c.dom.events.EventTarget"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getScreenX"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getScreenY"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getShiftKey"
- return="boolean"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="initMouseEvent"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="typeArg" type="java.lang.String">
-</parameter>
-<parameter name="canBubbleArg" type="boolean">
-</parameter>
-<parameter name="cancelableArg" type="boolean">
-</parameter>
-<parameter name="viewArg" type="org.w3c.dom.views.AbstractView">
-</parameter>
-<parameter name="detailArg" type="int">
-</parameter>
-<parameter name="screenXArg" type="int">
-</parameter>
-<parameter name="screenYArg" type="int">
-</parameter>
-<parameter name="clientXArg" type="int">
-</parameter>
-<parameter name="clientYArg" type="int">
-</parameter>
-<parameter name="ctrlKeyArg" type="boolean">
-</parameter>
-<parameter name="altKeyArg" type="boolean">
-</parameter>
-<parameter name="shiftKeyArg" type="boolean">
-</parameter>
-<parameter name="metaKeyArg" type="boolean">
-</parameter>
-<parameter name="buttonArg" type="short">
-</parameter>
-<parameter name="relatedTargetArg" type="org.w3c.dom.events.EventTarget">
-</parameter>
-</method>
-</interface>
-<interface name="MutationEvent"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="org.w3c.dom.events.Event">
-</implements>
-<method name="getAttrChange"
- return="short"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getAttrName"
- return="java.lang.String"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getNewValue"
- return="java.lang.String"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getPrevValue"
- return="java.lang.String"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getRelatedNode"
- return="org.w3c.dom.Node"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="initMutationEvent"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="typeArg" type="java.lang.String">
-</parameter>
-<parameter name="canBubbleArg" type="boolean">
-</parameter>
-<parameter name="cancelableArg" type="boolean">
-</parameter>
-<parameter name="relatedNodeArg" type="org.w3c.dom.Node">
-</parameter>
-<parameter name="prevValueArg" type="java.lang.String">
-</parameter>
-<parameter name="newValueArg" type="java.lang.String">
-</parameter>
-<parameter name="attrNameArg" type="java.lang.String">
-</parameter>
-<parameter name="attrChangeArg" type="short">
-</parameter>
-</method>
-<field name="ADDITION"
- type="short"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="MODIFICATION"
- type="short"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="REMOVAL"
- type="short"
- transient="false"
- volatile="false"
- value="3"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</interface>
-<interface name="UIEvent"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="org.w3c.dom.events.Event">
-</implements>
-<method name="getDetail"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getView"
- return="org.w3c.dom.views.AbstractView"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="initUIEvent"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="typeArg" type="java.lang.String">
-</parameter>
-<parameter name="canBubbleArg" type="boolean">
-</parameter>
-<parameter name="cancelableArg" type="boolean">
-</parameter>
-<parameter name="viewArg" type="org.w3c.dom.views.AbstractView">
-</parameter>
-<parameter name="detailArg" type="int">
-</parameter>
-</method>
-</interface>
-</package>
<package name="org.w3c.dom.ls"
>
<interface name="DOMImplementationLS"
@@ -385374,38 +386337,6 @@
</parameter>
</method>
</interface>
-<interface name="LSLoadEvent"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="org.w3c.dom.events.Event">
-</implements>
-<method name="getInput"
- return="org.w3c.dom.ls.LSInput"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getNewDocument"
- return="org.w3c.dom.Document"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-</interface>
<interface name="LSOutput"
abstract="true"
static="false"
@@ -385785,49 +386716,6 @@
>
</field>
</interface>
-<interface name="LSProgressEvent"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="org.w3c.dom.events.Event">
-</implements>
-<method name="getInput"
- return="org.w3c.dom.ls.LSInput"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getPosition"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getTotalSize"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-</interface>
<interface name="LSResourceResolver"
abstract="true"
static="false"
@@ -385875,17 +386763,6 @@
visibility="public"
>
</method>
-<method name="getFilter"
- return="org.w3c.dom.ls.LSSerializerFilter"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
<method name="getNewLine"
return="java.lang.String"
abstract="true"
@@ -385897,19 +386774,6 @@
visibility="public"
>
</method>
-<method name="setFilter"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="filter" type="org.w3c.dom.ls.LSSerializerFilter">
-</parameter>
-</method>
<method name="setNewLine"
return="void"
abstract="true"
@@ -385975,562 +386839,6 @@
</exception>
</method>
</interface>
-<interface name="LSSerializerFilter"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="org.w3c.dom.traversal.NodeFilter">
-</implements>
-<method name="getWhatToShow"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-</interface>
-</package>
-<package name="org.w3c.dom.traversal"
->
-<interface name="DocumentTraversal"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="createNodeIterator"
- return="org.w3c.dom.traversal.NodeIterator"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="root" type="org.w3c.dom.Node">
-</parameter>
-<parameter name="whatToShow" type="int">
-</parameter>
-<parameter name="filter" type="org.w3c.dom.traversal.NodeFilter">
-</parameter>
-<parameter name="entityReferenceExpansion" type="boolean">
-</parameter>
-<exception name="DOMException" type="org.w3c.dom.DOMException">
-</exception>
-</method>
-<method name="createTreeWalker"
- return="org.w3c.dom.traversal.TreeWalker"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="root" type="org.w3c.dom.Node">
-</parameter>
-<parameter name="whatToShow" type="int">
-</parameter>
-<parameter name="filter" type="org.w3c.dom.traversal.NodeFilter">
-</parameter>
-<parameter name="entityReferenceExpansion" type="boolean">
-</parameter>
-<exception name="DOMException" type="org.w3c.dom.DOMException">
-</exception>
-</method>
-</interface>
-<interface name="NodeFilter"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="acceptNode"
- return="short"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="n" type="org.w3c.dom.Node">
-</parameter>
-</method>
-<field name="FILTER_ACCEPT"
- type="short"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="FILTER_REJECT"
- type="short"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="FILTER_SKIP"
- type="short"
- transient="false"
- volatile="false"
- value="3"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SHOW_ALL"
- type="int"
- transient="false"
- volatile="false"
- value="-1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SHOW_ATTRIBUTE"
- type="int"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SHOW_CDATA_SECTION"
- type="int"
- transient="false"
- volatile="false"
- value="8"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SHOW_COMMENT"
- type="int"
- transient="false"
- volatile="false"
- value="128"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SHOW_DOCUMENT"
- type="int"
- transient="false"
- volatile="false"
- value="256"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SHOW_DOCUMENT_FRAGMENT"
- type="int"
- transient="false"
- volatile="false"
- value="1024"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SHOW_DOCUMENT_TYPE"
- type="int"
- transient="false"
- volatile="false"
- value="512"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SHOW_ELEMENT"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SHOW_ENTITY"
- type="int"
- transient="false"
- volatile="false"
- value="32"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SHOW_ENTITY_REFERENCE"
- type="int"
- transient="false"
- volatile="false"
- value="16"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SHOW_NOTATION"
- type="int"
- transient="false"
- volatile="false"
- value="2048"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SHOW_PROCESSING_INSTRUCTION"
- type="int"
- transient="false"
- volatile="false"
- value="64"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SHOW_TEXT"
- type="int"
- transient="false"
- volatile="false"
- value="4"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</interface>
-<interface name="NodeIterator"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="detach"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getExpandEntityReferences"
- return="boolean"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getFilter"
- return="org.w3c.dom.traversal.NodeFilter"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getRoot"
- return="org.w3c.dom.Node"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getWhatToShow"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="nextNode"
- return="org.w3c.dom.Node"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<exception name="DOMException" type="org.w3c.dom.DOMException">
-</exception>
-</method>
-<method name="previousNode"
- return="org.w3c.dom.Node"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<exception name="DOMException" type="org.w3c.dom.DOMException">
-</exception>
-</method>
-</interface>
-<interface name="TreeWalker"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="firstChild"
- return="org.w3c.dom.Node"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getCurrentNode"
- return="org.w3c.dom.Node"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getExpandEntityReferences"
- return="boolean"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getFilter"
- return="org.w3c.dom.traversal.NodeFilter"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getRoot"
- return="org.w3c.dom.Node"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getWhatToShow"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="lastChild"
- return="org.w3c.dom.Node"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="nextNode"
- return="org.w3c.dom.Node"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="nextSibling"
- return="org.w3c.dom.Node"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="parentNode"
- return="org.w3c.dom.Node"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="previousNode"
- return="org.w3c.dom.Node"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="previousSibling"
- return="org.w3c.dom.Node"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="setCurrentNode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="currentNode" type="org.w3c.dom.Node">
-</parameter>
-<exception name="DOMException" type="org.w3c.dom.DOMException">
-</exception>
-</method>
-</interface>
-</package>
-<package name="org.w3c.dom.views"
->
-<interface name="AbstractView"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="getDocument"
- return="org.w3c.dom.views.DocumentView"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-</interface>
-<interface name="DocumentView"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="getDefaultView"
- return="org.w3c.dom.views.AbstractView"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-</interface>
</package>
<package name="org.xml.sax"
>
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 86a6fac27009..7e81e90cf3c0 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -29,6 +29,8 @@
#include <surfaceflinger/ISurface.h>
#include <ui/Overlay.h>
+#include <hardware/hardware.h>
+
#include <media/mediaplayer.h>
#include <media/AudioSystem.h>
#include "CameraService.h"
@@ -605,8 +607,9 @@ status_t CameraService::Client::registerPreviewBuffers()
CameraParameters params(mHardware->getParameters());
params.getPreviewSize(&w, &h);
+ // don't use a hardcoded format here
ISurface::BufferHeap buffers(w, h, w, h,
- PIXEL_FORMAT_YCbCr_420_SP,
+ HAL_PIXEL_FORMAT_YCrCb_420_SP,
mOrientation,
0,
mHardware->getPreviewHeap());
@@ -926,8 +929,10 @@ void CameraService::Client::handleShutter(
h &= ~1;
LOGV("Snapshot image width=%d, height=%d", w, h);
}
+ // FIXME: don't use hardcoded format constants here
ISurface::BufferHeap buffers(w, h, w, h,
- PIXEL_FORMAT_YCbCr_420_SP, mOrientation, 0, mHardware->getRawHeap());
+ HAL_PIXEL_FORMAT_YCrCb_420_SP, mOrientation, 0,
+ mHardware->getRawHeap());
mSurface->registerBuffers(buffers);
}
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index cd0302c22225..a447f536e71c 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -690,6 +690,83 @@ void mkinnerdirs(char* path, int basepos, mode_t mode, int uid, int gid)
}
}
+int movefileordir(char* srcpath, char* dstpath, int dstuid, int dstgid,
+ struct stat* statbuf)
+{
+ DIR *d;
+ struct dirent *de;
+ int res;
+
+ int srcend = strlen(srcpath);
+ int dstend = strlen(dstpath);
+
+ if (lstat(srcpath, statbuf) < 0) {
+ LOGW("Unable to stat %s: %s\n", srcpath, strerror(errno));
+ return 1;
+ }
+
+ if ((statbuf->st_mode&S_IFDIR) == 0) {
+ LOGI("Renaming %s to %s (uid %d)\n", srcpath, dstpath, dstuid);
+ mkinnerdirs(dstpath, dstend-1, S_IRWXU|S_IRWXG|S_IXOTH, dstuid, dstgid);
+ if (rename(srcpath, dstpath) >= 0) {
+ if (chown(dstpath, dstuid, dstgid) < 0) {
+ LOGE("cannot chown %s: %s\n", dstpath, strerror(errno));
+ unlink(dstpath);
+ return 1;
+ }
+ } else {
+ LOGW("Unable to rename %s to %s: %s\n",
+ srcpath, dstpath, strerror(errno));
+ return 1;
+ }
+ return 0;
+ }
+
+ d = opendir(srcpath);
+ if (d == NULL) {
+ LOGW("Unable to opendir %s: %s\n", srcpath, strerror(errno));
+ return 1;
+ }
+
+ res = 0;
+
+ while ((de = readdir(d))) {
+ const char *name = de->d_name;
+ /* always skip "." and ".." */
+ if (name[0] == '.') {
+ if (name[1] == 0) continue;
+ if ((name[1] == '.') && (name[2] == 0)) continue;
+ }
+
+ if ((srcend+strlen(name)) >= (PKG_PATH_MAX-2)) {
+ LOGW("Source path too long; skipping: %s/%s\n", srcpath, name);
+ continue;
+ }
+
+ if ((dstend+strlen(name)) >= (PKG_PATH_MAX-2)) {
+ LOGW("Destination path too long; skipping: %s/%s\n", dstpath, name);
+ continue;
+ }
+
+ srcpath[srcend] = dstpath[dstend] = '/';
+ strcpy(srcpath+srcend+1, name);
+ strcpy(dstpath+dstend+1, name);
+
+ if (movefileordir(srcpath, dstpath, dstuid, dstgid, statbuf) != 0) {
+ res = 1;
+ }
+
+ // Note: we will be leaving empty directories behind in srcpath,
+ // but that is okay, the package manager will be erasing all of the
+ // data associated with .apks that disappear.
+
+ srcpath[srcend] = dstpath[dstend] = 0;
+ }
+
+ closedir(d);
+ return res;
+}
+
int movefiles()
{
DIR *d;
@@ -703,7 +780,7 @@ int movefiles()
char dstpkg[PKG_NAME_MAX];
char srcpath[PKG_PATH_MAX];
char dstpath[PKG_PATH_MAX];
- int dstuid, dstgid;
+ int dstuid=-1, dstgid=-1;
int hasspace;
d = opendir(UPDATE_COMMANDS_DIR_PREFIX);
@@ -757,18 +834,7 @@ int movefiles()
LOGV("Move file: %s (from %s to %s)\n", buf+bufp, srcpkg, dstpkg);
if (!create_move_path(srcpath, PKG_DIR_PREFIX, srcpkg, buf+bufp) &&
!create_move_path(dstpath, PKG_DIR_PREFIX, dstpkg, buf+bufp)) {
- LOGI("Renaming %s to %s (uid %d)\n", srcpath, dstpath, dstuid);
- mkinnerdirs(dstpath, strlen(dstpath)-(bufi-bufp),
- S_IRWXU|S_IRWXG|S_IXOTH, dstuid, dstgid);
- if (rename(srcpath, dstpath) >= 0) {
- if (chown(dstpath, dstuid, dstgid) < 0) {
- LOGE("cannot chown %s: %s\n", dstpath, strerror(errno));
- unlink(dstpath);
- }
- } else {
- LOGW("Unable to rename %s to %s: %s\n",
- srcpath, dstpath, strerror(errno));
- }
+ movefileordir(srcpath, dstpath, dstuid, dstgid, &s);
}
}
} else {
@@ -812,10 +878,11 @@ int movefiles()
dstuid = s.st_uid;
dstgid = s.st_gid;
} else {
+ // Destination package doesn't
+ // exist... due to original-package,
+ // this is normal, so don't be
+ // noisy about it.
srcpkg[0] = 0;
- LOGW("Can't stat path %s in %s%s: %s\n",
- dstpath, UPDATE_COMMANDS_DIR_PREFIX,
- name, strerror(errno));
}
} else {
srcpkg[0] = 0;
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 68373cb3c973..ff16c6e340b3 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -600,7 +600,7 @@ public final class Pm {
} else if (opt.equals("-t")) {
installFlags |= PackageManager.INSTALL_ALLOW_TEST;
} else if (opt.equals("-s")) {
- installFlags |= PackageManager.INSTALL_ON_SDCARD;
+ installFlags |= PackageManager.INSTALL_EXTERNAL;
} else {
System.err.println("Error: Unknown option: " + opt);
showUsage();
diff --git a/common/java/com/android/common/Base64.java b/common/java/com/android/common/Base64.java
deleted file mode 100644
index d65e24eaf4b6..000000000000
--- a/common/java/com/android/common/Base64.java
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.common;
-
-/**
- * Utilities for encoding and decoding the Base64 encoding. See RFCs
- * 2045 and 3548.
- */
-public class Base64 {
- /**
- * Default values for encoder/decoder flags.
- */
- public static final int DEFAULT = 0;
-
- /**
- * Encoder flag bit to indicate you want the padding '='
- * characters at the end (if any) to be omitted.
- */
- public static final int NO_PADDING = 1;
-
- /**
- * Encoder flag bit to indicate you want all line terminators to
- * be omitted (ie, the output will be on one long line).
- */
- public static final int NO_WRAP = 2;
-
- /**
- * Encoder flag bit to indicate you want lines to be ended with
- * CRLF instead of just LF.
- */
- public static final int CRLF = 4;
-
- /**
- * Encoder/decoder flag bit to indicate using the "web safe"
- * variant of Base64 (see RFC 3548 section 4) where '-' and '_'
- * are used in place of '+' and '/'.
- */
- public static final int WEB_SAFE = 8;
-
- /**
- * Flag to pass to Base64OutputStream to indicate that it should
- * not close the output stream it is wrapping when it itself is
- * closed.
- */
- public static final int NO_CLOSE = 16;
-
- // --------------------------------------------------------
- // decoding
- // --------------------------------------------------------
-
- /**
- * Lookup table for turning bytes into their position in the
- * Base64 alphabet.
- */
- private static final int DECODE[] = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
- -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- };
-
- /**
- * Decode lookup table for the "web safe" variant (RFC 3548
- * sec. 4) where - and _ replace + and /.
- */
- private static final int DECODE_WEBSAFE[] = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
- -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- };
-
- /** Non-data values in the DECODE arrays. */
- private static final int SKIP = -1;
- private static final int EQUALS = -2;
-
- /**
- * Decode the Base64-encoded data in input and return the data in
- * a new byte array.
- *
- * The padding '=' characters at the end are considered optional, but
- * if any are present, there must be the correct number of them.
- *
- * @param input the input String to decode, which is converted to
- * bytes using the default charset
- * @param flags controls certain features of the decoded output.
- * Pass {@code DEFAULT} to decode standard Base64.
- *
- * @throws IllegalArgumentException if the input contains
- * incorrect padding
- */
- public static byte[] decode(String str, int flags) {
- return decode(str.getBytes(), flags);
- }
-
- /**
- * Decode the Base64-encoded data in input and return the data in
- * a new byte array.
- *
- * The padding '=' characters at the end are considered optional, but
- * if any are present, there must be the correct number of them.
- *
- * @param input the input array to decode
- * @param flags controls certain features of the decoded output.
- * Pass {@code DEFAULT} to decode standard Base64.
- *
- * @throws IllegalArgumentException if the input contains
- * incorrect padding
- */
- public static byte[] decode(byte[] input, int flags) {
- return decode(input, 0, input.length, flags);
- }
-
- /**
- * Decode the Base64-encoded data in input and return the data in
- * a new byte array.
- *
- * The padding '=' characters at the end are considered optional, but
- * if any are present, there must be the correct number of them.
- *
- * @param input the data to decode
- * @param offset the position within the input array at which to start
- * @param len the number of bytes of input to decode
- * @param flags controls certain features of the decoded output.
- * Pass {@code DEFAULT} to decode standard Base64.
- *
- * @throws IllegalArgumentException if the input contains
- * incorrect padding
- */
- public static byte[] decode(byte[] input, int offset, int len, int flags) {
- // Allocate space for the most data the input could represent.
- // (It could contain less if it contains whitespace, etc.)
- DecoderState state = new DecoderState(flags, new byte[len*3/4]);
-
- if (!decodeInternal(input, offset, len, state, true)) {
- throw new IllegalArgumentException("bad base-64");
- }
-
- // Maybe we got lucky and allocated exactly enough output space.
- if (state.op == state.output.length) {
- return state.output;
- }
-
- // Need to shorten the array, so allocate a new one of the
- // right size and copy.
- byte[] temp = new byte[state.op];
- System.arraycopy(state.output, 0, temp, 0, state.op);
- return temp;
- }
-
- /* package */ static class DecoderState {
- public byte[] output;
- public int op;
-
- public int state; // state number (0 to 6)
- public int value;
-
- final public int[] alphabet;
-
- public DecoderState(int flags, byte[] output) {
- this.output = output;
-
- alphabet = ((flags & WEB_SAFE) == 0) ? DECODE : DECODE_WEBSAFE;
- state = 0;
- value = 0;
- }
- }
-
- /**
- * Decode another block of input data.
- *
- * @param dstate a DecoderState object whose (caller-provided)
- * output array is big enough to hold all the decoded data.
- * On return, dstate.op will be set to the length of the
- * decoded data.
- * @param finish true if this is the final call to decodeInternal
- * with the given DecoderState object. Will finalize the
- * decoder state and include any final bytes in the output.
- *
- * @return true if the state machine is still healthy. false if
- * bad base-64 data has been detected in the input stream.
- */
-
- /* package */ static boolean decodeInternal(
- byte[] input, int offset, int len, final DecoderState dstate, boolean finish) {
- if (dstate.state == 6) return false;
-
- int state = dstate.state;
- int value = dstate.value;
- final int[] decode = dstate.alphabet;
- final byte[] output = dstate.output;
- int op = 0;
-
- int p = offset;
- len += offset;
-
- while (p < len) {
-
- // Try the fast path: we're starting a new tuple and the
- // next four bytes of the input stream are all data
- // bytes. This corresponds to going through states
- // 0-1-2-3-0. We expect to use this method for most of
- // the data.
- //
- // If any of the next four bytes of input are non-data
- // (whitespace, etc.), value will end up negative. (All
- // the non-data values in decode are small negative
- // numbers, so shifting any of them up and or'ing them
- // together will result in a value with its top bit set.)
- //
- // You can remove this whole block and the output should
- // be the same, just slower.
- if (state == 0 && p+4 <= len &&
- (value = ((decode[input[p] & 0xff] << 18) |
- (decode[input[p+1] & 0xff] << 12) |
- (decode[input[p+2] & 0xff] << 6) |
- (decode[input[p+3] & 0xff]))) >= 0) {
- output[op+2] = (byte) value;
- output[op+1] = (byte) (value >> 8);
- output[op] = (byte) (value >> 16);
- op += 3;
- p += 4;
- continue;
- }
-
- // The fast path isn't available -- either we've read a
- // partial tuple, or the next four input bytes aren't all
- // data, or whatever. Fall back to the slower state
- // machine implementation.
- //
- // States 0-3 are reading through the next input tuple.
- // State 4 is having read one '=' and expecting exactly
- // one more.
- // State 5 is expecting no more data or padding characters
- // in the input.
- // State 6 is the error state; an error has been detected
- // in the input and no future input can "fix" it.
-
- int d = decode[input[p++] & 0xff];
-
- switch (state) {
- case 0:
- if (d >= 0) {
- value = d;
- ++state;
- } else if (d != SKIP) {
- dstate.state = 6;
- return false;
- }
- break;
-
- case 1:
- if (d >= 0) {
- value = (value << 6) | d;
- ++state;
- } else if (d != SKIP) {
- dstate.state = 6;
- return false;
- }
- break;
-
- case 2:
- if (d >= 0) {
- value = (value << 6) | d;
- ++state;
- } else if (d == EQUALS) {
- // Emit the last (partial) output tuple;
- // expect exactly one more padding character.
- output[op++] = (byte) (value >> 4);
- state = 4;
- } else if (d != SKIP) {
- dstate.state = 6;
- return false;
- }
- break;
-
- case 3:
- if (d >= 0) {
- // Emit the output triple and return to state 0.
- value = (value << 6) | d;
- output[op+2] = (byte) value;
- output[op+1] = (byte) (value >> 8);
- output[op] = (byte) (value >> 16);
- op += 3;
- state = 0;
- } else if (d == EQUALS) {
- // Emit the last (partial) output tuple;
- // expect no further data or padding characters.
- output[op+1] = (byte) (value >> 2);
- output[op] = (byte) (value >> 10);
- op += 2;
- state = 5;
- } else if (d != SKIP) {
- dstate.state = 6;
- return false;
- }
- break;
-
- case 4:
- if (d == EQUALS) {
- ++state;
- } else if (d != SKIP) {
- dstate.state = 6;
- return false;
- }
- break;
-
- case 5:
- if (d != SKIP) {
- dstate.state = 6;
- return false;
- }
- break;
- }
- }
-
- if (!finish) {
- // We're out of input, but a future call could provide
- // more. Return the output we've produced on this call
- // and save the current state of the state machine.
- dstate.state = state;
- dstate.value = value;
- dstate.op = op;
- return true;
- }
-
- // Done reading input. Now figure out where we are left in
- // the state machine and finish up.
-
- switch (state) {
- case 0:
- // Output length is a multiple of three. Fine.
- break;
- case 1:
- // Read one extra input byte, which isn't enough to
- // make another output byte. Illegal.
- dstate.state = 6;
- return false;
- case 2:
- // Read two extra input bytes, enough to emit 1 more
- // output byte. Fine.
- output[op++] = (byte) (value >> 4);
- break;
- case 3:
- // Read three extra input bytes, enough to emit 2 more
- // output bytes. Fine.
- output[op+1] = (byte) (value >> 2);
- output[op] = (byte) (value >> 10);
- op += 2;
- break;
- case 4:
- // Read one padding '=' when we expected 2. Illegal.
- dstate.state = 6;
- return false;
- case 5:
- // Read all the padding '='s we expected and no more.
- // Fine.
- break;
- }
-
- dstate.op = op;
- return true;
- }
-
- // --------------------------------------------------------
- // encoding
- // --------------------------------------------------------
-
- /**
- * Emit a new line every this many output tuples. Corresponds to
- * a 76-character line length (the maximum allowable according to
- * RFC 2045).
- */
- private static final int LINE_GROUPS = 19;
-
- /**
- * Lookup table for turning Base64 alphabet positions (6 bits)
- * into output bytes.
- */
- private static final byte ENCODE[] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
- 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
- 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
- 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0', '1', '2', '3',
- '4', '5', '6', '7', '8', '9', '+', '/',
- };
-
- /**
- * Lookup table for turning Base64 alphabet positions (6 bits)
- * into output bytes.
- */
- private static final byte ENCODE_WEBSAFE[] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
- 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
- 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
- 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0', '1', '2', '3',
- '4', '5', '6', '7', '8', '9', '-', '_',
- };
-
- /**
- * Base64-encode the given data and return a newly allocated
- * String with the result.
- *
- * @param input the data to encode
- * @param flags controls certain features of the encoded output.
- * Passing {@code DEFAULT} results in output that
- * adheres to RFC 2045.
- */
- public static String encodeToString(byte[] input, int flags) {
- return new String(encode(input, flags));
- }
-
- /**
- * Base64-encode the given data and return a newly allocated
- * String with the result.
- *
- * @param input the data to encode
- * @param offset the position within the input array at which to
- * start
- * @param len the number of bytes of input to encode
- * @param flags controls certain features of the encoded output.
- * Passing {@code DEFAULT} results in output that
- * adheres to RFC 2045.
- */
- public static String encodeToString(byte[] input, int offset, int len, int flags) {
- return new String(encode(input, offset, len, flags));
- }
-
- /**
- * Base64-encode the given data and return a newly allocated
- * byte[] with the result.
- *
- * @param input the data to encode
- * @param flags controls certain features of the encoded output.
- * Passing {@code DEFAULT} results in output that
- * adheres to RFC 2045.
- */
- public static byte[] encode(byte[] input, int flags) {
- return encode(input, 0, input.length, flags);
- }
-
- /**
- * Base64-encode the given data and return a newly allocated
- * byte[] with the result.
- *
- * @param input the data to encode
- * @param offset the position within the input array at which to
- * start
- * @param len the number of bytes of input to encode
- * @param flags controls certain features of the encoded output.
- * Passing {@code DEFAULT} results in output that
- * adheres to RFC 2045.
- */
- public static byte[] encode(byte[] input, int offset, int len, int flags) {
- EncoderState state = new EncoderState(flags, null);
-
- // Compute the exact length of the array we will produce.
- int output_len = len / 3 * 4;
-
- // Account for the tail of the data and the padding bytes, if any.
- if (state.do_padding) {
- if (len % 3 > 0) {
- output_len += 4;
- }
- } else {
- switch (len % 3) {
- case 0: break;
- case 1: output_len += 2; break;
- case 2: output_len += 3; break;
- }
- }
-
- // Account for the newlines, if any.
- if (state.do_newline && len > 0) {
- output_len += (((len-1) / (3 * LINE_GROUPS)) + 1) * (state.do_cr ? 2 : 1);
- }
-
- state.output = new byte[output_len];
- encodeInternal(input, offset, len, state, true);
-
- assert state.op == output_len;
-
- return state.output;
- }
-
- /* package */ static class EncoderState {
- public byte[] output;
- public int op;
-
- final public byte[] tail;
- public int tailLen;
- public int count;
-
- final public boolean do_padding;
- final public boolean do_newline;
- final public boolean do_cr;
- final public byte[] alphabet;
-
- public EncoderState(int flags, byte[] output) {
- this.output = output;
-
- do_padding = (flags & NO_PADDING) == 0;
- do_newline = (flags & NO_WRAP) == 0;
- do_cr = (flags & CRLF) != 0;
- alphabet = ((flags & WEB_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE;
-
- tail = new byte[2];
- tailLen = 0;
-
- count = do_newline ? LINE_GROUPS : -1;
- }
- }
-
- /**
- * Encode another block of input data.
- *
- * @param estate an EncoderState object whose (caller-provided)
- * output array is big enough to hold all the encoded data.
- * On return, estate.op will be set to the length of the
- * encoded data.
- * @param finish true if this is the final call to encodeInternal
- * with the given EncoderState object. Will finalize the
- * encoder state and include any final bytes in the output.
- */
- static void encodeInternal(byte[] input, int offset, int len,
- final EncoderState estate, boolean finish) {
- final boolean do_cr = estate.do_cr;
- final boolean do_newline = estate.do_newline;
- final boolean do_padding = estate.do_padding;
- final byte[] output = estate.output;
-
- int op = 0;
-
- int p = offset;
- len += offset;
- int v = -1;
- int count = estate.count;
-
- // First we need to concatenate the tail of the previous call
- // with any input bytes available now and see if we can empty
- // the tail.
-
- switch (estate.tailLen) {
- case 0:
- // There was no tail.
- break;
-
- case 1:
- if (p+2 <= len) {
- // A 1-byte tail with at least 2 bytes of
- // input available now.
- v = ((estate.tail[0] & 0xff) << 16) |
- ((input[p++] & 0xff) << 8) |
- (input[p++] & 0xff);
- estate.tailLen = 0;
- };
- break;
-
- case 2:
- if (p+1 <= len) {
- // A 2-byte tail with at least 1 byte of input.
- v = ((estate.tail[0] & 0xff) << 16) |
- ((estate.tail[1] & 0xff) << 8) |
- (input[p++] & 0xff);
- estate.tailLen = 0;
- }
- break;
- }
-
- if (v != -1) {
- output[op++] = estate.alphabet[(v >> 18) & 0x3f];
- output[op++] = estate.alphabet[(v >> 12) & 0x3f];
- output[op++] = estate.alphabet[(v >> 6) & 0x3f];
- output[op++] = estate.alphabet[v & 0x3f];
- if (--count == 0) {
- if (do_cr) output[op++] = '\r';
- output[op++] = '\n';
- count = LINE_GROUPS;
- }
- }
-
- // At this point either there is no tail, or there are fewer
- // than 3 bytes of input available.
-
- // The main loop, turning 3 input bytes into 4 output bytes on
- // each iteration.
- while (p+3 <= len) {
- v = ((input[p++] & 0xff) << 16) |
- ((input[p++] & 0xff) << 8) |
- (input[p++] & 0xff);
- output[op++] = estate.alphabet[(v >> 18) & 0x3f];
- output[op++] = estate.alphabet[(v >> 12) & 0x3f];
- output[op++] = estate.alphabet[(v >> 6) & 0x3f];
- output[op++] = estate.alphabet[v & 0x3f];
- if (--count == 0) {
- if (do_cr) output[op++] = '\r';
- output[op++] = '\n';
- count = LINE_GROUPS;
- }
- }
-
- if (finish) {
- // Finish up the tail of the input. Note that we need to
- // consume any bytes in estate.tail before any bytes
- // remaining in input; there should be at most two bytes
- // total.
-
- if (p-estate.tailLen == len-1) {
- int t = 0;
- v = ((estate.tailLen > 0 ? estate.tail[t++] : input[p++]) & 0xff) << 4;
- estate.tailLen -= t;
- output[op++] = estate.alphabet[(v >> 6) & 0x3f];
- output[op++] = estate.alphabet[v & 0x3f];
- if (do_padding) {
- output[op++] = '=';
- output[op++] = '=';
- }
- if (do_newline) {
- if (do_cr) output[op++] = '\r';
- output[op++] = '\n';
- }
- } else if (p-estate.tailLen == len-2) {
- int t = 0;
- v = (((estate.tailLen > 1 ? estate.tail[t++] : input[p++]) & 0xff) << 10) |
- (((estate.tailLen > 0 ? estate.tail[t++] : input[p++]) & 0xff) << 2);
- estate.tailLen -= t;
- output[op++] = estate.alphabet[(v >> 12) & 0x3f];
- output[op++] = estate.alphabet[(v >> 6) & 0x3f];
- output[op++] = estate.alphabet[v & 0x3f];
- if (do_padding) {
- output[op++] = '=';
- }
- if (do_newline) {
- if (do_cr) output[op++] = '\r';
- output[op++] = '\n';
- }
- } else if (do_newline && op > 0 && count != LINE_GROUPS) {
- if (do_cr) output[op++] = '\r';
- output[op++] = '\n';
- }
-
- assert estate.tailLen == 0;
- assert p == len;
- } else {
- // Save the leftovers in tail to be consumed on the next
- // call to encodeInternal.
-
- if (p == len-1) {
- estate.tail[estate.tailLen++] = input[p];
- } else if (p == len-2) {
- estate.tail[estate.tailLen++] = input[p];
- estate.tail[estate.tailLen++] = input[p+1];
- }
- }
-
- estate.op = op;
- estate.count = count;
- }
-
- private Base64() { } // don't instantiate
-}
diff --git a/common/java/com/android/common/Patterns.java b/common/java/com/android/common/Patterns.java
index 71c3a5e64a48..3b3b0387631e 100644
--- a/common/java/com/android/common/Patterns.java
+++ b/common/java/com/android/common/Patterns.java
@@ -24,12 +24,12 @@ import java.util.regex.Pattern;
*/
public class Patterns {
/**
- * Regular expression pattern to match all IANA top-level domains.
+ * Regular expression to match all IANA top-level domains.
* List accurate as of 2010/02/05. List taken from:
* http://data.iana.org/TLD/tlds-alpha-by-domain.txt
- * This pattern is auto-generated by development/tools/make-iana-tld-pattern.py
+ * This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
*/
- public static final Pattern TOP_LEVEL_DOMAIN = Pattern.compile(
+ public static final String TOP_LEVEL_DOMAIN_STR =
"((aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
+ "|(biz|b[abdefghijmnorstvwyz])"
+ "|(cat|com|coop|c[acdfghiklmnoruvxyz])"
@@ -55,20 +55,22 @@ public class Patterns {
+ "|w[fs]"
+ "|(xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-zckzah)"
+ "|y[etu]"
- + "|z[amw])");
+ + "|z[amw])";
+
+ /**
+ * Regular expression pattern to match all IANA top-level domains.
+ */
+ public static final Pattern TOP_LEVEL_DOMAIN =
+ Pattern.compile(TOP_LEVEL_DOMAIN_STR);
/**
- * Regular expression pattern to match RFC 1738 URLs
+ * Regular expression to match all IANA top-level domains for WEB_URL.
* List accurate as of 2010/02/05. List taken from:
* http://data.iana.org/TLD/tlds-alpha-by-domain.txt
- * This pattern is auto-generated by development/tools/make-iana-tld-pattern.py
+ * This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
*/
- public static final Pattern WEB_URL = Pattern.compile(
- "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
- + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
- + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
- + "((?:(?:[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}\\.)+" // named host
- + "(?:" // plus top level domain
+ public static final String TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL =
+ "(?:"
+ "(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
+ "|(?:biz|b[abdefghijmnorstvwyz])"
+ "|(?:cat|com|coop|c[acdfghiklmnoruvxyz])"
@@ -94,7 +96,28 @@ public class Patterns {
+ "|w[fs]"
+ "|(?:xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-zckzah)"
+ "|y[etu]"
- + "|z[amw]))"
+ + "|z[amw]))";
+
+ /**
+ * Good characters for Internationalized Resource Identifiers (IRI).
+ * This comprises most common used Unicode characters allowed in IRI
+ * as detailed in RFC 3987.
+ * Specifically, those two byte Unicode characters are not included.
+ */
+ public static final String GOOD_IRI_CHAR =
+ "a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
+
+ /**
+ * Regular expression pattern to match most part of RFC 3987
+ * Internationalized URLs, aka IRIs. Commonly used Unicode characters are
+ * added.
+ */
+ public static final Pattern WEB_URL = Pattern.compile(
+ "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+ + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
+ + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
+ + "((?:(?:[" + GOOD_IRI_CHAR + "][" + GOOD_IRI_CHAR + "\\-]{0,64}\\.)+" // named host
+ + TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL
+ "|(?:(?:25[0-5]|2[0-4]" // or ip address
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]"
+ "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]"
@@ -116,7 +139,7 @@ public class Patterns {
public static final Pattern DOMAIN_NAME
= Pattern.compile(
- "(((([a-zA-Z0-9][a-zA-Z0-9\\-]*)*[a-zA-Z0-9]\\.)+"
+ "(((([" + GOOD_IRI_CHAR + "][" + GOOD_IRI_CHAR + "\\-]*)*[" + GOOD_IRI_CHAR + "]\\.)+"
+ TOP_LEVEL_DOMAIN + ")|"
+ IP_ADDRESS + ")");
diff --git a/common/java/com/android/common/speech/Recognition.java b/common/java/com/android/common/speech/Recognition.java
new file mode 100644
index 000000000000..6f164a93fc5e
--- /dev/null
+++ b/common/java/com/android/common/speech/Recognition.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.common.speech;
+
+/**
+ * Utilities for voice recognition implementations.
+ *
+ * @see android.app.RecognitionService
+ */
+public class Recognition {
+
+ /**
+ * The extra key used in an intent to the speech recognizer for voice search. Not
+ * generally to be used by developers. The system search dialog uses this, for example,
+ * to set a calling package for identification by a voice search API. If this extra
+ * is set by anyone but the system process, it should be overridden by the voice search
+ * implementation.
+ */
+ public final static String EXTRA_CALLING_PACKAGE = "calling_package";
+
+ private Recognition() { } // don't instantiate
+}
diff --git a/common/java/com/android/common/ui/PointerLocationView.java b/common/java/com/android/common/ui/PointerLocationView.java
new file mode 100644
index 000000000000..7bdb0bced1c4
--- /dev/null
+++ b/common/java/com/android/common/ui/PointerLocationView.java
@@ -0,0 +1,337 @@
+package com.android.common.ui;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Paint.FontMetricsInt;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+
+import java.util.ArrayList;
+
+public class PointerLocationView extends View {
+ public static class PointerState {
+ private final ArrayList<Float> mXs = new ArrayList<Float>();
+ private final ArrayList<Float> mYs = new ArrayList<Float>();
+ private boolean mCurDown;
+ private int mCurX;
+ private int mCurY;
+ private float mCurPressure;
+ private float mCurSize;
+ private int mCurWidth;
+ private VelocityTracker mVelocity;
+ }
+
+ private final ViewConfiguration mVC;
+ private final Paint mTextPaint;
+ private final Paint mTextBackgroundPaint;
+ private final Paint mTextLevelPaint;
+ private final Paint mPaint;
+ private final Paint mTargetPaint;
+ private final Paint mPathPaint;
+ private final FontMetricsInt mTextMetrics = new FontMetricsInt();
+ private int mHeaderBottom;
+ private boolean mCurDown;
+ private int mCurNumPointers;
+ private int mMaxNumPointers;
+ private final ArrayList<PointerState> mPointers
+ = new ArrayList<PointerState>();
+
+ private boolean mPrintCoords = true;
+
+ public PointerLocationView(Context c) {
+ super(c);
+ mVC = ViewConfiguration.get(c);
+ mTextPaint = new Paint();
+ mTextPaint.setAntiAlias(true);
+ mTextPaint.setTextSize(10
+ * getResources().getDisplayMetrics().density);
+ mTextPaint.setARGB(255, 0, 0, 0);
+ mTextBackgroundPaint = new Paint();
+ mTextBackgroundPaint.setAntiAlias(false);
+ mTextBackgroundPaint.setARGB(128, 255, 255, 255);
+ mTextLevelPaint = new Paint();
+ mTextLevelPaint.setAntiAlias(false);
+ mTextLevelPaint.setARGB(192, 255, 0, 0);
+ mPaint = new Paint();
+ mPaint.setAntiAlias(true);
+ mPaint.setARGB(255, 255, 255, 255);
+ mPaint.setStyle(Paint.Style.STROKE);
+ mPaint.setStrokeWidth(2);
+ mTargetPaint = new Paint();
+ mTargetPaint.setAntiAlias(false);
+ mTargetPaint.setARGB(255, 0, 0, 192);
+ mPathPaint = new Paint();
+ mPathPaint.setAntiAlias(false);
+ mPathPaint.setARGB(255, 0, 96, 255);
+ mPaint.setStyle(Paint.Style.STROKE);
+ mPaint.setStrokeWidth(1);
+
+ PointerState ps = new PointerState();
+ ps.mVelocity = VelocityTracker.obtain();
+ mPointers.add(ps);
+ }
+
+ public void setPrintCoords(boolean state) {
+ mPrintCoords = state;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ mTextPaint.getFontMetricsInt(mTextMetrics);
+ mHeaderBottom = -mTextMetrics.ascent+mTextMetrics.descent+2;
+ if (false) {
+ Log.i("foo", "Metrics: ascent=" + mTextMetrics.ascent
+ + " descent=" + mTextMetrics.descent
+ + " leading=" + mTextMetrics.leading
+ + " top=" + mTextMetrics.top
+ + " bottom=" + mTextMetrics.bottom);
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ synchronized (mPointers) {
+ final int w = getWidth();
+ final int itemW = w/7;
+ final int base = -mTextMetrics.ascent+1;
+ final int bottom = mHeaderBottom;
+
+ final int NP = mPointers.size();
+
+ if (NP > 0) {
+ final PointerState ps = mPointers.get(0);
+ canvas.drawRect(0, 0, itemW-1, bottom,mTextBackgroundPaint);
+ canvas.drawText("P: " + mCurNumPointers + " / " + mMaxNumPointers,
+ 1, base, mTextPaint);
+
+ final int N = ps.mXs.size();
+ if ((mCurDown && ps.mCurDown) || N == 0) {
+ canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom, mTextBackgroundPaint);
+ canvas.drawText("X: " + ps.mCurX, 1 + itemW, base, mTextPaint);
+ canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom, mTextBackgroundPaint);
+ canvas.drawText("Y: " + ps.mCurY, 1 + itemW * 2, base, mTextPaint);
+ } else {
+ float dx = ps.mXs.get(N-1) - ps.mXs.get(0);
+ float dy = ps.mYs.get(N-1) - ps.mYs.get(0);
+ canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom,
+ Math.abs(dx) < mVC.getScaledTouchSlop()
+ ? mTextBackgroundPaint : mTextLevelPaint);
+ canvas.drawText("dX: " + String.format("%.1f", dx), 1 + itemW, base, mTextPaint);
+ canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom,
+ Math.abs(dy) < mVC.getScaledTouchSlop()
+ ? mTextBackgroundPaint : mTextLevelPaint);
+ canvas.drawText("dY: " + String.format("%.1f", dy), 1 + itemW * 2, base, mTextPaint);
+ }
+
+ canvas.drawRect(itemW * 3, 0, (itemW * 4) - 1, bottom, mTextBackgroundPaint);
+ int velocity = ps.mVelocity == null ? 0 : (int) (ps.mVelocity.getXVelocity() * 1000);
+ canvas.drawText("Xv: " + velocity, 1 + itemW * 3, base, mTextPaint);
+
+ canvas.drawRect(itemW * 4, 0, (itemW * 5) - 1, bottom, mTextBackgroundPaint);
+ velocity = ps.mVelocity == null ? 0 : (int) (ps.mVelocity.getYVelocity() * 1000);
+ canvas.drawText("Yv: " + velocity, 1 + itemW * 4, base, mTextPaint);
+
+ canvas.drawRect(itemW * 5, 0, (itemW * 6) - 1, bottom, mTextBackgroundPaint);
+ canvas.drawRect(itemW * 5, 0, (itemW * 5) + (ps.mCurPressure * itemW) - 1,
+ bottom, mTextLevelPaint);
+ canvas.drawText("Prs: " + String.format("%.2f", ps.mCurPressure), 1 + itemW * 5,
+ base, mTextPaint);
+
+ canvas.drawRect(itemW * 6, 0, w, bottom, mTextBackgroundPaint);
+ canvas.drawRect(itemW * 6, 0, (itemW * 6) + (ps.mCurSize * itemW) - 1,
+ bottom, mTextLevelPaint);
+ canvas.drawText("Size: " + String.format("%.2f", ps.mCurSize), 1 + itemW * 6,
+ base, mTextPaint);
+ }
+
+ for (int p=0; p<NP; p++) {
+ final PointerState ps = mPointers.get(p);
+
+ if (mCurDown && ps.mCurDown) {
+ canvas.drawLine(0, (int)ps.mCurY, getWidth(), (int)ps.mCurY, mTargetPaint);
+ canvas.drawLine((int)ps.mCurX, 0, (int)ps.mCurX, getHeight(), mTargetPaint);
+ int pressureLevel = (int)(ps.mCurPressure*255);
+ mPaint.setARGB(255, pressureLevel, 128, 255-pressureLevel);
+ canvas.drawPoint(ps.mCurX, ps.mCurY, mPaint);
+ canvas.drawCircle(ps.mCurX, ps.mCurY, ps.mCurWidth, mPaint);
+ }
+ }
+
+ for (int p=0; p<NP; p++) {
+ final PointerState ps = mPointers.get(p);
+
+ final int N = ps.mXs.size();
+ float lastX=0, lastY=0;
+ boolean haveLast = false;
+ boolean drawn = false;
+ mPaint.setARGB(255, 128, 255, 255);
+ for (int i=0; i<N; i++) {
+ float x = ps.mXs.get(i);
+ float y = ps.mYs.get(i);
+ if (Float.isNaN(x)) {
+ haveLast = false;
+ continue;
+ }
+ if (haveLast) {
+ canvas.drawLine(lastX, lastY, x, y, mPathPaint);
+ canvas.drawPoint(lastX, lastY, mPaint);
+ drawn = true;
+ }
+ lastX = x;
+ lastY = y;
+ haveLast = true;
+ }
+
+ if (drawn) {
+ if (ps.mVelocity != null) {
+ mPaint.setARGB(255, 255, 64, 128);
+ float xVel = ps.mVelocity.getXVelocity() * (1000/60);
+ float yVel = ps.mVelocity.getYVelocity() * (1000/60);
+ canvas.drawLine(lastX, lastY, lastX+xVel, lastY+yVel, mPaint);
+ } else {
+ canvas.drawPoint(lastX, lastY, mPaint);
+ }
+ }
+ }
+ }
+ }
+
+ public void addTouchEvent(MotionEvent event) {
+ synchronized (mPointers) {
+ int action = event.getAction();
+
+ //Log.i("Pointer", "Motion: action=0x" + Integer.toHexString(action)
+ // + " pointers=" + event.getPointerCount());
+
+ int NP = mPointers.size();
+
+ //mRect.set(0, 0, getWidth(), mHeaderBottom+1);
+ //invalidate(mRect);
+ //if (mCurDown) {
+ // mRect.set(mCurX-mCurWidth-3, mCurY-mCurWidth-3,
+ // mCurX+mCurWidth+3, mCurY+mCurWidth+3);
+ //} else {
+ // mRect.setEmpty();
+ //}
+ if (action == MotionEvent.ACTION_DOWN) {
+ for (int p=0; p<NP; p++) {
+ final PointerState ps = mPointers.get(p);
+ ps.mXs.clear();
+ ps.mYs.clear();
+ ps.mVelocity = VelocityTracker.obtain();
+ ps.mCurDown = false;
+ }
+ mPointers.get(0).mCurDown = true;
+ mMaxNumPointers = 0;
+ if (mPrintCoords) {
+ Log.i("Pointer", "Pointer 1: DOWN");
+ }
+ }
+
+ if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
+ final int index = (action&MotionEvent.ACTION_POINTER_INDEX_MASK)
+ >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int id = event.getPointerId(index);
+ while (NP <= id) {
+ PointerState ps = new PointerState();
+ ps.mVelocity = VelocityTracker.obtain();
+ mPointers.add(ps);
+ NP++;
+ }
+ final PointerState ps = mPointers.get(id);
+ ps.mVelocity = VelocityTracker.obtain();
+ ps.mCurDown = true;
+ if (mPrintCoords) {
+ Log.i("Pointer", "Pointer " + (id+1) + ": DOWN");
+ }
+ }
+
+ final int NI = event.getPointerCount();
+
+ mCurDown = action != MotionEvent.ACTION_UP
+ && action != MotionEvent.ACTION_CANCEL;
+ mCurNumPointers = mCurDown ? NI : 0;
+ if (mMaxNumPointers < mCurNumPointers) {
+ mMaxNumPointers = mCurNumPointers;
+ }
+
+ for (int i=0; i<NI; i++) {
+ final int id = event.getPointerId(i);
+ final PointerState ps = mPointers.get(id);
+ ps.mVelocity.addMovement(event);
+ ps.mVelocity.computeCurrentVelocity(1);
+ final int N = event.getHistorySize();
+ for (int j=0; j<N; j++) {
+ if (mPrintCoords) {
+ Log.i("Pointer", "Pointer " + (id+1) + ": ("
+ + event.getHistoricalX(i, j)
+ + ", " + event.getHistoricalY(i, j) + ")"
+ + " Prs=" + event.getHistoricalPressure(i, j)
+ + " Size=" + event.getHistoricalSize(i, j));
+ }
+ ps.mXs.add(event.getHistoricalX(i, j));
+ ps.mYs.add(event.getHistoricalY(i, j));
+ }
+ if (mPrintCoords) {
+ Log.i("Pointer", "Pointer " + (id+1) + ": ("
+ + event.getX(i) + ", " + event.getY(i) + ")"
+ + " Prs=" + event.getPressure(i)
+ + " Size=" + event.getSize(i));
+ }
+ ps.mXs.add(event.getX(i));
+ ps.mYs.add(event.getY(i));
+ ps.mCurX = (int)event.getX(i);
+ ps.mCurY = (int)event.getY(i);
+ //Log.i("Pointer", "Pointer #" + p + ": (" + ps.mCurX
+ // + "," + ps.mCurY + ")");
+ ps.mCurPressure = event.getPressure(i);
+ ps.mCurSize = event.getSize(i);
+ ps.mCurWidth = (int)(ps.mCurSize*(getWidth()/3));
+ }
+
+ if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
+ final int index = (action&MotionEvent.ACTION_POINTER_INDEX_MASK)
+ >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int id = event.getPointerId(index);
+ final PointerState ps = mPointers.get(id);
+ ps.mXs.add(Float.NaN);
+ ps.mYs.add(Float.NaN);
+ ps.mCurDown = false;
+ if (mPrintCoords) {
+ Log.i("Pointer", "Pointer " + (id+1) + ": UP");
+ }
+ }
+
+ if (action == MotionEvent.ACTION_UP) {
+ for (int i=0; i<NI; i++) {
+ final int id = event.getPointerId(i);
+ final PointerState ps = mPointers.get(id);
+ if (ps.mCurDown) {
+ ps.mCurDown = false;
+ if (mPrintCoords) {
+ Log.i("Pointer", "Pointer " + (id+1) + ": UP");
+ }
+ }
+ }
+ }
+
+ //if (mCurDown) {
+ // mRect.union(mCurX-mCurWidth-3, mCurY-mCurWidth-3,
+ // mCurX+mCurWidth+3, mCurY+mCurWidth+3);
+ //}
+ //invalidate(mRect);
+ postInvalidate();
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ addTouchEvent(event);
+ return true;
+ }
+}
diff --git a/common/tests/src/com/android/common/PatternsTest.java b/common/tests/src/com/android/common/PatternsTest.java
index 635601ea0297..9e2ad588bdfe 100644
--- a/common/tests/src/com/android/common/PatternsTest.java
+++ b/common/tests/src/com/android/common/PatternsTest.java
@@ -68,6 +68,12 @@ public class PatternsTest extends TestCase {
t = Patterns.WEB_URL.matcher("xn--fsqu00a.xn--0zwm56d").matches();
assertTrue("Valid URL", t);
+ // Internationalized URL.
+ t = Patterns.WEB_URL.matcher("http://\uD604\uAE08\uC601\uC218\uC99D.kr").matches();
+ assertTrue("Valid URL", t);
+ t = Patterns.WEB_URL.matcher("\uD604\uAE08\uC601\uC218\uC99D.kr").matches();
+ assertTrue("Valid URL", t);
+
t = Patterns.WEB_URL.matcher("ftp://www.example.com").matches();
assertFalse("Matched invalid protocol", t);
@@ -99,6 +105,13 @@ public class PatternsTest extends TestCase {
t = Patterns.DOMAIN_NAME.matcher("mail.example.com").matches();
assertTrue("Valid domain", t);
+ t = Patterns.WEB_URL.matcher("google.me").matches();
+ assertTrue("Valid domain", t);
+
+ // Internationalized domains.
+ t = Patterns.DOMAIN_NAME.matcher("\uD604\uAE08\uC601\uC218\uC99D.kr").matches();
+ assertTrue("Valid domain", t);
+
t = Patterns.DOMAIN_NAME.matcher("__+&42.xer").matches();
assertFalse("Invalid domain", t);
}
diff --git a/common/tools/make-iana-tld-pattern.py b/common/tools/make-iana-tld-pattern.py
index ece4dcfea17e..de81c587566a 100755
--- a/common/tools/make-iana-tld-pattern.py
+++ b/common/tools/make-iana-tld-pattern.py
@@ -4,43 +4,27 @@ from urllib2 import urlopen
TLD_PREFIX = r"""
/**
- * Regular expression pattern to match all IANA top-level domains.
+ * Regular expression to match all IANA top-level domains.
* List accurate as of 2010/02/05. List taken from:
* http://data.iana.org/TLD/tlds-alpha-by-domain.txt
* This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
*/
- public static final Pattern TOP_LEVEL_DOMAIN = Pattern.compile(
+ public static final String TOP_LEVEL_DOMAIN_STR =
"""
-TLD_SUFFIX = '");'
+TLD_SUFFIX = '";'
URL_PREFIX = r"""
/**
- * Regular expression pattern to match RFC 1738 URLs
+ * Regular expression to match all IANA top-level domains for WEB_URL.
* List accurate as of 2010/02/05. List taken from:
* http://data.iana.org/TLD/tlds-alpha-by-domain.txt
- * This pattern is auto-generated by frameworkds/base/common/tools/make-iana-tld-pattern.py
+ * This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
*/
- public static final Pattern WEB_URL = Pattern.compile(
- "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
- + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
- + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
- + "((?:(?:[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}\\.)+" // named host
- + "(?:" // plus top level domain
+ public static final String TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL =
+ "(?:"
"""
-URL_SUFFIX = r"""
- + "|(?:(?:25[0-5]|2[0-4]" // or ip address
- + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]"
- + "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]"
- + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
- + "|[1-9][0-9]|[0-9])))"
- + "(?:\\:\\d{1,5})?)" // plus option port number
- + "(\\/(?:(?:[a-zA-Z0-9\\;\\/\\?\\:\\@\\&\\=\\#\\~" // plus option query params
- + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
- + "(?:\\b|$)"); // and finally, a word boundary or end of
- // input. This is to stop foo.sure from
- // matching as foo.su
-"""
+URL_SUFFIX = ';'
class Bucket:
def __init__(self, baseLetter):
diff --git a/core/java/android/app/BackupAgent.java b/core/java/android/app/BackupAgent.java
index 35b6fed71014..a2bfc76863f6 100644
--- a/core/java/android/app/BackupAgent.java
+++ b/core/java/android/app/BackupAgent.java
@@ -33,8 +33,8 @@ import java.io.IOException;
/**
* This is the central interface between an application and Android's
* settings backup mechanism.
- *
- * @hide pending API solidification
+ *
+ * <p>STOPSHIP write more documentation about the backup process here.
*/
public abstract class BackupAgent extends ContextWrapper {
private static final String TAG = "BackupAgent";
@@ -62,9 +62,9 @@ public abstract class BackupAgent extends ContextWrapper {
* state provided by the application. May be null, in which
* case no prior state is being provided and the application should
* perform a full backup.
- * @param data An open, read/write ParcelFileDescriptor pointing to the backup data
- * destination. Typically the application will use backup helper
- * classes to write to this file.
+ * @param data A structured wrapper around an open, read/write ParcelFileDescriptor
+ * pointing to the backup data destination. Typically the application will use
+ * backup helper classes to write to this file.
* @param newState An open, read/write ParcelFileDescriptor pointing to an empty
* file. The application should record the final backup state
* here after writing the requested data to dataFd.
@@ -77,10 +77,18 @@ public abstract class BackupAgent extends ContextWrapper {
* existing data with the contents of the backup. The backup data is
* provided in the file pointed to by the dataFd file descriptor. Once
* the restore is finished, the application should write a representation
- * of the final state to the newStateFd file descriptor,
+ * of the final state to the newStateFd file descriptor,
+ *
+ * <p>The application is responsible for properly erasing its old data and
+ * replacing it with the data supplied to this method. No "clear user data"
+ * operation will be performed automatically by the operating system. The
+ * exception to this is in the case of a failed restore attempt: if onRestore()
+ * throws an exception, the OS will assume that the application's data may now
+ * be in an incoherent state, and will clear it before proceeding.
*
- * @param data An open, read-only ParcelFileDescriptor pointing to a full snapshot
- * of the application's data.
+ * @param data A structured wrapper around an open, read-only ParcelFileDescriptor
+ * pointing to a full snapshot of the application's data. Typically the
+ * application will use helper classes to read this data.
* @param appVersionCode The android:versionCode value of the application that backed
* up this particular data set. This makes it easier for an application's
* agent to distinguish among several possible older data versions when
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index b4fe6986360c..db6a4bf1405e 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2659,102 +2659,6 @@ class ContextImpl extends Context {
return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
}
- // Constants related to app heuristics
- // No-installation limit for internal flash: 10% or less space available
- private static final double LOW_NAND_FLASH_TRESHOLD = 0.1;
-
- // SD-to-internal app size threshold: currently set to 1 MB
- private static final long INSTALL_ON_SD_THRESHOLD = (1024 * 1024);
-
- public int recommendAppInstallLocation(Package pkg) {
- // Initial implementation:
- // Package size = code size + cache size + data size
- // If code size > 1 MB, install on SD card.
- // Else install on internal NAND flash, unless space on NAND is less than 10%
-
- if (pkg == null) {
- return INSTALL_PARSE_FAILED_NOT_APK;
- }
-
- StatFs internalFlashStats = new StatFs(Environment.getDataDirectory().getPath());
- StatFs sdcardStats = new StatFs(Environment.getExternalStorageDirectory().getPath());
-
- long totalInternalFlashSize = (long)internalFlashStats.getBlockCount() *
- (long)internalFlashStats.getBlockSize();
- long availInternalFlashSize = (long)internalFlashStats.getAvailableBlocks() *
- (long)internalFlashStats.getBlockSize();
- long availSDSize = (long)sdcardStats.getAvailableBlocks() *
- (long)sdcardStats.getBlockSize();
-
- double pctNandFree = (double)availInternalFlashSize / (double)totalInternalFlashSize;
-
- final String archiveFilePath = pkg.mScanPath;
- File apkFile = new File(archiveFilePath);
- long pkgLen = apkFile.length();
-
- boolean auto = true;
- // To make final copy
- long reqInstallSize = pkgLen;
- // For dex files
- long reqInternalSize = 1 * pkgLen;
- boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD);
- boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalFlashSize);
- boolean fitsOnSd = (reqInstallSize < availSDSize) && intThresholdOk &&
- (reqInternalSize < availInternalFlashSize);
- boolean fitsOnInt = intThresholdOk && intAvailOk;
-
- // Consider application flags preferences as well...
- boolean installOnlyOnSd = (pkg.installLocation ==
- PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
- boolean installOnlyInternal = (pkg.installLocation ==
- PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
- if (installOnlyInternal) {
- // If set explicitly in manifest,
- // let that override everything else
- auto = false;
- } else if (installOnlyOnSd){
- // Check if this can be accommodated on the sdcard
- if (fitsOnSd) {
- auto = false;
- }
- } else {
- // Check if user option is enabled
- boolean setInstallLoc = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.SET_INSTALL_LOCATION, 0) != 0;
- if (setInstallLoc) {
- // Pick user preference
- int installPreference = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.DEFAULT_INSTALL_LOCATION,
- PackageInfo.INSTALL_LOCATION_AUTO);
- if (installPreference == 1) {
- installOnlyInternal = true;
- auto = false;
- } else if (installPreference == 2) {
- installOnlyOnSd = true;
- auto = false;
- }
- }
- }
- if (!auto) {
- if (installOnlyOnSd) {
- return fitsOnSd ? INSTALL_ON_SDCARD : INSTALL_FAILED_INSUFFICIENT_STORAGE;
- } else if (installOnlyInternal){
- // Check on internal flash
- return fitsOnInt ? INSTALL_ON_INTERNAL_FLASH : INSTALL_FAILED_INSUFFICIENT_STORAGE;
- }
- }
- // Try to install internally
- if (fitsOnInt) {
- return INSTALL_ON_INTERNAL_FLASH;
- }
- // Try the sdcard now.
- if (fitsOnSd) {
- return INSTALL_ON_SDCARD;
- }
- // Return error code
- return INSTALL_FAILED_INSUFFICIENT_STORAGE;
- }
-
private final ContextImpl mContext;
private final IPackageManager mPM;
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 63e95c0aa8f5..e4c1ba6e851f 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -68,6 +68,7 @@ import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import com.android.common.Patterns;
+import com.android.common.speech.Recognition;
import java.util.ArrayList;
import java.util.WeakHashMap;
@@ -94,9 +95,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
private static final String INSTANCE_KEY_PREVIOUS_COMPONENTS = "sPrev";
private static final String INSTANCE_KEY_USER_QUERY = "uQry";
- // The extra key used in an intent to the speech recognizer for in-app voice search.
- private static final String EXTRA_CALLING_PACKAGE = "calling_package";
-
// The string used for privateImeOptions to identify to the IME that it should not show
// a microphone button since one already exists in the search dialog.
private static final String IME_OPTION_NO_MICROPHONE = "nm";
@@ -948,7 +946,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, prompt);
voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, language);
voiceIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, maxResults);
- voiceIntent.putExtra(EXTRA_CALLING_PACKAGE,
+ voiceIntent.putExtra(Recognition.EXTRA_CALLING_PACKAGE,
searchActivity == null ? null : searchActivity.toShortString());
// Add the values that configure forwarding the results
diff --git a/core/java/android/backup/AbsoluteFileBackupHelper.java b/core/java/android/backup/AbsoluteFileBackupHelper.java
index 1dbccc9c47af..6bf848f555dd 100644
--- a/core/java/android/backup/AbsoluteFileBackupHelper.java
+++ b/core/java/android/backup/AbsoluteFileBackupHelper.java
@@ -27,7 +27,7 @@ import java.io.FileDescriptor;
* Like FileBackupHelper, but takes absolute paths for the files instead of
* subpaths of getFilesDir()
*
- * @hide
+ * STOPSHIP: document!
*/
public class AbsoluteFileBackupHelper extends FileBackupHelperBase implements BackupHelper {
private static final String TAG = "AbsoluteFileBackupHelper";
@@ -36,6 +36,13 @@ public class AbsoluteFileBackupHelper extends FileBackupHelperBase implements Ba
Context mContext;
String[] mFiles;
+ /**
+ * Construct a helper for backing up / restoring the files at the given absolute locations
+ * within the file system.
+ *
+ * @param context
+ * @param files
+ */
public AbsoluteFileBackupHelper(Context context, String... files) {
super(context);
@@ -54,6 +61,9 @@ public class AbsoluteFileBackupHelper extends FileBackupHelperBase implements Ba
performBackup_checked(oldState, data, newState, mFiles, mFiles);
}
+ /**
+ * Restore one absolute file entity from the restore stream
+ */
public void restoreEntity(BackupDataInputStream data) {
if (DEBUG) Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size());
String key = data.getKey();
diff --git a/core/java/android/backup/BackupDataInput.java b/core/java/android/backup/BackupDataInput.java
index e67b0bee7677..67d51eaee684 100644
--- a/core/java/android/backup/BackupDataInput.java
+++ b/core/java/android/backup/BackupDataInput.java
@@ -21,7 +21,9 @@ import android.content.Context;
import java.io.FileDescriptor;
import java.io.IOException;
-/** @hide */
+/**
+ * STOPSHIP: document!
+ */
public class BackupDataInput {
int mBackupReader;
@@ -33,6 +35,7 @@ public class BackupDataInput {
int dataSize;
}
+ /** @hide */
public BackupDataInput(FileDescriptor fd) {
if (fd == null) throw new NullPointerException();
mBackupReader = ctor(fd);
@@ -41,6 +44,7 @@ public class BackupDataInput {
}
}
+ /** @hide */
protected void finalize() throws Throwable {
try {
dtor(mBackupReader);
@@ -49,6 +53,13 @@ public class BackupDataInput {
}
}
+ /**
+ * Consumes the next header from the restore stream.
+ *
+ * @return true when there is an entity ready for consumption from the restore stream,
+ * false if the restore stream has been fully consumed.
+ * @throws IOException if an error occurred while reading the restore stream
+ */
public boolean readNextHeader() throws IOException {
int result = readNextHeader_native(mBackupReader, mHeader);
if (result == 0) {
@@ -66,6 +77,11 @@ public class BackupDataInput {
}
}
+ /**
+ * Report the key associated with the current record in the restore stream
+ * @return the current record's key string
+ * @throws IllegalStateException if the next record header has not yet been read
+ */
public String getKey() {
if (mHeaderReady) {
return mHeader.key;
@@ -74,6 +90,13 @@ public class BackupDataInput {
}
}
+ /**
+ * Report the size in bytes of the data associated with the current record in the
+ * restore stream.
+ *
+ * @return The size of the record's raw data, in bytes
+ * @throws IllegalStateException if the next record header has not yet been read
+ */
public int getDataSize() {
if (mHeaderReady) {
return mHeader.dataSize;
@@ -82,6 +105,19 @@ public class BackupDataInput {
}
}
+ /**
+ * Read a record's raw data from the restore stream. The record's header must first
+ * have been processed by the {@link #readNextHeader()} method. Multiple calls to
+ * this method may be made in order to process the data in chunks; not all of it
+ * must be read in a single call.
+ *
+ * @param data An allocated byte array of at least 'size' bytes
+ * @param offset Offset within the 'data' array at which the data will be placed
+ * when read from the stream.
+ * @param size The number of bytes to read in this pass.
+ * @return The number of bytes of data read
+ * @throws IOException if an error occurred when trying to read the restore data stream
+ */
public int readEntityData(byte[] data, int offset, int size) throws IOException {
if (mHeaderReady) {
int result = readEntityData_native(mBackupReader, data, offset, size);
@@ -95,6 +131,14 @@ public class BackupDataInput {
}
}
+ /**
+ * Consume the current record's data without actually reading it into a buffer
+ * for further processing. This allows a {@link android.backup.BackupAgent} to
+ * efficiently discard obsolete or otherwise uninteresting records during the
+ * restore operation.
+ *
+ * @throws IOException if an error occurred when trying to read the restore data stream
+ */
public void skipEntityData() throws IOException {
if (mHeaderReady) {
skipEntityData_native(mBackupReader);
diff --git a/core/java/android/backup/BackupDataInputStream.java b/core/java/android/backup/BackupDataInputStream.java
index b705c4c36022..503b3c1ba646 100644
--- a/core/java/android/backup/BackupDataInputStream.java
+++ b/core/java/android/backup/BackupDataInputStream.java
@@ -16,12 +16,11 @@
package android.backup;
-import android.util.Log;
-
import java.io.InputStream;
import java.io.IOException;
-/** @hide */
+/**
+ * STOPSHIP: document */
public class BackupDataInputStream extends InputStream {
String key;
@@ -30,6 +29,7 @@ public class BackupDataInputStream extends InputStream {
BackupDataInput mData;
byte[] mOneByte;
+ /** @hide */
BackupDataInputStream(BackupDataInput data) {
mData = data;
}
diff --git a/core/java/android/backup/BackupDataOutput.java b/core/java/android/backup/BackupDataOutput.java
index d29c5ba02f14..672d01f895cd 100644
--- a/core/java/android/backup/BackupDataOutput.java
+++ b/core/java/android/backup/BackupDataOutput.java
@@ -21,13 +21,16 @@ import android.content.Context;
import java.io.FileDescriptor;
import java.io.IOException;
-/** @hide */
+/**
+ * STOPSHIP: document
+ */
public class BackupDataOutput {
int mBackupWriter;
public static final int OP_UPDATE = 1;
public static final int OP_DELETE = 2;
+ /** @hide */
public BackupDataOutput(FileDescriptor fd) {
if (fd == null) throw new NullPointerException();
mBackupWriter = ctor(fd);
@@ -36,7 +39,15 @@ public class BackupDataOutput {
}
}
- // A dataSize of -1 indicates that the record under this key should be deleted
+ /**
+ * Mark the beginning of one record in the backup data stream.
+ *
+ * @param key
+ * @param dataSize The size in bytes of this record's data. Passing a dataSize
+ * of -1 indicates that the record under this key should be deleted.
+ * @return The number of bytes written to the backup stream
+ * @throws IOException if the write failed
+ */
public int writeEntityHeader(String key, int dataSize) throws IOException {
int result = writeEntityHeader_native(mBackupWriter, key, dataSize);
if (result >= 0) {
@@ -46,6 +57,13 @@ public class BackupDataOutput {
}
}
+ /**
+ * Write a chunk of data under the current entity to the backup transport.
+ * @param data A raw data buffer to send
+ * @param size The number of bytes to be sent in this chunk
+ * @return the number of bytes written
+ * @throws IOException if the write failed
+ */
public int writeEntityData(byte[] data, int size) throws IOException {
int result = writeEntityData_native(mBackupWriter, data, size);
if (result >= 0) {
@@ -59,6 +77,7 @@ public class BackupDataOutput {
setKeyPrefix_native(mBackupWriter, keyPrefix);
}
+ /** @hide */
protected void finalize() throws Throwable {
try {
dtor(mBackupWriter);
diff --git a/core/java/android/backup/BackupHelper.java b/core/java/android/backup/BackupHelper.java
index 3983e28cce39..fc48cf25721b 100644
--- a/core/java/android/backup/BackupHelper.java
+++ b/core/java/android/backup/BackupHelper.java
@@ -20,7 +20,9 @@ import android.os.ParcelFileDescriptor;
import java.io.InputStream;
-/** @hide */
+/**
+ * STOPSHIP: document!
+ */
public interface BackupHelper {
/**
* Based on oldState, determine which of the files from the application's data directory
@@ -31,16 +33,18 @@ public interface BackupHelper {
ParcelFileDescriptor newState);
/**
- * Called by BackupHelperDispatcher to dispatch one entity of data.
+ * Called by BackupHelperAgent to restore one entity from the restore dataset.
* <p class=note>
* Do not close the <code>data</code> stream. Do not read more than
- * <code>dataSize</code> bytes from <code>data</code>.
+ * <code>data.size()</code> bytes from <code>data</code>.
*/
public void restoreEntity(BackupDataInputStream data);
/**
- *
+ * Called by BackupHelperAgent to write the new backup state file corresponding to
+ * the current state of the app's data at the time the backup operation was
+ * performed.
*/
- public void writeRestoreSnapshot(ParcelFileDescriptor fd);
+ public void writeNewStateDescription(ParcelFileDescriptor fd);
}
diff --git a/core/java/android/backup/BackupHelperAgent.java b/core/java/android/backup/BackupHelperAgent.java
index 5d0c4a2514db..dc17154fac62 100644
--- a/core/java/android/backup/BackupHelperAgent.java
+++ b/core/java/android/backup/BackupHelperAgent.java
@@ -26,28 +26,54 @@ import android.util.Log;
import java.io.IOException;
-/** @hide */
+/**
+ * A convenient BackupAgent wrapper class that automatically manages heterogeneous
+ * data sets within the backup data, each identified by a unique key prefix. An
+ * application will typically extend this class in their own backup agent. Then,
+ * within the agent's onBackup() and onRestore() methods, it will call
+ * {@link #addHelper(String, BackupHelper)} one or more times to specify the data
+ * sets, then invoke super.onBackup() or super.onRestore() to have the BackupHelperAgent
+ * implementation process the data.
+ *
+ * STOPSHIP: document!
+ */
public class BackupHelperAgent extends BackupAgent {
static final String TAG = "BackupHelperAgent";
BackupHelperDispatcher mDispatcher = new BackupHelperDispatcher();
+ /**
+ * Run the backup process on each of the configured handlers.
+ */
@Override
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
ParcelFileDescriptor newState) throws IOException {
mDispatcher.performBackup(oldState, data, newState);
}
+ /**
+ * Run the restore process on each of the configured handlers.
+ */
@Override
public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
throws IOException {
mDispatcher.performRestore(data, appVersionCode, newState);
}
+ /** @hide */
public BackupHelperDispatcher getDispatcher() {
return mDispatcher;
}
+ /**
+ * Add a helper for a given data subset to the agent's configuration. Each helper
+ * must have a prefix string that is unique within this backup agent's set of
+ * helpers.
+ *
+ * @param keyPrefix A string used to disambiguate the various helpers within this agent
+ * @param helper A backup/restore helper object to be invoked during backup and restore
+ * operations.
+ */
public void addHelper(String keyPrefix, BackupHelper helper) {
mDispatcher.addHelper(keyPrefix, helper);
}
diff --git a/core/java/android/backup/BackupHelperDispatcher.java b/core/java/android/backup/BackupHelperDispatcher.java
index 6ccb83effd45..bf2c44d482af 100644
--- a/core/java/android/backup/BackupHelperDispatcher.java
+++ b/core/java/android/backup/BackupHelperDispatcher.java
@@ -138,7 +138,7 @@ public class BackupHelperDispatcher {
// Write out the state files -- mHelpers is a TreeMap, so the order is well defined.
for (BackupHelper helper: mHelpers.values()) {
- helper.writeRestoreSnapshot(newState);
+ helper.writeNewStateDescription(newState);
}
}
diff --git a/core/java/android/backup/BackupManager.java b/core/java/android/backup/BackupManager.java
index 0b27117d3f45..4bf59ebe3b8a 100644
--- a/core/java/android/backup/BackupManager.java
+++ b/core/java/android/backup/BackupManager.java
@@ -38,7 +38,11 @@ import android.util.Log;
* documentation for {@link android.app.BackupAgent} for a detailed description
* of how the backup then proceeds.
*
- * @hide pending API solidification
+ * <p>STOPSHIP more documentation here! Include the attributes:
+ * android:backupAgent
+ * android:allowBackup
+ * android:restoreNeedsApplication
+ * android:killAfterRestore
*/
public class BackupManager {
private static final String TAG = "BackupManager";
@@ -110,11 +114,8 @@ public class BackupManager {
}
/**
- * 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}
+ * Begin the process of restoring data from backup. See the
+ * {@link android.backup.RestoreSession} class for documentation on that process.
*/
public RestoreSession beginRestoreSession() {
if (!EVEN_THINK_ABOUT_DOING_RESTORE) {
@@ -128,7 +129,7 @@ public class BackupManager {
IRestoreSession binder = sService.beginRestoreSession(transport);
session = new RestoreSession(mContext, binder);
} catch (RemoteException e) {
- Log.d(TAG, "beginRestoreSession() couldn't connect");
+ Log.w(TAG, "beginRestoreSession() couldn't connect");
}
}
return session;
diff --git a/core/java/android/backup/FileBackupHelper.java b/core/java/android/backup/FileBackupHelper.java
index dacfc8f557dc..68b4d4219f6c 100644
--- a/core/java/android/backup/FileBackupHelper.java
+++ b/core/java/android/backup/FileBackupHelper.java
@@ -23,7 +23,9 @@ import android.util.Log;
import java.io.File;
import java.io.FileDescriptor;
-/** @hide */
+/**
+ * STOPSHIP: document! [manages backup of a set of files; restore is totally opaque]
+ */
public class FileBackupHelper extends FileBackupHelperBase implements BackupHelper {
private static final String TAG = "FileBackupHelper";
private static final boolean DEBUG = false;
@@ -32,6 +34,13 @@ public class FileBackupHelper extends FileBackupHelperBase implements BackupHelp
File mFilesDir;
String[] mFiles;
+ /**
+ * Construct a helper to manage backup/restore of entire files within the
+ * application's data directory hierarchy.
+ *
+ * @param context The backup agent's Context object
+ * @param files A list of the files to be backed up or restored.
+ */
public FileBackupHelper(Context context, String... files) {
super(context);
@@ -60,6 +69,9 @@ public class FileBackupHelper extends FileBackupHelperBase implements BackupHelp
performBackup_checked(oldState, data, newState, fullPaths, files);
}
+ /**
+ * Restore one record [representing a single file] from the restore dataset.
+ */
public void restoreEntity(BackupDataInputStream data) {
if (DEBUG) Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size());
String key = data.getKey();
diff --git a/core/java/android/backup/FileBackupHelperBase.java b/core/java/android/backup/FileBackupHelperBase.java
index 03ae4763fbd0..a0ff38b64126 100644
--- a/core/java/android/backup/FileBackupHelperBase.java
+++ b/core/java/android/backup/FileBackupHelperBase.java
@@ -20,7 +20,6 @@ import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.util.Log;
-import java.io.InputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
@@ -80,18 +79,14 @@ class FileBackupHelperBase {
}
}
- void writeFile(File f, InputStream in) {
- if (!(in instanceof BackupDataInputStream)) {
- throw new IllegalStateException("input stream must be a BackupDataInputStream");
- }
+ void writeFile(File f, BackupDataInputStream in) {
int result = -1;
// Create the enclosing directory.
File parent = f.getParentFile();
parent.mkdirs();
- result = writeFile_native(mPtr, f.getAbsolutePath(),
- ((BackupDataInputStream)in).mData.mBackupReader);
+ result = writeFile_native(mPtr, f.getAbsolutePath(), in.mData.mBackupReader);
if (result != 0) {
// Bail on this entity. Only log one failure per helper object.
if (!mExceptionLogged) {
@@ -103,7 +98,7 @@ class FileBackupHelperBase {
}
}
- public void writeRestoreSnapshot(ParcelFileDescriptor fd) {
+ public void writeNewStateDescription(ParcelFileDescriptor fd) {
int result = writeSnapshot_native(mPtr, fd.getFileDescriptor());
// TODO: Do something with the error.
}
diff --git a/core/java/android/backup/RestoreObserver.java b/core/java/android/backup/RestoreObserver.java
index 3be8c086ab50..e41827503f44 100644
--- a/core/java/android/backup/RestoreObserver.java
+++ b/core/java/android/backup/RestoreObserver.java
@@ -19,7 +19,6 @@ package android.backup;
/**
* Callback class for receiving progress reports during a restore operation. These
* methods will all be called on your application's main thread.
- * @hide
*/
public abstract class RestoreObserver {
/**
diff --git a/core/java/android/backup/RestoreSession.java b/core/java/android/backup/RestoreSession.java
index d10831e24a15..fc53854a7faa 100644
--- a/core/java/android/backup/RestoreSession.java
+++ b/core/java/android/backup/RestoreSession.java
@@ -27,7 +27,6 @@ import android.util.Log;
/**
* Interface for applications to use when managing a restore session.
- * @hide
*/
public class RestoreSession {
static final String TAG = "RestoreSession";
@@ -44,6 +43,8 @@ public class RestoreSession {
* 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.
* On error, returns null.
+ *
+ * {@hide}
*/
public RestoreSet[] getAvailableRestoreSets() {
try {
@@ -66,6 +67,8 @@ public class RestoreSession {
* the restore set that should be used.
* @param observer If non-null, this binder points to an object that will receive
* progress callbacks during the restore operation.
+ *
+ * {@hide}
*/
public int restoreAll(long token, RestoreObserver observer) {
int err = -1;
diff --git a/core/java/android/backup/SharedPreferencesBackupHelper.java b/core/java/android/backup/SharedPreferencesBackupHelper.java
index 6a0bc9653409..f9c97a3beb10 100644
--- a/core/java/android/backup/SharedPreferencesBackupHelper.java
+++ b/core/java/android/backup/SharedPreferencesBackupHelper.java
@@ -23,7 +23,9 @@ import android.util.Log;
import java.io.File;
import java.io.FileDescriptor;
-/** @hide */
+/**
+ * STOPSHIP: document!
+ */
public class SharedPreferencesBackupHelper extends FileBackupHelperBase implements BackupHelper {
private static final String TAG = "SharedPreferencesBackupHelper";
private static final boolean DEBUG = false;
@@ -31,6 +33,13 @@ public class SharedPreferencesBackupHelper extends FileBackupHelperBase implemen
private Context mContext;
private String[] mPrefGroups;
+ /**
+ * Construct a helper for backing up and restoring the
+ * {@link android.content.SharedPreferences} under the given names.
+ *
+ * @param context
+ * @param prefGroups
+ */
public SharedPreferencesBackupHelper(Context context, String... prefGroups) {
super(context);
@@ -38,6 +47,9 @@ public class SharedPreferencesBackupHelper extends FileBackupHelperBase implemen
mPrefGroups = prefGroups;
}
+ /**
+ * Backs up the configured SharedPreferences groups
+ */
public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
ParcelFileDescriptor newState) {
Context context = mContext;
@@ -54,6 +66,10 @@ public class SharedPreferencesBackupHelper extends FileBackupHelperBase implemen
performBackup_checked(oldState, data, newState, files, prefGroups);
}
+ /**
+ * Restores one entity from the restore data stream to its proper shared
+ * preferences file store.
+ */
public void restoreEntity(BackupDataInputStream data) {
Context context = mContext;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index e36eba9247e5..d31b25b58263 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1840,7 +1840,7 @@ public class Intent implements Parcelable, Cloneable {
* @hide
*/
public static final String ACTION_REMOTE_INTENT =
- "android.intent.action.REMOTE_INTENT";
+ "com.google.android.pushmessaging.intent.RECEIVE";
/**
* Broadcast Action: hook for permforming cleanup after a system update.
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 17bee483a94f..ff2ed3da6680 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -258,14 +258,7 @@ public abstract class PackageManager {
* package has to be installed on the sdcard.
* @hide
*/
- public static final int INSTALL_ON_SDCARD = 0x00000008;
-
- /**
- * Convenience flag parameter to indicate that this package has to be installed
- * on internal flash.
- * @hide
- */
- public static final int INSTALL_ON_INTERNAL_FLASH = 0x00000000;
+ public static final int INSTALL_EXTERNAL = 0x00000008;
/**
* Flag parameter for
@@ -529,6 +522,14 @@ public abstract class PackageManager {
public static final int INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109;
/**
+ * Installation failed return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+ * if the system failed to install the package because of system issues.
+ * @hide
+ */
+ public static final int INSTALL_FAILED_INTERNAL_ERROR = -110;
+
+ /**
* Indicates the state of installation. Used by PackageManager to
* figure out incomplete installations. Say a package is being installed
* (the state is set to PKG_INSTALL_INCOMPLETE) and remains so till
@@ -627,23 +628,6 @@ public abstract class PackageManager {
*/
public static final String ACTION_CLEAN_EXTERNAL_STORAGE
= "android.content.pm.CLEAN_EXTERNAL_STORAGE";
-
- /**
- * Determines best place to install an application: either SD or internal FLASH.
- * If applications explicitly set installLocation in their manifest, that
- * preference takes precedence. If not a recommended location is returned
- * based on current available storage on internal flash or sdcard.
- * @param pkgInfo PackageParser.Package of the package that is to be installed.
- * Call utility method to obtain.
- * @return {@link INSTALL_ON_INTERNAL_FLASH} if it is best to install package on internal
- * storage, {@link INSTALL_ON_SDCARD} if it is best to install package on SD card,
- * and {@link INSTALL_FAILED_INSUFFICIENT_STORAGE} if insufficient space to safely install
- * the application. {@link INSTALL_PARSE_FAILED_NOT_APK} Is returned if any input
- * parameter is <code>null</code>.
- * This recommendation does take into account the package's own flags.
- * @hide
- */
- public abstract int recommendAppInstallLocation(PackageParser.Package pkg);
/**
* Retrieve overall information about an application package that is
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index a7e6ca0c3f02..9ac8a4dab5e7 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -201,10 +201,17 @@ public class SQLiteDatabase extends SQLiteClosable {
private long mLastLockMessageTime = 0L;
- // always log queries which take 100ms+; shorter queries are sampled accordingly
+ // Things related to query logging/sampling for debugging
+ // slow/frequent queries during development. Always log queries
+ // which take 100ms+; shorter queries are sampled accordingly.
+ // Commit statements, which are typically slow, are logged
+ // together with the most recently executed SQL statement, for
+ // disambiguation.
private static final int QUERY_LOG_TIME_IN_MILLIS = 100;
private static final int QUERY_LOG_SQL_LENGTH = 64;
+ private static final String COMMIT_SQL = "COMMIT;";
private final Random mRandom = new Random();
+ private String mLastSqlStatement = null;
/** Used by native code, do not rename */
/* package */ int mNativeHandle = 0;
@@ -540,7 +547,7 @@ public class SQLiteDatabase extends SQLiteClosable {
}
}
if (mTransactionIsSuccessful) {
- execSQL("COMMIT;");
+ execSQL(COMMIT_SQL);
} else {
try {
execSQL("ROLLBACK;");
@@ -1660,7 +1667,15 @@ public class SQLiteDatabase extends SQLiteClosable {
} finally {
unlock();
}
- logTimeStat(sql, timeStart);
+
+ // Log commit statements along with the most recently executed
+ // SQL statement for disambiguation. Note that instance
+ // equality to COMMIT_SQL is safe here.
+ if (sql == COMMIT_SQL) {
+ logTimeStat(sql + mLastSqlStatement, timeStart);
+ } else {
+ logTimeStat(sql, timeStart);
+ }
}
/**
@@ -1786,6 +1801,11 @@ public class SQLiteDatabase extends SQLiteClosable {
/* package */ void logTimeStat(String sql, long beginMillis) {
+ // Keep track of the last statement executed here, as this is
+ // the common funnel through which all methods of hitting
+ // libsqlite eventually flow.
+ mLastSqlStatement = sql;
+
// Sample fast queries in proportion to the time taken.
// Quantize the % first, so the logged sampling probability
// exactly equals the actual sampling rate for this query.
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index d435df584286..badb7670adad 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -125,13 +125,21 @@ public class ConnectivityManager
/**
* @hide
+ * gives a String[]
*/
- public static final String EXTRA_AVAILABLE_TETHER_COUNT = "availableCount";
+ public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
/**
* @hide
+ * gives a String[]
*/
- public static final String EXTRA_ACTIVE_TETHER_COUNT = "activeCount";
+ public static final String EXTRA_ACTIVE_TETHER = "activeArray";
+
+ /**
+ * @hide
+ * gives a String[]
+ */
+ public static final String EXTRA_ERRORED_TETHER = "erroredArray";
/**
* The Default Mobile data connection. When active, all data traffic
@@ -400,4 +408,37 @@ public class ConnectivityManager
return false;
}
}
+
+ /**
+ * {@hide}
+ */
+ public boolean isTetheringSupported() {
+ try {
+ return mService.isTetheringSupported();
+ } catch (RemoteException e) {
+ return false;
+ }
+ }
+
+ /**
+ * {@hide}
+ */
+ public String[] getTetherableUsbRegexs() {
+ try {
+ return mService.getTetherableUsbRegexs();
+ } catch (RemoteException e) {
+ return new String[0];
+ }
+ }
+
+ /**
+ * {@hide}
+ */
+ public String[] getTetherableWifiRegexs() {
+ try {
+ return mService.getTetherableWifiRegexs();
+ } catch (RemoteException e) {
+ return new String[0];
+ }
+ }
}
diff --git a/core/java/android/net/Downloads.java b/core/java/android/net/Downloads.java
new file mode 100644
index 000000000000..72106c8f524d
--- /dev/null
+++ b/core/java/android/net/Downloads.java
@@ -0,0 +1,645 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.provider.BaseColumns;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.File;
+import java.io.InputStream;
+
+/**
+ * The Download Manager
+ *
+ *
+ */
+public final class Downloads {
+
+
+ /**
+ * Download status codes
+ */
+
+ /**
+ * This download hasn't started yet
+ */
+ public static final int STATUS_PENDING = 190;
+
+ /**
+ * This download has started
+ */
+ public static final int STATUS_RUNNING = 192;
+
+ /**
+ * This download has successfully completed.
+ * Warning: there might be other status values that indicate success
+ * in the future.
+ * Use isSucccess() to capture the entire category.
+ */
+ public static final int STATUS_SUCCESS = 200;
+
+ /**
+ * This download can't be performed because the content type cannot be
+ * handled.
+ */
+ public static final int STATUS_NOT_ACCEPTABLE = 406;
+
+ /**
+ * This download has completed with an error.
+ * Warning: there will be other status values that indicate errors in
+ * the future. Use isStatusError() to capture the entire category.
+ */
+ public static final int STATUS_UNKNOWN_ERROR = 491;
+
+ /**
+ * This download couldn't be completed because of an HTTP
+ * redirect response that the download manager couldn't
+ * handle.
+ */
+ public static final int STATUS_UNHANDLED_REDIRECT = 493;
+
+ /**
+ * This download couldn't be completed due to insufficient storage
+ * space. Typically, this is because the SD card is full.
+ */
+ public static final int STATUS_INSUFFICIENT_SPACE_ERROR = 498;
+
+ /**
+ * This download couldn't be completed because no external storage
+ * device was found. Typically, this is because the SD card is not
+ * mounted.
+ */
+ public static final int STATUS_DEVICE_NOT_FOUND_ERROR = 499;
+
+ /**
+ * Returns whether the status is a success (i.e. 2xx).
+ */
+ public static boolean isStatusSuccess(int status) {
+ return (status >= 200 && status < 300);
+ }
+
+ /**
+ * Returns whether the status is an error (i.e. 4xx or 5xx).
+ */
+ public static boolean isStatusError(int status) {
+ return (status >= 400 && status < 600);
+ }
+
+ /**
+ * Download destinations
+ */
+
+ /**
+ * This download will be saved to the external storage. This is the
+ * default behavior, and should be used for any file that the user
+ * can freely access, copy, delete. Even with that destination,
+ * unencrypted DRM files are saved in secure internal storage.
+ * Downloads to the external destination only write files for which
+ * there is a registered handler. The resulting files are accessible
+ * by filename to all applications.
+ */
+ public static final int DOWNLOAD_DESTINATION_EXTERNAL = 1;
+
+ /**
+ * This download will be saved to the download manager's private
+ * partition. This is the behavior used by applications that want to
+ * download private files that are used and deleted soon after they
+ * get downloaded. All file types are allowed, and only the initiating
+ * application can access the file (indirectly through a content
+ * provider). This requires the
+ * android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED permission.
+ */
+ public static final int DOWNLOAD_DESTINATION_CACHE = 2;
+
+ /**
+ * This download will be saved to the download manager's private
+ * partition and will be purged as necessary to make space. This is
+ * for private files (similar to CACHE_PARTITION) that aren't deleted
+ * immediately after they are used, and are kept around by the download
+ * manager as long as space is available.
+ */
+ public static final int DOWNLOAD_DESTINATION_CACHE_PURGEABLE = 3;
+
+
+ /**
+ * An invalid download id
+ */
+ public static final long DOWNLOAD_ID_INVALID = -1;
+
+
+ /**
+ * Broadcast Action: this is sent by the download manager to the app
+ * that had initiated a download when that download completes. The
+ * download's content: uri is specified in the intent's data.
+ */
+ public static final String ACTION_DOWNLOAD_COMPLETED =
+ "android.intent.action.DOWNLOAD_COMPLETED";
+
+ /**
+ * If extras are specified when requesting a download they will be provided in the intent that
+ * is sent to the specified class and package when a download has finished.
+ * <P>Type: TEXT</P>
+ * <P>Owner can Init</P>
+ */
+ public static final String COLUMN_NOTIFICATION_EXTRAS = "notificationextras";
+
+
+ /**
+ * Status class for a download
+ */
+ public static final class StatusInfo {
+ public boolean completed = false;
+ /** The filename of the active download. */
+ public String filename = null;
+ /** An opaque id for the download */
+ public long id = DOWNLOAD_ID_INVALID;
+ /** An opaque status code for the download */
+ public int statusCode = -1;
+ /** Approximate number of bytes downloaded so far, for debugging purposes. */
+ public long bytesSoFar = -1;
+
+ /**
+ * Returns whether the download is completed
+ * @return a boolean whether the download is complete.
+ */
+ public boolean isComplete() {
+ return android.provider.Downloads.Impl.isStatusCompleted(statusCode);
+ }
+
+ /**
+ * Returns whether the download is successful
+ * @return a boolean whether the download is successful.
+ */
+ public boolean isSuccessful() {
+ return android.provider.Downloads.Impl.isStatusCompleted(statusCode);
+ }
+ }
+
+ /**
+ * Class to access initiate and query download by server uri
+ */
+ public static final class ByUri extends DownloadBase {
+ /** @hide */
+ private ByUri() {}
+
+ /**
+ * Query where clause by app data.
+ * @hide
+ */
+ private static final String QUERY_WHERE_APP_DATA_CLAUSE =
+ android.provider.Downloads.Impl.COLUMN_APP_DATA + "=?";
+
+ /**
+ * Gets a Cursor pointing to the download(s) of the current system update.
+ * @hide
+ */
+ private static final Cursor getCurrentOtaDownloads(Context context, String url) {
+ return context.getContentResolver().query(
+ android.provider.Downloads.Impl.CONTENT_URI,
+ DOWNLOADS_PROJECTION,
+ QUERY_WHERE_APP_DATA_CLAUSE,
+ new String[] {url},
+ null);
+ }
+
+ /**
+ * Returns a StatusInfo with the result of trying to download the
+ * given URL. Returns null if no attempts have been made.
+ */
+ public static final StatusInfo getStatus(
+ Context context,
+ String url,
+ long redownload_threshold) {
+ StatusInfo result = null;
+ boolean hasFailedDownload = false;
+ long failedDownloadModificationTime = 0;
+ Cursor c = getCurrentOtaDownloads(context, url);
+ try {
+ while (c != null && c.moveToNext()) {
+ if (result == null) {
+ result = new StatusInfo();
+ }
+ int status = getStatusOfDownload(c, redownload_threshold);
+ if (status == STATUS_DOWNLOADING_UPDATE ||
+ status == STATUS_DOWNLOADED_UPDATE) {
+ result.completed = (status == STATUS_DOWNLOADED_UPDATE);
+ result.filename = c.getString(DOWNLOADS_COLUMN_FILENAME);
+ result.id = c.getLong(DOWNLOADS_COLUMN_ID);
+ result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
+ result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
+ return result;
+ }
+
+ long modTime = c.getLong(DOWNLOADS_COLUMN_LAST_MODIFICATION);
+ if (hasFailedDownload &&
+ modTime < failedDownloadModificationTime) {
+ // older than the one already in result; skip it.
+ continue;
+ }
+
+ hasFailedDownload = true;
+ failedDownloadModificationTime = modTime;
+ result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
+ result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
+ }
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Query where clause for general querying.
+ */
+ private static final String QUERY_WHERE_CLAUSE =
+ android.provider.Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE + "=? AND " +
+ android.provider.Downloads.Impl.COLUMN_NOTIFICATION_CLASS + "=?";
+
+ /**
+ * Delete all the downloads for a package/class pair.
+ */
+ public static final void removeAllDownloadsByPackage(
+ Context context,
+ String notification_package,
+ String notification_class) {
+ context.getContentResolver().delete(
+ android.provider.Downloads.Impl.CONTENT_URI,
+ QUERY_WHERE_CLAUSE,
+ new String[] { notification_package, notification_class });
+ }
+
+ /**
+ * The column for the id in the Cursor returned by
+ * getProgressCursor()
+ */
+ public static final int getProgressColumnId() {
+ return 0;
+ }
+
+ /**
+ * The column for the current byte count in the Cursor returned by
+ * getProgressCursor()
+ */
+ public static final int getProgressColumnCurrentBytes() {
+ return 1;
+ }
+
+ /**
+ * The column for the total byte count in the Cursor returned by
+ * getProgressCursor()
+ */
+ public static final int getProgressColumnTotalBytes() {
+ return 2;
+ }
+
+ /** @hide */
+ private static final String[] PROJECTION = {
+ BaseColumns._ID,
+ android.provider.Downloads.Impl.COLUMN_CURRENT_BYTES,
+ android.provider.Downloads.Impl.COLUMN_TOTAL_BYTES
+ };
+
+ /**
+ * Returns a Cursor representing the progress of the download identified by the ID.
+ */
+ public static final Cursor getProgressCursor(Context context, long id) {
+ Uri downloadUri = Uri.withAppendedPath(android.provider.Downloads.Impl.CONTENT_URI,
+ String.valueOf(id));
+ return context.getContentResolver().query(downloadUri, PROJECTION, null, null, null);
+ }
+ }
+
+ /**
+ * Class to access downloads by opaque download id
+ */
+ public static final class ById extends DownloadBase {
+ /** @hide */
+ private ById() {}
+
+ /**
+ * Get the mime tupe of the download specified by the download id
+ */
+ public static String getMimeTypeForId(Context context, long downloadId) {
+ ContentResolver cr = context.getContentResolver();
+
+ String mimeType = null;
+ Cursor downloadCursor = null;
+
+ try {
+ Uri downloadUri = getDownloadUri(downloadId);
+
+ downloadCursor = cr.query(
+ downloadUri, new String[]{android.provider.Downloads.Impl.COLUMN_MIME_TYPE},
+ null, null, null);
+ if (downloadCursor.moveToNext()) {
+ mimeType = downloadCursor.getString(0);
+ }
+ } finally {
+ if (downloadCursor != null) downloadCursor.close();
+ }
+ return mimeType;
+ }
+
+ /**
+ * Delete a download by Id
+ */
+ public static void deleteDownload(Context context, long downloadId) {
+ ContentResolver cr = context.getContentResolver();
+
+ String mimeType = null;
+
+ Uri downloadUri = getDownloadUri(downloadId);
+
+ cr.delete(downloadUri, null, null);
+ }
+
+ /**
+ * Open a filedescriptor to a particular download
+ */
+ public static ParcelFileDescriptor openDownload(
+ Context context, long downloadId, String mode)
+ throws FileNotFoundException
+ {
+ ContentResolver cr = context.getContentResolver();
+
+ String mimeType = null;
+
+ Uri downloadUri = getDownloadUri(downloadId);
+
+ return cr.openFileDescriptor(downloadUri, mode);
+ }
+
+ /**
+ * Open a stream to a particular download
+ */
+ public static InputStream openDownloadStream(Context context, long downloadId)
+ throws FileNotFoundException, IOException
+ {
+ ContentResolver cr = context.getContentResolver();
+
+ String mimeType = null;
+
+ Uri downloadUri = getDownloadUri(downloadId);
+
+ return cr.openInputStream(downloadUri);
+ }
+
+ private static Uri getDownloadUri(long downloadId) {
+ return Uri.parse(android.provider.Downloads.Impl.CONTENT_URI + "/" + downloadId);
+ }
+
+ /**
+ * Returns a StatusInfo with the result of trying to download the
+ * given URL. Returns null if no attempts have been made.
+ */
+ public static final StatusInfo getStatus(
+ Context context,
+ long downloadId) {
+ StatusInfo result = null;
+ boolean hasFailedDownload = false;
+ long failedDownloadModificationTime = 0;
+
+ Uri downloadUri = getDownloadUri(downloadId);
+
+ ContentResolver cr = context.getContentResolver();
+
+ Cursor c = cr.query(
+ downloadUri, DOWNLOADS_PROJECTION, null /* selection */, null /* selection args */,
+ null /* sort order */);
+ try {
+ if (!c.moveToNext()) {
+ return result;
+ }
+
+ if (result == null) {
+ result = new StatusInfo();
+ }
+ int status = getStatusOfDownload(c,0);
+ if (status == STATUS_DOWNLOADING_UPDATE ||
+ status == STATUS_DOWNLOADED_UPDATE) {
+ result.completed = (status == STATUS_DOWNLOADED_UPDATE);
+ result.filename = c.getString(DOWNLOADS_COLUMN_FILENAME);
+ result.id = c.getLong(DOWNLOADS_COLUMN_ID);
+ result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
+ result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
+ return result;
+ }
+
+ long modTime = c.getLong(DOWNLOADS_COLUMN_LAST_MODIFICATION);
+
+ result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
+ result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ return result;
+ }
+ }
+
+
+ /**
+ * Base class with common functionality for the various download classes
+ */
+ private static class DownloadBase {
+ /** @hide */
+ DownloadBase() {}
+
+ /**
+ * Initiate a download where the download will be tracked by its URI.
+ */
+ public static long startDownloadByUri(
+ Context context,
+ String url,
+ String cookieData,
+ boolean showDownload,
+ int downloadDestination,
+ boolean allowRoaming,
+ boolean skipIntegrityCheck,
+ String title,
+ String notification_package,
+ String notification_class,
+ String notification_extras) {
+ ContentResolver cr = context.getContentResolver();
+
+ // Tell download manager to start downloading update.
+ ContentValues values = new ContentValues();
+ values.put(android.provider.Downloads.Impl.COLUMN_URI, url);
+ values.put(android.provider.Downloads.Impl.COLUMN_COOKIE_DATA, cookieData);
+ values.put(android.provider.Downloads.Impl.COLUMN_VISIBILITY,
+ showDownload ? android.provider.Downloads.Impl.VISIBILITY_VISIBLE
+ : android.provider.Downloads.Impl.VISIBILITY_HIDDEN);
+ if (title != null) {
+ values.put(android.provider.Downloads.Impl.COLUMN_TITLE, title);
+ }
+ values.put(android.provider.Downloads.Impl.COLUMN_APP_DATA, url);
+
+
+ // NOTE: destination should be seperated from whether the download
+ // can happen when roaming
+ int destination = android.provider.Downloads.Impl.DESTINATION_EXTERNAL;
+ switch (downloadDestination) {
+ case DOWNLOAD_DESTINATION_EXTERNAL:
+ destination = android.provider.Downloads.Impl.DESTINATION_EXTERNAL;
+ break;
+ case DOWNLOAD_DESTINATION_CACHE:
+ if (allowRoaming) {
+ destination = android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION;
+ } else {
+ destination =
+ android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING;
+ }
+ break;
+ case DOWNLOAD_DESTINATION_CACHE_PURGEABLE:
+ destination =
+ android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE;
+ break;
+ }
+ values.put(android.provider.Downloads.Impl.COLUMN_DESTINATION, destination);
+ values.put(android.provider.Downloads.Impl.COLUMN_NO_INTEGRITY,
+ skipIntegrityCheck); // Don't check ETag
+ if (notification_package != null && notification_class != null) {
+ values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
+ notification_package);
+ values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
+ notification_class);
+
+ if (notification_extras != null) {
+ values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS,
+ notification_extras);
+ }
+ }
+
+ Uri downloadUri = cr.insert(android.provider.Downloads.Impl.CONTENT_URI, values);
+
+ long downloadId = DOWNLOAD_ID_INVALID;
+ if (downloadUri != null) {
+ downloadId = Long.parseLong(downloadUri.getLastPathSegment());
+ }
+ return downloadId;
+ }
+ }
+
+ /** @hide */
+ private static final int STATUS_INVALID = 0;
+ /** @hide */
+ private static final int STATUS_DOWNLOADING_UPDATE = 3;
+ /** @hide */
+ private static final int STATUS_DOWNLOADED_UPDATE = 4;
+
+ /**
+ * Column projection for the query to the download manager. This must match
+ * with the constants DOWNLOADS_COLUMN_*.
+ * @hide
+ */
+ private static final String[] DOWNLOADS_PROJECTION = {
+ BaseColumns._ID,
+ android.provider.Downloads.Impl.COLUMN_APP_DATA,
+ android.provider.Downloads.Impl.COLUMN_STATUS,
+ android.provider.Downloads.Impl._DATA,
+ android.provider.Downloads.Impl.COLUMN_LAST_MODIFICATION,
+ android.provider.Downloads.Impl.COLUMN_CURRENT_BYTES,
+ };
+
+ /**
+ * The column index for the ID.
+ * @hide
+ */
+ private static final int DOWNLOADS_COLUMN_ID = 0;
+ /**
+ * The column index for the URI.
+ * @hide
+ */
+ private static final int DOWNLOADS_COLUMN_URI = 1;
+ /**
+ * The column index for the status code.
+ * @hide
+ */
+ private static final int DOWNLOADS_COLUMN_STATUS = 2;
+ /**
+ * The column index for the filename.
+ * @hide
+ */
+ private static final int DOWNLOADS_COLUMN_FILENAME = 3;
+ /**
+ * The column index for the last modification time.
+ * @hide
+ */
+ private static final int DOWNLOADS_COLUMN_LAST_MODIFICATION = 4;
+ /**
+ * The column index for the number of bytes downloaded so far.
+ * @hide
+ */
+ private static final int DOWNLOADS_COLUMN_CURRENT_BYTES = 5;
+
+ /**
+ * Gets the status of a download.
+ *
+ * @param c A Cursor pointing to a download. The URL column is assumed to be valid.
+ * @return The status of the download.
+ * @hide
+ */
+ private static final int getStatusOfDownload( Cursor c, long redownload_threshold) {
+ int status = c.getInt(DOWNLOADS_COLUMN_STATUS);
+ long realtime = SystemClock.elapsedRealtime();
+
+ // TODO(dougz): special handling of 503, 404? (eg, special
+ // explanatory messages to user)
+
+ if (!android.provider.Downloads.Impl.isStatusCompleted(status)) {
+ // Check if it's stuck
+ long modified = c.getLong(DOWNLOADS_COLUMN_LAST_MODIFICATION);
+ long now = System.currentTimeMillis();
+ if (now < modified || now - modified > redownload_threshold) {
+ return STATUS_INVALID;
+ }
+
+ return STATUS_DOWNLOADING_UPDATE;
+ }
+
+ if (android.provider.Downloads.Impl.isStatusError(status)) {
+ return STATUS_INVALID;
+ }
+
+ String filename = c.getString(DOWNLOADS_COLUMN_FILENAME);
+ if (filename == null) {
+ return STATUS_INVALID;
+ }
+
+ return STATUS_DOWNLOADED_UPDATE;
+ }
+
+
+ /**
+ * @hide
+ */
+ private Downloads() {}
+}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index caa3f2bbc772..508e9c3acb5d 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -55,7 +55,13 @@ interface IConnectivityManager
boolean untether(String iface);
+ boolean isTetheringSupported();
+
String[] getTetherableIfaces();
String[] getTetheredIfaces();
+
+ String[] getTetherableUsbRegexs();
+
+ String[] getTetherableWifiRegexs();
}
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index ed76b1500b69..f959fee85a86 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -50,12 +50,14 @@ import org.apache.harmony.xnet.provider.jsse.SSLParameters;
* <ul>
* <li>Timeout specification for SSL handshake operations
* <li>Optional SSL session caching with {@link SSLSessionCache}
- * <li>On development devices, "setprop socket.relaxsslcheck yes" bypasses all
- * SSL certificate checks, for testing with development servers
+ * <li>Optionally bypass all SSL certificate checks
* </ul>
* Note that the handshake timeout does not apply to actual connection.
* If you want a connection timeout as well, use {@link #createSocket()} and
* {@link Socket#connect(SocketAddress, int)}.
+ * <p>
+ * On development devices, "setprop socket.relaxsslcheck yes" bypasses all
+ * SSL certificate checks, for testing with development servers.
*/
public class SSLCertificateSocketFactory extends SSLSocketFactory {
private static final String TAG = "SSLCertificateSocketFactory";
@@ -73,41 +75,57 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
private final int mHandshakeTimeoutMillis;
private final SSLClientSessionCache mSessionCache;
+ private final boolean mSecure;
/** @deprecated Use {@link #getDefault(int)} instead. */
public SSLCertificateSocketFactory(int handshakeTimeoutMillis) {
- this(handshakeTimeoutMillis, null /* cache */);
+ this(handshakeTimeoutMillis, null, true);
}
- private SSLCertificateSocketFactory(int handshakeTimeoutMillis, SSLSessionCache cache) {
+ private SSLCertificateSocketFactory(
+ int handshakeTimeoutMillis, SSLSessionCache cache, boolean secure) {
mHandshakeTimeoutMillis = handshakeTimeoutMillis;
mSessionCache = cache == null ? null : cache.mSessionCache;
+ mSecure = secure;
}
/**
- * Returns a new instance of a socket factory using the specified socket read
- * timeout while connecting with the server/negotiating an ssl session.
+ * Returns a new socket factory instance with an optional handshake timeout.
*
* @param handshakeTimeoutMillis to use for SSL connection handshake, or 0
* for none. The socket timeout is reset to 0 after the handshake.
* @return a new SocketFactory with the specified parameters
*/
public static SocketFactory getDefault(int handshakeTimeoutMillis) {
- return getDefault(handshakeTimeoutMillis, null /* cache */);
+ return new SSLCertificateSocketFactory(handshakeTimeoutMillis, null, true);
}
/**
- * Returns a new instance of a socket factory using the specified socket
- * read timeout while connecting with the server/negotiating an ssl session
- * Persists ssl sessions using the provided {@link SSLClientSessionCache}.
+ * Returns a new socket factory instance with an optional handshake timeout
+ * and SSL session cache.
*
* @param handshakeTimeoutMillis to use for SSL connection handshake, or 0
* for none. The socket timeout is reset to 0 after the handshake.
* @param cache The {@link SSLClientSessionCache} to use, or null for no cache.
* @return a new SocketFactory with the specified parameters
*/
- public static SocketFactory getDefault(int handshakeTimeoutMillis, SSLSessionCache cache) {
- return new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache);
+ public static SSLSocketFactory getDefault(int handshakeTimeoutMillis, SSLSessionCache cache) {
+ return new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache, true);
+ }
+
+ /**
+ * Returns a new instance of a socket factory with all SSL security checks
+ * disabled, using an optional handshake timeout and SSL session cache.
+ * Sockets created using this factory are vulnerable to man-in-the-middle
+ * attacks!
+ *
+ * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0
+ * for none. The socket timeout is reset to 0 after the handshake.
+ * @param cache The {@link SSLClientSessionCache} to use, or null for no cache.
+ * @return an insecure SocketFactory with the specified parameters
+ */
+ public static SSLSocketFactory getInsecure(int handshakeTimeoutMillis, SSLSessionCache cache) {
+ return new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache, false);
}
/**
@@ -123,7 +141,7 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
int handshakeTimeoutMillis,
SSLSessionCache cache) {
return new org.apache.http.conn.ssl.SSLSocketFactory(
- new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache));
+ new SSLCertificateSocketFactory(handshakeTimeoutMillis, cache, true));
}
private SSLSocketFactory makeSocketFactory(TrustManager[] trustManagers) {
@@ -138,12 +156,15 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
}
private synchronized SSLSocketFactory getDelegate() {
- // only allow relaxing the ssl check on non-secure builds where the relaxation is
- // specifically requested.
- if ("0".equals(SystemProperties.get("ro.secure")) &&
- "yes".equals(SystemProperties.get("socket.relaxsslcheck"))) {
+ // Relax the SSL check if instructed (for this factory, or systemwide)
+ if (!mSecure || ("0".equals(SystemProperties.get("ro.secure")) &&
+ "yes".equals(SystemProperties.get("socket.relaxsslcheck")))) {
if (mInsecureFactory == null) {
- Log.w(TAG, "*** BYPASSING SSL SECURITY CHECKS (socket.relaxsslcheck=yes) ***");
+ if (mSecure) {
+ Log.w(TAG, "*** BYPASSING SSL SECURITY CHECKS (socket.relaxsslcheck=yes) ***");
+ } else {
+ Log.w(TAG, "Bypassing SSL security checks at caller's request");
+ }
mInsecureFactory = makeSocketFactory(INSECURE_TRUST_MANAGER);
}
return mInsecureFactory;
diff --git a/core/java/android/net/WebAddress.java b/core/java/android/net/WebAddress.java
index f4ae66ac5d05..fa13894691af 100644
--- a/core/java/android/net/WebAddress.java
+++ b/core/java/android/net/WebAddress.java
@@ -16,6 +16,8 @@
package android.net;
+import static com.android.common.Patterns.GOOD_IRI_CHAR;
+
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -54,9 +56,10 @@ public class WebAddress {
static Pattern sAddressPattern = Pattern.compile(
/* scheme */ "(?:(http|HTTP|https|HTTPS|file|FILE)\\:\\/\\/)?" +
/* authority */ "(?:([-A-Za-z0-9$_.+!*'(),;?&=]+(?:\\:[-A-Za-z0-9$_.+!*'(),;?&=]+)?)@)?" +
- /* host */ "([-A-Za-z0-9%_]+(?:\\.[-A-Za-z0-9%_]+)*|\\[[0-9a-fA-F:\\.]+\\])?" +
+ /* host */ "([-" + GOOD_IRI_CHAR + "%_]+(?:\\.[-" + GOOD_IRI_CHAR + "%_]+)*|\\[[0-9a-fA-F:\\.]+\\])?" +
/* port */ "(?:\\:([0-9]+))?" +
- /* path */ "(\\/?.*)?");
+ /* path */ "(\\/?[^#]*)?" +
+ /* anchor */ ".*");
/** parses given uriString. */
public WebAddress(String address) throws ParseException {
diff --git a/core/java/android/os/ICheckinService.aidl b/core/java/android/os/ICheckinService.aidl
deleted file mode 100644
index 37af496a7620..000000000000
--- a/core/java/android/os/ICheckinService.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.os.IParentalControlCallback;
-
-/**
- * System private API for direct access to the checkin service.
- * Users should use the content provider instead.
- *
- * @see android.provider.Checkin
- * {@hide}
- */
-interface ICheckinService {
- /**
- * Determine if the device is under parental control. Return null if
- * we are unable to check the parental control status.
- */
- void getParentalControlState(IParentalControlCallback p,
- String requestingApp);
-}
diff --git a/core/java/android/os/IParentalControlCallback.aidl b/core/java/android/os/IParentalControlCallback.aidl
deleted file mode 100644
index 2f1a563c2066..000000000000
--- a/core/java/android/os/IParentalControlCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.google.android.net.ParentalControlState;
-
-/**
- * This callback interface is used to deliver the parental control state to the calling application.
- * {@hide}
- */
-oneway interface IParentalControlCallback {
- void onResult(in ParentalControlState state);
-}
diff --git a/core/java/android/os/storage/IMountService.aidl b/core/java/android/os/storage/IMountService.aidl
index 3d1ef250a366..816baf382147 100644
--- a/core/java/android/os/storage/IMountService.aidl
+++ b/core/java/android/os/storage/IMountService.aidl
@@ -72,6 +72,12 @@ interface IMountService
int formatVolume(String mountPoint);
/**
+ * Returns an array of pids with open files on
+ * the specified path.
+ */
+ int[] getStorageUsers(String path);
+
+ /**
* Gets the state of an volume via it's mountpoint.
*/
String getVolumeState(String mountPoint);
@@ -94,7 +100,7 @@ interface IMountService
* NOTE: Ensure all references are released prior to deleting.
* Returns an int consistent with MountServiceResultCode
*/
- int destroySecureContainer(String id);
+ int destroySecureContainer(String id);
/*
* Mount a secure container with the specified key and owner UID.
diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java
index 389c9f4f0553..2eb259544891 100644
--- a/core/java/android/pim/vcard/VCardComposer.java
+++ b/core/java/android/pim/vcard/VCardComposer.java
@@ -25,11 +25,13 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.RemoteException;
+import android.pim.vcard.exception.VCardException;
import android.provider.CallLog;
import android.provider.CallLog.Calls;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.RawContactsEntity;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Event;
import android.provider.ContactsContract.CommonDataKinds.Im;
@@ -54,6 +56,7 @@ import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
@@ -199,6 +202,10 @@ public class VCardComposer {
try {
// Create one empty entry.
mWriter.write(createOneEntryInternal("-1", null));
+ } catch (VCardException e) {
+ Log.e(LOG_TAG, "VCardException has been thrown during on Init(): " +
+ e.getMessage());
+ return false;
} catch (IOException e) {
Log.e(LOG_TAG,
"IOException occurred during exportOneContactData: "
@@ -455,6 +462,9 @@ public class VCardComposer {
return true;
}
}
+ } catch (VCardException e) {
+ Log.e(LOG_TAG, "VCardException has been thrown: " + e.getMessage());
+ return false;
} catch (OutOfMemoryError error) {
// Maybe some data (e.g. photo) is too big to have in memory. But it
// should be rare.
@@ -486,36 +496,42 @@ public class VCardComposer {
}
private String createOneEntryInternal(final String contactId,
- Method getEntityIteratorMethod) {
+ Method getEntityIteratorMethod) throws VCardException {
final Map<String, List<ContentValues>> contentValuesListMap =
new HashMap<String, List<ContentValues>>();
- // The resolver may return the entity iterator with no data. It is possiible.
+ // The resolver may return the entity iterator with no data. It is possible.
// e.g. If all the data in the contact of the given contact id are not exportable ones,
// they are hidden from the view of this method, though contact id itself exists.
- boolean dataExists = false;
EntityIterator entityIterator = null;
try {
-
+ final Uri uri = RawContactsEntity.CONTENT_URI.buildUpon()
+ .appendQueryParameter(Data.FOR_EXPORT_ONLY, "1")
+ .build();
+ final String selection = Data.CONTACT_ID + "=?";
+ final String[] selectionArgs = new String[] {contactId};
if (getEntityIteratorMethod != null) {
+ // Please note that this branch is executed by some tests only
try {
- final Uri uri = RawContacts.CONTENT_URI.buildUpon()
- .appendQueryParameter(Data.FOR_EXPORT_ONLY, "1")
- .build();
- final String selection = Data.CONTACT_ID + "=?";
- final String[] selectionArgs = new String[] {contactId};
entityIterator = (EntityIterator)getEntityIteratorMethod.invoke(null,
mContentResolver, uri, selection, selectionArgs, null);
- } catch (Exception e) {
- e.printStackTrace();
+ } catch (IllegalArgumentException e) {
+ Log.e(LOG_TAG, "IllegalArgumentException has been thrown: " +
+ e.getMessage());
+ } catch (IllegalAccessException e) {
+ Log.e(LOG_TAG, "IllegalAccessException has been thrown: " +
+ e.getMessage());
+ } catch (InvocationTargetException e) {
+ Log.e(LOG_TAG, "InvocationTargetException has been thrown: ");
+ StackTraceElement[] stackTraceElements = e.getCause().getStackTrace();
+ for (StackTraceElement element : stackTraceElements) {
+ Log.e(LOG_TAG, " at " + element.toString());
+ }
+ throw new VCardException("InvocationTargetException has been thrown: " +
+ e.getCause().getMessage());
}
} else {
- final Uri uri = RawContacts.CONTENT_URI.buildUpon()
- .appendEncodedPath(contactId)
- .appendEncodedPath(RawContacts.Entity.CONTENT_DIRECTORY)
- .appendQueryParameter(Data.FOR_EXPORT_ONLY, "1")
- .build();
entityIterator = RawContacts.newEntityIterator(mContentResolver.query(
- uri, null, null, null, null));
+ uri, null, selection, selectionArgs, null));
}
if (entityIterator == null) {
@@ -523,7 +539,11 @@ public class VCardComposer {
return "";
}
- dataExists = entityIterator.hasNext();
+ if (!entityIterator.hasNext()) {
+ Log.w(LOG_TAG, "Data does not exist. contactId: " + contactId);
+ return "";
+ }
+
while (entityIterator.hasNext()) {
Entity entity = entityIterator.next();
for (NamedContentValues namedContentValues : entity.getSubValues()) {
@@ -550,10 +570,6 @@ public class VCardComposer {
}
}
- if (!dataExists) {
- return "";
- }
-
final VCardBuilder builder = new VCardBuilder(mVCardType);
builder.appendNameProperties(contentValuesListMap.get(StructuredName.CONTENT_ITEM_TYPE))
.appendNickNames(contentValuesListMap.get(Nickname.CONTENT_ITEM_TYPE))
diff --git a/core/java/android/pim/vcard/VCardEntry.java b/core/java/android/pim/vcard/VCardEntry.java
index 20eee84fa8c0..1cf3144f2586 100644
--- a/core/java/android/pim/vcard/VCardEntry.java
+++ b/core/java/android/pim/vcard/VCardEntry.java
@@ -281,6 +281,29 @@ public class VCardEntry {
isPrimary == organization.isPrimary);
}
+ public String getFormattedString() {
+ final StringBuilder builder = new StringBuilder();
+ if (!TextUtils.isEmpty(companyName)) {
+ builder.append(companyName);
+ }
+
+ if (!TextUtils.isEmpty(departmentName)) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append(departmentName);
+ }
+
+ if (!TextUtils.isEmpty(titleName)) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append(titleName);
+ }
+
+ return builder.toString();
+ }
+
@Override
public String toString() {
return String.format(
@@ -1008,6 +1031,8 @@ public class VCardEntry {
mDisplayName = mPhoneList.get(0).data;
} else if (mPostalList != null && mPostalList.size() > 0) {
mDisplayName = mPostalList.get(0).getFormattedAddress(mVCardType);
+ } else if (mOrganizationList != null && mOrganizationList.size() > 0) {
+ mDisplayName = mOrganizationList.get(0).getFormattedString();
}
if (mDisplayName == null) {
diff --git a/core/java/android/provider/Checkin.java b/core/java/android/provider/Checkin.java
deleted file mode 100644
index 75936a1fb9e2..000000000000
--- a/core/java/android/provider/Checkin.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.provider;
-
-import org.apache.commons.codec.binary.Base64;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.database.SQLException;
-import android.net.Uri;
-import android.os.SystemClock;
-import android.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-
-/**
- * Contract class for the checkin provider, used to store events and
- * statistics that will be uploaded to a checkin server eventually.
- * Describes the exposed database schema, and offers methods to add
- * events and statistics to be uploaded.
- *
- * TODO: Move this to vendor/google when we have a home for it.
- *
- * @hide
- */
-public final class Checkin {
- public static final String AUTHORITY = "android.server.checkin";
-
- /**
- * The events table is a log of important timestamped occurrences.
- * Each event has a type tag and an optional string value.
- * If too many events are added before they can be reported, the
- * content provider will erase older events to limit the table size.
- */
- public interface Events extends BaseColumns {
- public static final String TABLE_NAME = "events";
- public static final Uri CONTENT_URI =
- Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME);
-
- public static final String TAG = "tag"; // TEXT
- public static final String VALUE = "value"; // TEXT
- public static final String DATE = "date"; // INTEGER
-
- /** Valid tag values. Extend as necessary for your needs. */
- public enum Tag {
- APANIC_CONSOLE,
- APANIC_THREADS,
- AUTOTEST_FAILURE,
- AUTOTEST_SEQUENCE_BEGIN,
- AUTOTEST_SUITE_BEGIN,
- AUTOTEST_TCPDUMP_BEGIN,
- AUTOTEST_TCPDUMP_DATA,
- AUTOTEST_TCPDUMP_END,
- AUTOTEST_TEST_BEGIN,
- AUTOTEST_TEST_FAILURE,
- AUTOTEST_TEST_SUCCESS,
- BROWSER_BUG_REPORT,
- CARRIER_BUG_REPORT,
- CHECKIN_FAILURE,
- CHECKIN_SUCCESS,
- FOTA_BEGIN,
- FOTA_FAILURE,
- FOTA_INSTALL,
- FOTA_PROMPT,
- FOTA_PROMPT_ACCEPT,
- FOTA_PROMPT_REJECT,
- FOTA_PROMPT_SKIPPED,
- GSERVICES_ERROR,
- GSERVICES_UPDATE,
- LOGIN_SERVICE_ACCOUNT_TRIED,
- LOGIN_SERVICE_ACCOUNT_SAVED,
- LOGIN_SERVICE_AUTHENTICATE,
- LOGIN_SERVICE_CAPTCHA_ANSWERED,
- LOGIN_SERVICE_CAPTCHA_SHOWN,
- LOGIN_SERVICE_PASSWORD_ENTERED,
- LOGIN_SERVICE_SWITCH_GOOGLE_MAIL,
- NETWORK_DOWN,
- NETWORK_UP,
- PHONE_UI,
- RADIO_BUG_REPORT,
- SETUP_COMPLETED,
- SETUP_INITIATED,
- SETUP_IO_ERROR,
- SETUP_NETWORK_ERROR,
- SETUP_REQUIRED_CAPTCHA,
- SETUP_RETRIES_EXHAUSTED,
- SETUP_SERVER_ERROR,
- SETUP_SERVER_TIMEOUT,
- SETUP_NO_DATA_NETWORK,
- SYSTEM_BOOT,
- SYSTEM_LAST_KMSG,
- SYSTEM_RECOVERY_LOG,
- SYSTEM_RESTART,
- SYSTEM_SERVICE_LOOPING,
- SYSTEM_TOMBSTONE,
- TEST,
- BATTERY_DISCHARGE_INFO,
- MARKET_DOWNLOAD,
- MARKET_INSTALL,
- MARKET_REMOVE,
- MARKET_REFUND,
- MARKET_UNINSTALL,
- }
- }
-
- /**
- * The stats table is a list of counter values indexed by a tag name.
- * Each statistic has a count and sum fields, so it can track averages.
- * When multiple statistics are inserted with the same tag, the count
- * and sum fields are added together into a single entry in the database.
- */
- public interface Stats extends BaseColumns {
- public static final String TABLE_NAME = "stats";
- public static final Uri CONTENT_URI =
- Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME);
-
- public static final String TAG = "tag"; // TEXT UNIQUE
- public static final String COUNT = "count"; // INTEGER
- public static final String SUM = "sum"; // REAL
-
- /** Valid tag values. Extend as necessary for your needs. */
- public enum Tag {
- BROWSER_SNAP_CENTER,
- BROWSER_TEXT_SIZE_CHANGE,
- BROWSER_ZOOM_OVERVIEW,
-
- CRASHES_REPORTED,
- CRASHES_TRUNCATED,
- ELAPSED_REALTIME_SEC,
- ELAPSED_UPTIME_SEC,
- HTTP_REQUEST,
- HTTP_REUSED,
- HTTP_STATUS,
- PHONE_GSM_REGISTERED,
- PHONE_GPRS_ATTEMPTED,
- PHONE_GPRS_CONNECTED,
- PHONE_RADIO_RESETS,
- TEST,
- NETWORK_RX_MOBILE,
- NETWORK_TX_MOBILE,
- PHONE_CDMA_REGISTERED,
- PHONE_CDMA_DATA_ATTEMPTED,
- PHONE_CDMA_DATA_CONNECTED,
- }
- }
-
- /**
- * The properties table is a set of tagged values sent with every checkin.
- * Unlike statistics or events, they are not cleared after being uploaded.
- * Multiple properties inserted with the same tag overwrite each other.
- */
- public interface Properties extends BaseColumns {
- public static final String TABLE_NAME = "properties";
- public static final Uri CONTENT_URI =
- Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME);
-
- public static final String TAG = "tag"; // TEXT UNIQUE
- public static final String VALUE = "value"; // TEXT
-
- /** Valid tag values, to be extended as necessary. */
- public enum Tag {
- DESIRED_BUILD,
- MARKET_CHECKIN,
- }
- }
-
- /**
- * The crashes table is a log of crash reports, kept separate from the
- * general event log because crashes are large, important, and bursty.
- * Like the events table, the crashes table is pruned on insert.
- */
- public interface Crashes extends BaseColumns {
- public static final String TABLE_NAME = "crashes";
- public static final Uri CONTENT_URI =
- Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME);
-
- // TODO: one or both of these should be a file attachment, not a column
- public static final String DATA = "data"; // TEXT
- public static final String LOGS = "logs"; // TEXT
- }
-
- /**
- * Intents with this action cause a checkin attempt. Normally triggered by
- * a periodic alarm, these may be sent directly to force immediate checkin.
- */
- public interface TriggerIntent {
- public static final String ACTION = "android.server.checkin.CHECKIN";
-
- // The category is used for GTalk service messages
- public static final String CATEGORY = "android.server.checkin.CHECKIN";
-
- // If true indicates that the checkin should only transfer market related data
- public static final String EXTRA_MARKET_ONLY = "market_only";
- }
-
- private static final String TAG = "Checkin";
-
- /**
- * Helper function to log an event to the database.
- *
- * @param resolver from {@link android.content.Context#getContentResolver}
- * @param tag identifying the type of event being recorded
- * @param value associated with event, if any
- * @return URI of the event that was added
- */
- static public Uri logEvent(ContentResolver resolver,
- Events.Tag tag, String value) {
- try {
- // Don't specify the date column; the content provider will add that.
- ContentValues values = new ContentValues();
- values.put(Events.TAG, tag.toString());
- if (value != null) values.put(Events.VALUE, value);
- return resolver.insert(Events.CONTENT_URI, values);
- } catch (IllegalArgumentException e) { // thrown when provider is unavailable.
- Log.w(TAG, "Can't log event " + tag + ": " + e);
- return null;
- } catch (SQLException e) {
- Log.e(TAG, "Can't log event " + tag, e); // Database errors are not fatal.
- return null;
- }
- }
-
- /**
- * Helper function to update statistics in the database.
- * Note that multiple updates to the same tag will be combined.
- *
- * @param tag identifying what is being observed
- * @param count of occurrences
- * @param sum of some value over these occurrences
- * @return URI of the statistic that was returned
- */
- static public Uri updateStats(ContentResolver resolver,
- Stats.Tag tag, int count, double sum) {
- try {
- ContentValues values = new ContentValues();
- values.put(Stats.TAG, tag.toString());
- if (count != 0) values.put(Stats.COUNT, count);
- if (sum != 0.0) values.put(Stats.SUM, sum);
- return resolver.insert(Stats.CONTENT_URI, values);
- } catch (IllegalArgumentException e) { // thrown when provider is unavailable.
- Log.w(TAG, "Can't update stat " + tag + ": " + e);
- return null;
- } catch (SQLException e) {
- Log.e(TAG, "Can't update stat " + tag, e); // Database errors are not fatal.
- return null;
- }
- }
-
- /** Minimum time to wait after a crash failure before trying again. */
- static private final long MIN_CRASH_FAILURE_RETRY = 10000; // 10 seconds
-
- /** {@link SystemClock#elapsedRealtime} of the last time a crash report failed. */
- static private volatile long sLastCrashFailureRealtime = -MIN_CRASH_FAILURE_RETRY;
-}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ee7193b4b83e..14e27eb228a9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1489,6 +1489,74 @@ public final class Settings {
public static final String DEFAULT_INSTALL_LOCATION = "default_install_location";
/**
+ * Show pointer location on screen?
+ * 0 = no
+ * 1 = yes
+ * @hide
+ */
+ public static final String POINTER_LOCATION = "pointer_location";
+
+ /**
+ * Whether to play a sound for low-battery alerts.
+ * @hide
+ */
+ public static final String POWER_SOUNDS_ENABLED = "power_sounds_enabled";
+
+ /**
+ * Whether to play a sound for dock events.
+ * @hide
+ */
+ public static final String DOCK_SOUNDS_ENABLED = "dock_sounds_enabled";
+
+ /**
+ * Whether to play sounds when the keyguard is shown and dismissed.
+ * @hide
+ */
+ public static final String LOCKSCREEN_SOUNDS_ENABLED = "lockscreen_sounds_enabled";
+
+ /**
+ * URI for the low battery sound file.
+ * @hide
+ */
+ public static final String LOW_BATTERY_SOUND = "low_battery_sound";
+
+ /**
+ * URI for the desk dock "in" event sound.
+ * @hide
+ */
+ public static final String DESK_DOCK_SOUND = "desk_dock_sound";
+
+ /**
+ * URI for the desk dock "out" event sound.
+ * @hide
+ */
+ public static final String DESK_UNDOCK_SOUND = "desk_undock_sound";
+
+ /**
+ * URI for the car dock "in" event sound.
+ * @hide
+ */
+ public static final String CAR_DOCK_SOUND = "car_dock_sound";
+
+ /**
+ * URI for the car dock "out" event sound.
+ * @hide
+ */
+ public static final String CAR_UNDOCK_SOUND = "car_undock_sound";
+
+ /**
+ * URI for the "device locked" (keyguard shown) sound.
+ * @hide
+ */
+ public static final String LOCK_SOUND = "lock_sound";
+
+ /**
+ * URI for the "device unlocked" (keyguard dismissed) sound.
+ * @hide
+ */
+ public static final String UNLOCK_SOUND = "unlock_sound";
+
+ /**
* Settings to backup. This is here so that it's in the same place as the settings
* keys and easy to update.
* @hide
@@ -2142,14 +2210,23 @@ public final class Settings {
public static final String NETWORK_PREFERENCE = "network_preference";
/**
+ * Used to disable Tethering on a device - defaults to true
+ * @hide
+ */
+ public static final String TETHER_SUPPORTED = "tether_supported";
+
+ /**
+ * No longer supported.
*/
public static final String PARENTAL_CONTROL_ENABLED = "parental_control_enabled";
/**
+ * No longer supported.
*/
public static final String PARENTAL_CONTROL_LAST_UPDATE = "parental_control_last_update";
/**
+ * No longer supported.
*/
public static final String PARENTAL_CONTROL_REDIRECT_URL = "parental_control_redirect_url";
diff --git a/core/java/android/speech/RecognizerIntent.java b/core/java/android/speech/RecognizerIntent.java
index 241a8b0d7d24..5f651e1ab409 100644
--- a/core/java/android/speech/RecognizerIntent.java
+++ b/core/java/android/speech/RecognizerIntent.java
@@ -208,10 +208,4 @@ public class RecognizerIntent {
* an activity result. In a PendingIntent, the lack of this extra indicates failure.
*/
public static final String EXTRA_RESULTS = "android.speech.extra.RESULTS";
-
- /**
- * Triggers the voice search settings activity.
- */
- public static final String ACTION_VOICE_SEARCH_SETTINGS =
- "android.speech.action.VOICE_SEARCH_SETTINGS";
}
diff --git a/core/java/android/text/AndroidCharacter.java b/core/java/android/text/AndroidCharacter.java
index 6dfd64d2bbe2..af93b5d3772b 100644
--- a/core/java/android/text/AndroidCharacter.java
+++ b/core/java/android/text/AndroidCharacter.java
@@ -22,6 +22,13 @@ package android.text;
*/
public class AndroidCharacter
{
+ public static final int EAST_ASIAN_WIDTH_NEUTRAL = 0;
+ public static final int EAST_ASIAN_WIDTH_AMBIGUOUS = 1;
+ public static final int EAST_ASIAN_WIDTH_HALF_WIDTH = 2;
+ public static final int EAST_ASIAN_WIDTH_FULL_WIDTH = 3;
+ public static final int EAST_ASIAN_WIDTH_NARROW = 4;
+ public static final int EAST_ASIAN_WIDTH_WIDE = 5;
+
/**
* Fill in the first <code>count</code> bytes of <code>dest</code> with the
* directionalities from the first <code>count</code> chars of <code>src</code>.
@@ -30,6 +37,38 @@ public class AndroidCharacter
*/
public native static void getDirectionalities(char[] src, byte[] dest,
int count);
+
+ /**
+ * Calculate the East Asian Width of a character according to
+ * <a href="http://unicode.org/reports/tr11/">Unicode TR#11</a>. The return
+ * will be one of {@link #EAST_ASIAN_WIDTH_NEUTRAL},
+ * {@link #EAST_ASIAN_WIDTH_AMBIGUOUS}, {@link #EAST_ASIAN_WIDTH_HALF_WIDTH},
+ * {@link #EAST_ASIAN_WIDTH_FULL_WIDTH}, {@link #EAST_ASIAN_WIDTH_NARROW},
+ * or {@link #EAST_ASIAN_WIDTH_WIDE}.
+ *
+ * @param input the character to measure
+ * @return the East Asian Width for input
+ */
+ public native static int getEastAsianWidth(char input);
+
+ /**
+ * Fill the first <code>count</code> bytes of <code>dest</code> with the
+ * East Asian Width from the first <code>count</code> chars of
+ * <code>src</code>. East Asian Width is calculated based on
+ * <a href="http://unicode.org/reports/tr11/">Unicode TR#11</a>. Each entry
+ * in <code>dest> will be one of {@link #EAST_ASIAN_WIDTH_NEUTRAL},
+ * {@link #EAST_ASIAN_WIDTH_AMBIGUOUS}, {@link #EAST_ASIAN_WIDTH_HALF_WIDTH},
+ * {@link #EAST_ASIAN_WIDTH_FULL_WIDTH}, {@link #EAST_ASIAN_WIDTH_NARROW},
+ * or {@link #EAST_ASIAN_WIDTH_WIDE}.
+ *
+ * @param src character array of input to measure
+ * @param start first character in array to measure
+ * @param count maximum number of characters to measure
+ * @param dest byte array of results for each character in src
+ */
+ public native static void getEastAsianWidths(char[] src, int start,
+ int count, byte[] dest);
+
/**
* Replace the specified slice of <code>text</code> with the chars'
* right-to-left mirrors (if any), returning true if any
diff --git a/core/java/android/text/util/Rfc822Tokenizer.java b/core/java/android/text/util/Rfc822Tokenizer.java
index 9d8bfd9faa5b..69d745da2cb9 100644
--- a/core/java/android/text/util/Rfc822Tokenizer.java
+++ b/core/java/android/text/util/Rfc822Tokenizer.java
@@ -84,7 +84,7 @@ public class Rfc822Tokenizer implements MultiAutoCompleteTextView.Tokenizer {
if (c == '"') {
i++;
break;
- } else if (c == '\\') {
+ } else if (c == '\\' && i + 1 < cursor) {
name.append(text.charAt(i + 1));
i += 2;
} else {
@@ -110,7 +110,7 @@ public class Rfc822Tokenizer implements MultiAutoCompleteTextView.Tokenizer {
comment.append(c);
level++;
i++;
- } else if (c == '\\') {
+ } else if (c == '\\' && i + 1 < cursor) {
comment.append(text.charAt(i + 1));
i += 2;
} else {
diff --git a/core/java/android/util/base64/Base64.java b/core/java/android/util/base64/Base64.java
new file mode 100644
index 000000000000..f6d3905b207f
--- /dev/null
+++ b/core/java/android/util/base64/Base64.java
@@ -0,0 +1,741 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util.base64;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Utilities for encoding and decoding the Base64 representation of
+ * binary data. See RFCs <a
+ * href="http://www.ietf.org/rfc/rfc2045.txt">2045</a> and <a
+ * href="http://www.ietf.org/rfc/rfc3548.txt">3548</a>.
+ */
+public class Base64 {
+ /**
+ * Default values for encoder/decoder flags.
+ */
+ public static final int DEFAULT = 0;
+
+ /**
+ * Encoder flag bit to omit the padding '=' characters at the end
+ * of the output (if any).
+ */
+ public static final int NO_PADDING = 1;
+
+ /**
+ * Encoder flag bit to omit all line terminators (i.e., the output
+ * will be on one long line).
+ */
+ public static final int NO_WRAP = 2;
+
+ /**
+ * Encoder flag bit to indicate lines should be terminated with a
+ * CRLF pair instead of just an LF. Has no effect if {@code
+ * NO_WRAP} is specified as well.
+ */
+ public static final int CRLF = 4;
+
+ /**
+ * Encoder/decoder flag bit to indicate using the "URL and
+ * filename safe" variant of Base64 (see RFC 3548 section 4) where
+ * {@code -} and {@code _} are used in place of {@code +} and
+ * {@code /}.
+ */
+ public static final int URL_SAFE = 8;
+
+ /**
+ * Flag to pass to {@link Base64OutputStream} to indicate that it
+ * should not close the output stream it is wrapping when it
+ * itself is closed.
+ */
+ public static final int NO_CLOSE = 16;
+
+ // --------------------------------------------------------
+ // shared code
+ // --------------------------------------------------------
+
+ /* package */ static abstract class Coder {
+ public byte[] output;
+ public int op;
+
+ /**
+ * Encode/decode another block of input data. this.output is
+ * provided by the caller, and must be big enough to hold all
+ * the coded data. On exit, this.opwill be set to the length
+ * of the coded data.
+ *
+ * @param finish true if this is the final call to process for
+ * this object. Will finalize the coder state and
+ * include any final bytes in the output.
+ *
+ * @return true if the input so far is good; false if some
+ * error has been detected in the input stream..
+ */
+ public abstract boolean process(byte[] input, int offset, int len, boolean finish);
+
+ /**
+ * @return the maximum number of bytes a call to process()
+ * could produce for the given number of input bytes. This may
+ * be an overestimate.
+ */
+ public abstract int maxOutputSize(int len);
+ }
+
+ // --------------------------------------------------------
+ // decoding
+ // --------------------------------------------------------
+
+ /**
+ * Decode the Base64-encoded data in input and return the data in
+ * a new byte array.
+ *
+ * <p>The padding '=' characters at the end are considered optional, but
+ * if any are present, there must be the correct number of them.
+ *
+ * @param str the input String to decode, which is converted to
+ * bytes using the default charset
+ * @param flags controls certain features of the decoded output.
+ * Pass {@code DEFAULT} to decode standard Base64.
+ *
+ * @throws IllegalArgumentException if the input contains
+ * incorrect padding
+ */
+ public static byte[] decode(String str, int flags) {
+ return decode(str.getBytes(), flags);
+ }
+
+ /**
+ * Decode the Base64-encoded data in input and return the data in
+ * a new byte array.
+ *
+ * <p>The padding '=' characters at the end are considered optional, but
+ * if any are present, there must be the correct number of them.
+ *
+ * @param input the input array to decode
+ * @param flags controls certain features of the decoded output.
+ * Pass {@code DEFAULT} to decode standard Base64.
+ *
+ * @throws IllegalArgumentException if the input contains
+ * incorrect padding
+ */
+ public static byte[] decode(byte[] input, int flags) {
+ return decode(input, 0, input.length, flags);
+ }
+
+ /**
+ * Decode the Base64-encoded data in input and return the data in
+ * a new byte array.
+ *
+ * <p>The padding '=' characters at the end are considered optional, but
+ * if any are present, there must be the correct number of them.
+ *
+ * @param input the data to decode
+ * @param offset the position within the input array at which to start
+ * @param len the number of bytes of input to decode
+ * @param flags controls certain features of the decoded output.
+ * Pass {@code DEFAULT} to decode standard Base64.
+ *
+ * @throws IllegalArgumentException if the input contains
+ * incorrect padding
+ */
+ public static byte[] decode(byte[] input, int offset, int len, int flags) {
+ // Allocate space for the most data the input could represent.
+ // (It could contain less if it contains whitespace, etc.)
+ Decoder decoder = new Decoder(flags, new byte[len*3/4]);
+
+ if (!decoder.process(input, offset, len, true)) {
+ throw new IllegalArgumentException("bad base-64");
+ }
+
+ // Maybe we got lucky and allocated exactly enough output space.
+ if (decoder.op == decoder.output.length) {
+ return decoder.output;
+ }
+
+ // Need to shorten the array, so allocate a new one of the
+ // right size and copy.
+ byte[] temp = new byte[decoder.op];
+ System.arraycopy(decoder.output, 0, temp, 0, decoder.op);
+ return temp;
+ }
+
+ /* package */ static class Decoder extends Coder {
+ /**
+ * Lookup table for turning bytes into their position in the
+ * Base64 alphabet.
+ */
+ private static final int DECODE[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ };
+
+ /**
+ * Decode lookup table for the "web safe" variant (RFC 3548
+ * sec. 4) where - and _ replace + and /.
+ */
+ private static final int DECODE_WEBSAFE[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ };
+
+ /** Non-data values in the DECODE arrays. */
+ private static final int SKIP = -1;
+ private static final int EQUALS = -2;
+
+ /**
+ * States 0-3 are reading through the next input tuple.
+ * State 4 is having read one '=' and expecting exactly
+ * one more.
+ * State 5 is expecting no more data or padding characters
+ * in the input.
+ * State 6 is the error state; an error has been detected
+ * in the input and no future input can "fix" it.
+ */
+ private int state; // state number (0 to 6)
+ private int value;
+
+ final private int[] alphabet;
+
+ public Decoder(int flags, byte[] output) {
+ this.output = output;
+
+ alphabet = ((flags & URL_SAFE) == 0) ? DECODE : DECODE_WEBSAFE;
+ state = 0;
+ value = 0;
+ }
+
+ /**
+ * @return an overestimate for the number of bytes {@code
+ * len} bytes could decode to.
+ */
+ public int maxOutputSize(int len) {
+ return len * 3/4 + 10;
+ }
+
+ /**
+ * Decode another block of input data.
+ *
+ * @return true if the state machine is still healthy. false if
+ * bad base-64 data has been detected in the input stream.
+ */
+ public boolean process(byte[] input, int offset, int len, boolean finish) {
+ if (this.state == 6) return false;
+
+ int p = offset;
+ len += offset;
+
+ // Using local variables makes the decoder about 12%
+ // faster than if we manipulate the member variables in
+ // the loop. (Even alphabet makes a measurable
+ // difference, which is somewhat surprising to me since
+ // the member variable is final.)
+ int state = this.state;
+ int value = this.value;
+ int op = 0;
+ final byte[] output = this.output;
+ final int[] alphabet = this.alphabet;
+
+ while (p < len) {
+ // Try the fast path: we're starting a new tuple and the
+ // next four bytes of the input stream are all data
+ // bytes. This corresponds to going through states
+ // 0-1-2-3-0. We expect to use this method for most of
+ // the data.
+ //
+ // If any of the next four bytes of input are non-data
+ // (whitespace, etc.), value will end up negative. (All
+ // the non-data values in decode are small negative
+ // numbers, so shifting any of them up and or'ing them
+ // together will result in a value with its top bit set.)
+ //
+ // You can remove this whole block and the output should
+ // be the same, just slower.
+ if (state == 0) {
+ while (p+4 <= len &&
+ (value = ((alphabet[input[p] & 0xff] << 18) |
+ (alphabet[input[p+1] & 0xff] << 12) |
+ (alphabet[input[p+2] & 0xff] << 6) |
+ (alphabet[input[p+3] & 0xff]))) >= 0) {
+ output[op+2] = (byte) value;
+ output[op+1] = (byte) (value >> 8);
+ output[op] = (byte) (value >> 16);
+ op += 3;
+ p += 4;
+ }
+ if (p >= len) break;
+ }
+
+ // The fast path isn't available -- either we've read a
+ // partial tuple, or the next four input bytes aren't all
+ // data, or whatever. Fall back to the slower state
+ // machine implementation.
+
+ int d = alphabet[input[p++] & 0xff];
+
+ switch (state) {
+ case 0:
+ if (d >= 0) {
+ value = d;
+ ++state;
+ } else if (d != SKIP) {
+ this.state = 6;
+ return false;
+ }
+ break;
+
+ case 1:
+ if (d >= 0) {
+ value = (value << 6) | d;
+ ++state;
+ } else if (d != SKIP) {
+ this.state = 6;
+ return false;
+ }
+ break;
+
+ case 2:
+ if (d >= 0) {
+ value = (value << 6) | d;
+ ++state;
+ } else if (d == EQUALS) {
+ // Emit the last (partial) output tuple;
+ // expect exactly one more padding character.
+ output[op++] = (byte) (value >> 4);
+ state = 4;
+ } else if (d != SKIP) {
+ this.state = 6;
+ return false;
+ }
+ break;
+
+ case 3:
+ if (d >= 0) {
+ // Emit the output triple and return to state 0.
+ value = (value << 6) | d;
+ output[op+2] = (byte) value;
+ output[op+1] = (byte) (value >> 8);
+ output[op] = (byte) (value >> 16);
+ op += 3;
+ state = 0;
+ } else if (d == EQUALS) {
+ // Emit the last (partial) output tuple;
+ // expect no further data or padding characters.
+ output[op+1] = (byte) (value >> 2);
+ output[op] = (byte) (value >> 10);
+ op += 2;
+ state = 5;
+ } else if (d != SKIP) {
+ this.state = 6;
+ return false;
+ }
+ break;
+
+ case 4:
+ if (d == EQUALS) {
+ ++state;
+ } else if (d != SKIP) {
+ this.state = 6;
+ return false;
+ }
+ break;
+
+ case 5:
+ if (d != SKIP) {
+ this.state = 6;
+ return false;
+ }
+ break;
+ }
+ }
+
+ if (!finish) {
+ // We're out of input, but a future call could provide
+ // more.
+ this.state = state;
+ this.value = value;
+ this.op = op;
+ return true;
+ }
+
+ // Done reading input. Now figure out where we are left in
+ // the state machine and finish up.
+
+ switch (state) {
+ case 0:
+ // Output length is a multiple of three. Fine.
+ break;
+ case 1:
+ // Read one extra input byte, which isn't enough to
+ // make another output byte. Illegal.
+ this.state = 6;
+ return false;
+ case 2:
+ // Read two extra input bytes, enough to emit 1 more
+ // output byte. Fine.
+ output[op++] = (byte) (value >> 4);
+ break;
+ case 3:
+ // Read three extra input bytes, enough to emit 2 more
+ // output bytes. Fine.
+ output[op++] = (byte) (value >> 10);
+ output[op++] = (byte) (value >> 2);
+ break;
+ case 4:
+ // Read one padding '=' when we expected 2. Illegal.
+ this.state = 6;
+ return false;
+ case 5:
+ // Read all the padding '='s we expected and no more.
+ // Fine.
+ break;
+ }
+
+ this.state = state;
+ this.op = op;
+ return true;
+ }
+ }
+
+ // --------------------------------------------------------
+ // encoding
+ // --------------------------------------------------------
+
+ /**
+ * Base64-encode the given data and return a newly allocated
+ * String with the result.
+ *
+ * @param input the data to encode
+ * @param flags controls certain features of the encoded output.
+ * Passing {@code DEFAULT} results in output that
+ * adheres to RFC 2045.
+ */
+ public static String encodeToString(byte[] input, int flags) {
+ try {
+ return new String(encode(input, flags), "US-ASCII");
+ } catch (UnsupportedEncodingException e) {
+ // US-ASCII is guaranteed to be available.
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * Base64-encode the given data and return a newly allocated
+ * String with the result.
+ *
+ * @param input the data to encode
+ * @param offset the position within the input array at which to
+ * start
+ * @param len the number of bytes of input to encode
+ * @param flags controls certain features of the encoded output.
+ * Passing {@code DEFAULT} results in output that
+ * adheres to RFC 2045.
+ */
+ public static String encodeToString(byte[] input, int offset, int len, int flags) {
+ try {
+ return new String(encode(input, offset, len, flags), "US-ASCII");
+ } catch (UnsupportedEncodingException e) {
+ // US-ASCII is guaranteed to be available.
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * Base64-encode the given data and return a newly allocated
+ * byte[] with the result.
+ *
+ * @param input the data to encode
+ * @param flags controls certain features of the encoded output.
+ * Passing {@code DEFAULT} results in output that
+ * adheres to RFC 2045.
+ */
+ public static byte[] encode(byte[] input, int flags) {
+ return encode(input, 0, input.length, flags);
+ }
+
+ /**
+ * Base64-encode the given data and return a newly allocated
+ * byte[] with the result.
+ *
+ * @param input the data to encode
+ * @param offset the position within the input array at which to
+ * start
+ * @param len the number of bytes of input to encode
+ * @param flags controls certain features of the encoded output.
+ * Passing {@code DEFAULT} results in output that
+ * adheres to RFC 2045.
+ */
+ public static byte[] encode(byte[] input, int offset, int len, int flags) {
+ Encoder encoder = new Encoder(flags, null);
+
+ // Compute the exact length of the array we will produce.
+ int output_len = len / 3 * 4;
+
+ // Account for the tail of the data and the padding bytes, if any.
+ if (encoder.do_padding) {
+ if (len % 3 > 0) {
+ output_len += 4;
+ }
+ } else {
+ switch (len % 3) {
+ case 0: break;
+ case 1: output_len += 2; break;
+ case 2: output_len += 3; break;
+ }
+ }
+
+ // Account for the newlines, if any.
+ if (encoder.do_newline && len > 0) {
+ output_len += (((len-1) / (3 * Encoder.LINE_GROUPS)) + 1) *
+ (encoder.do_cr ? 2 : 1);
+ }
+
+ encoder.output = new byte[output_len];
+ encoder.process(input, offset, len, true);
+
+ assert encoder.op == output_len;
+
+ return encoder.output;
+ }
+
+ /* package */ static class Encoder extends Coder {
+ /**
+ * Emit a new line every this many output tuples. Corresponds to
+ * a 76-character line length (the maximum allowable according to
+ * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>).
+ */
+ public static final int LINE_GROUPS = 19;
+
+ /**
+ * Lookup table for turning Base64 alphabet positions (6 bits)
+ * into output bytes.
+ */
+ private static final byte ENCODE[] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
+ };
+
+ /**
+ * Lookup table for turning Base64 alphabet positions (6 bits)
+ * into output bytes.
+ */
+ private static final byte ENCODE_WEBSAFE[] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_',
+ };
+
+ final private byte[] tail;
+ /* package */ int tailLen;
+ private int count;
+
+ final public boolean do_padding;
+ final public boolean do_newline;
+ final public boolean do_cr;
+ final private byte[] alphabet;
+
+ public Encoder(int flags, byte[] output) {
+ this.output = output;
+
+ do_padding = (flags & NO_PADDING) == 0;
+ do_newline = (flags & NO_WRAP) == 0;
+ do_cr = (flags & CRLF) != 0;
+ alphabet = ((flags & URL_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE;
+
+ tail = new byte[2];
+ tailLen = 0;
+
+ count = do_newline ? LINE_GROUPS : -1;
+ }
+
+ /**
+ * @return an overestimate for the number of bytes {@code
+ * len} bytes could encode to.
+ */
+ public int maxOutputSize(int len) {
+ return len * 8/5 + 10;
+ }
+
+ public boolean process(byte[] input, int offset, int len, boolean finish) {
+ // Using local variables makes the encoder about 9% faster.
+ final byte[] alphabet = this.alphabet;
+ final byte[] output = this.output;
+ int op = 0;
+ int count = this.count;
+
+ int p = offset;
+ len += offset;
+ int v = -1;
+
+ // First we need to concatenate the tail of the previous call
+ // with any input bytes available now and see if we can empty
+ // the tail.
+
+ switch (tailLen) {
+ case 0:
+ // There was no tail.
+ break;
+
+ case 1:
+ if (p+2 <= len) {
+ // A 1-byte tail with at least 2 bytes of
+ // input available now.
+ v = ((tail[0] & 0xff) << 16) |
+ ((input[p++] & 0xff) << 8) |
+ (input[p++] & 0xff);
+ tailLen = 0;
+ };
+ break;
+
+ case 2:
+ if (p+1 <= len) {
+ // A 2-byte tail with at least 1 byte of input.
+ v = ((tail[0] & 0xff) << 16) |
+ ((tail[1] & 0xff) << 8) |
+ (input[p++] & 0xff);
+ tailLen = 0;
+ }
+ break;
+ }
+
+ if (v != -1) {
+ output[op++] = alphabet[(v >> 18) & 0x3f];
+ output[op++] = alphabet[(v >> 12) & 0x3f];
+ output[op++] = alphabet[(v >> 6) & 0x3f];
+ output[op++] = alphabet[v & 0x3f];
+ if (--count == 0) {
+ if (do_cr) output[op++] = '\r';
+ output[op++] = '\n';
+ count = LINE_GROUPS;
+ }
+ }
+
+ // At this point either there is no tail, or there are fewer
+ // than 3 bytes of input available.
+
+ // The main loop, turning 3 input bytes into 4 output bytes on
+ // each iteration.
+ while (p+3 <= len) {
+ v = ((input[p] & 0xff) << 16) |
+ ((input[p+1] & 0xff) << 8) |
+ (input[p+2] & 0xff);
+ output[op] = alphabet[(v >> 18) & 0x3f];
+ output[op+1] = alphabet[(v >> 12) & 0x3f];
+ output[op+2] = alphabet[(v >> 6) & 0x3f];
+ output[op+3] = alphabet[v & 0x3f];
+ p += 3;
+ op += 4;
+ if (--count == 0) {
+ if (do_cr) output[op++] = '\r';
+ output[op++] = '\n';
+ count = LINE_GROUPS;
+ }
+ }
+
+ if (finish) {
+ // Finish up the tail of the input. Note that we need to
+ // consume any bytes in tail before any bytes
+ // remaining in input; there should be at most two bytes
+ // total.
+
+ if (p-tailLen == len-1) {
+ int t = 0;
+ v = ((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 4;
+ tailLen -= t;
+ output[op++] = alphabet[(v >> 6) & 0x3f];
+ output[op++] = alphabet[v & 0x3f];
+ if (do_padding) {
+ output[op++] = '=';
+ output[op++] = '=';
+ }
+ if (do_newline) {
+ if (do_cr) output[op++] = '\r';
+ output[op++] = '\n';
+ }
+ } else if (p-tailLen == len-2) {
+ int t = 0;
+ v = (((tailLen > 1 ? tail[t++] : input[p++]) & 0xff) << 10) |
+ (((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 2);
+ tailLen -= t;
+ output[op++] = alphabet[(v >> 12) & 0x3f];
+ output[op++] = alphabet[(v >> 6) & 0x3f];
+ output[op++] = alphabet[v & 0x3f];
+ if (do_padding) {
+ output[op++] = '=';
+ }
+ if (do_newline) {
+ if (do_cr) output[op++] = '\r';
+ output[op++] = '\n';
+ }
+ } else if (do_newline && op > 0 && count != LINE_GROUPS) {
+ if (do_cr) output[op++] = '\r';
+ output[op++] = '\n';
+ }
+
+ assert tailLen == 0;
+ assert p == len;
+ } else {
+ // Save the leftovers in tail to be consumed on the next
+ // call to encodeInternal.
+
+ if (p == len-1) {
+ tail[tailLen++] = input[p];
+ } else if (p == len-2) {
+ tail[tailLen++] = input[p];
+ tail[tailLen++] = input[p+1];
+ }
+ }
+
+ this.op = op;
+ this.count = count;
+
+ return true;
+ }
+ }
+
+ private Base64() { } // don't instantiate
+}
diff --git a/common/java/com/android/common/Base64InputStream.java b/core/java/android/util/base64/Base64InputStream.java
index 1969bc49565a..935939e097c5 100644
--- a/common/java/com/android/common/Base64InputStream.java
+++ b/core/java/android/util/base64/Base64InputStream.java
@@ -14,28 +14,24 @@
* limitations under the License.
*/
-package com.android.common;
+package android.util.base64;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
- * An OutputStream that does either Base64 encoding or decoding on the
- * data written to it, writing the resulting data to another
- * OutputStream.
+ * An InputStream that does Base64 decoding on the data read through
+ * it.
*/
public class Base64InputStream extends FilterInputStream {
- private final boolean encode;
- private final Base64.EncoderState estate;
- private final Base64.DecoderState dstate;
+ private final Base64.Coder coder;
private static byte[] EMPTY = new byte[0];
private static final int BUFFER_SIZE = 2048;
private boolean eof;
private byte[] inputBuffer;
- private byte[] outputBuffer;
private int outputStart;
private int outputEnd;
@@ -47,8 +43,8 @@ public class Base64InputStream extends FilterInputStream {
* @param flags bit flags for controlling the decoder; see the
* constants in {@link Base64}
*/
- public Base64InputStream(InputStream out, int flags) {
- this(out, flags, false);
+ public Base64InputStream(InputStream in, int flags) {
+ this(in, flags, false);
}
/**
@@ -59,25 +55,19 @@ public class Base64InputStream extends FilterInputStream {
* @param flags bit flags for controlling the decoder; see the
* constants in {@link Base64}
* @param encode true to encode, false to decode
+ *
+ * @hide
*/
- public Base64InputStream(InputStream out, int flags, boolean encode) {
- super(out);
- this.encode = encode;
+ public Base64InputStream(InputStream in, int flags, boolean encode) {
+ super(in);
eof = false;
inputBuffer = new byte[BUFFER_SIZE];
if (encode) {
- // len*8/5+10 is an overestimate of the most bytes the
- // encoder can produce for len bytes of input.
- outputBuffer = new byte[BUFFER_SIZE * 8/5 + 10];
- estate = new Base64.EncoderState(flags, outputBuffer);
- dstate = null;
+ coder = new Base64.Encoder(flags, null);
} else {
- // len*3/4+10 is an overestimate of the most bytes the
- // decoder can produce for len bytes of input.
- outputBuffer = new byte[BUFFER_SIZE * 3/4 + 10];
- estate = null;
- dstate = new Base64.DecoderState(flags, outputBuffer);
+ coder = new Base64.Decoder(flags, null);
}
+ coder.output = new byte[coder.maxOutputSize(BUFFER_SIZE)];
outputStart = 0;
outputEnd = 0;
}
@@ -122,7 +112,7 @@ public class Base64InputStream extends FilterInputStream {
if (outputStart >= outputEnd) {
return -1;
} else {
- return outputBuffer[outputStart++];
+ return coder.output[outputStart++];
}
}
@@ -134,36 +124,30 @@ public class Base64InputStream extends FilterInputStream {
return -1;
}
int bytes = Math.min(len, outputEnd-outputStart);
- System.arraycopy(outputBuffer, outputStart, b, off, bytes);
+ System.arraycopy(coder.output, outputStart, b, off, bytes);
outputStart += bytes;
return bytes;
}
/**
* Read data from the input stream into inputBuffer, then
- * decode/encode it into the empty outputBuffer, and reset the
+ * decode/encode it into the empty coder.output, and reset the
* outputStart and outputEnd pointers.
*/
private void refill() throws IOException {
if (eof) return;
int bytesRead = in.read(inputBuffer);
- if (encode) {
- if (bytesRead == -1) {
- eof = true;
- Base64.encodeInternal(EMPTY, 0, 0, estate, true);
- } else {
- Base64.encodeInternal(inputBuffer, 0, bytesRead, estate, false);
- }
- outputEnd = estate.op;
+ boolean success;
+ if (bytesRead == -1) {
+ eof = true;
+ success = coder.process(EMPTY, 0, 0, true);
} else {
- if (bytesRead == -1) {
- eof = true;
- Base64.decodeInternal(EMPTY, 0, 0, dstate, true);
- } else {
- Base64.decodeInternal(inputBuffer, 0, bytesRead, dstate, false);
- }
- outputEnd = dstate.op;
+ success = coder.process(inputBuffer, 0, bytesRead, false);
+ }
+ if (!success) {
+ throw new IOException("bad base-64");
}
+ outputEnd = coder.op;
outputStart = 0;
}
}
diff --git a/common/java/com/android/common/Base64OutputStream.java b/core/java/android/util/base64/Base64OutputStream.java
index 76e1b6a78793..35e9a2b8cf84 100644
--- a/common/java/com/android/common/Base64OutputStream.java
+++ b/core/java/android/util/base64/Base64OutputStream.java
@@ -14,21 +14,18 @@
* limitations under the License.
*/
-package com.android.common;
+package android.util.base64;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
- * An OutputStream that does either Base64 encoding or decoding on the
- * data written to it, writing the resulting data to another
- * OutputStream.
+ * An OutputStream that does Base64 encoding on the data written to
+ * it, writing the resulting data to another OutputStream.
*/
public class Base64OutputStream extends FilterOutputStream {
- private final boolean encode;
- private final Base64.EncoderState estate;
- private final Base64.DecoderState dstate;
+ private final Base64.Coder coder;
private final int flags;
private byte[] buffer = null;
@@ -57,17 +54,16 @@ public class Base64OutputStream extends FilterOutputStream {
* @param flags bit flags for controlling the encoder; see the
* constants in {@link Base64}
* @param encode true to encode, false to decode
+ *
+ * @hide
*/
public Base64OutputStream(OutputStream out, int flags, boolean encode) {
super(out);
this.flags = flags;
- this.encode = encode;
if (encode) {
- estate = new Base64.EncoderState(flags, null);
- dstate = null;
+ coder = new Base64.Encoder(flags, null);
} else {
- estate = null;
- dstate = new Base64.DecoderState(flags, null);
+ coder = new Base64.Decoder(flags, null);
}
}
@@ -106,12 +102,28 @@ public class Base64OutputStream extends FilterOutputStream {
}
public void close() throws IOException {
- flushBuffer();
- internalWrite(EMPTY, 0, 0, true);
- if ((flags & Base64.NO_CLOSE) == 0) {
- out.close();
- } else {
- out.flush();
+ IOException thrown = null;
+ try {
+ flushBuffer();
+ internalWrite(EMPTY, 0, 0, true);
+ } catch (IOException e) {
+ thrown = e;
+ }
+
+ try {
+ if ((flags & Base64.NO_CLOSE) == 0) {
+ out.close();
+ } else {
+ out.flush();
+ }
+ } catch (IOException e) {
+ if (thrown != null) {
+ thrown = e;
+ }
+ }
+
+ if (thrown != null) {
+ throw thrown;
}
}
@@ -122,21 +134,11 @@ public class Base64OutputStream extends FilterOutputStream {
* encoder/decoder state to be finalized.
*/
private void internalWrite(byte[] b, int off, int len, boolean finish) throws IOException {
- if (encode) {
- // len*8/5+10 is an overestimate of the most bytes the
- // encoder can produce for len bytes of input.
- estate.output = embiggen(estate.output, len*8/5+10);
- Base64.encodeInternal(b, off, len, estate, finish);
- out.write(estate.output, 0, estate.op);
- } else {
- // len*3/4+10 is an overestimate of the most bytes the
- // decoder can produce for len bytes of input.
- dstate.output = embiggen(dstate.output, len*3/4+10);
- if (!Base64.decodeInternal(b, off, len, dstate, finish)) {
- throw new IOException("bad base-64");
- }
- out.write(dstate.output, 0, dstate.op);
+ coder.output = embiggen(coder.output, coder.maxOutputSize(len));
+ if (!coder.process(b, off, len, finish)) {
+ throw new IOException("bad base-64");
}
+ out.write(coder.output, 0, coder.op);
}
/**
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index 3c79200410f1..58f998ea564f 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -465,10 +465,10 @@ public class GestureDetector {
case MotionEvent.ACTION_POINTER_UP:
// Ending a multitouch gesture and going back to 1 finger
if (mIgnoreMultitouch && ev.getPointerCount() == 2) {
- int id = (((action & MotionEvent.ACTION_POINTER_ID_MASK)
- >> MotionEvent.ACTION_POINTER_ID_SHIFT) == 0) ? 1 : 0;
- mLastMotionX = ev.getX(id);
- mLastMotionY = ev.getY(id);
+ int index = (((action & MotionEvent.ACTION_POINTER_INDEX_MASK)
+ >> MotionEvent.ACTION_POINTER_INDEX_SHIFT) == 0) ? 1 : 0;
+ mLastMotionX = ev.getX(index);
+ mLastMotionY = ev.getY(index);
mVelocityTracker.recycle();
mVelocityTracker = VelocityTracker.obtain();
}
diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java
index ccbd8d4877bf..d31c8dc0e222 100644
--- a/core/java/android/view/HapticFeedbackConstants.java
+++ b/core/java/android/view/HapticFeedbackConstants.java
@@ -34,13 +34,18 @@ public class HapticFeedbackConstants {
* The user has pressed on a virtual on-screen key.
*/
public static final int VIRTUAL_KEY = 1;
-
+
/**
* The user has hit the barrier point while scrolling a view.
*/
public static final int SCROLL_BARRIER = 2;
/**
+ * The user has pressed a soft keyboard key.
+ */
+ public static final int KEYBOARD_TAP = 3;
+
+ /**
* This is a private constant. Feel free to renumber as desired.
* @hide
*/
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index ca907af108dc..d648e96693c7 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -76,61 +76,81 @@ public final class MotionEvent implements Parcelable {
public static final int ACTION_POINTER_DOWN = 5;
/**
- * Synonym for {@link #ACTION_POINTER_DOWN} with
- * {@link #ACTION_POINTER_ID_MASK} of 0: the primary pointer has gone done.
+ * A non-primary pointer has gone up. The bits in
+ * {@link #ACTION_POINTER_ID_MASK} indicate which pointer changed.
*/
- public static final int ACTION_POINTER_1_DOWN = ACTION_POINTER_DOWN | 0x0000;
+ public static final int ACTION_POINTER_UP = 6;
/**
- * Synonym for {@link #ACTION_POINTER_DOWN} with
- * {@link #ACTION_POINTER_ID_MASK} of 1: the secondary pointer has gone done.
+ * Bits in the action code that represent a pointer index, used with
+ * {@link #ACTION_POINTER_DOWN} and {@link #ACTION_POINTER_UP}. Shifting
+ * down by {@link #ACTION_POINTER_INDEX_SHIFT} provides the actual pointer
+ * index where the data for the pointer going up or down can be found; you can
+ * get its identifier with {@link #getPointerId(int)} and the actual
+ * data with {@link #getX(int)} etc.
*/
- public static final int ACTION_POINTER_2_DOWN = ACTION_POINTER_DOWN | 0x0100;
+ public static final int ACTION_POINTER_INDEX_MASK = 0xff00;
/**
- * Synonym for {@link #ACTION_POINTER_DOWN} with
- * {@link #ACTION_POINTER_ID_MASK} of 2: the tertiary pointer has gone done.
+ * Bit shift for the action bits holding the pointer index as
+ * defined by {@link #ACTION_POINTER_INDEX_MASK}.
*/
- public static final int ACTION_POINTER_3_DOWN = ACTION_POINTER_DOWN | 0x0200;
+ public static final int ACTION_POINTER_INDEX_SHIFT = 8;
/**
- * A non-primary pointer has gone up. The bits in
- * {@link #ACTION_POINTER_ID_MASK} indicate which pointer changed.
+ * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
+ * data index associated with {@link #ACTION_POINTER_DOWN}.
*/
- public static final int ACTION_POINTER_UP = 6;
+ @Deprecated
+ public static final int ACTION_POINTER_1_DOWN = ACTION_POINTER_DOWN | 0x0000;
+
+ /**
+ * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
+ * data index associated with {@link #ACTION_POINTER_DOWN}.
+ */
+ @Deprecated
+ public static final int ACTION_POINTER_2_DOWN = ACTION_POINTER_DOWN | 0x0100;
/**
- * Synonym for {@link #ACTION_POINTER_UP} with
- * {@link #ACTION_POINTER_ID_MASK} of 0: the primary pointer has gone up.
+ * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
+ * data index associated with {@link #ACTION_POINTER_DOWN}.
*/
+ @Deprecated
+ public static final int ACTION_POINTER_3_DOWN = ACTION_POINTER_DOWN | 0x0200;
+
+ /**
+ * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
+ * data index associated with {@link #ACTION_POINTER_UP}.
+ */
+ @Deprecated
public static final int ACTION_POINTER_1_UP = ACTION_POINTER_UP | 0x0000;
/**
- * Synonym for {@link #ACTION_POINTER_UP} with
- * {@link #ACTION_POINTER_ID_MASK} of 1: the secondary pointer has gone up.
+ * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
+ * data index associated with {@link #ACTION_POINTER_UP}.
*/
+ @Deprecated
public static final int ACTION_POINTER_2_UP = ACTION_POINTER_UP | 0x0100;
/**
- * Synonym for {@link #ACTION_POINTER_UP} with
- * {@link #ACTION_POINTER_ID_MASK} of 2: the tertiary pointer has gone up.
+ * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
+ * data index associated with {@link #ACTION_POINTER_UP}.
*/
+ @Deprecated
public static final int ACTION_POINTER_3_UP = ACTION_POINTER_UP | 0x0200;
/**
- * Bits in the action code that represent a pointer ID, used with
- * {@link #ACTION_POINTER_DOWN} and {@link #ACTION_POINTER_UP}. Pointer IDs
- * start at 0, with 0 being the primary (first) pointer in the motion. Note
- * that this not <em>not</em> an index into the array of pointer values,
- * which is compacted to only contain pointers that are down; the pointer
- * ID for a particular index can be found with {@link #findPointerIndex}.
+ * @deprecated Renamed to {@link #ACTION_POINTER_INDEX_MASK} to match
+ * the actual data contained in these bits.
*/
+ @Deprecated
public static final int ACTION_POINTER_ID_MASK = 0xff00;
/**
- * Bit shift for the action bits holding the pointer identifier as
- * defined by {@link #ACTION_POINTER_ID_MASK}.
+ * @deprecated Renamed to {@link #ACTION_POINTER_INDEX_SHIFT} to match
+ * the actual data contained in these bits.
*/
+ @Deprecated
public static final int ACTION_POINTER_ID_SHIFT = 8;
private static final boolean TRACK_RECYCLED_LOCATION = false;
@@ -618,13 +638,39 @@ 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
- * {@link #ACTION_CANCEL}.
+ * {@link #ACTION_CANCEL}. Consider using {@link #getActionMasked}
+ * and {@link #getActionIndex} to retrieve the separate masked action
+ * and pointer index.
*/
public final int getAction() {
return mAction;
}
/**
+ * Return the masked action being performed, without pointer index
+ * information. May be any of the actions: {@link #ACTION_DOWN},
+ * {@link #ACTION_MOVE}, {@link #ACTION_UP}, {@link #ACTION_CANCEL},
+ * {@link #ACTION_POINTER_DOWN}, or {@link #ACTION_POINTER_UP}.
+ * Use {@link #getActionIndex} to return the index associated with
+ * pointer actions.
+ */
+ public final int getActionMasked() {
+ return mAction & ACTION_MASK;
+ }
+
+ /**
+ * For {@link #ACTION_POINTER_DOWN} or {@link #ACTION_POINTER_UP}
+ * as returned by {@link #getActionMasked}, this returns the associated
+ * pointer index. The index may be used with {@link #getPointerId(int)},
+ * {@link #getX(int)}, {@link #getY(int)}, {@link #getPressure(int)},
+ * and {@link #getSize(int)} to get information about the pointer that has
+ * gone down or up.
+ */
+ public final int getActionIndex() {
+ return (mAction & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT;
+ }
+
+ /**
* Returns the time (in ms) when the user originally pressed down to start
* a stream of position events.
*/
diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java
index 9a8ee02a8077..91fd6f1a509c 100644
--- a/core/java/android/view/VelocityTracker.java
+++ b/core/java/android/view/VelocityTracker.java
@@ -124,24 +124,37 @@ public final class VelocityTracker implements Poolable<VelocityTracker> {
* @param ev The MotionEvent you received and would like to track.
*/
public void addMovement(MotionEvent ev) {
- long time = ev.getEventTime();
final int N = ev.getHistorySize();
final int pointerCount = ev.getPointerCount();
- for (int p = 0; p < pointerCount; p++) {
- for (int i=0; i<N; i++) {
- addPoint(p, ev.getHistoricalX(p, i), ev.getHistoricalY(p, i),
- ev.getHistoricalEventTime(i));
+ int touchIndex = (mLastTouch + 1) % NUM_PAST;
+ for (int i=0; i<N; i++) {
+ for (int id = 0; id < MotionEvent.BASE_AVAIL_POINTERS; id++) {
+ mPastTime[id][touchIndex] = 0;
+ }
+ for (int p = 0; p < pointerCount; p++) {
+ int id = ev.getPointerId(p);
+ mPastX[id][touchIndex] = ev.getHistoricalX(p, i);
+ mPastY[id][touchIndex] = ev.getHistoricalY(p, i);
+ mPastTime[id][touchIndex] = ev.getHistoricalEventTime(i);
}
- addPoint(p, ev.getX(p), ev.getY(p), time);
+
+ touchIndex = (touchIndex + 1) % NUM_PAST;
+ }
+
+ // During calculation any pointer values with a time of 0 are treated
+ // as a break in input. Initialize all to 0 for each new touch index.
+ for (int id = 0; id < MotionEvent.BASE_AVAIL_POINTERS; id++) {
+ mPastTime[id][touchIndex] = 0;
+ }
+ final long time = ev.getEventTime();
+ for (int p = 0; p < pointerCount; p++) {
+ int id = ev.getPointerId(p);
+ mPastX[id][touchIndex] = ev.getX(p);
+ mPastY[id][touchIndex] = ev.getY(p);
+ mPastTime[id][touchIndex] = time;
}
- }
- private void addPoint(int pos, float x, float y, long time) {
- final int lastTouch = (mLastTouch + 1) % NUM_PAST;
- mPastX[pos][lastTouch] = x;
- mPastY[pos][lastTouch] = y;
- mPastTime[pos][lastTouch] = time;
- mLastTouch = lastTouch;
+ mLastTouch = touchIndex;
}
/**
@@ -177,10 +190,12 @@ public final class VelocityTracker implements Poolable<VelocityTracker> {
// find oldest acceptable time
int oldestTouch = lastTouch;
if (pastTime[lastTouch] > 0) { // cleared ?
- oldestTouch = (lastTouch + 1) % NUM_PAST;
final float acceptableTime = pastTime[lastTouch] - LONGEST_PAST_TIME;
- while (pastTime[oldestTouch] < acceptableTime) {
- oldestTouch = (oldestTouch + 1) % NUM_PAST;
+ int nextOldestTouch = (NUM_PAST + oldestTouch - 1) % NUM_PAST;
+ while (pastTime[nextOldestTouch] >= acceptableTime &&
+ nextOldestTouch != lastTouch) {
+ oldestTouch = nextOldestTouch;
+ nextOldestTouch = (NUM_PAST + oldestTouch - 1) % NUM_PAST;
}
}
@@ -241,25 +256,25 @@ public final class VelocityTracker implements Poolable<VelocityTracker> {
* Retrieve the last computed X velocity. You must first call
* {@link #computeCurrentVelocity(int)} before calling this function.
*
- * @param pos Which pointer's velocity to return.
+ * @param id Which pointer's velocity to return.
* @return The previously computed X velocity.
*
* @hide Pending API approval
*/
- public float getXVelocity(int pos) {
- return mXVelocity[pos];
+ public float getXVelocity(int id) {
+ return mXVelocity[id];
}
/**
* Retrieve the last computed Y velocity. You must first call
* {@link #computeCurrentVelocity(int)} before calling this function.
*
- * @param pos Which pointer's velocity to return.
+ * @param id Which pointer's velocity to return.
* @return The previously computed Y velocity.
*
* @hide Pending API approval
*/
- public float getYVelocity(int pos) {
- return mYVelocity[pos];
+ public float getYVelocity(int id) {
+ return mYVelocity[id];
}
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index cdf9eb0c513a..2ed623dcf8ed 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3398,7 +3398,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
/**
* Special value for the height or width requested by a View.
- * MATCH_PARENT means that the view wants to be as bigas its parent,
+ * MATCH_PARENT means that the view wants to be as big as its parent,
* minus the parent's padding, if any.
*/
public static final int MATCH_PARENT = -1;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 7bc5cced2115..ab3260e13f6c 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -851,6 +851,11 @@ public interface WindowManagerPolicy {
*/
public boolean isCheekPressedAgainstScreen(MotionEvent ev);
+ /**
+ * Called every time the window manager is dispatching a pointer event.
+ */
+ public void dispatchedPointerEventLw(MotionEvent ev, int targetX, int targetY);
+
public void setCurrentOrientationLw(int newOrientation);
/**
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 9e9cc7e508eb..d1ad61fa9bdc 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -116,7 +116,7 @@ import java.util.ArrayList;
* @param webView The WebView that created this.
*/
/* package */ WebTextView(Context context, WebView webView) {
- super(context);
+ super(context, null, com.android.internal.R.attr.webTextViewStyle);
mWebView = webView;
mMaxLength = -1;
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9148a18324f0..ae6c6660d80c 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -5893,6 +5893,10 @@ public class WebView extends AbsoluteLayout
}
break;
case UPDATE_TEXT_SELECTION_MSG_ID:
+ // If no textfield was in focus, and the user touched one,
+ // causing it to send this message, then WebTextView has not
+ // been set up yet. Rebuild it so it can set its selection.
+ rebuildWebTextView();
if (inEditingMode()
&& mWebTextView.isSameTextField(msg.arg1)
&& msg.arg2 == mTextGeneration) {
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index 57aca240502b..1532db194262 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -16,9 +16,13 @@
package android.widget;
-import android.text.*;
-import android.text.method.*;
import android.content.Context;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.TextUtils;
+import android.text.method.ArrowKeyMovementMethod;
+import android.text.method.MovementMethod;
import android.util.AttributeSet;
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 30a38df954e2..b9acf5ec38b5 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1856,8 +1856,11 @@ public class GridView extends AbsListView {
final int top = view.getTop();
int height = view.getHeight();
if (height > 0) {
- final int whichRow = mFirstPosition / mNumColumns;
- return Math.max(whichRow * 100 - (top * 100) / height, 0);
+ final int numColumns = mNumColumns;
+ final int whichRow = mFirstPosition / numColumns;
+ final int rowCount = (mItemCount + numColumns - 1) / numColumns;
+ return Math.max(whichRow * 100 - (top * 100) / height +
+ (int) ((float) mScrollY / getHeight() * rowCount * 100), 0);
}
}
return 0;
@@ -1868,7 +1871,12 @@ public class GridView extends AbsListView {
// TODO: Account for vertical spacing too
final int numColumns = mNumColumns;
final int rowCount = (mItemCount + numColumns - 1) / numColumns;
- return Math.max(rowCount * 100, 0);
+ int result = Math.max(rowCount * 100, 0);
+ if (mScrollY != 0) {
+ // Compensate for overscroll
+ result += Math.abs((int) ((float) mScrollY / getHeight() * rowCount * 100));
+ }
+ return result;
}
}
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index c62724c75341..a7b819a57850 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -890,14 +890,15 @@ public class HorizontalScrollView extends FrameLayout {
*/
@Override
protected int computeHorizontalScrollRange() {
- int count = getChildCount();
+ final int count = getChildCount();
+ final int contentWidth = getWidth() - mPaddingLeft - mPaddingRight;
if (count == 0) {
- return getWidth();
+ return contentWidth;
}
int scrollRange = getChildAt(0).getRight();
- int scrollX = mScrollX;
- int overscrollRight = scrollRange - getWidth() - mPaddingLeft - mPaddingRight;
+ final int scrollX = mScrollX;
+ final int overscrollRight = Math.max(0, scrollRange - contentWidth);
if (scrollX < 0) {
scrollRange -= scrollX;
} else if (scrollX > overscrollRight) {
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index ea5841a01641..9fcb8299e412 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -16,6 +16,8 @@
package android.widget;
+import com.android.internal.R;
+
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
@@ -25,8 +27,6 @@ import android.view.ViewDebug;
import android.view.ViewGroup;
import android.widget.RemoteViews.RemoteView;
-import com.android.internal.R;
-
/**
* A Layout that arranges its children in a single column or a single row. The direction of
@@ -366,14 +366,15 @@ public class LinearLayout extends ViewGroup {
int oldHeight = Integer.MIN_VALUE;
if (lp.height == 0 && lp.weight > 0) {
- // heightMode is either UNSPECIFIED OR AT_MOST, and this child
- // wanted to stretch to fill available space. Translate that to
- // WRAP_CONTENT so that it does not end up with a height of 0
- oldHeight = 0;
- lp.height = LayoutParams.WRAP_CONTENT;
+ // heightMode is either UNSPECIFIED or AT_MOST, and this
+ // child wanted to stretch to fill available space.
+ // Translate that to WRAP_CONTENT so that it does not end up
+ // with a height of 0
+ oldHeight = 0;
+ lp.height = LayoutParams.WRAP_CONTENT;
}
- // Determine how big this child would like to. If this or
+ // Determine how big this child would like to be. If this or
// previous children have given a weight, then we allow it to
// use all available space (and we will shrink things later
// if needed).
@@ -673,7 +674,8 @@ public class LinearLayout extends ViewGroup {
int oldWidth = Integer.MIN_VALUE;
if (lp.width == 0 && lp.weight > 0) {
- // widthMode is either UNSPECIFIED OR AT_MOST, and this child
+ // widthMode is either UNSPECIFIED or AT_MOST, and this
+ // child
// wanted to stretch to fill available space. Translate that to
// WRAP_CONTENT so that it does not end up with a width of 0
oldWidth = 0;
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 2ee7ad5517f9..52ed11d6d069 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -892,14 +892,15 @@ public class ScrollView extends FrameLayout {
*/
@Override
protected int computeVerticalScrollRange() {
- int count = getChildCount();
+ final int count = getChildCount();
+ final int contentHeight = getHeight() - mPaddingBottom - mPaddingTop;
if (count == 0) {
- return getHeight();
+ return contentHeight;
}
int scrollRange = getChildAt(0).getBottom();
- int scrollY = mScrollY;
- int overscrollBottom = scrollRange - getHeight() - mPaddingBottom - mPaddingTop;
+ final int scrollY = mScrollY;
+ final int overscrollBottom = Math.max(0, scrollRange - contentHeight);
if (scrollY < 0) {
scrollRange -= scrollY;
} else if (scrollY > overscrollBottom) {
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index 78e2fee3b4d2..d4d90635f49e 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -16,6 +16,8 @@
package android.widget;
+import com.android.internal.R;
+
import android.app.LocalActivityManager;
import android.content.Context;
import android.content.Intent;
@@ -33,8 +35,6 @@ import android.view.Window;
import java.util.ArrayList;
import java.util.List;
-import com.android.internal.R;
-
/**
* Container for a tabbed window view. This object holds two children: a set of tab labels that the
* user clicks to select a specific tab, and a FrameLayout object that displays the contents of that
@@ -624,7 +624,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
}
public void tabClosed() {
- mTabContent.setVisibility(View.INVISIBLE);
+ mTabContent.setVisibility(View.GONE);
}
}
diff --git a/core/java/android/widget/TableLayout.java b/core/java/android/widget/TableLayout.java
index 66500a33227d..73760acdb253 100644
--- a/core/java/android/widget/TableLayout.java
+++ b/core/java/android/widget/TableLayout.java
@@ -575,6 +575,16 @@ public class TableLayout extends LinearLayout {
final int totalExtraSpace = size - totalWidth;
int extraSpace = totalExtraSpace / count;
+ // Column's widths are changed: force child table rows to re-measure.
+ // (done by super.measureVertical after shrinkAndStretchColumns.)
+ final int nbChildren = getChildCount();
+ for (int i = 0; i < nbChildren; i++) {
+ View child = getChildAt(i);
+ if (child instanceof TableRow) {
+ child.forceLayout();
+ }
+ }
+
if (!allColumns) {
for (int i = 0; i < count; i++) {
int column = columns.keyAt(i);
diff --git a/core/java/android/widget/TableRow.java b/core/java/android/widget/TableRow.java
index abf08bfed273..48d12df8eb16 100644
--- a/core/java/android/widget/TableRow.java
+++ b/core/java/android/widget/TableRow.java
@@ -22,8 +22,8 @@ import android.util.AttributeSet;
import android.util.SparseIntArray;
import android.view.Gravity;
import android.view.View;
-import android.view.ViewGroup;
import android.view.ViewDebug;
+import android.view.ViewGroup;
/**
diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl
index 726e28f51551..c0e95875fcdb 100755
--- a/core/java/com/android/internal/app/IMediaContainerService.aidl
+++ b/core/java/com/android/internal/app/IMediaContainerService.aidl
@@ -25,4 +25,5 @@ interface IMediaContainerService {
String key, String resFileName);
boolean copyResource(in Uri packageURI,
in ParcelFileDescriptor outStream);
+ int getRecommendedInstallLocation(in Uri fileUri);
} \ No newline at end of file
diff --git a/core/java/com/android/internal/app/TetherActivity.java b/core/java/com/android/internal/app/TetherActivity.java
index cb268b378883..a48ccf9a2104 100644
--- a/core/java/com/android/internal/app/TetherActivity.java
+++ b/core/java/com/android/internal/app/TetherActivity.java
@@ -32,16 +32,19 @@ import android.widget.Toast;
import android.util.Log;
/**
- * This activity is shown to the user for him/her to connect/disconnect a Tether
- * connection. It will display notification when a suitable connection is made
- * to allow the tether to be setup. A second notification will be show when a
- * tether is active, allowing the user to manage tethered connections.
+ * This activity is shown to the user in two cases: when a connection is possible via
+ * a usb tether and when any type of tether is connected. In the connecting case
+ * It allows them to start a USB tether. In the Tethered/disconnecting case it
+ * will disconnect all tethers.
*/
public class TetherActivity extends AlertActivity implements
DialogInterface.OnClickListener {
private static final int POSITIVE_BUTTON = AlertDialog.BUTTON1;
+ // count of the number of tethered connections at activity create time.
+ private int mTethered;
+
/* Used to detect when the USB cable is unplugged, so we can call finish() */
private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
@Override
@@ -52,8 +55,6 @@ public class TetherActivity extends AlertActivity implements
}
};
- private boolean mWantTethering;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -61,17 +62,18 @@ public class TetherActivity extends AlertActivity implements
// determine if we advertise tethering or untethering
ConnectivityManager cm =
(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
- if (cm.getTetheredIfaces().length > 0) {
- mWantTethering = false;
- } else if (cm.getTetherableIfaces().length > 0) {
- mWantTethering = true;
- } else {
+ mTethered = cm.getTetheredIfaces().length;
+ int tetherable = cm.getTetherableIfaces().length;
+ if ((mTethered == 0) && (tetherable == 0)) {
finish();
return;
}
- // Set up the "dialog"
- if (mWantTethering == true) {
+ // Set up the dialog
+ // if we have a tethered connection we put up a "Do you want to Disconect" dialog
+ // otherwise we must have a tetherable interface (else we'd return above)
+ // and so we want to put up the "do you want to connect" dialog
+ if (mTethered == 0) {
mAlertParams.mIconId = com.android.internal.R.drawable.ic_dialog_usb;
mAlertParams.mTitle = getString(com.android.internal.R.string.tether_title);
mAlertParams.mMessage = getString(com.android.internal.R.string.tether_message);
@@ -114,17 +116,36 @@ public class TetherActivity extends AlertActivity implements
* {@inheritDoc}
*/
public void onClick(DialogInterface dialog, int which) {
+ boolean error = false;
if (which == POSITIVE_BUTTON) {
- ConnectivityManager connManager =
+ ConnectivityManager cm =
(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
// start/stop tethering
- if (mWantTethering) {
- if (!connManager.tether("ppp0")) {
+ String[] tethered = cm.getTetheredIfaces();
+
+ if (tethered.length == 0) {
+ String[] tetherable = cm.getTetherableIfaces();
+ String[] usbRegexs = cm.getTetherableUsbRegexs();
+ for (String t : tetherable) {
+ for (String r : usbRegexs) {
+ if (t.matches(r)) {
+ if (!cm.tether(t))
+ error = true;
+ break;
+ }
+ }
+ }
+ if (error) {
showTetheringError();
}
} else {
- if (!connManager.untether("ppp0")) {
+ for (String t : tethered) {
+ if (!cm.untether("ppp0")) {
+ error = true;
+ }
+ }
+ if (error) {
showUnTetheringError();
}
}
@@ -134,7 +155,12 @@ public class TetherActivity extends AlertActivity implements
}
private void handleTetherStateChanged(Intent intent) {
- finish();
+ // determine if we advertise tethering or untethering
+ ConnectivityManager cm =
+ (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (mTethered != cm.getTetheredIfaces().length) {
+ finish();
+ }
}
private void showTetheringError() {
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
new file mode 100644
index 000000000000..c5b869bca0fa
--- /dev/null
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -0,0 +1,182 @@
+/*
+ * 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.content;
+
+import android.os.storage.IMountService;
+
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.storage.StorageResultCode;
+import android.util.Log;
+
+import java.io.File;
+
+/**
+ * Constants used internally between the PackageManager
+ * and media container service transports.
+ * Some utility methods to invoke MountService api.
+ */
+public class PackageHelper {
+ public static final int RECOMMEND_INSTALL_INTERNAL = 1;
+ public static final int RECOMMEND_INSTALL_EXTERNAL = 2;
+ public static final int RECOMMEND_FAILED_INSUFFICIENT_STORAGE = -1;
+ public static final int RECOMMEND_FAILED_INVALID_APK = -2;
+ private static final boolean DEBUG_SD_INSTALL = true;
+ private static final String TAG = "PackageHelper";
+
+ public static IMountService getMountService() {
+ IBinder service = ServiceManager.getService("mount");
+ if (service != null) {
+ return IMountService.Stub.asInterface(service);
+ } else {
+ Log.e(TAG, "Can't get mount service");
+ }
+ return null;
+ }
+
+ public static String createSdDir(File tmpPackageFile, String cid,
+ String sdEncKey, int uid) {
+ // Create mount point via MountService
+ IMountService mountService = getMountService();
+ long len = tmpPackageFile.length();
+ int mbLen = (int) (len/(1024*1024));
+ if ((len - (mbLen * 1024 * 1024)) > 0) {
+ mbLen++;
+ }
+ if (DEBUG_SD_INSTALL) Log.i(TAG, "Size of resource " + mbLen);
+
+ try {
+ int rc = mountService.createSecureContainer(
+ cid, mbLen, "vfat", sdEncKey, uid);
+ if (rc != StorageResultCode.OperationSucceeded) {
+ Log.e(TAG, "Failed to create secure container " + cid);
+ return null;
+ }
+ String cachePath = mountService.getSecureContainerPath(cid);
+ if (DEBUG_SD_INSTALL) Log.i(TAG, "Created secure container " + cid +
+ " at " + cachePath);
+ return cachePath;
+ } catch (RemoteException e) {
+ Log.e(TAG, "MountService running?");
+ }
+ return null;
+ }
+
+ public static String mountSdDir(String cid, String key, int ownerUid) {
+ try {
+ int rc = getMountService().mountSecureContainer(cid, key, ownerUid);
+ if (rc != StorageResultCode.OperationSucceeded) {
+ Log.i(TAG, "Failed to mount container " + cid + " rc : " + rc);
+ return null;
+ }
+ return getMountService().getSecureContainerPath(cid);
+ } catch (RemoteException e) {
+ Log.e(TAG, "MountService running?");
+ }
+ return null;
+ }
+
+ public static boolean unMountSdDir(String cid) {
+ try {
+ int rc = getMountService().unmountSecureContainer(cid);
+ if (rc != StorageResultCode.OperationSucceeded) {
+ Log.e(TAG, "Failed to unmount " + cid + " with rc " + rc);
+ return false;
+ }
+ return true;
+ } catch (RemoteException e) {
+ Log.e(TAG, "MountService running?");
+ }
+ return false;
+ }
+
+ public static boolean renameSdDir(String oldId, String newId) {
+ try {
+ int rc = getMountService().renameSecureContainer(oldId, newId);
+ if (rc != StorageResultCode.OperationSucceeded) {
+ Log.e(TAG, "Failed to rename " + oldId + " to " +
+ newId + "with rc " + rc);
+ return false;
+ }
+ return true;
+ } catch (RemoteException e) {
+ Log.i(TAG, "Failed ot rename " + oldId + " to " + newId +
+ " with exception : " + e);
+ }
+ return false;
+ }
+
+ public static String getSdDir(String cid) {
+ try {
+ return getMountService().getSecureContainerPath(cid);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to get container path for " + cid +
+ " with exception " + e);
+ }
+ return null;
+ }
+
+ public static boolean finalizeSdDir(String cid) {
+ try {
+ int rc = getMountService().finalizeSecureContainer(cid);
+ if (rc != StorageResultCode.OperationSucceeded) {
+ Log.i(TAG, "Failed to finalize container " + cid);
+ return false;
+ }
+ return true;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to finalize container " + cid +
+ " with exception " + e);
+ }
+ return false;
+ }
+
+ public static boolean destroySdDir(String cid) {
+ try {
+ int rc = getMountService().destroySecureContainer(cid);
+ if (rc != StorageResultCode.OperationSucceeded) {
+ Log.i(TAG, "Failed to destroy container " + cid);
+ return false;
+ }
+ return true;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to destroy container " + cid +
+ " with exception " + e);
+ }
+ return false;
+ }
+
+ public static String[] getSecureContainerList() {
+ try {
+ return getMountService().getSecureContainerList();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to get secure container list with exception" +
+ e);
+ }
+ return null;
+ }
+
+ public static boolean isContainerMounted(String cid) {
+ try {
+ return getMountService().isSecureContainerMounted(cid);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to find out if container " + cid + " mounted");
+ }
+ return false;
+ }
+}
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 57a28e6d4759..c134d884e21a 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -22,7 +22,6 @@ import android.app.IActivityManager;
import android.os.Build;
import android.os.Debug;
import android.os.IBinder;
-import android.os.ICheckinService;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
diff --git a/core/java/com/android/internal/util/HierarchicalStateMachine.java b/core/java/com/android/internal/util/HierarchicalStateMachine.java
index a1c5078b567a..b4af79c00e1e 100644
--- a/core/java/com/android/internal/util/HierarchicalStateMachine.java
+++ b/core/java/com/android/internal/util/HierarchicalStateMachine.java
@@ -1021,7 +1021,7 @@ public class HierarchicalStateMachine {
* @param msg that couldn't be handled.
*/
protected void unhandledMessage(Message msg) {
- Log.e(TAG, "unhandledMessage: msg.what=" + msg.what);
+ Log.e(TAG, mName + " - unhandledMessage: msg.what=" + msg.what);
}
/**
diff --git a/core/java/com/google/android/net/ParentalControl.java b/core/java/com/google/android/net/ParentalControl.java
deleted file mode 100644
index 71a3958ef52f..000000000000
--- a/core/java/com/google/android/net/ParentalControl.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.net;
-
-import android.os.ICheckinService;
-import android.os.IParentalControlCallback;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.util.Log;
-
-public class ParentalControl {
- /**
- * Strings to identify your app. To enable parental control checking for
- * new apps, please add it here, and configure GServices accordingly.
- */
- public static final String VENDING = "vending";
- public static final String YOUTUBE = "youtube";
-
- /**
- * This interface is supplied to getParentalControlState and is callback upon with
- * the state of parental control.
- */
- public interface Callback {
- /**
- * This method will be called when the state of parental control is known. If state is
- * null, then the state of parental control is unknown.
- * @param state The state of parental control.
- */
- void onResult(ParentalControlState state);
- }
-
- private static class RemoteCallback extends IParentalControlCallback.Stub {
- private Callback mCallback;
-
- public RemoteCallback(Callback callback) {
- mCallback = callback;
- }
-
- public void onResult(ParentalControlState state) {
- if (mCallback != null) {
- mCallback.onResult(state);
- }
- }
- };
-
- public static void getParentalControlState(Callback callback,
- String requestingApp) {
- ICheckinService service =
- ICheckinService.Stub.asInterface(ServiceManager.getService("checkin"));
-
- RemoteCallback remoteCallback = new RemoteCallback(callback);
- try {
- service.getParentalControlState(remoteCallback, requestingApp);
- } catch (RemoteException e) {
- // This should never happen.
- Log.e("ParentalControl", "Failed to talk to the checkin service.");
- }
- }
-}
diff --git a/core/java/com/google/android/net/ParentalControlState.aidl b/core/java/com/google/android/net/ParentalControlState.aidl
deleted file mode 100644
index ed1326ad9d28..000000000000
--- a/core/java/com/google/android/net/ParentalControlState.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.net;
-parcelable ParentalControlState;
diff --git a/core/java/com/google/android/net/ParentalControlState.java b/core/java/com/google/android/net/ParentalControlState.java
deleted file mode 100644
index 162a1f632b97..000000000000
--- a/core/java/com/google/android/net/ParentalControlState.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.net;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class ParentalControlState implements Parcelable {
- public boolean isEnabled;
- public String redirectUrl;
-
- /**
- * Used to read a ParentalControlStatus from a Parcel.
- */
- public static final Parcelable.Creator<ParentalControlState> CREATOR =
- new Parcelable.Creator<ParentalControlState>() {
- public ParentalControlState createFromParcel(Parcel source) {
- ParentalControlState status = new ParentalControlState();
- status.isEnabled = (source.readInt() == 1);
- status.redirectUrl = source.readString();
- return status;
- }
-
- public ParentalControlState[] newArray(int size) {
- return new ParentalControlState[size];
- }
- };
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(isEnabled ? 1 : 0);
- dest.writeString(redirectUrl);
- }
-
- @Override
- public String toString() {
- return isEnabled + ", " + redirectUrl;
- }
-};
diff --git a/core/jni/android/graphics/YuvToJpegEncoder.cpp b/core/jni/android/graphics/YuvToJpegEncoder.cpp
index ef5c9aeb6142..e6a18728b4c5 100644
--- a/core/jni/android/graphics/YuvToJpegEncoder.cpp
+++ b/core/jni/android/graphics/YuvToJpegEncoder.cpp
@@ -1,16 +1,17 @@
#include "CreateJavaOutputStreamAdaptor.h"
#include "SkJpegUtility.h"
#include "YuvToJpegEncoder.h"
-#include "ui/PixelFormat.h"
+#include <ui/PixelFormat.h>
+#include <hardware/hardware.h>
#include <jni.h>
YuvToJpegEncoder* YuvToJpegEncoder::create(int format, int* strides) {
// Only PIXEL_FORMAT_YCbCr_420_SP and PIXEl_FOMAT_YCbCr_422_I are supported
// for now.
- if (format == android::PIXEL_FORMAT_YCbCr_420_SP) {
+ if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP) {
return new Yuv420SpToJpegEncoder(strides);
- } else if (format == android::PIXEL_FORMAT_YCbCr_422_I) {
+ } else if (format == HAL_PIXEL_FORMAT_YCbCr_422_I) {
return new Yuv422IToJpegEncoder(strides);
} else {
return NULL;
diff --git a/core/jni/android_text_AndroidCharacter.cpp b/core/jni/android_text_AndroidCharacter.cpp
index 450cee2df16c..1353478f39f4 100644
--- a/core/jni/android_text_AndroidCharacter.cpp
+++ b/core/jni/android_text_AndroidCharacter.cpp
@@ -20,8 +20,33 @@
#include <jni.h>
#include <android_runtime/AndroidRuntime.h>
#include "utils/misc.h"
-#include "utils/AndroidUnicode.h"
#include "utils/Log.h"
+#include "unicode/uchar.h"
+
+#define PROPERTY_UNDEFINED (-1)
+
+// ICU => JDK mapping
+static int directionality_map[U_CHAR_DIRECTION_COUNT] = {
+ 0, // U_LEFT_TO_RIGHT (0) => DIRECTIONALITY_LEFT_TO_RIGHT (0)
+ 1, // U_RIGHT_TO_LEFT (1) => DIRECTIONALITY_RIGHT_TO_LEFT (1)
+ 3, // U_EUROPEAN_NUMBER (2) => DIRECTIONALITY_EUROPEAN_NUMBER (3)
+ 4, // U_EUROPEAN_NUMBER_SEPARATOR (3) => DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR (4)
+ 5, // U_EUROPEAN_NUMBER_TERMINATOR (4) => DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR (5)
+ 6, // U_ARABIC_NUMBER (5) => DIRECTIONALITY_ARABIC_NUMBER (6)
+ 7, // U_COMMON_NUMBER_SEPARATOR (6) => DIRECTIONALITY_COMMON_NUMBER_SEPARATOR (7)
+ 10, // U_BLOCK_SEPARATOR (7) => DIRECTIONALITY_PARAGRAPH_SEPARATOR (10)
+ 11, // U_SEGMENT_SEPARATOR (8) => DIRECTIONALITY_SEGMENT_SEPARATOR (11)
+ 12, // U_WHITE_SPACE_NEUTRAL (9) => DIRECTIONALITY_WHITESPACE (12)
+ 13, // U_OTHER_NEUTRAL (10) => DIRECTIONALITY_OTHER_NEUTRALS (13)
+ 14, // U_LEFT_TO_RIGHT_EMBEDDING (11) => DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING (14)
+ 15, // U_LEFT_TO_RIGHT_OVERRIDE (12) => DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE (15)
+ 2, // U_RIGHT_TO_LEFT_ARABIC (13) => DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC (2)
+ 16, // U_RIGHT_TO_LEFT_EMBEDDING (14) => DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING (16)
+ 17, // U_RIGHT_TO_LEFT_OVERRIDE (15) => DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE (17)
+ 18, // U_POP_DIRECTIONAL_FORMAT (16) => DIRECTIONALITY_POP_DIRECTIONAL_FORMAT (18)
+ 8, // U_DIR_NON_SPACING_MARK (17) => DIRECTIONALITY_NONSPACING_MARK (8)
+ 9, // U_BOUNDARY_NEUTRAL (18) => DIRECTIONALITY_BOUNDARY_NEUTRAL (9)
+};
namespace android {
@@ -53,15 +78,21 @@ static void getDirectionalities(JNIEnv* env, jobject obj, jcharArray srcArray, j
src[i + 1] >= 0xDC00 && src[i + 1] <= 0xDFFF) {
int c = 0x00010000 + ((src[i] - 0xD800) << 10) +
(src[i + 1] & 0x3FF);
- int dir = android::Unicode::getDirectionality(c);
+ int dir = u_charDirection(c);
+ if (dir < 0 || dir >= U_CHAR_DIRECTION_COUNT)
+ dir = PROPERTY_UNDEFINED;
+ else
+ dir = directionality_map[dir];
dest[i++] = dir;
dest[i] = dir;
} else {
int c = src[i];
- int dir = android::Unicode::getDirectionality(c);
-
- dest[i] = dir;
+ int dir = u_charDirection(c);
+ if (dir < 0 || dir >= U_CHAR_DIRECTION_COUNT)
+ dest[i] = PROPERTY_UNDEFINED;
+ else
+ dest[i] = directionality_map[dir];
}
}
@@ -70,6 +101,60 @@ DIRECTION_END:
env->ReleaseByteArrayElements(destArray, dest, JNI_ABORT);
}
+static jint getEastAsianWidth(JNIEnv* env, jobject obj, jchar input)
+{
+ int width = u_getIntPropertyValue(input, UCHAR_EAST_ASIAN_WIDTH);
+ if (width < 0 || width >= U_EA_COUNT)
+ width = PROPERTY_UNDEFINED;
+
+ return width;
+}
+
+static void getEastAsianWidths(JNIEnv* env, jobject obj, jcharArray srcArray,
+ int start, int count, jbyteArray destArray)
+{
+ jchar* src = env->GetCharArrayElements(srcArray, NULL);
+ jbyte* dest = env->GetByteArrayElements(destArray, NULL);
+ if (src == NULL || dest == NULL) {
+ jniThrowException(env, "java/lang/NullPointerException", NULL);
+ goto EA_END;
+ }
+
+ if (start < 0 || start > start + count
+ || env->GetArrayLength(srcArray) < (start + count)
+ || env->GetArrayLength(destArray) < count) {
+ jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
+ goto EA_END;
+ }
+
+ for (int i = 0; i < count; i++) {
+ const int srci = start + i;
+ if (src[srci] >= 0xD800 && src[srci] <= 0xDBFF &&
+ i + 1 < count &&
+ src[srci + 1] >= 0xDC00 && src[srci + 1] <= 0xDFFF) {
+ int c = 0x00010000 + ((src[srci] - 0xD800) << 10) +
+ (src[srci + 1] & 0x3FF);
+ int width = u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH);
+ if (width < 0 || width >= U_EA_COUNT)
+ width = PROPERTY_UNDEFINED;
+
+ dest[i++] = width;
+ dest[i] = width;
+ } else {
+ int c = src[srci];
+ int width = u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH);
+ if (width < 0 || width >= U_EA_COUNT)
+ width = PROPERTY_UNDEFINED;
+
+ dest[i] = width;
+ }
+ }
+
+EA_END:
+ env->ReleaseCharArrayElements(srcArray, src, JNI_ABORT);
+ env->ReleaseByteArrayElements(destArray, dest, JNI_ABORT);
+}
+
static jboolean mirror(JNIEnv* env, jobject obj, jcharArray charArray, int start, int count)
{
jchar* data = env->GetCharArrayElements(charArray, NULL);
@@ -89,7 +174,7 @@ static jboolean mirror(JNIEnv* env, jobject obj, jcharArray charArray, int start
// XXX this thinks it knows that surrogates are never mirrored
int c1 = data[i];
- int c2 = android::Unicode::toMirror(c1);
+ int c2 = u_charMirror(c1);
if (c1 != c2) {
data[i] = c2;
@@ -104,12 +189,16 @@ MIRROR_END:
static jchar getMirror(JNIEnv* env, jobject obj, jchar c)
{
- return android::Unicode::toMirror(c);
+ return u_charMirror(c);
}
static JNINativeMethod gMethods[] = {
{ "getDirectionalities", "([C[BI)V",
(void*) getDirectionalities },
+ { "getEastAsianWidth", "(C)I",
+ (void*) getEastAsianWidth },
+ { "getEastAsianWidths", "([CII[B)V",
+ (void*) getEastAsianWidths },
{ "mirror", "([CII)Z",
(void*) mirror },
{ "getMirror", "(C)C",
diff --git a/core/jni/android_text_format_Time.cpp b/core/jni/android_text_format_Time.cpp
index d89a7e68a9fd..c152aa8351af 100644
--- a/core/jni/android_text_format_Time.cpp
+++ b/core/jni/android_text_format_Time.cpp
@@ -584,9 +584,9 @@ static jboolean android_text_format_Time_parse3339(JNIEnv* env,
inUtc = true;
if (offset != 0) {
- if (len < tz_index + 5) {
+ if (len < tz_index + 6) {
char msg[100];
- sprintf(msg, "Unexpected length; should be %d characters", tz_index + 5);
+ sprintf(msg, "Unexpected length; should be %d characters", tz_index + 6);
jniThrowException(env, "android/util/TimeFormatException", msg);
return false;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f5f5a27274dc..a27d28f6138a 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1161,13 +1161,6 @@
android:description="@string/permdesc_backup"
android:protectionLevel="signatureOrSystem" />
- <!-- Allows an application to participate in the backup and restore process
- @hide -->
- <permission android:name="android.permission.BACKUP_DATA"
- android:label="@string/permlab_backup_data"
- android:description="@string/permdesc_backup_data"
- android:protectionLevel="signatureOrSystem" />
-
<!-- Allows an application to tell the AppWidget service which application
can access AppWidget's data. The normal user flow is that a user
picks an AppWidget to go into a particular host, thereby giving that
@@ -1234,6 +1227,13 @@
android:description="@string/permlab_copyProtectedData"
android:protectionLevel="signature" />
+ <!-- Push messaging permission.
+ @hide Used internally.
+ -->
+ <permission android:name="android.intent.category.MASTER_CLEAR.permission.PUSH_MESSAGE"
+ android:protectionLevel="signature" />
+ <uses-permission android:name="android.intent.category.MASTER_CLEAR.permission.PUSH_MESSAGE"/>
+
<application android:process="system"
android:persistent="true"
android:hasCode="false"
@@ -1316,7 +1316,7 @@
<action android:name="android.intent.action.MASTER_CLEAR" />
<!-- MCS always uses REMOTE_INTENT: category=MASTER_CLEAR -->
- <action android:name="android.intent.action.REMOTE_INTENT" />
+ <action android:name="com.google.android.pushmessaging.intent.RECEIVE" />
<category android:name="android.intent.category.MASTER_CLEAR" />
</intent-filter>
</receiver>
diff --git a/core/res/res/anim/cycle_interpolator.xml b/core/res/res/anim/cycle_interpolator.xml
new file mode 100644
index 000000000000..70ebcb1b6db7
--- /dev/null
+++ b/core/res/res/anim/cycle_interpolator.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<cycleInterpolator />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index ff8cdc9d392b..0f6a5c1cb985 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -396,6 +396,8 @@
<attr name="tabWidgetStyle" format="reference" />
<!-- Default TextView style. -->
<attr name="textViewStyle" format="reference" />
+ <!-- Default WebTextView style. -->
+ <attr name="webTextViewStyle" format="reference" />
<!-- Default WebView style. -->
<attr name="webViewStyle" format="reference" />
<!-- Default style for drop down items. -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 7bd07a5739b5..5d561b8601dd 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -70,6 +70,22 @@
<item>"0,1"</item>
</string-array>
+ <!-- List of regexpressions describing the interface (if any) that represent tetherable
+ USB interfaces. If the device doesn't want to support tething over USB this should
+ be empty. An example would be "usb.*" -->
+ <string-array translatable="false" name="config_tether_usb_regexs">
+ </string-array>
+
+ <!-- List of regexpressions describing the interface (if any) that represent tetherable
+ Wifi interfaces. If the device doesn't want to support tethering over Wifi this
+ should be empty. An example would be "softap.*" -->
+ <string-array translatable="false" name="config_tether_wifi_regexs">
+ </string-array>
+
+ <!-- Dhcp range (min, max) to use for tethering purposes -->
+ <string-array name="config_tether_dhcp_range">
+ </string-array>
+
<!-- Flag indicating whether the keyguard should be bypassed when
the slider is open. This can be set or unset depending how easily
the slider can be opened (for example, in a pocket or purse). -->
@@ -138,6 +154,11 @@
<item>30</item>
</integer-array>
+ <!-- Vibrator pattern for a very short but reliable vibration for soft keyboard tap -->
+ <integer-array name="config_keyboardTapVibePattern">
+ <item>40</item>
+ </integer-array>
+
<!-- Vibrator pattern for feedback about booting with safe mode disabled -->
<integer-array name="config_safeModeDisabledVibePattern">
<item>0</item>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 7706f30d420a..aca220f8f753 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1230,5 +1230,8 @@
<public type="attr" name="neverEncrypt" id="0x010102b7" />
<public type="attr" name="installLocation" id="0x010102b8" />
<public type="attr" name="safeMode" id="0x010102b9" />
+ <public type="attr" name="webTextViewStyle" id="0x010102ba" />
+
+ <public type="anim" name="cycle_interpolator" id="0x010a000c" />
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 9e596ef489d9..6f34b4f84ed4 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -565,11 +565,6 @@
<string name="permdesc_backup">Allows the application to control the system\'s backup and restore mechanism. Not for use by 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_backup_data">back up and restore the application\'s data</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_backup_data">Allows the application to participate in the system\'s backup and restore mechanism.</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_internalSystemWindow">display unauthorized windows</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_internalSystemWindow">Allows the creation of
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 58e9f4590ab1..128766975fd0 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -503,6 +503,17 @@
<item name="android:scrollbars">horizontal|vertical</item>
</style>
+ <style name="Widget.WebTextView">
+ <item name="android:focusable">true</item>
+ <item name="android:focusableInTouchMode">true</item>
+ <item name="android:clickable">true</item>
+ <item name="android:completionHintView">@android:layout/simple_dropdown_item_1line</item>
+ <item name="android:textAppearance">?android:attr/textAppearanceLargeInverse</item>
+ <item name="android:completionThreshold">2</item>
+ <item name="android:dropDownSelector">@android:drawable/list_selector_background</item>
+ <item name="android:popupBackground">@android:drawable/spinner_dropdown_background</item>
+ </style>
+
<style name="Widget.TabWidget">
<item name="android:textAppearance">@style/TextAppearance.Widget.TabWidget</item>
<item name="ellipsize">marquee</item>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index d7a3be384578..9e19c57c7949 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -170,6 +170,7 @@
<item name="starStyle">@android:style/Widget.CompoundButton.Star</item>
<item name="tabWidgetStyle">@android:style/Widget.TabWidget</item>
<item name="textViewStyle">@android:style/Widget.TextView</item>
+ <item name="webTextViewStyle">@android:style/Widget.WebTextView</item>
<item name="webViewStyle">@android:style/Widget.WebView</item>
<item name="dropDownItemStyle">@android:style/Widget.DropDownItem</item>
<item name="spinnerDropDownItemStyle">@android:style/Widget.DropDownItem.Spinner</item>
diff --git a/core/tests/coretests/src/android/app/SearchManagerTest.java b/core/tests/coretests/src/android/app/SearchManagerTest.java
index 21ed4c5f12e0..fc7e78717788 100644
--- a/core/tests/coretests/src/android/app/SearchManagerTest.java
+++ b/core/tests/coretests/src/android/app/SearchManagerTest.java
@@ -141,7 +141,6 @@ public class SearchManagerTest extends ActivityInstrumentationTestCase2<LocalAct
* Tests that startSearch() can be called multiple times without stopSearch()
* in between.
*/
- @MediumTest
public void testStartSearchIdempotent() throws Exception {
SearchManager searchManager = (SearchManager)
mContext.getSystemService(Context.SEARCH_SERVICE);
@@ -156,7 +155,6 @@ public class SearchManagerTest extends ActivityInstrumentationTestCase2<LocalAct
* Tests that stopSearch() can be called when the search UI is not visible and can be
* called multiple times without startSearch() in between.
*/
- @MediumTest
public void testStopSearchIdempotent() throws Exception {
SearchManager searchManager = (SearchManager)
mContext.getSystemService(Context.SEARCH_SERVICE);
@@ -172,7 +170,6 @@ public class SearchManagerTest extends ActivityInstrumentationTestCase2<LocalAct
* The goal of this test is to confirm that we can start and then
* stop a simple search.
*/
- @MediumTest
public void testSearchManagerInvocations() throws Exception {
SearchManager searchManager = (SearchManager)
mContext.getSystemService(Context.SEARCH_SERVICE);
diff --git a/core/tests/coretests/src/android/os/MemoryFileTest.java b/core/tests/coretests/src/android/os/MemoryFileTest.java
index 411bdaa309f8..1f7ee266d94a 100644
--- a/core/tests/coretests/src/android/os/MemoryFileTest.java
+++ b/core/tests/coretests/src/android/os/MemoryFileTest.java
@@ -16,10 +16,8 @@
package android.os;
-import android.os.MemoryFile;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import java.io.File;
@@ -44,25 +42,30 @@ public class MemoryFileTest extends AndroidTestCase {
/**
* Keep allocating new files till the system purges them.
*/
- @MediumTest
+ @LargeTest
public void testPurge() throws Exception {
List<MemoryFile> files = new ArrayList<MemoryFile>();
- while (true) {
- MemoryFile newFile = new MemoryFile("MemoryFileTest", 1000000);
- newFile.allowPurging(true);
- newFile.writeBytes(testString, 0, 0, testString.length);
- files.add(newFile);
- for (MemoryFile file : files) {
- try {
- file.readBytes(testString, 0, 0, testString.length);
- } catch (IOException e) {
- // Expected
- for (MemoryFile fileToClose : files) {
- fileToClose.close();
+ try {
+ while (true) {
+ // This will fail if the process runs out of file descriptors before
+ // the kernel starts purging ashmem areas.
+ MemoryFile newFile = new MemoryFile("MemoryFileTest", 10000000);
+ newFile.allowPurging(true);
+ newFile.writeBytes(testString, 0, 0, testString.length);
+ files.add(newFile);
+ for (MemoryFile file : files) {
+ try {
+ file.readBytes(testString, 0, 0, testString.length);
+ } catch (IOException e) {
+ // Expected
+ return;
}
- return;
}
}
+ } finally {
+ for (MemoryFile fileToClose : files) {
+ fileToClose.close();
+ }
}
}
diff --git a/common/tests/src/com/android/common/Base64Test.java b/core/tests/coretests/src/android/util/base64/Base64Test.java
index 1064625f2d23..48192bb4fa08 100644
--- a/common/tests/src/com/android/common/Base64Test.java
+++ b/core/tests/coretests/src/android/util/base64/Base64Test.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.common;
+package android.util.base64;
import junit.framework.TestCase;
@@ -23,7 +23,7 @@ import java.io.ByteArrayOutputStream;
import java.util.Random;
public class Base64Test extends TestCase {
- private static final String TAG = "B64Test";
+ private static final String TAG = "Base64Test";
/** Decodes a string, returning a string. */
private String decodeString(String in) throws Exception {
@@ -134,25 +134,25 @@ public class Base64Test extends TestCase {
}
public void testWebSafe() throws Exception {
- assertEquals(BYTES, 0, Base64.decode("", Base64.WEB_SAFE));
- assertEquals(BYTES, 1, Base64.decode("_w==", Base64.WEB_SAFE));
- assertEquals(BYTES, 2, Base64.decode("_-4=", Base64.WEB_SAFE));
- assertEquals(BYTES, 3, Base64.decode("_-7d", Base64.WEB_SAFE));
- assertEquals(BYTES, 4, Base64.decode("_-7dzA==", Base64.WEB_SAFE));
- assertEquals(BYTES, 5, Base64.decode("_-7dzLs=", Base64.WEB_SAFE));
- assertEquals(BYTES, 6, Base64.decode("_-7dzLuq", Base64.WEB_SAFE));
- assertEquals(BYTES, 7, Base64.decode("_-7dzLuqmQ==", Base64.WEB_SAFE));
- assertEquals(BYTES, 8, Base64.decode("_-7dzLuqmYg=", Base64.WEB_SAFE));
-
- assertEquals("", Base64.encodeToString(BYTES, 0, 0, Base64.WEB_SAFE));
- assertEquals("_w==\n", Base64.encodeToString(BYTES, 0, 1, Base64.WEB_SAFE));
- assertEquals("_-4=\n", Base64.encodeToString(BYTES, 0, 2, Base64.WEB_SAFE));
- assertEquals("_-7d\n", Base64.encodeToString(BYTES, 0, 3, Base64.WEB_SAFE));
- assertEquals("_-7dzA==\n", Base64.encodeToString(BYTES, 0, 4, Base64.WEB_SAFE));
- assertEquals("_-7dzLs=\n", Base64.encodeToString(BYTES, 0, 5, Base64.WEB_SAFE));
- assertEquals("_-7dzLuq\n", Base64.encodeToString(BYTES, 0, 6, Base64.WEB_SAFE));
- assertEquals("_-7dzLuqmQ==\n", Base64.encodeToString(BYTES, 0, 7, Base64.WEB_SAFE));
- assertEquals("_-7dzLuqmYg=\n", Base64.encodeToString(BYTES, 0, 8, Base64.WEB_SAFE));
+ assertEquals(BYTES, 0, Base64.decode("", Base64.URL_SAFE));
+ assertEquals(BYTES, 1, Base64.decode("_w==", Base64.URL_SAFE));
+ assertEquals(BYTES, 2, Base64.decode("_-4=", Base64.URL_SAFE));
+ assertEquals(BYTES, 3, Base64.decode("_-7d", Base64.URL_SAFE));
+ assertEquals(BYTES, 4, Base64.decode("_-7dzA==", Base64.URL_SAFE));
+ assertEquals(BYTES, 5, Base64.decode("_-7dzLs=", Base64.URL_SAFE));
+ assertEquals(BYTES, 6, Base64.decode("_-7dzLuq", Base64.URL_SAFE));
+ assertEquals(BYTES, 7, Base64.decode("_-7dzLuqmQ==", Base64.URL_SAFE));
+ assertEquals(BYTES, 8, Base64.decode("_-7dzLuqmYg=", Base64.URL_SAFE));
+
+ assertEquals("", Base64.encodeToString(BYTES, 0, 0, Base64.URL_SAFE));
+ assertEquals("_w==\n", Base64.encodeToString(BYTES, 0, 1, Base64.URL_SAFE));
+ assertEquals("_-4=\n", Base64.encodeToString(BYTES, 0, 2, Base64.URL_SAFE));
+ assertEquals("_-7d\n", Base64.encodeToString(BYTES, 0, 3, Base64.URL_SAFE));
+ assertEquals("_-7dzA==\n", Base64.encodeToString(BYTES, 0, 4, Base64.URL_SAFE));
+ assertEquals("_-7dzLs=\n", Base64.encodeToString(BYTES, 0, 5, Base64.URL_SAFE));
+ assertEquals("_-7dzLuq\n", Base64.encodeToString(BYTES, 0, 6, Base64.URL_SAFE));
+ assertEquals("_-7dzLuqmQ==\n", Base64.encodeToString(BYTES, 0, 7, Base64.URL_SAFE));
+ assertEquals("_-7dzLuqmYg=\n", Base64.encodeToString(BYTES, 0, 8, Base64.URL_SAFE));
}
public void testFlags() throws Exception {
@@ -227,55 +227,55 @@ public class Base64Test extends TestCase {
}
/**
- * Tests that Base64.encodeInternal does correct handling of the
+ * Tests that Base64.Encoder.encode() does correct handling of the
* tail for each call.
*
* This test is disabled because while it passes if you can get it
* to run, android's test infrastructure currently doesn't allow
- * us to get at package-private members (Base64.EncoderState in
+ * us to get at package-private members (Base64.Encoder in
* this case).
*/
public void XXXtestEncodeInternal() throws Exception {
byte[] input = { (byte) 0x61, (byte) 0x62, (byte) 0x63 };
byte[] output = new byte[100];
- Base64.EncoderState state = new Base64.EncoderState(Base64.NO_PADDING | Base64.NO_WRAP,
- output);
+ Base64.Encoder encoder = new Base64.Encoder(Base64.NO_PADDING | Base64.NO_WRAP,
+ output);
- Base64.encodeInternal(input, 0, 3, state, false);
- assertEquals("YWJj".getBytes(), 4, state.output, state.op);
- assertEquals(0, state.tailLen);
+ encoder.process(input, 0, 3, false);
+ assertEquals("YWJj".getBytes(), 4, encoder.output, encoder.op);
+ assertEquals(0, encoder.tailLen);
- Base64.encodeInternal(input, 0, 3, state, false);
- assertEquals("YWJj".getBytes(), 4, state.output, state.op);
- assertEquals(0, state.tailLen);
+ encoder.process(input, 0, 3, false);
+ assertEquals("YWJj".getBytes(), 4, encoder.output, encoder.op);
+ assertEquals(0, encoder.tailLen);
- Base64.encodeInternal(input, 0, 1, state, false);
- assertEquals(0, state.op);
- assertEquals(1, state.tailLen);
+ encoder.process(input, 0, 1, false);
+ assertEquals(0, encoder.op);
+ assertEquals(1, encoder.tailLen);
- Base64.encodeInternal(input, 0, 1, state, false);
- assertEquals(0, state.op);
- assertEquals(2, state.tailLen);
+ encoder.process(input, 0, 1, false);
+ assertEquals(0, encoder.op);
+ assertEquals(2, encoder.tailLen);
- Base64.encodeInternal(input, 0, 1, state, false);
- assertEquals("YWFh".getBytes(), 4, state.output, state.op);
- assertEquals(0, state.tailLen);
+ encoder.process(input, 0, 1, false);
+ assertEquals("YWFh".getBytes(), 4, encoder.output, encoder.op);
+ assertEquals(0, encoder.tailLen);
- Base64.encodeInternal(input, 0, 2, state, false);
- assertEquals(0, state.op);
- assertEquals(2, state.tailLen);
+ encoder.process(input, 0, 2, false);
+ assertEquals(0, encoder.op);
+ assertEquals(2, encoder.tailLen);
- Base64.encodeInternal(input, 0, 2, state, false);
- assertEquals("YWJh".getBytes(), 4, state.output, state.op);
- assertEquals(1, state.tailLen);
+ encoder.process(input, 0, 2, false);
+ assertEquals("YWJh".getBytes(), 4, encoder.output, encoder.op);
+ assertEquals(1, encoder.tailLen);
- Base64.encodeInternal(input, 0, 2, state, false);
- assertEquals("YmFi".getBytes(), 4, state.output, state.op);
- assertEquals(0, state.tailLen);
+ encoder.process(input, 0, 2, false);
+ assertEquals("YmFi".getBytes(), 4, encoder.output, encoder.op);
+ assertEquals(0, encoder.tailLen);
- Base64.encodeInternal(input, 0, 1, state, true);
- assertEquals("YQ".getBytes(), 2, state.output, state.op);
+ encoder.process(input, 0, 1, true);
+ assertEquals("YQ".getBytes(), 2, encoder.output, encoder.op);
}
private static final String lipsum =
@@ -307,7 +307,7 @@ public class Base64Test extends TestCase {
Base64.NO_WRAP,
Base64.NO_PADDING | Base64.NO_WRAP,
Base64.CRLF,
- Base64.WEB_SAFE };
+ Base64.URL_SAFE };
int[] writeLengths = { -10, -5, -1, 0, 1, 1, 2, 2, 3, 10, 100 };
Random rng = new Random(32176L);
@@ -414,7 +414,7 @@ public class Base64Test extends TestCase {
Base64.NO_WRAP,
Base64.NO_PADDING | Base64.NO_WRAP,
Base64.CRLF,
- Base64.WEB_SAFE };
+ Base64.URL_SAFE };
int[] writeLengths = { -10, -5, -1, 0, 1, 1, 2, 2, 3, 10, 100 };
Random rng = new Random(32176L);
diff --git a/core/tests/coretests/src/com/google/android/net/ParentalControlTest.java b/core/tests/coretests/src/com/google/android/net/ParentalControlTest.java
deleted file mode 100644
index d8ffeab2892e..000000000000
--- a/core/tests/coretests/src/com/google/android/net/ParentalControlTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.net;
-
-import com.google.android.net.ParentalControl;
-import com.google.android.net.ParentalControlState;
-
-import android.os.SystemClock;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-
-import junit.framework.Assert;
-
-public class ParentalControlTest extends AndroidTestCase {
-
- private boolean mOnResultCalled = false;
-
- public class Callback implements ParentalControl.Callback {
- public void onResult(ParentalControlState state) {
- synchronized (ParentalControlTest.class) {
- mOnResultCalled = true;
- ParentalControlTest.class.notifyAll();
- }
- }
- }
-
- @SmallTest
- public void testParentalControlCallback() {
- synchronized (ParentalControlTest.class) {
- ParentalControl.getParentalControlState(new Callback(), null);
- try {
- long start = SystemClock.uptimeMillis();
- ParentalControlTest.class.wait(20 * 1000);
- long end = SystemClock.uptimeMillis();
- Log.d("AndroidTests", "ParentalControlTest callback took " + (end-start) + " ms.");
- } catch (InterruptedException ex) {
- }
- }
-
- Assert.assertTrue(mOnResultCalled);
- }
-}
diff --git a/data/sounds/AudioPackage2.mk b/data/sounds/AudioPackage2.mk
index 5dacc70bc903..d7f7c7e3d7fb 100644
--- a/data/sounds/AudioPackage2.mk
+++ b/data/sounds/AudioPackage2.mk
@@ -67,6 +67,11 @@ PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+ $(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+ $(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
+ $(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
+ $(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \
+ $(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
$(LOCAL_PATH)/newwavelabs/CrazyDream.ogg:system/media/audio/ringtones/CrazyDream.ogg \
$(LOCAL_PATH)/newwavelabs/DreamTheme.ogg:system/media/audio/ringtones/DreamTheme.ogg \
$(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \
diff --git a/data/sounds/AudioPackage3.mk b/data/sounds/AudioPackage3.mk
index f2f62128adef..64d67179716d 100644
--- a/data/sounds/AudioPackage3.mk
+++ b/data/sounds/AudioPackage3.mk
@@ -59,6 +59,11 @@ PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+ $(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+ $(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
+ $(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
+ $(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \
+ $(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
$(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \
$(LOCAL_PATH)/newwavelabs/Bollywood.ogg:system/media/audio/ringtones/Bollywood.ogg \
$(LOCAL_PATH)/newwavelabs/Cairo.ogg:system/media/audio/ringtones/Cairo.ogg \
@@ -89,4 +94,3 @@ PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \
$(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \
$(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg
-
diff --git a/data/sounds/AudioPackage4.mk b/data/sounds/AudioPackage4.mk
index 6c36bad223c5..b011b784ac03 100644
--- a/data/sounds/AudioPackage4.mk
+++ b/data/sounds/AudioPackage4.mk
@@ -46,6 +46,11 @@ PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+ $(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+ $(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
+ $(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
+ $(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \
+ $(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
$(LOCAL_PATH)/Ring_Classic_02.ogg:system/media/audio/ringtones/Ring_Classic_02.ogg \
$(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \
$(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \
diff --git a/data/sounds/effects/Dock.aif b/data/sounds/effects/Dock.aif
new file mode 100644
index 000000000000..9f408cc3e27c
--- /dev/null
+++ b/data/sounds/effects/Dock.aif
Binary files differ
diff --git a/data/sounds/effects/Dock.ogg b/data/sounds/effects/Dock.ogg
new file mode 100644
index 000000000000..1462813d4561
--- /dev/null
+++ b/data/sounds/effects/Dock.ogg
Binary files differ
diff --git a/data/sounds/effects/Lock.aiff b/data/sounds/effects/Lock.aiff
new file mode 100644
index 000000000000..90870f26ff52
--- /dev/null
+++ b/data/sounds/effects/Lock.aiff
Binary files differ
diff --git a/data/sounds/effects/Lock.ogg b/data/sounds/effects/Lock.ogg
new file mode 100644
index 000000000000..841ee2e86965
--- /dev/null
+++ b/data/sounds/effects/Lock.ogg
Binary files differ
diff --git a/data/sounds/effects/LowBattery.aif b/data/sounds/effects/LowBattery.aif
new file mode 100644
index 000000000000..9216583ee24f
--- /dev/null
+++ b/data/sounds/effects/LowBattery.aif
Binary files differ
diff --git a/data/sounds/effects/LowBattery.ogg b/data/sounds/effects/LowBattery.ogg
new file mode 100644
index 000000000000..68eb2c319488
--- /dev/null
+++ b/data/sounds/effects/LowBattery.ogg
Binary files differ
diff --git a/data/sounds/effects/Undock.aif b/data/sounds/effects/Undock.aif
new file mode 100644
index 000000000000..fe9d0b05db06
--- /dev/null
+++ b/data/sounds/effects/Undock.aif
Binary files differ
diff --git a/data/sounds/effects/Undock.ogg b/data/sounds/effects/Undock.ogg
new file mode 100644
index 000000000000..005306674e30
--- /dev/null
+++ b/data/sounds/effects/Undock.ogg
Binary files differ
diff --git a/data/sounds/effects/Unlock.aiff b/data/sounds/effects/Unlock.aiff
new file mode 100644
index 000000000000..546ea392ec0c
--- /dev/null
+++ b/data/sounds/effects/Unlock.aiff
Binary files differ
diff --git a/data/sounds/effects/Unlock.ogg b/data/sounds/effects/Unlock.ogg
new file mode 100644
index 000000000000..26d5ea6d4caa
--- /dev/null
+++ b/data/sounds/effects/Unlock.ogg
Binary files differ
diff --git a/docs/html/sitemap.txt b/docs/html/sitemap.txt
index f82b2fe771a8..5039dfcb7595 100644
--- a/docs/html/sitemap.txt
+++ b/docs/html/sitemap.txt
@@ -2864,11 +2864,6 @@ http://developer.android.com/reference/org/xmlpull/v1/XmlSerializer.html
http://developer.android.com/reference/org/apache/http/cookie/params/package-descr.html
http://developer.android.com/reference/java/util/concurrent/locks/package-descr.html
http://developer.android.com/reference/org/apache/http/conn/routing/package-descr.html
-http://developer.android.com/guide/samples/index.html
-http://developer.android.com/guide/tutorials/notepad/notepad-ex1.html
-http://developer.android.com/guide/tutorials/notepad/notepad-ex2.html
-http://developer.android.com/guide/tutorials/notepad/notepad-ex3.html
-http://developer.android.com/guide/tutorials/notepad/notepad-extra-credit.html
http://developer.android.com/guide/appendix/faq/commontasks.html
http://developer.android.com/reference/javax/security/cert/package-descr.html
http://developer.android.com/reference/org/xml/sax/ext/package-descr.html
@@ -3029,7 +3024,6 @@ http://developer.android.com/reference/javax/security/auth/x500/package-descr.ht
http://developer.android.com/sdk/api_diff/6/changes/android.view.WindowManager.LayoutParams.html
http://developer.android.com/reference/android/net/package-descr.html
http://developer.android.com/reference/org/apache/http/client/package-descr.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html
http://developer.android.com/sdk/download.html?v=archives/android-sdk-windows-1.6_r1.zip
http://developer.android.com/sdk/download.html?v=archives/android-sdk-mac_x86-1.6_r1.zip
http://developer.android.com/sdk/download.html?v=archives/android-sdk-linux_x86-1.6_r1.tgz
@@ -3299,7 +3293,6 @@ http://developer.android.com/resources/samples/BluetoothChat/res/layout/main.htm
http://developer.android.com/resources/samples/BluetoothChat/res/layout/message.html
http://developer.android.com/resources/samples/NotePad/res/drawable-ldpi-v6/app_notes.html
http://developer.android.com/resources/samples/NotePad/res/drawable-ldpi-v6/live_folder_notes.html
-http://developer.android.com/guide/tutorials/views/index.html
http://developer.android.com/sdk/api_diff/4/changes/pkg_android.html
http://developer.android.com/sdk/api_diff/4/changes/pkg_android.app.html
http://developer.android.com/sdk/api_diff/4/changes/pkg_android.content.res.html
@@ -3523,21 +3516,6 @@ http://developer.android.com/reference/javax/security/auth/login/package-descr.h
http://developer.android.com/resources/samples/ApiDemos/tests/src/com/example/android/apis/index.html
http://developer.android.com/reference/org/apache/http/conn/ssl/package-descr.html
http://developer.android.com/resources/samples/ContactManager/res/drawable-hdpi/icon.html
-http://developer.android.com/guide/tutorials/views/hello-linearlayout.html
-http://developer.android.com/guide/tutorials/views/hello-relativelayout.html
-http://developer.android.com/guide/tutorials/views/hello-tablelayout.html
-http://developer.android.com/guide/tutorials/views/hello-datepicker.html
-http://developer.android.com/guide/tutorials/views/hello-timepicker.html
-http://developer.android.com/guide/tutorials/views/hello-formstuff.html
-http://developer.android.com/guide/tutorials/views/hello-spinner.html
-http://developer.android.com/guide/tutorials/views/hello-autocomplete.html
-http://developer.android.com/guide/tutorials/views/hello-listview.html
-http://developer.android.com/guide/tutorials/views/hello-gridview.html
-http://developer.android.com/guide/tutorials/views/hello-gallery.html
-http://developer.android.com/guide/tutorials/views/hello-tabwidget.html
-http://developer.android.com/guide/tutorials/views/hello-mapview.html
-http://developer.android.com/guide/tutorials/views/hello-webview.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/index.html
http://developer.android.com/sdk/api_diff/5/changes/packages_index_all.html
http://developer.android.com/sdk/api_diff/5/changes/classes_index_all.html
http://developer.android.com/sdk/api_diff/5/changes/constructors_index_all.html
@@ -3858,112 +3836,6 @@ http://developer.android.com/resources/samples/Home/res/anim/show_applications.h
http://developer.android.com/reference/org/w3c/dom/package-descr.html
http://developer.android.com/reference/org/apache/http/package-descr.html
http://developer.android.com/resources/samples/MultiResolution/src/com/example/index.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/RelativeLayout1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/RelativeLayout2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout4.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout5.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout6.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout7.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout8.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout9.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollView1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollView2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout4.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout5.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout6.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout7.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout8.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout9.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout10.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout11.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout12.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline4.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline6.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline7.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/RadioGroup1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Visibility1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List4.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List5.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List6.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List7.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List8.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/CustomView1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ImageButton1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/DateWidgets1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/DateWidgets2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Gallery2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Spinner1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Grid1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Grid2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ImageSwitcher1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TextSwitcher1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Animation1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Animation2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Controls1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Controls2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete4.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete5.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar4.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Focus1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Focus2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Focus3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Animation3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete6.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Buttons1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ChronometerDemo.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ImageView1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionFocus.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionScroll.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionView.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LabelView.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation4.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation5.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation6.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation7.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout10.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List10.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List11.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List12.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List13.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List14.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List9.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/RatingBar1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/SeekBar1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Tabs1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Tabs2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Tabs3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/WebView1.html
http://developer.android.com/resources/samples/Home/res/drawable/all_applications.html
http://developer.android.com/resources/samples/Home/res/drawable/all_applications_background.html
http://developer.android.com/resources/samples/Home/res/drawable/all_applications_button_background.html
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h
index b6f654f8c58b..26196917203f 100644
--- a/include/media/IMediaPlayer.h
+++ b/include/media/IMediaPlayer.h
@@ -46,6 +46,8 @@ public:
virtual status_t setAudioStreamType(int type) = 0;
virtual status_t setLooping(int loop) = 0;
virtual status_t setVolume(float leftVolume, float rightVolume) = 0;
+ virtual status_t suspend() = 0;
+ virtual status_t resume() = 0;
// Invoke a generic method on the player by using opaque parcels
// for the request and reply.
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index ecb20e86b573..9e606d99f3de 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -118,6 +118,9 @@ public:
virtual status_t reset() = 0;
virtual status_t setLooping(int loop) = 0;
virtual player_type playerType() = 0;
+ virtual status_t suspend() { return INVALID_OPERATION; }
+ virtual status_t resume() { return INVALID_OPERATION; }
+
virtual void setNotifyCallback(void* cookie, notify_callback_f notifyFunc) {
mCookie = cookie; mNotify = notifyFunc; }
// Invoke a generic method on the player by using opaque parcels
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 8dc7c8aec682..7fad1b7b1aab 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -165,6 +165,8 @@ public:
status_t invoke(const Parcel& request, Parcel *reply);
status_t setMetadataFilter(const Parcel& filter);
status_t getMetadata(bool update_only, bool apply_filter, Parcel *metadata);
+ status_t suspend();
+ status_t resume();
private:
void clear_l();
status_t seekTo_l(int msec);
diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h
index 6d87321bb4ee..f46f25c36d14 100644
--- a/include/ui/PixelFormat.h
+++ b/include/ui/PixelFormat.h
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <utils/Errors.h>
#include <pixelflinger/format.h>
+#include <hardware/hardware.h>
namespace android {
@@ -57,25 +58,18 @@ enum {
// real pixel formats supported for rendering -----------------------------
- PIXEL_FORMAT_RGBA_8888 = GGL_PIXEL_FORMAT_RGBA_8888, // 4x8-bit RGBA
- PIXEL_FORMAT_RGBX_8888 = GGL_PIXEL_FORMAT_RGBX_8888, // 4x8-bit RGB0
- PIXEL_FORMAT_RGB_888 = GGL_PIXEL_FORMAT_RGB_888, // 3x8-bit RGB
- PIXEL_FORMAT_RGB_565 = GGL_PIXEL_FORMAT_RGB_565, // 16-bit RGB
- PIXEL_FORMAT_BGRA_8888 = GGL_PIXEL_FORMAT_BGRA_8888, // 4x8-bit BGRA
- PIXEL_FORMAT_RGBA_5551 = GGL_PIXEL_FORMAT_RGBA_5551, // 16-bit ARGB
- PIXEL_FORMAT_RGBA_4444 = GGL_PIXEL_FORMAT_RGBA_4444, // 16-bit ARGB
+ PIXEL_FORMAT_RGBA_8888 = HAL_PIXEL_FORMAT_RGBA_8888, // 4x8-bit RGBA
+ PIXEL_FORMAT_RGBX_8888 = HAL_PIXEL_FORMAT_RGBX_8888, // 4x8-bit RGB0
+ PIXEL_FORMAT_RGB_888 = HAL_PIXEL_FORMAT_RGB_888, // 3x8-bit RGB
+ PIXEL_FORMAT_RGB_565 = HAL_PIXEL_FORMAT_RGB_565, // 16-bit RGB
+ PIXEL_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888, // 4x8-bit BGRA
+ PIXEL_FORMAT_RGBA_5551 = HAL_PIXEL_FORMAT_RGBA_5551, // 16-bit ARGB
+ PIXEL_FORMAT_RGBA_4444 = HAL_PIXEL_FORMAT_RGBA_4444, // 16-bit ARGB
PIXEL_FORMAT_A_8 = GGL_PIXEL_FORMAT_A_8, // 8-bit A
PIXEL_FORMAT_L_8 = GGL_PIXEL_FORMAT_L_8, // 8-bit L (R=G=B=L)
PIXEL_FORMAT_LA_88 = GGL_PIXEL_FORMAT_LA_88, // 16-bit LA
PIXEL_FORMAT_RGB_332 = GGL_PIXEL_FORMAT_RGB_332, // 8-bit RGB
- PIXEL_FORMAT_YCbCr_422_SP= GGL_PIXEL_FORMAT_YCbCr_422_SP,
- PIXEL_FORMAT_YCbCr_420_SP= GGL_PIXEL_FORMAT_YCbCr_420_SP,
- PIXEL_FORMAT_YCbCr_422_P = GGL_PIXEL_FORMAT_YCbCr_422_P,
- PIXEL_FORMAT_YCbCr_420_P = GGL_PIXEL_FORMAT_YCbCr_420_P,
- PIXEL_FORMAT_YCbCr_422_I = GGL_PIXEL_FORMAT_YCbCr_422_I,
- PIXEL_FORMAT_YCbCr_420_I = GGL_PIXEL_FORMAT_YCbCr_420_I,
-
// New formats can be added if they're also defined in
// pixelflinger/format.h
};
@@ -97,9 +91,7 @@ struct PixelFormatInfo
RGBA = 3,
LUMINANCE = 4,
LUMINANCE_ALPHA = 5,
- Y_CB_CR_SP = 6,
- Y_CB_CR_P = 7,
- Y_CB_CR_I = 8,
+ OTHER = 0xFF
};
struct szinfo {
diff --git a/include/utils/AndroidUnicode.h b/include/utils/AndroidUnicode.h
deleted file mode 100644
index 563fcd0197fe..000000000000
--- a/include/utils/AndroidUnicode.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-
-#ifndef ANDROID_UNICODE_H
-#define ANDROID_UNICODE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#define REPLACEMENT_CHAR (0xFFFD)
-
-// this part of code is copied from umachine.h under ICU
-/**
- * Define UChar32 as a type for single Unicode code points.
- * UChar32 is a signed 32-bit integer (same as int32_t).
- *
- * The Unicode code point range is 0..0x10ffff.
- * All other values (negative or >=0x110000) are illegal as Unicode code points.
- * They may be used as sentinel values to indicate "done", "error"
- * or similar non-code point conditions.
- *
- * @stable ICU 2.4
- */
-typedef int32_t UChar32;
-
-namespace android {
-
- class Encoding;
- /**
- * \class Unicode
- *
- * Helper class for getting properties of Unicode characters. Characters
- * can have one of the types listed in CharType and each character can have the
- * directionality of Direction.
- */
- class Unicode
- {
- public:
- /**
- * Directions specified in the Unicode standard. These directions map directly
- * to java.lang.Character.
- */
- enum Direction {
- DIRECTIONALITY_UNDEFINED = -1,
- DIRECTIONALITY_LEFT_TO_RIGHT,
- DIRECTIONALITY_RIGHT_TO_LEFT,
- DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC,
- DIRECTIONALITY_EUROPEAN_NUMBER,
- DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR,
- DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR,
- DIRECTIONALITY_ARABIC_NUMBER,
- DIRECTIONALITY_COMMON_NUMBER_SEPARATOR,
- DIRECTIONALITY_NONSPACING_MARK,
- DIRECTIONALITY_BOUNDARY_NEUTRAL,
- DIRECTIONALITY_PARAGRAPH_SEPARATOR,
- DIRECTIONALITY_SEGMENT_SEPARATOR,
- DIRECTIONALITY_WHITESPACE,
- DIRECTIONALITY_OTHER_NEUTRALS,
- DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING,
- DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE,
- DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING,
- DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE,
- DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
- };
-
- /**
- * Character types as specified in the Unicode standard. These map directly to
- * java.lang.Character.
- */
- enum CharType {
- CHARTYPE_UNASSIGNED = 0,
- CHARTYPE_UPPERCASE_LETTER,
- CHARTYPE_LOWERCASE_LETTER,
- CHARTYPE_TITLECASE_LETTER,
- CHARTYPE_MODIFIER_LETTER,
- CHARTYPE_OTHER_LETTER,
- CHARTYPE_NON_SPACING_MARK,
- CHARTYPE_ENCLOSING_MARK,
- CHARTYPE_COMBINING_SPACING_MARK,
- CHARTYPE_DECIMAL_DIGIT_NUMBER,
- CHARTYPE_LETTER_NUMBER,
- CHARTYPE_OTHER_NUMBER,
- CHARTYPE_SPACE_SEPARATOR,
- CHARTYPE_LINE_SEPARATOR,
- CHARTYPE_PARAGRAPH_SEPARATOR,
- CHARTYPE_CONTROL,
- CHARTYPE_FORMAT,
- CHARTYPE_MISSING_VALUE_FOR_JAVA, /* This is the mysterious missing 17 value from the java constants */
- CHARTYPE_PRIVATE_USE,
- CHARTYPE_SURROGATE,
- CHARTYPE_DASH_PUNCTUATION,
- CHARTYPE_START_PUNCTUATION,
- CHARTYPE_END_PUNCTUATION,
- CHARTYPE_CONNECTOR_PUNCTUATION,
- CHARTYPE_OTHER_PUNCTUATION,
- CHARTYPE_MATH_SYMBOL,
- CHARTYPE_CURRENCY_SYMBOL,
- CHARTYPE_MODIFIER_SYMBOL,
- CHARTYPE_OTHER_SYMBOL,
- CHARTYPE_INITIAL_QUOTE_PUNCTUATION,
- CHARTYPE_FINAL_QUOTE_PUNCTUATION
- };
-
- /**
- * Decomposition types as described by the unicode standard. These values map to
- * the same values in uchar.h in ICU.
- */
- enum DecompositionType {
- DECOMPOSITION_NONE = 0,
- DECOMPOSITION_CANONICAL,
- DECOMPOSITION_COMPAT,
- DECOMPOSITION_CIRCLE,
- DECOMPOSITION_FINAL,
- DECOMPOSITION_FONT,
- DECOMPOSITION_FRACTION,
- DECOMPOSITION_INITIAL,
- DECOMPOSITION_ISOLATED,
- DECOMPOSITION_MEDIAL,
- DECOMPOSITION_NARROW,
- DECOMPOSITION_NOBREAK,
- DECOMPOSITION_SMALL,
- DECOMPOSITION_SQUARE,
- DECOMPOSITION_SUB,
- DECOMPOSITION_SUPER,
- DECOMPOSITION_VERTICAL,
- DECOMPOSITION_WIDE
- };
-
- /**
- * Returns the packed data for java calls
- * @param c The unicode character.
- * @return The packed data for the character.
- *
- * Copied from java.lang.Character implementation:
- * 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
- * F E D C B A 9 8 7 6 5 4 3 2 1 0 F E D C B A 9 8 7 6 5 4 3 2 1 0
- *
- * 31 types ---------
- * 18 directionalities ---------
- * 2 mirroreds -
- * ----------- 56 toupper diffs
- * ----------- 48 tolower diffs
- * --- 4 totitlecase diffs
- * ------------- 84 numeric values
- * --------- 24 mirror char diffs
- */
- static uint32_t getPackedData(UChar32 c);
-
- /**
- * Get the Character type.
- * @param c The unicode character.
- * @return The character's type or CHARTYPE_UNASSIGNED if the character is invalid
- * or has an unassigned class.
- */
- static CharType getType(UChar32 c);
-
- /**
- * Get the Character's decomposition type.
- * @param c The unicode character.
- * @return The character's decomposition type or DECOMPOSITION_NONE is there
- * is no decomposition.
- */
- static DecompositionType getDecompositionType(UChar32 c);
-
- /**
- * Returns the digit value of a character or -1 if the character
- * is not within the specified radix.
- *
- * The digit value is computed for integer characters and letters
- * within the given radix. This function does not handle Roman Numerals,
- * fractions, or any other characters that may represent numbers.
- *
- * @param c The unicode character
- * @param radix The intended radix.
- * @return The digit value or -1 if there is no digit value or if the value is outside the radix.
- */
- static int getDigitValue(UChar32 c, int radix = 10);
-
- /**
- * Return the numeric value of a character
- *
- * @param c The unicode character.
- * @return The numeric value of the character. -1 if the character has no numeric value,
- * -2 if the character has a numeric value that is not representable by an integer.
- */
- static int getNumericValue(UChar32 c);
-
- /**
- * Convert the character to lowercase
- * @param c The unicode character.
- * @return The lowercase character equivalent of c. If c does not have a lowercase equivalent,
- * the original character is returned.
- */
- static UChar32 toLower(UChar32 c);
-
- /**
- * Convert the character to uppercase
- * @param c The unicode character.
- * @return The uppercase character equivalent of c. If c does not have an uppercase equivalent,
- * the original character is returned.
- */
- static UChar32 toUpper(UChar32 c);
-
- /**
- * Get the directionality of the character.
- * @param c The unicode character.
- * @return The direction of the character or DIRECTIONALITY_UNDEFINED.
- */
- static Direction getDirectionality(UChar32 c);
-
- /**
- * Check if the character is a mirrored character. This means that the character
- * has an equivalent character that is the mirror image of itself.
- * @param c The unicode character.
- * @return True iff c has a mirror equivalent.
- */
- static bool isMirrored(UChar32 c);
-
- /**
- * Return the mirror of the given character.
- * @param c The unicode character.
- * @return The mirror equivalent of c. If c does not have a mirror equivalent,
- * the original character is returned.
- * @see isMirrored
- */
- static UChar32 toMirror(UChar32 c);
-
- /**
- * Convert the character to title case.
- * @param c The unicode character.
- * @return The titlecase equivalent of c. If c does not have a titlecase equivalent,
- * the original character is returned.
- */
- static UChar32 toTitle(UChar32 c);
-
- };
-
-}
-
-#endif
diff --git a/libs/rs/java/ImageProcessing/res/raw/threshold.rs b/libs/rs/java/ImageProcessing/res/raw/threshold.rs
index 888b5cd76cd5..888f0cdb029e 100644
--- a/libs/rs/java/ImageProcessing/res/raw/threshold.rs
+++ b/libs/rs/java/ImageProcessing/res/raw/threshold.rs
@@ -1,3 +1,29 @@
+/*
+// block of defines matching what RS will insert at runtime.
+struct Params_s{
+ int inHeight;
+ int inWidth;
+ int outHeight;
+ int outWidth;
+ float threshold;
+};
+struct Params_s * Params;
+struct InPixel_s{
+ char a;
+ char b;
+ char g;
+ char r;
+};
+struct InPixel_s * InPixel;
+struct OutPixel_s{
+ char a;
+ char b;
+ char g;
+ char r;
+};
+struct OutPixel_s * OutPixel;
+*/
+
struct color_s {
char b;
char g;
@@ -15,8 +41,6 @@ void main() {
int i;
float threshold = (Params->threshold * 255.f);
- //testFnc(count, threshold, in, out);
-
for (i = 0; i < count; i++) {
float luminance = 0.2125f * in->r +
0.7154f * in->g +
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index ac115d34ffbd..10e5285403f5 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -29,7 +29,7 @@ ContextResume {
ContextSetSurface {
param uint32_t width
param uint32_t height
- param void *sur
+ param android_native_window_t *sur
}
ContextDump {
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 2a0ccfb7d65e..dec993afd54b 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -19,7 +19,7 @@
#include "rsThreadIO.h"
#include <ui/FramebufferNativeWindow.h>
#include <ui/EGLUtils.h>
-#include <surfaceflinger/Surface.h>
+#include <ui/egl/android_natives.h>
#include <sys/types.h>
#include <sys/resource.h>
@@ -461,7 +461,7 @@ Context::~Context()
objDestroyOOBDestroy();
}
-void Context::setSurface(uint32_t w, uint32_t h, Surface *sur)
+void Context::setSurface(uint32_t w, uint32_t h, android_native_window_t *sur)
{
rsAssert(mIsGraphicsContext);
@@ -857,9 +857,9 @@ void rsi_ContextResume(Context *rsc)
rsc->resume();
}
-void rsi_ContextSetSurface(Context *rsc, uint32_t w, uint32_t h, void *sur)
+void rsi_ContextSetSurface(Context *rsc, uint32_t w, uint32_t h, android_native_window_t *sur)
{
- rsc->setSurface(w, h, (Surface *)sur);
+ rsc->setSurface(w, h, sur);
}
void rsi_ContextSetPriority(Context *rsc, int32_t p)
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index caf9728284a4..03e65f1f0f2b 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -41,12 +41,11 @@
#include "rsgApiStructs.h"
#include "rsLocklessFifo.h"
+#include <ui/egl/android_natives.h>
// ---------------------------------------------------------------------------
namespace android {
-class Surface;
-
namespace renderscript {
class Context
@@ -99,7 +98,7 @@ public:
void pause();
void resume();
- void setSurface(uint32_t w, uint32_t h, Surface *sur);
+ void setSurface(uint32_t w, uint32_t h, android_native_window_t *sur);
void setPriority(int32_t p);
void assignName(ObjectBase *obj, const char *name, uint32_t len);
@@ -239,7 +238,7 @@ private:
static void * threadProc(void *);
- Surface *mWndSurface;
+ android_native_window_t *mWndSurface;
Vector<ObjectBase *> mNames;
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index f38efab3d24f..c0805137f278 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -185,20 +185,20 @@ void Layer::reloadTexture(const Region& dirty)
if (res == NO_ERROR) {
int bpp = 0;
switch (t.format) {
- case GGL_PIXEL_FORMAT_RGB_565:
- case GGL_PIXEL_FORMAT_RGBA_4444:
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_RGBA_4444:
bpp = 2;
break;
- case GGL_PIXEL_FORMAT_RGBA_8888:
- case GGL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
bpp = 4;
break;
- case GGL_PIXEL_FORMAT_YCbCr_422_SP:
- case GGL_PIXEL_FORMAT_YCbCr_420_SP:
- // just show the Y plane of YUV buffers
- bpp = 1;
- break;
default:
+ if (isSupportedYuvFormat(t.format)) {
+ // just show the Y plane of YUV buffers
+ bpp = 1;
+ break;
+ }
// oops, we don't handle this format!
LOGE("layer %p, texture=%d, using format %d, which is not "
"supported by the GL", this, texture->name, t.format);
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index 4d7bef8da704..5b96e9dc834f 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -509,6 +509,21 @@ void LayerBase::validateTexture(GLint textureName) const
}
}
+bool LayerBase::isSupportedYuvFormat(int format) const
+{
+ switch (format) {
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_422_P:
+ case HAL_PIXEL_FORMAT_YCbCr_420_P:
+ case HAL_PIXEL_FORMAT_YCbCr_422_I:
+ case HAL_PIXEL_FORMAT_YCbCr_420_I:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ return true;
+ }
+ return false;
+}
+
void LayerBase::loadTexture(Texture* texture,
const Region& dirty, const GGLSurface& t) const
{
@@ -573,21 +588,20 @@ void LayerBase::loadTexture(Texture* texture,
data = t.data;
}
- if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
+ if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
glTexImage2D(GL_TEXTURE_2D, 0,
GL_RGB, texture->potWidth, texture->potHeight, 0,
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
- } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
+ } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
glTexImage2D(GL_TEXTURE_2D, 0,
GL_RGBA, texture->potWidth, texture->potHeight, 0,
GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
- } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888 ||
- t.format == GGL_PIXEL_FORMAT_RGBX_8888) {
+ } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
+ t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
glTexImage2D(GL_TEXTURE_2D, 0,
GL_RGBA, texture->potWidth, texture->potHeight, 0,
GL_RGBA, GL_UNSIGNED_BYTE, data);
- } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP ||
- t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
+ } else if (isSupportedYuvFormat(t.format)) {
// just show the Y plane of YUV buffers
glTexImage2D(GL_TEXTURE_2D, 0,
GL_LUMINANCE, texture->potWidth, texture->potHeight, 0,
@@ -599,24 +613,23 @@ void LayerBase::loadTexture(Texture* texture,
}
}
if (!data) {
- if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
+ if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, bounds.top, t.width, bounds.height(),
GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
t.data + bounds.top*t.stride*2);
- } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
+ } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, bounds.top, t.width, bounds.height(),
GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
t.data + bounds.top*t.stride*2);
- } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888 ||
- t.format == GGL_PIXEL_FORMAT_RGBX_8888) {
+ } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
+ t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, bounds.top, t.width, bounds.height(),
GL_RGBA, GL_UNSIGNED_BYTE,
t.data + bounds.top*t.stride*4);
- } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP ||
- t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
+ } else if (isSupportedYuvFormat(t.format)) {
// just show the Y plane of YUV buffers
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, bounds.top, t.width, bounds.height(),
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index a49faf7663a3..d1bbd046886b 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -265,6 +265,7 @@ protected:
status_t initializeEglImage(
const sp<GraphicBuffer>& buffer, Texture* texture);
+ bool isSupportedYuvFormat(int format) const;
sp<SurfaceFlinger> mFlinger;
uint32_t mFlags;
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index bd3113b4da02..6d1685b99e66 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -472,10 +472,12 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const
// First, try to use the buffer as an EGLImage directly
if (mUseEGLImageDirectly) {
// NOTE: Assume the buffer is allocated with the proper USAGE flags
+
sp<GraphicBuffer> buffer = new GraphicBuffer(
src.img.w, src.img.h, src.img.format,
GraphicBuffer::USAGE_HW_TEXTURE,
src.img.w, src.img.handle, false);
+
err = mLayer.initializeEglImage(buffer, &mTexture);
if (err != NO_ERROR) {
mUseEGLImageDirectly = false;
@@ -563,33 +565,27 @@ status_t LayerBuffer::BufferSource::initTempBuffer() const
}
// Allocate a temporary buffer and create the corresponding EGLImageKHR
-
- status_t err;
- mTempGraphicBuffer.clear();
- mTempGraphicBuffer = new GraphicBuffer(
+ // once the EGLImage has been created we don't need the
+ // graphic buffer reference anymore.
+ sp<GraphicBuffer> buffer = new GraphicBuffer(
w, h, HAL_PIXEL_FORMAT_RGB_565,
GraphicBuffer::USAGE_HW_TEXTURE |
GraphicBuffer::USAGE_HW_2D);
- err = mTempGraphicBuffer->initCheck();
+ status_t err = buffer->initCheck();
if (err == NO_ERROR) {
NativeBuffer& dst(mTempBuffer);
- dst.img.w = mTempGraphicBuffer->getStride();
+ dst.img.w = buffer->getStride();
dst.img.h = h;
- dst.img.format = mTempGraphicBuffer->getPixelFormat();
- dst.img.handle = (native_handle_t *)mTempGraphicBuffer->handle;
+ dst.img.format = buffer->getPixelFormat();
+ dst.img.handle = (native_handle_t *)buffer->handle;
dst.img.base = 0;
dst.crop.l = 0;
dst.crop.t = 0;
dst.crop.r = w;
dst.crop.b = h;
- err = mLayer.initializeEglImage(
- mTempGraphicBuffer, &mTexture);
- // once the EGLImage has been created (whether it fails
- // or not) we don't need the graphic buffer reference
- // anymore.
- mTempGraphicBuffer.clear();
+ err = mLayer.initializeEglImage(buffer, &mTexture);
}
return err;
@@ -606,9 +602,6 @@ void LayerBuffer::BufferSource::clearTempBufferImage() const
Texture defaultTexture;
mTexture = defaultTexture;
mTexture.name = mLayer.createTexture();
-
- // and the associated buffer
- mTempGraphicBuffer.clear();
}
// ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index 3257b76c45e7..eb5b8eb87e68 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -144,7 +144,6 @@ private:
size_t mBufferSize;
mutable LayerBase::Texture mTexture;
mutable NativeBuffer mTempBuffer;
- mutable sp<GraphicBuffer> mTempGraphicBuffer;
mutable bool mUseEGLImageDirectly;
};
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
index b65ed9736ba9..9b41804eafc5 100644
--- a/libs/ui/PixelFormat.cpp
+++ b/libs/ui/PixelFormat.cpp
@@ -16,14 +16,17 @@
#include <ui/PixelFormat.h>
#include <pixelflinger/format.h>
+#include <hardware/hardware.h>
namespace android {
+static const int COMPONENT_YUV = 0xFF;
+
size_t PixelFormatInfo::getScanlineSize(unsigned int width) const
{
size_t size;
- if ((components >= 6) && (components <= 8)) {
- // YCbCr formats are differents.
+ if (components == COMPONENT_YUV) {
+ // YCbCr formats are different.
size = (width * bitsPerPixel)>>3;
} else {
size = width * bytesPerPixel;
@@ -53,14 +56,42 @@ status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info)
if (info->version != sizeof(PixelFormatInfo))
return INVALID_OPERATION;
+ // YUV format from the HAL are handled here
+ switch (format) {
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_422_P:
+ case HAL_PIXEL_FORMAT_YCbCr_422_I:
+ case HAL_PIXEL_FORMAT_CbYCrY_422_I:
+ info->bitsPerPixel = 16;
+ goto done;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_TILED:
+ case HAL_PIXEL_FORMAT_YCbCr_420_P:
+ case HAL_PIXEL_FORMAT_YCbCr_420_I:
+ case HAL_PIXEL_FORMAT_CbYCrY_420_I:
+ info->bitsPerPixel = 12;
+ done:
+ info->format = format;
+ info->components = COMPONENT_YUV;
+ info->bytesPerPixel = 1;
+ info->h_alpha = 0;
+ info->l_alpha = 0;
+ info->h_red = info->h_green = info->h_blue = 8;
+ info->l_red = info->l_green = info->l_blue = 0;
+ return NO_ERROR;
+ }
+
size_t numEntries;
const GGLFormat *i = gglGetPixelFormatTable(&numEntries) + format;
bool valid = uint32_t(format) < numEntries;
if (!valid) {
return BAD_INDEX;
}
-
- #define COMPONENT(name) \
+
+ #define COMPONENT(name) \
case GGL_##name: info->components = PixelFormatInfo::name; break;
switch (i->components) {
@@ -69,9 +100,6 @@ status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info)
COMPONENT(RGBA)
COMPONENT(LUMINANCE)
COMPONENT(LUMINANCE_ALPHA)
- COMPONENT(Y_CB_CR_SP)
- COMPONENT(Y_CB_CR_P)
- COMPONENT(Y_CB_CR_I)
default:
return BAD_INDEX;
}
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index 59409a2bf919..d2cfd3b5c43b 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -75,7 +75,6 @@ include $(CLEAR_VARS)
# we have the common sources, plus some device-specific stuff
LOCAL_SRC_FILES:= \
$(commonSources) \
- Unicode.cpp \
BackupData.cpp \
BackupHelpers.cpp
diff --git a/libs/utils/CharacterData.h b/libs/utils/CharacterData.h
deleted file mode 100644
index e931d995e50d..000000000000
--- a/libs/utils/CharacterData.h
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Automatically generated on 07-11-2006 by make-CharacterDataC
-// DO NOT EDIT DIRECTLY
-namespace CharacterData {
-
- // Structure containing an array of ranges
- struct Range {
- int length;
- const uint32_t* array;
- };
-
- // For Latin1 characters just index into this array to get the index and decomposition
- static const uint16_t LATIN1_DATA[] = {
- 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
- 0x0001, 0x0002, 0x0003, 0x0002, 0x0004, 0x0003, 0x0001, 0x0001,
- 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
- 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0003, 0x0003, 0x0002,
- 0x0005, 0x0006, 0x0006, 0x0007, 0x0008, 0x0007, 0x0006, 0x0006,
- 0x0009, 0x000A, 0x0006, 0x000B, 0x000C, 0x000D, 0x000C, 0x000C,
- 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015,
- 0x0016, 0x0017, 0x000C, 0x0006, 0x0018, 0x0019, 0x001A, 0x0006,
- 0x0006, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021,
- 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029,
- 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031,
- 0x0032, 0x0033, 0x0034, 0x0035, 0x0006, 0x0036, 0x0037, 0x0038,
- 0x0037, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
- 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
- 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
- 0x0050, 0x0051, 0x0052, 0x0035, 0x0019, 0x0036, 0x0019, 0x0001,
- 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0001, 0x0001,
- 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
- 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
- 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
- 0x5853, 0x0006, 0x0008, 0x0008, 0x0008, 0x0008, 0x0054, 0x0054,
- 0x1037, 0x0054, 0x7855, 0x0056, 0x0019, 0x0057, 0x0054, 0x1037,
- 0x0058, 0x0059, 0x785A, 0x785B, 0x1037, 0x105C, 0x0054, 0x0006,
- 0x1037, 0x785D, 0x7855, 0x005E, 0x305F, 0x305F, 0x305F, 0x0006,
- 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0060, 0x0860,
- 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860,
- 0x0060, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0019,
- 0x0060, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0060, 0x0055,
- 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0061, 0x0861,
- 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861,
- 0x0061, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0019,
- 0x0061, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0061, 0x0862
- };
-
- // Each of these arrays is stripped into ranges. In order to build the arrays, each
- // codepoint was bit-shifted so that even and odd characters were separated into different
- // arrays. The identifier of each array is the top byte after bit-shifting.
- // The numbers stored in the array are the bit-shifted codepoint, the decomposition, and an
- // index into another array of all possible packed data values. The top 16 bits are the
- // codepoint and the bottom 16 are the decomposition and index. The top 5 bits for the decomposition
- // and the rest for the index.
- static const uint32_t a0[] = {
- 0x00800863, 0x00880063, 0x00890863, 0x00930063, 0x00940863, 0x00980864, 0x00991063, 0x009A0863,
- 0x009C0055, 0x009D0865, 0x00A01065, 0x00A10065, 0x00A20865, 0x00A50063, 0x00A60863, 0x00A90063,
- 0x00AA0863, 0x00B30063, 0x00B40863, 0x00BC0866, 0x00BD0865, 0x00C00055, 0x00C10063, 0x00C30067,
- 0x00C40065, 0x00C50068, 0x00C60065, 0x00C70069, 0x00C8006A, 0x00C90065, 0x00CA006B, 0x00CB006C,
- 0x00CC0063, 0x00CD006D, 0x00CE006C, 0x00CF006E, 0x00D00863, 0x00D10063, 0x00D3006F, 0x00D40065,
- 0x00D50055, 0x00D60063, 0x00D7006F, 0x00D80865, 0x00D90070, 0x00DA0065, 0x00DC0063, 0x00DD0055,
- 0x00DE0063, 0x00DF0055, 0x00E00071, 0x00E21072, 0x00E31073, 0x00E41074, 0x00E51072, 0x00E61073,
- 0x00E70865, 0x00EF0863, 0x00F20063, 0x00F30863, 0x00F80855, 0x00F91074, 0x00FA0863, 0x00FB0075,
- 0x00FC0863, 0x010E0063, 0x010F0863, 0x01100076, 0x01110063, 0x01130863, 0x011A0055, 0x011D0077,
- 0x011E0065, 0x011F0077, 0x01200055, 0x01210078, 0x01280055, 0x012A0079, 0x012B007A, 0x012C0055,
- 0x0130007A, 0x01310055, 0x0134007B, 0x01350055, 0x0139007C, 0x013A0055, 0x0140007D, 0x01410055,
- 0x0144007D, 0x0145007E, 0x01460055, 0x0149007F, 0x014A0080, 0x014B0055, 0x01587881, 0x015D0082,
- 0x015E0081, 0x01610037, 0x01630082, 0x01680081, 0x01690037, 0x016C1037, 0x016F0037, 0x01707881,
- 0x01730037, 0x01770081, 0x01780037, 0x01800083, 0x01A00883, 0x01A10083, 0x01A20883, 0x01A30083,
- 0x01B80078, 0x01BA0837, 0x01BB0078, 0x01BD1081, 0x01BE0078, 0x01BF0806, 0x01C00078, 0x01C21037,
- 0x01C30884, 0x01C40885, 0x01C60886, 0x01C70887, 0x01C80855, 0x01C90060, 0x01D10078, 0x01D20060,
- 0x01D50860, 0x01D60888, 0x01D70889, 0x01D80855, 0x01D90061, 0x01E1008A, 0x01E20061, 0x01E50861,
- 0x01E6088B, 0x01E7088C, 0x01E8108D, 0x01E91077, 0x01EA0877, 0x01EB108E, 0x01EC0063, 0x01F8108F,
- 0x01F91090, 0x01FA1091, 0x01FB0019, 0x01FC0065, 0x01FD0063, 0x01FE0055, 0x01FF0077, 0x02000892,
- 0x02010092, 0x02060892, 0x02080060, 0x02180061, 0x02280893, 0x02290093, 0x022E0893, 0x02300063,
- 0x023B0863, 0x023C0063, 0x02410094, 0x02420083, 0x02440095, 0x02450063, 0x02600077, 0x02610865,
- 0x02620065, 0x02680863, 0x026A0063, 0x026B0863, 0x026C0063, 0x026D0863, 0x02700063, 0x02710863,
- 0x02740063, 0x02750863, 0x027B0063, 0x027C0863, 0x027D0078, 0x02800063, 0x02880078, 0x02990096,
- 0x02AC0078, 0x02AD0097, 0x02B00078, 0x02B10098, 0x02C40078, 0x02C50099, 0x02C60078, 0x02C90083,
- 0x02DD0078, 0x02DE0083, 0x02DF009A, 0x02E10083, 0x02E3009A, 0x02E40078, 0x02E8009B, 0x02F60078,
- 0x02F8009B, 0x02FA009A, 0x02FB0078, 0x0300009C, 0x03020078, 0x0306000C, 0x03070054, 0x03080083,
- 0x030B0078, 0x030F009D, 0x03100078, 0x0311089E, 0x0314009E, 0x031E0078, 0x0320009F, 0x0321009E,
- 0x03260083, 0x033000A0, 0x033100A1, 0x033200A2, 0x033300A3, 0x033400A4, 0x03350007, 0x033600A5,
- 0x0337009E, 0x03380083, 0x0339009E, 0x033B109E, 0x033D009E, 0x0360089E, 0x0362009E, 0x036A009D,
- 0x036B0083, 0x036F0095, 0x03700083, 0x0373009F, 0x03740083, 0x0377009E, 0x0378000E, 0x03790010,
- 0x037A0012, 0x037B0014, 0x037C0016, 0x037D009E, 0x037F00A6, 0x0380009D, 0x03870078, 0x0388009E,
- 0x03980083, 0x03A60078, 0x03A7009E, 0x03B70078, 0x03C0009E, 0x03D30083, 0x03D90078, 0x04810083,
- 0x04820071, 0x049A0871, 0x049B0071, 0x049D0078, 0x049E0083, 0x049F00A7, 0x04A10083, 0x04A500A7,
- 0x04A70078, 0x04A80071, 0x04A90083, 0x04AB0078, 0x04AC0871, 0x04B00071, 0x04B10083, 0x04B20097,
- 0x04B300A8, 0x04B400A9, 0x04B500AA, 0x04B600AB, 0x04B700AC, 0x04B80097, 0x04B90078, 0x04C100A7,
- 0x04C20078, 0x04C30071, 0x04C70078, 0x04C80071, 0x04C90078, 0x04CA0071, 0x04DA0078, 0x04DB0071,
- 0x04DD0078, 0x04DE0083, 0x04DF00A7, 0x04E10083, 0x04E30078, 0x04E400A7, 0x04E50078, 0x04E608A7,
- 0x04E70071, 0x04E80078, 0x04EE0871, 0x04EF0078, 0x04F00071, 0x04F10083, 0x04F20078, 0x04F300A8,
- 0x04F400A9, 0x04F500AA, 0x04F600AB, 0x04F700AC, 0x04F80071, 0x04F90008, 0x04FA00AD, 0x04FB00AE,
- 0x04FC00AF, 0x04FD0094, 0x04FE0078, 0x05010083, 0x05020078, 0x05030071, 0x05060078, 0x05080071,
- 0x05090078, 0x050A0071, 0x051A0078, 0x051B0871, 0x051C0071, 0x051D0078, 0x051E0083, 0x051F00A7,
- 0x05210083, 0x05220078, 0x05240083, 0x05250078, 0x05260083, 0x05270078, 0x052D0871, 0x052E0071,
- 0x052F0871, 0x05300078, 0x053300A8, 0x053400A9, 0x053500AA, 0x053600AB, 0x053700AC, 0x05380083,
- 0x05390071, 0x053B0078, 0x05410083, 0x05420078, 0x05430071, 0x05470078, 0x05480071, 0x05490078,
- 0x054A0071, 0x055A0078, 0x055B0071, 0x055D0078, 0x055E0083, 0x055F00A7, 0x05610083, 0x05630078,
- 0x05640083, 0x05650078, 0x056600A7, 0x05670078, 0x05680071, 0x05690078, 0x05700071, 0x05710083,
- 0x05720078, 0x057300A8, 0x057400A9, 0x057500AA, 0x057600AB, 0x057700AC, 0x05780078, 0x058100A7,
- 0x05820078, 0x05830071, 0x05870078, 0x05880071, 0x05890078, 0x058A0071, 0x059A0078, 0x059B0071,
- 0x059D0078, 0x059E0083, 0x059F00A7, 0x05A10083, 0x05A20078, 0x05A408A7, 0x05A50078, 0x05A608A7,
- 0x05A70078, 0x05AB0083, 0x05AC0078, 0x05AE0871, 0x05AF0078, 0x05B00071, 0x05B10078, 0x05B300A8,
- 0x05B400A9, 0x05B500AA, 0x05B600AB, 0x05B700AC, 0x05B80094, 0x05B90078, 0x05C10083, 0x05C20078,
- 0x05C30071, 0x05C60078, 0x05C70071, 0x05CA0871, 0x05CB0078, 0x05CD0071, 0x05D00078, 0x05D20071,
- 0x05D30078, 0x05D40071, 0x05D60078, 0x05D70071, 0x05DD0078, 0x05DF00A7, 0x05E00083, 0x05E100A7,
- 0x05E20078, 0x05E300A7, 0x05E508A7, 0x05E70078, 0x05F300A8, 0x05F400A9, 0x05F500AA, 0x05F600AB,
- 0x05F700AC, 0x05F800B0, 0x05F900B1, 0x05FA0054, 0x05FE0078, 0x060100A7, 0x06020078, 0x06030071,
- 0x061A0078, 0x061B0071, 0x061D0078, 0x061F0083, 0x062100A7, 0x06230083, 0x06240883, 0x06250083,
- 0x06270078, 0x062B0083, 0x062C0078, 0x06300071, 0x06310078, 0x063300A8, 0x063400A9, 0x063500AA,
- 0x063600AB, 0x063700AC, 0x06380078, 0x064100A7, 0x06420078, 0x06430071, 0x065A0078, 0x065B0071,
- 0x065D0078, 0x065E0083, 0x065F00A7, 0x066008A7, 0x066100A7, 0x066300B2, 0x066408A7, 0x06660083,
- 0x06670078, 0x066B00A7, 0x066C0078, 0x066F0071, 0x06710078, 0x067300A8, 0x067400A9, 0x067500AA,
- 0x067600AB, 0x067700AC, 0x06780078, 0x068100A7, 0x06820078, 0x06830071, 0x069D0078, 0x069F00A7,
- 0x06A10083, 0x06A20078, 0x06A300A7, 0x06A508A7, 0x06A70078, 0x06B00071, 0x06B10078, 0x06B300A8,
- 0x06B400A9, 0x06B500AA, 0x06B600AB, 0x06B700AC, 0x06B80078, 0x06C100A7, 0x06C20078, 0x06C30071,
- 0x06CC0078, 0x06CD0071, 0x06D90078, 0x06DA0071, 0x06DE0078, 0x06E00071, 0x06E40078, 0x06E50083,
- 0x06E60078, 0x06E800A7, 0x06E90083, 0x06EC00A7, 0x06ED08A7, 0x06F00078, 0x06F900A7, 0x06FA0097,
- 0x06FB0078, 0x07010071, 0x071A0083, 0x071E0078, 0x07200071, 0x07230081, 0x07240083, 0x072800A8,
- 0x072900A9, 0x072A00AA, 0x072B00AB, 0x072C00AC, 0x072D0097, 0x072E0078, 0x07410071, 0x07430078,
- 0x07440071, 0x07460078, 0x074A0071, 0x074C0078, 0x074D0071, 0x07500078, 0x07510071, 0x07520078,
- 0x07550071, 0x07560078, 0x07570071, 0x075A0083, 0x075D0078, 0x075E0083, 0x075F0078, 0x07600071,
- 0x07630081, 0x07640083, 0x07670078, 0x076800A8, 0x076900A9, 0x076A00AA, 0x076B00AB, 0x076C00AC,
- 0x076D0078, 0x076E1071, 0x076F0078, 0x07800071, 0x07810094, 0x07820097, 0x07865897, 0x07870097,
- 0x078A0094, 0x078C0083, 0x078D0094, 0x079000A8, 0x079100A9, 0x079200AA, 0x079300AB, 0x079400AC,
- 0x079500B3, 0x079A0094, 0x079D00B4, 0x079F00A7, 0x07A00071, 0x07A40078, 0x07A50071, 0x07A90871,
- 0x07AA0071, 0x07AE0871, 0x07AF0071, 0x07B60078, 0x07B90083, 0x07BB0883, 0x07BD0083, 0x07C40071,
- 0x07C60078, 0x07C80083, 0x07CC0078, 0x07CD0083, 0x07D10883, 0x07D20083, 0x07D60883, 0x07D70083,
- 0x07DF0094, 0x07E30083, 0x07E40094, 0x07E70078, 0x07E80097, 0x07E90078, 0x08000071, 0x08110078,
- 0x08120071, 0x08130871, 0x08140078, 0x08150071, 0x081600A7, 0x08170083, 0x081A0078, 0x081B0083,
- 0x081C00A7, 0x081D0078, 0x082000A8, 0x082100A9, 0x082200AA, 0x082300AB, 0x082400AC, 0x08250097,
- 0x08280071, 0x082B00A7, 0x082C0083, 0x082D0078, 0x085000B5, 0x08630078, 0x08680071, 0x087E7881,
- 0x087F0078, 0x08800071, 0x08AD0078, 0x08B00071, 0x08D20078, 0x08D40071, 0x08FD0078, 0x09000071,
- 0x09270078, 0x09280071, 0x092F0078, 0x09300071, 0x09470078, 0x09480071, 0x095B0078, 0x095C0071,
- 0x09630078, 0x09640071, 0x098B0078, 0x098C0071, 0x09AE0078, 0x09B00094, 0x09B10097, 0x09B500B6,
- 0x09B600B7, 0x09B700B8, 0x09B800B9, 0x09B900B0, 0x09BA00BA, 0x09BB00BB, 0x09BC00BC, 0x09BD00BD,
- 0x09BE00BE, 0x09BF0078, 0x09C00071, 0x09C80054, 0x09CD0078, 0x09D00071, 0x09FB0078, 0x0A010071,
- 0x0B370097, 0x0B380071, 0x0B3C0078, 0x0B400005, 0x0B410071, 0x0B4E00BF, 0x0B4F0078, 0x0B500071,
- 0x0B760097, 0x0B7700C0, 0x0B7800C1, 0x0B790078, 0x0B800071, 0x0B890083, 0x0B8B0078, 0x0B900071,
- 0x0B990083, 0x0B9B0097, 0x0B9C0078, 0x0BA00071, 0x0BA90083, 0x0BAA0078, 0x0BB00071, 0x0BB90083,
- 0x0BBA0078, 0x0BC00071, 0x0BDA00C2, 0x0BDB00A7, 0x0BDC0083, 0x0BDF00A7, 0x0BE30083, 0x0BE400A7,
- 0x0BE50083, 0x0BEA0097, 0x0BEE0071, 0x0BEF0078, 0x0BF000A8, 0x0BF100A9, 0x0BF200AA, 0x0BF300AB,
- 0x0BF400AC, 0x0BF50078, 0x0BF800C3, 0x0BF900C4, 0x0BFA00C5, 0x0BFB00C6, 0x0BFC00C7, 0x0BFD0078,
- 0x0C000006, 0x0C030099, 0x0C040006, 0x0C060083, 0x0C070005, 0x0C0800A8, 0x0C0900A9, 0x0C0A00AA,
- 0x0C0B00AB, 0x0C0C00AC, 0x0C0D0078, 0x0C100071, 0x0C3C0078, 0x0C400071, 0x0C550078, 0x0C800071,
- 0x0C8F0078, 0x0C900083, 0x0C9200A7, 0x0C940083, 0x0C9500C8, 0x0C960078, 0x0C9800A7, 0x0C990083,
- 0x0C9A00A7, 0x0C9D0083, 0x0C9E0078, 0x0CA00054, 0x0CA10078, 0x0CA20006, 0x0CA300A8, 0x0CA400A9,
- 0x0CA500AA, 0x0CA600AB, 0x0CA700AC, 0x0CA80071, 0x0CB70078, 0x0CB80071, 0x0CBB0078, 0x0CC00071,
- 0x0CD50078, 0x0CD800A7, 0x0CE10071, 0x0CE400A7, 0x0CE50078, 0x0CE800A8, 0x0CE900A9, 0x0CEA00AA,
- 0x0CEB00AB, 0x0CEC00AC, 0x0CED0078, 0x0CEF0006, 0x0CF00054, 0x0D000071, 0x0D0C0083, 0x0D0D00A7,
- 0x0D0E0078, 0x0D0F0097, 0x0D100078, 0x0E800055, 0x0E967881, 0x0EA70081, 0x0EA87881, 0x0EB17055,
- 0x0EB60055, 0x0EBC7881, 0x0EBD0055, 0x0ECE7881, 0x0EE00083, 0x0EE20078, 0x0F000863, 0x0F4B0855,
- 0x0F4D1055, 0x0F4E0078, 0x0F500863, 0x0F7D0078, 0x0F8008C9, 0x0F8408CA, 0x0F8808C9, 0x0F8B0078,
- 0x0F8C08CA, 0x0F8F0078, 0x0F9008C9, 0x0F9408CA, 0x0F9808C9, 0x0F9C08CA, 0x0FA008C9, 0x0FA30078,
- 0x0FA408CA, 0x0FA70078, 0x0FA80855, 0x0FAC0078, 0x0FB008C9, 0x0FB408CA, 0x0FB808CB, 0x0FB908CC,
- 0x0FBB08CD, 0x0FBC08CE, 0x0FBD08CF, 0x0FBE08D0, 0x0FBF0078, 0x0FC008C9, 0x0FC408D1, 0x0FC808C9,
- 0x0FCC08D1, 0x0FD008C9, 0x0FD408D1, 0x0FD808C9, 0x0FD90855, 0x0FDC08CA, 0x0FDD08D2, 0x0FDE08D3,
- 0x0FDF08D4, 0x0FE01037, 0x0FE10855, 0x0FE408D5, 0x0FE608D3, 0x0FE70837, 0x0FE808C9, 0x0FE90855,
- 0x0FEA0078, 0x0FEB0855, 0x0FEC08CA, 0x0FED08D6, 0x0FEE0078, 0x0FEF0837, 0x0FF008C9, 0x0FF10855,
- 0x0FF408CA, 0x0FF508D7, 0x0FF608D8, 0x0FF70837, 0x0FF80078, 0x0FF90855, 0x0FFC08D9, 0x0FFD08DA,
- 0x0FFE08D3, 0x0FFF1037, 0x10000805, 0x10011005, 0x10060057, 0x100700C2, 0x10080099, 0x100B0006,
- 0x100C00DB, 0x100D00B4, 0x100E00DB, 0x100F00B4, 0x10100006, 0x10121006, 0x101400DC, 0x101500DD,
- 0x101600DE, 0x101700DF, 0x10180007, 0x101A1007, 0x101B1006, 0x101C0006, 0x101D00E0, 0x101E1006,
- 0x10200038, 0x10210006, 0x102200E1, 0x1023000A, 0x10241006, 0x10250006, 0x10290019, 0x102A0038,
- 0x102B0006, 0x10300057, 0x10320078, 0x10350057, 0x103878E2, 0x10390078, 0x103A78E3, 0x103B78E4,
- 0x103C78E5, 0x103D780B, 0x103E7819, 0x103F780A, 0x104070E2, 0x1041705A, 0x104270E3, 0x104370E4,
- 0x104470E5, 0x1045700B, 0x10467019, 0x1047700A, 0x10487081, 0x104B0078, 0x10500008, 0x10541008,
- 0x10550008, 0x105B0078, 0x10680083, 0x106F0095, 0x10730083, 0x10760078, 0x10801054, 0x10812877,
- 0x10820054, 0x10831054, 0x10840054, 0x10852855, 0x10862877, 0x10872855, 0x10882877, 0x108A0054,
- 0x108B1054, 0x108C0054, 0x108D2877, 0x108F0054, 0x10907854, 0x10922877, 0x109308E6, 0x10942877,
- 0x109508E7, 0x10962877, 0x10970058, 0x10982877, 0x10990054, 0x109A2855, 0x109B1071, 0x109D0054,
- 0x109E2855, 0x109F2877, 0x10A028E8, 0x10A10019, 0x10A32855, 0x10A50054, 0x10A70078, 0x10AA305F,
- 0x10B010E9, 0x10B110EA, 0x10B210EB, 0x10B310EC, 0x10B410ED, 0x10B510EE, 0x10B610EF, 0x10B710F0,
- 0x10B810F1, 0x10B910F2, 0x10BA10F3, 0x10BB10F4, 0x10BC10F5, 0x10BD10F6, 0x10BE10F7, 0x10BF10F8,
- 0x10C000F9, 0x10C100FA, 0x10C20078, 0x10C80019, 0x10CB0054, 0x10CD0819, 0x10CE0054, 0x10D00019,
- 0x10D10054, 0x10D30019, 0x10D40054, 0x10D70819, 0x10D80054, 0x10E70819, 0x10E80054, 0x10E90019,
- 0x10EB0054, 0x10FA0019, 0x110100E8, 0x110208E8, 0x11030019, 0x110400FB, 0x110608FC, 0x11070019,
- 0x1109000B, 0x110A0019, 0x110B00E8, 0x110C0019, 0x110D00E8, 0x110F0019, 0x111000E8, 0x111208E8,
- 0x11140019, 0x111610E8, 0x111700E8, 0x111810E8, 0x111900E8, 0x111A0019, 0x111E00FD, 0x111F00E8,
- 0x112208E8, 0x112300E8, 0x11270019, 0x112900FD, 0x112B0019, 0x113008E8, 0x113200FD, 0x11360019,
- 0x113708FD, 0x113900FD, 0x113A08FD, 0x113B00FD, 0x113C08FD, 0x113D00FD, 0x114008FD, 0x114100FD,
- 0x114208FD, 0x114300FD, 0x114408FD, 0x114500FD, 0x114600E8, 0x11470019, 0x114800FE, 0x114A0019,
- 0x114C00FF, 0x114D0019, 0x115100FD, 0x11520019, 0x11530100, 0x11540101, 0x115500E8, 0x115608E8,
- 0x115800FD, 0x115C00E8, 0x115D0019, 0x115F00E8, 0x11600019, 0x116500FE, 0x11670019, 0x116800FD,
- 0x11690019, 0x116B00FD, 0x117008FD, 0x117200FD, 0x117508FD, 0x11770019, 0x117800FD, 0x11790102,
- 0x117B0103, 0x117C00E8, 0x117D0104, 0x117F0105, 0x11800054, 0x118400FD, 0x11860054, 0x119000E8,
- 0x11910054, 0x1195080A, 0x11960054, 0x119B0094, 0x11BE0019, 0x11BF0054, 0x11CE0019, 0x11DA00B4,
- 0x11DB0006, 0x11DC0054, 0x11EE0078, 0x12000054, 0x12140078, 0x12200054, 0x12260078, 0x12301906,
- 0x12311907, 0x12321908, 0x12331909, 0x1234190A, 0x1235190B, 0x1236190C, 0x1237190D, 0x1238190E,
- 0x1239190F, 0x123A1106, 0x123B1107, 0x123C1108, 0x123D1109, 0x123E110A, 0x123F110B, 0x1240110C,
- 0x1241110D, 0x1242110E, 0x1243110F, 0x1244105D, 0x1245105B, 0x12461110, 0x12471111, 0x12481112,
- 0x12491113, 0x124A1114, 0x124B1115, 0x124C1116, 0x124D1117, 0x124E1094, 0x125B1918, 0x12681919,
- 0x127518C3, 0x1276011A, 0x1277011B, 0x1278011C, 0x1279011D, 0x127A011E, 0x127B00C4, 0x127C00C5,
- 0x127D00C6, 0x127E00C7, 0x127F011F, 0x12800054, 0x12FC0019, 0x13000054, 0x134F0078, 0x13500054,
- 0x13560094, 0x13570054, 0x13590078, 0x13810054, 0x13850078, 0x13860054, 0x13940078, 0x13950054,
- 0x13A60078, 0x13A80054, 0x13AA0078, 0x13AB0054, 0x13B00078, 0x13B10054, 0x13B40009, 0x13BB0106,
- 0x13BC0107, 0x13BD0108, 0x13BE0109, 0x13BF010A, 0x13C00106, 0x13C10107, 0x13C20108, 0x13C30109,
- 0x13C4010A, 0x13C50106, 0x13C60107, 0x13C70108, 0x13C80109, 0x13C9010A, 0x13CA0054, 0x13CB0078,
- 0x13CC0054, 0x13D80078, 0x13D90054, 0x13E000E8, 0x13E10019, 0x13E200FE, 0x13E3000A, 0x13E40078,
- 0x13E80019, 0x13EA00E8, 0x13EB00FE, 0x13EC0019, 0x13EE00E8, 0x13EF00FE, 0x13F00019, 0x13F100FD,
- 0x13F30009, 0x13F60078, 0x13F80019, 0x14000094, 0x14800019, 0x14C2000A, 0x14C70120, 0x14C80121,
- 0x14C9000A, 0x14CD0019, 0x14CE00E8, 0x14D80019, 0x14DC0122, 0x14DD0019, 0x14E000FD, 0x14E100E8,
- 0x14E200FD, 0x14E30019, 0x14E700E8, 0x14E800FE, 0x14EA00FD, 0x14EB0019, 0x14EC0009, 0x14EE00E8,
- 0x14EF0019, 0x14F200E8, 0x14F30019, 0x14F400E8, 0x14F50019, 0x14FA00E8, 0x14FC00FD, 0x14FD0019,
- 0x14FE0009, 0x14FF0019, 0x150500E8, 0x150610E8, 0x150700E8, 0x15110019, 0x151200E8, 0x15140019,
- 0x151600FE, 0x15180019, 0x151A00FD, 0x151B0019, 0x151E00FD, 0x151F00E8, 0x15200019, 0x152C00E8,
- 0x152D0019, 0x153200FD, 0x15330019, 0x153500E8, 0x15370019, 0x153800E8, 0x15390019, 0x153A10E8,
- 0x153B1019, 0x153C0019, 0x153D00FE, 0x153E00E8, 0x153F00FE, 0x154300E8, 0x154600FE, 0x154700E8,
- 0x154900FE, 0x154F00E8, 0x155100FE, 0x15520019, 0x155300FD, 0x15570019, 0x155800FE, 0x155900E8,
- 0x155A00FE, 0x155B00E8, 0x155E00FE, 0x156400E8, 0x156700FE, 0x156C0019, 0x156E08E8, 0x156F0123,
- 0x15700019, 0x157100E8, 0x15720124, 0x157300E8, 0x15740019, 0x157600FD, 0x157700E8, 0x15780019,
- 0x157C00FE, 0x157E0019, 0x15800054, 0x158A0078, 0x16000096, 0x16180098, 0x16300078, 0x16400063,
- 0x16720055, 0x16730054, 0x16760078, 0x167D0006, 0x16800125, 0x16930078, 0x16980071, 0x16B30078,
- 0x16C00071, 0x16CC0078, 0x16D00071, 0x16F00078, 0x17000006, 0x17010126, 0x17030006, 0x170500E0,
- 0x17060126, 0x17070006, 0x170C0078, 0x170E0126, 0x170F0078, 0x17400054, 0x174D0078, 0x174E0054,
- 0x177A0078, 0x17801054, 0x17EB0078, 0x17F80054, 0x17FE0078, 0x18008805, 0x18010006, 0x18020054,
- 0x18030071, 0x18040009, 0x18090054, 0x180A0009, 0x180E0099, 0x180F00BF, 0x18100054, 0x18110127,
- 0x18120128, 0x18130129, 0x1814012A, 0x18150083, 0x18180099, 0x18190081, 0x181B1054, 0x181C112B,
- 0x181D112C, 0x181E0071, 0x181F0054, 0x18200078, 0x18210071, 0x18260871, 0x18320071, 0x18380871,
- 0x18390071, 0x183A0871, 0x183C0071, 0x183D0871, 0x183F0071, 0x184A0871, 0x184B0071, 0x184C0078,
- 0x184D0083, 0x184E1037, 0x184F0881, 0x18500099, 0x18510071, 0x18560871, 0x18620071, 0x18680871,
- 0x18690071, 0x186A0871, 0x186C0071, 0x186D0871, 0x186F0071, 0x187A0871, 0x187B0071, 0x187C0871,
- 0x187E0081, 0x187F0881, 0x18800078, 0x18830071, 0x18970078, 0x18991071, 0x18C80094, 0x18C978AD,
- 0x18CA78AE, 0x18CB7894, 0x18D00071, 0x18DC0078, 0x18E00054, 0x18E80078, 0x18F80071, 0x19001094,
- 0x190F1054, 0x191010AD, 0x191110AE, 0x1912112D, 0x1913112E, 0x1914112F, 0x19151094, 0x19220078,
- 0x19286854, 0x19291930, 0x192A1931, 0x192B1932, 0x192C1933, 0x192D1934, 0x192E1935, 0x192F1936,
- 0x19301894, 0x193E1854, 0x194018AD, 0x194118AE, 0x1942192D, 0x1943192E, 0x1944192F, 0x19451894,
- 0x19591937, 0x195A1938, 0x195B1939, 0x195C193A, 0x195D193B, 0x195E193C, 0x195F193D, 0x19601094,
- 0x19666854, 0x19681894, 0x19806894, 0x19AC1094, 0x19B96894, 0x19BC6854, 0x19BE6894, 0x19EF6854,
- 0x19F01094, 0x1A000071, 0x26DB0078, 0x26E00054, 0x27000071, 0x4FDE0078, 0x50000071, 0x52470078,
- 0x52480054, 0x52640078, 0x53800037, 0x538C0078, 0x54000071, 0x540100C8, 0x54020071, 0x54030083,
- 0x54040071, 0x541200A7, 0x54130083, 0x54140054, 0x54160078, 0x56000071, 0x6BD20078, 0x6C00013E,
- 0x7000013F, 0x7C800871, 0x7D070071, 0x7D080871, 0x7D0A0071, 0x7D0B0871, 0x7D120071, 0x7D130871,
- 0x7D140071, 0x7D150871, 0x7D170078, 0x7D180871, 0x7D360078, 0x7D380871, 0x7D6D0078, 0x7D801055,
- 0x7D840078, 0x7D8A1055, 0x7D8C0078, 0x7D8F0083, 0x7D90289B, 0x7D95089B, 0x7DA10078, 0x7DA2089B,
- 0x7DA8409E, 0x7DAA389E, 0x7DAB409E, 0x7DAC389E, 0x7DAD409E, 0x7DAE389E, 0x7DAF409E, 0x7DB0389E,
- 0x7DB1409E, 0x7DB2389E, 0x7DB3409E, 0x7DB4389E, 0x7DB5409E, 0x7DB6389E, 0x7DB7409E, 0x7DB8389E,
- 0x7DB9409E, 0x7DBA389E, 0x7DBB409E, 0x7DBC389E, 0x7DBD409E, 0x7DBE389E, 0x7DBF409E, 0x7DC0389E,
- 0x7DC1409E, 0x7DC8389E, 0x7DC9409E, 0x7DCA389E, 0x7DCB409E, 0x7DCC389E, 0x7DCD409E, 0x7DCE389E,
- 0x7DCF409E, 0x7DD1389E, 0x7DD2409E, 0x7DD4389E, 0x7DD5409E, 0x7DD6389E, 0x7DD7409E, 0x7DD90078,
- 0x7DEA209E, 0x7DEB489E, 0x7DEC209E, 0x7DEF409E, 0x7DF3389E, 0x7DF5409E, 0x7DFC389E, 0x7DFD209E,
- 0x7DFE409E, 0x7DFF389E, 0x7E00409E, 0x7E32209E, 0x7E4C389E, 0x7E70489E, 0x7E7B409E, 0x7E89209E,
- 0x7E97389E, 0x7E9A489E, 0x7E9E209E, 0x7E9F00B4, 0x7EA00078, 0x7EA8389E, 0x7EAC209E, 0x7EAE389E,
- 0x7EAF209E, 0x7EB0389E, 0x7EB1209E, 0x7EB4389E, 0x7EB5209E, 0x7EB8389E, 0x7EBA209E, 0x7EC3389E,
- 0x7EC80078, 0x7EC9389E, 0x7ECB209E, 0x7ECC389E, 0x7ECD209E, 0x7EDA389E, 0x7EDB209E, 0x7EDC389E,
- 0x7EDE209E, 0x7EE2389E, 0x7EE3209E, 0x7EE40078, 0x7EF8409E, 0x7EFE4140, 0x7EFF0078, 0x7F000083,
- 0x7F088006, 0x7F0C80BF, 0x7F0D0078, 0x7F100083, 0x7F120078, 0x7F188006, 0x7F198099, 0x7F1A8038,
- 0x7F1B80BF, 0x7F230006, 0x7F2480BF, 0x7F251006, 0x7F271038, 0x7F28600C, 0x7F2A6006, 0x7F2C6099,
- 0x7F2D60BF, 0x7F306006, 0x7F31600B, 0x7F326019, 0x7F346006, 0x7F356007, 0x7F360078, 0x7F38409E,
- 0x7F41209E, 0x7F46489E, 0x7F47209E, 0x7F49489E, 0x7F4A209E, 0x7F4C489E, 0x7F4D209E, 0x7F4E489E,
- 0x7F4F209E, 0x7F50489E, 0x7F51209E, 0x7F52489E, 0x7F53209E, 0x7F54489E, 0x7F55209E, 0x7F5A489E,
- 0x7F5B209E, 0x7F5C489E, 0x7F5D209E, 0x7F5E489E, 0x7F5F209E, 0x7F60489E, 0x7F61209E, 0x7F62489E,
- 0x7F63209E, 0x7F64489E, 0x7F65209E, 0x7F66489E, 0x7F67209E, 0x7F68489E, 0x7F69209E, 0x7F6A489E,
- 0x7F6B209E, 0x7F6C489E, 0x7F6D209E, 0x7F6E489E, 0x7F6F209E, 0x7F70489E, 0x7F71209E, 0x7F72489E,
- 0x7F73209E, 0x7F74489E, 0x7F75209E, 0x7F76489E, 0x7F77209E, 0x7F7A489E, 0x7F7B209E, 0x7F7F0078,
- 0x7F818806, 0x7F828808, 0x7F838806, 0x7F848809, 0x7F858806, 0x7F86880C, 0x7F88880E, 0x7F898810,
- 0x7F8A8812, 0x7F8B8814, 0x7F8C8816, 0x7F8D880C, 0x7F8E8818, 0x7F8F881A, 0x7F908806, 0x7F918860,
- 0x7F9E8806, 0x7F9F8837, 0x7FA18861, 0x7FAE8819, 0x7FB0880A, 0x7FB15009, 0x7FB25006, 0x7FB35071,
- 0x7FB85081, 0x7FB95071, 0x7FCF5081, 0x7FD05071, 0x7FE00078, 0x7FE15071, 0x7FE40078, 0x7FE55071,
- 0x7FE80078, 0x7FE95071, 0x7FEC0078, 0x7FED5071, 0x7FEF0078, 0x7FF08808, 0x7FF18819, 0x7FF28854,
- 0x7FF38808, 0x7FF45054, 0x7FF55019, 0x7FF75054, 0x7FF80078, 0x7FFD0141, 0x7FFE0054, 0x7FFF0078,
- 0x80000071, 0x80060078, 0x80070071, 0x801F0078, 0x80200071, 0x80270078, 0x80280071, 0x802F0078,
- 0x80400071, 0x807E0078, 0x80800097, 0x80810094, 0x80820078, 0x808400B6, 0x808500B7, 0x808600B8,
- 0x808700B9, 0x808800B0, 0x808900BA, 0x808A00BB, 0x808B00BC, 0x808C00BD, 0x808D0142, 0x808E0143,
- 0x808F0144, 0x80900145, 0x809100B1, 0x80920146, 0x80930147, 0x80940148, 0x80950149, 0x8096014A,
- 0x8097014B, 0x8098014C, 0x8099014D, 0x809A0078, 0x809C0094, 0x80A0014E, 0x80A1014F, 0x80A20150,
- 0x80A30151, 0x80A40152, 0x80A50150, 0x80A60153, 0x80A70151, 0x80A80154, 0x80A90155, 0x80AA0156,
- 0x80AB0157, 0x80AC014F, 0x80AE0158, 0x80B00154, 0x80B30150, 0x80B50155, 0x80B60153, 0x80B90151,
- 0x80BA0150, 0x80BB005F, 0x80BD0054, 0x80C500C3, 0x80C60078, 0x81800071, 0x819000AD, 0x819100B0,
- 0x81920078, 0x81980071, 0x81A50159, 0x81A60078, 0x81C00071, 0x81CF0078, 0x81D00071, 0x81E20078,
- 0x81E40071, 0x81E80094, 0x81E90158, 0x81EA015A, 0x81EB0078, 0x8200015B, 0x8214015C, 0x82280071,
- 0x824F0078, 0x825000A8, 0x825100A9, 0x825200AA, 0x825300AB, 0x825400AC, 0x82550078, 0x8400009B,
- 0x84030078, 0x8404009B, 0x841B0078, 0x841C009B, 0x841D0078, 0x841E009B, 0x841F0078, 0x8500009B,
- 0x85010083, 0x85020078, 0x85030083, 0x85040078, 0x85060083, 0x8508009B, 0x850A0078, 0x850B009B,
- 0x850C0078, 0x850D009B, 0x851A0078, 0x851C0083, 0x851E0078, 0x8520015D, 0x8521015E, 0x8522015F,
- 0x85230160, 0x85240078, 0x8528009A, 0x852D0078, 0xE8000094, 0xE87B0078, 0xE8800094, 0xE8940078,
- 0xE8950094, 0xE8AF0894, 0xE8B300A7, 0xE8B40083, 0xE8B50094, 0xE8B700A7, 0xE8BA0057, 0xE8BE0083,
- 0xE8C20094, 0xE8C30083, 0xE8C60094, 0xE8D50083, 0xE8D70094, 0xE8DE0894, 0xE8E10094, 0xE8EF0078,
- 0xE9000054, 0xE9210083, 0xE9230078, 0xE9800054, 0xE9AC0078, 0xEA002877, 0xEA0D2855, 0xEA1A2877,
- 0xEA272855, 0xEA342877, 0xEA412855, 0xEA4E2877, 0xEA500078, 0xEA512877, 0xEA520078, 0xEA532877,
- 0xEA540078, 0xEA552877, 0xEA5B2855, 0xEA5D0078, 0xEA5F2855, 0xEA620078, 0xEA632855, 0xEA682877,
- 0xEA752855, 0xEA822877, 0xEA830078, 0xEA842877, 0xEA860078, 0xEA872877, 0xEA8F2855, 0xEA9C2877,
- 0xEA9D0078, 0xEA9E2877, 0xEAA40078, 0xEAA52877, 0xEAA92855, 0xEAB62877, 0xEAC32855, 0xEAD02877,
- 0xEADD2855, 0xEAEA2877, 0xEAF72855, 0xEB042877, 0xEB112855, 0xEB1E2877, 0xEB2B2855, 0xEB382877,
- 0xEB452855, 0xEB530078, 0xEB542877, 0xEB612855, 0xEB712877, 0xEB7E2855, 0xEB8E2877, 0xEB9B2855,
- 0xEBAB2877, 0xEBB82855, 0xEBC82877, 0xEBD52855, 0xEBE50078, 0xEBE7280E, 0xEBE82810, 0xEBE92812,
- 0xEBEA2814, 0xEBEB2816, 0xEBEC280E, 0xEBED2810, 0xEBEE2812, 0xEBEF2814, 0xEBF02816, 0xEBF1280E,
- 0xEBF22810, 0xEBF32812, 0xEBF42814, 0xEBF52816, 0xEBF6280E, 0xEBF72810, 0xEBF82812, 0xEBF92814,
- 0xEBFA2816, 0xEBFB280E, 0xEBFC2810, 0xEBFD2812, 0xEBFE2814, 0xEBFF2816, 0xEC000078
- };
-
- static const uint32_t a1[] = {
- 0x00000071, 0x536C0078, 0x7C000871, 0x7D0F0078
- };
-
- static const uint32_t a7[] = {
- 0x00100057, 0x00400078, 0x00800083, 0x00F80078, 0x8000013F, 0xFFFF0078
- };
-
- static const uint32_t a8[] = {
- 0x0000013F, 0x7FFF0078
- };
-
- static const uint32_t a16[] = {
- 0x00800865, 0x00880065, 0x00890865, 0x00930065, 0x00940865, 0x00980161, 0x00991065, 0x009A0865,
- 0x009C0863, 0x009F1063, 0x00A00063, 0x00A10863, 0x00A41055, 0x00A50065, 0x00A60865, 0x00A90065,
- 0x00AA0865, 0x00B30065, 0x00B40865, 0x00BC0863, 0x00BF1162, 0x00C00163, 0x00C10065, 0x00C30063,
- 0x00C40068, 0x00C50063, 0x00C60055, 0x00C70164, 0x00C80063, 0x00C90068, 0x00CA0165, 0x00CB0166,
- 0x00CC0065, 0x00CD0055, 0x00CE0167, 0x00CF0168, 0x00D00865, 0x00D10065, 0x00D30063, 0x00D4006F,
- 0x00D50055, 0x00D60065, 0x00D70863, 0x00D80070, 0x00D90063, 0x00DB0169, 0x00DC0065, 0x00DD0071,
- 0x00DE0065, 0x00DF016A, 0x00E00071, 0x00E21074, 0x00E31072, 0x00E41073, 0x00E51074, 0x00E60863,
- 0x00EE016B, 0x00EF0865, 0x00F20065, 0x00F30865, 0x00F81072, 0x00F91073, 0x00FA0865, 0x00FB016C,
- 0x00FC0865, 0x010E0065, 0x010F0865, 0x01100055, 0x01110065, 0x01130865, 0x011A0055, 0x011D0063,
- 0x011E016D, 0x011F0055, 0x0120016E, 0x01210078, 0x01280055, 0x0129016F, 0x012A0055, 0x012B007A,
- 0x012C0170, 0x012D0171, 0x012E0055, 0x01310172, 0x01320055, 0x01340173, 0x01350055, 0x01370173,
- 0x01380055, 0x013A0174, 0x013B0055, 0x0141007D, 0x01420055, 0x0145007E, 0x01460055, 0x01587881,
- 0x015C0082, 0x015D0081, 0x01610037, 0x01630082, 0x01680081, 0x01690037, 0x016C1037, 0x016F0037,
- 0x01707881, 0x01720037, 0x01800083, 0x01A00883, 0x01A20175, 0x01A30083, 0x01B80078, 0x01BA0037,
- 0x01BB0078, 0x01C20837, 0x01C30806, 0x01C40885, 0x01C50078, 0x01C70887, 0x01C80060, 0x01D50860,
- 0x01D60889, 0x01D80061, 0x01E50861, 0x01E6088C, 0x01E70078, 0x01E81176, 0x01E90877, 0x01EA1177,
- 0x01EB0055, 0x01EC0065, 0x01F81093, 0x01F90055, 0x01FA1178, 0x01FB0063, 0x01FC10D8, 0x01FD0065,
- 0x01FE0077, 0x02000892, 0x02020092, 0x02030892, 0x02040092, 0x02060892, 0x02070092, 0x02080060,
- 0x020C0860, 0x020D0060, 0x02180061, 0x021C0861, 0x021D0061, 0x02280893, 0x022A0093, 0x022B0893,
- 0x022C0093, 0x022E0893, 0x022F0093, 0x02300065, 0x023B0865, 0x023C0065, 0x02410083, 0x02430078,
- 0x02440095, 0x02450065, 0x02600863, 0x02610063, 0x02670078, 0x02680865, 0x026A0065, 0x026B0865,
- 0x026C0065, 0x026D0865, 0x02700065, 0x02710865, 0x02740065, 0x02750865, 0x027B0065, 0x027C0865,
- 0x027D0078, 0x02800065, 0x02880078, 0x02980096, 0x02AB0078, 0x02AC0081, 0x02AD0097, 0x02B00098,
- 0x02C31055, 0x02C40097, 0x02C50078, 0x02C80083, 0x02E1009A, 0x02E20083, 0x02E40078, 0x02E8009B,
- 0x02F50078, 0x02F8009B, 0x02F9009A, 0x02FA0078, 0x0300009C, 0x03020078, 0x03050140, 0x0306009D,
- 0x03070054, 0x03080083, 0x030B0078, 0x030D009D, 0x030E0078, 0x030F009D, 0x0310009E, 0x0311089E,
- 0x0313009E, 0x031D0078, 0x0320009E, 0x03250083, 0x032F0078, 0x03300179, 0x0331017A, 0x0332017B,
- 0x0333017C, 0x0334017D, 0x033500A5, 0x0336009D, 0x0337009E, 0x033A109E, 0x033C009E, 0x0369089E,
- 0x036A009E, 0x036B0083, 0x036E009C, 0x036F0083, 0x0372009F, 0x03730083, 0x03740054, 0x03750083,
- 0x0377009E, 0x0378000F, 0x03790011, 0x037A0013, 0x037B0015, 0x037C0017, 0x037D009E, 0x037E00A6,
- 0x037F009E, 0x0380009D, 0x03870057, 0x03880083, 0x0389009E, 0x03980083, 0x03A50078, 0x03A6009E,
- 0x03B70078, 0x03C0009E, 0x03D30083, 0x03D8009E, 0x03D90078, 0x04800083, 0x048100A7, 0x04820071,
- 0x04940871, 0x04950071, 0x04980871, 0x04990071, 0x049D0078, 0x049E0071, 0x049F00A7, 0x04A00083,
- 0x04A400A7, 0x04A60083, 0x04A70078, 0x04A80083, 0x04AA0078, 0x04AC0871, 0x04B00071, 0x04B10083,
- 0x04B20097, 0x04B3017E, 0x04B4017F, 0x04B50180, 0x04B60181, 0x04B70182, 0x04B80078, 0x04BE0071,
- 0x04BF0078, 0x04C00083, 0x04C100A7, 0x04C20071, 0x04C60078, 0x04C70071, 0x04C80078, 0x04C90071,
- 0x04D40078, 0x04D50071, 0x04D80078, 0x04DB0071, 0x04DD0078, 0x04DE0071, 0x04DF00A7, 0x04E00083,
- 0x04E20078, 0x04E300A7, 0x04E40078, 0x04E508A7, 0x04E60083, 0x04E70078, 0x04EB00A7, 0x04EC0078,
- 0x04EE0871, 0x04F00071, 0x04F10083, 0x04F20078, 0x04F3017E, 0x04F4017F, 0x04F50180, 0x04F60181,
- 0x04F70182, 0x04F80071, 0x04F90008, 0x04FA00B6, 0x04FB00B7, 0x04FC0183, 0x04FD0078, 0x05000083,
- 0x050100A7, 0x05020071, 0x05050078, 0x05070071, 0x05080078, 0x05090071, 0x05140078, 0x05150071,
- 0x05180078, 0x05190871, 0x051A0071, 0x051B0078, 0x051C0071, 0x051D0078, 0x051F00A7, 0x05200083,
- 0x05210078, 0x05230083, 0x05240078, 0x05250083, 0x05270078, 0x052C0871, 0x052E0078, 0x0533017E,
- 0x0534017F, 0x05350180, 0x05360181, 0x05370182, 0x05380083, 0x05390071, 0x053A0078, 0x05400083,
- 0x054100A7, 0x05420071, 0x05540078, 0x05550071, 0x05580078, 0x05590071, 0x055D0078, 0x055E0071,
- 0x055F00A7, 0x05600083, 0x056400A7, 0x05660083, 0x05670078, 0x05700071, 0x05710083, 0x05720078,
- 0x0573017E, 0x0574017F, 0x05750180, 0x05760181, 0x05770182, 0x05780008, 0x05790078, 0x05800083,
- 0x058100A7, 0x05820071, 0x05860078, 0x05870071, 0x05880078, 0x05890071, 0x05940078, 0x05950071,
- 0x05980078, 0x05990071, 0x059D0078, 0x059E0071, 0x059F0083, 0x05A20078, 0x05A300A7, 0x05A40078,
- 0x05A508A7, 0x05A60083, 0x05A70078, 0x05AB00A7, 0x05AC0078, 0x05AE0871, 0x05AF0071, 0x05B10078,
- 0x05B3017E, 0x05B4017F, 0x05B50180, 0x05B60181, 0x05B70182, 0x05B80071, 0x05B90078, 0x05C10071,
- 0x05C50078, 0x05C70071, 0x05C80078, 0x05C90071, 0x05CB0078, 0x05CC0071, 0x05CD0078, 0x05CF0071,
- 0x05D00078, 0x05D10071, 0x05D20078, 0x05D40071, 0x05D50078, 0x05D70071, 0x05DD0078, 0x05DF00A7,
- 0x05E10078, 0x05E300A7, 0x05E40078, 0x05E508A7, 0x05E60083, 0x05E70078, 0x05EB00A7, 0x05EC0078,
- 0x05F3017E, 0x05F4017F, 0x05F50180, 0x05F60181, 0x05F70182, 0x05F80184, 0x05F90054, 0x05FC0008,
- 0x05FD0078, 0x060000A7, 0x06020071, 0x06060078, 0x06070071, 0x06080078, 0x06090071, 0x06140078,
- 0x06150071, 0x061D0078, 0x061F0083, 0x062000A7, 0x06220078, 0x06230083, 0x06240078, 0x06250083,
- 0x06270078, 0x062A0083, 0x062B0078, 0x06300071, 0x06310078, 0x0633017E, 0x0634017F, 0x06350180,
- 0x06360181, 0x06370182, 0x06380078, 0x064100A7, 0x06420071, 0x06460078, 0x06470071, 0x06480078,
- 0x06490071, 0x06540078, 0x06550071, 0x065D0078, 0x065E0071, 0x065F00B2, 0x066000A7, 0x06620078,
- 0x066308A7, 0x06640078, 0x066508A7, 0x06660083, 0x06670078, 0x066A00A7, 0x066B0078, 0x06700071,
- 0x06710078, 0x0673017E, 0x0674017F, 0x06750180, 0x06760181, 0x06770182, 0x06780078, 0x068100A7,
- 0x06820071, 0x06860078, 0x06870071, 0x06880078, 0x06890071, 0x06940078, 0x06950071, 0x069D0078,
- 0x069F00A7, 0x06A00083, 0x06A20078, 0x06A300A7, 0x06A40078, 0x06A508A7, 0x06A60083, 0x06A70078,
- 0x06AB00A7, 0x06AC0078, 0x06B00071, 0x06B10078, 0x06B3017E, 0x06B4017F, 0x06B50180, 0x06B60181,
- 0x06B70182, 0x06B80078, 0x06C100A7, 0x06C20071, 0x06CB0078, 0x06CD0071, 0x06DF0078, 0x06E00071,
- 0x06E30078, 0x06E700A7, 0x06E90083, 0x06EA0078, 0x06EC00A7, 0x06EE08A7, 0x06EF00A7, 0x06F00078,
- 0x06F900A7, 0x06FA0078, 0x07000071, 0x07180083, 0x07191071, 0x071A0083, 0x071D0078, 0x071F0008,
- 0x07200071, 0x07230083, 0x07270097, 0x0728017E, 0x0729017F, 0x072A0180, 0x072B0181, 0x072C0182,
- 0x072D0097, 0x072E0078, 0x07400071, 0x07410078, 0x07430071, 0x07440078, 0x07460071, 0x07470078,
- 0x074A0071, 0x07540078, 0x07550071, 0x07580083, 0x07591071, 0x075A0083, 0x075E0071, 0x075F0078,
- 0x07600071, 0x07620078, 0x07640083, 0x07670078, 0x0768017E, 0x0769017F, 0x076A0180, 0x076B0181,
- 0x076C0182, 0x076D0078, 0x076E1071, 0x076F0078, 0x07800094, 0x07820097, 0x07890094, 0x078C0083,
- 0x078D0094, 0x0790017E, 0x0791017F, 0x07920180, 0x07930181, 0x07940182, 0x079500B3, 0x079A0083,
- 0x079D00BF, 0x079F00A7, 0x07A00071, 0x07A10871, 0x07A20071, 0x07A60871, 0x07A70071, 0x07AB0871,
- 0x07AC0071, 0x07B40871, 0x07B50078, 0x07B80083, 0x07B90883, 0x07BB1083, 0x07BD0083, 0x07BF00A7,
- 0x07C00883, 0x07C10083, 0x07C20097, 0x07C30083, 0x07C40071, 0x07C60078, 0x07C80083, 0x07C90883,
- 0x07CA0083, 0x07CE0883, 0x07CF0083, 0x07D30883, 0x07D40083, 0x07DC0883, 0x07DD0083, 0x07DE0078,
- 0x07DF0094, 0x07E60078, 0x07E70094, 0x07E80097, 0x07E90078, 0x08000071, 0x08150078, 0x08160083,
- 0x081800A7, 0x08190078, 0x081B0083, 0x081D0078, 0x0820017E, 0x0821017F, 0x08220180, 0x08230181,
- 0x08240182, 0x08250097, 0x08280071, 0x082B00A7, 0x082C0083, 0x082D0078, 0x085000B5, 0x08630078,
- 0x08680071, 0x087D0097, 0x087E0078, 0x08800071, 0x08AD0078, 0x08AF0071, 0x08D10078, 0x08D40071,
- 0x08FD0078, 0x09000071, 0x09240078, 0x09250071, 0x09270078, 0x09280071, 0x092B0078, 0x092D0071,
- 0x092F0078, 0x09300071, 0x09440078, 0x09450071, 0x09470078, 0x09480071, 0x09580078, 0x09590071,
- 0x095B0078, 0x095C0071, 0x095F0078, 0x09610071, 0x09630078, 0x09640071, 0x096B0078, 0x096C0071,
- 0x09880078, 0x09890071, 0x098B0078, 0x098C0071, 0x09AD0078, 0x09AF0083, 0x09B00097, 0x09B400AD,
- 0x09B500AE, 0x09B6012D, 0x09B7012E, 0x09B8012F, 0x09B90185, 0x09BA0186, 0x09BB0187, 0x09BC0188,
- 0x09BD0184, 0x09BE0078, 0x09C00071, 0x09C80054, 0x09CD0078, 0x09D00071, 0x09FA0078, 0x0A000071,
- 0x0B360097, 0x0B370071, 0x0B3B0078, 0x0B400071, 0x0B4D00B4, 0x0B4E0078, 0x0B500071, 0x0B750097,
- 0x0B770189, 0x0B780078, 0x0B800071, 0x0B860078, 0x0B870071, 0x0B890083, 0x0B8A0078, 0x0B900071,
- 0x0B990083, 0x0B9A0097, 0x0B9B0078, 0x0BA00071, 0x0BA90083, 0x0BAA0078, 0x0BB00071, 0x0BB60078,
- 0x0BB70071, 0x0BB80078, 0x0BB90083, 0x0BBA0078, 0x0BC00071, 0x0BDA00C2, 0x0BDB0083, 0x0BDF00A7,
- 0x0BE40083, 0x0BEA0097, 0x0BEB0081, 0x0BEC0097, 0x0BED0008, 0x0BEE0083, 0x0BEF0078, 0x0BF0017E,
- 0x0BF1017F, 0x0BF20180, 0x0BF30181, 0x0BF40182, 0x0BF50078, 0x0BF80106, 0x0BF90107, 0x0BFA0108,
- 0x0BFB0109, 0x0BFC010A, 0x0BFD0078, 0x0C000006, 0x0C050083, 0x0C070078, 0x0C08017E, 0x0C09017F,
- 0x0C0A0180, 0x0C0B0181, 0x0C0C0182, 0x0C0D0078, 0x0C100071, 0x0C210081, 0x0C220071, 0x0C3C0078,
- 0x0C400071, 0x0C540083, 0x0C550078, 0x0C800071, 0x0C8E0078, 0x0C900083, 0x0C9100A7, 0x0C930083,
- 0x0C9400C8, 0x0C960078, 0x0C9800A7, 0x0C9C0083, 0x0C9E0078, 0x0CA20006, 0x0CA3017E, 0x0CA4017F,
- 0x0CA50180, 0x0CA60181, 0x0CA70182, 0x0CA80071, 0x0CB70078, 0x0CB80071, 0x0CBA0078, 0x0CC00071,
- 0x0CD50078, 0x0CD800A7, 0x0CE00071, 0x0CE400A7, 0x0CE50078, 0x0CE8017E, 0x0CE9017F, 0x0CEA0180,
- 0x0CEB0181, 0x0CEC0182, 0x0CED0078, 0x0CEF0006, 0x0CF00054, 0x0D000071, 0x0D0B0083, 0x0D0C00A7,
- 0x0D0E0078, 0x0D0F0097, 0x0D100078, 0x0E800055, 0x0E967881, 0x0E970081, 0x0E987881, 0x0E9D0081,
- 0x0E9E7881, 0x0EB17055, 0x0EB50055, 0x0ECD7881, 0x0EE00083, 0x0EE20078, 0x0F000865, 0x0F4B0855,
- 0x0F4D098A, 0x0F4E0078, 0x0F500865, 0x0F7D0078, 0x0F8008C9, 0x0F8408CA, 0x0F8808C9, 0x0F8B0078,
- 0x0F8C08CA, 0x0F8F0078, 0x0F9008C9, 0x0F9408CA, 0x0F9808C9, 0x0F9C08CA, 0x0FA008C9, 0x0FA30078,
- 0x0FA408CA, 0x0FA70078, 0x0FA808C9, 0x0FAC08CA, 0x0FB008C9, 0x0FB408CA, 0x0FB808CB, 0x0FB908CC,
- 0x0FBB08CD, 0x0FBC08CE, 0x0FBD08CF, 0x0FBE08D0, 0x0FBF0078, 0x0FC008C9, 0x0FC408D1, 0x0FC808C9,
- 0x0FCC08D1, 0x0FD008C9, 0x0FD408D1, 0x0FD808C9, 0x0FD9098B, 0x0FDA0078, 0x0FDB0855, 0x0FDC08CA,
- 0x0FDD08D2, 0x0FDE1037, 0x0FE00837, 0x0FE1098B, 0x0FE20078, 0x0FE30855, 0x0FE408D5, 0x0FE60837,
- 0x0FE808C9, 0x0FE90855, 0x0FEA0078, 0x0FEB0855, 0x0FEC08CA, 0x0FED08D6, 0x0FEE0837, 0x0FF008C9,
- 0x0FF10855, 0x0FF20890, 0x0FF30855, 0x0FF408CA, 0x0FF508D7, 0x0FF60837, 0x0FF80078, 0x0FF9098B,
- 0x0FFA0078, 0x0FFB0855, 0x0FFC08D9, 0x0FFD08DA, 0x0FFE0837, 0x0FFF0078, 0x10000805, 0x10011005,
- 0x10035805, 0x10041005, 0x10050057, 0x1007018C, 0x10085899, 0x10090099, 0x100B1006, 0x100C018D,
- 0x100D00DB, 0x100E018D, 0x100F00DB, 0x10100006, 0x10121006, 0x10130006, 0x1014018E, 0x1015018F,
- 0x10160190, 0x10175853, 0x10180007, 0x10191007, 0x101A0006, 0x101B1006, 0x101C0126, 0x101D0006,
- 0x101F0038, 0x10200006, 0x10220009, 0x10231006, 0x10250006, 0x102B1006, 0x102C0006, 0x102F1005,
- 0x10300057, 0x10320078, 0x10350057, 0x10387855, 0x10390078, 0x103A7910, 0x103B7911, 0x103C7912,
- 0x103D780B, 0x103E7809, 0x103F7855, 0x1040705D, 0x1041705B, 0x10427110, 0x10437111, 0x10447112,
- 0x1045700B, 0x10467009, 0x10470078, 0x10487081, 0x104A0078, 0x10500008, 0x105B0078, 0x10680083,
- 0x106E0095, 0x10700083, 0x10710095, 0x10720083, 0x10760078, 0x10801054, 0x10831077, 0x10841054,
- 0x10852877, 0x10872855, 0x10882877, 0x10892855, 0x108A2877, 0x108B0054, 0x108C2877, 0x108F0054,
- 0x10901054, 0x10910054, 0x10950991, 0x10962877, 0x10972855, 0x10982877, 0x109A1071, 0x109C2855,
- 0x109D1054, 0x109E2855, 0x109F2877, 0x10A00019, 0x10A22877, 0x10A32855, 0x10A50019, 0x10A60078,
- 0x10A9305F, 0x10AF3106, 0x10B01192, 0x10B11193, 0x10B21194, 0x10B31195, 0x10B41196, 0x10B51197,
- 0x10B61198, 0x10B71199, 0x10B8119A, 0x10B9119B, 0x10BA119C, 0x10BB119D, 0x10BC119E, 0x10BD119F,
- 0x10BE11A0, 0x10BF11A1, 0x10C001A2, 0x10C101A3, 0x10C20078, 0x10C80019, 0x10CA0054, 0x10CD0819,
- 0x10CE0054, 0x10D10019, 0x10D20054, 0x10E60854, 0x10E70819, 0x10E80054, 0x10FA0019, 0x110000E8,
- 0x11020019, 0x110408FB, 0x110500FC, 0x11070019, 0x110800E8, 0x11090059, 0x110A01A4, 0x110B0019,
- 0x110D00E8, 0x11110019, 0x111500E8, 0x111610E8, 0x111800E8, 0x111A0019, 0x111C00E8, 0x111E00FE,
- 0x111F00E8, 0x112008E8, 0x112101A5, 0x112200E8, 0x112308E8, 0x112500E8, 0x11260019, 0x112900FE,
- 0x112B0019, 0x112F00E8, 0x11300019, 0x113200FE, 0x11360819, 0x113708FE, 0x113900FE, 0x113A08FE,
- 0x113B00FE, 0x113C08FE, 0x113D00FE, 0x114008FE, 0x114100FE, 0x114208FE, 0x114300FE, 0x114408FE,
- 0x114500FE, 0x11460019, 0x114700FD, 0x11490019, 0x115100FE, 0x11520019, 0x115300E8, 0x115401A6,
- 0x115608E8, 0x115800FE, 0x115C0019, 0x115F00E8, 0x11600019, 0x116400FD, 0x116601A7, 0x11670019,
- 0x116800FE, 0x11690019, 0x116B00FE, 0x117008FE, 0x117200FE, 0x117508FE, 0x11770019, 0x117800FE,
- 0x11790102, 0x117A00E8, 0x117B0103, 0x117C00E8, 0x117D0104, 0x117E0105, 0x117F00E8, 0x11800054,
- 0x118400FE, 0x11860054, 0x119000E8, 0x11910054, 0x11940809, 0x11950054, 0x119B0094, 0x11BD0054,
- 0x11CA0094, 0x11CB0054, 0x11CD0019, 0x11DA00BF, 0x11DB0054, 0x11EE0078, 0x12000054, 0x12130078,
- 0x12200054, 0x12250078, 0x123018C4, 0x123118C5, 0x123218C6, 0x123318C7, 0x1234191F, 0x1235191A,
- 0x1236191B, 0x1237191C, 0x1238191D, 0x1239191E, 0x123A10C4, 0x123B10C5, 0x123C10C6, 0x123D10C7,
- 0x123E111F, 0x123F111A, 0x1240111B, 0x1241111C, 0x1242111D, 0x1243111E, 0x1244105A, 0x124510E3,
- 0x124610E4, 0x124710E5, 0x124811A8, 0x124911A9, 0x124A11AA, 0x124B11AB, 0x124C11AC, 0x124D11AD,
- 0x124E1094, 0x125B1918, 0x12681919, 0x1275010B, 0x1276010C, 0x1277010D, 0x1278010E, 0x1279010F,
- 0x127A0106, 0x127B0107, 0x127C0108, 0x127D0109, 0x127E010A, 0x127F00C3, 0x12800054, 0x12DB0019,
- 0x12DC0054, 0x12E00019, 0x12E10054, 0x12FC0019, 0x13000054, 0x13370019, 0x13380054, 0x134E0078,
- 0x13500054, 0x13590078, 0x13800054, 0x13820078, 0x13830054, 0x13850078, 0x13860054, 0x13A90078,
- 0x13AC0054, 0x13AF0078, 0x13B00054, 0x13B4000A, 0x13BB00C4, 0x13BC00C5, 0x13BD00C6, 0x13BE00C7,
- 0x13BF011F, 0x13C000C4, 0x13C100C5, 0x13C200C6, 0x13C300C7, 0x13C4011F, 0x13C500C4, 0x13C600C5,
- 0x13C700C6, 0x13C800C7, 0x13C9011F, 0x13CA0078, 0x13CC0054, 0x13DF0078, 0x13E00019, 0x13E100FD,
- 0x13E20009, 0x13E30078, 0x13E80019, 0x13E900E8, 0x13EA00FD, 0x13EB0019, 0x13EE00FD, 0x13EF0019,
- 0x13F100FE, 0x13F3000A, 0x13F60078, 0x13F80019, 0x14000094, 0x14800019, 0x14C10009, 0x14C601AE,
- 0x14C701AF, 0x14C80009, 0x14CC0019, 0x14CD00E8, 0x14D80019, 0x14E000FE, 0x14E100E8, 0x14E200FE,
- 0x14E30019, 0x14E400E8, 0x14E50019, 0x14E700FD, 0x14E90019, 0x14EA00FE, 0x14EB0019, 0x14EC000A,
- 0x14EE0019, 0x14F000E8, 0x14F30019, 0x14F400E8, 0x14F50019, 0x14FA01B0, 0x14FB00E8, 0x14FC00FE,
- 0x14FD0019, 0x14FE000A, 0x14FF0019, 0x150500E8, 0x150E0019, 0x150F00E8, 0x15110019, 0x151400E8,
- 0x151500FD, 0x15170019, 0x151A00FE, 0x151B0019, 0x151E00FE, 0x151F0019, 0x152B00E8, 0x152C0019,
- 0x153200FE, 0x15330019, 0x153500E8, 0x15380019, 0x153900E8, 0x153A1019, 0x153B0019, 0x153C00FD,
- 0x153D00E8, 0x153E00FD, 0x154200E8, 0x154500FD, 0x154600E8, 0x154800FD, 0x154E00E8, 0x155000FD,
- 0x155100E8, 0x15520019, 0x155300FE, 0x155700FD, 0x155800E8, 0x155900FD, 0x155A00E8, 0x155D00FD,
- 0x156300E8, 0x156600FD, 0x156B0019, 0x157101B1, 0x15730019, 0x157600FE, 0x15770019, 0x157900E8,
- 0x157A0019, 0x157B00FD, 0x157D00E8, 0x157F0019, 0x15800054, 0x158A0078, 0x16000096, 0x16170078,
- 0x16180098, 0x162F0078, 0x16400065, 0x16720054, 0x16750078, 0x167C0006, 0x167E005F, 0x167F0006,
- 0x16800125, 0x16930078, 0x16980071, 0x16B30078, 0x16B77881, 0x16B80078, 0x16C00071, 0x16CB0078,
- 0x16D00071, 0x16D30078, 0x16D40071, 0x16D70078, 0x16D80071, 0x16DB0078, 0x16DC0071, 0x16DF0078,
- 0x16E00071, 0x16E30078, 0x16E40071, 0x16E70078, 0x16E80071, 0x16EB0078, 0x16EC0071, 0x16EF0078,
- 0x17000006, 0x170100E0, 0x17030006, 0x17040126, 0x17050006, 0x170600E0, 0x17070006, 0x170B0099,
- 0x170C0078, 0x170E00E0, 0x170F0078, 0x17400054, 0x174F1054, 0x17500054, 0x17791054, 0x177A0078,
- 0x17801054, 0x17EB0078, 0x17F80054, 0x17FE0078, 0x18000006, 0x18020081, 0x180301B2, 0x1804000A,
- 0x18090054, 0x180A000A, 0x180E00B4, 0x180F00BF, 0x181001B3, 0x181101B4, 0x181201B5, 0x181301B6,
- 0x181401B7, 0x18150083, 0x18180081, 0x181B0054, 0x181C11B8, 0x181D0081, 0x181E0006, 0x181F0054,
- 0x18200071, 0x18320871, 0x18350071, 0x18380871, 0x183A0071, 0x183B0871, 0x183D0071, 0x183E0871,
- 0x183F0071, 0x184B0078, 0x184C0083, 0x184D1037, 0x184E0081, 0x184F8071, 0x18500071, 0x18620871,
- 0x18650071, 0x18680871, 0x186A0071, 0x186B0871, 0x186D0071, 0x186E0871, 0x186F0071, 0x187B0871,
- 0x187D0006, 0x187E0081, 0x187F8071, 0x18800078, 0x18820071, 0x18960078, 0x18981071, 0x18C70078,
- 0x18C80094, 0x18C978B6, 0x18CA78B7, 0x18CB7894, 0x18D00071, 0x18DC0078, 0x18E00054, 0x18E80078,
- 0x18F80071, 0x19001094, 0x190E1054, 0x190F0078, 0x191010B6, 0x191110B7, 0x191210B8, 0x191310B9,
- 0x191410B0, 0x19151094, 0x19220078, 0x192819B9, 0x192919BA, 0x192A19BB, 0x192B19BC, 0x192C19BD,
- 0x192D19BE, 0x192E19BF, 0x192F19C0, 0x19301894, 0x193E1854, 0x193F0094, 0x194018B6, 0x194118B7,
- 0x194218B8, 0x194318B9, 0x194418B0, 0x19451894, 0x195819C1, 0x195919C2, 0x195A19C3, 0x195B19C4,
- 0x195C19C5, 0x195D19C6, 0x195E19C7, 0x195F19C8, 0x19601094, 0x19666854, 0x19681894, 0x197F0078,
- 0x19806894, 0x19AC1094, 0x19B86894, 0x19BB6854, 0x19BD6894, 0x19EF6854, 0x19F01094, 0x19FF6854,
- 0x1A000071, 0x26DB0078, 0x26E00054, 0x27000071, 0x4FDE0078, 0x50000071, 0x500A0081, 0x500B0071,
- 0x52460078, 0x52480054, 0x52630078, 0x53800037, 0x538B0078, 0x54000071, 0x54050083, 0x54060071,
- 0x541100A7, 0x54120083, 0x541300A7, 0x54140054, 0x54160078, 0x56000071, 0x6BD20078, 0x6C00013E,
- 0x7000013F, 0x7C800871, 0x7D070071, 0x7D0A0871, 0x7D0F0071, 0x7D120871, 0x7D130071, 0x7D150871,
- 0x7D170078, 0x7D180871, 0x7D350078, 0x7D380871, 0x7D6D0078, 0x7D801055, 0x7D830078, 0x7D891055,
- 0x7D8C0078, 0x7D8E089B, 0x7D90289B, 0x7D94280B, 0x7D95089B, 0x7D9B0078, 0x7D9C089B, 0x7D9E0078,
- 0x7DA0089B, 0x7DA20078, 0x7DA3089B, 0x7DA7109B, 0x7DA8209E, 0x7DAA489E, 0x7DAB209E, 0x7DAC489E,
- 0x7DAD209E, 0x7DAE489E, 0x7DAF209E, 0x7DB0489E, 0x7DB1209E, 0x7DB2489E, 0x7DB3209E, 0x7DB4489E,
- 0x7DB5209E, 0x7DB6489E, 0x7DB7209E, 0x7DB8489E, 0x7DB9209E, 0x7DBA489E, 0x7DBB209E, 0x7DBC489E,
- 0x7DBD209E, 0x7DBE489E, 0x7DBF209E, 0x7DC0489E, 0x7DC1209E, 0x7DC8489E, 0x7DC9209E, 0x7DCA489E,
- 0x7DCB209E, 0x7DCC489E, 0x7DCD209E, 0x7DCE489E, 0x7DCF209E, 0x7DD1489E, 0x7DD2209E, 0x7DD4489E,
- 0x7DD5209E, 0x7DD6489E, 0x7DD7209E, 0x7DD90078, 0x7DE9409E, 0x7DEA389E, 0x7DEB409E, 0x7DEF209E,
- 0x7DF3489E, 0x7DF5209E, 0x7DFC409E, 0x7DFD389E, 0x7DFE209E, 0x7DFF489E, 0x7E00409E, 0x7E32209E,
- 0x7E4B389E, 0x7E6F489E, 0x7E7A409E, 0x7E88209E, 0x7E96389E, 0x7E9A489E, 0x7E9E409E, 0x7E9F00BF,
- 0x7EA00078, 0x7EA8209E, 0x7EA9389E, 0x7EAD209E, 0x7EAE389E, 0x7EAF209E, 0x7EB0389E, 0x7EB3209E,
- 0x7EB5389E, 0x7EB7209E, 0x7EB9389E, 0x7EBA209E, 0x7EBB389E, 0x7EBC209E, 0x7EBE389E, 0x7EBF209E,
- 0x7EC1389E, 0x7EC2209E, 0x7EC4389E, 0x7EC5209E, 0x7EC6389E, 0x7EC80078, 0x7EC9389E, 0x7ECB209E,
- 0x7ECE389E, 0x7ECF209E, 0x7EDA389E, 0x7EDB209E, 0x7EE1389E, 0x7EE3209E, 0x7EE40078, 0x7EF8409E,
- 0x7EFE0054, 0x7EFF0078, 0x7F000083, 0x7F088006, 0x7F0B80B4, 0x7F0C8006, 0x7F0D0078, 0x7F100083,
- 0x7F120078, 0x7F188099, 0x7F198038, 0x7F1A80B4, 0x7F220006, 0x7F2380B4, 0x7F241006, 0x7F261038,
- 0x7F286006, 0x7F290078, 0x7F2A600C, 0x7F2B6006, 0x7F2C60B4, 0x7F2F6007, 0x7F306006, 0x7F31600D,
- 0x7F326019, 0x7F330078, 0x7F346008, 0x7F356006, 0x7F360078, 0x7F38489E, 0x7F39009E, 0x7F3A0078,
- 0x7F3B489E, 0x7F40409E, 0x7F45389E, 0x7F46409E, 0x7F48389E, 0x7F49409E, 0x7F4B389E, 0x7F4C409E,
- 0x7F4D389E, 0x7F4E409E, 0x7F4F389E, 0x7F50409E, 0x7F51389E, 0x7F52409E, 0x7F53389E, 0x7F54409E,
- 0x7F59389E, 0x7F5A409E, 0x7F5B389E, 0x7F5C409E, 0x7F5D389E, 0x7F5E409E, 0x7F5F389E, 0x7F60409E,
- 0x7F61389E, 0x7F62409E, 0x7F63389E, 0x7F64409E, 0x7F65389E, 0x7F66409E, 0x7F67389E, 0x7F68409E,
- 0x7F69389E, 0x7F6A409E, 0x7F6B389E, 0x7F6C409E, 0x7F6D389E, 0x7F6E409E, 0x7F6F389E, 0x7F70409E,
- 0x7F71389E, 0x7F72409E, 0x7F73389E, 0x7F74409E, 0x7F75389E, 0x7F76409E, 0x7F79389E, 0x7F7A409E,
- 0x7F7E0078, 0x7F7F0057, 0x7F808806, 0x7F818807, 0x7F838806, 0x7F84880A, 0x7F85880B, 0x7F86880D,
- 0x7F87880C, 0x7F88880F, 0x7F898811, 0x7F8A8813, 0x7F8B8815, 0x7F8C8817, 0x7F8D8806, 0x7F8E8819,
- 0x7F8F8806, 0x7F908860, 0x7F9D8835, 0x7F9E8836, 0x7F9F8838, 0x7FA08861, 0x7FAD8835, 0x7FAE8836,
- 0x7FAF8809, 0x7FB05006, 0x7FB1500A, 0x7FB25006, 0x7FB35071, 0x7FCF5081, 0x7FD05071, 0x7FDF0078,
- 0x7FE15071, 0x7FE40078, 0x7FE55071, 0x7FE80078, 0x7FE95071, 0x7FEC0078, 0x7FED5071, 0x7FEE0078,
- 0x7FF08808, 0x7FF18837, 0x7FF28808, 0x7FF30078, 0x7FF45019, 0x7FF65054, 0x7FF70078, 0x7FFC0141,
- 0x7FFE0054, 0x7FFF0078, 0x80000071, 0x80130078, 0x80140071, 0x801D0078, 0x801E0071, 0x80270078,
- 0x80280071, 0x802F0078, 0x80400071, 0x807D0078, 0x80800006, 0x80810078, 0x808300AD, 0x808400AE,
- 0x8085012D, 0x8086012E, 0x8087012F, 0x80880185, 0x80890186, 0x808A0187, 0x808B0188, 0x808C0184,
- 0x808D01C9, 0x808E01CA, 0x808F01CB, 0x809001CC, 0x809101CD, 0x809201CE, 0x809301CF, 0x809401D0,
- 0x809500BE, 0x809601D1, 0x809701D2, 0x809801D3, 0x809901D4, 0x809A0078, 0x809B0094, 0x80A0014E,
- 0x80A10152, 0x80A20153, 0x80A30157, 0x80A40154, 0x80A50155, 0x80A60156, 0x80A70152, 0x80A80150,
- 0x80A90153, 0x80AA01D5, 0x80AB0154, 0x80AC014F, 0x80AD0158, 0x80AF0152, 0x80B00154, 0x80B201D6,
- 0x80B30150, 0x80B501D7, 0x80B60153, 0x80B80156, 0x80B90152, 0x80BA005F, 0x80BC0054, 0x80C50078,
- 0x81800071, 0x818F0078, 0x8190012D, 0x819100BB, 0x81920078, 0x81980071, 0x81A50078, 0x81C00071,
- 0x81CF0097, 0x81D00071, 0x81E20078, 0x81E40071, 0x81E8014F, 0x81E90154, 0x81EA0155, 0x81EB0078,
- 0x8200015B, 0x8214015C, 0x82280071, 0x824F0078, 0x8250017E, 0x8251017F, 0x82520180, 0x82530181,
- 0x82540182, 0x82550078, 0x8400009B, 0x84030078, 0x8405009B, 0x841C0078, 0x841F009B, 0x84200078,
- 0x85000083, 0x85030078, 0x85060083, 0x8508009B, 0x851A0078, 0x851C0083, 0x851D0078, 0x851F0083,
- 0x852001D8, 0x852101D9, 0x852201DA, 0x852301DB, 0x85240078, 0x8528009A, 0x852C0078, 0xE8000094,
- 0xE87B0078, 0xE8800094, 0xE8930078, 0xE8950094, 0xE8AF0894, 0xE8B200A7, 0xE8B30083, 0xE8B50094,
- 0xE8B600A7, 0xE8B90057, 0xE8BD0083, 0xE8C10094, 0xE8C20083, 0xE8C60094, 0xE8D50083, 0xE8D70094,
- 0xE8DD0894, 0xE8E00094, 0xE8EF0078, 0xE9000054, 0xE9210083, 0xE9220054, 0xE9230078, 0xE9800054,
- 0xE9AB0078, 0xEA002877, 0xEA0D2855, 0xEA1A2877, 0xEA272855, 0xEA2A0078, 0xEA2B2855, 0xEA342877,
- 0xEA412855, 0xEA4E0078, 0xEA4F2877, 0xEA500078, 0xEA522877, 0xEA530078, 0xEA542877, 0xEA560078,
- 0xEA572877, 0xEA5B2855, 0xEA682877, 0xEA752855, 0xEA822877, 0xEA850078, 0xEA862877, 0xEA8A0078,
- 0xEA8B2877, 0xEA8E0078, 0xEA8F2855, 0xEA9C2877, 0xEA9F0078, 0xEAA02877, 0xEAA20078, 0xEAA52877,
- 0xEAA80078, 0xEAA92855, 0xEAB62877, 0xEAC32855, 0xEAD02877, 0xEADD2855, 0xEAEA2877, 0xEAF72855,
- 0xEB042877, 0xEB112855, 0xEB1E2877, 0xEB2B2855, 0xEB382877, 0xEB452855, 0xEB530078, 0xEB542877,
- 0xEB6029DC, 0xEB612855, 0xEB6D29DC, 0xEB6E2855, 0xEB712877, 0xEB7D29DC, 0xEB7E2855, 0xEB8A29DC,
- 0xEB8B2855, 0xEB8E2877, 0xEB9A29DC, 0xEB9B2855, 0xEBA729DC, 0xEBA82855, 0xEBAB2877, 0xEBB729DC,
- 0xEBB82855, 0xEBC429DC, 0xEBC52855, 0xEBC82877, 0xEBD429DC, 0xEBD52855, 0xEBE129DC, 0xEBE22855,
- 0xEBE50078, 0xEBE7280F, 0xEBE82811, 0xEBE92813, 0xEBEA2815, 0xEBEB2817, 0xEBEC280F, 0xEBED2811,
- 0xEBEE2813, 0xEBEF2815, 0xEBF02817, 0xEBF1280F, 0xEBF22811, 0xEBF32813, 0xEBF42815, 0xEBF52817,
- 0xEBF6280F, 0xEBF72811, 0xEBF82813, 0xEBF92815, 0xEBFA2817, 0xEBFB280F, 0xEBFC2811, 0xEBFD2813,
- 0xEBFE2815, 0xEBFF2817, 0xEC000078
- };
-
- static const uint32_t a17[] = {
- 0x00000071, 0x536B0078, 0x7C000871, 0x7D0F0078
- };
-
- static const uint32_t a23[] = {
- 0x00000057, 0x00010078, 0x00100057, 0x00400078, 0x00800083, 0x00F80078, 0x8000013F, 0xFFFF0078
- };
-
- static const uint32_t a24[] = {
- 0x0000013F, 0x7FFF0078
- };
-
-
- // The full set of all arrays to be searched.
- static const Range FULL_DATA[] = {
- {sizeof(a0)/sizeof(uint32_t), a0},
- {sizeof(a1)/sizeof(uint32_t), a1},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {sizeof(a7)/sizeof(uint32_t), a7},
- {sizeof(a8)/sizeof(uint32_t), a8},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {sizeof(a16)/sizeof(uint32_t), a16},
- {sizeof(a17)/sizeof(uint32_t), a17},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {sizeof(a23)/sizeof(uint32_t), a23},
- {sizeof(a24)/sizeof(uint32_t), a24},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0},
- {0, 0}
- };
-
- // Array of uppercase differences
- static const short UCDIFF[] = {
- 0, -32, 743, 121, -1, -232, -300, 97,
- 163, 130, 56, -2, -79, -210, -206, -205,
- -202, -203, -207, -209, -211, -213, -214, -218,
- -217, -219, -83, 84, -38, -37, -31, -64,
- -63, -62, -57, -47, -54, -86, -80, 7,
- -96, -48, -59, 8, 74, 86, 100, 128,
- 112, 126, 9, -7205, -16, -26, -7264, -40
- };
-
- // Array of lowercase differences
- static const short LCDIFF[] = {
- 0, 32, 1, -199, -121, 210, 206, 205,
- 79, 202, 203, 207, 211, 209, 213, 214,
- 218, 217, 219, 2, -97, -56, -130, -163,
- 83, 38, 37, 64, 63, -60, -7, 80,
- 48, 7264, -8, -74, -9, -86, -100, -112,
- -128, -126, -7517, -8383, -8262, 16, 26, 40
- };
-
- // Array of titlecase differences
- static const short TCDIFF[] = {
- 3, 1, 0, -1
- };
-
- // Array of mirrored character differences
- static const short MIRROR_DIFF[] = {
- 0, 1, -1, 2, -2, 16, -16, 3,
- -3, 2016, 138, 1824, 2104, 2108, 2106, -138,
- 8, 7, -8, -7, -1824, -2016, -2104, -2106,
- -2108
- };
-
- // Array of all possible numeric values
- static const int NUMERICS[] = {
- -1, 0, 1, 2, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 27, 28, 29, 30,
- 31, 32, 33, 34, 35, -2, 100, 1000,
- 40, 50, 60, 70, 80, 90, 10000, 500,
- 5000, 36, 37, 38, 39, 41, 42, 43,
- 44, 45, 46, 47, 48, 49, 200, 300,
- 400, 600, 700, 800, 900, 2000, 3000, 4000,
- 6000, 7000, 8000, 9000, 20000, 30000, 40000, 50000,
- 60000, 70000, 80000, 90000
- };
-
- // All possible packed data values, no duplicates
- static const uint32_t PACKED_DATA[] = {
- 0x00000000, 0x0000012F, 0x0000016F, 0x0000014F, 0x0000018F, 0x0000018C, 0x000001B8, 0x000000B8,
- 0x000000BA, 0x020005B5, 0x040005B6, 0x00000099, 0x000000F8, 0x00000094, 0x02000069, 0x04000069,
- 0x06000069, 0x08000069, 0x0A000069, 0x0C000069, 0x0E000069, 0x10000069, 0x12000069, 0x14000069,
- 0x060005B9, 0x000001B9, 0x080005B9, 0x16020001, 0x18020001, 0x1A020001, 0x1C020001, 0x1E020001,
- 0x20020001, 0x22020001, 0x24020001, 0x26020001, 0x28020001, 0x2A020001, 0x2C020001, 0x2E020001,
- 0x30020001, 0x32020001, 0x34020001, 0x36020001, 0x38020001, 0x3A020001, 0x3C020001, 0x3E020001,
- 0x40020001, 0x42020001, 0x44020001, 0x46020001, 0x48020001, 0x060005B5, 0x080005B6, 0x000001BB,
- 0x000001B7, 0x16000802, 0x18000802, 0x1A000802, 0x1C000802, 0x1E000802, 0x20000802, 0x22000802,
- 0x24000802, 0x26000802, 0x28000802, 0x2A000802, 0x2C000802, 0x2E000802, 0x30000802, 0x32000802,
- 0x34000802, 0x36000802, 0x38000802, 0x3A000802, 0x3C000802, 0x3E000802, 0x40000802, 0x42000802,
- 0x44000802, 0x46000802, 0x48000802, 0x000000EC, 0x000001BC, 0x00000002, 0x0A0005BD, 0x00000130,
- 0x000000BC, 0x000000B9, 0x0600006B, 0x0800006B, 0x00001002, 0x0400006B, 0x0C0005BE, 0x4A0001AB,
- 0x00020001, 0x00000802, 0x00001802, 0x00040001, 0x00060001, 0x00002002, 0x00080001, 0x000C0001,
- 0x000E0001, 0x00100001, 0x00140001, 0x00160001, 0x00180001, 0x00004002, 0x00004802, 0x00200001,
- 0x00220001, 0x00000005, 0x00A60001, 0x01805802, 0x01042003, 0x00280001, 0x002C0001, 0x00000001,
- 0x00000000, 0x00007002, 0x00007802, 0x00009802, 0x0000A802, 0x0000B802, 0x0000C002, 0x0000C802,
- 0x0000D002, 0x00000004, 0x000001A4, 0x00000106, 0x00320001, 0x00340001, 0x00360001, 0x00380001,
- 0x0000E002, 0x0000E802, 0x0000F002, 0x0000F802, 0x00010002, 0x00010802, 0x00012002, 0x00012802,
- 0x00013802, 0x003A0001, 0x003E0001, 0x00013002, 0x0000001C, 0x00000107, 0x00400001, 0x00000018,
- 0x00014802, 0x000001B4, 0x00000038, 0x00000025, 0x00000050, 0x00000058, 0x00000045, 0x00000044,
- 0x020000C9, 0x060000C9, 0x0A0000C9, 0x0E0000C9, 0x120000C9, 0x000000D8, 0x0000005C, 0x00000008,
- 0x02000009, 0x06000009, 0x0A000009, 0x0E000009, 0x12000009, 0x0400000B, 0x0800000B, 0x0000000B,
- 0x1600000B, 0x4E00000B, 0x00000006, 0x4A00000B, 0x000001B5, 0x00420001, 0x0600000B, 0x0A00000B,
- 0x0E00000B, 0x1200000B, 0x3E00000B, 0x5200000B, 0x5600000B, 0x5A00000B, 0x5C00000B, 0x000001B6,
- 0x2400000A, 0x2800000A, 0x00000010, 0x020001AB, 0x060001AB, 0x0A0001AB, 0x0E0001AB, 0x120001AB,
- 0x00000108, 0x00015802, 0x00440001, 0x00016002, 0x00016802, 0x00017002, 0x00017802, 0x00018002,
- 0x00018802, 0x00440003, 0x00460001, 0x00480003, 0x00019802, 0x004A0001, 0x004C0001, 0x004E0001,
- 0x003C0001, 0x00500001, 0x00520001, 0x000001BD, 0x0000018D, 0x000001D0, 0x00000250, 0x00000230,
- 0x040005BE, 0x000000F9, 0x0200006B, 0x0A00006B, 0x0E00006B, 0x1200006B, 0x00540001, 0x00560001,
- 0x000005B9, 0x045A000A, 0x085A000A, 0x0C5A000A, 0x105A000A, 0x145A000A, 0x185A000A, 0x525A000A,
- 0x5E5A000A, 0x0401A00A, 0x0801A00A, 0x0C01A00A, 0x1001A00A, 0x1401A00A, 0x1801A00A, 0x5201A00A,
- 0x5E01A00A, 0x4E00000A, 0x5C00000A, 0x0E0005B9, 0x100005B9, 0x020005B9, 0x040005B9, 0x160005B9,
- 0x180005B9, 0x1A0005B9, 0x200005B9, 0x220005B9, 0x240005B9, 0x260005B9, 0x040001AB, 0x080001AB,
- 0x0C0001AB, 0x100001AB, 0x140001AB, 0x180001AB, 0x1C0001AB, 0x200001AB, 0x240001AB, 0x280001AB,
- 0x0C00006B, 0x1000006B, 0x1400006B, 0x1800006B, 0x1C00006B, 0x2000006B, 0x2400006B, 0x2800006B,
- 0x005C001C, 0x0001A81C, 0x1A0001AB, 0x1E0001AB, 0x220001AB, 0x260001AB, 0x2A0001AB, 0x160001AB,
- 0x020005B6, 0x100005B6, 0x280005B9, 0x2C0005B9, 0x300005B9, 0x0001B002, 0x020005BD, 0x0600000A,
- 0x0A00000A, 0x0E00000A, 0x1200000A, 0x1600000A, 0x3E00000A, 0x0C00000B, 0x1000000B, 0x1400000B,
- 0x2E0001AB, 0x320001AB, 0x360001AB, 0x3A0001AB, 0x3E0001AB, 0x420001AB, 0x460001AB, 0x640001AB,
- 0x680001AB, 0x6A0001AB, 0x6E0001AB, 0x720001AB, 0x760001AB, 0x7A0001AB, 0x00000013, 0x00000012,
- 0x0000005A, 0x000001B0, 0x7C00000B, 0x8000000B, 0x8200000B, 0x8600000B, 0x8C00000B, 0x6000000B,
- 0x9200000B, 0x9600000B, 0x9800000B, 0x9C00000B, 0xA000000B, 0xA400000B, 0x4A0001AA, 0x040001AA,
- 0x520001AA, 0x600001AA, 0x0C0001AA, 0x5E0001AA, 0x160001AA, 0x4C0001AA, 0x4E0001AA, 0x9E0001AA,
- 0x060001AA, 0x8800000A, 0x2A0001AA, 0x005E0001, 0x0001B802, 0x0400002B, 0x0800002B, 0x1600002B,
- 0x4C00002B, 0x00002802, 0x00003002, 0x000A0001, 0x00120001, 0x00003802, 0x001A0001, 0x001C0001,
- 0x001E0001, 0x00240001, 0x00005002, 0x00006002, 0x002A0001, 0x002E0001, 0x00300001, 0x00006802,
- 0x00008002, 0x00008802, 0x00009002, 0x0000A002, 0x0000B002, 0x0000D906, 0x00011002, 0x00011802,
- 0x00014002, 0x040000C9, 0x080000C9, 0x0C0000C9, 0x100000C9, 0x140000C9, 0x04000009, 0x08000009,
- 0x0C000009, 0x10000009, 0x14000009, 0x2200000B, 0x4C00000B, 0x2A00000B, 0x5000000B, 0x5400000B,
- 0x5800000B, 0x2600000A, 0x00015002, 0x00019002, 0x00000030, 0x000001BE, 0x0000014E, 0x00000210,
- 0x000001F0, 0x00580001, 0x065A000A, 0x0A5A000A, 0x0E5A000A, 0x125A000A, 0x165A000A, 0x1A5A000A,
- 0x4C5A000A, 0x4E5A000A, 0x0601A00A, 0x0A01A00A, 0x0E01A00A, 0x1201A00A, 0x1601A00A, 0x1A01A00A,
- 0x4C01A00A, 0x4E01A00A, 0x6000000A, 0x0000000A, 0x120005B9, 0x140005B9, 0x1C0005B9, 0x1E0005B9,
- 0x1600006B, 0x1A00006B, 0x1E00006B, 0x2200006B, 0x2600006B, 0x2A00006B, 0x0E0005B5, 0x040005B5,
- 0x2A0005B9, 0x2E0005B9, 0x0200000A, 0x0400000A, 0x0800000A, 0x0C00000A, 0x1000000A, 0x1400000A,
- 0x2A00000A, 0x2C0001AB, 0x300001AB, 0x340001AB, 0x380001AB, 0x3C0001AB, 0x400001AB, 0x440001AB,
- 0x480001AB, 0x620001AB, 0x660001AB, 0x500001AB, 0x6C0001AB, 0x700001AB, 0x740001AB, 0x780001AB,
- 0x520001AB, 0x7E00000B, 0x5E00000B, 0x8400000B, 0x8800000B, 0x8A00000B, 0x8E00000B, 0x9000000B,
- 0x9400000B, 0x9A00000B, 0x9E00000B, 0xA200000B, 0xA600000B, 0x5C0001AA, 0x3E0001AA, 0x7E0001AA,
- 0x0600002B, 0x0A00002B, 0x2A00002B, 0x4E00002B, 0x00000019
- };
-}
diff --git a/libs/utils/Unicode.cpp b/libs/utils/Unicode.cpp
deleted file mode 100644
index f92703e7f0e8..000000000000
--- a/libs/utils/Unicode.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/AndroidUnicode.h>
-#include "CharacterData.h"
-
-#define LOG_TAG "Unicode"
-#include <utils/Log.h>
-
-// ICU headers for using macros
-#include <unicode/utf16.h>
-
-#define MIN_RADIX 2
-#define MAX_RADIX 36
-
-#define TYPE_SHIFT 0
-#define TYPE_MASK ((1<<5)-1)
-
-#define DIRECTION_SHIFT (TYPE_SHIFT+5)
-#define DIRECTION_MASK ((1<<5)-1)
-
-#define MIRRORED_SHIFT (DIRECTION_SHIFT+5)
-#define MIRRORED_MASK ((1<<1)-1)
-
-#define TOUPPER_SHIFT (MIRRORED_SHIFT+1)
-#define TOUPPER_MASK ((1<<6)-1)
-
-#define TOLOWER_SHIFT (TOUPPER_SHIFT+6)
-#define TOLOWER_MASK ((1<<6)-1)
-
-#define TOTITLE_SHIFT (TOLOWER_SHIFT+6)
-#define TOTITLE_MASK ((1<<2)-1)
-
-#define MIRROR_SHIFT (TOTITLE_SHIFT+2)
-#define MIRROR_MASK ((1<<5)-1)
-
-#define NUMERIC_SHIFT (TOTITLE_SHIFT+2)
-#define NUMERIC_MASK ((1<<7)-1)
-
-#define DECOMPOSITION_SHIFT (11)
-#define DECOMPOSITION_MASK ((1<<5)-1)
-
-/*
- * Returns the value stored in the CharacterData tables that contains
- * an index into the packed data table and the decomposition type.
- */
-static uint16_t findCharacterValue(UChar32 c)
-{
- LOG_ASSERT(c >= 0 && c <= 0x10FFFF, "findCharacterValue received an invalid codepoint");
- if (c < 256)
- return CharacterData::LATIN1_DATA[c];
-
- // Rotate the bits because the tables are separated into even and odd codepoints
- c = (c >> 1) | ((c & 1) << 20);
-
- CharacterData::Range search = CharacterData::FULL_DATA[c >> 16];
- const uint32_t* array = search.array;
-
- // This trick is so that that compare in the while loop does not
- // need to shift the array entry down by 16
- c <<= 16;
- c |= 0xFFFF;
-
- int high = (int)search.length - 1;
- int low = 0;
-
- if (high < 0)
- return 0;
-
- while (low < high - 1)
- {
- int probe = (high + low) >> 1;
-
- // The entries contain the codepoint in the high 16 bits and the index
- // into PACKED_DATA in the low 16.
- if (array[probe] > (unsigned)c)
- high = probe;
- else
- low = probe;
- }
-
- LOG_ASSERT((array[low] <= (unsigned)c), "A suitable range was not found");
- return array[low] & 0xFFFF;
-}
-
-uint32_t android::Unicode::getPackedData(UChar32 c)
-{
- // findCharacterValue returns a 16-bit value with the top 5 bits containing a decomposition type
- // and the remaining bits containing an index.
- return CharacterData::PACKED_DATA[findCharacterValue(c) & 0x7FF];
-}
-
-android::Unicode::CharType android::Unicode::getType(UChar32 c)
-{
- if (c < 0 || c >= 0x10FFFF)
- return CHARTYPE_UNASSIGNED;
- return (CharType)((getPackedData(c) >> TYPE_SHIFT) & TYPE_MASK);
-}
-
-android::Unicode::DecompositionType android::Unicode::getDecompositionType(UChar32 c)
-{
- // findCharacterValue returns a 16-bit value with the top 5 bits containing a decomposition type
- // and the remaining bits containing an index.
- return (DecompositionType)((findCharacterValue(c) >> DECOMPOSITION_SHIFT) & DECOMPOSITION_MASK);
-}
-
-int android::Unicode::getDigitValue(UChar32 c, int radix)
-{
- if (radix < MIN_RADIX || radix > MAX_RADIX)
- return -1;
-
- int tempValue = radix;
-
- if (c >= '0' && c <= '9')
- tempValue = c - '0';
- else if (c >= 'a' && c <= 'z')
- tempValue = c - 'a' + 10;
- else if (c >= 'A' && c <= 'Z')
- tempValue = c - 'A' + 10;
-
- return tempValue < radix ? tempValue : -1;
-}
-
-int android::Unicode::getNumericValue(UChar32 c)
-{
- if (isMirrored(c))
- return -1;
-
- return (int) CharacterData::NUMERICS[((getPackedData(c) >> NUMERIC_SHIFT) & NUMERIC_MASK)];
-}
-
-UChar32 android::Unicode::toLower(UChar32 c)
-{
- return c + CharacterData::LCDIFF[(getPackedData(c) >> TOLOWER_SHIFT) & TOLOWER_MASK];
-}
-
-UChar32 android::Unicode::toUpper(UChar32 c)
-{
- return c + CharacterData::UCDIFF[(getPackedData(c) >> TOUPPER_SHIFT) & TOUPPER_MASK];
-}
-
-android::Unicode::Direction android::Unicode::getDirectionality(UChar32 c)
-{
- uint32_t data = getPackedData(c);
-
- if (0 == data)
- return DIRECTIONALITY_UNDEFINED;
-
- Direction d = (Direction) ((data >> DIRECTION_SHIFT) & DIRECTION_MASK);
-
- if (DIRECTION_MASK == d)
- return DIRECTIONALITY_UNDEFINED;
-
- return d;
-}
-
-bool android::Unicode::isMirrored(UChar32 c)
-{
- return ((getPackedData(c) >> MIRRORED_SHIFT) & MIRRORED_MASK) != 0;
-}
-
-UChar32 android::Unicode::toMirror(UChar32 c)
-{
- if (!isMirrored(c))
- return c;
-
- return c + CharacterData::MIRROR_DIFF[(getPackedData(c) >> MIRROR_SHIFT) & MIRROR_MASK];
-}
-
-UChar32 android::Unicode::toTitle(UChar32 c)
-{
- int32_t diff = CharacterData::TCDIFF[(getPackedData(c) >> TOTITLE_SHIFT) & TOTITLE_MASK];
-
- if (TOTITLE_MASK == diff)
- return toUpper(c);
-
- return c + diff;
-}
-
-
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 70c27c25a1f6..32c5c23fd976 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -87,10 +87,11 @@ public class AudioManager {
/**
* @hide Broadcast intent when the volume for a particular stream type changes.
- * Includes the stream and the new volume
+ * Includes the stream, the new volume and previous volumes
*
* @see #EXTRA_VOLUME_STREAM_TYPE
* @see #EXTRA_VOLUME_STREAM_VALUE
+ * @see #EXTRA_PREV_VOLUME_STREAM_VALUE
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String VOLUME_CHANGED_ACTION = "android.media.VOLUME_CHANGED_ACTION";
@@ -126,6 +127,12 @@ public class AudioManager {
public static final String EXTRA_VOLUME_STREAM_VALUE =
"android.media.EXTRA_VOLUME_STREAM_VALUE";
+ /**
+ * @hide The previous volume associated with the stream for the volume changed intent.
+ */
+ public static final String EXTRA_PREV_VOLUME_STREAM_VALUE =
+ "android.media.EXTRA_PREV_VOLUME_STREAM_VALUE";
+
/** The audio stream for phone calls */
public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL;
/** The audio stream for system sounds */
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index bde8a473cfce..668917e6ef8d 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -403,30 +403,34 @@ public class AudioService extends IAudioService.Stub {
// UI
mVolumePanel.postVolumeChanged(streamType, flags);
// Broadcast Intent
- sendVolumeUpdate(streamType);
+ sendVolumeUpdate(streamType, oldIndex, streamState.mIndex);
}
/** @see AudioManager#setStreamVolume(int, int, int) */
public void setStreamVolume(int streamType, int index, int flags) {
ensureValidStreamType(streamType);
+
+ final int oldIndex = mStreamStates[STREAM_VOLUME_ALIAS[streamType]].mIndex;
+
index = rescaleIndex(index * 10, streamType, STREAM_VOLUME_ALIAS[streamType]);
setStreamVolumeInt(STREAM_VOLUME_ALIAS[streamType], index, false, true);
// UI, etc.
mVolumePanel.postVolumeChanged(streamType, flags);
// Broadcast Intent
- sendVolumeUpdate(streamType);
+ sendVolumeUpdate(streamType, oldIndex, index);
}
- private void sendVolumeUpdate(int streamType) {
+ private void sendVolumeUpdate(int streamType, int oldIndex, int index) {
+ oldIndex = (oldIndex + 5) / 10;
+ index = (index + 5) / 10;
+
Intent intent = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType);
- intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, getStreamVolume(streamType));
+ intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index);
+ intent.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex);
- // Currently, sending the intent only when the stream is BLUETOOTH_SCO
- if (streamType == AudioSystem.STREAM_BLUETOOTH_SCO) {
- mContext.sendBroadcast(intent);
- }
+ mContext.sendBroadcast(intent);
}
/**
diff --git a/media/java/android/media/DecoderCapabilities.java b/media/java/android/media/DecoderCapabilities.java
new file mode 100644
index 000000000000..f16cccfba21e
--- /dev/null
+++ b/media/java/android/media/DecoderCapabilities.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * {@hide}
+ *
+ * The DecoderCapabilities class is used to retrieve the types of the
+ * video and audio decoder(s) supported on a specific Android platform.
+ */
+public class DecoderCapabilities
+{
+ /**
+ * The VideoDecoder class represents the type of a video decoder
+ *
+ */
+ public enum VideoDecoder {
+ VIDEO_DECODER_WMV,
+ };
+
+ /**
+ * The AudioDecoder class represents the type of an audio decoder
+ */
+ public enum AudioDecoder {
+ AUDIO_DECODER_WMA,
+ };
+
+ static {
+ System.loadLibrary("media_jni");
+ native_init();
+ }
+
+ /**
+ * Returns the list of video decoder types
+ * @see android.media.DecoderCapabilities.VideoDecoder
+ */
+ public static List<VideoDecoder> getVideoDecoders() {
+ List<VideoDecoder> decoderList = new ArrayList<VideoDecoder>();
+ int nDecoders = native_get_num_video_decoders();
+ for (int i = 0; i < nDecoders; ++i) {
+ decoderList.add(VideoDecoder.values()[native_get_video_decoder_type(i)]);
+ }
+ return decoderList;
+ }
+
+ /**
+ * Returns the list of audio decoder types
+ * @see android.media.DecoderCapabilities.AudioDecoder
+ */
+ public static List<AudioDecoder> getAudioDecoders() {
+ List<AudioDecoder> decoderList = new ArrayList<AudioDecoder>();
+ int nDecoders = native_get_num_audio_decoders();
+ for (int i = 0; i < nDecoders; ++i) {
+ decoderList.add(AudioDecoder.values()[native_get_audio_decoder_type(i)]);
+ }
+ return decoderList;
+ }
+
+ private DecoderCapabilities() {} // Don't call me
+
+ // Implemented by JNI
+ private static native final void native_init();
+ private static native final int native_get_num_video_decoders();
+ private static native final int native_get_video_decoder_type(int index);
+ private static native final int native_get_num_audio_decoders();
+ private static native final int native_get_audio_decoder_type(int index);
+}
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 89ee7d33b547..e8b89e0e63c5 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1064,6 +1064,53 @@ public class MediaPlayer
private native void _reset();
/**
+ * Suspends the MediaPlayer. The only methods that may be called while
+ * suspended are {@link #reset()}, {@link #release()} and {@link #resume()}.
+ * MediaPlayer will release its hardware resources as far as
+ * possible and reasonable. A successfully suspended MediaPlayer will
+ * cease sending events.
+ * If suspension is successful, this method returns true, otherwise
+ * false is returned and the player's state is not affected.
+ * @hide
+ */
+ public boolean suspend() {
+ if (native_suspend_resume(true) < 0) {
+ return false;
+ }
+
+ stayAwake(false);
+
+ // make sure none of the listeners get called anymore
+ mEventHandler.removeCallbacksAndMessages(null);
+
+ return true;
+ }
+
+ /**
+ * Resumes the MediaPlayer. Only to be called after a previous (successful)
+ * call to {@link #suspend()}.
+ * MediaPlayer will return to a state close to what it was in before
+ * suspension.
+ * @hide
+ */
+ public boolean resume() {
+ if (native_suspend_resume(false) < 0) {
+ return false;
+ }
+
+ if (isPlaying()) {
+ stayAwake(true);
+ }
+
+ return true;
+ }
+
+ /**
+ * @hide
+ */
+ private native int native_suspend_resume(boolean isSuspend);
+
+ /**
* Sets the audio stream type for this MediaPlayer. See {@link AudioManager}
* for a list of stream types.
*
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index df21aa425c0b..62a4fe98f587 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -321,6 +321,28 @@ public class SoundPool
public native final void resume(int streamID);
/**
+ * Pause all active streams.
+ *
+ * Pause all streams that are currently playing. This function
+ * iterates through all the active streams and pauses any that
+ * are playing. It also sets a flag so that any streams that
+ * are playing can be resumed by calling autoResume().
+ *
+ * @hide
+ */
+ public native final void autoPause();
+
+ /**
+ * Resume all previously active streams.
+ *
+ * Automatically resumes all streams that were paused in previous
+ * calls to autoPause().
+ *
+ * @hide
+ */
+ public native final void autoResume();
+
+ /**
* Stop a playback stream.
*
* Stop the stream specified by the streamID. This
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 2773e5ca9f4c..8ed37301156e 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -692,6 +692,19 @@ android_media_MediaPlayer_snoop(JNIEnv* env, jobject thiz, jobject data, jint ki
return ret;
}
+static jint
+android_media_MediaPlayer_native_suspend_resume(
+ JNIEnv *env, jobject thiz, jboolean isSuspend) {
+ LOGV("suspend_resume(%d)", isSuspend);
+ sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
+ if (mp == NULL ) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return UNKNOWN_ERROR;
+ }
+
+ return isSuspend ? mp->suspend() : mp->resume();
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gMethods[] = {
@@ -724,6 +737,7 @@ static JNINativeMethod gMethods[] = {
{"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaPlayer_native_finalize},
{"snoop", "([SI)I", (void *)android_media_MediaPlayer_snoop},
+ {"native_suspend_resume", "(Z)I", (void *)android_media_MediaPlayer_native_suspend_resume},
};
static const char* const kClassPathName = "android/media/MediaPlayer";
diff --git a/media/jni/android_media_MediaProfiles.cpp b/media/jni/android_media_MediaProfiles.cpp
index 50380c11a1cb..19132c5d37ba 100644
--- a/media/jni/android_media_MediaProfiles.cpp
+++ b/media/jni/android_media_MediaProfiles.cpp
@@ -44,14 +44,14 @@ android_media_MediaProfiles_native_init(JNIEnv *env)
}
}
-static int
+static jint
android_media_MediaProfiles_native_get_num_file_formats(JNIEnv *env, jobject thiz)
{
LOGV("native_get_num_file_formats");
return sProfiles->getOutputFileFormats().size();
}
-static int
+static jint
android_media_MediaProfiles_native_get_file_format(JNIEnv *env, jobject thiz, jint index)
{
LOGV("native_get_file_format: %d", index);
@@ -61,11 +61,10 @@ android_media_MediaProfiles_native_get_file_format(JNIEnv *env, jobject thiz, ji
jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
return -1;
}
- int format = static_cast<int>(formats[index]);
- return format;
+ return static_cast<jint>(formats[index]);
}
-static int
+static jint
android_media_MediaProfiles_native_get_num_video_encoders(JNIEnv *env, jobject thiz)
{
LOGV("native_get_num_video_encoders");
@@ -116,7 +115,7 @@ android_media_MediaProfiles_native_get_video_encoder_cap(JNIEnv *env, jobject th
return cap;
}
-static int
+static jint
android_media_MediaProfiles_native_get_num_audio_encoders(JNIEnv *env, jobject thiz)
{
LOGV("native_get_num_audio_encoders");
@@ -209,6 +208,48 @@ android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject th
audioChannels);
}
+static jint
+android_media_MediaProfiles_native_get_num_video_decoders(JNIEnv *env, jobject thiz)
+{
+ LOGV("native_get_num_video_decoders");
+ return sProfiles->getVideoDecoders().size();
+}
+
+static jint
+android_media_MediaProfiles_native_get_video_decoder_type(JNIEnv *env, jobject thiz, jint index)
+{
+ LOGV("native_get_video_decoder_type: %d", index);
+ Vector<video_decoder> decoders = sProfiles->getVideoDecoders();
+ int nSize = decoders.size();
+ if (index < 0 || index >= nSize) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
+ return -1;
+ }
+
+ return static_cast<jint>(decoders[index]);
+}
+
+static jint
+android_media_MediaProfiles_native_get_num_audio_decoders(JNIEnv *env, jobject thiz)
+{
+ LOGV("native_get_num_audio_decoders");
+ return sProfiles->getAudioDecoders().size();
+}
+
+static jint
+android_media_MediaProfiles_native_get_audio_decoder_type(JNIEnv *env, jobject thiz, jint index)
+{
+ LOGV("native_get_audio_decoder_type: %d", index);
+ Vector<audio_decoder> decoders = sProfiles->getAudioDecoders();
+ int nSize = decoders.size();
+ if (index < 0 || index >= nSize) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
+ return -1;
+ }
+
+ return static_cast<jint>(decoders[index]);
+}
+
static JNINativeMethod gMethodsForEncoderCapabilitiesClass[] = {
{"native_init", "()V", (void *)android_media_MediaProfiles_native_init},
{"native_get_num_file_formats", "()I", (void *)android_media_MediaProfiles_native_get_num_file_formats},
@@ -229,7 +270,16 @@ static JNINativeMethod gMethodsForCamcorderProfileClass[] = {
(void *)android_media_MediaProfiles_native_get_camcorder_profile},
};
+static JNINativeMethod gMethodsForDecoderCapabilitiesClass[] = {
+ {"native_init", "()V", (void *)android_media_MediaProfiles_native_init},
+ {"native_get_num_video_decoders", "()I", (void *)android_media_MediaProfiles_native_get_num_video_decoders},
+ {"native_get_num_audio_decoders", "()I", (void *)android_media_MediaProfiles_native_get_num_audio_decoders},
+ {"native_get_video_decoder_type", "(I)I", (void *)android_media_MediaProfiles_native_get_video_decoder_type},
+ {"native_get_audio_decoder_type", "(I)I", (void *)android_media_MediaProfiles_native_get_audio_decoder_type},
+};
+
static const char* const kEncoderCapabilitiesClassPathName = "android/media/EncoderCapabilities";
+static const char* const kDecoderCapabilitiesClassPathName = "android/media/DecoderCapabilities";
static const char* const kCamcorderProfileClassPathName = "android/media/CamcorderProfile";
// This function only registers the native methods, and is called from
@@ -246,6 +296,11 @@ int register_android_media_MediaProfiles(JNIEnv *env)
gMethodsForCamcorderProfileClass,
NELEM(gMethodsForCamcorderProfileClass));
- // Success if ret1 == 0 && ret2 == 0
- return (ret1 || ret2);
+ int ret3 = AndroidRuntime::registerNativeMethods(env,
+ kDecoderCapabilitiesClassPathName,
+ gMethodsForDecoderCapabilitiesClass,
+ NELEM(gMethodsForDecoderCapabilitiesClass));
+
+ // Success if ret1 == 0 && ret2 == 0 && ret3 == 0
+ return (ret1 || ret2 || ret3);
}
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index e57f4a46aa66..2a65b0d5c7f2 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -294,6 +294,16 @@ void SoundPool::pause(int channelID)
}
}
+void SoundPool::autoPause()
+{
+ LOGV("pauseAll()");
+ Mutex::Autolock lock(&mLock);
+ for (int i = 0; i < mMaxChannels; ++i) {
+ SoundChannel* channel = &mChannelPool[i];
+ channel->autoPause();
+ }
+}
+
void SoundPool::resume(int channelID)
{
LOGV("resume(%d)", channelID);
@@ -304,6 +314,16 @@ void SoundPool::resume(int channelID)
}
}
+void SoundPool::autoResume()
+{
+ LOGV("pauseAll()");
+ Mutex::Autolock lock(&mLock);
+ for (int i = 0; i < mMaxChannels; ++i) {
+ SoundChannel* channel = &mChannelPool[i];
+ channel->autoResume();
+ }
+}
+
void SoundPool::stop(int channelID)
{
LOGV("stop(%d)", channelID);
@@ -710,12 +730,35 @@ void SoundChannel::pause()
}
}
+void SoundChannel::autoPause()
+{
+ Mutex::Autolock lock(&mLock);
+ if (mState == PLAYING) {
+ LOGV("pause track");
+ mState = PAUSED;
+ mAutoPaused = true;
+ mAudioTrack->pause();
+ }
+}
+
void SoundChannel::resume()
{
Mutex::Autolock lock(&mLock);
if (mState == PAUSED) {
LOGV("resume track");
mState = PLAYING;
+ mAutoPaused = false;
+ mAudioTrack->start();
+ }
+}
+
+void SoundChannel::autoResume()
+{
+ Mutex::Autolock lock(&mLock);
+ if (mAutoPaused && (mState == PAUSED)) {
+ LOGV("resume track");
+ mState = PLAYING;
+ mAutoPaused = false;
mAudioTrack->start();
}
}
diff --git a/media/jni/soundpool/SoundPool.h b/media/jni/soundpool/SoundPool.h
index 7a2d631b8b48..42037af6e118 100644
--- a/media/jni/soundpool/SoundPool.h
+++ b/media/jni/soundpool/SoundPool.h
@@ -117,7 +117,8 @@ protected:
class SoundChannel : public SoundEvent {
public:
enum state { IDLE, RESUMING, STOPPING, PAUSED, PLAYING };
- SoundChannel() : mAudioTrack(0), mState(IDLE), mNumChannels(1), mPos(0), mToggle(0) {}
+ SoundChannel() : mAudioTrack(0), mState(IDLE), mNumChannels(1),
+ mPos(0), mToggle(0), mAutoPaused(false) {}
~SoundChannel();
void init(SoundPool* soundPool);
void play(const sp<Sample>& sample, int channelID, float leftVolume, float rightVolume,
@@ -127,7 +128,9 @@ public:
void stop_l();
void stop();
void pause();
+ void autoPause();
void resume();
+ void autoResume();
void setRate(float rate);
int state() { return mState; }
void setPriority(int priority) { mPriority = priority; }
@@ -151,6 +154,7 @@ private:
int mPos;
int mAudioBufferSize;
unsigned long mToggle;
+ bool mAutoPaused;
};
// application object for managing a pool of sounds
@@ -166,7 +170,9 @@ public:
int play(int sampleID, float leftVolume, float rightVolume, int priority,
int loop, float rate);
void pause(int channelID);
+ void autoPause();
void resume(int channelID);
+ void autoResume();
void stop(int channelID);
void setVolume(int channelID, float leftVolume, float rightVolume);
void setPriority(int channelID, int priority);
diff --git a/media/jni/soundpool/android_media_SoundPool.cpp b/media/jni/soundpool/android_media_SoundPool.cpp
index f0677a692c9f..447f9319504f 100644
--- a/media/jni/soundpool/android_media_SoundPool.cpp
+++ b/media/jni/soundpool/android_media_SoundPool.cpp
@@ -102,6 +102,24 @@ android_media_SoundPool_resume(JNIEnv *env, jobject thiz, jint channelID)
}
static void
+android_media_SoundPool_autoPause(JNIEnv *env, jobject thiz)
+{
+ LOGV("android_media_SoundPool_autoPause");
+ SoundPool *ap = MusterSoundPool(env, thiz);
+ if (ap == NULL) return;
+ ap->autoPause();
+}
+
+static void
+android_media_SoundPool_autoResume(JNIEnv *env, jobject thiz)
+{
+ LOGV("android_media_SoundPool_autoResume");
+ SoundPool *ap = MusterSoundPool(env, thiz);
+ if (ap == NULL) return;
+ ap->autoResume();
+}
+
+static void
android_media_SoundPool_stop(JNIEnv *env, jobject thiz, jint channelID)
{
LOGV("android_media_SoundPool_stop");
@@ -223,6 +241,14 @@ static JNINativeMethod gMethods[] = {
"(I)V",
(void *)android_media_SoundPool_resume
},
+ { "autoPause",
+ "()V",
+ (void *)android_media_SoundPool_autoPause
+ },
+ { "autoResume",
+ "()V",
+ (void *)android_media_SoundPool_autoResume
+ },
{ "stop",
"(I)V",
(void *)android_media_SoundPool_stop
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index 9c127d43796d..ed792b337693 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -43,6 +43,8 @@ enum {
INVOKE,
SET_METADATA_FILTER,
GET_METADATA,
+ SUSPEND,
+ RESUME,
};
class BpMediaPlayer: public BpInterface<IMediaPlayer>
@@ -199,6 +201,26 @@ public:
remote()->transact(GET_METADATA, request, reply);
return reply->readInt32();
}
+
+ status_t suspend() {
+ Parcel request;
+ request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+
+ Parcel reply;
+ remote()->transact(SUSPEND, request, &reply);
+
+ return reply.readInt32();
+ }
+
+ status_t resume() {
+ Parcel request;
+ request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+
+ Parcel reply;
+ remote()->transact(RESUME, request, &reply);
+
+ return reply.readInt32();
+ }
};
IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
@@ -299,6 +321,16 @@ status_t BnMediaPlayer::onTransact(
reply->writeInt32(setMetadataFilter(data));
return NO_ERROR;
} break;
+ case SUSPEND: {
+ CHECK_INTERFACE(IMediaPlayer, data, reply);
+ reply->writeInt32(suspend());
+ return NO_ERROR;
+ } break;
+ case RESUME: {
+ CHECK_INTERFACE(IMediaPlayer, data, reply);
+ reply->writeInt32(resume());
+ return NO_ERROR;
+ } break;
case GET_METADATA: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
const status_t retcode = getMetadata(data.readInt32(), data.readInt32(), reply);
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 01cd8ce2cbed..2157814ad754 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -167,6 +167,16 @@ status_t MediaPlayer::invoke(const Parcel& request, Parcel *reply)
return INVALID_OPERATION;
}
+status_t MediaPlayer::suspend() {
+ Mutex::Autolock _l(mLock);
+ return mPlayer->suspend();
+}
+
+status_t MediaPlayer::resume() {
+ Mutex::Autolock _l(mLock);
+ return mPlayer->resume();
+}
+
status_t MediaPlayer::setMetadataFilter(const Parcel& filter)
{
LOGD("setMetadataFilter");
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index a9a0fde61b71..cf97b2344eba 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -59,15 +59,8 @@ LOCAL_C_INCLUDES := \
$(JNI_H_INCLUDE) \
$(call include-path-for, graphics corecg) \
$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
- $(TOP)/frameworks/base/media/libstagefright/include
-
-ifeq ($(TARGET_ARCH),arm)
- LOCAL_C_INCLUDES += \
+ $(TOP)/frameworks/base/media/libstagefright/include \
$(TOP)/external/tremolo/Tremolo
-else
- LOCAL_C_INCLUDES += \
- $(TOP)/external/tremor/Tremor
-endif
LOCAL_MODULE:= libmediaplayerservice
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 55b06f4af331..b4fc0350e390 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -970,6 +970,20 @@ status_t MediaPlayerService::Client::getMetadata(
return OK;
}
+status_t MediaPlayerService::Client::suspend() {
+ sp<MediaPlayerBase> p = getPlayer();
+ if (p == 0) return UNKNOWN_ERROR;
+
+ return p->suspend();
+}
+
+status_t MediaPlayerService::Client::resume() {
+ sp<MediaPlayerBase> p = getPlayer();
+ if (p == 0) return UNKNOWN_ERROR;
+
+ return p->resume();
+}
+
status_t MediaPlayerService::Client::prepareAsync()
{
LOGV("[%d] prepareAsync", mConnId);
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index c9cae3508e9d..2408c621b9b5 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -222,6 +222,8 @@ private:
virtual status_t getMetadata(bool update_only,
bool apply_filter,
Parcel *reply);
+ virtual status_t suspend();
+ virtual status_t resume();
sp<MediaPlayerBase> createPlayer(player_type playerType);
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index 1bfcf6589614..7776b4e5b60f 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -136,6 +136,16 @@ player_type StagefrightPlayer::playerType() {
return STAGEFRIGHT_PLAYER;
}
+status_t StagefrightPlayer::suspend() {
+ LOGV("suspend");
+ return mPlayer->suspend();
+}
+
+status_t StagefrightPlayer::resume() {
+ LOGV("resume");
+ return mPlayer->resume();
+}
+
status_t StagefrightPlayer::invoke(const Parcel &request, Parcel *reply) {
return INVALID_OPERATION;
}
diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h
index 9e6674a2a007..4446582f23b4 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.h
+++ b/media/libmediaplayerservice/StagefrightPlayer.h
@@ -50,6 +50,8 @@ public:
virtual player_type playerType();
virtual status_t invoke(const Parcel &request, Parcel *reply);
virtual void setAudioSink(const sp<AudioSink> &audioSink);
+ virtual status_t suspend();
+ virtual status_t resume();
private:
AwesomePlayer *mPlayer;
diff --git a/media/libstagefright/AMRExtractor.cpp b/media/libstagefright/AMRExtractor.cpp
index 3193d5e34eab..2a16d26a0a63 100644
--- a/media/libstagefright/AMRExtractor.cpp
+++ b/media/libstagefright/AMRExtractor.cpp
@@ -225,27 +225,32 @@ status_t AMRSource::read(
return ERROR_IO;
}
- MediaBuffer *buffer;
- status_t err = mGroup->acquire_buffer(&buffer);
- if (err != OK) {
- return err;
- }
-
if (header & 0x83) {
// Padding bits must be 0.
+ LOGE("padding bits must be 0, header is 0x%02x", header);
+
return ERROR_MALFORMED;
}
unsigned FT = (header >> 3) & 0x0f;
if (FT > 8 || (!mIsWide && FT > 7)) {
+
+ LOGE("illegal AMR frame type %d", FT);
+
return ERROR_MALFORMED;
}
size_t frameSize = getFrameSize(mIsWide, FT);
CHECK_EQ(frameSize, mFrameSize);
+ MediaBuffer *buffer;
+ status_t err = mGroup->acquire_buffer(&buffer);
+ if (err != OK) {
+ return err;
+ }
+
n = mDataSource->readAt(mOffset, buffer->data(), frameSize);
if (n != (ssize_t)frameSize) {
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 1db398ee83d6..071bb9ecd8fb 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -48,15 +48,8 @@ endif
LOCAL_C_INCLUDES:= \
$(JNI_H_INCLUDE) \
$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
- $(TOP)/external/opencore/android
-
-ifeq ($(TARGET_ARCH),arm)
- LOCAL_C_INCLUDES += \
+ $(TOP)/external/opencore/android \
$(TOP)/external/tremolo/Tremolo
-else
- LOCAL_C_INCLUDES += \
- $(TOP)/external/tremor/Tremor
-endif
LOCAL_SHARED_LIBRARIES := \
libbinder \
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 5d2127b13cf6..1c9f4fd732bc 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -84,6 +84,7 @@ private:
struct AwesomeLocalRenderer : public AwesomeRenderer {
AwesomeLocalRenderer(
+ bool previewOnly,
const char *componentName,
OMX_COLOR_FORMATTYPE colorFormat,
const sp<ISurface> &surface,
@@ -91,15 +92,18 @@ struct AwesomeLocalRenderer : public AwesomeRenderer {
size_t decodedWidth, size_t decodedHeight)
: mTarget(NULL),
mLibHandle(NULL) {
- init(componentName,
+ init(previewOnly, componentName,
colorFormat, surface, displayWidth,
displayHeight, decodedWidth, decodedHeight);
}
virtual void render(MediaBuffer *buffer) {
- mTarget->render(
- (const uint8_t *)buffer->data() + buffer->range_offset(),
- buffer->range_length(), NULL);
+ render((const uint8_t *)buffer->data() + buffer->range_offset(),
+ buffer->range_length());
+ }
+
+ void render(const void *data, size_t size) {
+ mTarget->render(data, size, NULL);
}
protected:
@@ -118,6 +122,7 @@ private:
void *mLibHandle;
void init(
+ bool previewOnly,
const char *componentName,
OMX_COLOR_FORMATTYPE colorFormat,
const sp<ISurface> &surface,
@@ -129,31 +134,39 @@ private:
};
void AwesomeLocalRenderer::init(
+ bool previewOnly,
const char *componentName,
OMX_COLOR_FORMATTYPE colorFormat,
const sp<ISurface> &surface,
size_t displayWidth, size_t displayHeight,
size_t decodedWidth, size_t decodedHeight) {
- mLibHandle = dlopen("libstagefrighthw.so", RTLD_NOW);
-
- if (mLibHandle) {
- typedef VideoRenderer *(*CreateRendererFunc)(
- const sp<ISurface> &surface,
- const char *componentName,
- OMX_COLOR_FORMATTYPE colorFormat,
- size_t displayWidth, size_t displayHeight,
- size_t decodedWidth, size_t decodedHeight);
-
- CreateRendererFunc func =
- (CreateRendererFunc)dlsym(
- mLibHandle,
- "_Z14createRendererRKN7android2spINS_8ISurfaceEEEPKc20"
- "OMX_COLOR_FORMATTYPEjjjj");
-
- if (func) {
- mTarget =
- (*func)(surface, componentName, colorFormat,
- displayWidth, displayHeight, decodedWidth, decodedHeight);
+ if (!previewOnly) {
+ // We will stick to the vanilla software-color-converting renderer
+ // for "previewOnly" mode, to avoid unneccessarily switching overlays
+ // more often than necessary.
+
+ mLibHandle = dlopen("libstagefrighthw.so", RTLD_NOW);
+
+ if (mLibHandle) {
+ typedef VideoRenderer *(*CreateRendererFunc)(
+ const sp<ISurface> &surface,
+ const char *componentName,
+ OMX_COLOR_FORMATTYPE colorFormat,
+ size_t displayWidth, size_t displayHeight,
+ size_t decodedWidth, size_t decodedHeight);
+
+ CreateRendererFunc func =
+ (CreateRendererFunc)dlsym(
+ mLibHandle,
+ "_Z14createRendererRKN7android2spINS_8ISurfaceEEEPKc20"
+ "OMX_COLOR_FORMATTYPEjjjj");
+
+ if (func) {
+ mTarget =
+ (*func)(surface, componentName, colorFormat,
+ displayWidth, displayHeight,
+ decodedWidth, decodedHeight);
+ }
}
}
@@ -166,10 +179,12 @@ void AwesomeLocalRenderer::init(
AwesomePlayer::AwesomePlayer()
: mTimeSource(NULL),
+ mVideoRendererIsPreview(false),
mAudioPlayer(NULL),
mFlags(0),
mLastVideoBuffer(NULL),
- mVideoBuffer(NULL) {
+ mVideoBuffer(NULL),
+ mSuspensionState(NULL) {
CHECK_EQ(mClient.connect(), OK);
DataSource::RegisterDefaultSniffers();
@@ -221,7 +236,11 @@ void AwesomePlayer::setListener(const wp<MediaPlayerBase> &listener) {
status_t AwesomePlayer::setDataSource(
const char *uri, const KeyedVector<String8, String8> *headers) {
Mutex::Autolock autoLock(mLock);
+ return setDataSource_l(uri, headers);
+}
+status_t AwesomePlayer::setDataSource_l(
+ const char *uri, const KeyedVector<String8, String8> *headers) {
reset_l();
mUri = uri;
@@ -243,15 +262,22 @@ status_t AwesomePlayer::setDataSource(
reset_l();
- sp<DataSource> source = new FileSource(fd, offset, length);
+ sp<DataSource> dataSource = new FileSource(fd, offset, length);
- status_t err = source->initCheck();
+ status_t err = dataSource->initCheck();
if (err != OK) {
return err;
}
- sp<MediaExtractor> extractor = MediaExtractor::Create(source);
+ mFileSource = dataSource;
+
+ return setDataSource_l(dataSource);
+}
+
+status_t AwesomePlayer::setDataSource_l(
+ const sp<DataSource> &dataSource) {
+ sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
if (extractor == NULL) {
return UNKNOWN_ERROR;
@@ -299,6 +325,26 @@ void AwesomePlayer::reset_l() {
cancelPlayerEvents();
+ if (mPrefetcher != NULL) {
+ CHECK_EQ(mPrefetcher->getStrongCount(), 1);
+ }
+ mPrefetcher.clear();
+
+ // Shutdown audio first, so that the respone to the reset request
+ // appears to happen instantaneously as far as the user is concerned
+ // If we did this later, audio would continue playing while we
+ // shutdown the video-related resources and the player appear to
+ // not be as responsive to a reset request.
+ mAudioSource.clear();
+
+ if (mTimeSource != mAudioPlayer) {
+ delete mTimeSource;
+ }
+ mTimeSource = NULL;
+
+ delete mAudioPlayer;
+ mAudioPlayer = NULL;
+
mVideoRenderer.clear();
if (mLastVideoBuffer) {
@@ -325,16 +371,6 @@ void AwesomePlayer::reset_l() {
IPCThreadState::self()->flushCommands();
}
- mAudioSource.clear();
-
- if (mTimeSource != mAudioPlayer) {
- delete mTimeSource;
- }
- mTimeSource = NULL;
-
- delete mAudioPlayer;
- mAudioPlayer = NULL;
-
mDurationUs = -1;
mFlags = 0;
mVideoWidth = mVideoHeight = -1;
@@ -344,10 +380,13 @@ void AwesomePlayer::reset_l() {
mSeeking = false;
mSeekTimeUs = 0;
- mPrefetcher.clear();
-
mUri.setTo("");
mUriHeaders.clear();
+
+ mFileSource.clear();
+
+ delete mSuspensionState;
+ mSuspensionState = NULL;
}
void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
@@ -403,7 +442,10 @@ void AwesomePlayer::onStreamDone() {
status_t AwesomePlayer::play() {
Mutex::Autolock autoLock(mLock);
+ return play_l();
+}
+status_t AwesomePlayer::play_l() {
if (mFlags & PLAYING) {
return OK;
}
@@ -504,6 +546,7 @@ void AwesomePlayer::initRenderer_l() {
// Other decoders are instantiated locally and as a consequence
// allocate their buffers in local address space.
mVideoRenderer = new AwesomeLocalRenderer(
+ false, // previewOnly
component,
(OMX_COLOR_FORMATTYPE)format,
mISurface,
@@ -579,7 +622,10 @@ status_t AwesomePlayer::getDuration(int64_t *durationUs) {
status_t AwesomePlayer::getPosition(int64_t *positionUs) {
Mutex::Autolock autoLock(mLock);
+ return getPosition_l(positionUs);
+}
+status_t AwesomePlayer::getPosition_l(int64_t *positionUs) {
if (mVideoSource != NULL) {
*positionUs = mVideoTimeUs;
} else if (mAudioPlayer != NULL) {
@@ -697,7 +743,11 @@ status_t AwesomePlayer::setVideoSource(sp<MediaSource> source) {
void AwesomePlayer::onVideoEvent() {
Mutex::Autolock autoLock(mLock);
-
+ if (!mVideoEventPending) {
+ // The event has been cancelled in reset_l() but had already
+ // been scheduled for execution at that time.
+ return;
+ }
mVideoEventPending = false;
if (mSeeking) {
@@ -730,6 +780,7 @@ void AwesomePlayer::onVideoEvent() {
LOGV("VideoSource signalled format change.");
if (mVideoRenderer != NULL) {
+ mVideoRendererIsPreview = false;
initRenderer_l();
}
continue;
@@ -808,7 +859,9 @@ void AwesomePlayer::onVideoEvent() {
return;
}
- if (mVideoRenderer == NULL) {
+ if (mVideoRendererIsPreview || mVideoRenderer == NULL) {
+ mVideoRendererIsPreview = false;
+
initRenderer_l();
}
@@ -985,6 +1038,7 @@ void AwesomePlayer::onPrepareAsyncEvent() {
if (prefetcher != NULL) {
prefetcher->prepare();
+ prefetcher.clear();
}
Mutex::Autolock autoLock(mLock);
@@ -1006,5 +1060,113 @@ void AwesomePlayer::onPrepareAsyncEvent() {
mPreparedCondition.broadcast();
}
+status_t AwesomePlayer::suspend() {
+ LOGI("suspend");
+ Mutex::Autolock autoLock(mLock);
+
+ if (mSuspensionState != NULL) {
+ return INVALID_OPERATION;
+ }
+
+ while (mFlags & PREPARING) {
+ mPreparedCondition.wait(mLock);
+ }
+
+ SuspensionState *state = new SuspensionState;
+ state->mUri = mUri;
+ state->mUriHeaders = mUriHeaders;
+ state->mFileSource = mFileSource;
+
+ state->mFlags = mFlags & (PLAYING | LOOPING);
+ getPosition_l(&state->mPositionUs);
+
+ if (mLastVideoBuffer) {
+ size_t size = mLastVideoBuffer->range_length();
+ if (size) {
+ state->mLastVideoFrameSize = size;
+ state->mLastVideoFrame = malloc(size);
+ memcpy(state->mLastVideoFrame,
+ (const uint8_t *)mLastVideoBuffer->data()
+ + mLastVideoBuffer->range_offset(),
+ size);
+
+ state->mVideoWidth = mVideoWidth;
+ state->mVideoHeight = mVideoHeight;
+
+ sp<MetaData> meta = mVideoSource->getFormat();
+ CHECK(meta->findInt32(kKeyColorFormat, &state->mColorFormat));
+ CHECK(meta->findInt32(kKeyWidth, &state->mDecodedWidth));
+ CHECK(meta->findInt32(kKeyHeight, &state->mDecodedHeight));
+ }
+ }
+
+ reset_l();
+
+ mSuspensionState = state;
+
+ return OK;
+}
+
+status_t AwesomePlayer::resume() {
+ LOGI("resume");
+ Mutex::Autolock autoLock(mLock);
+
+ if (mSuspensionState == NULL) {
+ return INVALID_OPERATION;
+ }
+
+ SuspensionState *state = mSuspensionState;
+ mSuspensionState = NULL;
+
+ status_t err;
+ if (state->mFileSource != NULL) {
+ err = setDataSource_l(state->mFileSource);
+
+ if (err == OK) {
+ mFileSource = state->mFileSource;
+ }
+ } else {
+ err = setDataSource_l(state->mUri, &state->mUriHeaders);
+ }
+
+ if (err != OK) {
+ delete state;
+ state = NULL;
+
+ return err;
+ }
+
+ seekTo_l(state->mPositionUs);
+
+ mFlags = state->mFlags & LOOPING;
+
+ if (state->mLastVideoFrame && mISurface != NULL) {
+ mVideoRenderer =
+ new AwesomeLocalRenderer(
+ true, // previewOnly
+ "",
+ (OMX_COLOR_FORMATTYPE)state->mColorFormat,
+ mISurface,
+ state->mVideoWidth,
+ state->mVideoHeight,
+ state->mDecodedWidth,
+ state->mDecodedHeight);
+
+ mVideoRendererIsPreview = true;
+
+ ((AwesomeLocalRenderer *)mVideoRenderer.get())->render(
+ state->mLastVideoFrame, state->mLastVideoFrameSize);
+ }
+
+ if (state->mFlags & PLAYING) {
+ play_l();
+ }
+
+ delete state;
+ state = NULL;
+
+ return OK;
+}
+
} // namespace android
diff --git a/media/libstagefright/HTTPDataSource.cpp b/media/libstagefright/HTTPDataSource.cpp
index 4b630b999c6b..bf020e92b6f5 100644
--- a/media/libstagefright/HTTPDataSource.cpp
+++ b/media/libstagefright/HTTPDataSource.cpp
@@ -14,6 +14,10 @@
* limitations under the License.
*/
+//#define LOG_NDEBUG 0
+#define LOG_TAG "HTTPDataSource"
+#include <utils/Log.h>
+
#include "include/stagefright_string.h"
#include "include/HTTPStream.h"
@@ -266,6 +270,8 @@ ssize_t HTTPDataSource::sendRangeRequest(size_t offset) {
}
ssize_t HTTPDataSource::readAt(off_t offset, void *data, size_t size) {
+ LOGV("readAt %ld, size %d", offset, size);
+
if (offset >= mBufferOffset
&& offset < (off_t)(mBufferOffset + mBufferLength)) {
size_t num_bytes_available = mBufferLength - (offset - mBufferOffset);
@@ -298,6 +304,15 @@ ssize_t HTTPDataSource::readAt(off_t offset, void *data, size_t size) {
mBufferOffset = offset;
+ if (mContentLengthValid
+ && mBufferOffset + contentLength >= mContentLength) {
+ // If we never triggered a range request but know the content length,
+ // make sure to not read more data than there could be, otherwise
+ // we'd block indefinitely if the server doesn't close the connection.
+
+ contentLength = mContentLength - mBufferOffset;
+ }
+
if (contentLength <= 0) {
return contentLength;
}
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index 3711acacdde6..2c5da686b50e 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -276,11 +276,11 @@ ssize_t HTTPStream::receive(void *data, size_t size) {
}
disconnect();
- return total == 0 ? ERROR_IO : total;
+ return total == 0 ? (ssize_t)ERROR_IO : total;
} else if (n == 0) {
disconnect();
- return total == 0 ? ERROR_CONNECTION_LOST : total;
+ return total == 0 ? (ssize_t)ERROR_CONNECTION_LOST : total;
}
total += (size_t)n;
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 666ed080388e..16635d3ef4a7 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -60,6 +60,8 @@ protected:
virtual ~MPEG4Source();
private:
+ Mutex mLock;
+
sp<MetaData> mFormat;
sp<DataSource> mDataSource;
int32_t mTimescale;
@@ -1300,6 +1302,8 @@ MPEG4Source::~MPEG4Source() {
}
status_t MPEG4Source::start(MetaData *params) {
+ Mutex::Autolock autoLock(mLock);
+
CHECK(!mStarted);
int32_t val;
@@ -1325,6 +1329,8 @@ status_t MPEG4Source::start(MetaData *params) {
}
status_t MPEG4Source::stop() {
+ Mutex::Autolock autoLock(mLock);
+
CHECK(mStarted);
if (mBuffer != NULL) {
@@ -1345,6 +1351,8 @@ status_t MPEG4Source::stop() {
}
sp<MetaData> MPEG4Source::getFormat() {
+ Mutex::Autolock autoLock(mLock);
+
return mFormat;
}
@@ -1369,6 +1377,8 @@ size_t MPEG4Source::parseNALSize(const uint8_t *data) const {
status_t MPEG4Source::read(
MediaBuffer **out, const ReadOptions *options) {
+ Mutex::Autolock autoLock(mLock);
+
CHECK(mStarted);
*out = NULL;
@@ -1428,6 +1438,7 @@ status_t MPEG4Source::read(
return ERROR_IO;
}
+ CHECK(mBuffer != NULL);
mBuffer->set_range(0, size);
mBuffer->meta_data()->clear();
mBuffer->meta_data()->setInt64(
@@ -1461,8 +1472,10 @@ status_t MPEG4Source::read(
}
MediaBuffer *clone = mBuffer->clone();
+ CHECK(clone != NULL);
clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
+ CHECK(mBuffer != NULL);
mBuffer->set_range(
mBuffer->range_offset() + mNALLengthSize + nal_size,
mBuffer->range_length() - mNALLengthSize - nal_size);
@@ -1521,6 +1534,7 @@ status_t MPEG4Source::read(
}
CHECK_EQ(srcOffset, size);
+ CHECK(mBuffer != NULL);
mBuffer->set_range(0, dstOffset);
mBuffer->meta_data()->clear();
mBuffer->meta_data()->setInt64(
diff --git a/media/libstagefright/Prefetcher.cpp b/media/libstagefright/Prefetcher.cpp
index 835e1671b41b..76ca77b7492e 100644
--- a/media/libstagefright/Prefetcher.cpp
+++ b/media/libstagefright/Prefetcher.cpp
@@ -31,7 +31,6 @@ namespace android {
struct PrefetchedSource : public MediaSource {
PrefetchedSource(
- const sp<Prefetcher> &prefetcher,
size_t index,
const sp<MediaSource> &source);
@@ -52,13 +51,13 @@ private:
Mutex mLock;
Condition mCondition;
- sp<Prefetcher> mPrefetcher;
sp<MediaSource> mSource;
size_t mIndex;
bool mStarted;
bool mReachedEOS;
int64_t mSeekTimeUs;
int64_t mCacheDurationUs;
+ bool mPrefetcherStopped;
List<MediaBuffer *> mCachedBuffers;
@@ -69,6 +68,7 @@ private:
void clearCache_l();
void cacheMore();
+ void onPrefetcherStopped();
PrefetchedSource(const PrefetchedSource &);
PrefetchedSource &operator=(const PrefetchedSource &);
@@ -88,7 +88,7 @@ sp<MediaSource> Prefetcher::addSource(const sp<MediaSource> &source) {
Mutex::Autolock autoLock(mLock);
sp<PrefetchedSource> psource =
- new PrefetchedSource(this, mSources.size(), source);
+ new PrefetchedSource(mSources.size(), source);
mSources.add(psource);
@@ -128,47 +128,64 @@ static int64_t kMaxCacheDurationUs = 10000000ll;
void Prefetcher::threadFunc() {
for (;;) {
- Mutex::Autolock autoLock(mLock);
- if (mDone) {
- mThreadExited = true;
- mCondition.signal();
- break;
- }
- mCondition.waitRelative(mLock, 10000000ll);
+ sp<PrefetchedSource> minSource;
- int64_t minCacheDurationUs = -1;
- ssize_t minIndex = -1;
- for (size_t i = 0; i < mSources.size(); ++i) {
- sp<PrefetchedSource> source = mSources[i].promote();
-
- if (source == NULL) {
- continue;
+ {
+ Mutex::Autolock autoLock(mLock);
+ if (mDone) {
+ break;
}
-
- int64_t cacheDurationUs;
- if (!source->getCacheDurationUs(&cacheDurationUs)) {
- continue;
+ mCondition.waitRelative(mLock, 10000000ll);
+
+ int64_t minCacheDurationUs = -1;
+ ssize_t minIndex = -1;
+ for (size_t i = 0; i < mSources.size(); ++i) {
+ sp<PrefetchedSource> source = mSources[i].promote();
+
+ if (source == NULL) {
+ continue;
+ }
+
+ int64_t cacheDurationUs;
+ if (!source->getCacheDurationUs(&cacheDurationUs)) {
+ continue;
+ }
+
+ if (cacheDurationUs >= kMaxCacheDurationUs) {
+ continue;
+ }
+
+ if (minIndex < 0 || cacheDurationUs < minCacheDurationUs) {
+ minCacheDurationUs = cacheDurationUs;
+ minIndex = i;
+ minSource = source;
+ }
}
- if (cacheDurationUs >= kMaxCacheDurationUs) {
+ if (minIndex < 0) {
continue;
}
-
- if (minIndex < 0 || cacheDurationUs < minCacheDurationUs) {
- minCacheDurationUs = cacheDurationUs;
- minIndex = i;
- }
}
- if (minIndex < 0) {
+ // Make sure not to hold the lock while calling into the source.
+ // The lock guards the list of sources, not the individual sources
+ // themselves.
+ minSource->cacheMore();
+ }
+
+ Mutex::Autolock autoLock(mLock);
+ for (size_t i = 0; i < mSources.size(); ++i) {
+ sp<PrefetchedSource> source = mSources[i].promote();
+
+ if (source == NULL) {
continue;
}
- sp<PrefetchedSource> source = mSources[minIndex].promote();
- if (source != NULL) {
- source->cacheMore();
- }
+ source->onPrefetcherStopped();
}
+
+ mThreadExited = true;
+ mCondition.signal();
}
int64_t Prefetcher::getCachedDurationUs(bool *noMoreData) {
@@ -219,16 +236,15 @@ status_t Prefetcher::prepare() {
////////////////////////////////////////////////////////////////////////////////
PrefetchedSource::PrefetchedSource(
- const sp<Prefetcher> &prefetcher,
size_t index,
const sp<MediaSource> &source)
- : mPrefetcher(prefetcher),
- mSource(source),
+ : mSource(source),
mIndex(index),
mStarted(false),
mReachedEOS(false),
mSeekTimeUs(0),
- mCacheDurationUs(0) {
+ mCacheDurationUs(0),
+ mPrefetcherStopped(false) {
}
PrefetchedSource::~PrefetchedSource() {
@@ -238,6 +254,8 @@ PrefetchedSource::~PrefetchedSource() {
}
status_t PrefetchedSource::start(MetaData *params) {
+ CHECK(!mStarted);
+
Mutex::Autolock autoLock(mLock);
status_t err = mSource->start(params);
@@ -252,6 +270,8 @@ status_t PrefetchedSource::start(MetaData *params) {
}
status_t PrefetchedSource::stop() {
+ CHECK(mStarted);
+
Mutex::Autolock autoLock(mLock);
clearCache_l();
@@ -281,7 +301,7 @@ status_t PrefetchedSource::read(
mSeekTimeUs = seekTimeUs;
}
- while (!mReachedEOS && mCachedBuffers.empty()) {
+ while (!mPrefetcherStopped && !mReachedEOS && mCachedBuffers.empty()) {
mCondition.wait(mLock);
}
@@ -390,4 +410,10 @@ void PrefetchedSource::clearCache_l() {
updateCacheDuration_l();
}
+void PrefetchedSource::onPrefetcherStopped() {
+ Mutex::Autolock autoLock(mLock);
+ mPrefetcherStopped = true;
+ mCondition.signal();
+}
+
} // namespace android
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index a19784ba5f92..114d4c649c5d 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -21,12 +21,14 @@
#include "TimedEventQueue.h"
#include <media/MediaPlayerInterface.h>
+#include <media/stagefright/DataSource.h>
#include <media/stagefright/OMXClient.h>
#include <utils/threads.h>
namespace android {
struct AudioPlayer;
+struct DataSource;
struct MediaBuffer;
struct MediaExtractor;
struct MediaSource;
@@ -78,6 +80,9 @@ struct AwesomePlayer {
status_t getVideoDimensions(int32_t *width, int32_t *height) const;
+ status_t suspend();
+ status_t resume();
+
private:
friend struct AwesomeEvent;
@@ -103,8 +108,11 @@ private:
String8 mUri;
KeyedVector<String8, String8> mUriHeaders;
+ sp<DataSource> mFileSource;
+
sp<MediaSource> mVideoSource;
sp<AwesomeRenderer> mVideoRenderer;
+ bool mVideoRendererIsPreview;
sp<MediaSource> mAudioSource;
AudioPlayer *mAudioPlayer;
@@ -140,12 +148,45 @@ private:
void postBufferingEvent_l();
void postStreamDoneEvent_l();
void postCheckAudioStatusEvent_l();
+ status_t getPosition_l(int64_t *positionUs);
+ status_t play_l();
MediaBuffer *mLastVideoBuffer;
MediaBuffer *mVideoBuffer;
sp<Prefetcher> mPrefetcher;
+ struct SuspensionState {
+ String8 mUri;
+ KeyedVector<String8, String8> mUriHeaders;
+ sp<DataSource> mFileSource;
+
+ uint32_t mFlags;
+ int64_t mPositionUs;
+
+ void *mLastVideoFrame;
+ size_t mLastVideoFrameSize;
+ int32_t mColorFormat;
+ int32_t mVideoWidth, mVideoHeight;
+ int32_t mDecodedWidth, mDecodedHeight;
+
+ SuspensionState()
+ : mLastVideoFrame(NULL) {
+ }
+
+ ~SuspensionState() {
+ if (mLastVideoFrame) {
+ free(mLastVideoFrame);
+ mLastVideoFrame = NULL;
+ }
+ }
+ } *mSuspensionState;
+
+ status_t setDataSource_l(
+ const char *uri,
+ const KeyedVector<String8, String8> *headers = NULL);
+
+ status_t setDataSource_l(const sp<DataSource> &dataSource);
status_t setDataSource_l(const sp<MediaExtractor> &extractor);
void reset_l();
status_t seekTo_l(int64_t timeUs);
diff --git a/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java b/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java
index 1434d3f55b3b..df1b37599052 100644
--- a/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java
+++ b/media/tests/SoundPoolTest/src/com/android/SoundPoolTest.java
@@ -52,7 +52,6 @@ public class SoundPoolTest extends Activity
R.raw.test5
};
- private final static int MAX_STREAMS = 1;
private final static float SEMITONE = 1.059463094f;
private final static float DEFAULT_VOLUME = 0.707f;
private final static float MAX_VOLUME = 1.0f;
@@ -70,6 +69,7 @@ public class SoundPoolTest extends Activity
private boolean mRunning;
private SoundPool mSoundPool = null;
private int mLastSample;
+ private int mMaxStreams;
private int mLoadStatus;
private int[] mSounds;
private float mScale[];
@@ -101,17 +101,18 @@ public class SoundPoolTest extends Activity
return id;
}
- private int initSoundPool() throws java.lang.InterruptedException {
+ private int initSoundPool(int numStreams) throws java.lang.InterruptedException {
if (mSoundPool != null) {
- if (mLoadStatus == 0) return mLoadStatus;
+ if ((mMaxStreams == numStreams) && (mLoadStatus == 0)) return mLoadStatus;
mSoundPool.release();
mSoundPool = null;
}
// create sound pool
mLoadStatus = 0;
- mSoundPool = new SoundPool(MAX_STREAMS, AudioSystem.STREAM_MUSIC, 0);
+ mMaxStreams = numStreams;
+ mSoundPool = new SoundPool(numStreams, AudioSystem.STREAM_MUSIC, 0);
mSoundPool.setOnLoadCompleteListener(new LoadCompleteCallback());
int numSounds = mTestFiles.length;
mSounds = new int[numSounds];
@@ -262,6 +263,31 @@ public class SoundPoolTest extends Activity
mSoundPool.stop(id);
+ // play 5 sounds, forces one to be stolen
+ int ids[] = new int[5];
+ for (int i = 0; i < 5; i++) {
+ ids[i] = mSoundPool.play(mSounds[0], DEFAULT_VOLUME, DEFAULT_VOLUME,
+ NORMAL_PRIORITY, DEFAULT_LOOP, mScale[i]);
+ if (DEBUG) Log.d(LOG_TAG, "Start note " + ids[i]);
+ if (ids[i] == 0) {
+ Log.e(LOG_TAG, "Error occurred starting note");
+ return false;
+ }
+ sleep(250);
+ }
+
+ // pause and resume sound a few times
+ for (int count = 0; count < 5; count++) {
+ mSoundPool.autoPause();
+ sleep(250);
+ mSoundPool.autoResume();
+ sleep(250);
+ }
+
+ for (int i = 0; i < 5; i++) {
+ mSoundPool.stop(ids[i]);
+ }
+
if (DEBUG) Log.d(LOG_TAG, "End pause/resume test");
return result;
}
@@ -309,17 +335,18 @@ public class SoundPoolTest extends Activity
try {
- // load sound pool
- initSoundPool();
-
- // do tests
+ // do single stream tests
+ initSoundPool(1);
if (!TestSounds()) failures = failures + 1;
if (!TestScales()) failures = failures + 1;
if (!TestRates()) failures = failures + 1;
if (!TestPriority()) failures = failures + 1;
- if (!TestPauseResume()) failures = failures + 1;
if (!TestVolume()) failures = failures + 1;
+ // do multiple stream tests
+ initSoundPool(4);
+ if (!TestPauseResume()) failures = failures + 1;
+
} catch (java.lang.InterruptedException e) {
if (DEBUG) Log.d(LOG_TAG, "Test interrupted");
failures = failures + 1;
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/Base64.java b/mms-common/java/com/android/mmscommon/mms/pdu/Base64.java
deleted file mode 100644
index 4c95dec72dd0..000000000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/Base64.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * 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.mmscommon.mms.pdu;
-
-public class Base64 {
- /**
- * Used to get the number of Quadruples.
- */
- static final int FOURBYTE = 4;
-
- /**
- * Byte used to pad output.
- */
- static final byte PAD = (byte) '=';
-
- /**
- * The base length.
- */
- static final int BASELENGTH = 255;
-
- // Create arrays to hold the base64 characters
- private static byte[] base64Alphabet = new byte[BASELENGTH];
-
- // Populating the character arrays
- static {
- for (int i = 0; i < BASELENGTH; i++) {
- base64Alphabet[i] = (byte) -1;
- }
- for (int i = 'Z'; i >= 'A'; i--) {
- base64Alphabet[i] = (byte) (i - 'A');
- }
- for (int i = 'z'; i >= 'a'; i--) {
- base64Alphabet[i] = (byte) (i - 'a' + 26);
- }
- for (int i = '9'; i >= '0'; i--) {
- base64Alphabet[i] = (byte) (i - '0' + 52);
- }
-
- base64Alphabet['+'] = 62;
- base64Alphabet['/'] = 63;
- }
-
- /**
- * Decodes Base64 data into octects
- *
- * @param base64Data Byte array containing Base64 data
- * @return Array containing decoded data.
- */
- public static byte[] decodeBase64(byte[] base64Data) {
- // RFC 2045 requires that we discard ALL non-Base64 characters
- base64Data = discardNonBase64(base64Data);
-
- // handle the edge case, so we don't have to worry about it later
- if (base64Data.length == 0) {
- return new byte[0];
- }
-
- int numberQuadruple = base64Data.length / FOURBYTE;
- byte decodedData[] = null;
- byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0;
-
- // Throw away anything not in base64Data
-
- int encodedIndex = 0;
- int dataIndex = 0;
- {
- // this sizes the output array properly - rlw
- int lastData = base64Data.length;
- // ignore the '=' padding
- while (base64Data[lastData - 1] == PAD) {
- if (--lastData == 0) {
- return new byte[0];
- }
- }
- decodedData = new byte[lastData - numberQuadruple];
- }
-
- for (int i = 0; i < numberQuadruple; i++) {
- dataIndex = i * 4;
- marker0 = base64Data[dataIndex + 2];
- marker1 = base64Data[dataIndex + 3];
-
- b1 = base64Alphabet[base64Data[dataIndex]];
- b2 = base64Alphabet[base64Data[dataIndex + 1]];
-
- if (marker0 != PAD && marker1 != PAD) {
- //No PAD e.g 3cQl
- b3 = base64Alphabet[marker0];
- b4 = base64Alphabet[marker1];
-
- decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
- decodedData[encodedIndex + 1] =
- (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
- decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4);
- } else if (marker0 == PAD) {
- //Two PAD e.g. 3c[Pad][Pad]
- decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
- } else if (marker1 == PAD) {
- //One PAD e.g. 3cQ[Pad]
- b3 = base64Alphabet[marker0];
-
- decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
- decodedData[encodedIndex + 1] =
- (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
- }
- encodedIndex += 3;
- }
- return decodedData;
- }
-
- /**
- * Check octect wheter it is a base64 encoding.
- *
- * @param octect to be checked byte
- * @return ture if it is base64 encoding, false otherwise.
- */
- private static boolean isBase64(byte octect) {
- if (octect == PAD) {
- return true;
- } else if (base64Alphabet[octect] == -1) {
- return false;
- } else {
- return true;
- }
- }
-
- /**
- * Discards any characters outside of the base64 alphabet, per
- * the requirements on page 25 of RFC 2045 - "Any characters
- * outside of the base64 alphabet are to be ignored in base64
- * encoded data."
- *
- * @param data The base-64 encoded data to groom
- * @return The data, less non-base64 characters (see RFC 2045).
- */
- static byte[] discardNonBase64(byte[] data) {
- byte groomedData[] = new byte[data.length];
- int bytesCopied = 0;
-
- for (int i = 0; i < data.length; i++) {
- if (isBase64(data[i])) {
- groomedData[bytesCopied++] = data[i];
- }
- }
-
- byte packedData[] = new byte[bytesCopied];
-
- System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
-
- return packedData;
- }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/PduParser.java b/mms-common/java/com/android/mmscommon/mms/pdu/PduParser.java
index 9253f8373efb..6a58ba691b29 100644
--- a/mms-common/java/com/android/mmscommon/mms/pdu/PduParser.java
+++ b/mms-common/java/com/android/mmscommon/mms/pdu/PduParser.java
@@ -17,14 +17,15 @@
package com.android.mmscommon.mms.pdu;
-import com.android.mmscommon.ContentType;
import com.android.mmscommon.CharacterSets;
+import com.android.mmscommon.ContentType;
import com.android.mmscommon.EncodedStringValue;
import com.android.mmscommon.InvalidHeaderValueException;
import com.android.mmscommon.PduHeaders;
import android.util.Config;
import android.util.Log;
+import android.util.base64.Base64;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -790,7 +791,7 @@ public class PduParser {
String encoding = new String(partDataEncoding);
if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) {
// Decode "base64" into "binary".
- partData = Base64.decodeBase64(partData);
+ partData = Base64.decode(partData, Base64.DEFAULT);
} else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) {
// Decode "quoted-printable" into "binary".
partData = QuotedPrintable.decodeQuotedPrintable(partData);
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
index 4cacc1125f24..67d1ce70be1a 100644
--- a/opengl/libagl/copybit.cpp
+++ b/opengl/libagl/copybit.cpp
@@ -48,19 +48,8 @@ static void textureToCopyBitImage(
const GGLSurface* surface, int32_t opFormat,
android_native_buffer_t* buffer, copybit_image_t* img)
{
- uint32_t vstride = 0;
- if (opFormat == COPYBIT_FORMAT_YCbCr_422_SP ||
- opFormat == COPYBIT_FORMAT_YCbCr_420_SP) {
- // NOTE: this static_cast is really not safe b/c we can't know for
- // sure the buffer passed is of the right type.
- // However, since we do this only for YUV formats, we should be safe
- // since only SurfaceFlinger makes use of them.
- GraphicBuffer* graphicBuffer = static_cast<GraphicBuffer*>(buffer);
- vstride = graphicBuffer->getVerticalStride();
- }
-
img->w = surface->stride;
- img->h = vstride ? vstride : surface->height;
+ img->h = surface->height;
img->format = opFormat;
img->base = surface->data;
img->handle = (native_handle_t *)buffer->handle;
@@ -98,8 +87,6 @@ static bool supportedCopybitsFormat(int format) {
case COPYBIT_FORMAT_BGRA_8888:
case COPYBIT_FORMAT_RGBA_5551:
case COPYBIT_FORMAT_RGBA_4444:
- case COPYBIT_FORMAT_YCbCr_422_SP:
- case COPYBIT_FORMAT_YCbCr_420_SP:
return true;
default:
return false;
diff --git a/packages/DefaultContainerService/AndroidManifest.xml b/packages/DefaultContainerService/AndroidManifest.xml
index 5ec72df156f0..078daa76d501 100755
--- a/packages/DefaultContainerService/AndroidManifest.xml
+++ b/packages/DefaultContainerService/AndroidManifest.xml
@@ -6,6 +6,7 @@
<uses-permission android:name="android.permission.ASEC_DESTROY"/>
<uses-permission android:name="android.permission.ASEC_MOUNT_UNMOUNT"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM" />
<application android:label="@string/service_name">
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index c418ccbb9743..933a7e575045 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -1,22 +1,23 @@
package com.android.defcontainer;
import com.android.internal.app.IMediaContainerService;
-
+import com.android.internal.content.PackageHelper;
import android.content.Intent;
import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.content.pm.PackageParser.Package;
import android.net.Uri;
-import android.os.Debug;
import android.os.Environment;
import android.os.IBinder;
-import android.os.storage.IMountService;
-import android.os.storage.StorageResultCode;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.StatFs;
import android.app.IntentService;
-import android.app.Service;
+import android.util.DisplayMetrics;
import android.util.Log;
import java.io.File;
@@ -25,9 +26,9 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
import android.os.FileUtils;
+import android.provider.Settings;
/*
* This service copies a downloaded apk to a file passed in as
@@ -45,7 +46,7 @@ public class DefaultContainerService extends IntentService {
* Creates a new container and copies resource there.
* @param paackageURI the uri of resource to be copied. Can be either
* a content uri or a file uri
- * @param containerId the id of the secure container that should
+ * @param cid the id of the secure container that should
* be used for creating a secure container into which the resource
* will be copied.
* @param key Refers to key used for encrypting the secure container
@@ -55,12 +56,12 @@ public class DefaultContainerService extends IntentService {
*
*/
public String copyResourceToContainer(final Uri packageURI,
- final String containerId,
+ final String cid,
final String key, final String resFileName) {
- if (packageURI == null || containerId == null) {
+ if (packageURI == null || cid == null) {
return null;
}
- return copyResourceInner(packageURI, containerId, key, resFileName);
+ return copyResourceInner(packageURI, cid, key, resFileName);
}
/*
@@ -79,6 +80,44 @@ public class DefaultContainerService extends IntentService {
autoOut = new ParcelFileDescriptor.AutoCloseOutputStream(outStream);
return copyFile(packageURI, autoOut);
}
+
+ /*
+ * Determine the recommended install location for package
+ * specified by file uri location.
+ * @param fileUri the uri of resource to be copied. Should be a
+ * file uri
+ * @return Returns
+ * PackageHelper.RECOMMEND_INSTALL_INTERNAL to install on internal storage
+ * PackageHelper.RECOMMEND_INSTALL_EXTERNAL to install on external media
+ * PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE for storage errors
+ * PackageHelper.RECOMMEND_FAILED_INVALID_APK for parse errors.
+ */
+ public int getRecommendedInstallLocation(final Uri fileUri) {
+ if (!fileUri.getScheme().equals("file")) {
+ Log.w(TAG, "Falling back to installing on internal storage only");
+ return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
+ }
+ final String archiveFilePath = fileUri.getPath();
+ PackageParser packageParser = new PackageParser(archiveFilePath);
+ File sourceFile = new File(archiveFilePath);
+ DisplayMetrics metrics = new DisplayMetrics();
+ metrics.setToDefaults();
+ PackageParser.Package pkg = packageParser.parsePackage(sourceFile, archiveFilePath, metrics, 0);
+ if (pkg == null) {
+ Log.w(TAG, "Failed to parse package");
+ return PackageHelper.RECOMMEND_FAILED_INVALID_APK;
+ }
+ int loc = recommendAppInstallLocation(pkg);
+ if (loc == PackageManager.INSTALL_EXTERNAL) {
+ return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
+ } else if (loc == ERR_LOC) {
+ Log.i(TAG, "Failed to install insufficient storage");
+ return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
+ } else {
+ // Implies install on internal storage.
+ return 0;
+ }
+ }
};
public DefaultContainerService() {
@@ -111,7 +150,6 @@ public class DefaultContainerService extends IntentService {
}
}
}
- //Log.i(TAG, "Deleting: " + path);
path.delete();
}
@@ -119,13 +157,10 @@ public class DefaultContainerService extends IntentService {
return mBinder;
}
- private IMountService getMountService() {
- return IMountService.Stub.asInterface(ServiceManager.getService("mount"));
- }
-
- private String copyResourceInner(Uri packageURI, String newCacheId, String key, String resFileName) {
+ private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName) {
// Create new container at newCachePath
String codePath = packageURI.getPath();
+ File codeFile = new File(codePath);
String newCachePath = null;
final int CREATE_FAILED = 1;
final int COPY_FAILED = 2;
@@ -133,8 +168,9 @@ public class DefaultContainerService extends IntentService {
final int PASS = 4;
int errCode = CREATE_FAILED;
// Create new container
- if ((newCachePath = createSdDir(packageURI, newCacheId, key)) != null) {
- if (localLOGV) Log.i(TAG, "Created container for " + newCacheId
+ if ((newCachePath = PackageHelper.createSdDir(codeFile,
+ newCid, key, Process.myUid())) != null) {
+ if (localLOGV) Log.i(TAG, "Created container for " + newCid
+ " at path : " + newCachePath);
File resFile = new File(newCachePath, resFileName);
errCode = COPY_FAILED;
@@ -142,7 +178,8 @@ public class DefaultContainerService extends IntentService {
if (FileUtils.copyFile(new File(codePath), resFile)) {
if (localLOGV) Log.i(TAG, "Copied " + codePath + " to " + resFile);
errCode = FINALIZE_FAILED;
- if (finalizeSdDir(newCacheId)) {
+ if (PackageHelper.finalizeSdDir(newCid)) {
+ if (localLOGV) Log.i(TAG, "Finalized container " + newCid);
errCode = PASS;
}
}
@@ -155,21 +192,25 @@ public class DefaultContainerService extends IntentService {
break;
case COPY_FAILED:
errMsg = "COPY_FAILED";
- if (localLOGV) Log.i(TAG, "Destroying " + newCacheId +
+ if (localLOGV) Log.i(TAG, "Destroying " + newCid +
" at path " + newCachePath + " after " + errMsg);
- destroySdDir(newCacheId);
+ PackageHelper.destroySdDir(newCid);
break;
case FINALIZE_FAILED:
errMsg = "FINALIZE_FAILED";
- if (localLOGV) Log.i(TAG, "Destroying " + newCacheId +
+ if (localLOGV) Log.i(TAG, "Destroying " + newCid +
" at path " + newCachePath + " after " + errMsg);
- destroySdDir(newCacheId);
+ PackageHelper.destroySdDir(newCid);
break;
default:
errMsg = "PASS";
- if (localLOGV) Log.i(TAG, "Unmounting " + newCacheId +
- " at path " + newCachePath + " after " + errMsg);
- unMountSdDir(newCacheId);
+ if (PackageHelper.isContainerMounted(newCid)) {
+ if (localLOGV) Log.i(TAG, "Unmounting " + newCid +
+ " at path " + newCachePath + " after " + errMsg);
+ PackageHelper.unMountSdDir(newCid);
+ } else {
+ if (localLOGV) Log.i(TAG, "Container " + newCid + " not mounted");
+ }
break;
}
if (errCode != PASS) {
@@ -178,102 +219,6 @@ public class DefaultContainerService extends IntentService {
return newCachePath;
}
- private String createSdDir(final Uri packageURI,
- String containerId, String sdEncKey) {
- File tmpPackageFile = new File(packageURI.getPath());
- // Create mount point via MountService
- IMountService mountService = getMountService();
- long len = tmpPackageFile.length();
- int mbLen = (int) (len/(1024*1024));
- if ((len - (mbLen * 1024 * 1024)) > 0) {
- mbLen++;
- }
- if (localLOGV) Log.i(TAG, "mbLen=" + mbLen);
- String cachePath = null;
- int ownerUid = Process.myUid();
- try {
- int rc = mountService.createSecureContainer(
- containerId, mbLen, "vfat", sdEncKey, ownerUid);
-
- if (rc != StorageResultCode.OperationSucceeded) {
- Log.e(TAG, String.format("Container creation failed (%d)", rc));
-
- // XXX: This destroy should not be necessary
- rc = mountService.destroySecureContainer(containerId);
- if (rc != StorageResultCode.OperationSucceeded) {
- Log.e(TAG, String.format("Container creation-cleanup failed (%d)", rc));
- return null;
- }
-
- // XXX: Does this ever actually succeed?
- rc = mountService.createSecureContainer(
- containerId, mbLen, "vfat", sdEncKey, ownerUid);
- if (rc != StorageResultCode.OperationSucceeded) {
- Log.e(TAG, String.format("Container creation retry failed (%d)", rc));
- }
- }
-
- cachePath = mountService.getSecureContainerPath(containerId);
- if (localLOGV) Log.i(TAG, "Trying to create secure container for "
- + containerId + ", cachePath =" + cachePath);
- return cachePath;
- } catch(RemoteException e) {
- Log.e(TAG, "MountService not running?");
- return null;
- }
- }
-
- private boolean destroySdDir(String containerId) {
- try {
- // We need to destroy right away
- getMountService().destroySecureContainer(containerId);
- return true;
- } catch (IllegalStateException e) {
- Log.i(TAG, "Failed to destroy container : " + containerId);
- } catch(RemoteException e) {
- Log.e(TAG, "MountService not running?");
- }
- return false;
- }
-
- private boolean finalizeSdDir(String containerId){
- try {
- getMountService().finalizeSecureContainer(containerId);
- return true;
- } catch (IllegalStateException e) {
- Log.i(TAG, "Failed to finalize container for pkg : " + containerId);
- } catch(RemoteException e) {
- Log.e(TAG, "MountService not running?");
- }
- return false;
- }
-
- private boolean unMountSdDir(String containerId) {
- try {
- getMountService().unmountSecureContainer(containerId);
- return true;
- } catch (IllegalStateException e) {
- Log.e(TAG, "Failed to unmount id: " + containerId + " with exception " + e);
- } catch(RemoteException e) {
- Log.e(TAG, "MountService not running?");
- }
- return false;
- }
-
- private String mountSdDir(String containerId, String key) {
- try {
- int rc = getMountService().mountSecureContainer(containerId, key, Process.myUid());
- if (rc == StorageResultCode.OperationSucceeded) {
- return getMountService().getSecureContainerPath(containerId);
- } else {
- Log.e(TAG, String.format("Failed to mount id %s with rc %d ", containerId, rc));
- }
- } catch(RemoteException e) {
- Log.e(TAG, "MountService not running?");
- }
- return null;
- }
-
public static boolean copyToFile(InputStream inputStream, FileOutputStream out) {
try {
byte[] buffer = new byte[4096];
@@ -341,4 +286,103 @@ public class DefaultContainerService extends IntentService {
}
return true;
}
+
+ // Constants related to app heuristics
+ // No-installation limit for internal flash: 10% or less space available
+ private static final double LOW_NAND_FLASH_TRESHOLD = 0.1;
+
+ // SD-to-internal app size threshold: currently set to 1 MB
+ private static final long INSTALL_ON_SD_THRESHOLD = (1024 * 1024);
+ private static final int ERR_LOC = -1;
+
+ public int recommendAppInstallLocation(Package pkg) {
+ // Initial implementation:
+ // Package size = code size + cache size + data size
+ // If code size > 1 MB, install on SD card.
+ // Else install on internal NAND flash, unless space on NAND is less than 10%
+
+ if (pkg == null) {
+ return ERR_LOC;
+ }
+
+ StatFs internalFlashStats = new StatFs(Environment.getDataDirectory().getPath());
+ StatFs sdcardStats = new StatFs(Environment.getExternalStorageDirectory().getPath());
+
+ long totalInternalFlashSize = (long)internalFlashStats.getBlockCount() *
+ (long)internalFlashStats.getBlockSize();
+ long availInternalFlashSize = (long)internalFlashStats.getAvailableBlocks() *
+ (long)internalFlashStats.getBlockSize();
+ long availSDSize = (long)sdcardStats.getAvailableBlocks() *
+ (long)sdcardStats.getBlockSize();
+
+ double pctNandFree = (double)availInternalFlashSize / (double)totalInternalFlashSize;
+
+ final String archiveFilePath = pkg.mScanPath;
+ File apkFile = new File(archiveFilePath);
+ long pkgLen = apkFile.length();
+
+ boolean auto = true;
+ // To make final copy
+ long reqInstallSize = pkgLen;
+ // For dex files
+ long reqInternalSize = 1 * pkgLen;
+ boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD);
+ boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalFlashSize);
+ boolean fitsOnSd = (reqInstallSize < availSDSize) && intThresholdOk &&
+ (reqInternalSize < availInternalFlashSize);
+ boolean fitsOnInt = intThresholdOk && intAvailOk;
+
+ // Consider application flags preferences as well...
+ boolean installOnlyOnSd = (pkg.installLocation ==
+ PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+ boolean installOnlyInternal = (pkg.installLocation ==
+ PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+ if (installOnlyInternal) {
+ // If set explicitly in manifest,
+ // let that override everything else
+ auto = false;
+ } else if (installOnlyOnSd){
+ // Check if this can be accommodated on the sdcard
+ if (fitsOnSd) {
+ auto = false;
+ }
+ } else {
+ // Check if user option is enabled
+ boolean setInstallLoc = Settings.System.getInt(getApplicationContext()
+ .getContentResolver(),
+ Settings.System.SET_INSTALL_LOCATION, 0) != 0;
+ if (setInstallLoc) {
+ // Pick user preference
+ int installPreference = Settings.System.getInt(getApplicationContext()
+ .getContentResolver(),
+ Settings.System.DEFAULT_INSTALL_LOCATION,
+ PackageInfo.INSTALL_LOCATION_AUTO);
+ if (installPreference == 1) {
+ installOnlyInternal = true;
+ auto = false;
+ } else if (installPreference == 2) {
+ installOnlyOnSd = true;
+ auto = false;
+ }
+ }
+ }
+ if (!auto) {
+ if (installOnlyOnSd) {
+ return fitsOnSd ? PackageManager.INSTALL_EXTERNAL : ERR_LOC;
+ } else if (installOnlyInternal){
+ // Check on internal flash
+ return fitsOnInt ? 0 : ERR_LOC;
+ }
+ }
+ // Try to install internally
+ if (fitsOnInt) {
+ return 0;
+ }
+ // Try the sdcard now.
+ if (fitsOnSd) {
+ return PackageManager.INSTALL_EXTERNAL;
+ }
+ // Return error code
+ return ERR_LOC;
+ }
}
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index a54251828e34..c92b9d7fb564 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -2,8 +2,6 @@
package="com.android.providers.settings"
android:sharedUserId="android.uid.system">
- <uses-permission android:name="android.permission.BACKUP_DATA" />
-
<application android:allowClearUserData="false"
android:label="@string/app_label"
android:process="system"
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index ba6024f8005c..654ca32eaaa4 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -58,4 +58,16 @@
<bool name="def_mount_ums_notify_enabled">true</bool>
<bool name="set_install_location">true</bool>
+ <!-- user interface sound effects -->
+ <integer name="def_power_sounds_enabled">1</integer>
+ <string name="def_low_battery_sound">/system/media/ui/LowBattery.ogg</string>
+ <integer name="def_dock_sounds_enabled">1</integer>
+ <string name="def_desk_dock_sound">/system/media/audio/ui/dock.ogg</string>
+ <string name="def_desk_undock_sound">/system/media/audio/ui/undock.ogg</string>
+ <string name="def_car_dock_sound">/system/media/audio/ui/Dock.ogg</string>
+ <string name="def_car_undock_sound">/system/media/audio/ui/Undock.ogg</string>
+ <integer name="def_lockscreen_sounds_enabled">1</integer>
+ <string name="def_lock_sound">/system/media/audio/ui/Lock.ogg</string>
+ <string name="def_unlock_sound">/system/media/audio/ui/Unlock.ogg</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 b26607f4a18f..cf34d4e2f59c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -76,7 +76,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
// is properly propagated through your change. Not doing so will result in a loss of user
// settings.
- private static final int DATABASE_VERSION = 49;
+ private static final int DATABASE_VERSION = 50;
private Context mContext;
@@ -600,7 +600,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
upgradeVersion = 47;
}
-
+
if (upgradeVersion == 47) {
/*
* The password mode constants have changed again; reset back to no
@@ -615,7 +615,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
}
upgradeVersion = 48;
}
-
+
if (upgradeVersion == 48) {
/*
* Adding a new setting for which voice recognition service to use.
@@ -633,6 +633,24 @@ public class DatabaseHelper extends SQLiteOpenHelper {
upgradeVersion = 49;
}
+ if (upgradeVersion == 49) {
+ /*
+ * New settings for new user interface noises.
+ */
+ db.beginTransaction();
+ try {
+ SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+ + " VALUES(?,?);");
+ loadUISoundEffectsSettings(stmt);
+ stmt.close();
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+
+ upgradeVersion = 50;
+ }
+
if (upgradeVersion != currentVersion) {
Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion
+ ", must wipe the settings provider");
@@ -648,6 +666,11 @@ public class DatabaseHelper extends SQLiteOpenHelper {
db.execSQL("DROP INDEX IF EXISTS bookmarksIndex2");
db.execSQL("DROP TABLE IF EXISTS favorites");
onCreate(db);
+
+ // Added for diagnosing settings.db wipes after the fact
+ String wipeReason = oldVersion + "/" + upgradeVersion + "/" + currentVersion;
+ db.execSQL("INSERT INTO secure(name,value) values('" +
+ "wiped_db_reason" + "','" + wipeReason + "');");
}
}
@@ -889,9 +912,37 @@ public class DatabaseHelper extends SQLiteOpenHelper {
loadBooleanSetting(stmt, Settings.System.SET_INSTALL_LOCATION, R.bool.set_install_location);
loadSetting(stmt, Settings.System.DEFAULT_INSTALL_LOCATION,
PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+
+ loadUISoundEffectsSettings(stmt);
+
stmt.close();
}
+ private void loadUISoundEffectsSettings(SQLiteStatement stmt) {
+ loadIntegerSetting(stmt, Settings.System.POWER_SOUNDS_ENABLED,
+ R.integer.def_power_sounds_enabled);
+ loadStringSetting(stmt, Settings.System.LOW_BATTERY_SOUND,
+ R.string.def_low_battery_sound);
+
+ loadIntegerSetting(stmt, Settings.System.DOCK_SOUNDS_ENABLED,
+ R.integer.def_dock_sounds_enabled);
+ loadStringSetting(stmt, Settings.System.DESK_DOCK_SOUND,
+ R.string.def_desk_dock_sound);
+ loadStringSetting(stmt, Settings.System.DESK_UNDOCK_SOUND,
+ R.string.def_desk_undock_sound);
+ loadStringSetting(stmt, Settings.System.CAR_DOCK_SOUND,
+ R.string.def_car_dock_sound);
+ loadStringSetting(stmt, Settings.System.CAR_UNDOCK_SOUND,
+ R.string.def_car_undock_sound);
+
+ loadIntegerSetting(stmt, Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
+ R.integer.def_lockscreen_sounds_enabled);
+ loadStringSetting(stmt, Settings.System.LOCK_SOUND,
+ R.string.def_lock_sound);
+ loadStringSetting(stmt, Settings.System.UNLOCK_SOUND,
+ R.string.def_unlock_sound);
+ }
+
private void loadDefaultAnimationSettings(SQLiteStatement stmt) {
loadFractionSetting(stmt, Settings.System.WINDOW_ANIMATION_SCALE,
R.fraction.def_window_animation_scale, 1);
@@ -976,7 +1027,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
R.bool.def_mount_ums_notify_enabled);
-
+
loadVoiceRecognitionServiceSetting(stmt);
stmt.close();
@@ -989,7 +1040,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
loadStringSetting(stmt, Settings.Secure.BACKUP_TRANSPORT,
R.string.def_backup_transport);
}
-
+
/**
* Introduced in database version 49.
*/
@@ -999,19 +1050,19 @@ public class DatabaseHelper extends SQLiteOpenHelper {
mContext.getPackageManager().queryIntentServices(
new Intent(RecognitionService.SERVICE_INTERFACE), 0);
int numAvailable = availableRecognitionServices.size();
-
+
if (numAvailable == 0) {
Log.w(TAG, "no available voice recognition services found");
} else {
if (numAvailable > 1) {
Log.w(TAG, "more than one voice recognition service found, picking first");
}
-
+
ServiceInfo serviceInfo = availableRecognitionServices.get(0).serviceInfo;
selectedService =
new ComponentName(serviceInfo.packageName, serviceInfo.name).flattenToString();
}
-
+
loadSetting(stmt, Settings.Secure.VOICE_RECOGNITION_SERVICE,
selectedService == null ? "" : selectedService);
}
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 27055edadfe1..d43039d97eff 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -896,9 +896,7 @@ class BackupManagerService extends IBackupManager.Stub {
try {
ApplicationInfo app = pkg.applicationInfo;
if (((app.flags&ApplicationInfo.FLAG_ALLOW_BACKUP) == 0)
- || app.backupAgentName == null
- || (mPackageManager.checkPermission(android.Manifest.permission.BACKUP_DATA,
- pkg.packageName) != PackageManager.PERMISSION_GRANTED)) {
+ || app.backupAgentName == null) {
packages.remove(a);
}
else {
@@ -1085,15 +1083,11 @@ class BackupManagerService extends IBackupManager.Stub {
synchronized(mClearDataLock) {
mClearingData = true;
- /* This is causing some critical processes to be killed during setup.
- Temporarily revert this change until we find a better solution.
try {
mActivityManager.clearApplicationUserData(packageName, observer);
} catch (RemoteException e) {
// can't happen because the activity manager is in this process
}
- */
- mPackageManager.clearApplicationUserData(packageName, observer);
// only wait 10 seconds for the clear data to happen
long timeoutMark = System.currentTimeMillis() + TIMEOUT_INTERVAL;
@@ -1282,15 +1276,6 @@ class BackupManagerService extends IBackupManager.Stub {
for (BackupRequest request : mQueue) {
Log.d(TAG, "starting agent for backup of " + request);
- // Don't run backup, even if requested, if the target app does not have
- // the requisite permission
- if (mPackageManager.checkPermission(android.Manifest.permission.BACKUP_DATA,
- request.appInfo.packageName) != PackageManager.PERMISSION_GRANTED) {
- Log.w(TAG, "Skipping backup of unprivileged package "
- + request.appInfo.packageName);
- continue;
- }
-
IBackupAgent agent = null;
int mode = (request.fullBackup)
? IApplicationThread.BACKUP_MODE_FULL
@@ -1671,10 +1656,6 @@ class BackupManagerService extends IBackupManager.Stub {
+ "] is compatible with installed version ["
+ packageInfo.versionCode + "]");
- // Now perform the actual restore: first clear the app's data
- // if appropriate
- clearApplicationDataSynchronous(packageName);
-
// Then set up and bind the agent (with a restricted Application object
// unless the application says otherwise)
boolean useRealApp = (packageInfo.applicationInfo.flags
@@ -1760,12 +1741,6 @@ class BackupManagerService extends IBackupManager.Stub {
if (DEBUG) Log.d(TAG, "processOneRestore packageName=" + packageName);
- // Don't restore to unprivileged packages
- if (mPackageManager.checkPermission(android.Manifest.permission.BACKUP_DATA,
- packageName) != PackageManager.PERMISSION_GRANTED) {
- Log.d(TAG, "Skipping restore of unprivileged package " + packageName);
- }
-
// !!! TODO: get the dirs from the transport
File backupDataName = new File(mDataDir, packageName + ".restore");
File newStateName = new File(mStateDir, packageName + ".new");
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 42590160d99a..108246daa1b9 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -798,6 +798,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
"ConnectivityService");
}
+ private void enforceTetherAccessPermission() {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.ACCESS_NETWORK_STATE,
+ "ConnectivityService");
+ }
+
/**
* Handle a {@code DISCONNECTED} event. If this pertains to the non-active
* network, we ignore it. If it is for the active network, we send out a
@@ -1289,6 +1295,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
pw.println(requester.toString());
}
pw.println();
+
+ mTethering.dump(fd, pw, args);
}
// must be stateless - things change under us.
@@ -1386,24 +1394,54 @@ public class ConnectivityService extends IConnectivityManager.Stub {
// javadoc from interface
public boolean tether(String iface) {
enforceTetherChangePermission();
- return mTethering.tether(iface);
+ return isTetheringSupported() && mTethering.tether(iface);
}
// javadoc from interface
public boolean untether(String iface) {
enforceTetherChangePermission();
- return mTethering.untether(iface);
+ return isTetheringSupported() && mTethering.untether(iface);
+ }
+
+ // TODO - proper iface API for selection by property, inspection, etc
+ public String[] getTetherableUsbRegexs() {
+ enforceTetherAccessPermission();
+ if (isTetheringSupported()) {
+ return mTethering.getTetherableUsbRegexs();
+ } else {
+ return new String[0];
+ }
+ }
+
+ public String[] getTetherableWifiRegexs() {
+ enforceTetherAccessPermission();
+ if (isTetheringSupported()) {
+ return mTethering.getTetherableWifiRegexs();
+ } else {
+ return new String[0];
+ }
}
// TODO - move iface listing, queries, etc to new module
// javadoc from interface
public String[] getTetherableIfaces() {
- enforceAccessPermission();
+ enforceTetherAccessPermission();
return mTethering.getTetherableIfaces();
}
public String[] getTetheredIfaces() {
- enforceAccessPermission();
+ enforceTetherAccessPermission();
return mTethering.getTetheredIfaces();
}
+
+ // if ro.tether.denied = true we default to no tethering
+ // gservices could set the secure setting to 1 though to enable it on a build where it
+ // had previously been turned off.
+ public boolean isTetheringSupported() {
+ enforceTetherAccessPermission();
+ int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
+ return ((Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0) &&
+ (mNetTrackers[ConnectivityManager.TYPE_MOBILE_DUN] != null));
+ }
}
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index c90736876ee8..d2804750059b 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -26,10 +26,14 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Binder;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
@@ -60,8 +64,11 @@ class DockObserver extends UEventObserver {
public static final int MODE_NIGHT_YES = Configuration.UI_MODE_NIGHT_YES >> 4;
private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
+ private int mPreviousDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
+
private int mNightMode = MODE_NIGHT_NO;
private boolean mCarModeEnabled = false;
+
private boolean mSystemReady;
private final Context mContext;
@@ -129,7 +136,7 @@ class DockObserver extends UEventObserver {
try {
int newState = Integer.parseInt(event.get("SWITCH_STATE"));
if (newState != mDockState) {
- int oldState = mDockState;
+ mPreviousDockState = mDockState;
mDockState = newState;
boolean carModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
if (mCarModeEnabled != carModeEnabled) {
@@ -143,8 +150,8 @@ class DockObserver extends UEventObserver {
// Don't force screen on when undocking from the desk dock.
// The change in power state will do this anyway.
// FIXME - we should be configurable.
- if (oldState != Intent.EXTRA_DOCK_STATE_DESK ||
- newState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+ if (mPreviousDockState != Intent.EXTRA_DOCK_STATE_DESK ||
+ mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
mPowerManager.userActivityWithForce(SystemClock.uptimeMillis(),
false, true);
}
@@ -163,7 +170,7 @@ class DockObserver extends UEventObserver {
try {
FileReader file = new FileReader(DOCK_STATE_PATH);
int len = file.read(buffer, 0, 1024);
- mDockState = Integer.valueOf((new String(buffer, 0, len)).trim());
+ mPreviousDockState = mDockState = Integer.valueOf((new String(buffer, 0, len)).trim());
} catch (FileNotFoundException e) {
Log.w(TAG, "This kernel does not have dock station support");
@@ -195,7 +202,10 @@ class DockObserver extends UEventObserver {
public void handleMessage(Message msg) {
synchronized (this) {
Log.i(TAG, "Dock state changed: " + mDockState);
- if (Settings.Secure.getInt(mContext.getContentResolver(),
+
+ final ContentResolver cr = mContext.getContentResolver();
+
+ if (Settings.Secure.getInt(cr,
Settings.Secure.DEVICE_PROVISIONED, 0) == 0) {
Log.i(TAG, "Device not provisioned, skipping dock broadcast");
return;
@@ -217,6 +227,38 @@ class DockObserver extends UEventObserver {
intent.putExtra(BluetoothDevice.EXTRA_DEVICE,
BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address));
+ // User feedback to confirm dock connection. Particularly
+ // useful for flaky contact pins...
+ if (Settings.System.getInt(cr,
+ Settings.System.DOCK_SOUNDS_ENABLED, 1) == 1)
+ {
+ String whichSound = null;
+ if (mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+ if (mPreviousDockState == Intent.EXTRA_DOCK_STATE_DESK) {
+ whichSound = Settings.System.DESK_UNDOCK_SOUND;
+ } else if (mPreviousDockState == Intent.EXTRA_DOCK_STATE_CAR) {
+ whichSound = Settings.System.CAR_UNDOCK_SOUND;
+ }
+ } else {
+ if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) {
+ whichSound = Settings.System.DESK_DOCK_SOUND;
+ } else if (mDockState == Intent.EXTRA_DOCK_STATE_CAR) {
+ whichSound = Settings.System.CAR_DOCK_SOUND;
+ }
+ }
+
+ if (whichSound != null) {
+ final String soundPath = Settings.System.getString(cr, whichSound);
+ if (soundPath != null) {
+ final Uri soundUri = Uri.parse("file://" + soundPath);
+ if (soundUri != null) {
+ final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
+ if (sfx != null) sfx.play();
+ }
+ }
+ }
+ }
+
// Send the ordered broadcast; the result receiver will receive after all
// broadcasts have been sent. If any broadcast receiver changes the result
// code from the initial value of RESULT_OK, then the result receiver will
diff --git a/services/java/com/android/server/FallbackCheckinService.java b/services/java/com/android/server/FallbackCheckinService.java
deleted file mode 100644
index 195eb63aea42..000000000000
--- a/services/java/com/android/server/FallbackCheckinService.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Binder;
-import android.os.ICheckinService;
-import android.os.IParentalControlCallback;
-import android.os.RecoverySystem;
-import android.util.Log;
-
-import java.io.IOException;
-
-import com.google.android.net.ParentalControlState;
-
-/**
- * @hide
- */
-public final class FallbackCheckinService extends ICheckinService.Stub {
- static final String TAG = "FallbackCheckinService";
- final Context mContext;
-
- public FallbackCheckinService(Context context) {
- mContext = context;
- }
-
- public void getParentalControlState(IParentalControlCallback p, String requestingApp)
- throws android.os.RemoteException {
- ParentalControlState state = new ParentalControlState();
- state.isEnabled = false;
- p.onResult(state);
- }
-}
diff --git a/services/java/com/android/server/InputDevice.java b/services/java/com/android/server/InputDevice.java
index 6f207e0ff8b9..d3bb6dc4a9d0 100644
--- a/services/java/com/android/server/InputDevice.java
+++ b/services/java/com/android/server/InputDevice.java
@@ -570,14 +570,14 @@ public class InputDevice {
mDownTime = curTime;
} else {
action = MotionEvent.ACTION_POINTER_DOWN
- | (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
+ | (upOrDownPointer << MotionEvent.ACTION_POINTER_INDEX_SHIFT);
}
} else {
if (numPointers == 1) {
action = MotionEvent.ACTION_UP;
} else {
action = MotionEvent.ACTION_POINTER_UP
- | (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
+ | (upOrDownPointer << MotionEvent.ACTION_POINTER_INDEX_SHIFT);
}
}
currentMove = null;
diff --git a/services/java/com/android/server/MasterClearReceiver.java b/services/java/com/android/server/MasterClearReceiver.java
index ab0eb813682f..0417e7182b00 100644
--- a/services/java/com/android/server/MasterClearReceiver.java
+++ b/services/java/com/android/server/MasterClearReceiver.java
@@ -30,7 +30,7 @@ public class MasterClearReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_REMOTE_INTENT)) {
- if (!intent.getBooleanExtra("android.intent.extra.from_trusted_server", false)) {
+ if (!"google.com".equals(intent.getStringExtra("from"))) {
Log.w(TAG, "Ignoring master clear request -- not from trusted server.");
return;
}
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index e764bbbe7af0..4e2ffa4f696b 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -80,6 +80,7 @@ class MountService extends IMountService.Stub
*/
public static final int VolumeListResult = 110;
public static final int AsecListResult = 111;
+ public static final int StorageUsersListResult = 112;
/*
* 200 series - Requestion action has been successfully completed.
@@ -795,6 +796,31 @@ class MountService extends IMountService.Stub
return doFormatVolume(path);
}
+ public int []getStorageUsers(String path) {
+ validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
+ waitForReady();
+ try {
+ String[] r = mConnector.doListCommand(
+ String.format("storage users %s", path),
+ VoldResponseCode.StorageUsersListResult);
+ // FMT: <pid> <process name>
+ int[] data = new int[r.length];
+ for (int i = 0; i < r.length; i++) {
+ String []tok = r[i].split(" ");
+ try {
+ data[i] = Integer.parseInt(tok[0]);
+ } catch (NumberFormatException nfe) {
+ Log.e(TAG, String.format("Error parsing pid %s", tok[0]));
+ return new int[0];
+ }
+ }
+ return data;
+ } catch (NativeDaemonConnectorException e) {
+ Log.e(TAG, "Failed to retrieve storage users list", e);
+ return new int[0];
+ }
+ }
+
private void warnOnNotMounted() {
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Log.w(TAG, "getSecureContainerList() called when storage not mounted");
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index a5213a02fd9f..4326efcdcefb 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -20,6 +20,7 @@ import com.android.internal.app.IMediaContainerService;
import com.android.internal.app.ResolverActivity;
import com.android.common.FastXmlSerializer;
import com.android.common.XmlUtils;
+import com.android.internal.content.PackageHelper;
import com.android.server.JournaledFile;
import org.xmlpull.v1.XmlPullParser;
@@ -304,6 +305,7 @@ class PackageManagerService extends IPackageManager.Stub {
static final int INIT_COPY = 5;
static final int MCS_UNBIND = 6;
static final int START_CLEANING_PACKAGE = 7;
+ static final int FIND_INSTALL_LOC = 8;
// Delay time in millisecs
static final int BROADCAST_DELAY = 10 * 1000;
private ServiceConnection mDefContainerConn = new ServiceConnection() {
@@ -319,8 +321,8 @@ class PackageManagerService extends IPackageManager.Stub {
};
class PackageHandler extends Handler {
- final ArrayList<InstallArgs> mPendingInstalls =
- new ArrayList<InstallArgs>();
+ final ArrayList<InstallParams> mPendingInstalls =
+ new ArrayList<InstallParams>();
// Service Connection to remote media container service to copy
// package uri's from external media onto secure containers
// or internal storage.
@@ -332,21 +334,20 @@ class PackageManagerService extends IPackageManager.Stub {
public void handleMessage(Message msg) {
switch (msg.what) {
case INIT_COPY: {
- InstallArgs args = (InstallArgs) msg.obj;
- args.createCopyFile();
+ InstallParams params = (InstallParams) msg.obj;
Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
if (mContainerService != null) {
// No need to add to pending list. Use remote stub directly
- handleStartCopy(args);
+ handleStartCopy(params);
} else {
if (mContext.bindService(service, mDefContainerConn,
Context.BIND_AUTO_CREATE)) {
- mPendingInstalls.add(args);
+ mPendingInstalls.add(params);
} else {
Log.e(TAG, "Failed to bind to media container service");
// Indicate install failure TODO add new error code
- processPendingInstall(args,
- PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE);
+ processPendingInstall(createInstallArgs(params),
+ PackageManager.INSTALL_FAILED_INTERNAL_ERROR);
}
}
break;
@@ -357,9 +358,9 @@ class PackageManagerService extends IPackageManager.Stub {
mContainerService = (IMediaContainerService) msg.obj;
}
if (mPendingInstalls.size() > 0) {
- InstallArgs args = mPendingInstalls.remove(0);
- if (args != null) {
- handleStartCopy(args);
+ InstallParams params = mPendingInstalls.remove(0);
+ if (params != null) {
+ handleStartCopy(params);
}
}
break;
@@ -423,22 +424,56 @@ class PackageManagerService extends IPackageManager.Stub {
// Utility method to initiate copying apk via media
// container service.
- private void handleStartCopy(InstallArgs args) {
- int ret = PackageManager.INSTALL_SUCCEEDED;
- if (mContainerService == null) {
- // Install error
- ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
- } else {
- ret = args.copyApk(mContainerService);
+ private void handleStartCopy(InstallParams params) {
+ int ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+ if (mContainerService != null) {
+ // Remote call to find out default install location
+ int loc = params.getInstallLocation(mContainerService);
+ // Use install location to create InstallArgs and temporary
+ // install location
+ if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE){
+ ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+ } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
+ ret = PackageManager.INSTALL_FAILED_INVALID_APK;
+ } else {
+ if ((params.flags & PackageManager.INSTALL_EXTERNAL) == 0){
+ if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
+ // Set the flag to install on external media.
+ params.flags |= PackageManager.INSTALL_EXTERNAL;
+ } else {
+ // Make sure the flag for installing on external
+ // media is unset
+ params.flags &= ~PackageManager.INSTALL_EXTERNAL;
+ }
+ }
+ // Disable forward locked apps on sdcard.
+ if ((params.flags & PackageManager.INSTALL_FORWARD_LOCK) != 0 &&
+ (params.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
+ // Make sure forward locked apps can only be installed
+ // on internal storage
+ Log.w(TAG, "Cannot install protected apps on sdcard");
+ ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
+ } else {
+ ret = PackageManager.INSTALL_SUCCEEDED;
+ }
+ }
}
mHandler.sendEmptyMessage(MCS_UNBIND);
+ // Create the file args now.
+ InstallArgs args = createInstallArgs(params);
+ if (ret == PackageManager.INSTALL_SUCCEEDED) {
+ // Create copy only if we are not in an erroneous state.
+ args.createCopyFile();
+ // Remote call to initiate copy
+ ret = args.copyApk(mContainerService);
+ }
processPendingInstall(args, ret);
}
}
static boolean installOnSd(int flags) {
if (((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) ||
- ((flags & PackageManager.INSTALL_ON_SDCARD) == 0)) {
+ ((flags & PackageManager.INSTALL_EXTERNAL) == 0)) {
return false;
}
return true;
@@ -2145,10 +2180,15 @@ class PackageManagerService extends IPackageManager.Stub {
int i;
for (i=0; i<files.length; i++) {
File file = new File(dir, files[i]);
+ if (files[i] != null && files[i].endsWith(".zip")) {
+ // Public resource for forward locked package. Ignore
+ continue;
+ }
PackageParser.Package pkg = scanPackageLI(file,
flags|PackageParser.PARSE_MUST_BE_APK, scanMode);
// Don't mess around with apps in system partition.
- if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0) {
+ if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
+ mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) {
// Delete the apk
Log.w(TAG, "Cleaning up failed install of " + file);
file.delete();
@@ -4249,29 +4289,11 @@ class PackageManagerService extends IPackageManager.Stub {
android.Manifest.permission.INSTALL_PACKAGES, null);
Message msg = mHandler.obtainMessage(INIT_COPY);
- msg.obj = createInstallArgs(packageURI, observer, flags, installerPackageName);
+ msg.obj = new InstallParams(packageURI, observer, flags,
+ installerPackageName);
mHandler.sendMessage(msg);
}
- private InstallArgs createInstallArgs(Uri packageURI, IPackageInstallObserver observer,
- int flags, String installerPackageName) {
- if (installOnSd(flags)) {
- return new SdInstallArgs(packageURI, observer, flags,
- installerPackageName);
- } else {
- return new FileInstallArgs(packageURI, observer, flags,
- installerPackageName);
- }
- }
-
- private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath) {
- if (installOnSd(flags)) {
- return new SdInstallArgs(fullCodePath, fullResourcePath);
- } else {
- return new FileInstallArgs(fullCodePath, fullResourcePath);
- }
- }
-
private void processPendingInstall(final InstallArgs args, final int currentStatus) {
// Queue up an async operation since the package installation may take a little while.
mHandler.post(new Runnable() {
@@ -4327,6 +4349,45 @@ class PackageManagerService extends IPackageManager.Stub {
});
}
+ static final class InstallParams {
+ final IPackageInstallObserver observer;
+ int flags;
+ final Uri packageURI;
+ final String installerPackageName;
+ InstallParams(Uri packageURI,
+ IPackageInstallObserver observer, int flags,
+ String installerPackageName) {
+ this.packageURI = packageURI;
+ this.flags = flags;
+ this.observer = observer;
+ this.installerPackageName = installerPackageName;
+ }
+
+ public int getInstallLocation(IMediaContainerService imcs) {
+ try {
+ return imcs.getRecommendedInstallLocation(packageURI);
+ } catch (RemoteException e) {
+ }
+ return -1;
+ }
+ };
+
+ private InstallArgs createInstallArgs(InstallParams params) {
+ if (installOnSd(params.flags)) {
+ return new SdInstallArgs(params);
+ } else {
+ return new FileInstallArgs(params);
+ }
+ }
+
+ private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath) {
+ if (installOnSd(flags)) {
+ return new SdInstallArgs(fullCodePath, fullResourcePath);
+ } else {
+ return new FileInstallArgs(fullCodePath, fullResourcePath);
+ }
+ }
+
static abstract class InstallArgs {
final IPackageInstallObserver observer;
final int flags;
@@ -4359,10 +4420,9 @@ class PackageManagerService extends IPackageManager.Stub {
String codeFileName;
String resourceFileName;
- FileInstallArgs(Uri packageURI,
- IPackageInstallObserver observer, int flags,
- String installerPackageName) {
- super(packageURI, observer, flags, installerPackageName);
+ FileInstallArgs(InstallParams params) {
+ super(params.packageURI, params.observer,
+ params.flags, params.installerPackageName);
}
FileInstallArgs(String fullCodePath, String fullResourcePath) {
@@ -4373,6 +4433,10 @@ class PackageManagerService extends IPackageManager.Stub {
resourceFileName = fullResourcePath;
}
+ String getCodePath() {
+ return codeFileName;
+ }
+
void createCopyFile() {
boolean fwdLocked = isFwdLocked(flags);
installDir = fwdLocked ? mDrmAppPrivateInstallDir : mAppInstallDir;
@@ -4380,10 +4444,6 @@ class PackageManagerService extends IPackageManager.Stub {
resourceFileName = getResourcePathFromCodePath();
}
- String getCodePath() {
- return codeFileName;
- }
-
int copyApk(IMediaContainerService imcs) {
// Get a ParcelFileDescriptor to write to the output file
File codeFile = new File(codeFileName);
@@ -4528,10 +4588,9 @@ class PackageManagerService extends IPackageManager.Stub {
String cachePath;
static final String RES_FILE_NAME = "pkg.apk";
- SdInstallArgs(Uri packageURI,
- IPackageInstallObserver observer, int flags,
- String installerPackageName) {
- super(packageURI, observer, flags, installerPackageName);
+ SdInstallArgs(InstallParams params) {
+ super(params.packageURI, params.observer,
+ params.flags, params.installerPackageName);
}
SdInstallArgs(String fullCodePath, String fullResourcePath) {
@@ -4577,13 +4636,11 @@ class PackageManagerService extends IPackageManager.Stub {
int doPreInstall(int status) {
if (status != PackageManager.INSTALL_SUCCEEDED) {
// Destroy container
- destroySdDir(cid);
+ PackageHelper.destroySdDir(cid);
} else {
- // STOPSHIP Remove once new api is added in MountService
- //boolean mounted = isContainerMounted(cid);
- boolean mounted = false;
+ boolean mounted = PackageHelper.isContainerMounted(cid);
if (!mounted) {
- cachePath = mountSdDir(cid, Process.SYSTEM_UID);
+ cachePath = PackageHelper.mountSdDir(cid, getEncryptKey(), Process.SYSTEM_UID);
if (cachePath == null) {
return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
}
@@ -4596,96 +4653,41 @@ class PackageManagerService extends IPackageManager.Stub {
String oldCodePath) {
String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME);
String newCachePath = null;
- /*final int RENAME_FAILED = 1;
+ final int RENAME_FAILED = 1;
final int MOUNT_FAILED = 2;
- final int DESTROY_FAILED = 3;
final int PASS = 4;
int errCode = RENAME_FAILED;
+ String errMsg = "RENAME_FAILED";
+ boolean mounted = PackageHelper.isContainerMounted(cid);
if (mounted) {
// Unmount the container
- if (!unMountSdDir(cid)) {
+ if (!PackageHelper.unMountSdDir(cid)) {
Log.i(TAG, "Failed to unmount " + cid + " before renaming");
return false;
}
mounted = false;
}
- if (renameSdDir(cid, newCacheId)) {
+ if (PackageHelper.renameSdDir(cid, newCacheId)) {
errCode = MOUNT_FAILED;
- if ((newCachePath = mountSdDir(newCacheId, Process.SYSTEM_UID)) != null) {
+ errMsg = "MOUNT_FAILED";
+ if ((newCachePath = PackageHelper.mountSdDir(newCacheId,
+ getEncryptKey(), Process.SYSTEM_UID)) != null) {
errCode = PASS;
- }
- }
- String errMsg = "";
- switch (errCode) {
- case RENAME_FAILED:
- errMsg = "RENAME_FAILED";
- break;
- case MOUNT_FAILED:
- errMsg = "MOUNT_FAILED";
- break;
- case DESTROY_FAILED:
- errMsg = "DESTROY_FAILED";
- break;
- default:
errMsg = "PASS";
- break;
- }
- Log.i(TAG, "Status: " + errMsg);
- if (errCode != PASS) {
- return false;
- }
- Log.i(TAG, "Succesfully renamed " + cid + " to " +newCacheId +
- " at path: " + cachePath + " to new path: " + newCachePath);
- cid = newCacheId;
- cachePath = newCachePath;
- return true;
- */
- // STOPSHIP TEMPORARY HACK FOR RENAME
- // Create new container at newCachePath
- String codePath = getCodePath();
- final int CREATE_FAILED = 1;
- final int COPY_FAILED = 3;
- final int FINALIZE_FAILED = 5;
- final int PASS = 7;
- int errCode = CREATE_FAILED;
-
- if ((newCachePath = createSdDir(new File(codePath), newCacheId)) != null) {
- errCode = COPY_FAILED;
- // Copy file from codePath
- if (FileUtils.copyFile(new File(codePath), new File(newCachePath, RES_FILE_NAME))) {
- errCode = FINALIZE_FAILED;
- if (finalizeSdDir(newCacheId)) {
- errCode = PASS;
- }
- }
- }
- // Print error based on errCode
- String errMsg = "";
- switch (errCode) {
- case CREATE_FAILED:
- errMsg = "CREATE_FAILED";
- break;
- case COPY_FAILED:
- errMsg = "COPY_FAILED";
- destroySdDir(newCacheId);
- break;
- case FINALIZE_FAILED:
- errMsg = "FINALIZE_FAILED";
- destroySdDir(newCacheId);
- break;
- default:
- errMsg = "PASS";
- break;
+ }
}
- // Destroy the temporary container
- destroySdDir(cid);
- Log.i(TAG, "Status: " + errMsg);
if (errCode != PASS) {
+ Log.i(TAG, "Failed to rename " + cid + " to " + newCacheId +
+ " at path: " + cachePath + " to new path: " + newCachePath +
+ "err = " + errMsg);
+ // Mount old container?
return false;
+ } else {
+ Log.i(TAG, "Succesfully renamed " + cid + " to " + newCacheId +
+ " at path: " + cachePath + " to new path: " + newCachePath);
}
cid = newCacheId;
cachePath = newCachePath;
-
return true;
}
@@ -4693,11 +4695,10 @@ class PackageManagerService extends IPackageManager.Stub {
if (status != PackageManager.INSTALL_SUCCEEDED) {
cleanUp();
} else {
- // STOP SHIP Change this once new api is added.
- //boolean mounted = isContainerMounted(cid);
- boolean mounted = false;
+ boolean mounted = PackageHelper.isContainerMounted(cid);
if (!mounted) {
- mountSdDir(cid, Process.SYSTEM_UID);
+ PackageHelper.mountSdDir(cid,
+ getEncryptKey(), Process.myUid());
}
}
return status;
@@ -4705,7 +4706,7 @@ class PackageManagerService extends IPackageManager.Stub {
private void cleanUp() {
// Destroy secure container
- destroySdDir(cid);
+ PackageHelper.destroySdDir(cid);
}
void cleanUpResourcesLI() {
@@ -4740,10 +4741,10 @@ class PackageManagerService extends IPackageManager.Stub {
boolean doPostDeleteLI(boolean delete) {
boolean ret = false;
- boolean mounted = isContainerMounted(cid);
+ boolean mounted = PackageHelper.isContainerMounted(cid);
if (mounted) {
// Unmount first
- ret = unMountSdDir(cid);
+ ret = PackageHelper.unMountSdDir(cid);
}
if (ret && delete) {
cleanUpResourcesLI();
@@ -5105,7 +5106,7 @@ class PackageManagerService extends IPackageManager.Stub {
String installerPackageName = args.installerPackageName;
File tmpPackageFile = new File(args.getCodePath());
boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
- boolean onSd = ((pFlags & PackageManager.INSTALL_ON_SDCARD) != 0);
+ boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0);
boolean replace = false;
int scanMode = SCAN_MONITOR | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE
| (newInstall ? SCAN_NEW_INSTALL : 0);
@@ -5136,14 +5137,6 @@ class PackageManagerService extends IPackageManager.Stub {
res.returnCode = pp.getParseError();
return;
}
- // Some preinstall checks
- if (forwardLocked && onSd) {
- // Make sure forward locked apps can only be installed
- // on internal storage
- Log.w(TAG, "Cannot install protected apps on sdcard");
- res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
- return;
- }
// Get rid of all references to package scan path via parser.
pp = null;
String oldCodePath = null;
@@ -5560,7 +5553,7 @@ class PackageManagerService extends IPackageManager.Stub {
if (deleteCodeAndResources) {
// TODO can pick up from PackageSettings as well
int installFlags = ((p.applicationInfo.flags & ApplicationInfo.FLAG_ON_SDCARD)!=0) ?
- PackageManager.INSTALL_ON_SDCARD : 0;
+ PackageManager.INSTALL_EXTERNAL : 0;
installFlags |= ((p.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK)!=0) ?
PackageManager.INSTALL_FORWARD_LOCK : 0;
outInfo.args = createInstallArgs(installFlags,
@@ -8544,11 +8537,6 @@ class PackageManagerService extends IPackageManager.Stub {
private boolean mMediaMounted = false;
private static final int MAX_CONTAINERS = 250;
-
- static MountService getMountService() {
- return (MountService) ServiceManager.getService("mount");
- }
-
private String getEncryptKey() {
try {
String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(mSdEncryptKey);
@@ -8567,134 +8555,10 @@ class PackageManagerService extends IPackageManager.Stub {
}
}
- private String createSdDir(File tmpPackageFile, String pkgName) {
- // Create mount point via MountService
- MountService mountService = getMountService();
- long len = tmpPackageFile.length();
- int mbLen = (int) (len/(1024*1024));
- if ((len - (mbLen * 1024 * 1024)) > 0) {
- mbLen++;
- }
- if (DEBUG_SD_INSTALL) Log.i(TAG, "mbLen="+mbLen);
- String cachePath = null;
- String sdEncKey;
- try {
- sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(mSdEncryptKey);
- if (sdEncKey == null) {
- sdEncKey = SystemKeyStore.getInstance().
- generateNewKeyHexString(128, mSdEncryptAlg, mSdEncryptKey);
- if (sdEncKey == null) {
- Log.e(TAG, "Failed to create encryption keys for package: " + pkgName + ".");
- return null;
- }
- }
- } catch (NoSuchAlgorithmException nsae) {
- Log.e(TAG, "Failed to create encryption keys with exception: " + nsae);
- return null;
- }
-
- int rc = mountService.createSecureContainer(
- pkgName, mbLen, "vfat", sdEncKey, Process.SYSTEM_UID);
- if (rc != StorageResultCode.OperationSucceeded) {
- Log.e(TAG, String.format("Failed to create container (%d)", rc));
-
- rc = mountService.destroySecureContainer(pkgName);
- if (rc != StorageResultCode.OperationSucceeded) {
- Log.e(TAG, String.format("Failed to cleanup container (%d)", rc));
- return null;
- }
- rc = mountService.createSecureContainer(
- pkgName, mbLen, "vfat", sdEncKey, Process.SYSTEM_UID);
- if (rc != StorageResultCode.OperationSucceeded) {
- Log.e(TAG, String.format("Failed to create container (2nd try) (%d)", rc));
- return null;
- }
- }
-
- cachePath = mountService.getSecureContainerPath(pkgName);
- if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to install " + pkgName + ", cachePath =" + cachePath);
- return cachePath;
- }
-
- private String mountSdDir(String pkgName, int ownerUid) {
- String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(mSdEncryptKey);
- if (sdEncKey == null) {
- Log.e(TAG, "Failed to retrieve encryption keys to mount package code: " + pkgName + ".");
- return null;
- }
-
- int rc = getMountService().mountSecureContainer(pkgName, sdEncKey, ownerUid);
-
- if (rc != StorageResultCode.OperationSucceeded) {
- Log.i(TAG, "Failed to mount container for pkg : " + pkgName + " rc : " + rc);
- return null;
- }
-
- return getMountService().getSecureContainerPath(pkgName);
- }
-
- private boolean unMountSdDir(String pkgName) {
- // STOPSHIP unmount directory
- int rc = getMountService().unmountSecureContainer(pkgName);
- if (rc != StorageResultCode.OperationSucceeded) {
- Log.e(TAG, "Failed to unmount : " + pkgName + " with rc " + rc);
- return false;
- }
- return true;
- }
-
- private boolean renameSdDir(String oldId, String newId) {
- try {
- getMountService().renameSecureContainer(oldId, newId);
- return true;
- } catch (IllegalStateException e) {
- Log.i(TAG, "Failed ot rename " + oldId + " to " + newId +
- " with exception : " + e);
- }
- return false;
- }
-
- private String getSdDir(String pkgName) {
- return getMountService().getSecureContainerPath(pkgName);
- }
-
- private boolean finalizeSdDir(String pkgName) {
- int rc = getMountService().finalizeSecureContainer(pkgName);
- if (rc != StorageResultCode.OperationSucceeded) {
- Log.i(TAG, "Failed to finalize container for pkg : " + pkgName);
- return false;
- }
- return true;
- }
-
- private boolean destroySdDir(String pkgName) {
- int rc = getMountService().destroySecureContainer(pkgName);
- if (rc != StorageResultCode.OperationSucceeded) {
- Log.i(TAG, "Failed to destroy container for pkg : " + pkgName);
- return false;
- }
- return true;
- }
-
- static String[] getSecureContainerList() {
- String[] list = getMountService().getSecureContainerList();
- return list.length == 0 ? null : list;
- }
-
- static boolean isContainerMounted(String cid) {
- // STOPSHIP
- // New api from MountService
- try {
- return (getMountService().getSecureContainerPath(cid) != null);
- } catch (IllegalStateException e) {
- }
- return false;
- }
-
static String getTempContainerId() {
String prefix = "smdl1tmp";
int tmpIdx = 1;
- String list[] = getSecureContainerList();
+ String list[] = PackageHelper.getSecureContainerList();
if (list != null) {
int idx = 0;
int idList[] = new int[MAX_CONTAINERS];
@@ -8753,7 +8617,7 @@ class PackageManagerService extends IPackageManager.Stub {
}
void updateExternalMediaStatusInner(boolean mediaStatus) {
- final String list[] = getSecureContainerList();
+ final String list[] = PackageHelper.getSecureContainerList();
if (list == null || list.length == 0) {
return;
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 6e9c21bde0b0..a09896a2b367 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -22,6 +22,7 @@ import com.android.internal.os.BinderInternal;
import com.android.internal.os.SamplingProfilerIntegration;
import dalvik.system.VMRuntime;
+import dalvik.system.Zygote;
import android.app.ActivityManagerNative;
import android.bluetooth.BluetoothAdapter;
@@ -329,19 +330,6 @@ class ServerThread extends Thread {
}
try {
- Log.i(TAG, "Checkin Service");
- Intent intent = new Intent().setComponent(new ComponentName(
- "com.google.android.server.checkin",
- "com.google.android.server.checkin.CheckinService"));
- if (context.startService(intent) == null) {
- Log.w(TAG, "Using fallback Checkin Service.");
- ServiceManager.addService("checkin", new FallbackCheckinService(context));
- }
- } catch (Throwable e) {
- Log.e(TAG, "Failure starting Checkin Service", e);
- }
-
- try {
Log.i(TAG, "Wallpaper Service");
wallpaper = new WallpaperManagerService(context);
ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
@@ -409,8 +397,15 @@ class ServerThread extends Thread {
if (safeMode) {
try {
ActivityManagerNative.getDefault().enterSafeMode();
+ // Post the safe mode state in the Zygote class
+ Zygote.systemInSafeMode = true;
+ // Disable the JIT for the system_server process
+ VMRuntime.getRuntime().disableJitCompilation();
} catch (RemoteException e) {
}
+ } else {
+ // Enable the JIT for the system_server process
+ VMRuntime.getRuntime().startJitCompilation();
}
// It is now time to start up the app processes...
@@ -532,7 +527,6 @@ public class SystemServer
// 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);
- VMRuntime.getRuntime().startJitCompilation();
System.loadLibrary("android_servers");
init1(args);
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index b5e652085821..7fcf900231c6 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -1773,6 +1773,32 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ void dispatchPointerElsewhereLocked(WindowState srcWin, WindowState relWin,
+ MotionEvent pointer, long eventTime, boolean skipped) {
+ if (relWin != null) {
+ mPolicy.dispatchedPointerEventLw(pointer, relWin.mFrame.left, relWin.mFrame.top);
+ } else {
+ mPolicy.dispatchedPointerEventLw(pointer, 0, 0);
+ }
+
+ // If we sent an initial down to the wallpaper, then continue
+ // sending events until the final up.
+ if (mSendingPointersToWallpaper) {
+ if (skipped) {
+ Log.i(TAG, "Sending skipped pointer to wallpaper!");
+ }
+ sendPointerToWallpaperLocked(relWin, pointer, eventTime);
+
+ // If we are on top of the wallpaper, then the wallpaper also
+ // gets to see this movement.
+ } else if (srcWin != null
+ && pointer.getAction() == MotionEvent.ACTION_DOWN
+ && mWallpaperTarget == srcWin
+ && srcWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
+ sendPointerToWallpaperLocked(relWin, pointer, eventTime);
+ }
+ }
+
public int addWindow(Session session, IWindow client,
WindowManager.LayoutParams attrs, int viewVisibility,
Rect outContentInsets) {
@@ -4918,10 +4944,7 @@ public class WindowManagerService extends IWindowManager.Stub
Log.w(TAG, "No window to dispatch pointer action " + ev.getAction());
}
synchronized (mWindowMap) {
- if (mSendingPointersToWallpaper) {
- Log.i(TAG, "Sending skipped pointer to wallpaper!");
- sendPointerToWallpaperLocked(null, ev, ev.getEventTime());
- }
+ dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
}
if (qev != null) {
mQueue.recycleEvent(qev);
@@ -4931,10 +4954,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (targetObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
synchronized (mWindowMap) {
- if (mSendingPointersToWallpaper) {
- Log.i(TAG, "Sending skipped pointer to wallpaper!");
- sendPointerToWallpaperLocked(null, ev, ev.getEventTime());
- }
+ dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
}
if (qev != null) {
mQueue.recycleEvent(qev);
@@ -5059,9 +5079,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (!target.isVisibleLw()) {
// During this motion dispatch, the target window has become
// invisible.
- if (mSendingPointersToWallpaper) {
- sendPointerToWallpaperLocked(null, ev, eventTime);
- }
+ dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), false);
if (qev != null) {
mQueue.recycleEvent(qev);
}
@@ -5094,13 +5112,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- // If we are on top of the wallpaper, then the wallpaper also
- // gets to see this movement.
- if ((mWallpaperTarget == target &&
- target.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD)
- || mSendingPointersToWallpaper) {
- sendPointerToWallpaperLocked(null, ev, eventTime);
- }
+ dispatchPointerElsewhereLocked(target, null, ev, ev.getEventTime(), false);
final Rect frame = target.mFrame;
ev.offsetLocation(-(float)frame.left, -(float)frame.top);
@@ -6031,11 +6043,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (res != null && returnWhat == RETURN_PENDING_POINTER) {
synchronized (mWindowMap) {
- if ((mWallpaperTarget == win &&
- win.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD)
- || mSendingPointersToWallpaper) {
- sendPointerToWallpaperLocked(win, res, res.getEventTime());
- }
+ dispatchPointerElsewhereLocked(win, win, res, res.getEventTime(), false);
}
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d0f6a7c03b57..3ecfd8a1b635 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1940,7 +1940,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
}
- if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0) {
+ // Run the app in safe mode if its manifest requests so or the
+ // system is booted in safe mode.
+ if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
+ Zygote.systemInSafeMode == true) {
debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
}
if ("1".equals(SystemProperties.get("debug.checkjni"))) {
@@ -9493,7 +9496,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
String[] newArgs;
String componentNameString;
ServiceRecord r;
- if (opti <= args.length) {
+ if (opti >= args.length) {
componentNameString = null;
newArgs = EMPTY_STRING_ARRAY;
r = null;
@@ -13463,6 +13466,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
app.hidden = false;
}
}
+ // If we have let the service slide into the background
+ // state, still have some text describing what it is doing
+ // even though the service no longer has an impact.
+ if (adj > SECONDARY_SERVER_ADJ) {
+ app.adjType = "started-bg-services";
+ }
}
if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
|| schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
@@ -13853,6 +13862,15 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
mAdjSeq++;
+ // Let's determine how many processes we have running vs.
+ // how many slots we have for background processes; we may want
+ // to put multiple processes in a slot of there are enough of
+ // them.
+ int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
+ int factor = (mLruProcesses.size()-4)/numSlots;
+ if (factor < 1) factor = 1;
+ int step = 0;
+
// First try updating the OOM adjustment for each of the
// application processes based on their current state.
int i = mLruProcesses.size();
@@ -13864,7 +13882,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
if (curHiddenAdj < EMPTY_APP_ADJ
&& app.curAdj == curHiddenAdj) {
- curHiddenAdj++;
+ step++;
+ if (step >= factor) {
+ step = 0;
+ curHiddenAdj++;
+ }
}
} else {
didOomAdj = false;
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index f6853839a66f..1d200749fd6c 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -24,19 +24,37 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.ConnectivityManager;
+import android.net.IConnectivityManager;
import android.net.INetworkManagementEventObserver;
+import android.net.NetworkInfo;
+import android.os.Binder;
import android.os.IBinder;
import android.os.INetworkManagementService;
+import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
import android.util.Log;
+import com.android.internal.telephony.Phone;
+import com.android.internal.util.HierarchicalState;
+import com.android.internal.util.HierarchicalStateMachine;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Set;
/**
* @hide
+ *
+ * Timeout
+ * TODO - review error states - they currently are dead-ends with no recovery possible
+ *
+ * TODO - look for parent classes and code sharing
*/
public class Tethering extends INetworkManagementEventObserver.Stub {
@@ -46,13 +64,24 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
private boolean mPlaySounds = false;
- private ArrayList<String> mAvailableIfaces;
- private ArrayList<String> mActiveIfaces;
+ // TODO - remove both of these - should be part of interface inspection/selection stuff
+ private String[] mTetherableUsbRegexs;
+ private String[] mTetherableWifiRegexs;
+
+ private HashMap<String, TetherInterfaceSM> mIfaces;
private ArrayList<String> mActiveTtys;
private BroadcastReceiver mStateReceiver;
+ private String[] mDhcpRange;
+
+ private String[] mDnsServers;
+
+ private String mUpstreamIfaceName;
+
+ HierarchicalStateMachine mTetherMasterSM;
+
public Tethering(Context context) {
Log.d(TAG, "Tethering starting");
mContext = context;
@@ -66,212 +95,234 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
Log.e(TAG, "Error registering observer :" + e);
}
- mAvailableIfaces = new ArrayList<String>();
- mActiveIfaces = new ArrayList<String>();
+ mIfaces = new HashMap<String, TetherInterfaceSM>();
mActiveTtys = new ArrayList<String>();
+ mTetherMasterSM = new TetherMasterSM("TetherMaster");
+ mTetherMasterSM.start();
+
// TODO - remove this hack after real USB connections are detected.
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_UMS_DISCONNECTED);
filter.addAction(Intent.ACTION_UMS_CONNECTED);
- mStateReceiver = new UMSStateReceiver();
+ filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ mStateReceiver = new StateReceiver();
mContext.registerReceiver(mStateReceiver, filter);
+
+ mDhcpRange = context.getResources().getStringArray(
+ com.android.internal.R.array.config_tether_dhcp_range);
+ if (mDhcpRange.length == 0) {
+ mDhcpRange = new String[2];
+ mDhcpRange[0] = new String("169.254.2.1");
+ mDhcpRange[1] = new String("169.254.2.64");
+ } else if(mDhcpRange.length == 1) {
+ String[] tmp = new String[2];
+ tmp[0] = mDhcpRange[0];
+ tmp[1] = new String("");
+ mDhcpRange = tmp;
+ }
+
+ mTetherableUsbRegexs = context.getResources().getStringArray(
+ com.android.internal.R.array.config_tether_usb_regexs);
+ mTetherableWifiRegexs = context.getResources().getStringArray(
+ com.android.internal.R.array.config_tether_wifi_regexs);
+
+ String[] ifaces = new String[0];
+ try {
+ ifaces = service.listInterfaces();
+ } catch (Exception e) {
+ Log.e(TAG, "Error listing Interfaces :" + e);
+ }
+ for (String iface : ifaces) {
+ interfaceAdded(iface);
+ }
+
+ // TODO - remove and rely on real notifications of the current iface
+ mDnsServers = new String[2];
+ mDnsServers[0] = "8.8.8.8";
+ mDnsServers[1] = "4.2.2.2";
+ mUpstreamIfaceName = "rmnet0";
}
- public synchronized void interfaceLinkStatusChanged(String iface, boolean link) {
+ public void interfaceLinkStatusChanged(String iface, boolean link) {
Log.d(TAG, "interfaceLinkStatusChanged " + iface + ", " + link);
+ boolean found = false;
+ for (String regex : mTetherableWifiRegexs) {
+ if (iface.matches(regex)) {
+ found = true;
+ break;
+ }
+ }
+ for (String regex: mTetherableUsbRegexs) {
+ if (iface.matches(regex)) {
+ found = true;
+ break;
+ }
+ }
+ if (found == false) return;
+
+ synchronized (mIfaces) {
+ TetherInterfaceSM sm = mIfaces.get(iface);
+ if (link) {
+ if (sm == null) {
+ sm = new TetherInterfaceSM(iface);
+ mIfaces.put(iface, sm);
+ sm.start();
+ }
+ } else {
+ if (sm != null) {
+ sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN));
+ mIfaces.remove(iface);
+ }
+ }
+ }
}
- public synchronized void interfaceAdded(String iface) {
- if (mActiveIfaces.contains(iface)) {
- Log.e(TAG, "active iface (" + iface + ") reported as added, ignoring");
- return;
+ public void interfaceAdded(String iface) {
+ boolean found = false;
+ for (String regex : mTetherableWifiRegexs) {
+ if (iface.matches(regex)) {
+ found = true;
+ break;
+ }
+ }
+ for (String regex : mTetherableUsbRegexs) {
+ if (iface.matches(regex)) {
+ found = true;
+ break;
+ }
}
- if (mAvailableIfaces.contains(iface)) {
- Log.e(TAG, "available iface (" + iface + ") readded, ignoring");
+ if (found == false) {
+ Log.d(TAG, iface + " is not a tetherable iface, ignoring");
return;
}
- mAvailableIfaces.add(iface);
+ synchronized (mIfaces) {
+ TetherInterfaceSM sm = mIfaces.get(iface);
+ if (sm != null) {
+ Log.e(TAG, "active iface (" + iface + ") reported as added, ignoring");
+ return;
+ }
+ sm = new TetherInterfaceSM(iface);
+ mIfaces.put(iface, sm);
+ sm.start();
+ }
Log.d(TAG, "interfaceAdded :" + iface);
- sendTetherStateChangedBroadcast();
}
- public synchronized void interfaceRemoved(String iface) {
- if (mActiveIfaces.contains(iface)) {
- Log.d(TAG, "removed an active iface (" + iface + ")");
- untether(iface);
- }
- if (mAvailableIfaces.contains(iface)) {
- mAvailableIfaces.remove(iface);
- Log.d(TAG, "interfaceRemoved " + iface);
- sendTetherStateChangedBroadcast();
+ public void interfaceRemoved(String iface) {
+ synchronized (mIfaces) {
+ TetherInterfaceSM sm = mIfaces.get(iface);
+ if (sm == null) {
+ Log.e(TAG, "attempting to remove unknown iface (" + iface + "), ignoring");
+ return;
+ }
+ sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN));
+ mIfaces.remove(iface);
}
}
- public synchronized boolean tether(String iface) {
+ public boolean tether(String iface) {
Log.d(TAG, "Tethering " + iface);
-
- if (!mAvailableIfaces.contains(iface)) {
- Log.e(TAG, "Tried to Tether an unavailable iface :" + iface + ", ignoring");
- return false;
+ TetherInterfaceSM sm = null;
+ synchronized (mIfaces) {
+ sm = mIfaces.get(iface);
}
- if (mActiveIfaces.contains(iface)) {
- Log.e(TAG, "Tried to Tether an already Tethered iface :" + iface + ", ignoring");
+ if (sm == null) {
+ Log.e(TAG, "Tried to Tether an unknown iface :" + iface + ", ignoring");
return false;
}
-
- IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
- INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
-
- if (mActiveIfaces.size() == 0) {
- try {
- service.setIpForwardingEnabled(true);
- } catch (Exception e) {
- Log.e(TAG, "Error in setIpForwardingEnabled(true) :" + e);
- return false;
- }
-
- try {
- // TODO - don't hardcode this - though with non-conf values (un-routable)
- // maybe it's not a big deal
- service.startTethering("169.254.2.1", "169.254.2.64");
- } catch (Exception e) {
- Log.e(TAG, "Error in startTethering :" + e);
- try {
- service.setIpForwardingEnabled(false);
- } catch (Exception ee) {}
- return false;
- }
-
- try {
- // TODO - maybe use the current connection's dns servers for this
- String[] dns = new String[2];
- dns[0] = new String("8.8.8.8");
- dns[1] = new String("4.2.2.2");
- service.setDnsForwarders(dns);
- } catch (Exception e) {
- Log.e(TAG, "Error in setDnsForwarders :" + e);
- try {
- service.stopTethering();
- } catch (Exception ee) {}
- try {
- service.setIpForwardingEnabled(false);
- } catch (Exception ee) {}
- }
- }
-
- try {
- service.tetherInterface(iface);
- } catch (Exception e) {
- Log.e(TAG, "Error in tetherInterface :" + e);
- if (mActiveIfaces.size() == 0) {
- try {
- service.stopTethering();
- } catch (Exception ee) {}
- try {
- service.setIpForwardingEnabled(false);
- } catch (Exception ee) {}
- }
+ if (sm.isErrored()) {
+ Log.e(TAG, "Tried to Tether to an errored iface :" + iface + ", ignoring");
return false;
}
-
- try {
- // TODO - use the currently active external iface
- service.enableNat (iface, "rmnet0");
- } catch (Exception e) {
- Log.e(TAG, "Error in enableNat :" + e);
- try {
- service.untetherInterface(iface);
- } catch (Exception ee) {}
- if (mActiveIfaces.size() == 0) {
- try {
- service.stopTethering();
- } catch (Exception ee) {}
- try {
- service.setIpForwardingEnabled(false);
- } catch (Exception ee) {}
- }
+ if (!sm.isAvailable()) {
+ Log.e(TAG, "Tried to Tether an unavailable iface :" + iface + ", ignoring");
return false;
}
- mAvailableIfaces.remove(iface);
- mActiveIfaces.add(iface);
- Log.d(TAG, "Tethered " + iface);
- sendTetherStateChangedBroadcast();
+ sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_REQUESTED));
return true;
}
- public synchronized boolean untether(String iface) {
+ public boolean untether(String iface) {
Log.d(TAG, "Untethering " + iface);
-
- if (mAvailableIfaces.contains(iface)) {
- Log.e(TAG, "Tried to Untether an available iface :" + iface);
+ TetherInterfaceSM sm = null;
+ synchronized (mIfaces) {
+ sm = mIfaces.get(iface);
+ }
+ if (sm == null) {
+ Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring");
return false;
}
- if (!mActiveIfaces.contains(iface)) {
- Log.e(TAG, "Tried to Untether an inactive iface :" + iface);
+ if (sm.isErrored()) {
+ Log.e(TAG, "Tried to Untethered an errored iface :" + iface + ", ignoring");
return false;
}
+ sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_UNREQUESTED));
+ return true;
+ }
- IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
- INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
-
- // none of these errors are recoverable - ie, multiple calls won't help
- // and the user can't do anything. Basically a reboot is required and probably
- // the device is misconfigured or something bad has happend.
- // Because of this, we should try to unroll as much state as we can.
- try {
- service.disableNat(iface, "rmnet0");
- } catch (Exception e) {
- Log.e(TAG, "Error in disableNat :" + e);
- }
+ private void sendTetherStateChangedBroadcast() {
+ IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+ IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
try {
- service.untetherInterface(iface);
- } catch (Exception e) {
- Log.e(TAG, "Error untethering " + iface + ", :" + e);
+ if (!service.isTetheringSupported()) return;
+ } catch (RemoteException e) {
+ return;
}
- mActiveIfaces.remove(iface);
- mAvailableIfaces.add(iface);
- if (mActiveIfaces.size() == 0) {
- Log.d(TAG, "no active tethers - turning down dhcp/ipforward");
- try {
- service.stopTethering();
- } catch (Exception e) {
- Log.e(TAG, "Error in stopTethering :" + e);
- }
- try {
- service.setIpForwardingEnabled(false);
- } catch (Exception e) {
- Log.e(TAG, "Error in setIpForwardingEnabled(false) :" + e);
+ ArrayList<String> availableList = new ArrayList<String>();
+ ArrayList<String> activeList = new ArrayList<String>();
+ ArrayList<String> erroredList = new ArrayList<String>();
+
+ synchronized (mIfaces) {
+ Set ifaces = mIfaces.keySet();
+ for (Object iface : ifaces) {
+ TetherInterfaceSM sm = mIfaces.get(iface);
+ if (sm != null) {
+ if(sm.isErrored()) {
+ erroredList.add((String)iface);
+ } else if (sm.isAvailable()) {
+ availableList.add((String)iface);
+ } else if (sm.isTethered()) {
+ activeList.add((String)iface);
+ }
+ }
}
}
- sendTetherStateChangedBroadcast();
- Log.d(TAG, "Untethered " + iface);
- return true;
- }
-
- private void sendTetherStateChangedBroadcast() {
Intent broadcast = new Intent(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
broadcast.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- broadcast.putExtra(ConnectivityManager.EXTRA_AVAILABLE_TETHER_COUNT,
- mAvailableIfaces.size());
- broadcast.putExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER_COUNT, mActiveIfaces.size());
- mContext.sendBroadcast(broadcast);
-
- // for USB we only have the one, so don't have to deal with additional
- if (mAvailableIfaces.size() > 0) {
- // Check if the user wants to be bothered
- boolean tellUser = (Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.TETHER_NOTIFY, 0) == 1);
-
- if (tellUser) {
- showTetherAvailableNotification();
- }
- } else if (mActiveIfaces.size() > 0) {
- showTetheredNotification();
- } else {
- clearNotification();
+ broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_AVAILABLE_TETHER,
+ availableList);
+ broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER, activeList);
+ broadcast.putStringArrayListExtra(ConnectivityManager.EXTRA_ERRORED_TETHER,
+ erroredList);
+ mContext.sendStickyBroadcast(broadcast);
+
+ // check if we need to send a USB notification
+ // Check if the user wants to be bothered
+ boolean tellUser = (Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.TETHER_NOTIFY, 0) == 1);
+ for (Object o : activeList) {
+ String s = (String)o;
+ for (Object regexObject : mTetherableUsbRegexs) {
+ if (s.matches((String)regexObject)) {
+ showTetheredNotification();
+ return;
+ }
+ }
+ }
+ if (tellUser) {
+ for (Object o : availableList) {
+ String s = (String)o;
+ for (Object matchObject : mTetherableUsbRegexs) {
+ if (s.matches((String)matchObject)) {
+ showTetherAvailableNotification();
+ return;
+ }
+ }
+ }
}
+ clearNotification();
}
private void showTetherAvailableNotification() {
@@ -280,7 +331,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
if (notificationManager == null) {
return;
}
-
Intent intent = new Intent();
intent.setClass(mContext, com.android.internal.app.TetherActivity.class);
@@ -367,18 +417,32 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
-// TODO - remove this hack after we get proper USB detection
- private class UMSStateReceiver extends BroadcastReceiver {
+ private class StateReceiver extends BroadcastReceiver {
public void onReceive(Context content, Intent intent) {
- if (intent.getAction().equals(Intent.ACTION_UMS_CONNECTED)) {
+ String action = intent.getAction();
+ if (action.equals(Intent.ACTION_UMS_CONNECTED)) {
Tethering.this.handleTtyConnect();
- } else if (intent.getAction().equals(Intent.ACTION_UMS_DISCONNECTED)) {
+ } else if (action.equals(Intent.ACTION_UMS_DISCONNECTED)) {
Tethering.this.handleTtyDisconnect();
+ } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
+ IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+ IConnectivityManager service =
+ IConnectivityManager.Stub.asInterface(b);
+ try {
+ NetworkInfo info = service.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_DUN);
+ int msg;
+ if (info != null && info.isConnected() == true) {
+ msg = TetherMasterSM.CMD_CELL_DUN_ENABLED;
+ } else {
+ msg = TetherMasterSM.CMD_CELL_DUN_DISABLED;
+ }
+ mTetherMasterSM.sendMessage(mTetherMasterSM.obtainMessage(msg));
+ } catch (RemoteException e) {}
}
}
}
- private synchronized void handleTtyConnect() {
+ private void handleTtyConnect() {
Log.d(TAG, "handleTtyConnect");
// for each of the available Tty not already supported by a ppp session,
// create a ppp session
@@ -461,23 +525,950 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
}
}
- public synchronized String[] getTetheredIfaces() {
- int size = mActiveIfaces.size();
- String[] result = new String[size];
- size -= 1;
- for (int i=0; i< size; i++) {
- result[i] = mActiveIfaces.get(i);
+ public String[] getTetherableUsbRegexs() {
+ return mTetherableUsbRegexs;
+ }
+
+ public String[] getTetherableWifiRegexs() {
+ return mTetherableWifiRegexs;
+ }
+
+ public String[] getTetheredIfaces() {
+ ArrayList<String> list = new ArrayList<String>();
+ synchronized (mIfaces) {
+ Set keys = mIfaces.keySet();
+ for (Object key : keys) {
+ TetherInterfaceSM sm = mIfaces.get(key);
+ if (sm.isTethered()) {
+ list.add((String)key);
+ }
+ }
+ }
+ String[] retVal = new String[list.size()];
+ for (int i=0; i < list.size(); i++) {
+ retVal[i] = list.get(i);
+ }
+ return retVal;
+ }
+
+ public String[] getTetherableIfaces() {
+ ArrayList<String> list = new ArrayList<String>();
+ synchronized (mIfaces) {
+ Set keys = mIfaces.keySet();
+ for (Object key : keys) {
+ TetherInterfaceSM sm = mIfaces.get(key);
+ if (sm.isAvailable()) {
+ list.add((String)key);
+ }
+ }
+ }
+ String[] retVal = new String[list.size()];
+ for (int i=0; i < list.size(); i++) {
+ retVal[i] = list.get(i);
+ }
+ return retVal;
+ }
+
+
+ class TetherInterfaceSM extends HierarchicalStateMachine {
+ // notification from the master SM that it's in tether mode
+ static final int CMD_TETHER_MODE_ALIVE = 1;
+ // notification from the master SM that it's not in tether mode
+ static final int CMD_TETHER_MODE_DEAD = 2;
+ // request from the user that it wants to tether
+ static final int CMD_TETHER_REQUESTED = 3;
+ // request from the user that it wants to untether
+ static final int CMD_TETHER_UNREQUESTED = 4;
+ // notification that this interface is down
+ static final int CMD_INTERFACE_DOWN = 5;
+ // notification that this interface is up
+ static final int CMD_INTERFACE_UP = 6;
+ // notification from the master SM that it had an error turning on cellular dun
+ static final int CMD_CELL_DUN_ERROR = 10;
+ // notification from the master SM that it had trouble enabling IP Forwarding
+ static final int CMD_IP_FORWARDING_ENABLE_ERROR = 11;
+ // notification from the master SM that it had trouble disabling IP Forwarding
+ static final int CMD_IP_FORWARDING_DISABLE_ERROR = 12;
+ // notification from the master SM that it had trouble staring tethering
+ static final int CMD_START_TETHERING_ERROR = 13;
+ // notification from the master SM that it had trouble stopping tethering
+ static final int CMD_STOP_TETHERING_ERROR = 14;
+ // notification from the master SM that it had trouble setting the DNS forwarders
+ static final int CMD_SET_DNS_FORWARDERS_ERROR = 15;
+ // a mechanism to transition self to error state from an enter function
+ static final int CMD_TRANSITION_TO_ERROR = 16;
+
+ private HierarchicalState mDefaultState;
+
+ private HierarchicalState mInitialState;
+ private HierarchicalState mStartingState;
+ private HierarchicalState mTetheredState;
+
+ private HierarchicalState mMasterTetherErrorState;
+ private HierarchicalState mTetherInterfaceErrorState;
+ private HierarchicalState mUntetherInterfaceErrorState;
+ private HierarchicalState mEnableNatErrorState;
+ private HierarchicalState mDisableNatErrorState;
+
+ private HierarchicalState mUnavailableState;
+
+ private boolean mAvailable;
+ private boolean mErrored;
+ private boolean mTethered;
+
+ String mIfaceName;
+
+ TetherInterfaceSM(String name) {
+ super(name);
+ mIfaceName = name;
+
+ mInitialState = new InitialState();
+ addState(mInitialState);
+ mStartingState = new StartingState();
+ addState(mStartingState);
+ mTetheredState = new TetheredState();
+ addState(mTetheredState);
+ mMasterTetherErrorState = new MasterTetherErrorState();
+ addState(mMasterTetherErrorState);
+ mTetherInterfaceErrorState = new TetherInterfaceErrorState();
+ addState(mTetherInterfaceErrorState);
+ mUntetherInterfaceErrorState = new UntetherInterfaceErrorState();
+ addState(mUntetherInterfaceErrorState);
+ mEnableNatErrorState = new EnableNatErrorState();
+ addState(mEnableNatErrorState);
+ mDisableNatErrorState = new DisableNatErrorState();
+ addState(mDisableNatErrorState);
+ mUnavailableState = new UnavailableState();
+ addState(mUnavailableState);
+
+ setInitialState(mInitialState);
+ }
+
+ public String toString() {
+ String res = new String();
+ res += mIfaceName + " - ";
+ HierarchicalState current = getCurrentState();
+ if (current == mInitialState) res += "InitialState";
+ if (current == mStartingState) res += "StartingState";
+ if (current == mTetheredState) res += "TetheredState";
+ if (current == mMasterTetherErrorState) res += "MasterTetherErrorState";
+ if (current == mTetherInterfaceErrorState) res += "TetherInterfaceErrorState";
+ if (current == mUntetherInterfaceErrorState) res += "UntetherInterfaceErrorState";
+ if (current == mEnableNatErrorState) res += "EnableNatErrorState";
+ if (current == mDisableNatErrorState) res += "DisableNatErrorState";
+ if (current == mUnavailableState) res += "UnavailableState";
+ if (mAvailable) res += " - Available";
+ if (mTethered) res += " - Tethered";
+ if (mErrored) res += " - ERRORED";
+ return res;
+ }
+
+ // synchronized between this getter and the following setter
+ public synchronized boolean isAvailable() {
+ return mAvailable;
+ }
+
+ private synchronized void setAvailable(boolean available) {
+ mAvailable = available;
+ }
+
+ // synchronized between this getter and the following setter
+ public synchronized boolean isTethered() {
+ return mTethered;
+ }
+
+ private synchronized void setTethered(boolean tethered) {
+ mTethered = tethered;
+ }
+
+ // synchronized between this getter and the following setter
+ public synchronized boolean isErrored() {
+ return mErrored;
+ }
+
+ private synchronized void setErrored(boolean errored) {
+ mErrored = errored;
+ }
+
+ class InitialState extends HierarchicalState {
+ @Override
+ public void enter() {
+ setAvailable(true);
+ setTethered(false);
+ setErrored(false);
+ sendTetherStateChangedBroadcast();
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ Log.d(TAG, "InitialState.processMessage what=" + message.what);
+ boolean retValue = true;
+ switch (message.what) {
+ case CMD_TETHER_REQUESTED:
+ Message m = mTetherMasterSM.obtainMessage(
+ TetherMasterSM.CMD_TETHER_MODE_REQUESTED);
+ m.obj = TetherInterfaceSM.this;
+ mTetherMasterSM.sendMessage(m);
+ transitionTo(mStartingState);
+ break;
+ case CMD_INTERFACE_DOWN:
+ transitionTo(mUnavailableState);
+ break;
+ default:
+ retValue = false;
+ break;
+ }
+ return retValue;
+ }
+ }
+
+ class StartingState extends HierarchicalState {
+ @Override
+ public void enter() {
+ setAvailable(false);
+ sendTetherStateChangedBroadcast();
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ Log.d(TAG, "StartingState.processMessage what=" + message.what);
+ boolean retValue = true;
+ switch (message.what) {
+ // maybe a parent class?
+ case CMD_TETHER_UNREQUESTED:
+ Message m = mTetherMasterSM.obtainMessage(
+ TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED);
+ m.obj = TetherInterfaceSM.this;
+ mTetherMasterSM.sendMessage(m);
+ transitionTo(mInitialState);
+ break;
+ case CMD_TETHER_MODE_ALIVE:
+ transitionTo(mTetheredState);
+ break;
+ case CMD_CELL_DUN_ERROR:
+ case CMD_IP_FORWARDING_ENABLE_ERROR:
+ case CMD_IP_FORWARDING_DISABLE_ERROR:
+ case CMD_START_TETHERING_ERROR:
+ case CMD_STOP_TETHERING_ERROR:
+ case CMD_SET_DNS_FORWARDERS_ERROR:
+ transitionTo(mMasterTetherErrorState);
+ break;
+ case CMD_INTERFACE_DOWN:
+ m = mTetherMasterSM.obtainMessage(
+ TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED);
+ m.obj = TetherInterfaceSM.this;
+ mTetherMasterSM.sendMessage(m);
+ transitionTo(mUnavailableState);
+ break;
+ default:
+ retValue = false;
+ }
+ return retValue;
+ }
+ }
+
+ class TetheredState extends HierarchicalState {
+ @Override
+ public void enter() {
+ IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+ INetworkManagementService service =
+ INetworkManagementService.Stub.asInterface(b);
+ try {
+ service.tetherInterface(mIfaceName);
+ } catch (Exception e) {
+ Message m = obtainMessage(CMD_TRANSITION_TO_ERROR);
+ m.obj = mTetherInterfaceErrorState;
+ sendMessageAtFrontOfQueue(m);
+ return;
+ }
+ try {
+ service.enableNat(mIfaceName, mUpstreamIfaceName);
+ } catch (Exception e) {
+ Message m = obtainMessage(CMD_TRANSITION_TO_ERROR);
+ m.obj = mEnableNatErrorState;
+ sendMessageAtFrontOfQueue(m);
+ return;
+ }
+ Log.d(TAG, "Tethered " + mIfaceName);
+ setAvailable(false);
+ setTethered(true);
+ sendTetherStateChangedBroadcast();
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ Log.d(TAG, "TetheredState.processMessage what=" + message.what);
+ boolean retValue = true;
+ boolean error = false;
+ switch (message.what) {
+ case CMD_TETHER_UNREQUESTED:
+ case CMD_INTERFACE_DOWN:
+ IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+ INetworkManagementService service =
+ INetworkManagementService.Stub.asInterface(b);
+ try {
+ service.disableNat(mIfaceName, mUpstreamIfaceName);
+ } catch (Exception e) {
+ transitionTo(mDisableNatErrorState);
+ break;
+ }
+ try {
+ service.untetherInterface(mIfaceName);
+ } catch (Exception e) {
+ transitionTo(mUntetherInterfaceErrorState);
+ break;
+ }
+ Message m = mTetherMasterSM.obtainMessage(
+ TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED);
+ m.obj = TetherInterfaceSM.this;
+ mTetherMasterSM.sendMessage(m);
+ if (message.what == CMD_TETHER_UNREQUESTED) {
+ transitionTo(mInitialState);
+ } else if (message.what == CMD_INTERFACE_DOWN) {
+ transitionTo(mUnavailableState);
+ }
+ Log.d(TAG, "Untethered " + mIfaceName);
+ sendTetherStateChangedBroadcast();
+ break;
+ case CMD_CELL_DUN_ERROR:
+ case CMD_IP_FORWARDING_ENABLE_ERROR:
+ case CMD_IP_FORWARDING_DISABLE_ERROR:
+ case CMD_START_TETHERING_ERROR:
+ case CMD_STOP_TETHERING_ERROR:
+ case CMD_SET_DNS_FORWARDERS_ERROR:
+ error = true;
+ // fall through
+ case CMD_TETHER_MODE_DEAD:
+ b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+ service = INetworkManagementService.Stub.asInterface(b);
+ try {
+ service.disableNat(mIfaceName, mUpstreamIfaceName);
+ } catch (Exception e) {
+ transitionTo(mDisableNatErrorState);
+ break;
+ }
+ try {
+ service.untetherInterface(mIfaceName);
+ } catch (Exception e) {
+ transitionTo(mUntetherInterfaceErrorState);
+ break;
+ }
+ if (error) {
+ transitionTo(mMasterTetherErrorState);
+ break;
+ }
+ Log.d(TAG, "Tether lost upstream connection " + mIfaceName);
+ sendTetherStateChangedBroadcast();
+ transitionTo(mInitialState);
+ break;
+ case CMD_TRANSITION_TO_ERROR:
+ HierarchicalState s = (HierarchicalState)(message.obj);
+ transitionTo(s);
+ break;
+ default:
+ retValue = false;
+ break;
+ }
+ return retValue;
+ }
+ }
+
+ class UnavailableState extends HierarchicalState {
+ @Override
+ public void enter() {
+ setAvailable(false);
+ setErrored(false);
+ setTethered(false);
+ sendTetherStateChangedBroadcast();
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ boolean retValue = true;
+ switch (message.what) {
+ case CMD_INTERFACE_UP:
+ transitionTo(mInitialState);
+ break;
+ default:
+ retValue = false;
+ break;
+ }
+ return retValue;
+ }
+ }
+
+
+ class ErrorState extends HierarchicalState {
+ int mErrorNotification;
+ @Override
+ public boolean processMessage(Message message) {
+ boolean retValue = true;
+ switch (message.what) {
+ case CMD_TETHER_REQUESTED:
+ sendTetherStateChangedBroadcast();
+ break;
+ default:
+ retValue = false;
+ break;
+ }
+ return retValue;
+ }
+ }
+
+ class MasterTetherErrorState extends ErrorState {
+ @Override
+ public void enter() {
+ Log.e(TAG, "Error in Master Tether state " + mIfaceName);
+ setAvailable(false);
+ setErrored(true);
+ sendTetherStateChangedBroadcast();
+ }
+ }
+
+ class TetherInterfaceErrorState extends ErrorState {
+ @Override
+ public void enter() {
+ Log.e(TAG, "Error trying to tether " + mIfaceName);
+ setAvailable(false);
+ setErrored(true);
+ sendTetherStateChangedBroadcast();
+ }
+ }
+
+ class UntetherInterfaceErrorState extends ErrorState {
+ @Override
+ public void enter() {
+ Log.e(TAG, "Error trying to untether " + mIfaceName);
+ setAvailable(false);
+ setErrored(true);
+ sendTetherStateChangedBroadcast();
+ }
+ }
+
+ class EnableNatErrorState extends ErrorState {
+ @Override
+ public void enter() {
+ Log.e(TAG, "Error trying to enable NAT " + mIfaceName);
+ setAvailable(false);
+ setErrored(true);
+
+ IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+ INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
+ try {
+ service.untetherInterface(mIfaceName);
+ } catch (Exception e) {}
+ sendTetherStateChangedBroadcast();
+ }
+ }
+
+
+ class DisableNatErrorState extends ErrorState {
+ @Override
+ public void enter() {
+ Log.e(TAG, "Error trying to disable NAT " + mIfaceName);
+ setAvailable(false);
+ setErrored(true);
+
+ IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+ INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
+ try {
+ service.untetherInterface(mIfaceName);
+ } catch (Exception e) {}
+ sendTetherStateChangedBroadcast();
+ }
+ }
+ }
+
+ class TetherMasterSM extends HierarchicalStateMachine {
+ // an interface SM has requested Tethering
+ static final int CMD_TETHER_MODE_REQUESTED = 1;
+ // an interface SM has unrequested Tethering
+ static final int CMD_TETHER_MODE_UNREQUESTED = 2;
+ // we received notice that the cellular DUN connection is up
+ static final int CMD_CELL_DUN_ENABLED = 3;
+ // we received notice that the cellular DUN connection is down
+ static final int CMD_CELL_DUN_DISABLED = 4;
+ // we timed out on a cellular DUN toggle
+ static final int CMD_CELL_DUN_TIMEOUT = 5;
+ // it's time to renew our cellular DUN reservation
+ static final int CMD_CELL_DUN_RENEW = 6;
+
+ // This indicates what a timeout event relates to. A state that
+ // sends itself a delayed timeout event and handles incoming timeout events
+ // should inc this when it is entered and whenever it sends a new timeout event.
+ // We do not flush the old ones.
+ private int mSequenceNumber;
+
+ private HierarchicalState mInitialState;
+ private HierarchicalState mCellDunRequestedState;
+ private HierarchicalState mCellDunAliveState;
+ private HierarchicalState mTetherModeAliveState;
+ private HierarchicalState mCellDunUnRequestedState;
+
+ private HierarchicalState mCellDunErrorState;
+ private HierarchicalState mSetIpForwardingEnabledErrorState;
+ private HierarchicalState mSetIpForwardingDisabledErrorState;
+ private HierarchicalState mStartTetheringErrorState;
+ private HierarchicalState mStopTetheringErrorState;
+ private HierarchicalState mSetDnsForwardersErrorState;
+
+ private ArrayList mNotifyList;
+
+
+ private static final int CELL_DUN_TIMEOUT_MS = 45000;
+ private static final int CELL_DISABLE_DUN_TIMEOUT_MS = 3000;
+ private static final int CELL_DUN_RENEW_MS = 40000;
+
+ TetherMasterSM(String name) {
+ super(name);
+
+ //Add states
+ mInitialState = new InitialState();
+ addState(mInitialState);
+ mCellDunRequestedState = new CellDunRequestedState();
+ addState(mCellDunRequestedState);
+ mCellDunAliveState = new CellDunAliveState();
+ addState(mCellDunAliveState);
+ mTetherModeAliveState = new TetherModeAliveState();
+ addState(mTetherModeAliveState);
+ mCellDunUnRequestedState = new CellDunUnRequestedState();
+ addState(mCellDunUnRequestedState);
+
+ mCellDunErrorState = new CellDunErrorState();
+ addState(mCellDunErrorState);
+ mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState();
+ addState(mSetIpForwardingEnabledErrorState);
+ mSetIpForwardingDisabledErrorState = new SetIpForwardingDisabledErrorState();
+ addState(mSetIpForwardingDisabledErrorState);
+ mStartTetheringErrorState = new StartTetheringErrorState();
+ addState(mStartTetheringErrorState);
+ mStopTetheringErrorState = new StopTetheringErrorState();
+ addState(mStopTetheringErrorState);
+ mSetDnsForwardersErrorState = new SetDnsForwardersErrorState();
+ addState(mSetDnsForwardersErrorState);
+
+ mNotifyList = new ArrayList();
+
+ setInitialState(mInitialState);
+ }
+
+
+ class InitialState extends HierarchicalState {
+ @Override
+ public boolean processMessage(Message message) {
+ Log.d(TAG, "MasterInitialState.processMessage what=" + message.what);
+ boolean retValue = true;
+ switch (message.what) {
+ case CMD_TETHER_MODE_REQUESTED:
+ TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
+ Log.d(TAG, "Tether Mode requested by " + who.toString());
+ mNotifyList.add(who);
+ transitionTo(mCellDunRequestedState);
+ break;
+ case CMD_TETHER_MODE_UNREQUESTED:
+ who = (TetherInterfaceSM)message.obj;
+ Log.d(TAG, "Tether Mode unrequested by " + who.toString());
+ int index = mNotifyList.indexOf(who);
+ if (index != -1) {
+ mNotifyList.remove(who);
+ }
+ break;
+ case CMD_CELL_DUN_ENABLED:
+ transitionTo(mCellDunAliveState);
+ break;
+ default:
+ retValue = false;
+ break;
+ }
+ return retValue;
+ }
+ }
+ class CellDunRequestedState extends HierarchicalState {
+ @Override
+ public void enter() {
+ ++mSequenceNumber;
+ IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+ IConnectivityManager service =
+ IConnectivityManager.Stub.asInterface(b);
+ int result;
+ try {
+ result = service.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+ Phone.FEATURE_ENABLE_DUN, new Binder());
+ } catch (Exception e) {
+ result = Phone.APN_REQUEST_FAILED;
+ }
+ switch (result) {
+ case Phone.APN_ALREADY_ACTIVE:
+ Log.d(TAG, "Dun already active");
+ sendMessage(obtainMessage(CMD_CELL_DUN_ENABLED));
+ break;
+ case Phone.APN_REQUEST_FAILED:
+ case Phone.APN_TYPE_NOT_AVAILABLE:
+ Log.d(TAG, "Error bringing up Dun connection");
+ Message m = obtainMessage(CMD_CELL_DUN_TIMEOUT);
+ m.arg1 = mSequenceNumber;
+ sendMessage(m);
+ break;
+ case Phone.APN_REQUEST_STARTED:
+ Log.d(TAG, "Started bringing up Dun connection");
+ m = obtainMessage(CMD_CELL_DUN_TIMEOUT);
+ m.arg1 = mSequenceNumber;
+ sendMessageDelayed(m, CELL_DUN_TIMEOUT_MS);
+ break;
+ default:
+ Log.e(TAG, "Unknown return value from startUsingNetworkFeature " + result);
+ }
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ Log.d(TAG, "CellDunRequestedState.processMessage what=" + message.what);
+ boolean retValue = true;
+ switch (message.what) {
+ case CMD_TETHER_MODE_REQUESTED:
+ TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
+ mNotifyList.add(who);
+ break;
+ case CMD_TETHER_MODE_UNREQUESTED:
+ who = (TetherInterfaceSM)message.obj;
+ int index = mNotifyList.indexOf(who);
+ if (index != -1) {
+ mNotifyList.remove(index);
+ if (mNotifyList.isEmpty()) {
+ transitionTo(mCellDunUnRequestedState);
+ }
+ }
+ break;
+ case CMD_CELL_DUN_ENABLED:
+ IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+ INetworkManagementService service =
+ INetworkManagementService.Stub.asInterface(b);
+
+ try {
+ service.setIpForwardingEnabled(true);
+ } catch (Exception e) {
+ transitionTo(mSetIpForwardingEnabledErrorState);
+ break;
+ }
+ try {
+ service.startTethering(mDhcpRange[0], mDhcpRange[1]);
+ } catch (Exception e) {
+ transitionTo(mStartTetheringErrorState);
+ break;
+ }
+ try {
+ service.setDnsForwarders(mDnsServers);
+ } catch (Exception e) {
+ transitionTo(mSetDnsForwardersErrorState);
+ break;
+ }
+ transitionTo(mTetherModeAliveState);
+ break;
+ case CMD_CELL_DUN_DISABLED:
+ break;
+ case CMD_CELL_DUN_TIMEOUT:
+ if (message.arg1 == mSequenceNumber) {
+ transitionTo(mCellDunErrorState);
+ }
+ break;
+ default:
+ retValue = false;
+ break;
+ }
+ return retValue;
+ }
+ }
+
+ class CellDunAliveState extends HierarchicalState {
+ @Override
+ public void enter() {
+ sendMessageDelayed(obtainMessage(CMD_CELL_DUN_RENEW), CELL_DUN_RENEW_MS);
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ Log.d(TAG, "CellDunAliveState.processMessage what=" + message.what);
+ boolean retValue = true;
+ switch (message.what) {
+ case CMD_TETHER_MODE_REQUESTED:
+ TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
+ mNotifyList.add(who);
+ IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+ INetworkManagementService service =
+ INetworkManagementService.Stub.asInterface(b);
+
+ try {
+ service.setIpForwardingEnabled(true);
+ } catch (Exception e) {
+ transitionTo(mSetIpForwardingEnabledErrorState);
+ break;
+ }
+ try {
+ service.startTethering(mDhcpRange[0], mDhcpRange[1]);
+ } catch (Exception e) {
+ transitionTo(mStartTetheringErrorState);
+ break;
+ }
+ try {
+ service.setDnsForwarders(mDnsServers);
+ } catch (Exception e) {
+ transitionTo(mSetDnsForwardersErrorState);
+ break;
+ }
+ transitionTo(mTetherModeAliveState);
+ break;
+ case CMD_TETHER_MODE_UNREQUESTED:
+ who = (TetherInterfaceSM)message.obj;
+ int index = mNotifyList.indexOf(who);
+ if (index != -1) {
+ mNotifyList.remove(index);
+ if (mNotifyList.isEmpty()) {
+ transitionTo(mCellDunUnRequestedState);
+ }
+ }
+ break;
+ case CMD_CELL_DUN_DISABLED:
+ transitionTo(mInitialState);
+ break;
+ case CMD_CELL_DUN_RENEW:
+ b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+ IConnectivityManager cservice = IConnectivityManager.Stub.asInterface(b);
+ try {
+ cservice.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+ Phone.FEATURE_ENABLE_DUN, new Binder());
+ } catch (Exception e) {
+ }
+ sendMessageDelayed(obtainMessage(CMD_CELL_DUN_RENEW), CELL_DUN_RENEW_MS);
+ break;
+ default:
+ retValue = false;
+ break;
+ }
+ return retValue;
+ }
+ }
+
+ class TetherModeAliveState extends HierarchicalState {
+ @Override
+ public void enter() {
+ for (Object o : mNotifyList) {
+ TetherInterfaceSM sm = (TetherInterfaceSM)o;
+ sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_MODE_ALIVE));
+ }
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ Log.d(TAG, "TetherModeAliveState.processMessage what=" + message.what);
+ boolean retValue = true;
+ switch (message.what) {
+ case CMD_TETHER_MODE_REQUESTED:
+ TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
+ mNotifyList.add(who);
+ who.sendMessage(who.obtainMessage(TetherInterfaceSM.CMD_TETHER_MODE_ALIVE));
+ break;
+ case CMD_TETHER_MODE_UNREQUESTED:
+ who = (TetherInterfaceSM)message.obj;
+ int index = mNotifyList.indexOf(who);
+ if (index != -1) {
+ mNotifyList.remove(index);
+ if (mNotifyList.isEmpty()) {
+ transitionTo(mCellDunUnRequestedState);
+ }
+ }
+ break;
+ case CMD_CELL_DUN_DISABLED:
+ int size = mNotifyList.size();
+ for (int i = 0; i < size; i++) {
+ TetherInterfaceSM sm = (TetherInterfaceSM)mNotifyList.get(i);
+ mNotifyList.remove(i);
+ sm.sendMessage(sm.obtainMessage(
+ TetherInterfaceSM.CMD_TETHER_MODE_DEAD));
+ }
+ IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+ INetworkManagementService service =
+ INetworkManagementService.Stub.asInterface(b);
+ try {
+ service.stopTethering();
+ } catch (Exception e) {
+ transitionTo(mStopTetheringErrorState);
+ break;
+ }
+ try {
+ service.setIpForwardingEnabled(false);
+ } catch (Exception e) {
+ transitionTo(mSetIpForwardingDisabledErrorState);
+ break;
+ }
+ transitionTo(mInitialState);
+ break;
+ default:
+ retValue = false;
+ break;
+ }
+ return retValue;
+ }
+ }
+
+ class CellDunUnRequestedState extends HierarchicalState {
+ @Override
+ public void enter() {
+ IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+ IConnectivityManager service =
+ IConnectivityManager.Stub.asInterface(b);
+ NetworkInfo dunInfo = null;
+ try {
+ dunInfo = service.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_DUN);
+ } catch (Exception e) {}
+ if (dunInfo != null && !dunInfo.isConnectedOrConnecting()) {
+ sendMessage(obtainMessage(CMD_CELL_DUN_DISABLED));
+ return;
+ }
+ try {
+ service.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+ Phone.FEATURE_ENABLE_DUN);
+ } catch (Exception e) {}
+ Message m = obtainMessage(CMD_CELL_DUN_TIMEOUT);
+ m.arg1 = ++mSequenceNumber;
+ // use a short timeout - this will often be a no-op and
+ // we just want this request to get into the queue before we
+ // try again.
+ sendMessageDelayed(m, CELL_DISABLE_DUN_TIMEOUT_MS);
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ Log.d(TAG, "CellDunUnRequestedState.processMessage what=" + message.what);
+ boolean retValue = true;
+ switch (message.what) {
+ case CMD_TETHER_MODE_REQUESTED:
+ case CMD_TETHER_MODE_UNREQUESTED:
+ deferMessage(message);
+ break;
+ case CMD_CELL_DUN_DISABLED:
+ transitionTo(mInitialState);
+ break;
+ case CMD_CELL_DUN_TIMEOUT:
+ // if we aren't using a sep apn, we won't get a disconnect broadcast..
+ // just go back to initial after our short pause
+ if (message.arg1 == mSequenceNumber) {
+ transitionTo(mInitialState);
+ }
+ break;
+ default:
+ retValue = false;
+ break;
+ }
+ return retValue;
+ }
+ }
+
+ class ErrorState extends HierarchicalState {
+ int mErrorNotification;
+ @Override
+ public boolean processMessage(Message message) {
+ boolean retValue = true;
+ switch (message.what) {
+ case CMD_TETHER_MODE_REQUESTED:
+ TetherInterfaceSM who = (TetherInterfaceSM)message.obj;
+ who.sendMessage(who.obtainMessage(mErrorNotification));
+ break;
+ default:
+ retValue = false;
+ }
+ return retValue;
+ }
+ void notify(int msgType) {
+ mErrorNotification = msgType;
+ for (Object o : mNotifyList) {
+ TetherInterfaceSM sm = (TetherInterfaceSM)o;
+ sm.sendMessage(sm.obtainMessage(msgType));
+ }
+ }
+
+ }
+ class CellDunErrorState extends ErrorState {
+ @Override
+ public void enter() {
+ Log.e(TAG, "Error trying to enable Cell DUN");
+ notify(TetherInterfaceSM.CMD_CELL_DUN_ERROR);
+ }
+ }
+
+ class SetIpForwardingEnabledErrorState extends ErrorState {
+ @Override
+ public void enter() {
+ Log.e(TAG, "Error in setIpForwardingEnabled");
+ notify(TetherInterfaceSM.CMD_IP_FORWARDING_ENABLE_ERROR);
+ }
+ }
+
+ class SetIpForwardingDisabledErrorState extends ErrorState {
+ @Override
+ public void enter() {
+ Log.e(TAG, "Error in setIpForwardingDisabled");
+ notify(TetherInterfaceSM.CMD_IP_FORWARDING_DISABLE_ERROR);
+ }
+ }
+
+ class StartTetheringErrorState extends ErrorState {
+ @Override
+ public void enter() {
+ Log.e(TAG, "Error in startTethering");
+ notify(TetherInterfaceSM.CMD_START_TETHERING_ERROR);
+ IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+ INetworkManagementService service =
+ INetworkManagementService.Stub.asInterface(b);
+ try {
+ service.setIpForwardingEnabled(false);
+ } catch (Exception e) {}
+ }
+ }
+
+ class StopTetheringErrorState extends ErrorState {
+ @Override
+ public void enter() {
+ Log.e(TAG, "Error in stopTethering");
+ notify(TetherInterfaceSM.CMD_STOP_TETHERING_ERROR);
+ IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+ INetworkManagementService service =
+ INetworkManagementService.Stub.asInterface(b);
+ try {
+ service.setIpForwardingEnabled(false);
+ } catch (Exception e) {}
+ }
+ }
+
+ class SetDnsForwardersErrorState extends ErrorState {
+ @Override
+ public void enter() {
+ Log.e(TAG, "Error in setDnsForwarders");
+ notify(TetherInterfaceSM.CMD_SET_DNS_FORWARDERS_ERROR);
+ IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+ INetworkManagementService service =
+ INetworkManagementService.Stub.asInterface(b);
+ try {
+ service.stopTethering();
+ } catch (Exception e) {}
+ try {
+ service.setIpForwardingEnabled(false);
+ } catch (Exception e) {}
+ }
}
- return result;
}
- public synchronized String[] getTetherableIfaces() {
- int size = mAvailableIfaces.size();
- String[] result = new String[size];
- size -= 1;
- for (int i=0; i< size; i++) {
- result[i] = mActiveIfaces.get(i);
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump ConnectivityService.Tether " +
+ "from from pid=" + Binder.getCallingPid() + ", uid=" +
+ Binder.getCallingUid());
+ return;
+ }
+
+ pw.println();
+ pw.println("Tether state:");
+ synchronized (mIfaces) {
+ for (Object o : mIfaces.values()) {
+ pw.println(" "+o.toString());
+ }
}
- return result;
+ pw.println();
+ return;
}
}
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index 20209e4224d2..d13f9d38d36e 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -22,6 +22,7 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothPbap;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@@ -30,7 +31,10 @@ import android.content.res.TypedArray;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
import android.net.NetworkInfo;
+import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Handler;
@@ -109,6 +113,7 @@ public class StatusBarPolicy {
private int mBatteryViewSequence;
private boolean mBatteryShowLowOnEndCall = false;
private static final boolean SHOW_LOW_BATTERY_WARNING = true;
+ private static final boolean SHOW_BATTERY_WARNINGS_IN_CALL = true;
// phone
private TelephonyManager mPhone;
@@ -686,7 +691,7 @@ public class StatusBarPolicy {
+ " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);
}
- if (mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
+ if (SHOW_BATTERY_WARNINGS_IN_CALL || mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
showLowBatteryWarning();
} else {
mBatteryShowLowOnEndCall = true;
@@ -810,6 +815,21 @@ public class StatusBarPolicy {
d.show();
mLowBatteryDialog = d;
}
+
+ final ContentResolver cr = mContext.getContentResolver();
+ if (Settings.System.getInt(cr,
+ Settings.System.POWER_SOUNDS_ENABLED, 1) == 1)
+ {
+ final String soundPath = Settings.System.getString(cr,
+ Settings.System.LOW_BATTERY_SOUND);
+ if (soundPath != null) {
+ final Uri soundUri = Uri.parse("file://" + soundPath);
+ if (soundUri != null) {
+ final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
+ if (sfx != null) sfx.play();
+ }
+ }
+ }
}
private final void updateCallState(int state) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index c35128971ae2..39fe007f4b20 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -1203,32 +1203,23 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
} else {
int[] ints = (int[])ar.result;
int offset = 2;
-
int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120;
int cdmaEcio = (ints[offset+1] > 0) ? -ints[offset+1] : -160;
+ int evdoRssi = (ints[offset+2] > 0) ? -ints[offset+2] : -120;
+ int evdoEcio = (ints[offset+3] > 0) ? -ints[offset+3] : -1;
+ int evdoSnr = ((ints[offset+4] > 0) && (ints[offset+4] <= 8)) ? ints[offset+4] : -1;
- int evdoRssi = -1;
- int evdoEcio = -1;
- int evdoSnr = -1;
- if ((networkType == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
- || (networkType == ServiceState.RADIO_TECHNOLOGY_EVDO_A)) {
- evdoRssi = (ints[offset+2] > 0) ? -ints[offset+2] : -120;
- evdoEcio = (ints[offset+3] > 0) ? -ints[offset+3] : -1;
- evdoSnr = ((ints[offset+4] > 0) && (ints[offset+4] <= 8)) ? ints[offset+4] : -1;
- }
-
+ //log(String.format("onSignalStrengthResult cdmaDbm=%d cdmaEcio=%d evdoRssi=%d evdoEcio=%d evdoSnr=%d",
+ // cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, evdoSnr));
mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio,
evdoRssi, evdoEcio, evdoSnr, false);
}
- if (!mSignalStrength.equals(oldSignalStrength)) {
- try { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after
- // POLL_PERIOD_MILLIS) during Radio Technology Change)
- phone.notifySignalStrength();
- } catch (NullPointerException ex) {
- log("onSignalStrengthResult() Phone already destroyed: " + ex
- + "SignalStrength not notified");
- }
+ try {
+ phone.notifySignalStrength();
+ } catch (NullPointerException ex) {
+ log("onSignalStrengthResult() Phone already destroyed: " + ex
+ + "SignalStrength not notified");
}
}
diff --git a/test-runner/android/test/mock/MockPackageManager.java b/test-runner/android/test/mock/MockPackageManager.java
index 2a4b3f7adb17..f1ba44ac170e 100644
--- a/test-runner/android/test/mock/MockPackageManager.java
+++ b/test-runner/android/test/mock/MockPackageManager.java
@@ -449,12 +449,4 @@ public class MockPackageManager extends PackageManager {
public boolean isSafeMode() {
throw new UnsupportedOperationException();
}
-
- /**
- * @hide
- */
- @Override
- public int recommendAppInstallLocation(PackageParser.Package pkg) {
- throw new UnsupportedOperationException();
- }
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
index 07bd4897effe..8f4d0a17a7f1 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
@@ -192,6 +192,27 @@ public class PackageManagerTests extends AndroidTestCase {
}
}
+ public boolean invokeInstallPackageFail(Uri packageURI, int flags,
+ final String pkgName, int result) throws Exception {
+ PackageInstallObserver observer = new PackageInstallObserver();
+ try {
+ // Wait on observer
+ synchronized(observer) {
+ getPm().installPackage(packageURI, observer, flags, null);
+ long waitTime = 0;
+ while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
+ observer.wait(WAIT_TIME_INCR);
+ waitTime += WAIT_TIME_INCR;
+ }
+ if(!observer.isDone()) {
+ throw new Exception("Timed out waiting for packageInstalled callback");
+ }
+ return (observer.returnCode == result);
+ }
+ } finally {
+ }
+ }
+
Uri getInstallablePackage(int fileResId, File outFile) {
Resources res = mContext.getResources();
InputStream is = null;
@@ -238,7 +259,7 @@ public class PackageManagerTests extends AndroidTestCase {
assertEquals(publicSrcPath, appInstallPath);
} else {
assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
- if ((flags & PackageManager.INSTALL_ON_SDCARD) != 0) {
+ if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
assertTrue((info.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0);
// Hardcoded for now
assertTrue(srcPath.startsWith("/asec"));
@@ -253,6 +274,13 @@ public class PackageManagerTests extends AndroidTestCase {
failStr("failed with exception : " + e);
}
}
+ private void assertNotInstalled(String pkgName) {
+ try {
+ ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0);
+ fail(pkgName + " shouldnt be installed");
+ } catch (NameNotFoundException e) {
+ }
+ }
class InstallParams {
String outFileName;
@@ -265,30 +293,42 @@ public class PackageManagerTests extends AndroidTestCase {
}
}
+ private InstallParams sampleInstallFromRawResource(int flags, boolean cleanUp) {
+ return installFromRawResource("install.apk", R.raw.install, flags, cleanUp,
+ false, -1);
+ }
/*
* Utility function that reads a apk bundled as a raw resource
* copies it into own data directory and invokes
* PackageManager api to install it.
*/
- public InstallParams installFromRawResource(int flags, boolean cleanUp) {
- String outFileName = "install.apk";
+ private InstallParams installFromRawResource(String outFileName,
+ int rawResId, int flags, boolean cleanUp, boolean fail, int result) {
File filesDir = mContext.getFilesDir();
File outFile = new File(filesDir, outFileName);
- Uri packageURI = getInstallablePackage(R.raw.install, outFile);
+ Uri packageURI = getInstallablePackage(rawResId, outFile);
PackageParser.Package pkg = parsePackage(packageURI);
assertNotNull(pkg);
- InstallReceiver receiver = new InstallReceiver(pkg.packageName);
InstallParams ip = null;
try {
try {
- assertTrue(invokeInstallPackage(packageURI, flags,
- pkg.packageName, receiver));
+ if (fail) {
+ // Make sure it doesn't exist
+ getPm().deletePackage(pkg.packageName, null, 0);
+ assertTrue(invokeInstallPackageFail(packageURI, flags,
+ pkg.packageName, result));
+ assertNotInstalled(pkg.packageName);
+ } else {
+ InstallReceiver receiver = new InstallReceiver(pkg.packageName);
+ assertTrue(invokeInstallPackage(packageURI, flags,
+ pkg.packageName, receiver));
+ // Verify installed information
+ assertInstall(pkg.packageName, flags);
+ ip = new InstallParams(pkg, outFileName, packageURI);
+ }
} catch (Exception e) {
failStr("Failed with exception : " + e);
}
- // Verify installed information
- assertInstall(pkg.packageName, flags);
- ip = new InstallParams(pkg, outFileName, packageURI);
return ip;
} finally {
if (cleanUp) {
@@ -299,17 +339,17 @@ public class PackageManagerTests extends AndroidTestCase {
@MediumTest
public void testInstallNormalInternal() {
- installFromRawResource(0, true);
+ sampleInstallFromRawResource(0, true);
}
@MediumTest
public void testInstallFwdLockedInternal() {
- installFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
+ sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
}
@MediumTest
public void testInstallSdcard() {
- installFromRawResource(PackageManager.INSTALL_ON_SDCARD, true);
+ sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
}
/* ------------------------- Test replacing packages --------------*/
@@ -373,7 +413,7 @@ public class PackageManagerTests extends AndroidTestCase {
* again.
*/
public void replaceFromRawResource(int flags) {
- InstallParams ip = installFromRawResource(flags, false);
+ InstallParams ip = sampleInstallFromRawResource(flags, false);
boolean replace = ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0);
GenericReceiver receiver;
if (replace) {
@@ -409,7 +449,7 @@ public class PackageManagerTests extends AndroidTestCase {
@MediumTest
public void testReplaceFailSdcard() {
- replaceFromRawResource(PackageManager.INSTALL_ON_SDCARD);
+ replaceFromRawResource(PackageManager.INSTALL_EXTERNAL);
}
@MediumTest
@@ -426,7 +466,7 @@ public class PackageManagerTests extends AndroidTestCase {
@MediumTest
public void testReplaceSdcard() {
replaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
- PackageManager.INSTALL_ON_SDCARD);
+ PackageManager.INSTALL_EXTERNAL);
}
/* -------------- Delete tests ---*/
@@ -508,7 +548,7 @@ public class PackageManagerTests extends AndroidTestCase {
}
public void deleteFromRawResource(int iFlags, int dFlags) {
- InstallParams ip = installFromRawResource(iFlags, false);
+ InstallParams ip = sampleInstallFromRawResource(iFlags, false);
boolean retainData = ((dFlags & PackageManager.DONT_DELETE_DATA) != 0);
GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
DeleteObserver observer = new DeleteObserver();
@@ -550,7 +590,7 @@ public class PackageManagerTests extends AndroidTestCase {
@MediumTest
public void testDeleteSdcard() {
- deleteFromRawResource(PackageManager.INSTALL_ON_SDCARD, 0);
+ deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, 0);
}
@MediumTest
@@ -565,7 +605,7 @@ public class PackageManagerTests extends AndroidTestCase {
@MediumTest
public void testDeleteSdcardRetainData() {
- deleteFromRawResource(PackageManager.INSTALL_ON_SDCARD, PackageManager.DONT_DELETE_DATA);
+ deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.DONT_DELETE_DATA);
}
/* sdcard mount/unmount tests ******/
@@ -696,7 +736,7 @@ public class PackageManagerTests extends AndroidTestCase {
private boolean mountFromRawResource() {
// Install pkg on sdcard
- InstallParams ip = installFromRawResource(PackageManager.INSTALL_ON_SDCARD |
+ InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL |
PackageManager.INSTALL_REPLACE_EXISTING, false);
if (localLOGV) Log.i(TAG, "Installed pkg on sdcard");
boolean origState = getMediaState();
@@ -764,169 +804,32 @@ public class PackageManagerTests extends AndroidTestCase {
}
}
- public void invokeRecommendAppInstallLocation(String outFileName,
- int fileResId, int expected) {
- int origSetting = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.SET_INSTALL_LOCATION, 0);
- try {
- // Make sure the set install location setting is diabled.
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SET_INSTALL_LOCATION, 0);
- File filesDir = mContext.getFilesDir();
- File outFile = new File(filesDir, outFileName);
- Uri packageURI = getInstallablePackage(fileResId, outFile);
- PackageParser.Package pkg = parsePackage(packageURI);
- assertNotNull(pkg);
- int installLoc = getPm().recommendAppInstallLocation(pkg);
- Log.i(TAG, "expected=" + expected +", installLoc="+installLoc);
- // Atleast one of the specified expected flags should be set.
- boolean onFlash = (installLoc &
- PackageManager.INSTALL_ON_INTERNAL_FLASH) != 0;
- boolean onSd = (installLoc &
- PackageManager.INSTALL_ON_SDCARD) != 0;
- boolean expOnFlash = (expected &
- PackageManager.INSTALL_ON_INTERNAL_FLASH) != 0;
- boolean expOnSd = (expected &
- PackageManager.INSTALL_ON_SDCARD) != 0;
- assertTrue(expOnFlash == onFlash || expOnSd == onSd);
- } finally {
- // Restore original setting
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SET_INSTALL_LOCATION, origSetting);
- }
+ public void testManifestInstallLocationInternal() {
+ installFromRawResource("install.apk", R.raw.install_loc_internal,
+ 0, true, false, -1);
}
- /*
- * Tests if an apk can be installed on internal flash by
- * explicitly specifying in its manifest.
- */
- public void testInstallLocationInternal() {
- invokeRecommendAppInstallLocation("install.apk",
- R.raw.install_loc_internal, PackageManager.INSTALL_ON_INTERNAL_FLASH);
+ public void testManifestInstallLocationSdcard() {
+ installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+ PackageManager.INSTALL_EXTERNAL, true, false, -1);
}
- /*
- * Tests if an apk can be installed on internal flash by
- * explicitly specifying in its manifest and filling up
- * internal flash. Should fail to install.
- * TODO
- */
- public void xxxtestInstallLocationInternalFail() {
+ public void testManifestInstallLocationAuto() {
+ installFromRawResource("install.apk", R.raw.install_loc_auto,
+ 0, true, false, -1);
}
- /*
- * Tests if an apk can be installed on sdcard by
- * explicitly specifying in its manifest.
- */
- public void testInstallLocationSdcard() {
- // TODO No guarantee this will be on sdcard.
- invokeRecommendAppInstallLocation("install.apk",
- R.raw.install_loc_sdcard, PackageManager.INSTALL_ON_SDCARD
- | PackageManager.INSTALL_ON_INTERNAL_FLASH);
+ public void testManifestInstallLocationUnspecified() {
+ installFromRawResource("install.apk", R.raw.install_loc_unspecified,
+ 0, true, false, -1);
}
- /*
- * Tests if an apk can be installed on sdcard by
- * explicitly specifying in its manifest and filling up
- * the sdcard. Should result in install failure
- * TODO
- */
- public void xxxtestInstallLocationSdcardFail() {
+ public void testManifestInstallLocationFwdLockedSdcard() {
+ installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+ PackageManager.INSTALL_FORWARD_LOCK |
+ PackageManager.INSTALL_EXTERNAL, true, true,
+ PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION);
}
-
- /*
- * Tests if an apk can be installed by specifying
- * auto for install location
- */
- public void xxxtestInstallLocationAutoInternal() {
- // TODO clear and make room on internal flash
- invokeRecommendAppInstallLocation("install.apk",
- R.raw.install_loc_auto, PackageManager.INSTALL_ON_INTERNAL_FLASH);
- }
-
- /*
- * Tests if an apk can be installed by specifying
- * auto for install location
- */
- public void testInstallLocationAutoSdcard() {
- // TODO clear and make room on sdcard.
- // Fill up internal
- invokeRecommendAppInstallLocation("install.apk",
- R.raw.install_loc_auto, PackageManager.INSTALL_ON_SDCARD |
- PackageManager.INSTALL_ON_INTERNAL_FLASH);
- }
-
- /*
- * Tests if an apk can be installed by specifying
- * auto for install location
- * fill up both internal and sdcard
- * TODO
- */
- public void xxxtestInstallLocationAutoFail() {
- }
- /*
- * Tests where an apk gets installed based
- * on a not specifying anything in manifest.
- */
- public void testInstallLocationUnspecifiedInt() {
- invokeRecommendAppInstallLocation("install.apk",
- R.raw.install_loc_unspecified, PackageManager.INSTALL_ON_INTERNAL_FLASH);
- }
-
- public void xxxtestInstallLocationUnspecifiedStorage() {
- // TODO Fill up internal storage
- invokeRecommendAppInstallLocation("install.apk",
- R.raw.install_loc_unspecified, PackageManager.INSTALL_ON_SDCARD
- | PackageManager.INSTALL_ON_INTERNAL_FLASH);
- }
-
- /*
- * Tests where an apk gets installed by expcitly setting
- * the user specified install location
- */
- public void testInstallLocationUserSpecifiedInternal() {
- // Enable user setting
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SET_INSTALL_LOCATION, 1);
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.DEFAULT_INSTALL_LOCATION, 1);
- invokeRecommendAppInstallLocation("install.apk",
- R.raw.install_loc_unspecified, PackageManager.INSTALL_ON_INTERNAL_FLASH);
- }
-
- /*
- * Tests where an apk gets installed by expcitly setting
- * the user specified install location
- */
- public void testInstallLocationUserSpecifiedSdcard() {
- // Enable user setting
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SET_INSTALL_LOCATION, 1);
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.DEFAULT_INSTALL_LOCATION, 2);
- int i = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.DEFAULT_INSTALL_LOCATION, 0);
- invokeRecommendAppInstallLocation("install.apk",
- R.raw.install_loc_unspecified, PackageManager.INSTALL_ON_SDCARD);
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SET_INSTALL_LOCATION, 0);
- }
- /*
- * Tests where an apk gets installed by expcitly setting
- * the user specified install location
- */
- public void testInstallLocationUserSpecifiedAuto() {
- // Enable user setting
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SET_INSTALL_LOCATION, 1);
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.DEFAULT_INSTALL_LOCATION, 0);
- invokeRecommendAppInstallLocation("install.apk",
- R.raw.install_loc_unspecified, PackageManager.INSTALL_ON_INTERNAL_FLASH);
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.SET_INSTALL_LOCATION, 0);
- }
-
/*
* TODO's
* check version numbers for upgrades
diff --git a/tests/backup/AndroidManifest.xml b/tests/backup/AndroidManifest.xml
index d992627de609..3778742e105e 100644
--- a/tests/backup/AndroidManifest.xml
+++ b/tests/backup/AndroidManifest.xml
@@ -1,6 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.backuptest">
- <uses-permission android:name="android.permission.BACKUP_DATA" />
<application android:backupAgent="BackupTestAgent">
<activity android:name="BackupTestActivity" android:label="_BackupTest">
<intent-filter>