summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml1002
-rw-r--r--cmds/dumpstate/dumpstate.c26
-rw-r--r--cmds/dumpstate/dumpstate.h18
-rw-r--r--core/java/android/app/PendingIntent.java13
-rw-r--r--core/java/android/app/SearchDialog.java9
-rw-r--r--core/java/android/app/Service.java8
-rw-r--r--core/java/android/bluetooth/ScoSocket.java19
-rw-r--r--core/java/android/content/BroadcastReceiver.java4
-rw-r--r--core/java/android/content/ContentProvider.java64
-rw-r--r--core/java/android/content/Intent.java31
-rw-r--r--core/java/android/content/package.html7
-rw-r--r--core/java/android/content/pm/PackageInfo.java18
-rw-r--r--core/java/android/content/pm/PackageParser.java7
-rw-r--r--core/java/android/database/DatabaseUtils.java1
-rw-r--r--core/java/android/inputmethodservice/ExtractEditText.java7
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java76
-rwxr-xr-xcore/java/android/inputmethodservice/Keyboard.java60
-rwxr-xr-xcore/java/android/inputmethodservice/KeyboardView.java149
-rw-r--r--core/java/android/os/BatteryStats.java135
-rw-r--r--core/java/android/os/ICheckinService.aidl8
-rw-r--r--core/java/android/os/IPowerManager.aidl1
-rw-r--r--core/java/android/preference/PreferenceGroupAdapter.java2
-rw-r--r--core/java/android/provider/Checkin.java1
-rw-r--r--core/java/android/provider/Settings.java7
-rw-r--r--core/java/android/server/BluetoothDeviceService.java50
-rw-r--r--core/java/android/server/BluetoothEventLoop.java2
-rw-r--r--core/java/android/speech/srec/MicrophoneInputStream.java12
-rw-r--r--core/java/android/text/format/Time.java1
-rw-r--r--core/java/android/text/style/ImageSpan.java5
-rw-r--r--core/java/android/util/SparseIntArray.java13
-rw-r--r--core/java/android/view/GestureDetector.java24
-rwxr-xr-xcore/java/android/view/OrientationEventListener.java156
-rw-r--r--core/java/android/view/OrientationListener.java99
-rw-r--r--core/java/android/view/RemotableViewMethod.java (renamed from core/java/android/os/HandlerInterface.java)24
-rw-r--r--core/java/android/view/View.java11
-rw-r--r--core/java/android/view/ViewConfiguration.java19
-rw-r--r--core/java/android/view/ViewGroup.java35
-rw-r--r--core/java/android/view/ViewRoot.java94
-rw-r--r--core/java/android/view/ViewTreeObserver.java66
-rw-r--r--core/java/android/view/WindowManager.java30
-rwxr-xr-xcore/java/android/view/WindowOrientationListener.java162
-rw-r--r--core/java/android/view/animation/Animation.java7
-rw-r--r--core/java/android/view/inputmethod/BaseInputConnection.java15
-rw-r--r--core/java/android/view/inputmethod/InputConnection.java20
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java51
-rw-r--r--core/java/android/webkit/BrowserFrame.java2
-rw-r--r--core/java/android/webkit/LoadListener.java2
-rw-r--r--core/java/android/webkit/TextDialog.java22
-rw-r--r--core/java/android/webkit/WebView.java294
-rw-r--r--core/java/android/webkit/WebViewCore.java99
-rw-r--r--core/java/android/webkit/gears/HttpRequestAndroid.java745
-rw-r--r--core/java/android/webkit/gears/UrlInterceptHandlerGears.java6
-rw-r--r--core/java/android/widget/AbsListView.java73
-rw-r--r--core/java/android/widget/Chronometer.java48
-rw-r--r--core/java/android/widget/FrameLayout.java2
-rw-r--r--core/java/android/widget/ImageView.java7
-rw-r--r--core/java/android/widget/LinearLayout.java6
-rw-r--r--core/java/android/widget/ListView.java4
-rw-r--r--core/java/android/widget/PopupWindow.java91
-rw-r--r--core/java/android/widget/ProgressBar.java4
-rw-r--r--core/java/android/widget/RelativeLayout.java4
-rw-r--r--core/java/android/widget/RemoteViews.java664
-rw-r--r--core/java/android/widget/TabHost.java6
-rw-r--r--core/java/android/widget/TextView.java65
-rw-r--r--core/java/android/widget/ViewFlipper.java2
-rw-r--r--core/java/android/widget/ZoomRing.java687
-rw-r--r--core/java/android/widget/ZoomRingController.java471
-rw-r--r--core/java/com/android/internal/app/IBatteryStats.aidl8
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java679
-rw-r--r--core/java/com/android/internal/os/HandlerThread.java91
-rw-r--r--core/java/com/android/internal/view/IInputConnectionWrapper.java4
-rw-r--r--core/java/com/android/internal/widget/EditableInputConnection.java17
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java30
-rw-r--r--core/java/com/android/internal/widget/TextProgressBar.java177
-rw-r--r--core/jni/android_hardware_Camera.cpp21
-rw-r--r--core/jni/android_media_AudioTrack.cpp59
-rw-r--r--core/jni/android_media_JetPlayer.cpp2
-rw-r--r--core/jni/android_os_Debug.cpp15
-rw-r--r--core/jni/android_server_BluetoothDeviceService.cpp33
-rw-r--r--core/jni/android_server_BluetoothEventLoop.cpp7
-rw-r--r--core/jni/android_view_Surface.cpp12
-rw-r--r--core/res/AndroidManifest.xml5
-rw-r--r--core/res/res/drawable-land/title_bar.9.pngbin357 -> 5751 bytes
-rw-r--r--core/res/res/drawable-land/title_bar_tall.pngbin11833 -> 18449 bytes
-rw-r--r--core/res/res/drawable/popup_inline_error_above.9.pngbin0 -> 2043 bytes
-rwxr-xr-xcore/res/res/drawable/scrollbar_handle_accelerated_anim2.9.pngbin1115 -> 1144 bytes
-rw-r--r--core/res/res/drawable/sym_action_call.pngbin3568 -> 904 bytes
-rw-r--r--core/res/res/drawable/sym_action_chat.pngbin3407 -> 808 bytes
-rw-r--r--core/res/res/drawable/sym_action_email.pngbin3385 -> 791 bytes
-rw-r--r--core/res/res/drawable/sym_action_map.pngbin3779 -> 0 bytes
-rw-r--r--core/res/res/drawable/sym_action_sms.pngbin3409 -> 0 bytes
-rw-r--r--core/res/res/drawable/title_bar.9.pngbin337 -> 4121 bytes
-rw-r--r--core/res/res/drawable/title_bar_tall.pngbin8489 -> 12764 bytes
-rw-r--r--core/res/res/drawable/zoom_ring_overview_tab.9.pngbin0 -> 845 bytes
-rw-r--r--core/res/res/drawable/zoom_ring_thumb.pngbin3778 -> 2684 bytes
-rw-r--r--core/res/res/drawable/zoom_ring_thumb_minus_arrow.pngbin0 -> 3157 bytes
-rw-r--r--core/res/res/drawable/zoom_ring_thumb_minus_arrow_rotatable.xml22
-rw-r--r--core/res/res/drawable/zoom_ring_thumb_plus_arrow.pngbin0 -> 3231 bytes
-rw-r--r--core/res/res/drawable/zoom_ring_thumb_plus_arrow_rotatable.xml22
-rw-r--r--core/res/res/drawable/zoom_ring_track.pngbin22395 -> 16980 bytes
-rw-r--r--core/res/res/drawable/zoom_ring_track_absolute.pngbin0 -> 16759 bytes
-rw-r--r--core/res/res/values-cs/strings.xml193
-rw-r--r--core/res/res/values-de/strings.xml196
-rw-r--r--core/res/res/values-en-rAU/strings.xml90
-rw-r--r--core/res/res/values-en-rSG/strings.xml91
-rw-r--r--core/res/res/values-es-rES/arrays.xml32
-rw-r--r--core/res/res/values-es/strings.xml207
-rw-r--r--core/res/res/values-fr-rFR/arrays.xml32
-rw-r--r--core/res/res/values-fr/strings.xml233
-rw-r--r--core/res/res/values-it-rIT/arrays.xml32
-rw-r--r--core/res/res/values-it/strings.xml193
-rw-r--r--core/res/res/values-ja/strings.xml537
-rw-r--r--core/res/res/values-ko/strings.xml193
-rw-r--r--core/res/res/values-nb/strings.xml14
-rw-r--r--core/res/res/values-nl/strings.xml193
-rw-r--r--core/res/res/values-pl/strings.xml193
-rw-r--r--core/res/res/values-ru/strings.xml193
-rw-r--r--core/res/res/values-zh-rCN/strings.xml193
-rw-r--r--core/res/res/values-zh-rTW/strings.xml193
-rw-r--r--core/res/res/values/attrs.xml11
-rw-r--r--core/res/res/values/attrs_manifest.xml7
-rw-r--r--core/res/res/values/public.xml1
-rw-r--r--core/res/res/values/strings.xml6
-rw-r--r--data/sounds/Android.mk29
-rw-r--r--data/sounds/effects/Effect_Tick.ogg (renamed from data/sounds/Effect_Tick.ogg)bin3994 -> 3994 bytes
-rw-r--r--data/sounds/effects/KeypressDelete.oggbin0 -> 6630 bytes
-rw-r--r--data/sounds/effects/KeypressDelete.wavbin0 -> 33424 bytes
-rw-r--r--data/sounds/effects/KeypressReturn.oggbin0 -> 7400 bytes
-rw-r--r--data/sounds/effects/KeypressReturn.wavbin0 -> 46756 bytes
-rw-r--r--data/sounds/effects/KeypressSpacebar.oggbin0 -> 7122 bytes
-rw-r--r--data/sounds/effects/KeypressSpacebar.wavbin0 -> 35536 bytes
-rw-r--r--data/sounds/effects/KeypressStandard.oggbin0 -> 5519 bytes
-rw-r--r--data/sounds/effects/KeypressStandard.wavbin0 -> 21172 bytes
-rwxr-xr-xdata/sounds/testfiles/test.mid (renamed from data/sounds/test.mid)bin2956 -> 2956 bytes
-rw-r--r--docs/html/_build_id.cs2
-rwxr-xr-xdocs/html/about.jd13
-rw-r--r--docs/html/goodies/index.jd85
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper1_1024x768.pngbin42181 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper1_1280x800.pngbin48098 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper1_1440x900.pngbin54844 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper1_1600x1200.pngbin70619 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper1_1680x1050.pngbin64785 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper1_1920x1200.pngbin73761 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper1_2560x1600.pngbin120591 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper1_thumbnail.pngbin7953 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper2_1024x768.pngbin183833 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper2_1280x800.pngbin242116 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper2_1440x900.pngbin323386 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper2_1600x1200.pngbin498565 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper2_1680x1050.pngbin450824 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper2_1920x1200.pngbin592473 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper2_2560x1600.pngbin1025582 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper2_thumbnail.pngbin6558 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper3_1024x768.pngbin99066 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper3_1280x800.pngbin126316 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper3_1440x900.pngbin143988 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper3_1600x1200.pngbin163220 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper3_1680x1050.pngbin169823 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper3_1920x1200.pngbin196865 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper3_2560x1600.pngbin194785 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper3_thumbnail.pngbin4494 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper4_1024x768.pngbin15917 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper4_1280x800.pngbin17296 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper4_1440x900.pngbin18061 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper4_1600x1200.pngbin23167 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper4_1680x1050.pngbin20703 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper4_1920x1200.pngbin22709 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper4_2560x1600.pngbin32802 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper4_thumbnail.pngbin4913 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper5_1024x768.jpgbin65004 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper5_1280x800.jpgbin77434 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper5_1440x900.jpgbin79572 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper5_1600x1200.jpgbin93356 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper5_1680x1050.jpgbin91781 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper5_1920x1080.jpgbin95046 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper5_1920x1200.jpgbin99396 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper5_2560x1600.jpgbin137815 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper5_thumbnail.jpgbin7351 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper6_1024x768.jpgbin79675 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper6_1280x800.jpgbin91634 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper6_1440x900.jpgbin99794 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper6_1600x1200.jpgbin113072 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper6_1680x1050.jpgbin113303 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper6_1920x1200.jpgbin126091 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper6_2560x1600.jpgbin173505 -> 0 bytes
-rw-r--r--docs/html/goodies/wallpaper/android-wallpaper6_thumbnail.jpgbin7320 -> 0 bytes
-rw-r--r--docs/html/googleb38c1d60b7ba5d19.html0
-rw-r--r--docs/html/guide/developing/device.jd2
-rw-r--r--docs/html/guide/developing/instrumentation/inst-testing.jd205
-rw-r--r--docs/html/guide/developing/tools/emulator.jd2
-rw-r--r--docs/html/guide/guide_toc.cs23
-rw-r--r--docs/html/guide/publishing/preparing.jd20
-rw-r--r--docs/html/guide/publishing/versioning.jd4
-rw-r--r--docs/html/guide/samples/index.jd14
-rw-r--r--docs/html/guide/topics/fundamentals.jd67
-rw-r--r--docs/html/guide/topics/intents/intents-filters.jd2
-rw-r--r--docs/html/guide/topics/manifest/action-element.jd46
-rw-r--r--docs/html/guide/topics/manifest/activity-alias-element.jd129
-rw-r--r--docs/html/guide/topics/manifest/activity-element.jd565
-rw-r--r--docs/html/guide/topics/manifest/application-element.jd226
-rw-r--r--docs/html/guide/topics/manifest/category-element.jd38
-rw-r--r--docs/html/guide/topics/manifest/data-element.jd148
-rw-r--r--docs/html/guide/topics/manifest/grant-uri-permission-element.jd85
-rw-r--r--docs/html/guide/topics/manifest/instrumentation-element.jd61
-rw-r--r--docs/html/guide/topics/manifest/intent-filter-element.jd130
-rw-r--r--docs/html/guide/topics/manifest/manifest-element.jd94
-rw-r--r--docs/html/guide/topics/manifest/manifest-intro.jd511
-rw-r--r--docs/html/guide/topics/manifest/manifest.jd3063
-rw-r--r--docs/html/guide/topics/manifest/meta-data-element.jd90
-rw-r--r--docs/html/guide/topics/manifest/permission-element.jd131
-rw-r--r--docs/html/guide/topics/manifest/permission-group-element.jd59
-rw-r--r--docs/html/guide/topics/manifest/permission-tree-element.jd61
-rw-r--r--docs/html/guide/topics/manifest/provider-element.jd267
-rw-r--r--docs/html/guide/topics/manifest/receiver-element.jd164
-rw-r--r--docs/html/guide/topics/manifest/service-element.jd176
-rw-r--r--docs/html/guide/topics/manifest/uses-library-element.jd32
-rw-r--r--docs/html/guide/topics/manifest/uses-permission-element.jd39
-rw-r--r--docs/html/guide/topics/manifest/uses-sdk-element.jd49
-rw-r--r--docs/html/guide/topics/ui/binding.jd3
-rw-r--r--docs/html/guide/topics/ui/declaring-layout.jd6
-rw-r--r--docs/html/guide/topics/ui/index.jd6
-rw-r--r--docs/html/guide/topics/ui/menus.jd12
-rw-r--r--docs/html/guide/topics/ui/themes.jd21
-rw-r--r--docs/html/guide/tutorials/hello-world.jd171
-rw-r--r--docs/html/images/judgebio_charles.jpgbin16354 -> 0 bytes
-rw-r--r--docs/html/images/judgebio_dibona.jpgbin10286 -> 0 bytes
-rw-r--r--docs/html/images/judgebio_gadi.jpgbin8040 -> 0 bytes
-rw-r--r--docs/html/images/judgebio_jens.jpgbin17098 -> 0 bytes
-rw-r--r--docs/html/images/judgebio_jeremiah.jpgbin17703 -> 0 bytes
-rw-r--r--docs/html/images/judgebio_kristian.jpgbin18145 -> 0 bytes
-rw-r--r--docs/html/images/judgebio_leon.jpgbin17302 -> 0 bytes
-rw-r--r--docs/html/index.jd1
-rw-r--r--docs/html/license.jd7
-rw-r--r--docs/html/offline.jd32
-rw-r--r--docs/html/roadmap.jd120
-rw-r--r--docs/html/robots.txt6
-rw-r--r--docs/html/sdk/1.1_r1/index.jd16
-rw-r--r--docs/html/sdk/1.1_r1/installing.jd43
-rw-r--r--docs/html/sdk/1.1_r1/upgrading.jd51
-rw-r--r--docs/html/sdk/RELEASENOTES.jd199
-rw-r--r--docs/html/sdk/android-1.1.jd13
-rw-r--r--docs/html/sdk/download.jd48
-rw-r--r--docs/html/sdk/sdk_toc.cs12
-rw-r--r--docs/html/sdk/terms.jd2
-rw-r--r--include/media/AudioSystem.h11
-rw-r--r--libs/audioflinger/A2dpAudioInterface.cpp3
-rw-r--r--libs/audioflinger/A2dpAudioInterface.h3
-rw-r--r--libs/audioflinger/AudioDumpInterface.h5
-rw-r--r--libs/audioflinger/AudioFlinger.cpp62
-rw-r--r--libs/audioflinger/AudioFlinger.h19
-rw-r--r--libs/audioflinger/AudioHardwareGeneric.cpp8
-rw-r--r--libs/audioflinger/AudioHardwareGeneric.h6
-rw-r--r--libs/audioflinger/AudioHardwareStub.cpp8
-rw-r--r--libs/audioflinger/AudioHardwareStub.h5
-rw-r--r--location/java/android/location/Location.java11
-rw-r--r--media/java/android/media/AsyncPlayer.java9
-rw-r--r--media/java/android/media/AudioManager.java72
-rw-r--r--media/java/android/media/AudioService.java37
-rw-r--r--media/java/android/media/AudioTrack.java33
-rw-r--r--media/java/android/media/IAudioService.aidl2
-rw-r--r--media/libmedia/AudioTrack.cpp2
-rw-r--r--media/libmedia/JetPlayer.cpp11
-rwxr-xr-xmedia/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java2
-rw-r--r--opengl/libs/EGL/egl.cpp8
-rw-r--r--preloaded-classes2
-rw-r--r--services/java/com/android/server/BatteryService.java7
-rw-r--r--services/java/com/android/server/DeviceStorageMonitorService.java58
-rw-r--r--services/java/com/android/server/GadgetService.java97
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java7
-rw-r--r--services/java/com/android/server/LocationManagerService.java1453
-rw-r--r--services/java/com/android/server/PowerManagerService.java46
-rw-r--r--services/java/com/android/server/SensorService.java4
-rw-r--r--services/java/com/android/server/SystemServer.java7
-rw-r--r--services/java/com/android/server/WindowManagerService.java86
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java54
-rw-r--r--services/java/com/android/server/am/BatteryStatsService.java59
-rw-r--r--services/java/com/android/server/status/AnimatedImageView.java1
-rw-r--r--services/java/com/android/server/status/StatusBarService.java80
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl32
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/DataConnectionTracker.java29
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GSMPhone.java9
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/MccTable.java10
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SIMRecords.java10
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java7
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java17
-rw-r--r--test-runner/android/test/ServiceTestCase.java4
-rw-r--r--test-runner/android/test/TestCaseUtil.java38
-rw-r--r--tests/AndroidTests/Android.mk2
-rw-r--r--tests/AndroidTests/DisabledTestApp/Android.mk2
-rw-r--r--tests/AndroidTests/EnabledTestApp/Android.mk2
-rw-r--r--tests/CoreTests/android/Android.mk2
-rw-r--r--tests/CoreTests/android/AndroidManifest.xml1
-rw-r--r--tests/CoreTests/android/core/TestHandler.java174
-rw-r--r--tests/CoreTests/com/android/internal/telephony/gsm/GSMPhoneTest.java568
-rw-r--r--tests/CoreTests/com/android/internal/telephony/gsm/GSMTestHandler.java118
-rw-r--r--tests/CoreTests/com/android/internal/telephony/gsm/SMSDispatcherTest.java15
-rw-r--r--tests/CoreTests/com/android/internal/telephony/gsm/SimPhoneBookTest.java11
-rw-r--r--tests/FrameworkTest/AndroidManifest.xml8
-rw-r--r--tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithFirstScreenUnSelectable.java (renamed from core/java/com/android/internal/os/HandlerHelper.java)31
-rw-r--r--tests/FrameworkTest/tests/src/com/android/frameworktest/focus/ScrollingThroughListOfFocusablesTest.java13
-rw-r--r--tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithFirstScreenUnSelectableTest.java64
301 files changed, 11372 insertions, 9584 deletions
diff --git a/api/current.xml b/api/current.xml
index 2e8db51..aa6471b 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -6411,6 +6411,17 @@
visibility="public"
>
</field>
+<field name="sharedUserLabel"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843361"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="shouldDisableView"
type="int"
transient="false"
@@ -31296,6 +31307,26 @@
visibility="public"
>
</field>
+<field name="sharedUserId"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="sharedUserLabel"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="signatures"
type="android.content.pm.Signature[]"
transient="false"
@@ -58689,8 +58720,8 @@
<parameter name="event" type="android.view.KeyEvent">
</parameter>
</method>
-<method name="onShowRequested"
- return="void"
+<method name="onShowInputRequested"
+ return="boolean"
abstract="false"
native="false"
synchronized="false"
@@ -58701,6 +58732,8 @@
>
<parameter name="flags" type="int">
</parameter>
+<parameter name="configChange" type="boolean">
+</parameter>
</method>
<method name="onStartCandidatesView"
return="void"
@@ -59405,6 +59438,21 @@
visibility="public"
>
</method>
+<method name="getNearestKeys"
+ return="int[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="x" type="int">
+</parameter>
+<parameter name="y" type="int">
+</parameter>
+</method>
<method name="getShiftKeyIndex"
return="int"
abstract="false"
@@ -61504,6 +61552,21 @@
<parameter name="dest" type="android.location.Location">
</parameter>
</method>
+<method name="dump"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="pw" type="android.util.Printer">
+</parameter>
+<parameter name="prefix" type="java.lang.String">
+</parameter>
+</method>
<method name="getAccuracy"
return="float"
abstract="false"
@@ -73532,544 +73595,6 @@
>
</field>
</class>
-<class name="BatteryStats"
- extends="java.lang.Object"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="BatteryStats"
- type="android.os.BatteryStats"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="computeBatteryRealtime"
- return="long"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="curTime" type="long">
-</parameter>
-<parameter name="which" type="int">
-</parameter>
-</method>
-<method name="computeBatteryUptime"
- return="long"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="curTime" type="long">
-</parameter>
-<parameter name="which" type="int">
-</parameter>
-</method>
-<method name="computeRealtime"
- return="long"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="curTime" type="long">
-</parameter>
-<parameter name="which" type="int">
-</parameter>
-</method>
-<method name="computeUptime"
- return="long"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="curTime" type="long">
-</parameter>
-<parameter name="which" type="int">
-</parameter>
-</method>
-<method name="dumpLocked"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="fd" type="java.io.FileDescriptor">
-</parameter>
-<parameter name="pw" type="java.io.PrintWriter">
-</parameter>
-<parameter name="args" type="java.lang.String[]">
-</parameter>
-</method>
-<method name="getBatteryRealtime"
- return="long"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="curTime" type="long">
-</parameter>
-</method>
-<method name="getBatteryUptime"
- return="long"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="curTime" type="long">
-</parameter>
-</method>
-<method name="getStartCount"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getUidStats"
- return="android.util.SparseArray&lt;? extends android.os.BatteryStats.Uid&gt;"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<field name="STATS_CURRENT"
- type="int"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="STATS_LAST"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="STATS_TOTAL"
- type="int"
- transient="false"
- volatile="false"
- value="0"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="STATS_UNPLUGGED"
- type="int"
- transient="false"
- volatile="false"
- value="3"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="WAKE_TYPE_FULL"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="WAKE_TYPE_PARTIAL"
- type="int"
- transient="false"
- volatile="false"
- value="0"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="WAKE_TYPE_WINDOW"
- type="int"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-</class>
-<class name="BatteryStats.Timer"
- extends="java.lang.Object"
- abstract="true"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="BatteryStats.Timer"
- type="android.os.BatteryStats.Timer"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="getCount"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="which" type="int">
-</parameter>
-</method>
-<method name="getTotalTime"
- return="long"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="now" type="long">
-</parameter>
-<parameter name="which" type="int">
-</parameter>
-</method>
-</class>
-<class name="BatteryStats.Uid"
- extends="java.lang.Object"
- abstract="true"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="BatteryStats.Uid"
- type="android.os.BatteryStats.Uid"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="getPackageStats"
- return="java.util.Map&lt;java.lang.String, ? extends android.os.BatteryStats.Uid.Pkg&gt;"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getProcessStats"
- return="java.util.Map&lt;java.lang.String, ? extends android.os.BatteryStats.Uid.Proc&gt;"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getSensorStats"
- return="java.util.Map&lt;java.lang.Integer, ? extends android.os.BatteryStats.Uid.Sensor&gt;"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getWakelockStats"
- return="java.util.Map&lt;java.lang.String, ? extends android.os.BatteryStats.Uid.Wakelock&gt;"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-</class>
-<class name="BatteryStats.Uid.Pkg"
- extends="java.lang.Object"
- abstract="true"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="BatteryStats.Uid.Pkg"
- type="android.os.BatteryStats.Uid.Pkg"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="getServiceStats"
- return="java.util.Map&lt;java.lang.String, ? extends android.os.BatteryStats.Uid.Pkg.Serv&gt;"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="getWakeups"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="which" type="int">
-</parameter>
-</method>
-</class>
-<class name="BatteryStats.Uid.Pkg.Serv"
- extends="java.lang.Object"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="BatteryStats.Uid.Pkg.Serv"
- type="android.os.BatteryStats.Uid.Pkg.Serv"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="getLaunches"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="which" type="int">
-</parameter>
-</method>
-<method name="getStartTime"
- return="long"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="now" type="long">
-</parameter>
-<parameter name="which" type="int">
-</parameter>
-</method>
-<method name="getStarts"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="which" type="int">
-</parameter>
-</method>
-</class>
-<class name="BatteryStats.Uid.Proc"
- extends="java.lang.Object"
- abstract="true"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="BatteryStats.Uid.Proc"
- type="android.os.BatteryStats.Uid.Proc"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="getStarts"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="which" type="int">
-</parameter>
-</method>
-<method name="getSystemTime"
- return="long"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="which" type="int">
-</parameter>
-</method>
-<method name="getUserTime"
- return="long"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="which" type="int">
-</parameter>
-</method>
-</class>
-<class name="BatteryStats.Uid.Sensor"
- extends="java.lang.Object"
- abstract="true"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="BatteryStats.Uid.Sensor"
- type="android.os.BatteryStats.Uid.Sensor"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="getSensorTime"
- return="android.os.BatteryStats.Timer"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-</class>
-<class name="BatteryStats.Uid.Wakelock"
- extends="java.lang.Object"
- abstract="true"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="BatteryStats.Uid.Wakelock"
- type="android.os.BatteryStats.Uid.Wakelock"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</constructor>
-<method name="getWakeTime"
- return="android.os.BatteryStats.Timer"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="type" type="int">
-</parameter>
-</method>
-</class>
<class name="Binder"
extends="java.lang.Object"
abstract="false"
@@ -115705,6 +115230,19 @@
<parameter name="value" type="int">
</parameter>
</method>
+<method name="removeAt"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="index" type="int">
+</parameter>
+</method>
<method name="size"
return="int"
abstract="false"
@@ -121687,7 +121225,7 @@
>
</field>
</class>
-<class name="OrientationListener"
+<class name="OrientationEventListener"
extends="java.lang.Object"
abstract="true"
static="false"
@@ -121695,6 +121233,83 @@
deprecated="not deprecated"
visibility="public"
>
+<constructor name="OrientationEventListener"
+ type="android.view.OrientationEventListener"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</constructor>
+<constructor name="OrientationEventListener"
+ type="android.view.OrientationEventListener"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="rate" type="int">
+</parameter>
+</constructor>
+<method name="disable"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="enable"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="onOrientationChanged"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="orientation" type="int">
+</parameter>
+</method>
+<field name="ORIENTATION_UNKNOWN"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="OrientationListener"
+ extends="java.lang.Object"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
<implements name="android.hardware.SensorListener">
</implements>
<constructor name="OrientationListener"
@@ -131777,6 +131392,17 @@
visibility="public"
>
</field>
+<field name="SCREEN_BRIGHTNESS_CHANGED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2048"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="SCREEN_ORIENTATION_CHANGED"
type="int"
transient="false"
@@ -131865,11 +131491,22 @@
visibility="public"
>
</field>
+<field name="SOFT_INPUT_STATE_ALWAYS_HIDDEN"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="SOFT_INPUT_STATE_ALWAYS_VISIBLE"
type="int"
transient="false"
volatile="false"
- value="4"
+ value="5"
static="true"
final="true"
deprecated="not deprecated"
@@ -131913,7 +131550,7 @@
type="int"
transient="false"
volatile="false"
- value="3"
+ value="4"
static="true"
final="true"
deprecated="not deprecated"
@@ -132263,6 +131900,16 @@
visibility="public"
>
</field>
+<field name="screenBrightness"
+ type="float"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="screenOrientation"
type="int"
transient="false"
@@ -144666,6 +144313,17 @@
visibility="public"
>
</method>
+<method name="getOnChronometerTickListener"
+ return="android.widget.Chronometer.OnChronometerTickListener"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="setBase"
return="void"
abstract="false"
@@ -144692,6 +144350,32 @@
<parameter name="format" type="java.lang.String">
</parameter>
</method>
+<method name="setOnChronometerTickListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.widget.Chronometer.OnChronometerTickListener">
+</parameter>
+</method>
+<method name="setStarted"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="started" type="boolean">
+</parameter>
+</method>
<method name="start"
return="void"
abstract="false"
@@ -144715,6 +144399,27 @@
>
</method>
</class>
+<interface name="Chronometer.OnChronometerTickListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onChronometerTick"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="chronometer" type="android.widget.Chronometer">
+</parameter>
+</method>
+</interface>
<class name="CompoundButton"
extends="android.widget.Button"
abstract="true"
@@ -151742,7 +151447,7 @@
<parameter name="v" type="android.view.View">
</parameter>
</method>
-<method name="setChronometer"
+<method name="setBitmap"
return="void"
abstract="false"
native="false"
@@ -151754,14 +151459,29 @@
>
<parameter name="viewId" type="int">
</parameter>
-<parameter name="base" type="long">
+<parameter name="methodName" type="java.lang.String">
</parameter>
-<parameter name="format" type="java.lang.String">
+<parameter name="value" type="android.graphics.Bitmap">
+</parameter>
+</method>
+<method name="setBoolean"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="viewId" type="int">
+</parameter>
+<parameter name="methodName" type="java.lang.String">
</parameter>
-<parameter name="running" type="boolean">
+<parameter name="value" type="boolean">
</parameter>
</method>
-<method name="setDrawableParameters"
+<method name="setByte"
return="void"
abstract="false"
native="false"
@@ -151773,18 +151493,65 @@
>
<parameter name="viewId" type="int">
</parameter>
-<parameter name="targetBackground" type="boolean">
+<parameter name="methodName" type="java.lang.String">
</parameter>
-<parameter name="alpha" type="int">
+<parameter name="value" type="byte">
+</parameter>
+</method>
+<method name="setChar"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="viewId" type="int">
</parameter>
-<parameter name="colorFilter" type="int">
+<parameter name="methodName" type="java.lang.String">
</parameter>
-<parameter name="mode" type="android.graphics.PorterDuff.Mode">
+<parameter name="value" type="char">
</parameter>
-<parameter name="level" type="int">
+</method>
+<method name="setCharSequence"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="viewId" type="int">
+</parameter>
+<parameter name="methodName" type="java.lang.String">
+</parameter>
+<parameter name="value" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="setChronometer"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="viewId" type="int">
+</parameter>
+<parameter name="base" type="long">
+</parameter>
+<parameter name="format" type="java.lang.String">
+</parameter>
+<parameter name="started" type="boolean">
</parameter>
</method>
-<method name="setFlipping"
+<method name="setDouble"
return="void"
abstract="false"
native="false"
@@ -151796,9 +151563,26 @@
>
<parameter name="viewId" type="int">
</parameter>
-<parameter name="flipping" type="boolean">
+<parameter name="methodName" type="java.lang.String">
</parameter>
-<parameter name="milliseconds" type="int">
+<parameter name="value" type="double">
+</parameter>
+</method>
+<method name="setFloat"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="viewId" type="int">
+</parameter>
+<parameter name="methodName" type="java.lang.String">
+</parameter>
+<parameter name="value" type="float">
</parameter>
</method>
<method name="setImageViewBitmap"
@@ -151846,6 +151630,40 @@
<parameter name="uri" type="android.net.Uri">
</parameter>
</method>
+<method name="setInt"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="viewId" type="int">
+</parameter>
+<parameter name="methodName" type="java.lang.String">
+</parameter>
+<parameter name="value" type="int">
+</parameter>
+</method>
+<method name="setLong"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="viewId" type="int">
+</parameter>
+<parameter name="methodName" type="java.lang.String">
+</parameter>
+<parameter name="value" type="long">
+</parameter>
+</method>
<method name="setOnClickPendingIntent"
return="void"
abstract="false"
@@ -151880,6 +151698,40 @@
<parameter name="indeterminate" type="boolean">
</parameter>
</method>
+<method name="setShort"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="viewId" type="int">
+</parameter>
+<parameter name="methodName" type="java.lang.String">
+</parameter>
+<parameter name="value" type="short">
+</parameter>
+</method>
+<method name="setString"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="viewId" type="int">
+</parameter>
+<parameter name="methodName" type="java.lang.String">
+</parameter>
+<parameter name="value" type="java.lang.String">
+</parameter>
+</method>
<method name="setTextColor"
return="void"
abstract="false"
@@ -151910,6 +151762,23 @@
<parameter name="text" type="java.lang.CharSequence">
</parameter>
</method>
+<method name="setUri"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="viewId" type="int">
+</parameter>
+<parameter name="methodName" type="java.lang.String">
+</parameter>
+<parameter name="value" type="android.net.Uri">
+</parameter>
+</method>
<method name="setViewVisibility"
return="void"
abstract="false"
@@ -151966,6 +151835,16 @@
deprecated="not deprecated"
visibility="public"
>
+<parameter name="ex" type="java.lang.Exception">
+</parameter>
+</constructor>
+<constructor name="RemoteViews.ActionException"
+ type="android.widget.RemoteViews.ActionException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
<parameter name="message" type="java.lang.String">
</parameter>
</constructor>
@@ -155024,6 +154903,17 @@
<parameter name="offset" type="int">
</parameter>
</method>
+<method name="clearComposingText"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="debug"
return="void"
abstract="false"
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 4621f57..e08230f 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -40,6 +40,18 @@ static void dumpstate(int full) {
PRINT("========================================================");
PRINT("== dumpstate");
PRINT("========================================================");
+ PRINT("------ MEMORY INFO ------");
+ DUMP("/proc/meminfo");
+ PRINT("------ CPU INFO ------");
+ EXEC7("top", "-n", "1", "-d", "1", "-m", "30", "-t");
+ PRINT("------ PROCRANK ------");
+ EXEC_XBIN("procrank");
+ PRINT("------ VIRTUAL MEMORY STATS ------");
+ DUMP("/proc/vmstat");
+ PRINT("------ SLAB INFO ------");
+ DUMP("/proc/slabinfo");
+ PRINT("------ ZONEINFO ------");
+ DUMP("/proc/zoneinfo");
PRINT("------ SYSTEM LOG ------");
EXEC4("logcat", "-v", "time", "-d", "*:v");
PRINT("------ VM TRACES ------");
@@ -67,20 +79,8 @@ static void dumpstate(int full) {
EXEC("ps");
PRINT("------ PROCESSES AND THREADS ------");
EXEC2("ps", "-t", "-p");
- PRINT("------ MEMORY INFO ------");
- DUMP("/proc/meminfo");
- PRINT("------ PSS INFO ------");
- EXEC8("top", "-n", "1", "-d", "0", "-m", "15", "-s", "pss");
- PRINT("------ PROCRANK ------");
- EXEC("procrank");
PRINT("------ LIBRANK ------");
- EXEC("librank");
- PRINT("------ VIRTUAL MEMORY STATS ------");
- DUMP("/proc/vmstat");
- PRINT("------ SLAB INFO ------");
- DUMP("/proc/slabinfo");
- PRINT("------ ZONEINFO ------");
- DUMP("/proc/zoneinfo");
+ EXEC_XBIN("librank");
PRINT("------ BINDER FAILED TRANSACTION LOG ------");
DUMP("/proc/binder/failed_transaction_log");
PRINT("");
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index b956f99..4e88e4b 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -43,6 +43,15 @@
run_command(&c, TIMEOUT); \
}
+#define EXEC_XBIN(cmd) \
+{ \
+ static struct Command c = { \
+ "/system/xbin/" cmd, \
+ { cmd, 0 } \
+ }; \
+ run_command(&c, TIMEOUT); \
+}
+
#define EXEC2(cmd, a1, a2) \
{ \
static struct Command c = { \
@@ -70,6 +79,15 @@
run_command(&c, TIMEOUT); \
}
+#define EXEC7(cmd, a1, a2, a3, a4, a5, a6, a7) \
+{ \
+ static struct Command c = { \
+ "/system/bin/" cmd, \
+ { cmd, a1, a2, a3, a4, a5, a6, a7, 0 } \
+ }; \
+ run_command(&c, TIMEOUT); \
+}
+
#define EXEC8(cmd, a1, a2, a3, a4, a5, a6, a7, a8) \
{ \
static struct Command c = { \
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index b59e9dc..1bed706 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -426,13 +426,9 @@ public final class PendingIntent implements Parcelable {
*/
@Override
public boolean equals(Object otherObj) {
- if (otherObj == null) {
- return false;
- }
- try {
+ if (otherObj instanceof PendingIntent) {
return mTarget.asBinder().equals(((PendingIntent)otherObj)
.mTarget.asBinder());
- } catch (ClassCastException e) {
}
return false;
}
@@ -442,6 +438,13 @@ public final class PendingIntent implements Parcelable {
return mTarget.asBinder().hashCode();
}
+ @Override
+ public String toString() {
+ return "PendingIntent{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " target " + (mTarget != null ? mTarget.asBinder() : null) + "}";
+ }
+
public int describeContents() {
return 0;
}
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 5744ddc..7b8256c 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -31,8 +31,6 @@ import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -64,7 +62,6 @@ import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import java.lang.ref.WeakReference;
-import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
/**
@@ -538,9 +535,9 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
testIntent = mVoiceAppSearchIntent;
}
if (testIntent != null) {
- List<ResolveInfo> list = getContext().getPackageManager().
- queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
- if (list.size() > 0) {
+ ResolveInfo ri = getContext().getPackageManager().
+ resolveActivity(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
+ if (ri != null) {
visibility = View.VISIBLE;
}
}
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 72692f4..a6a436f 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -327,11 +327,15 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
}
/**
- * Print the Service's state into the given stream.
+ * Print the Service's state into the given stream. This gets invoked if
+ * you run "adb shell dumpsys activity service <yourservicename>".
+ * This is distinct from "dumpsys <servicename>", which only works for
+ * named system services and which invokes the {@link IBinder#dump} method
+ * on the {@link IBinder} interface registered with ServiceManager.
*
* @param fd The raw file descriptor that the dump is being sent to.
* @param writer The PrintWriter to which you should dump your state. This will be
- * closed for you after you return.
+ * closed for you after you return.
* @param args additional arguments to the dump request.
*/
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
diff --git a/core/java/android/bluetooth/ScoSocket.java b/core/java/android/bluetooth/ScoSocket.java
index 75b3329..a43a08b 100644
--- a/core/java/android/bluetooth/ScoSocket.java
+++ b/core/java/android/bluetooth/ScoSocket.java
@@ -16,17 +16,12 @@
package android.bluetooth;
-import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;
-import java.io.IOException;
-import java.lang.Thread;
-
-
/**
* The Android Bluetooth API is not finalized, and *will* change. Use at your
* own risk.
@@ -56,7 +51,7 @@ public class ScoSocket {
private int mConnectedCode;
private int mClosedCode;
- private WakeLock mWakeLock; // held while STATE_CONNECTING or STATE_CONNECTED
+ private WakeLock mWakeLock; // held while in STATE_CONNECTING
static {
classInitNative();
@@ -130,6 +125,7 @@ public class ScoSocket {
public synchronized void close() {
if (DBG) log(this + " SCO OBJECT close() mState = " + mState);
+ acquireWakeLock();
mState = STATE_CLOSED;
closeNative();
releaseWakeLock();
@@ -152,19 +148,16 @@ public class ScoSocket {
mState = STATE_CLOSED;
}
mHandler.obtainMessage(mConnectedCode, mState, -1, this).sendToTarget();
- if (result < 0) {
- releaseWakeLock();
- }
+ releaseWakeLock();
}
private synchronized void onAccepted(int result) {
if (VDBG) log("onAccepted() " + this);
if (mState != STATE_ACCEPT) {
- if (DBG) log("Strange state" + this);
+ if (DBG) log("Strange state " + this);
return;
}
if (result >= 0) {
- acquireWakeLock();
mState = STATE_CONNECTED;
} else {
mState = STATE_CLOSED;
@@ -184,13 +177,13 @@ public class ScoSocket {
private void acquireWakeLock() {
if (!mWakeLock.isHeld()) {
mWakeLock.acquire();
- if (VDBG) log("mWakeLock.acquire()" + this);
+ if (VDBG) log("mWakeLock.acquire() " + this);
}
}
private void releaseWakeLock() {
if (mWakeLock.isHeld()) {
- if (VDBG) log("mWakeLock.release()" + this);
+ if (VDBG) log("mWakeLock.release() " + this);
mWakeLock.release();
}
}
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index ee08eea..08f6191 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -79,7 +79,7 @@ import android.util.Log;
* <p>The BroadcastReceiver class (when launched as a component through
* a manifest's {@link android.R.styleable#AndroidManifestReceiver &lt;receiver&gt;}
* tag) is an important part of an
- * <a href="{@docRoot}intro/lifecycle.html">application's overall lifecycle</a>.</p>
+ * <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">application's overall lifecycle</a>.</p>
*
* <p>Topics covered here:
* <ol>
@@ -135,7 +135,7 @@ import android.util.Log;
* tag in their <code>AndroidManifest.xml</code>) will be able to send an
* Intent to the receiver.
*
- * <p>See the <a href="{@docRoot}devel/security.html">Security Model</a>
+ * <p>See the <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a>
* document for more information on permissions and security in general.
*
* <a name="ProcessLifecycle"></a>
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 226c5ab..3a64cee 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -41,8 +41,8 @@ import java.io.FileNotFoundException;
* multiple applications you can use a database directly via
* {@link android.database.sqlite.SQLiteDatabase}.
*
- * <p>See <a href="{@docRoot}devel/data/contentproviders.html">this page</a> for more information on
- * content providers.</p>
+ * <p>For more information, read <a href="{@docRoot}guide/topics/providers/content-providers.html">Content
+ * Providers</a>.</p>
*
* <p>When a request is made via
* a {@link ContentResolver} the system inspects the authority of the given URI and passes the
@@ -226,9 +226,9 @@ public abstract class ContentProvider implements ComponentCallbacks {
/**
* Return the name of the permission required for read-only access to
* this content provider. This method can be called from multiple
- * threads, as described in the
- * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of
- * the Application Model overview</a>.
+ * threads, as described in
+ * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
+ * Processes and Threads</a>.
*/
public final String getReadPermission() {
return mReadPermission;
@@ -248,9 +248,9 @@ public abstract class ContentProvider implements ComponentCallbacks {
/**
* Return the name of the permission required for read/write access to
* this content provider. This method can be called from multiple
- * threads, as described in the
- * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of
- * the Application Model overview</a>.
+ * threads, as described in
+ * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
+ * Processes and Threads</a>.
*/
public final String getWritePermission() {
return mWritePermission;
@@ -273,9 +273,9 @@ public abstract class ContentProvider implements ComponentCallbacks {
* Receives a query request from a client in a local process, and
* returns a Cursor. This is called internally by the {@link ContentResolver}.
* This method can be called from multiple
- * threads, as described in the
- * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of
- * the Application Model overview</a>.
+ * threads, as described in
+ * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
+ * Processes and Threads</a>.
* <p>
* Example client call:<p>
* <pre>// Request a specific record.
@@ -330,9 +330,9 @@ public abstract class ContentProvider implements ComponentCallbacks {
* <code>vnd.android.cursor.item</code> for a single record,
* or <code>vnd.android.cursor.dir/</code> for multiple items.
* This method can be called from multiple
- * threads, as described in the
- * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of
- * the Application Model overview</a>.
+ * threads, as described in
+ * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
+ * Processes and Threads</a>.
*
* @param uri the URI to query.
* @return a MIME type string, or null if there is no type.
@@ -344,9 +344,9 @@ public abstract class ContentProvider implements ComponentCallbacks {
* As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
* after inserting.
* This method can be called from multiple
- * threads, as described in the
- * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of the
- * Application Model overview</a>.
+ * threads, as described in
+ * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
+ * Processes and Threads</a>.
* @param uri The content:// URI of the insertion request.
* @param values A set of column_name/value pairs to add to the database.
* @return The URI for the newly inserted item.
@@ -359,9 +359,9 @@ public abstract class ContentProvider implements ComponentCallbacks {
* As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
* after inserting.
* This method can be called from multiple
- * threads, as described in the
- * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of
- * the Application Model overview</a>.
+ * threads, as described in
+ * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
+ * Processes and Threads</a>.
*
* @param uri The content:// URI of the insertion request.
* @param values An array of sets of column_name/value pairs to add to the database.
@@ -382,9 +382,9 @@ public abstract class ContentProvider implements ComponentCallbacks {
* As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyDelete()}
* after deleting.
* This method can be called from multiple
- * threads, as described in the
- * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of the
- * Application Model overview</a>.
+ * threads, as described in
+ * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
+ * Processes and Threads</a>.
*
* <p>The implementation is responsible for parsing out a row ID at the end
* of the URI, if a specific row is being deleted. That is, the client would
@@ -405,9 +405,9 @@ public abstract class ContentProvider implements ComponentCallbacks {
* As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
* after updating.
* This method can be called from multiple
- * threads, as described in the
- * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of the
- * Application Model overview</a>.
+ * threads, as described in
+ * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
+ * Processes and Threads</a>.
*
* @param uri The URI to query. This can potentially have a record ID if this
* is an update request for a specific record.
@@ -422,9 +422,9 @@ public abstract class ContentProvider implements ComponentCallbacks {
/**
* Open a file blob associated with a content URI.
* This method can be called from multiple
- * threads, as described in the
- * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of the
- * Application Model overview</a>.
+ * threads, as described in
+ * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
+ * Processes and Threads</a>.
*
* <p>Returns a
* ParcelFileDescriptor, from which you can obtain a
@@ -507,9 +507,9 @@ public abstract class ContentProvider implements ComponentCallbacks {
* This is intended for use by the sync system. If null then this
* content provider is considered not syncable.
* This method can be called from multiple
- * threads, as described in the
- * <a href="{@docRoot}intro/appmodel.html#Threads">Threading section of
- * the Application Model overview</a>.
+ * threads, as described in
+ * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
+ * Processes and Threads</a>.
*
* @return the SyncAdapter that is to be used by this ContentProvider, or null
* if this ContentProvider is not syncable
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index c4d3f9d..c1c3b49 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1766,9 +1766,9 @@ public class Intent implements Parcelable {
* next task activity) defines an atomic group of activities that the
* user can move to. Tasks can be moved to the foreground and background;
* all of the activities inside of a particular task always remain in
- * the same order. See the
- * <a href="{@docRoot}intro/appmodel.html">Application Model</a>
- * documentation for more details on tasks.
+ * the same order. See
+ * <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application Fundamentals:
+ * Activities and Tasks</a> for more details on tasks.
*
* <p>This flag is generally used by activities that want
* to present a "launcher" style behavior: they give the user a list of
@@ -1801,9 +1801,8 @@ public class Intent implements Parcelable {
* <p>This flag is ignored if
* {@link #FLAG_ACTIVITY_NEW_TASK} is not set.
*
- * <p>See the
- * <a href="{@docRoot}intro/appmodel.html">Application Model</a>
- * documentation for more details on tasks.
+ * <p>See <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application Fundamentals:
+ * Activities and Tasks</a> for more details on tasks.
*/
public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 0x08000000;
/**
@@ -1831,9 +1830,8 @@ public class Intent implements Parcelable {
* especially useful, for example, when launching an activity from the
* notification manager.
*
- * <p>See the
- * <a href="{@docRoot}intro/appmodel.html">Application Model</a>
- * documentation for more details on tasks.
+ * <p>See <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application Fundamentals:
+ * Activities and Tasks</a> for more details on tasks.
*/
public static final int FLAG_ACTIVITY_CLEAR_TOP = 0x04000000;
/**
@@ -3919,8 +3917,8 @@ public class Intent implements Parcelable {
* FLAG_RECEIVER_* flags are all for use with
* {@link Context#sendBroadcast(Intent) Context.sendBroadcast()}.
*
- * <p>See the <a href="{@docRoot}intro/appmodel.html">Application Model</a>
- * documentation for important information on how some of these options impact
+ * <p>See the <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application Fundamentals:
+ * Activities and Tasks</a> documentation for important information on how some of these options impact
* the behavior of your application.
*
* @param flags The desired flags.
@@ -4195,14 +4193,11 @@ public class Intent implements Parcelable {
@Override
public boolean equals(Object obj) {
- Intent other;
- try {
- other = ((FilterComparison)obj).mIntent;
- } catch (ClassCastException e) {
- return false;
+ if (obj instanceof FilterComparison) {
+ Intent other = ((FilterComparison)obj).mIntent;
+ return mIntent.filterEquals(other);
}
-
- return mIntent.filterEquals(other);
+ return false;
}
@Override
diff --git a/core/java/android/content/package.html b/core/java/android/content/package.html
index 7b3e8cf..dd5360f 100644
--- a/core/java/android/content/package.html
+++ b/core/java/android/content/package.html
@@ -50,9 +50,9 @@ an application's resources and transfer data between applications.</p>
<p>This topic includes a terminology list associated with resources, and a series
of examples of using resources in code. For a complete guide on creating and
- using resources, see the document on <a href="{@docRoot}devel/resources-i18n.html">Resources
+ using resources, see the document on <a href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources
and Internationalization</a>. For a reference on the supported Android resource types,
- see <a href="{@docRoot}reference/available-resources.html">Available Resource Types</a>.</p>
+ see <a href="{@docRoot}guide/topics/resources/available-resources.html">Available Resource Types</a>.</p>
<p>The Android resource system keeps track of all non-code
assets associated with an application. You use the
{@link android.content.res.Resources Resources} class to access your
@@ -175,7 +175,8 @@ download files with new appearances.</p>
<p>This section gives a few quick examples you can use to make your own resources.
For more details on how to define and use resources, see <a
- href="{@docRoot}devel/resources-i18n.html">Resources</a>. </p>
+ href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources and
+ Internationalization</a>. </p>
<a name="UsingSystemResources"></a>
<h4>Using System Resources</h4>
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 994afc8..d9326f2 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -29,6 +29,20 @@ public class PackageInfo implements Parcelable {
public String versionName;
/**
+ * The shared user ID name of this package, as specified by the &lt;manifest&gt;
+ * tag's {@link android.R.styleable#AndroidManifest_sharedUserId sharedUserId}
+ * attribute.
+ */
+ public String sharedUserId;
+
+ /**
+ * The shared user ID label of this package, as specified by the &lt;manifest&gt;
+ * tag's {@link android.R.styleable#AndroidManifest_sharedUserLabel sharedUserLabel}
+ * attribute.
+ */
+ public int sharedUserLabel;
+
+ /**
* Information collected from the &lt;application&gt; tag, or null if
* there was none.
*/
@@ -130,6 +144,8 @@ public class PackageInfo implements Parcelable {
dest.writeString(packageName);
dest.writeInt(versionCode);
dest.writeString(versionName);
+ dest.writeString(sharedUserId);
+ dest.writeInt(sharedUserLabel);
if (applicationInfo != null) {
dest.writeInt(1);
applicationInfo.writeToParcel(dest, parcelableFlags);
@@ -163,6 +179,8 @@ public class PackageInfo implements Parcelable {
packageName = source.readString();
versionCode = source.readInt();
versionName = source.readString();
+ sharedUserId = source.readString();
+ sharedUserLabel = source.readInt();
int hasApp = source.readInt();
if (hasApp != 0) {
applicationInfo = ApplicationInfo.CREATOR.createFromParcel(source);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e08f1d1..4ae8b08 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -101,6 +101,8 @@ public class PackageParser {
pi.packageName = p.packageName;
pi.versionCode = p.mVersionCode;
pi.versionName = p.mVersionName;
+ pi.sharedUserId = p.mSharedUserId;
+ pi.sharedUserLabel = p.mSharedUserLabel;
pi.applicationInfo = p.applicationInfo;
if ((flags&PackageManager.GET_GIDS) != 0) {
pi.gids = gids;
@@ -585,6 +587,8 @@ public class PackageParser {
return null;
}
pkg.mSharedUserId = str.intern();
+ pkg.mSharedUserLabel = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifest_sharedUserLabel, 0);
}
sa.recycle();
@@ -2045,6 +2049,9 @@ public class PackageParser {
// The shared user id that this package wants to use.
public String mSharedUserId;
+ // The shared user label that this package wants to use.
+ public int mSharedUserLabel;
+
// Signatures that were read from the package.
public Signature mSignatures[];
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index 2ff7294..10f3806 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -84,6 +84,7 @@ public class DatabaseUtils {
code = 9;
} else {
reply.writeException(e);
+ Log.e(TAG, "Writing exception to parcel", e);
return;
}
reply.writeInt(code);
diff --git a/core/java/android/inputmethodservice/ExtractEditText.java b/core/java/android/inputmethodservice/ExtractEditText.java
index d9f10a9..52f8209 100644
--- a/core/java/android/inputmethodservice/ExtractEditText.java
+++ b/core/java/android/inputmethodservice/ExtractEditText.java
@@ -102,7 +102,7 @@ public class ExtractEditText extends EditText {
* highlight and cursor will be displayed.
*/
@Override public boolean hasWindowFocus() {
- return true;
+ return this.isEnabled() ? true : false;
}
/**
@@ -110,7 +110,7 @@ public class ExtractEditText extends EditText {
* highlight and cursor will be displayed.
*/
@Override public boolean isFocused() {
- return true;
+ return this.isEnabled() ? true : false;
}
/**
@@ -118,7 +118,6 @@ public class ExtractEditText extends EditText {
* highlight and cursor will be displayed.
*/
@Override public boolean hasFocus() {
- return true;
+ return this.isEnabled() ? true : false;
}
-
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index c884120..4be1fc7 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -229,9 +229,11 @@ public class InputMethodService extends AbstractInputMethodService {
InputConnection mStartedInputConnection;
EditorInfo mInputEditorInfo;
+ int mShowInputFlags;
boolean mShowInputRequested;
boolean mLastShowInputRequested;
int mCandidatesVisibility;
+ CompletionInfo[] mCurCompletions;
boolean mShowInputForced;
@@ -328,6 +330,7 @@ public class InputMethodService extends AbstractInputMethodService {
*/
public void hideSoftInput() {
if (DEBUG) Log.v(TAG, "hideSoftInput()");
+ mShowInputFlags = 0;
mShowInputRequested = false;
mShowInputForced = false;
hideWindow();
@@ -338,7 +341,10 @@ public class InputMethodService extends AbstractInputMethodService {
*/
public void showSoftInput(int flags) {
if (DEBUG) Log.v(TAG, "showSoftInput()");
- onShowRequested(flags);
+ mShowInputFlags = 0;
+ if (onShowInputRequested(flags, false)) {
+ showWindow(true);
+ }
}
}
@@ -364,6 +370,7 @@ public class InputMethodService extends AbstractInputMethodService {
if (!isEnabled()) {
return;
}
+ mCurCompletions = completions;
onDisplayCompletions(completions);
}
@@ -557,8 +564,9 @@ public class InputMethodService extends AbstractInputMethodService {
super.onConfigurationChanged(newConfig);
boolean visible = mWindowVisible;
+ int showFlags = mShowInputFlags;
boolean showingInput = mShowInputRequested;
- boolean showingForced = mShowInputForced;
+ CompletionInfo[] completions = mCurCompletions;
initViews();
mInputViewStarted = false;
mCandidatesViewStarted = false;
@@ -567,19 +575,24 @@ public class InputMethodService extends AbstractInputMethodService {
getCurrentInputEditorInfo(), true);
}
if (visible) {
- if (showingForced) {
- // If we are showing the full soft keyboard, then go through
- // this path to take care of current decisions about fullscreen
- // etc.
- onShowRequested(InputMethod.SHOW_FORCED|InputMethod.SHOW_EXPLICIT);
- } else if (showingInput) {
- // If we are showing the full soft keyboard, then go through
- // this path to take care of current decisions about fullscreen
- // etc.
- onShowRequested(InputMethod.SHOW_EXPLICIT);
- } else {
- // Otherwise just put it back for its candidates.
+ if (showingInput) {
+ // If we were last showing the soft keyboard, try to do so again.
+ if (onShowInputRequested(showFlags, true)) {
+ showWindow(true);
+ if (completions != null) {
+ mCurCompletions = completions;
+ onDisplayCompletions(completions);
+ }
+ } else {
+ hideWindow();
+ }
+ } else if (mCandidatesVisibility == View.VISIBLE) {
+ // If the candidates are currently visible, make sure the
+ // window is shown for them.
showWindow(false);
+ } else {
+ // Otherwise hide the window.
+ hideWindow();
}
}
}
@@ -1065,36 +1078,42 @@ public class InputMethodService extends AbstractInputMethodService {
* The system has decided that it may be time to show your input method.
* This is called due to a corresponding call to your
* {@link InputMethod#showSoftInput(int) InputMethod.showSoftInput(int)}
- * method. The default implementation simply calls
- * {@link #showWindow(boolean)}, except if the
- * {@link InputMethod#SHOW_EXPLICIT InputMethod.SHOW_EXPLICIT} flag is
- * not set and the input method is running in fullscreen mode.
+ * method. The default implementation uses
+ * {@link #onEvaluateInputViewShown()}, {@link #onEvaluateFullscreenMode()},
+ * and the current configuration to decide whether the input view should
+ * be shown at this point.
*
* @param flags Provides additional information about the show request,
* as per {@link InputMethod#showSoftInput(int) InputMethod.showSoftInput(int)}.
+ * @param configChange This is true if we are re-showing due to a
+ * configuration change.
+ * @return Returns true to indicate that the window should be shown.
*/
- public void onShowRequested(int flags) {
+ public boolean onShowInputRequested(int flags, boolean configChange) {
if (!onEvaluateInputViewShown()) {
- return;
+ return false;
}
if ((flags&InputMethod.SHOW_EXPLICIT) == 0) {
- if (onEvaluateFullscreenMode()) {
+ if (!configChange && onEvaluateFullscreenMode()) {
// Don't show if this is not explicitly requested by the user and
// the input method is fullscreen. That would be too disruptive.
- return;
+ // However, we skip this change for a config change, since if
+ // the IME is already shown we do want to go into fullscreen
+ // mode at this point.
+ return false;
}
Configuration config = getResources().getConfiguration();
if (config.keyboard != Configuration.KEYBOARD_NOKEYS) {
// And if the device has a hard keyboard, even if it is
// currently hidden, don't show the input method implicitly.
// These kinds of devices don't need it that much.
- return;
+ return false;
}
}
if ((flags&InputMethod.SHOW_FORCED) != 0) {
mShowInputForced = true;
}
- showWindow(true);
+ return true;
}
public void showWindow(boolean showInput) {
@@ -1106,7 +1125,6 @@ public class InputMethodService extends AbstractInputMethodService {
+ " mInputStarted=" + mInputStarted);
boolean doShowInput = false;
boolean wasVisible = mWindowVisible;
- boolean wasCreated = mWindowCreated;
mWindowVisible = true;
if (!mShowInputRequested) {
if (mInputStarted) {
@@ -1240,6 +1258,7 @@ public class InputMethodService extends AbstractInputMethodService {
}
mInputStarted = false;
mStartedInputConnection = null;
+ mCurCompletions = null;
}
void doStartInput(InputConnection ic, EditorInfo attribute, boolean restarting) {
@@ -1550,7 +1569,11 @@ public class InputMethodService extends AbstractInputMethodService {
eet.setInputType(inputType);
eet.setHint(mInputEditorInfo.hintText);
if (mExtractedText != null) {
+ eet.setEnabled(true);
eet.setExtractedText(mExtractedText);
+ } else {
+ eet.setEnabled(false);
+ eet.setText("");
}
} finally {
eet.finishInternalChanges();
@@ -1586,7 +1609,8 @@ public class InputMethodService extends AbstractInputMethodService {
p.println(" mShowInputRequested=" + mShowInputRequested
+ " mLastShowInputRequested=" + mLastShowInputRequested
- + " mShowInputForced=" + mShowInputForced);
+ + " mShowInputForced=" + mShowInputForced
+ + " mShowInputFlags=0x" + Integer.toHexString(mShowInputFlags));
p.println(" mCandidatesVisibility=" + mCandidatesVisibility
+ " mFullscreenApplied=" + mFullscreenApplied
+ " mIsFullscreen=" + mIsFullscreen);
diff --git a/core/java/android/inputmethodservice/Keyboard.java b/core/java/android/inputmethodservice/Keyboard.java
index 228acbe..6a560ce 100755
--- a/core/java/android/inputmethodservice/Keyboard.java
+++ b/core/java/android/inputmethodservice/Keyboard.java
@@ -132,7 +132,19 @@ public class Keyboard {
/** Keyboard mode, or zero, if none. */
private int mKeyboardMode;
+
+ // Variables for pre-computing nearest keys.
+ private static final int GRID_WIDTH = 10;
+ private static final int GRID_HEIGHT = 5;
+ private static final int GRID_SIZE = GRID_WIDTH * GRID_HEIGHT;
+ private int mCellWidth;
+ private int mCellHeight;
+ private int[][] mGridNeighbors;
+ private int mProximityThreshold;
+ /** Number of key widths from current touch point to search for nearest keys. */
+ private static float SEARCH_DISTANCE = 1.4f;
+
/**
* Container for keys in the keyboard. All keys in a row are at the same Y-coordinate.
* Some of the key size defaults can be overridden per row from what the {@link Keyboard}
@@ -637,6 +649,52 @@ public class Keyboard {
public int getShiftKeyIndex() {
return mShiftKeyIndex;
}
+
+ private void computeNearestNeighbors() {
+ // Round-up so we don't have any pixels outside the grid
+ mCellWidth = (getMinWidth() + GRID_WIDTH - 1) / GRID_WIDTH;
+ mCellHeight = (getHeight() + GRID_HEIGHT - 1) / GRID_HEIGHT;
+ mGridNeighbors = new int[GRID_SIZE][];
+ int[] indices = new int[mKeys.size()];
+ final int gridWidth = GRID_WIDTH * mCellWidth;
+ final int gridHeight = GRID_HEIGHT * mCellHeight;
+ for (int x = 0; x < gridWidth; x += mCellWidth) {
+ for (int y = 0; y < gridHeight; y += mCellHeight) {
+ int count = 0;
+ for (int i = 0; i < mKeys.size(); i++) {
+ final Key key = mKeys.get(i);
+ if (key.squaredDistanceFrom(x, y) < mProximityThreshold ||
+ key.squaredDistanceFrom(x + mCellWidth - 1, y) < mProximityThreshold ||
+ key.squaredDistanceFrom(x + mCellWidth - 1, y + mCellHeight - 1)
+ < mProximityThreshold ||
+ key.squaredDistanceFrom(x, y + mCellHeight - 1) < mProximityThreshold) {
+ indices[count++] = i;
+ }
+ }
+ int [] cell = new int[count];
+ System.arraycopy(indices, 0, cell, 0, count);
+ mGridNeighbors[(y / mCellHeight) * GRID_WIDTH + (x / mCellWidth)] = cell;
+ }
+ }
+ }
+
+ /**
+ * Returns the indices of the keys that are closest to the given point.
+ * @param x the x-coordinate of the point
+ * @param y the y-coordinate of the point
+ * @return the array of integer indices for the nearest keys to the given point. If the given
+ * point is out of range, then an array of size zero is returned.
+ */
+ public int[] getNearestKeys(int x, int y) {
+ if (mGridNeighbors == null) computeNearestNeighbors();
+ if (x >= 0 && x < getMinWidth() && y >= 0 && y < getHeight()) {
+ int index = (y / mCellHeight) * GRID_WIDTH + (x / mCellWidth);
+ if (index < GRID_SIZE) {
+ return mGridNeighbors[index];
+ }
+ }
+ return new int[0];
+ }
protected Row createRowFromXml(Resources res, XmlResourceParser parser) {
return new Row(res, this, parser);
@@ -738,6 +796,8 @@ public class Keyboard {
mDefaultVerticalGap = getDimensionOrFraction(a,
com.android.internal.R.styleable.Keyboard_verticalGap,
mDisplayHeight, 0);
+ mProximityThreshold = (int) (mDefaultWidth * SEARCH_DISTANCE);
+ mProximityThreshold = mProximityThreshold * mProximityThreshold; // Square it for comparison
a.recycle();
}
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index b8bd10d..886e688 100755
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -159,6 +159,9 @@ public class KeyboardView extends View implements View.OnClickListener {
private static final int MSG_REPEAT = 3;
private static final int MSG_LONGPRESS = 4;
+ private static final int DELAY_BEFORE_PREVIEW = 70;
+ private static final int DELAY_AFTER_PREVIEW = 60;
+
private int mVerticalCorrection;
private int mProximityThreshold;
@@ -219,7 +222,7 @@ public class KeyboardView extends View implements View.OnClickListener {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SHOW_PREVIEW:
- mPreviewText.setVisibility(VISIBLE);
+ showKey(msg.arg1);
break;
case MSG_REMOVE_PREVIEW:
mPreviewText.setVisibility(INVISIBLE);
@@ -234,7 +237,6 @@ public class KeyboardView extends View implements View.OnClickListener {
openPopupIfRequired((MotionEvent) msg.obj);
break;
}
-
}
};
@@ -533,10 +535,10 @@ public class KeyboardView extends View implements View.OnClickListener {
dimensionSum += Math.min(key.width, key.height) + key.gap;
}
if (dimensionSum < 0 || length == 0) return;
- mProximityThreshold = (int) (dimensionSum * 1.5f / length);
+ mProximityThreshold = (int) (dimensionSum * 1.4f / length);
mProximityThreshold *= mProximityThreshold; // Square it
}
-
+
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
@@ -647,9 +649,10 @@ public class KeyboardView extends View implements View.OnClickListener {
int closestKey = NOT_A_KEY;
int closestKeyDist = mProximityThreshold + 1;
java.util.Arrays.fill(mDistances, Integer.MAX_VALUE);
- final int keyCount = keys.length;
+ int [] nearestKeyIndices = mKeyboard.getNearestKeys(x, y);
+ final int keyCount = nearestKeyIndices.length;
for (int i = 0; i < keyCount; i++) {
- final Key key = keys[i];
+ final Key key = keys[nearestKeyIndices[i]];
int dist = 0;
boolean isInside = key.isInside(x,y);
if (((mProximityCorrectOn
@@ -660,7 +663,7 @@ public class KeyboardView extends View implements View.OnClickListener {
final int nCodes = key.codes.length;
if (dist < closestKeyDist) {
closestKeyDist = dist;
- closestKey = i;
+ closestKey = nearestKeyIndices[i];
}
if (allKeys == null) continue;
@@ -674,9 +677,6 @@ public class KeyboardView extends View implements View.OnClickListener {
allKeys.length - j - nCodes);
for (int c = 0; c < nCodes; c++) {
allKeys[j + c] = key.codes[c];
- if (shifted) {
- //allKeys[j + c] = Character.toUpperCase(key.codes[c]);
- }
mDistances[j + c] = dist;
}
break;
@@ -685,7 +685,7 @@ public class KeyboardView extends View implements View.OnClickListener {
}
if (isInside) {
- primaryIndex = i;
+ primaryIndex = nearestKeyIndices[i];
}
}
if (primaryIndex == NOT_A_KEY) {
@@ -696,7 +696,7 @@ public class KeyboardView extends View implements View.OnClickListener {
private void detectAndSendKey(int x, int y, long eventTime) {
int index = mCurrentKey;
- if (index != NOT_A_KEY) {
+ if (index != NOT_A_KEY && index < mKeys.length) {
final Key key = mKeys[index];
if (key.text != null) {
for (int i = 0; i < key.text.length(); i++) {
@@ -763,70 +763,83 @@ public class KeyboardView extends View implements View.OnClickListener {
if (previewPopup.isShowing()) {
if (keyIndex == NOT_A_KEY) {
mHandler.sendMessageDelayed(mHandler
- .obtainMessage(MSG_REMOVE_PREVIEW), 60);
+ .obtainMessage(MSG_REMOVE_PREVIEW),
+ DELAY_AFTER_PREVIEW);
}
}
if (keyIndex != NOT_A_KEY) {
- Key key = keys[keyIndex];
- if (key.icon != null) {
- mPreviewText.setCompoundDrawables(null, null, null,
- key.iconPreview != null ? key.iconPreview : key.icon);
- mPreviewText.setText(null);
- } else {
- mPreviewText.setCompoundDrawables(null, null, null, null);
- mPreviewText.setText(getPreviewText(key));
- if (key.label.length() > 1 && key.codes.length < 2) {
- mPreviewText.setTextSize(mLabelTextSize);
- mPreviewText.setTypeface(Typeface.DEFAULT_BOLD);
- } else {
- mPreviewText.setTextSize(mPreviewTextSizeLarge);
- mPreviewText.setTypeface(Typeface.DEFAULT);
- }
- }
- mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
- int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), key.width
- + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight());
- final int popupHeight = mPreviewHeight;
- LayoutParams lp = mPreviewText.getLayoutParams();
- if (lp != null) {
- lp.width = popupWidth;
- lp.height = popupHeight;
- }
- if (!mPreviewCentered) {
- mPopupPreviewX = key.x - mPreviewText.getPaddingLeft() + mPaddingLeft;
- mPopupPreviewY = key.y - popupHeight + mPreviewOffset;
- } else {
- // TODO: Fix this if centering is brought back
- mPopupPreviewX = 160 - mPreviewText.getMeasuredWidth() / 2;
- mPopupPreviewY = - mPreviewText.getMeasuredHeight();
- }
- mHandler.removeMessages(MSG_REMOVE_PREVIEW);
- if (mOffsetInWindow == null) {
- mOffsetInWindow = new int[2];
- getLocationInWindow(mOffsetInWindow);
- mOffsetInWindow[0] += mMiniKeyboardOffsetX; // Offset may be zero
- mOffsetInWindow[1] += mMiniKeyboardOffsetY; // Offset may be zero
- }
- // Set the preview background state
- mPreviewText.getBackground().setState(
- key.popupResId != 0 ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET);
- if (previewPopup.isShowing()) {
- previewPopup.update(mPopupPreviewX + mOffsetInWindow[0],
- mPopupPreviewY + mOffsetInWindow[1],
- popupWidth, popupHeight);
+ if (previewPopup.isShowing() && mPreviewText.getVisibility() == VISIBLE) {
+ // Show right away, if it's already visible and finger is moving around
+ showKey(keyIndex);
} else {
- previewPopup.setWidth(popupWidth);
- previewPopup.setHeight(popupHeight);
- previewPopup.showAtLocation(mPopupParent, Gravity.NO_GRAVITY,
- mPopupPreviewX + mOffsetInWindow[0],
- mPopupPreviewY + mOffsetInWindow[1]);
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(MSG_SHOW_PREVIEW, keyIndex, 0),
+ DELAY_BEFORE_PREVIEW);
}
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_PREVIEW, keyIndex, 0),
- ViewConfiguration.getTapTimeout());
}
}
}
+
+ private void showKey(final int keyIndex) {
+ final PopupWindow previewPopup = mPreviewPopup;
+ final Key[] keys = mKeys;
+ Key key = keys[keyIndex];
+ if (key.icon != null) {
+ mPreviewText.setCompoundDrawables(null, null, null,
+ key.iconPreview != null ? key.iconPreview : key.icon);
+ mPreviewText.setText(null);
+ } else {
+ mPreviewText.setCompoundDrawables(null, null, null, null);
+ mPreviewText.setText(getPreviewText(key));
+ if (key.label.length() > 1 && key.codes.length < 2) {
+ mPreviewText.setTextSize(mLabelTextSize);
+ mPreviewText.setTypeface(Typeface.DEFAULT_BOLD);
+ } else {
+ mPreviewText.setTextSize(mPreviewTextSizeLarge);
+ mPreviewText.setTypeface(Typeface.DEFAULT);
+ }
+ }
+ mPreviewText.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+ int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), key.width
+ + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight());
+ final int popupHeight = mPreviewHeight;
+ LayoutParams lp = mPreviewText.getLayoutParams();
+ if (lp != null) {
+ lp.width = popupWidth;
+ lp.height = popupHeight;
+ }
+ if (!mPreviewCentered) {
+ mPopupPreviewX = key.x - mPreviewText.getPaddingLeft() + mPaddingLeft;
+ mPopupPreviewY = key.y - popupHeight + mPreviewOffset;
+ } else {
+ // TODO: Fix this if centering is brought back
+ mPopupPreviewX = 160 - mPreviewText.getMeasuredWidth() / 2;
+ mPopupPreviewY = - mPreviewText.getMeasuredHeight();
+ }
+ mHandler.removeMessages(MSG_REMOVE_PREVIEW);
+ if (mOffsetInWindow == null) {
+ mOffsetInWindow = new int[2];
+ getLocationInWindow(mOffsetInWindow);
+ mOffsetInWindow[0] += mMiniKeyboardOffsetX; // Offset may be zero
+ mOffsetInWindow[1] += mMiniKeyboardOffsetY; // Offset may be zero
+ }
+ // Set the preview background state
+ mPreviewText.getBackground().setState(
+ key.popupResId != 0 ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET);
+ if (previewPopup.isShowing()) {
+ previewPopup.update(mPopupPreviewX + mOffsetInWindow[0],
+ mPopupPreviewY + mOffsetInWindow[1],
+ popupWidth, popupHeight);
+ } else {
+ previewPopup.setWidth(popupWidth);
+ previewPopup.setHeight(popupHeight);
+ previewPopup.showAtLocation(mPopupParent, Gravity.NO_GRAVITY,
+ mPopupPreviewX + mOffsetInWindow[0],
+ mPopupPreviewY + mOffsetInWindow[1]);
+ }
+ mPreviewText.setVisibility(VISIBLE);
+ }
private void invalidateKey(int keyIndex) {
if (keyIndex < 0 || keyIndex >= mKeys.length) {
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 017b14d..6f9d6c6 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1,18 +1,20 @@
package android.os;
-import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Formatter;
import java.util.Map;
+import android.util.Log;
+import android.util.Printer;
import android.util.SparseArray;
/**
* A class providing access to battery usage statistics, including information on
* wakelocks, processes, packages, and services. All times are represented in microseconds
* except where indicated otherwise.
+ * @hide
*/
-public abstract class BatteryStats {
+public abstract class BatteryStats implements Parcelable {
/**
* A constant indicating a partial wake lock timer.
@@ -96,6 +98,11 @@ public abstract class BatteryStats {
* @return a time in microseconds
*/
public abstract long getTotalTime(long now, int which);
+
+ /**
+ * Temporary for debugging.
+ */
+ public abstract void logState();
}
/**
@@ -154,10 +161,10 @@ public abstract class BatteryStats {
public abstract long getTcpBytesSent(int which);
public static abstract class Sensor {
- /**
- * {@hide}
- */
- public abstract String getName();
+ // Magic sensor number for the GPS.
+ public static final int GPS = -10000;
+
+ public abstract int getHandle();
public abstract Timer getSensorTime();
}
@@ -260,6 +267,11 @@ public abstract class BatteryStats {
public abstract long getPluggedScreenOnTime();
/**
+ * Return whether we are currently running on battery.
+ */
+ public abstract boolean getIsOnBattery();
+
+ /**
* Returns a SparseArray containing the statistics for each uid.
*/
public abstract SparseArray<? extends Uid> getUidStats();
@@ -457,7 +469,7 @@ public abstract class BatteryStats {
* @param pw
* @param which
*/
- private final void dumpCheckinLocked(FileDescriptor fd, PrintWriter pw, int which) {
+ private final void dumpCheckinLocked(PrintWriter pw, int which) {
long uSecTime = SystemClock.elapsedRealtime() * 1000;
final long uSecNow = getBatteryUptime(uSecTime);
@@ -578,35 +590,18 @@ public abstract class BatteryStats {
}
@SuppressWarnings("unused")
- private final void dumpLocked(FileDescriptor fd, PrintWriter pw, String prefix, int which) {
+ private final void dumpLocked(Printer pw, String prefix, int which) {
long uSecTime = SystemClock.elapsedRealtime() * 1000;
final long uSecNow = getBatteryUptime(uSecTime);
StringBuilder sb = new StringBuilder(128);
- switch (which) {
- case STATS_TOTAL:
- pw.println(prefix + "Current and Historic Battery Usage Statistics:");
- pw.println(prefix + " System starts: " + getStartCount());
- break;
- case STATS_LAST:
- pw.println(prefix + "Last Battery Usage Statistics:");
- break;
- case STATS_UNPLUGGED:
- pw.println(prefix + "Last Unplugged Battery Usage Statistics:");
- break;
- case STATS_CURRENT:
- pw.println(prefix + "Current Battery Usage Statistics:");
- break;
- default:
- throw new IllegalArgumentException("which = " + which);
- }
long batteryUptime = computeBatteryUptime(uSecNow, which);
long batteryRealtime = computeBatteryRealtime(getBatteryRealtime(uSecTime), which);
long elapsedRealtime = computeRealtime(uSecTime, which);
long uptime = computeUptime(SystemClock.uptimeMillis() * 1000, which);
pw.println(prefix
- + " On battery: " + formatTimeMs(batteryUptime / 1000) + "("
+ + " Time on battery: " + formatTimeMs(batteryUptime / 1000) + "("
+ formatRatioLocked(batteryUptime, elapsedRealtime)
+ ") uptime, "
+ formatTimeMs(batteryRealtime / 1000) + "("
@@ -618,7 +613,7 @@ public abstract class BatteryStats {
+ "uptime, "
+ formatTimeMs(elapsedRealtime / 1000)
+ "realtime");
-
+
pw.println(" ");
SparseArray<? extends Uid> uidStats = getUidStats();
@@ -629,8 +624,12 @@ public abstract class BatteryStats {
pw.println(prefix + " #" + uid + ":");
boolean uidActivity = false;
- pw.println(prefix + " Network: " + u.getTcpBytesReceived(which) + " bytes received, "
- + u.getTcpBytesSent(which) + " bytes sent");
+ long tcpReceived = u.getTcpBytesReceived(which);
+ long tcpSent = u.getTcpBytesSent(which);
+ if (tcpReceived != 0 || tcpSent != 0) {
+ pw.println(prefix + " Network: " + tcpReceived + " bytes received, "
+ + tcpSent + " bytes sent");
+ }
Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
if (wakelocks.size() > 0) {
@@ -648,7 +647,9 @@ public abstract class BatteryStats {
"partial", which, linePrefix);
linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), uSecNow,
"window", which, linePrefix);
- if (linePrefix.equals(": ")) {
+ if (!linePrefix.equals(": ")) {
+ sb.append(" realtime");
+ } else {
sb.append(": (nothing executed)");
}
pw.println(sb.toString());
@@ -665,23 +666,30 @@ public abstract class BatteryStats {
sb.setLength(0);
sb.append(prefix);
sb.append(" Sensor ");
- sb.append(sensorNumber);
+ int handle = se.getHandle();
+ if (handle == Uid.Sensor.GPS) {
+ sb.append("GPS");
+ } else {
+ sb.append(handle);
+ }
+ sb.append(": ");
Timer timer = se.getSensorTime();
if (timer != null) {
// Convert from microseconds to milliseconds with rounding
long totalTime = (timer.getTotalTime(uSecNow, which) + 500) / 1000;
int count = timer.getCount(which);
+ //timer.logState();
if (totalTime != 0) {
- sb.append(": ");
sb.append(formatTimeMs(totalTime));
- sb.append(' ');
- sb.append('(');
+ sb.append("realtime (");
sb.append(count);
sb.append(" times)");
+ } else {
+ sb.append("(not used)");
}
} else {
- sb.append(": (none used)");
+ sb.append("(not used)");
}
pw.println(sb.toString());
@@ -734,8 +742,9 @@ public abstract class BatteryStats {
int launches = ss.getLaunches(which);
if (startTime != 0 || starts != 0 || launches != 0) {
pw.println(prefix + " Service " + sent.getKey() + ":");
- pw.println(prefix + " Time spent started: "
- + formatTimeMs(startTime / 1000));
+ pw.println(prefix + " Created for: "
+ + formatTimeMs(startTime / 1000)
+ + " uptime");
pw.println(prefix + " Starts: " + starts
+ ", launches: " + launches);
apkActivity = true;
@@ -757,36 +766,30 @@ public abstract class BatteryStats {
/**
* Dumps a human-readable summary of the battery statistics to the given PrintWriter.
*
- * @param fd a FileDescriptor, currently unused.
- * @param pw a PrintWriter to receive the dump output.
- * @param args an array of Strings, currently unused.
+ * @param pw a Printer to receive the dump output.
*/
@SuppressWarnings("unused")
- public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
- boolean isCheckin = false;
- if (args != null) {
- for (String arg : args) {
- if ("-c".equals(arg)) {
- isCheckin = true;
- break;
- }
- }
- }
- synchronized (this) {
- if (isCheckin) {
- dumpCheckinLocked(fd, pw, STATS_TOTAL);
- dumpCheckinLocked(fd, pw, STATS_LAST);
- dumpCheckinLocked(fd, pw, STATS_UNPLUGGED);
- dumpCheckinLocked(fd, pw, STATS_CURRENT);
- } else {
- dumpLocked(fd, pw, "", STATS_TOTAL);
- pw.println("");
- dumpLocked(fd, pw, "", STATS_LAST);
- pw.println("");
- dumpLocked(fd, pw, "", STATS_UNPLUGGED);
- pw.println("");
- dumpLocked(fd, pw, "", STATS_CURRENT);
- }
- }
+ public void dumpLocked(Printer pw) {
+ pw.println("Total Statistics (Current and Historic):");
+ pw.println(" System starts: " + getStartCount()
+ + ", currently on battery: " + getIsOnBattery());
+ dumpLocked(pw, "", STATS_TOTAL);
+ pw.println("");
+ pw.println("Last Run Statistics (Previous run of system):");
+ dumpLocked(pw, "", STATS_LAST);
+ pw.println("");
+ pw.println("Current Battery Statistics (Currently running system):");
+ dumpLocked(pw, "", STATS_CURRENT);
+ pw.println("");
+ pw.println("Unplugged Statistics (Since last unplugged from power):");
+ dumpLocked(pw, "", STATS_UNPLUGGED);
+ }
+
+ @SuppressWarnings("unused")
+ public void dumpCheckinLocked(PrintWriter pw, String[] args) {
+ dumpCheckinLocked(pw, STATS_TOTAL);
+ dumpCheckinLocked(pw, STATS_LAST);
+ dumpCheckinLocked(pw, STATS_UNPLUGGED);
+ dumpCheckinLocked(pw, STATS_CURRENT);
}
}
diff --git a/core/java/android/os/ICheckinService.aidl b/core/java/android/os/ICheckinService.aidl
index 11becc4..e56b55d 100644
--- a/core/java/android/os/ICheckinService.aidl
+++ b/core/java/android/os/ICheckinService.aidl
@@ -26,7 +26,13 @@ import android.os.IParentalControlCallback;
* {@hide}
*/
interface ICheckinService {
- /** Synchronously attempt a checkin with the server, return true on success. */
+ /** Synchronously attempt a checkin with the server, return true
+ * on success.
+ * @throws IllegalStateException whenever an error occurs. The
+ * cause of the exception will be the real exception:
+ * IOException for network errors, JSONException for invalid
+ * server responses, etc.
+ */
boolean checkin();
/** Direct submission of crash data; returns after writing the crash. */
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index e48f152..5486920 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -29,4 +29,5 @@ interface IPowerManager
void setStayOnSetting(int val);
long getScreenOnTime();
void preventScreenOn(boolean prevent);
+ void setScreenBrightnessOverride(int brightness);
}
diff --git a/core/java/android/preference/PreferenceGroupAdapter.java b/core/java/android/preference/PreferenceGroupAdapter.java
index 02ab1da..14c0054 100644
--- a/core/java/android/preference/PreferenceGroupAdapter.java
+++ b/core/java/android/preference/PreferenceGroupAdapter.java
@@ -242,7 +242,7 @@ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeIn
mHasReturnedViewTypeCount = true;
}
- return mPreferenceClassNames.size();
+ return Math.max(1, mPreferenceClassNames.size());
}
}
diff --git a/core/java/android/provider/Checkin.java b/core/java/android/provider/Checkin.java
index 5767c65..688e19a 100644
--- a/core/java/android/provider/Checkin.java
+++ b/core/java/android/provider/Checkin.java
@@ -97,6 +97,7 @@ public final class Checkin {
SETUP_RETRIES_EXHAUSTED,
SETUP_SERVER_ERROR,
SETUP_SERVER_TIMEOUT,
+ SETUP_NO_DATA_NETWORK,
SYSTEM_APP_NOT_RESPONDING,
SYSTEM_BOOT,
SYSTEM_LAST_KMSG,
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c6a7b40..4a784c8 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2321,6 +2321,13 @@ public final class Settings {
public static final String GMAIL_SEND_IMMEDIATELY = "gmail_send_immediately";
/**
+ * Controls whether gmail buffers server responses. Possible values are "memory", for a
+ * memory-based buffer, or "file", for a temp-file-based buffer. All other values
+ * (including not set) disable buffering.
+ */
+ public static final String GMAIL_BUFFER_SERVER_RESPONSE = "gmail_buffer_server_response";
+
+ /**
* Hostname of the GTalk server.
*/
public static final String GTALK_SERVICE_HOSTNAME = "gtalk_hostname";
diff --git a/core/java/android/server/BluetoothDeviceService.java b/core/java/android/server/BluetoothDeviceService.java
index 7c15045..86d5a1e 100644
--- a/core/java/android/server/BluetoothDeviceService.java
+++ b/core/java/android/server/BluetoothDeviceService.java
@@ -111,9 +111,19 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
private native int isEnabledNative();
/**
- * Disable bluetooth. Returns true on success.
+ * Bring down bluetooth and disable BT in settings. Returns true on success.
*/
- public synchronized boolean disable() {
+ public boolean disable() {
+ return disable(true);
+ }
+
+ /**
+ * Bring down bluetooth. Returns true on success.
+ *
+ * @param saveSetting If true, disable BT in settings
+ *
+ */
+ public synchronized boolean disable(boolean saveSetting) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
@@ -137,7 +147,9 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
mIsEnabled = false;
- persistBluetoothOnSetting(false);
+ if (saveSetting) {
+ persistBluetoothOnSetting(false);
+ }
mIsDiscovering = false;
intent = new Intent(BluetoothIntent.DISABLED_ACTION);
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
@@ -145,13 +157,27 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
}
/**
+ * Bring up bluetooth, asynchronously, and enable BT in settings.
+ * This turns on/off the underlying hardware.
+ *
+ * @return True on success (so far), guaranteeing the callback with be
+ * notified when complete.
+ */
+ public boolean enable(IBluetoothDeviceCallback callback) {
+ return enable(callback, true);
+ }
+
+ /**
* Enable this Bluetooth device, asynchronously.
* This turns on/off the underlying hardware.
*
- * @return True on success (so far), guarenteeing the callback with be
+ * @param saveSetting If true, enable BT in settings
+ *
+ * @return True on success (so far), guaranteeing the callback with be
* notified when complete.
*/
- public synchronized boolean enable(IBluetoothDeviceCallback callback) {
+ public synchronized boolean enable(IBluetoothDeviceCallback callback,
+ boolean saveSetting) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
@@ -165,7 +191,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
if (mEnableThread != null && mEnableThread.isAlive()) {
return false;
}
- mEnableThread = new EnableThread(callback);
+ mEnableThread = new EnableThread(callback, saveSetting);
mEnableThread.start();
return true;
}
@@ -189,8 +215,10 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
private class EnableThread extends Thread {
private final IBluetoothDeviceCallback mEnableCallback;
- public EnableThread(IBluetoothDeviceCallback callback) {
+ private final boolean mSaveSetting;
+ public EnableThread(IBluetoothDeviceCallback callback, boolean saveSetting) {
mEnableCallback = callback;
+ mSaveSetting = saveSetting;
}
public void run() {
boolean res = (enableNative() == 0);
@@ -208,7 +236,9 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
if (res) {
mIsEnabled = true;
- persistBluetoothOnSetting(true);
+ if (mSaveSetting) {
+ persistBluetoothOnSetting(true);
+ }
mIsDiscovering = false;
Intent intent = new Intent(BluetoothIntent.ENABLED_ACTION);
mBondState.loadBondState();
@@ -952,9 +982,9 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
// If bluetooth is currently expected to be on, then enable or disable bluetooth
if (Settings.Secure.getInt(resolver, Settings.Secure.BLUETOOTH_ON, 0) > 0) {
if (enabled) {
- enable(null);
+ enable(null, false);
} else {
- disable();
+ disable(false);
}
}
}
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index b5e4090..187ec2c 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -359,10 +359,10 @@ class BluetoothEventLoop {
private void onGetRemoteServiceChannelResult(String address, int channel) {
IBluetoothDeviceCallback callback = mGetRemoteServiceChannelCallbacks.get(address);
if (callback != null) {
+ mGetRemoteServiceChannelCallbacks.remove(address);
try {
callback.onGetRemoteServiceChannelResult(address, channel);
} catch (RemoteException e) {}
- mGetRemoteServiceChannelCallbacks.remove(address);
}
}
diff --git a/core/java/android/speech/srec/MicrophoneInputStream.java b/core/java/android/speech/srec/MicrophoneInputStream.java
index 160a003..fab77a9 100644
--- a/core/java/android/speech/srec/MicrophoneInputStream.java
+++ b/core/java/android/speech/srec/MicrophoneInputStream.java
@@ -1,5 +1,5 @@
/*---------------------------------------------------------------------------*
- * MicrophoneInputStream.java *
+ * MicrophoneInputStream.java *
* *
* Copyright 2007 Nuance Communciations, Inc. *
* *
@@ -45,8 +45,12 @@ public final class MicrophoneInputStream extends InputStream {
*/
public MicrophoneInputStream(int sampleRate, int fifoDepth) throws IOException {
mAudioRecord = AudioRecordNew(sampleRate, fifoDepth);
- if (mAudioRecord == 0) throw new IllegalStateException("not open");
- AudioRecordStart(mAudioRecord);
+ if (mAudioRecord == 0) throw new IOException("AudioRecord constructor failed - busy?");
+ int status = AudioRecordStart(mAudioRecord);
+ if (status != 0) {
+ close();
+ throw new IOException("AudioRecord start failed: " + status);
+ }
}
@Override
@@ -99,7 +103,7 @@ public final class MicrophoneInputStream extends InputStream {
// AudioRecord JNI interface
//
private static native int AudioRecordNew(int sampleRate, int fifoDepth);
- private static native void AudioRecordStart(int audioRecord);
+ private static native int AudioRecordStart(int audioRecord);
private static native int AudioRecordRead(int audioRecord, byte[] b, int offset, int length) throws IOException;
private static native void AudioRecordStop(int audioRecord) throws IOException;
private static native void AudioRecordDelete(int audioRecord) throws IOException;
diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java
index 5bf9b20..daa99c2 100644
--- a/core/java/android/text/format/Time.java
+++ b/core/java/android/text/format/Time.java
@@ -394,6 +394,7 @@ public class Time {
*
* @param s the string to parse
* @return true if the resulting time value is in UTC time
+ * @throws android.util.TimeFormatException if s cannot be parsed.
*/
public boolean parse(String s) {
if (nativeParse(s)) {
diff --git a/core/java/android/text/style/ImageSpan.java b/core/java/android/text/style/ImageSpan.java
index 2eebc0d..efb88a0 100644
--- a/core/java/android/text/style/ImageSpan.java
+++ b/core/java/android/text/style/ImageSpan.java
@@ -44,8 +44,9 @@ public class ImageSpan extends DynamicDrawableSpan {
public ImageSpan(Bitmap b, int verticalAlignment) {
super(verticalAlignment);
mDrawable = new BitmapDrawable(b);
- mDrawable.setBounds(0, 0, mDrawable.getIntrinsicWidth(),
- mDrawable.getIntrinsicHeight());
+ int width = mDrawable.getIntrinsicWidth();
+ int height = mDrawable.getIntrinsicHeight();
+ mDrawable.setBounds(0, 0, width > 0 ? width : 0, height > 0 ? height : 0);
}
public ImageSpan(Drawable d) {
diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java
index 610cfd4..9ab3b53 100644
--- a/core/java/android/util/SparseIntArray.java
+++ b/core/java/android/util/SparseIntArray.java
@@ -73,13 +73,20 @@ public class SparseIntArray {
int i = binarySearch(mKeys, 0, mSize, key);
if (i >= 0) {
- System.arraycopy(mKeys, i + 1, mKeys, i, mSize - (i + 1));
- System.arraycopy(mValues, i + 1, mValues, i, mSize - (i + 1));
- mSize--;
+ removeAt(i);
}
}
/**
+ * Removes the mapping at the given index.
+ */
+ public void removeAt(int index) {
+ System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
+ System.arraycopy(mValues, index + 1, mValues, index, mSize - (index + 1));
+ mSize--;
+ }
+
+ /**
* Adds a mapping from the specified key to the specified value,
* replacing the previous mapping from the specified key if there
* was one.
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index a472689..679c683 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -163,7 +163,7 @@ public class GestureDetector {
private static final int TAP_TIMEOUT = ViewConfiguration.getTapTimeout();
// TODO make new double-tap timeout, and define its events (i.e. either time
// between down-down or time between up-down)
- private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getJumpTapTimeout();
+ private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();
// constants for Message.what used by GestureHandler below
private static final int SHOW_PRESS = 1;
@@ -174,11 +174,13 @@ public class GestureDetector {
private final OnGestureListener mListener;
private OnDoubleTapListener mDoubleTapListener;
+ private boolean mStillDown;
private boolean mInLongPress;
private boolean mAlwaysInTapRegion;
private boolean mAlwaysInBiggerTapRegion;
private MotionEvent mCurrentDownEvent;
+ private MotionEvent mPreviousUpEvent;
/**
* True when the user is still touching for the second tap (down, move, and
@@ -217,7 +219,8 @@ public class GestureDetector {
break;
case TAP:
- if (mDoubleTapListener != null) {
+ // If the user's finger is still down, do not count it as a tap
+ if (mDoubleTapListener != null && !mStillDown) {
mDoubleTapListener.onSingleTapConfirmed(mCurrentDownEvent);
}
break;
@@ -378,8 +381,10 @@ public class GestureDetector {
switch (action) {
case MotionEvent.ACTION_DOWN:
if (mDoubleTapListener != null) {
- mHandler.removeMessages(TAP);
- if (mCurrentDownEvent != null && isConsideredDoubleTap(mCurrentDownEvent, ev)) {
+ boolean hadTapMessage = mHandler.hasMessages(TAP);
+ if (hadTapMessage) mHandler.removeMessages(TAP);
+ if ((mCurrentDownEvent != null) && (mPreviousUpEvent != null) && hadTapMessage &&
+ isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) {
// This is a second tap
mIsDoubleTapping = true;
handled = mDoubleTapListener.onDoubleTapEvent(ev);
@@ -394,6 +399,7 @@ public class GestureDetector {
mCurrentDownEvent = MotionEvent.obtain(ev);
mAlwaysInTapRegion = true;
mAlwaysInBiggerTapRegion = true;
+ mStillDown = true;
mInLongPress = false;
if (mIsLongpressEnabled) {
@@ -422,6 +428,7 @@ public class GestureDetector {
mLastMotionX = x;
mLastMotionY = y;
mAlwaysInTapRegion = false;
+ mHandler.removeMessages(TAP);
mHandler.removeMessages(SHOW_PRESS);
mHandler.removeMessages(LONG_PRESS);
}
@@ -436,6 +443,7 @@ public class GestureDetector {
break;
case MotionEvent.ACTION_UP:
+ mStillDown = false;
MotionEvent currentUpEvent = MotionEvent.obtain(ev);
if (mIsDoubleTapping) {
handled = mDoubleTapListener.onDoubleTapEvent(ev);
@@ -461,6 +469,7 @@ public class GestureDetector {
handled = mListener.onFling(mCurrentDownEvent, currentUpEvent, velocityX, velocityY);
}
}
+ mPreviousUpEvent = MotionEvent.obtain(ev);
mVelocityTracker.recycle();
mVelocityTracker = null;
mHandler.removeMessages(SHOW_PRESS);
@@ -472,6 +481,7 @@ public class GestureDetector {
mHandler.removeMessages(TAP);
mVelocityTracker.recycle();
mVelocityTracker = null;
+ mStillDown = false;
if (mInLongPress) {
mInLongPress = false;
break;
@@ -480,12 +490,13 @@ public class GestureDetector {
return handled;
}
- private boolean isConsideredDoubleTap(MotionEvent firstDown, MotionEvent secondDown) {
+ private boolean isConsideredDoubleTap(MotionEvent firstDown, MotionEvent firstUp,
+ MotionEvent secondDown) {
if (!mAlwaysInBiggerTapRegion) {
return false;
}
- if (secondDown.getEventTime() - firstDown.getEventTime() > DOUBLE_TAP_TIMEOUT) {
+ if (secondDown.getEventTime() - firstUp.getEventTime() > DOUBLE_TAP_TIMEOUT) {
return false;
}
@@ -495,6 +506,7 @@ public class GestureDetector {
}
private void dispatchLongPress() {
+ mHandler.removeMessages(TAP);
mInLongPress = true;
mListener.onLongPress(mCurrentDownEvent);
}
diff --git a/core/java/android/view/OrientationEventListener.java b/core/java/android/view/OrientationEventListener.java
new file mode 100755
index 0000000..cddec11
--- /dev/null
+++ b/core/java/android/view/OrientationEventListener.java
@@ -0,0 +1,156 @@
+/*
+ * 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.view;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.util.Config;
+import android.util.Log;
+
+/**
+ * Helper class for receiving notifications from the SensorManager when
+ * the orientation of the device has changed.
+ */
+public abstract class OrientationEventListener {
+ private static final String TAG = "OrientationEventListener";
+ private static final boolean DEBUG = false;
+ private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
+ private int mOrientation = ORIENTATION_UNKNOWN;
+ private SensorManager mSensorManager;
+ private boolean mEnabled = false;
+ private int mRate;
+ private Sensor mSensor;
+ private SensorEventListener mSensorEventListener;
+ private OrientationListener mOldListener;
+
+ /**
+ * Returned from onOrientationChanged when the device orientation cannot be determined
+ * (typically when the device is in a close to flat position).
+ *
+ * @see #onOrientationChanged
+ */
+ public static final int ORIENTATION_UNKNOWN = -1;
+
+ /**
+ * Creates a new OrientationEventListener.
+ *
+ * @param context for the OrientationEventListener.
+ */
+ public OrientationEventListener(Context context) {
+ this(context, SensorManager.SENSOR_DELAY_NORMAL);
+ }
+
+ /**
+ * Creates a new OrientationEventListener.
+ *
+ * @param context for the OrientationEventListener.
+ * @param rate at which sensor events are processed (see also
+ * {@link android.hardware.SensorManager SensorManager}). Use the default
+ * value of {@link android.hardware.SensorManager#SENSOR_DELAY_NORMAL
+ * SENSOR_DELAY_NORMAL} for simple screen orientation change detection.
+ */
+ public OrientationEventListener(Context context, int rate) {
+ mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
+ mRate = rate;
+ mSensorEventListener = new SensorEventListenerImpl();
+ mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ }
+
+ void registerListener(OrientationListener lis) {
+ mOldListener = lis;
+ }
+
+ /**
+ * Enables the OrientationEventListener so it will monitor the sensor and call
+ * {@link #onOrientationChanged} when the device orientation changes.
+ */
+ public void enable() {
+ if (mEnabled == false) {
+ if (localLOGV) Log.d(TAG, "OrientationEventListener enabled");
+ mSensorManager.registerListener(mSensorEventListener, mSensor, mRate);
+ mEnabled = true;
+ }
+ }
+
+ /**
+ * Disables the OrientationEventListener.
+ */
+ public void disable() {
+ if (mEnabled == true) {
+ if (localLOGV) Log.d(TAG, "OrientationEventListener disabled");
+ mSensorManager.unregisterListener(mSensorEventListener);
+ mEnabled = false;
+ }
+ }
+
+ class SensorEventListenerImpl implements SensorEventListener {
+ private static final int _DATA_X = 0;
+ private static final int _DATA_Y = 1;
+ private static final int _DATA_Z = 2;
+
+ public void onSensorChanged(SensorEvent event) {
+ float[] values = event.values;
+ int orientation = ORIENTATION_UNKNOWN;
+ float X = -values[_DATA_X];
+ float Y = -values[_DATA_Y];
+ float Z = -values[_DATA_Z];
+ float magnitude = X*X + Y*Y;
+ // Don't trust the angle if the magnitude is small compared to the y value
+ if (magnitude * 4 >= Z*Z) {
+ float OneEightyOverPi = 57.29577957855f;
+ float angle = (float)Math.atan2(-Y, X) * OneEightyOverPi;
+ orientation = 90 - (int)Math.round(angle);
+ // normalize to 0 - 359 range
+ while (orientation >= 360) {
+ orientation -= 360;
+ }
+ while (orientation < 0) {
+ orientation += 360;
+ }
+ }
+ if (mOldListener != null) {
+ mOldListener.onSensorChanged(Sensor.TYPE_ACCELEROMETER, event.values);
+ }
+ if (orientation != mOrientation) {
+ mOrientation = orientation;
+ onOrientationChanged(orientation);
+ }
+ }
+
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+
+ }
+ }
+
+ /**
+ * Called when the orientation of the device has changed.
+ * orientation parameter is in degrees, ranging from 0 to 359.
+ * orientation is 0 degrees when the device is oriented in its natural position,
+ * 90 degrees when its left side is at the top, 180 degrees when it is upside down,
+ * and 270 degrees when its right side is to the top.
+ * {@link #ORIENTATION_UNKNOWN} is returned when the device is close to flat
+ * and the orientation cannot be determined.
+ *
+ * @param orientation The new orientation of the device.
+ *
+ * @see #ORIENTATION_UNKNOWN
+ */
+ abstract public void onOrientationChanged(int orientation);
+}
diff --git a/core/java/android/view/OrientationListener.java b/core/java/android/view/OrientationListener.java
index 974c2e8..ce8074e 100644
--- a/core/java/android/view/OrientationListener.java
+++ b/core/java/android/view/OrientationListener.java
@@ -18,23 +18,16 @@ package android.view;
import android.content.Context;
import android.hardware.SensorListener;
-import android.hardware.SensorManager;
-import android.util.Config;
-import android.util.Log;
/**
* Helper class for receiving notifications from the SensorManager when
* the orientation of the device has changed.
+ * @deprecated use {@link android.view.OrientationEventListener} instead.
+ * This class internally uses the OrientationEventListener.
*/
+@Deprecated
public abstract class OrientationListener implements SensorListener {
-
- private static final String TAG = "OrientationListener";
- private static final boolean DEBUG = false;
- private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
- private SensorManager mSensorManager;
- private int mOrientation = ORIENTATION_UNKNOWN;
- private boolean mEnabled = false;
- private int mRate;
+ private OrientationEventListener mOrientationEventLis;
/**
* Returned from onOrientationChanged when the device orientation cannot be determined
@@ -42,7 +35,7 @@ public abstract class OrientationListener implements SensorListener {
*
* @see #onOrientationChanged
*/
- public static final int ORIENTATION_UNKNOWN = -1;
+ public static final int ORIENTATION_UNKNOWN = OrientationEventListener.ORIENTATION_UNKNOWN;
/**
* Creates a new OrientationListener.
@@ -50,8 +43,7 @@ public abstract class OrientationListener implements SensorListener {
* @param context for the OrientationListener.
*/
public OrientationListener(Context context) {
- mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
- mRate = SensorManager.SENSOR_DELAY_NORMAL;
+ mOrientationEventLis = new OrientationEventListenerInternal(context);
}
/**
@@ -64,78 +56,55 @@ public abstract class OrientationListener implements SensorListener {
* SENSOR_DELAY_NORMAL} for simple screen orientation change detection.
*/
public OrientationListener(Context context, int rate) {
- mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
- mRate = rate;
+ mOrientationEventLis = new OrientationEventListenerInternal(context, rate);
}
-
+
+ class OrientationEventListenerInternal extends OrientationEventListener {
+ OrientationEventListenerInternal(Context context) {
+ super(context);
+ }
+
+ OrientationEventListenerInternal(Context context, int rate) {
+ super(context, rate);
+ // register so that onSensorChanged gets invoked
+ registerListener(OrientationListener.this);
+ }
+
+ public void onOrientationChanged(int orientation) {
+ OrientationListener.this.onOrientationChanged(orientation);
+ }
+ }
+
/**
* Enables the OrientationListener so it will monitor the sensor and call
* {@link #onOrientationChanged} when the device orientation changes.
*/
public void enable() {
- if (mEnabled == false) {
- if (localLOGV) Log.d(TAG, "OrientationListener enabled");
- mSensorManager.registerListener(this, SensorManager.SENSOR_ACCELEROMETER, mRate);
- mEnabled = true;
- }
+ mOrientationEventLis.enable();
}
/**
* Disables the OrientationListener.
*/
public void disable() {
- if (mEnabled == true) {
- if (localLOGV) Log.d(TAG, "OrientationListener disabled");
- mSensorManager.unregisterListener(this);
- mEnabled = false;
- }
+ mOrientationEventLis.disable();
}
-
- /**
- *
- */
+
+ public void onAccuracyChanged(int sensor, int accuracy) {
+ }
+
public void onSensorChanged(int sensor, float[] values) {
- int orientation = ORIENTATION_UNKNOWN;
- float X = values[SensorManager.RAW_DATA_X];
- float Y = values[SensorManager.RAW_DATA_Y];
- float Z = values[SensorManager.RAW_DATA_Z];
- float magnitude = X*X + Y*Y;
- // Don't trust the angle if the magnitude is small compared to the y value
- if (magnitude * 4 >= Z*Z) {
- float OneEightyOverPi = 57.29577957855f;
- float angle = (float)Math.atan2(-Y, X) * OneEightyOverPi;
- orientation = 90 - (int)Math.round(angle);
- // normalize to 0 - 359 range
- while (orientation >= 360) {
- orientation -= 360;
- }
- while (orientation < 0) {
- orientation += 360;
- }
- }
-
- if (orientation != mOrientation) {
- mOrientation = orientation;
- onOrientationChanged(orientation);
- }
+ // just ignore the call here onOrientationChanged is invoked anyway
}
- public void onAccuracyChanged(int sensor, int accuracy) {
- // TODO Auto-generated method stub
- }
/**
- * Called when the orientation of the device has changed.
- * orientation parameter is in degrees, ranging from 0 to 359.
- * orientation is 0 degrees when the device is oriented in its natural position,
- * 90 degrees when its left side is at the top, 180 degrees when it is upside down,
- * and 270 degrees when its right side is to the top.
- * {@link #ORIENTATION_UNKNOWN} is returned when the device is close to flat
- * and the orientation cannot be determined.
- *
+ * Look at {@link android.view.OrientationEventListener#onOrientationChanged}
+ * for method description and usage
* @param orientation The new orientation of the device.
*
* @see #ORIENTATION_UNKNOWN
*/
abstract public void onOrientationChanged(int orientation);
+
}
diff --git a/core/java/android/os/HandlerInterface.java b/core/java/android/view/RemotableViewMethod.java
index 62dc273..4318290 100644
--- a/core/java/android/os/HandlerInterface.java
+++ b/core/java/android/view/RemotableViewMethod.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * 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.
@@ -14,14 +14,22 @@
* limitations under the License.
*/
-package android.os;
+package android.view;
-/**
- * @hide
- * @deprecated
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @hide
+ * This annotation indicates that a method on a subclass of View
+ * is alllowed to be used with the {@link android.widget.RemoteViews} mechanism.
*/
-public interface HandlerInterface
-{
- void handleMessage(Message msg);
+@Target({ ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RemotableViewMethod {
}
+
+
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1d5e7cd..5ed3a7e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2674,6 +2674,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
* @param visibility One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
* @attr ref android.R.styleable#View_visibility
*/
+ @RemotableViewMethod
public void setVisibility(int visibility) {
setFlags(visibility, VISIBILITY_MASK);
if (mBGDrawable != null) mBGDrawable.setVisible(visibility == VISIBLE, false);
@@ -4016,6 +4017,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
*/
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
mBackgroundSizeChanged = true;
+
+ final AttachInfo ai = mAttachInfo;
+ if (ai != null) {
+ ai.mViewScrollChanged = true;
+ }
}
/**
@@ -7948,6 +7954,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
boolean mViewVisibilityChanged;
/**
+ * Set to true if a view has been scrolled.
+ */
+ boolean mViewScrollChanged;
+
+ /**
* Global to the view hierarchy used as a temporary for dealing with
* x/y points in the transparent region computations.
*/
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 7153ea1..2f7b0d1 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -67,6 +67,13 @@ public class ViewConfiguration {
* considered to be a tap.
*/
private static final int JUMP_TAP_TIMEOUT = 500;
+
+ /**
+ * Defines the duration in milliseconds between the first tap's up event and
+ * the second tap's down event for an interaction to be considered a
+ * double-tap.
+ */
+ private static final int DOUBLE_TAP_TIMEOUT = 300;
/**
* Defines the duration in milliseconds we want to display zoom controls in response
@@ -82,7 +89,7 @@ public class ViewConfiguration {
/**
* Distance a touch can wander before we think the user is scrolling in pixels
*/
- private static final int TOUCH_SLOP = 12;
+ private static final int TOUCH_SLOP = 25;
/**
* Distance between the first touch and second touch to still be considered a double tap
@@ -257,6 +264,16 @@ public class ViewConfiguration {
}
/**
+ * @return Defines the duration in milliseconds between the first tap's up event and
+ * the second tap's down event for an interaction to be considered a
+ * double-tap.
+ * @hide pending API council
+ */
+ public static int getDoubleTapTimeout() {
+ return DOUBLE_TAP_TIMEOUT;
+ }
+
+ /**
* @return Inset in pixels to look for touchable content when the user touches the edge of the
* screen
*
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index c758662..70cc2a9 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -27,6 +27,7 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.RectF;
import android.os.Parcelable;
+import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.EventLog;
import android.util.Log;
@@ -1023,6 +1024,20 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
@Override
void dispatchDetachedFromWindow() {
+ // If we still have a motion target, we are still in the process of
+ // dispatching motion events to a child; we need to get rid of that
+ // child to avoid dispatching events to it after the window is torn
+ // down. To make sure we keep the child in a consistent state, we
+ // first send it an ACTION_CANCEL motion event.
+ if (mMotionTarget != null) {
+ final long now = SystemClock.uptimeMillis();
+ final MotionEvent event = MotionEvent.obtain(now, now,
+ MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
+ mMotionTarget.dispatchTouchEvent(event);
+ event.recycle();
+ mMotionTarget = null;
+ }
+
final int count = mChildrenCount;
final View[] children = mChildren;
for (int i = 0; i < count; i++) {
@@ -1331,6 +1346,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final Animation a = child.getAnimation();
boolean concatMatrix = false;
+ final int childWidth = cr - cl;
+ final int childHeight = cb - ct;
+
if (a != null) {
if (mInvalidateRegion == null) {
mInvalidateRegion = new RectF();
@@ -1339,8 +1357,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final boolean initialized = a.isInitialized();
if (!initialized) {
- a.initialize(cr - cl, cb - ct, getWidth(), getHeight());
- a.initializeInvalidateRegion(cl, ct, cr, cb);
+ a.initialize(childWidth, childHeight, getWidth(), getHeight());
+ a.initializeInvalidateRegion(0, 0, childWidth, childHeight);
child.onAnimationStart();
}
@@ -1364,7 +1382,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
invalidate(cl, ct, cr, cb);
}
} else {
- a.getInvalidateRegion(cl, ct, cr, cb, region, transformToApply);
+ a.getInvalidateRegion(0, 0, childWidth, childHeight, region, transformToApply);
// The child need to draw an animation, potentially offscreen, so
// make sure we do not cancel invalidate requests
@@ -1372,8 +1390,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
// Enlarge the invalidate region to account for rounding errors
// in Animation#getInvalidateRegion(); Using 0.5f is unfortunately
// not enough for some types of animations (e.g. scale down.)
- invalidate((int) (region.left - 1.0f), (int) (region.top - 1.0f),
- (int) (region.right + 1.0f), (int) (region.bottom + 1.0f));
+ final int left = cl + (int) (region.left - 1.0f);
+ final int top = ct + (int) (region.top - 1.0f);
+ invalidate(left, top,
+ left + (int) (region.width() + 1.0f),
+ top + (int) (region.height() + 1.0f));
}
}
} else if ((flags & FLAG_SUPPORT_STATIC_TRANSFORMATIONS) ==
@@ -1453,9 +1474,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if ((flags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN) {
if (hasNoCache) {
- canvas.clipRect(sx, sy, sx + cr - cl, sy + cb - ct);
+ canvas.clipRect(sx, sy, sx + childWidth, sy + childHeight);
} else {
- canvas.clipRect(0, 0, cr - cl, cb - ct);
+ canvas.clipRect(0, 0, childWidth, childHeight);
}
}
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index ccfa6bf..db8829f 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -33,6 +33,7 @@ import android.util.Config;
import android.util.Log;
import android.util.EventLog;
import android.util.SparseArray;
+import android.util.DisplayMetrics;
import android.view.View.MeasureSpec;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
@@ -184,6 +185,7 @@ public final class ViewRoot extends Handler implements ViewParent,
*/
AudioManager mAudioManager;
+ private final float mDensity;
public ViewRoot(Context context) {
super();
@@ -226,6 +228,7 @@ public final class ViewRoot extends Handler implements ViewParent,
mAdded = false;
mAttachInfo = new View.AttachInfo(sWindowSession, mWindow, this, this);
mViewConfiguration = ViewConfiguration.get(context);
+ mDensity = context.getResources().getDisplayMetrics().density;
}
@Override
@@ -1077,6 +1080,11 @@ public final class ViewRoot extends Handler implements ViewParent,
}
scrollToRectOrFocus(null, false);
+
+ if (mAttachInfo.mViewScrollChanged) {
+ mAttachInfo.mViewScrollChanged = false;
+ mAttachInfo.mTreeObserver.dispatchOnScrollChanged();
+ }
int yoff;
final boolean scrolling = mScroller != null
@@ -1090,7 +1098,7 @@ public final class ViewRoot extends Handler implements ViewParent,
mCurScrollY = yoff;
fullRedrawNeeded = true;
}
-
+
Rect dirty = mDirty;
if (mUseGL) {
if (!dirty.isEmpty()) {
@@ -1126,7 +1134,6 @@ public final class ViewRoot extends Handler implements ViewParent,
return;
}
-
if (fullRedrawNeeded)
dirty.union(0, 0, mWidth, mHeight);
@@ -1138,22 +1145,22 @@ public final class ViewRoot extends Handler implements ViewParent,
+ surface + " surface.isValid()=" + surface.isValid());
}
- if (!dirty.isEmpty()) {
- Canvas canvas;
- try {
- canvas = surface.lockCanvas(dirty);
- // TODO: Do this in native
- canvas.setDensityScale(mView.getResources().getDisplayMetrics().density);
- } catch (Surface.OutOfResourcesException e) {
- Log.e("ViewRoot", "OutOfResourcesException locking surface", e);
- // TODO: we should ask the window manager to do something!
- // for now we just do nothing
- return;
- }
+ Canvas canvas;
+ try {
+ canvas = surface.lockCanvas(dirty);
+ // TODO: Do this in native
+ canvas.setDensityScale(mDensity);
+ } catch (Surface.OutOfResourcesException e) {
+ Log.e("ViewRoot", "OutOfResourcesException locking surface", e);
+ // TODO: we should ask the window manager to do something!
+ // for now we just do nothing
+ return;
+ }
- long startTime;
+ try {
+ if (!dirty.isEmpty()) {
+ long startTime;
- try {
if (DEBUG_ORIENTATION || DEBUG_DRAW) {
Log.v("ViewRoot", "Surface " + surface + " drawing to bitmap w="
+ canvas.getWidth() + ", h=" + canvas.getHeight());
@@ -1169,7 +1176,7 @@ public final class ViewRoot extends Handler implements ViewParent,
// properly re-composite its drawing on a transparent
// background. This automatically respects the clip/dirty region
if (!canvas.isOpaque()) {
- canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+ canvas.drawColor(0xff0000ff, PorterDuff.Mode.CLEAR);
} else if (yoff != 0) {
// If we are applying an offset, we need to clear the area
// where the offset doesn't appear to avoid having garbage
@@ -1192,35 +1199,18 @@ public final class ViewRoot extends Handler implements ViewParent,
sDrawTime = now;
}
- } finally {
- surface.unlockCanvasAndPost(canvas);
- }
-
- if (PROFILE_DRAWING) {
- EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
- }
-
- if (LOCAL_LOGV) {
- Log.v("ViewRoot", "Surface " + surface + " unlockCanvasAndPost");
+ if (PROFILE_DRAWING) {
+ EventLog.writeEvent(60000, SystemClock.elapsedRealtime() - startTime);
+ }
}
- } else if (mWidth == 0 || mHeight == 0) {
- // This is a special case where a window dimension is 0 -- we
- // normally wouldn't draw anything because we have an empty
- // dirty rect, but the surface flinger may be waiting for us to
- // draw the window before it stops freezing the screen, so we
- // need to diddle it like this to keep it from getting stuck.
- Canvas canvas;
- try {
- canvas = surface.lockCanvas(dirty);
- } catch (Surface.OutOfResourcesException e) {
- Log.e("ViewRoot", "OutOfResourcesException locking surface", e);
- // TODO: we should ask the window manager to do something!
- // for now we just do nothing
- return;
- }
+ } finally {
surface.unlockCanvasAndPost(canvas);
}
+
+ if (LOCAL_LOGV) {
+ Log.v("ViewRoot", "Surface " + surface + " unlockCanvasAndPost");
+ }
if (scrolling) {
mFullRedrawNeeded = true;
@@ -1401,14 +1391,22 @@ public final class ViewRoot extends Handler implements ViewParent,
void dispatchDetachedFromWindow() {
if (Config.LOGV) Log.v("ViewRoot", "Detaching in " + this + " of " + mSurface);
+
if (mView != null) {
mView.dispatchDetachedFromWindow();
}
+
mView = null;
mAttachInfo.mRootView = null;
+
if (mUseGL) {
destroyGL();
}
+
+ try {
+ sWindowSession.remove(mWindow);
+ } catch (RemoteException e) {
+ }
}
/**
@@ -1609,16 +1607,20 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
}
+
+ InputMethodManager imm = InputMethodManager.peekInstance();
if (mView != null) {
+ if (hasWindowFocus && imm != null) {
+ imm.startGettingWindowFocus();
+ }
mView.dispatchWindowFocusChanged(hasWindowFocus);
}
// Note: must be done after the focus change callbacks,
// so all of the view state is set up correctly.
if (hasWindowFocus) {
- InputMethodManager imm = InputMethodManager.peekInstance();
if (imm != null) {
- imm.onWindowFocus(mView.findFocus(),
+ imm.onWindowFocus(mView, mView.findFocus(),
mWindowAttributes.softInputMode,
!mHasHadWindowFocus, mWindowAttributes.flags);
}
@@ -2289,10 +2291,6 @@ public final class ViewRoot extends Handler implements ViewParent,
}
if (mAdded) {
mAdded = false;
- try {
- sWindowSession.remove(mWindow);
- } catch (RemoteException e) {
- }
if (immediate) {
dispatchDetachedFromWindow();
} else if (mView != null) {
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index 05f5fa2..47b52e4 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -35,6 +35,7 @@ public final class ViewTreeObserver {
private ArrayList<OnPreDrawListener> mOnPreDrawListeners;
private ArrayList<OnTouchModeChangeListener> mOnTouchModeChangeListeners;
private ArrayList<OnComputeInternalInsetsListener> mOnComputeInternalInsetsListeners;
+ private ArrayList<OnScrollChangedListener> mOnScrollChangedListeners;
private boolean mAlive = true;
@@ -99,6 +100,20 @@ public final class ViewTreeObserver {
}
/**
+ * Interface definition for a callback to be invoked when
+ * something in the view tree has been scrolled.
+ *
+ * @hide pending API council approval
+ */
+ public interface OnScrollChangedListener {
+ /**
+ * Callback method to be invoked when something in the view tree
+ * has been scrolled.
+ */
+ public void onScrollChanged();
+ }
+
+ /**
* Parameters used with OnComputeInternalInsetsListener.
* {@hide pending API Council approval}
*/
@@ -361,6 +376,44 @@ public final class ViewTreeObserver {
}
/**
+ * Register a callback to be invoked when a view has been scrolled.
+ *
+ * @param listener The callback to add
+ *
+ * @throws IllegalStateException If {@link #isAlive()} returns false
+ *
+ * @hide pending API council approval
+ */
+ public void addOnScrollChangedListener(OnScrollChangedListener listener) {
+ checkIsAlive();
+
+ if (mOnScrollChangedListeners == null) {
+ mOnScrollChangedListeners = new ArrayList<OnScrollChangedListener>();
+ }
+
+ mOnScrollChangedListeners.add(listener);
+ }
+
+ /**
+ * Remove a previously installed scroll-changed callback
+ *
+ * @param victim The callback to remove
+ *
+ * @throws IllegalStateException If {@link #isAlive()} returns false
+ *
+ * @see #addOnScrollChangedListener(OnScrollChangedListener)
+ *
+ * @hide pending API council approval
+ */
+ public void removeOnScrollChangedListener(OnScrollChangedListener victim) {
+ checkIsAlive();
+ if (mOnScrollChangedListeners == null) {
+ return;
+ }
+ mOnScrollChangedListeners.remove(victim);
+ }
+
+ /**
* Register a callback to be invoked when the invoked when the touch mode changes.
*
* @param listener The callback to add
@@ -525,6 +578,19 @@ public final class ViewTreeObserver {
}
/**
+ * Notifies registered listeners that something has scrolled.
+ */
+ final void dispatchOnScrollChanged() {
+ final ArrayList<OnScrollChangedListener> listeners = mOnScrollChangedListeners;
+
+ if (listeners != null) {
+ for (OnScrollChangedListener scl : mOnScrollChangedListeners) {
+ scl.onScrollChanged();
+ }
+ }
+ }
+
+ /**
* Returns whether there are listeners for computing internal insets.
*/
final boolean hasComputeInternalInsetsListeners() {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 406af3e3..b87cc42 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -513,26 +513,33 @@ public interface WindowManager extends ViewManager {
/**
* Visibility state for {@link #softInputMode}: please hide any soft input
- * area.
+ * area when normally appropriate (when the user is navigating
+ * forward to your window).
*/
public static final int SOFT_INPUT_STATE_HIDDEN = 2;
/**
+ * Visibility state for {@link #softInputMode}: please always hide any
+ * soft input area when this window receives focus.
+ */
+ public static final int SOFT_INPUT_STATE_ALWAYS_HIDDEN = 3;
+
+ /**
* Visibility state for {@link #softInputMode}: please show the soft
* input area when normally appropriate (when the user is navigating
* forward to your window).
*/
- public static final int SOFT_INPUT_STATE_VISIBLE = 3;
+ public static final int SOFT_INPUT_STATE_VISIBLE = 4;
/**
* Visibility state for {@link #softInputMode}: please always make the
* soft input area visible when this window receives input focus.
*/
- public static final int SOFT_INPUT_STATE_ALWAYS_VISIBLE = 4;
+ public static final int SOFT_INPUT_STATE_ALWAYS_VISIBLE = 5;
/**
* Mask for {@link #softInputMode} of the bits that determine the
- * way that the window should be adjusted to accomodate the soft
+ * way that the window should be adjusted to accommodate the soft
* input window.
*/
public static final int SOFT_INPUT_MASK_ADJUST = 0xf0;
@@ -634,6 +641,14 @@ public interface WindowManager extends ViewManager {
public float dimAmount = 1.0f;
/**
+ * This can be used to override the user's preferred brightness of
+ * the screen. A value of less than 0, the default, means to use the
+ * preferred screen brightness. 0 to 1 adjusts the brightness from
+ * dark to full bright.
+ */
+ public float screenBrightness = -1.0f;
+
+ /**
* Identifier for this window. This will usually be filled in for
* you.
*/
@@ -729,6 +744,7 @@ public interface WindowManager extends ViewManager {
out.writeInt(windowAnimations);
out.writeFloat(alpha);
out.writeFloat(dimAmount);
+ out.writeFloat(screenBrightness);
out.writeStrongBinder(token);
out.writeString(packageName);
TextUtils.writeToParcel(mTitle, out, parcelableFlags);
@@ -763,6 +779,7 @@ public interface WindowManager extends ViewManager {
windowAnimations = in.readInt();
alpha = in.readFloat();
dimAmount = in.readFloat();
+ screenBrightness = in.readFloat();
token = in.readStrongBinder();
packageName = in.readString();
mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
@@ -780,6 +797,7 @@ public interface WindowManager extends ViewManager {
public static final int MEMORY_TYPE_CHANGED = 1<<8;
public static final int SOFT_INPUT_MODE_CHANGED = 1<<9;
public static final int SCREEN_ORIENTATION_CHANGED = 1<<10;
+ public static final int SCREEN_BRIGHTNESS_CHANGED = 1<<11;
public final int copyFrom(LayoutParams o) {
int changes = 0;
@@ -874,6 +892,10 @@ public interface WindowManager extends ViewManager {
dimAmount = o.dimAmount;
changes |= DIM_AMOUNT_CHANGED;
}
+ if (screenBrightness != o.screenBrightness) {
+ screenBrightness = o.screenBrightness;
+ changes |= SCREEN_BRIGHTNESS_CHANGED;
+ }
if (screenOrientation != o.screenOrientation) {
screenOrientation = o.screenOrientation;
diff --git a/core/java/android/view/WindowOrientationListener.java b/core/java/android/view/WindowOrientationListener.java
new file mode 100755
index 0000000..4aa3f7a
--- /dev/null
+++ b/core/java/android/view/WindowOrientationListener.java
@@ -0,0 +1,162 @@
+/*
+ * 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.view;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.util.Config;
+import android.util.Log;
+
+/**
+ * A special helper class used by the WindowManager
+ * for receiving notifications from the SensorManager when
+ * the orientation of the device has changed.
+ * @hide
+ */
+public abstract class WindowOrientationListener {
+ private static final String TAG = "WindowOrientationListener";
+ private static final boolean DEBUG = false;
+ private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
+ private int mOrientation = ORIENTATION_UNKNOWN;
+ private SensorManager mSensorManager;
+ private boolean mEnabled = false;
+ private int mRate;
+ private Sensor mSensor;
+ private SensorEventListener mSensorEventListener;
+
+ /**
+ * Returned from onOrientationChanged when the device orientation cannot be determined
+ * (typically when the device is in a close to flat position).
+ *
+ * @see #onOrientationChanged
+ */
+ public static final int ORIENTATION_UNKNOWN = -1;
+ /*
+ * Returned when the device is almost lying flat on a surface
+ */
+ public static final int ORIENTATION_FLAT = -2;
+
+ /**
+ * Creates a new WindowOrientationListener.
+ *
+ * @param context for the WindowOrientationListener.
+ */
+ public WindowOrientationListener(Context context) {
+ this(context, SensorManager.SENSOR_DELAY_NORMAL);
+ }
+
+ /**
+ * Creates a new WindowOrientationListener.
+ *
+ * @param context for the WindowOrientationListener.
+ * @param rate at which sensor events are processed (see also
+ * {@link android.hardware.SensorManager SensorManager}). Use the default
+ * value of {@link android.hardware.SensorManager#SENSOR_DELAY_NORMAL
+ * SENSOR_DELAY_NORMAL} for simple screen orientation change detection.
+ */
+ public WindowOrientationListener(Context context, int rate) {
+ mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
+ mRate = rate;
+ mSensorEventListener = new SensorEventListenerImpl();
+ mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ }
+
+ /**
+ * Enables the WindowOrientationListener so it will monitor the sensor and call
+ * {@link #onOrientationChanged} when the device orientation changes.
+ */
+ public void enable() {
+ if (mEnabled == false) {
+ if (localLOGV) Log.d(TAG, "WindowOrientationListener enabled");
+ mSensorManager.registerListener(mSensorEventListener, mSensor, mRate);
+ mEnabled = true;
+ }
+ }
+
+ /**
+ * Disables the WindowOrientationListener.
+ */
+ public void disable() {
+ if (mEnabled == true) {
+ if (localLOGV) Log.d(TAG, "WindowOrientationListener disabled");
+ mSensorManager.unregisterListener(mSensorEventListener);
+ mEnabled = false;
+ }
+ }
+
+ class SensorEventListenerImpl implements SensorEventListener {
+ private static final int _DATA_X = 0;
+ private static final int _DATA_Y = 1;
+ private static final int _DATA_Z = 2;
+
+ public void onSensorChanged(SensorEvent event) {
+ float[] values = event.values;
+ int orientation = ORIENTATION_UNKNOWN;
+ float X = values[_DATA_X];
+ float Y = values[_DATA_Y];
+ float Z = values[_DATA_Z];
+ float OneEightyOverPi = 57.29577957855f;
+ float gravity = (float) Math.sqrt(X*X+Y*Y+Z*Z);
+ float zyangle = Math.abs((float)Math.asin(Z/gravity)*OneEightyOverPi);
+ // The device is considered flat if the angle is more than 75
+ // if the angle is less than 40, its considered too flat to switch
+ // orientation. if the angle is between 40 - 75, the orientation is unknown
+ if (zyangle < 40) {
+ // Check orientation only if the phone is flat enough
+ // Don't trust the angle if the magnitude is small compared to the y value
+ float angle = (float)Math.atan2(Y, -X) * OneEightyOverPi;
+ orientation = 90 - (int)Math.round(angle);
+ // normalize to 0 - 359 range
+ while (orientation >= 360) {
+ orientation -= 360;
+ }
+ while (orientation < 0) {
+ orientation += 360;
+ }
+ } else if (zyangle >= 75){
+ orientation = ORIENTATION_FLAT;
+ }
+
+ if (orientation != mOrientation) {
+ mOrientation = orientation;
+ onOrientationChanged(orientation);
+ }
+ }
+
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+
+ }
+ }
+
+ /**
+ * Called when the orientation of the device has changed.
+ * orientation parameter is in degrees, ranging from 0 to 359.
+ * orientation is 0 degrees when the device is oriented in its natural position,
+ * 90 degrees when its left side is at the top, 180 degrees when it is upside down,
+ * and 270 degrees when its right side is to the top.
+ * {@link #ORIENTATION_UNKNOWN} is returned when the device is close to flat
+ * and the orientation cannot be determined.
+ *
+ * @param orientation The new orientation of the device.
+ *
+ * @see #ORIENTATION_UNKNOWN
+ */
+ abstract public void onOrientationChanged(int orientation);
+}
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index c96b3e5..b9c8ec3 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -179,6 +179,7 @@ public abstract class Animation implements Cloneable {
private boolean mOneMoreTime = true;
RectF mPreviousRegion = new RectF();
+ RectF mRegion = new RectF();
Transformation mTransformation = new Transformation();
Transformation mPreviousTransformation = new Transformation();
@@ -226,6 +227,7 @@ public abstract class Animation implements Cloneable {
protected Animation clone() throws CloneNotSupportedException {
final Animation animation = (Animation) super.clone();
animation.mPreviousRegion = new RectF();
+ animation.mRegion = new RectF();
animation.mTransformation = new Transformation();
animation.mPreviousTransformation = new Transformation();
return animation;
@@ -799,14 +801,15 @@ public abstract class Animation implements Cloneable {
public void getInvalidateRegion(int left, int top, int right, int bottom,
RectF invalidate, Transformation transformation) {
+ final RectF tempRegion = mRegion;
final RectF previousRegion = mPreviousRegion;
invalidate.set(left, top, right, bottom);
transformation.getMatrix().mapRect(invalidate);
+ tempRegion.set(invalidate);
invalidate.union(previousRegion);
- previousRegion.set(left, top, right, bottom);
- transformation.getMatrix().mapRect(previousRegion);
+ previousRegion.set(tempRegion);
final Transformation tempTransformation = mTransformation;
final Transformation previousTransformation = mPreviousTransformation;
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index 9509b15..6fbc174 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -525,9 +525,6 @@ public class BaseInputConnection implements InputConnection {
setComposingSpans(sp);
}
- // Adjust newCursorPosition to be relative the start of the text.
- newCursorPosition += a;
-
if (DEBUG) Log.v(TAG, "Replacing from " + a + " to " + b + " with \""
+ text + "\", composing=" + composing
+ ", type=" + text.getClass().getCanonicalName());
@@ -540,11 +537,21 @@ public class BaseInputConnection implements InputConnection {
TextUtils.dumpSpans(text, lp, " ");
}
- content.replace(a, b, text);
+ // Position the cursor appropriately, so that after replacing the
+ // desired range of text it will be located in the correct spot.
+ // This allows us to deal with filters performing edits on the text
+ // we are providing here.
+ if (newCursorPosition > 0) {
+ newCursorPosition += b - 1;
+ } else {
+ newCursorPosition += a;
+ }
if (newCursorPosition < 0) newCursorPosition = 0;
if (newCursorPosition > content.length())
newCursorPosition = content.length();
Selection.setSelection(content, newCursorPosition);
+
+ content.replace(a, b, text);
if (DEBUG) {
LogPrinter lp = new LogPrinter(Log.VERBOSE, TAG);
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 13173f6..530127d 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -148,8 +148,14 @@ public interface InputConnection {
* object to the text. {#link android.text.SpannableString} and
* {#link android.text.SpannableStringBuilder} are two
* implementations of the interface {#link android.text.Spanned}.
- * @param newCursorPosition The new cursor position within the
- * <var>text</var>.
+ * @param newCursorPosition The new cursor position around the text. If
+ * > 0, this is relative to the end of the text - 1; if <= 0, this
+ * is relative to the start of the text. So a value of 1 will
+ * always advance you to the position after the full text being
+ * inserted. Note that this means you can't position the cursor
+ * within the text, because the editor can make modifications to
+ * the text you are providing so it is not possible to correctly
+ * specify locations there.
*
* @return Returns true on success, false if the input connection is no longer
* valid.
@@ -170,8 +176,14 @@ public interface InputConnection {
* automatically.
*
* @param text The committed text.
- * @param newCursorPosition The new cursor position within the
- * <var>text</var>.
+ * @param newCursorPosition The new cursor position around the text. If
+ * > 0, this is relative to the end of the text - 1; if <= 0, this
+ * is relative to the start of the text. So a value of 1 will
+ * always advance you to the position after the full text being
+ * inserted. Note that this means you can't position the cursor
+ * within the text, because the editor can make modifications to
+ * the text you are providing so it is not possible to correctly
+ * specify locations there.
*
*
* @return Returns true on success, false if the input connection is no longer
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index fe14166..91fa211 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -226,6 +226,10 @@ public final class InputMethodManager {
* regardless of the state of setting that up.
*/
View mServedView;
+ /*
+ * Keep track of the view that was set when our window gained focus.
+ */
+ View mWindowFocusedView;
/**
* For evaluating the state after a focus change, this is the view that
* had focus.
@@ -466,8 +470,8 @@ public final class InputMethodManager {
}
/** @hide */
- public void setFullscreenMode(boolean enabled) {
- mFullscreenMode = true;
+ public void setFullscreenMode(boolean fullScreen) {
+ mFullscreenMode = fullScreen;
}
/**
@@ -828,19 +832,23 @@ public final class InputMethodManager {
*/
public void focusIn(View view) {
synchronized (mH) {
- if (DEBUG) Log.v(TAG, "focusIn: " + view);
- // Okay we have a new view that is being served.
- if (mServedView != view) {
- mCurrentTextBoxAttribute = null;
- }
- mServedView = view;
- mCompletions = null;
- mServedConnecting = true;
+ focusInLocked(view);
}
startInputInner();
}
+ void focusInLocked(View view) {
+ if (DEBUG) Log.v(TAG, "focusIn: " + view);
+ // Okay we have a new view that is being served.
+ if (mServedView != view) {
+ mCurrentTextBoxAttribute = null;
+ }
+ mServedView = view;
+ mCompletions = null;
+ mServedConnecting = true;
+ }
+
/**
* Call this when a view loses focus.
* @hide
@@ -908,16 +916,28 @@ public final class InputMethodManager {
* Called by ViewRoot the first time it gets window focus.
* @hide
*/
- public void onWindowFocus(View focusedView, int softInputMode,
+ public void onWindowFocus(View rootView, View focusedView, int softInputMode,
boolean first, int windowFlags) {
+ boolean needStartInput = false;
synchronized (mH) {
if (DEBUG) Log.v(TAG, "onWindowFocus: " + focusedView
+ " softInputMode=" + softInputMode
+ " first=" + first + " flags=#"
+ Integer.toHexString(windowFlags));
+ if (mWindowFocusedView == null) {
+ focusInLocked(focusedView != null ? focusedView : rootView);
+ needStartInput = true;
+ }
+ }
+
+ if (needStartInput) {
+ startInputInner();
+ }
+
+ synchronized (mH) {
try {
final boolean isTextEditor = focusedView != null &&
- focusedView.onCheckIsTextEditor();
+ focusedView.onCheckIsTextEditor();
mService.windowGainedFocus(mClient, focusedView != null,
isTextEditor, softInputMode, first, windowFlags);
} catch (RemoteException e) {
@@ -925,6 +945,13 @@ public final class InputMethodManager {
}
}
+ /** @hide */
+ public void startGettingWindowFocus() {
+ synchronized (mH) {
+ mWindowFocusedView = null;
+ }
+ }
+
/**
* Report the current selection range.
*/
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 1dd37be..451af6d 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -51,7 +51,7 @@ class BrowserFrame extends Handler {
private final Context mContext;
private final WebViewDatabase mDatabase;
private final WebViewCore mWebViewCore;
- private boolean mLoadInitFromJava;
+ /* package */ boolean mLoadInitFromJava;
private int mLoadType;
private boolean mFirstLayoutDone = true;
private boolean mCommitted = true;
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 3694969..dfae17d 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -575,7 +575,7 @@ class LoadListener extends Handler implements EventHandler {
mRequestHandle.getMethod().equals("POST")) {
sendMessageInternal(obtainMessage(
MSG_LOCATION_CHANGED_REQUEST));
- } else if (mMethod.equals("POST")) {
+ } else if (mMethod != null && mMethod.equals("POST")) {
sendMessageInternal(obtainMessage(
MSG_LOCATION_CHANGED_REQUEST));
} else {
diff --git a/core/java/android/webkit/TextDialog.java b/core/java/android/webkit/TextDialog.java
index 9af30c5..c2620a5 100644
--- a/core/java/android/webkit/TextDialog.java
+++ b/core/java/android/webkit/TextDialog.java
@@ -291,6 +291,25 @@ import java.util.ArrayList;
}
/**
+ * Create a fake touch up event at (x,y) with respect to this TextDialog.
+ * This is used by WebView to act as though a touch event which happened
+ * before we placed the TextDialog actually hit it, so that it can place
+ * the cursor accordingly.
+ */
+ /* package */ void fakeTouchEvent(float x, float y) {
+ // We need to ensure that there is a Layout, since the Layout is used
+ // in determining where to place the cursor.
+ if (getLayout() == null) {
+ measure(mWidthSpec, mHeightSpec);
+ }
+ // Create a fake touch up, which is used to place the cursor.
+ MotionEvent ev = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP,
+ x, y, 0);
+ onTouchEvent(ev);
+ ev.recycle();
+ }
+
+ /**
* Determine whether this TextDialog currently represents the node
* represented by ptr.
* @param ptr Pointer to a node to compare to.
@@ -461,9 +480,8 @@ import java.util.ArrayList;
*/
public void setAdapterCustom(AutoCompleteAdapter adapter) {
if (adapter != null) {
- adapter.setTextView(this);
- } else {
setInputType(EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE);
+ adapter.setTextView(this);
}
super.setAdapter(adapter);
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index bdbf38a..4d9a8fb 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -45,6 +45,8 @@ import android.util.AttributeSet;
import android.util.Config;
import android.util.Log;
import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -234,6 +236,9 @@ public class WebView extends AbsoluteLayout
*/
VelocityTracker mVelocityTracker;
+ private static boolean mShowZoomRingTutorial = true;
+ private static final int ZOOM_RING_TUTORIAL_DURATION = 3000;
+
/**
* Touch mode
*/
@@ -284,9 +289,7 @@ public class WebView extends AbsoluteLayout
// In the browser, if it switches out of tap too soon, jump tap won't work.
private static final int TAP_TIMEOUT = 200;
// The duration in milliseconds we will wait to see if it is a double tap.
- // With a limited survey, the time between the first tap up and the second
- // tap down in the double tap case is around 70ms - 120ms.
- private static final int DOUBLE_TAP_TIMEOUT = 200;
+ private static final int DOUBLE_TAP_TIMEOUT = 250;
// This should be ViewConfiguration.getLongPressTimeout()
// But system time out is 500ms, which is too short for the browser.
// With a short timeout, it's difficult to treat trigger a short press.
@@ -315,6 +318,9 @@ public class WebView extends AbsoluteLayout
private int mContentWidth; // cache of value from WebViewCore
private int mContentHeight; // cache of value from WebViewCore
+ static int MAX_FLOAT_CONTENT_WIDTH = 480;
+ private int mMinContentWidth;
+
// Need to have the separate control for horizontal and vertical scrollbar
// style than the View's single scrollbar style
private boolean mOverlayHorizontalScrollbar = true;
@@ -348,6 +354,7 @@ public class WebView extends AbsoluteLayout
private static final int UPDATE_TEXT_ENTRY_ADAPTER = 6;
private static final int SWITCH_TO_ENTER = 7;
private static final int RESUME_WEBCORE_UPDATE = 8;
+ private static final int DISMISS_ZOOM_RING_TUTORIAL = 9;
//! arg1=x, arg2=y
static final int SCROLL_TO_MSG_ID = 10;
@@ -370,12 +377,46 @@ public class WebView extends AbsoluteLayout
static final int WEBCORE_NEED_TOUCH_EVENTS = 25;
// obj=Rect in doc coordinates
static final int INVAL_RECT_MSG_ID = 26;
+
+ static final String[] HandlerDebugString = {
+ "REMEMBER_PASSWORD", // = 1;
+ "NEVER_REMEMBER_PASSWORD", // = 2;
+ "SWITCH_TO_SHORTPRESS", // = 3;
+ "SWITCH_TO_LONGPRESS", // = 4;
+ "RELEASE_SINGLE_TAP", // = 5;
+ "UPDATE_TEXT_ENTRY_ADAPTER", // = 6;
+ "SWITCH_TO_ENTER", // = 7;
+ "RESUME_WEBCORE_UPDATE", // = 8;
+ "9",
+ "SCROLL_TO_MSG_ID", // = 10;
+ "SCROLL_BY_MSG_ID", // = 11;
+ "SPAWN_SCROLL_TO_MSG_ID", // = 12;
+ "SYNC_SCROLL_TO_MSG_ID", // = 13;
+ "NEW_PICTURE_MSG_ID", // = 14;
+ "UPDATE_TEXT_ENTRY_MSG_ID", // = 15;
+ "WEBCORE_INITIALIZED_MSG_ID", // = 16;
+ "UPDATE_TEXTFIELD_TEXT_MSG_ID", // = 17;
+ "DID_FIRST_LAYOUT_MSG_ID", // = 18;
+ "RECOMPUTE_FOCUS_MSG_ID", // = 19;
+ "NOTIFY_FOCUS_SET_MSG_ID", // = 20;
+ "MARK_NODE_INVALID_ID", // = 21;
+ "UPDATE_CLIPBOARD", // = 22;
+ "LONG_PRESS_ENTER", // = 23;
+ "PREVENT_TOUCH_ID", // = 24;
+ "WEBCORE_NEED_TOUCH_EVENTS", // = 25;
+ "INVAL_RECT_MSG_ID" // = 26;
+ };
// width which view is considered to be fully zoomed out
static final int ZOOM_OUT_WIDTH = 1024;
- private static final float DEFAULT_MAX_ZOOM_SCALE = 4;
- private static final float DEFAULT_MIN_ZOOM_SCALE = 0.25f;
+ private static final float MAX_ZOOM_RING_ANGLE = (float) (Math.PI * 2 / 3);
+ private static final int ZOOM_RING_STEPS = 4;
+ private static final float ZOOM_RING_ANGLE_UNIT = MAX_ZOOM_RING_ANGLE
+ / ZOOM_RING_STEPS;
+
+ private static final float DEFAULT_MAX_ZOOM_SCALE = 2;
+ private static final float DEFAULT_MIN_ZOOM_SCALE = (float) 1/3;
// scale limit, which can be set through viewport meta tag in the web page
private float mMaxZoomScale = DEFAULT_MAX_ZOOM_SCALE;
private float mMinZoomScale = DEFAULT_MIN_ZOOM_SCALE;
@@ -505,6 +546,8 @@ public class WebView extends AbsoluteLayout
}
private ZoomRingController mZoomRingController;
+ private ImageView mZoomRingOverview;
+ private Animation mZoomRingOverviewExitAnimation;
// These keep track of the center point of the zoom ring. They are used to
// determine the point around which we should zoom.
@@ -519,51 +562,83 @@ public class WebView extends AbsoluteLayout
// in this callback
}
+ public void onBeginPan() {
+ setZoomOverviewVisible(false);
+ }
+
public boolean onPan(int deltaX, int deltaY) {
return pinScrollBy(deltaX, deltaY, false, 0);
}
+ public void onEndPan() {
+ }
+
public void onVisibilityChanged(boolean visible) {
if (visible) {
- mZoomControls.show(false, canZoomScrollOut());
- } else {
- mZoomControls.hide();
+ switchOutDrawHistory();
+ float angle = 0f;
+ if (mActualScale > 1) {
+ angle = -(float) Math.round(ZOOM_RING_STEPS
+ * (mActualScale - 1) / (mMaxZoomScale - 1))
+ / ZOOM_RING_STEPS;
+ } else if (mActualScale < 1) {
+ angle = (float) Math.round(ZOOM_RING_STEPS
+ * (1 - mActualScale) / (1 - mMinZoomScale))
+ / ZOOM_RING_STEPS;
+ }
+ mZoomRingController.setThumbAngle(angle * MAX_ZOOM_RING_ANGLE);
+
+ // Show the zoom overview tab on the ring
+ setZoomOverviewVisible(true);
}
}
-
- public void onBeginDrag(float startAngle) {
+
+ public void onBeginDrag() {
mPreviewZoomOnly = true;
+ setZoomOverviewVisible(false);
}
- public void onEndDrag(float endAngle) {
+ public void onEndDrag() {
mPreviewZoomOnly = false;
setNewZoomScale(mActualScale, true);
}
public boolean onDragZoom(int deltaZoomLevel, int centerX,
int centerY, float startAngle, float curAngle) {
-
- if (mZoomScale == mMinZoomScale && deltaZoomLevel < 0 ||
- mZoomScale == mMaxZoomScale && deltaZoomLevel > 0 ||
- deltaZoomLevel == 0) {
+ if (deltaZoomLevel < 0
+ && Math.abs(mActualScale - mMinZoomScale) < 0.01f
+ || deltaZoomLevel > 0
+ && Math.abs(mActualScale - mMaxZoomScale) < 0.01f
+ || deltaZoomLevel == 0) {
return false;
}
mZoomCenterX = (float) centerX;
mZoomCenterY = (float) centerY;
- while (deltaZoomLevel != 0) {
- if (deltaZoomLevel > 0) {
- if (!zoomIn()) return false;
- deltaZoomLevel--;
+ float scale = 1.0f;
+ if (curAngle > (float) Math.PI)
+ curAngle -= (float) 2 * Math.PI;
+ if (curAngle > 0) {
+ if (curAngle >= MAX_ZOOM_RING_ANGLE) {
+ scale = mMinZoomScale;
+ } else {
+ scale = 1 - (float) Math.round(curAngle
+ / ZOOM_RING_ANGLE_UNIT) / ZOOM_RING_STEPS
+ * (1 - mMinZoomScale);
+ }
+ } else if (curAngle < 0) {
+ if (curAngle <= -MAX_ZOOM_RING_ANGLE) {
+ scale = mMaxZoomScale;
} else {
- if (!zoomOut()) return false;
- deltaZoomLevel++;
+ scale = 1 + (float) Math.round(-curAngle
+ / ZOOM_RING_ANGLE_UNIT) / ZOOM_RING_STEPS
+ * (mMaxZoomScale - 1);
}
}
-
+ zoomWithPreview(scale);
return true;
}
-
+
public void onSimpleZoom(boolean zoomIn) {
if (zoomIn) {
zoomIn();
@@ -571,6 +646,7 @@ public class WebView extends AbsoluteLayout
zoomOut();
}
}
+
};
/**
@@ -610,7 +686,14 @@ public class WebView extends AbsoluteLayout
mFocusData.mY = 0;
mScroller = new Scroller(context);
mZoomRingController = new ZoomRingController(context, this);
+ mZoomRingController.setResetThumbAutomatically(false);
+ mZoomRingController.setThumbClockwiseBound(
+ (float) (2 * Math.PI - MAX_ZOOM_RING_ANGLE));
+ mZoomRingController.setThumbCounterclockwiseBound(MAX_ZOOM_RING_ANGLE);
mZoomRingController.setCallback(mZoomListener);
+ mZoomRingController.setZoomRingTrack(
+ com.android.internal.R.drawable.zoom_ring_track_absolute);
+ createZoomRingOverviewTab();
}
private void init() {
@@ -625,6 +708,63 @@ public class WebView extends AbsoluteLayout
mMinLockSnapReverseDistance = slop;
}
+ private void createZoomRingOverviewTab() {
+ Context context = getContext();
+
+ mZoomRingOverviewExitAnimation = AnimationUtils.loadAnimation(context,
+ com.android.internal.R.anim.fade_out);
+
+ mZoomRingOverview = new ImageView(context);
+ mZoomRingOverview.setBackgroundResource(
+ com.android.internal.R.drawable.zoom_ring_overview_tab);
+ mZoomRingOverview.setImageResource(com.android.internal.R.drawable.btn_zoom_page);
+
+ FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.WRAP_CONTENT,
+ FrameLayout.LayoutParams.WRAP_CONTENT,
+ Gravity.CENTER);
+ // TODO: magic constant that's based on the zoom ring radius + some offset
+ lp.topMargin = 208;
+ mZoomRingOverview.setLayoutParams(lp);
+ mZoomRingOverview.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ // Hide the zoom ring
+ mZoomRingController.setVisible(false);
+ zoomScrollOut();
+ }});
+
+ // Measure the overview View to figure out its height
+ mZoomRingOverview.forceLayout();
+ mZoomRingOverview.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+
+ ViewGroup container = mZoomRingController.getContainer();
+ // Find the index of the zoom ring in the container
+ View zoomRing = container.findViewById(mZoomRingController.getZoomRingId());
+ int zoomRingIndex;
+ for (zoomRingIndex = container.getChildCount() - 1; zoomRingIndex >= 0; zoomRingIndex--) {
+ if (container.getChildAt(zoomRingIndex) == zoomRing) break;
+ }
+ // Add the overview tab below the zoom ring (so we don't steal its events)
+ container.addView(mZoomRingOverview, zoomRingIndex);
+ // Since we use margins to adjust the vertical placement of the tab, the widget
+ // ends up getting clipped off. Ensure the container is big enough for
+ // us.
+ int myHeight = mZoomRingOverview.getMeasuredHeight() + lp.topMargin / 2;
+ // Multiplied by 2 b/c the zoom ring needs to be centered on the screen
+ container.setMinimumHeight(myHeight * 2);
+ }
+
+ private void setZoomOverviewVisible(boolean visible) {
+ int newVisibility = visible ? View.VISIBLE : View.INVISIBLE;
+ if (mZoomRingOverview.getVisibility() == newVisibility) return;
+
+ if (!visible) {
+ mZoomRingOverview.startAnimation(mZoomRingOverviewExitAnimation);
+ }
+ mZoomRingOverview.setVisibility(newVisibility);
+ }
+
/* package */ boolean onSavePassword(String schemePlusHost, String username,
String password, final Message resumeMsg) {
boolean rVal = false;
@@ -1653,7 +1793,8 @@ public class WebView extends AbsoluteLayout
* @return true if new values were sent
*/
private boolean sendViewSizeZoom() {
- int newWidth = Math.round(getViewWidth() * mInvActualScale);
+ int viewWidth = getViewWidth();
+ int newWidth = Math.round(viewWidth * mInvActualScale);
int newHeight = Math.round(getViewHeight() * mInvActualScale);
/*
* Because the native side may have already done a layout before the
@@ -1669,7 +1810,7 @@ public class WebView extends AbsoluteLayout
// Avoid sending another message if the dimensions have not changed.
if (newWidth != mLastWidthSent || newHeight != mLastHeightSent) {
mWebViewCore.sendMessage(EventHub.VIEW_SIZE_CHANGED,
- newWidth, newHeight, new Float(mActualScale));
+ newWidth, newHeight, new Integer(viewWidth));
mLastWidthSent = newWidth;
mLastHeightSent = newHeight;
return true;
@@ -1968,7 +2109,7 @@ public class WebView extends AbsoluteLayout
// Scale from content to view coordinates, and pin.
// Also called by jni webview.cpp
- private void setContentScrollBy(int cx, int cy) {
+ private void setContentScrollBy(int cx, int cy, boolean animate) {
if (mDrawHistory) {
// disallow WebView to change the scroll position as History Picture
// is used in the view system.
@@ -1992,10 +2133,10 @@ public class WebView extends AbsoluteLayout
// vertical scroll?
// Log.d(LOGTAG, "setContentScrollBy cy=" + cy);
if (cy == 0 && cx != 0) {
- pinScrollBy(cx, 0, true, 0);
+ pinScrollBy(cx, 0, animate, 0);
}
} else {
- pinScrollBy(cx, cy, true, 0);
+ pinScrollBy(cx, cy, animate, 0);
}
}
@@ -2205,7 +2346,8 @@ public class WebView extends AbsoluteLayout
// state.
// If mNativeClass is 0, we should not reach here, so we do not
// need to check it again.
- nativeRecordButtons(mTouchMode == TOUCH_SHORTPRESS_START_MODE
+ nativeRecordButtons(hasFocus() && hasWindowFocus(),
+ mTouchMode == TOUCH_SHORTPRESS_START_MODE
|| mTrackballDown || mGotEnterDown, false);
drawCoreAndFocusRing(canvas, mBackgroundColor, mDrawFocusRing);
}
@@ -2254,6 +2396,8 @@ public class WebView extends AbsoluteLayout
invalidate();
} else {
zoomScale = mZoomScale;
+ // set mZoomScale to be 0 as we have done animation
+ mZoomScale = 0;
}
float scale = (mActualScale - zoomScale) * mInvActualScale;
float tx = scale * (mZoomCenterX + mScrollX);
@@ -2775,6 +2919,17 @@ public class WebView extends AbsoluteLayout
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(mTextEntry, 0);
mTextEntry.enableScrollOnScreen(true);
+ // Now we need to fake a touch event to place the cursor where the
+ // user touched.
+ AbsoluteLayout.LayoutParams lp = (AbsoluteLayout.LayoutParams)
+ mTextEntry.getLayoutParams();
+ if (lp != null) {
+ // Take the last touch and adjust for the location of the
+ // TextDialog.
+ float x = mLastTouchX - lp.x;
+ float y = mLastTouchY - lp.y;
+ mTextEntry.fakeTouchEvent(x, y);
+ }
}
private void updateTextEntry() {
@@ -2987,7 +3142,9 @@ public class WebView extends AbsoluteLayout
mGotEnterDown = true;
mPrivateHandler.sendMessageDelayed(mPrivateHandler
.obtainMessage(LONG_PRESS_ENTER), LONG_PRESS_TIMEOUT);
- nativeRecordButtons(true, true);
+ // Already checked mNativeClass, so we do not need to check it
+ // again.
+ nativeRecordButtons(hasFocus() && hasWindowFocus(), true, true);
return true;
}
// Bubble up the key event as WebView doesn't handle it
@@ -3198,6 +3355,9 @@ public class WebView extends AbsoluteLayout
ViewGroup p = (ViewGroup) parent;
p.setOnHierarchyChangeListener(null);
}
+
+ // Clean up the zoom ring
+ mZoomRingController.setVisible(false);
}
// Implementation for OnHierarchyChangeListener
@@ -3234,16 +3394,25 @@ public class WebView extends AbsoluteLayout
if (mNeedsUpdateTextEntry) {
updateTextEntry();
}
+ if (mNativeClass != 0) {
+ nativeRecordButtons(true, false, true);
+ }
} else {
// If our window gained focus, but we do not have it, do not
// draw the focus ring.
mDrawFocusRing = false;
+ // We do not call nativeRecordButtons here because we assume
+ // that when we lost focus, or window focus, it got called with
+ // false for the first parameter
}
} else {
// If our window has lost focus, stop drawing the focus ring
mDrawFocusRing = false;
mGotKeyDown = false;
mShiftIsPressed = false;
+ if (mNativeClass != 0) {
+ nativeRecordButtons(false, false, true);
+ }
}
invalidate();
super.onWindowFocusChanged(hasWindowFocus);
@@ -3264,12 +3433,22 @@ public class WebView extends AbsoluteLayout
updateTextEntry();
mNeedsUpdateTextEntry = false;
}
+ if (mNativeClass != 0) {
+ nativeRecordButtons(true, false, true);
+ }
+ //} else {
+ // The WebView has gained focus while we do not have
+ // windowfocus. When our window lost focus, we should have
+ // called nativeRecordButtons(false...)
}
} else {
// When we lost focus, unless focus went to the TextView (which is
// true if we are in editing mode), stop drawing the focus ring.
if (!inEditingMode()) {
mDrawFocusRing = false;
+ if (mNativeClass != 0) {
+ nativeRecordButtons(false, false, true);
+ }
}
mGotKeyDown = false;
}
@@ -3285,6 +3464,22 @@ public class WebView extends AbsoluteLayout
// the new zoom ring controller
mZoomCenterX = getViewWidth() * .5f;
mZoomCenterY = getViewHeight() * .5f;
+
+ // update mMinZoomScale
+ if (mMinContentWidth > MAX_FLOAT_CONTENT_WIDTH) {
+ boolean atMin = Math.abs(mActualScale - mMinZoomScale) < 0.01f;
+ mMinZoomScale = (float) getViewWidth() / mMinContentWidth;
+ if (atMin) {
+ // if the WebView was at the minimum zoom scale, keep it. e,g.,
+ // the WebView was at the minimum zoom scale at the portrait
+ // mode, rotate it to the landscape modifying the scale to the
+ // new minimum zoom scale, when rotating back, we would like to
+ // keep the minimum zoom scale instead of keeping the same scale
+ // as normally we do.
+ mActualScale = mMinZoomScale;
+ }
+ }
+
// we always force, in case our height changed, in which case we still
// want to send the notification over to webkit
setNewZoomScale(mActualScale, true);
@@ -3340,6 +3535,14 @@ public class WebView extends AbsoluteLayout
return false;
}
+ if (mShowZoomRingTutorial && mMinZoomScale < mMaxZoomScale) {
+ ZoomRingController.showZoomTutorialOnce(mContext);
+ mShowZoomRingTutorial = false;
+ mPrivateHandler.sendMessageDelayed(mPrivateHandler
+ .obtainMessage(DISMISS_ZOOM_RING_TUTORIAL),
+ ZOOM_RING_TUTORIAL_DURATION);
+ }
+
if (LOGV_ENABLED) {
Log.v(LOGTAG, ev + " at " + ev.getEventTime() + " mTouchMode="
+ mTouchMode);
@@ -3749,7 +3952,7 @@ public class WebView extends AbsoluteLayout
mPrivateHandler.removeMessages(SWITCH_TO_ENTER);
mTrackballDown = true;
if (mNativeClass != 0) {
- nativeRecordButtons(true, true);
+ nativeRecordButtons(hasFocus() && hasWindowFocus(), true, true);
}
if (time - mLastFocusTime <= TRACKBALL_TIMEOUT
&& !mLastFocusBounds.equals(nativeGetFocusRingBounds())) {
@@ -4148,6 +4351,9 @@ public class WebView extends AbsoluteLayout
});
zoomControls.setOnZoomMagnifyClickListener(new OnClickListener() {
public void onClick(View v) {
+ // Hide the zoom ring
+ mZoomRingController.setVisible(false);
+
mPrivateHandler.removeCallbacks(mZoomControlRunnable);
mPrivateHandler.postDelayed(mZoomControlRunnable,
ZOOM_CONTROLS_TIMEOUT);
@@ -4200,6 +4406,12 @@ public class WebView extends AbsoluteLayout
}
}
+ // Called by JNI to handle a touch on a node representing an email address,
+ // address, or phone number
+ private void overrideLoading(String url) {
+ mCallbackProxy.uiOverrideUrlLoading(url);
+ }
+
@Override
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
boolean result = false;
@@ -4372,6 +4584,11 @@ public class WebView extends AbsoluteLayout
class PrivateHandler extends Handler {
@Override
public void handleMessage(Message msg) {
+ if (LOGV_ENABLED) {
+ Log.v(LOGTAG, msg.what < REMEMBER_PASSWORD || msg.what
+ > INVAL_RECT_MSG_ID ? Integer.toString(msg.what)
+ : HandlerDebugString[msg.what - REMEMBER_PASSWORD]);
+ }
switch (msg.what) {
case REMEMBER_PASSWORD: {
mDatabase.setUsernamePassword(
@@ -4413,7 +4630,7 @@ public class WebView extends AbsoluteLayout
, KeyEvent.KEYCODE_ENTER));
break;
case SCROLL_BY_MSG_ID:
- setContentScrollBy(msg.arg1, msg.arg2);
+ setContentScrollBy(msg.arg1, msg.arg2, (Boolean) msg.obj);
break;
case SYNC_SCROLL_TO_MSG_ID:
if (mUserScroll) {
@@ -4451,6 +4668,11 @@ public class WebView extends AbsoluteLayout
0, 0);
}
}
+ mMinContentWidth = msg.arg1;
+ if (mMinContentWidth > MAX_FLOAT_CONTENT_WIDTH) {
+ mMinZoomScale = (float) getViewWidth()
+ / mMinContentWidth;
+ }
// We update the layout (i.e. request a layout from the
// view system) if the last view size that we sent to
// WebCore matches the view size of the picture we just
@@ -4638,6 +4860,10 @@ public class WebView extends AbsoluteLayout
}
break;
+ case DISMISS_ZOOM_RING_TUTORIAL:
+ mZoomRingController.finishZoomTutorial();
+ break;
+
default:
super.handleMessage(msg);
break;
@@ -5018,8 +5244,8 @@ public class WebView extends AbsoluteLayout
private native void nativeRecomputeFocus();
// Like many other of our native methods, you must make sure that
// mNativeClass is not null before calling this method.
- private native void nativeRecordButtons(boolean pressed,
- boolean invalidate);
+ private native void nativeRecordButtons(boolean focused,
+ boolean pressed, boolean invalidate);
private native void nativeResetFocus();
private native void nativeResetNavClipBounds();
private native void nativeSelectBestAt(Rect rect);
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index b979032..45113ab 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -271,6 +271,11 @@ final class WebViewCore {
static native String nativeFindAddress(String addr);
/**
+ * Rebuild the nav cache if the dom changed.
+ */
+ private native void nativeCheckNavCache();
+
+ /**
* Empty the picture set.
*/
private native void nativeClearContent();
@@ -317,7 +322,7 @@ final class WebViewCore {
should this be called nativeSetViewPortSize?
*/
private native void nativeSetSize(int width, int height, int screenWidth,
- float scale);
+ float scale, int realScreenWidth, int screenHeight);
private native int nativeGetContentMinPrefWidth();
@@ -501,6 +506,51 @@ final class WebViewCore {
int mY;
}
+ static final String[] HandlerDebugString = {
+ "LOAD_URL", // = 100;
+ "STOP_LOADING", // = 101;
+ "RELOAD", // = 102;
+ "KEY_DOWN", // = 103;
+ "KEY_UP", // = 104;
+ "VIEW_SIZE_CHANGED", // = 105;
+ "GO_BACK_FORWARD", // = 106;
+ "SET_SCROLL_OFFSET", // = 107;
+ "RESTORE_STATE", // = 108;
+ "PAUSE_TIMERS", // = 109;
+ "RESUME_TIMERS", // = 110;
+ "CLEAR_CACHE", // = 111;
+ "CLEAR_HISTORY", // = 112;
+ "SET_SELECTION", // = 113;
+ "REPLACE_TEXT", // = 114;
+ "PASS_TO_JS", // = 115;
+ "SET_GLOBAL_BOUNDS", // = 116;
+ "UPDATE_CACHE_AND_TEXT_ENTRY", // = 117;
+ "CLICK", // = 118;
+ "119",
+ "DOC_HAS_IMAGES", // = 120;
+ "SET_SNAP_ANCHOR", // = 121;
+ "DELETE_SELECTION", // = 122;
+ "LISTBOX_CHOICES", // = 123;
+ "SINGLE_LISTBOX_CHOICE", // = 124;
+ "125",
+ "SET_BACKGROUND_COLOR", // = 126;
+ "UNBLOCK_FOCUS", // = 127;
+ "SAVE_DOCUMENT_STATE", // = 128;
+ "GET_SELECTION", // = 129;
+ "WEBKIT_DRAW", // = 130;
+ "SYNC_SCROLL", // = 131;
+ "REFRESH_PLUGINS", // = 132;
+ "SPLIT_PICTURE_SET", // = 133;
+ "CLEAR_CONTENT", // = 134;
+ "SET_FINAL_FOCUS", // = 135;
+ "SET_KIT_FOCUS", // = 136;
+ "REQUEST_FOCUS_HREF", // = 137;
+ "ADD_JS_INTERFACE", // = 138;
+ "LOAD_DATA", // = 139;
+ "TOUCH_UP", // = 140;
+ "TOUCH_EVENT", // = 141;
+ };
+
class EventHub {
// Message Ids
static final int LOAD_URL = 100;
@@ -595,6 +645,11 @@ final class WebViewCore {
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
+ if (LOGV_ENABLED) {
+ Log.v(LOGTAG, msg.what < LOAD_URL || msg.what
+ > TOUCH_EVENT ? Integer.toString(msg.what)
+ : HandlerDebugString[msg.what - LOAD_URL]);
+ }
switch (msg.what) {
case WEBKIT_DRAW:
webkitDraw();
@@ -675,7 +730,7 @@ final class WebViewCore {
case VIEW_SIZE_CHANGED:
viewSizeChanged(msg.arg1, msg.arg2,
- ((Float) msg.obj).floatValue());
+ ((Integer) msg.obj).intValue());
break;
case SET_SCROLL_OFFSET:
@@ -1131,12 +1186,22 @@ final class WebViewCore {
private int mCurrentViewWidth = 0;
private int mCurrentViewHeight = 0;
+ // Define a minimum screen width so that we won't wrap the paragraph to one
+ // word per line during zoom-in.
+ private static final int MIN_SCREEN_WIDTH = 160;
+
// notify webkit that our virtual view size changed size (after inv-zoom)
- private void viewSizeChanged(int w, int h, float scale) {
+ private void viewSizeChanged(int w, int h, int viewWidth) {
if (LOGV_ENABLED) Log.v(LOGTAG, "CORE onSizeChanged");
+ if (w == 0) {
+ Log.w(LOGTAG, "skip viewSizeChanged as w is 0");
+ return;
+ }
+ float scale = (float) viewWidth / w;
if (mSettings.getUseWideViewPort()
&& (w < mViewportWidth || mViewportWidth == -1)) {
int width = mViewportWidth;
+ int screenWidth = Math.max(w, MIN_SCREEN_WIDTH);
if (mViewportWidth == -1) {
if (mSettings.getLayoutAlgorithm() ==
WebSettings.LayoutAlgorithm.NORMAL) {
@@ -1154,12 +1219,21 @@ final class WebViewCore {
* In the worse case, the native width will be adjusted when
* next zoom or screen orientation change happens.
*/
- width = Math.max(w, nativeGetContentMinPrefWidth());
+ int minContentWidth = nativeGetContentMinPrefWidth();
+ if (minContentWidth > WebView.MAX_FLOAT_CONTENT_WIDTH) {
+ // keep the same width and screen width so that there is
+ // no reflow when zoom-out
+ width = minContentWidth;
+ screenWidth = Math.min(screenWidth, viewWidth);
+ } else {
+ width = Math.max(w, minContentWidth);
+ }
}
}
- nativeSetSize(width, Math.round((float) width * h / w), w, scale);
+ nativeSetSize(width, Math.round((float) width * h / w),
+ screenWidth, scale, w, h);
} else {
- nativeSetSize(w, h, w, scale);
+ nativeSetSize(w, h, w, scale, w, h);
}
// Remember the current width and height
boolean needInvalidate = (mCurrentViewWidth == 0);
@@ -1219,7 +1293,9 @@ final class WebViewCore {
draw.mViewPoint = new Point(mCurrentViewWidth, mCurrentViewHeight);
if (LOGV_ENABLED) Log.v(LOGTAG, "webkitDraw NEW_PICTURE_MSG_ID");
Message.obtain(mWebView.mPrivateHandler,
- WebView.NEW_PICTURE_MSG_ID, draw).sendToTarget();
+ WebView.NEW_PICTURE_MSG_ID, nativeGetContentMinPrefWidth(),
+ 0, draw).sendToTarget();
+ nativeCheckNavCache();
if (mWebkitScrollX != 0 || mWebkitScrollY != 0) {
// as we have the new picture, try to sync the scroll position
Message.obtain(mWebView.mPrivateHandler,
@@ -1324,7 +1400,9 @@ final class WebViewCore {
for (int i = 0; i < size; i++) {
list.getItemAtIndex(i).inflate(mBrowserFrame.mNativeFrame);
}
+ mBrowserFrame.mLoadInitFromJava = true;
list.restoreIndex(mBrowserFrame.mNativeFrame, index);
+ mBrowserFrame.mLoadInitFromJava = false;
}
//-------------------------------------------------------------------------
@@ -1349,14 +1427,15 @@ final class WebViewCore {
}
// called by JNI
- private void contentScrollBy(int dx, int dy) {
+ private void contentScrollBy(int dx, int dy, boolean animate) {
if (!mBrowserFrame.firstLayoutDone()) {
// Will this happen? If yes, we need to do something here.
return;
}
if (mWebView != null) {
Message.obtain(mWebView.mPrivateHandler,
- WebView.SCROLL_BY_MSG_ID, dx, dy).sendToTarget();
+ WebView.SCROLL_BY_MSG_ID, dx, dy,
+ new Boolean(animate)).sendToTarget();
}
}
@@ -1461,7 +1540,7 @@ final class WebViewCore {
// current scale
mEventHub.sendMessage(Message.obtain(null,
EventHub.VIEW_SIZE_CHANGED, mWebView.mLastWidthSent,
- mWebView.mLastHeightSent, -1.0f));
+ mWebView.mLastHeightSent, new Integer(-1)));
}
mBrowserFrame.didFirstLayout();
diff --git a/core/java/android/webkit/gears/HttpRequestAndroid.java b/core/java/android/webkit/gears/HttpRequestAndroid.java
deleted file mode 100644
index 30f855f..0000000
--- a/core/java/android/webkit/gears/HttpRequestAndroid.java
+++ /dev/null
@@ -1,745 +0,0 @@
-// Copyright 2008, The Android Open Source Project
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// 3. Neither the name of Google Inc. nor the names of its contributors may be
-// used to endorse or promote products derived from this software without
-// specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package android.webkit.gears;
-
-import android.net.http.Headers;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-import android.webkit.CacheManager;
-import android.webkit.CacheManager.CacheResult;
-import android.webkit.CookieManager;
-
-import org.apache.http.conn.ssl.StrictHostnameVerifier;
-import org.apache.http.impl.cookie.DateUtils;
-import org.apache.http.util.CharArrayBuffer;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import javax.net.ssl.*;
-
-/**
- * Performs the underlying HTTP/HTTPS GET and POST requests.
- * <p> These are performed synchronously (blocking). The caller should
- * ensure that it is in a background thread if asynchronous behavior
- * is required. All data is pushed, so there is no need for JNI native
- * callbacks.
- * <p> This uses the java.net.HttpURLConnection class to perform most
- * of the underlying network activity. The Android brower's cache,
- * android.webkit.CacheManager, is also used when caching is enabled,
- * and updated with new data. The android.webkit.CookieManager is also
- * queried and updated as necessary.
- * <p> The public interface is designed to be called by native code
- * through JNI, and to simplify coding none of the public methods will
- * surface a checked exception. Unchecked exceptions may still be
- * raised but only if the system is in an ill state, such as out of
- * memory.
- * <p> TODO: This isn't plumbed into LocalServer yet. Mutually
- * dependent on LocalServer - will attach the two together once both
- * are submitted.
- */
-public final class HttpRequestAndroid {
- /** Debug logging tag. */
- private static final String LOG_TAG = "Gears-J";
- /** HTTP response header line endings are CR-LF style. */
- private static final String HTTP_LINE_ENDING = "\r\n";
- /** Safe MIME type to use whenever it isn't specified. */
- private static final String DEFAULT_MIME_TYPE = "text/plain";
- /** Case-sensitive header keys */
- public static final String KEY_CONTENT_LENGTH = "Content-Length";
- public static final String KEY_EXPIRES = "Expires";
- public static final String KEY_LAST_MODIFIED = "Last-Modified";
- public static final String KEY_ETAG = "ETag";
- public static final String KEY_LOCATION = "Location";
- public static final String KEY_CONTENT_TYPE = "Content-Type";
- /** Number of bytes to send and receive on the HTTP connection in
- * one go. */
- private static final int BUFFER_SIZE = 4096;
- /** The first element of the String[] value in a headers map is the
- * unmodified (case-sensitive) key. */
- public static final int HEADERS_MAP_INDEX_KEY = 0;
- /** The second element of the String[] value in a headers map is the
- * associated value. */
- public static final int HEADERS_MAP_INDEX_VALUE = 1;
-
- /** Enable/disable all logging in this class. */
- private static boolean logEnabled = false;
- /** The underlying HTTP or HTTPS network connection. */
- private HttpURLConnection connection;
- /** HTTP body stream, setup after connection. */
- private InputStream inputStream;
- /** The complete response line e.g "HTTP/1.0 200 OK" */
- private String responseLine;
- /** Request headers, as a lowercase key -> [ unmodified key, value ] map. */
- private Map<String, String[]> requestHeaders =
- new HashMap<String, String[]>();
- /** Response headers, as a lowercase key -> [ unmodified key, value ] map. */
- private Map<String, String[]> responseHeaders;
- /** True if the child thread is in performing blocking IO. */
- private boolean inBlockingOperation = false;
- /** True when the thread acknowledges the abort. */
- private boolean abortReceived = false;
- /** The URL used for createCacheResult() */
- private String cacheResultUrl;
- /** CacheResult being saved into, if inserting a new cache entry. */
- private CacheResult cacheResult;
- /** Initialized by initChildThread(). Used to target abort(). */
- private Thread childThread;
-
- /**
- * Convenience debug function. Calls Android logging mechanism.
- * @param str String to log to the Android console.
- */
- private static void log(String str) {
- if (logEnabled) {
- Log.i(LOG_TAG, str);
- }
- }
-
- /**
- * Turn on/off logging in this class.
- * @param on Logging enable state.
- */
- public static void enableLogging(boolean on) {
- logEnabled = on;
- }
-
- /**
- * Initialize childThread using the TLS value of
- * Thread.currentThread(). Called on start up of the native child
- * thread.
- */
- public synchronized void initChildThread() {
- childThread = Thread.currentThread();
- }
-
- /**
- * Analagous to the native-side HttpRequest::open() function. This
- * initializes an underlying java.net.HttpURLConnection, but does
- * not go to the wire. On success, this enables a call to send() to
- * initiate the transaction.
- *
- * @param method The HTTP method, e.g GET or POST.
- * @param url The URL to open.
- * @return True on success with a complete HTTP response.
- * False on failure.
- */
- public synchronized boolean open(String method, String url) {
- if (logEnabled)
- log("open " + method + " " + url);
- // Reset the response between calls to open().
- inputStream = null;
- responseLine = null;
- responseHeaders = null;
- if (!method.equals("GET") && !method.equals("POST")) {
- log("Method " + method + " not supported");
- return false;
- }
- // Setup the connection. This doesn't go to the wire yet - it
- // doesn't block.
- try {
- URL url_object = new URL(url);
- // Check that the protocol is indeed HTTP(S).
- String protocol = url_object.getProtocol();
- if (protocol == null) {
- log("null protocol for URL " + url);
- return false;
- }
- protocol = protocol.toLowerCase();
- if (!"http".equals(protocol) && !"https".equals(protocol)) {
- log("Url has wrong protocol: " + url);
- return false;
- }
-
- connection = (HttpURLConnection) url_object.openConnection();
- connection.setRequestMethod(method);
- // Manually follow redirects.
- connection.setInstanceFollowRedirects(false);
- // Manually cache.
- connection.setUseCaches(false);
- // Enable data output in POST method requests.
- connection.setDoOutput(method.equals("POST"));
- // Enable data input in non-HEAD method requests.
- // TODO: HEAD requests not tested.
- connection.setDoInput(!method.equals("HEAD"));
- if (connection instanceof javax.net.ssl.HttpsURLConnection) {
- // Verify the certificate matches the origin.
- ((HttpsURLConnection) connection).setHostnameVerifier(
- new StrictHostnameVerifier());
- }
- return true;
- } catch (IOException e) {
- log("Got IOException in open: " + e.toString());
- return false;
- }
- }
-
- /**
- * Interrupt a blocking IO operation. This will cause the child
- * thread to expediently return from an operation if it was stuck at
- * the time. Note that this inherently races, and unfortunately
- * requires the caller to loop.
- */
- public synchronized void interrupt() {
- if (childThread == null) {
- log("interrupt() called but no child thread");
- return;
- }
- synchronized (this) {
- if (inBlockingOperation) {
- log("Interrupting blocking operation");
- childThread.interrupt();
- } else {
- log("Nothing to interrupt");
- }
- }
- }
-
- /**
- * Set a header to send with the HTTP request. Will not take effect
- * on a transaction already in progress. The key is associated
- * case-insensitive, but stored case-sensitive.
- * @param name The name of the header, e.g "Set-Cookie".
- * @param value The value for this header, e.g "text/html".
- */
- public synchronized void setRequestHeader(String name, String value) {
- String[] mapValue = { name, value };
- requestHeaders.put(name.toLowerCase(), mapValue);
- }
-
- /**
- * Returns the value associated with the given request header.
- * @param name The name of the request header, non-null, case-insensitive.
- * @return The value associated with the request header, or null if
- * not set, or error.
- */
- public synchronized String getRequestHeader(String name) {
- String[] value = requestHeaders.get(name.toLowerCase());
- if (value != null) {
- return value[HEADERS_MAP_INDEX_VALUE];
- } else {
- return null;
- }
- }
-
- /**
- * Returns the value associated with the given response header.
- * @param name The name of the response header, non-null, case-insensitive.
- * @return The value associated with the response header, or null if
- * not set or error.
- */
- public synchronized String getResponseHeader(String name) {
- if (responseHeaders != null) {
- String[] value = responseHeaders.get(name.toLowerCase());
- if (value != null) {
- return value[HEADERS_MAP_INDEX_VALUE];
- } else {
- return null;
- }
- } else {
- log("getResponseHeader() called but response not received");
- return null;
- }
- }
-
- /**
- * Set a response header and associated value. The key is associated
- * case-insensitively, but stored case-sensitively.
- * @param name Case sensitive request header key.
- * @param value The associated value.
- */
- private void setResponseHeader(String name, String value) {
- if (logEnabled)
- log("Set response header " + name + ": " + value);
- String mapValue[] = { name, value };
- responseHeaders.put(name.toLowerCase(), mapValue);
- }
-
- /**
- * Apply the contents of the Map requestHeaders to the connection
- * object. Calls to setRequestHeader() after this will not affect
- * the connection.
- */
- private synchronized void applyRequestHeadersToConnection() {
- Iterator<String[]> it = requestHeaders.values().iterator();
- while (it.hasNext()) {
- // Set the key case-sensitive.
- String[] entry = it.next();
- connection.setRequestProperty(
- entry[HEADERS_MAP_INDEX_KEY],
- entry[HEADERS_MAP_INDEX_VALUE]);
- }
- }
-
- /**
- * Return all response headers, separated by CR-LF line endings, and
- * ending with a trailing blank line. This mimics the format of the
- * raw response header up to but not including the body.
- * @return A string containing the entire response header.
- */
- public synchronized String getAllResponseHeaders() {
- if (responseHeaders == null) {
- log("getAllResponseHeaders() called but response not received");
- return null;
- }
- String result = new String();
- Iterator<String[]> it = responseHeaders.values().iterator();
- while (it.hasNext()) {
- String[] entry = it.next();
- // Output the "key: value" lines.
- result += entry[HEADERS_MAP_INDEX_KEY] + ": "
- + entry[HEADERS_MAP_INDEX_VALUE] + HTTP_LINE_ENDING;
- }
- result += HTTP_LINE_ENDING;
- return result;
- }
-
- /**
- * Get the complete response line of the HTTP request. Only valid on
- * completion of the transaction.
- * @return The complete HTTP response line, e.g "HTTP/1.0 200 OK".
- */
- public synchronized String getResponseLine() {
- return responseLine;
- }
-
- /**
- * Get the cookie for the given URL.
- * @param url The fully qualified URL.
- * @return A string containing the cookie for the URL if it exists,
- * or null if not.
- */
- public static String getCookieForUrl(String url) {
- // Get the cookie for this URL, set as a header
- return CookieManager.getInstance().getCookie(url);
- }
-
- /**
- * Set the cookie for the given URL.
- * @param url The fully qualified URL.
- * @param cookie The new cookie value.
- * @return A string containing the cookie for the URL if it exists,
- * or null if not.
- */
- public static void setCookieForUrl(String url, String cookie) {
- // Get the cookie for this URL, set as a header
- CookieManager.getInstance().setCookie(url, cookie);
- }
-
- /**
- * Perform a request using LocalServer if possible. Initializes
- * class members so that receive() will obtain data from the stream
- * provided by the response.
- * @param url The fully qualified URL to try in LocalServer.
- * @return True if the url was found and is now setup to receive.
- * False if not found, with no side-effect.
- */
- public synchronized boolean useLocalServerResult(String url) {
- UrlInterceptHandlerGears handler = UrlInterceptHandlerGears.getInstance();
- if (handler == null) {
- return false;
- }
- UrlInterceptHandlerGears.ServiceResponse serviceResponse =
- handler.getServiceResponse(url, requestHeaders);
- if (serviceResponse == null) {
- log("No response in LocalServer");
- return false;
- }
- // LocalServer will handle this URL. Initialize stream and
- // response.
- inputStream = serviceResponse.getInputStream();
- responseLine = serviceResponse.getStatusLine();
- responseHeaders = serviceResponse.getResponseHeaders();
- if (logEnabled)
- log("Got response from LocalServer: " + responseLine);
- return true;
- }
-
- /**
- * Perform a request using the cache result if present. Initializes
- * class members so that receive() will obtain data from the cache.
- * @param url The fully qualified URL to try in the cache.
- * @return True is the url was found and is now setup to receive
- * from cache. False if not found, with no side-effect.
- */
- public synchronized boolean useCacheResult(String url) {
- // Try the browser's cache. CacheManager wants a Map<String, String>.
- Map<String, String> cacheRequestHeaders = new HashMap<String, String>();
- Iterator<Map.Entry<String, String[]>> it =
- requestHeaders.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry<String, String[]> entry = it.next();
- cacheRequestHeaders.put(
- entry.getKey(),
- entry.getValue()[HEADERS_MAP_INDEX_VALUE]);
- }
- CacheResult cacheResult =
- CacheManager.getCacheFile(url, cacheRequestHeaders);
- if (cacheResult == null) {
- if (logEnabled)
- log("No CacheResult for " + url);
- return false;
- }
- if (logEnabled)
- log("Got CacheResult from browser cache");
- // Check for expiry. -1 is "never", otherwise milliseconds since 1970.
- // Can be compared to System.currentTimeMillis().
- long expires = cacheResult.getExpires();
- if (expires >= 0 && System.currentTimeMillis() >= expires) {
- log("CacheResult expired "
- + (System.currentTimeMillis() - expires)
- + " milliseconds ago");
- // Cache hit has expired. Do not return it.
- return false;
- }
- // Setup the inputStream to come from the cache.
- inputStream = cacheResult.getInputStream();
- if (inputStream == null) {
- // Cache result may have gone away.
- log("No inputStream for CacheResult " + url);
- return false;
- }
- // Cache hit. Parse headers.
- synthesizeHeadersFromCacheResult(cacheResult);
- return true;
- }
-
- /**
- * Take the limited set of headers in a CacheResult and synthesize
- * response headers.
- * @param cacheResult A CacheResult to populate responseHeaders with.
- */
- private void synthesizeHeadersFromCacheResult(CacheResult cacheResult) {
- int statusCode = cacheResult.getHttpStatusCode();
- // The status message is informal, so we can greatly simplify it.
- String statusMessage;
- if (statusCode >= 200 && statusCode < 300) {
- statusMessage = "OK";
- } else if (statusCode >= 300 && statusCode < 400) {
- statusMessage = "MOVED";
- } else {
- statusMessage = "UNAVAILABLE";
- }
- // Synthesize the response line.
- responseLine = "HTTP/1.1 " + statusCode + " " + statusMessage;
- if (logEnabled)
- log("Synthesized " + responseLine);
- // Synthesize the returned headers from cache.
- responseHeaders = new HashMap<String, String[]>();
- String contentLength = Long.toString(cacheResult.getContentLength());
- setResponseHeader(KEY_CONTENT_LENGTH, contentLength);
- long expires = cacheResult.getExpires();
- if (expires >= 0) {
- // "Expires" header is valid and finite. Milliseconds since 1970
- // epoch, formatted as RFC-1123.
- String expiresString = DateUtils.formatDate(new Date(expires));
- setResponseHeader(KEY_EXPIRES, expiresString);
- }
- String lastModified = cacheResult.getLastModified();
- if (lastModified != null) {
- // Last modification time of the page. Passed end-to-end, but
- // not used by us.
- setResponseHeader(KEY_LAST_MODIFIED, lastModified);
- }
- String eTag = cacheResult.getETag();
- if (eTag != null) {
- // Entity tag. A kind of GUID to identify identical resources.
- setResponseHeader(KEY_ETAG, eTag);
- }
- String location = cacheResult.getLocation();
- if (location != null) {
- // If valid, refers to the location of a redirect.
- setResponseHeader(KEY_LOCATION, location);
- }
- String mimeType = cacheResult.getMimeType();
- if (mimeType == null) {
- // Use a safe default MIME type when none is
- // specified. "text/plain" is safe to render in the browser
- // window (even if large) and won't be intepreted as anything
- // that would cause execution.
- mimeType = DEFAULT_MIME_TYPE;
- }
- String encoding = cacheResult.getEncoding();
- // Encoding may not be specified. No default.
- String contentType = mimeType;
- if (encoding != null && encoding.length() > 0) {
- contentType += "; charset=" + encoding;
- }
- setResponseHeader(KEY_CONTENT_TYPE, contentType);
- }
-
- /**
- * Create a CacheResult for this URL. This enables the repsonse body
- * to be sent in calls to appendCacheResult().
- * @param url The fully qualified URL to add to the cache.
- * @param responseCode The response code returned for the request, e.g 200.
- * @param mimeType The MIME type of the body, e.g "text/plain".
- * @param encoding The encoding, e.g "utf-8". Use "" for unknown.
- */
- public synchronized boolean createCacheResult(
- String url, int responseCode, String mimeType, String encoding) {
- if (logEnabled)
- log("Making cache entry for " + url);
- // Take the headers and parse them into a format needed by
- // CacheManager.
- Headers cacheHeaders = new Headers();
- Iterator<Map.Entry<String, String[]>> it =
- responseHeaders.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry<String, String[]> entry = it.next();
- // Headers.parseHeader() expects lowercase keys.
- String keyValue = entry.getKey() + ": "
- + entry.getValue()[HEADERS_MAP_INDEX_VALUE];
- CharArrayBuffer buffer = new CharArrayBuffer(keyValue.length());
- buffer.append(keyValue);
- // Parse it into the header container.
- cacheHeaders.parseHeader(buffer);
- }
- cacheResult = CacheManager.createCacheFile(
- url, responseCode, cacheHeaders, mimeType, true);
- if (cacheResult != null) {
- if (logEnabled)
- log("Saving into cache");
- cacheResult.setEncoding(encoding);
- cacheResultUrl = url;
- return true;
- } else {
- log("Couldn't create cacheResult");
- return false;
- }
- }
-
- /**
- * Add data from the response body to the CacheResult created with
- * createCacheResult().
- * @param data A byte array of the next sequential bytes in the
- * response body.
- * @param bytes The number of bytes to write from the start of
- * the array.
- * @return True if all bytes successfully written, false on failure.
- */
- public synchronized boolean appendCacheResult(byte[] data, int bytes) {
- if (cacheResult == null) {
- log("appendCacheResult() called without a CacheResult initialized");
- return false;
- }
- try {
- cacheResult.getOutputStream().write(data, 0, bytes);
- } catch (IOException ex) {
- log("Got IOException writing cache data: " + ex);
- return false;
- }
- return true;
- }
-
- /**
- * Save the completed CacheResult into the CacheManager. This must
- * have been created first with createCacheResult().
- * @return Returns true if the entry has been successfully saved.
- */
- public synchronized boolean saveCacheResult() {
- if (cacheResult == null || cacheResultUrl == null) {
- log("Tried to save cache result but createCacheResult not called");
- return false;
- }
- if (logEnabled)
- log("Saving cache result");
- CacheManager.saveCacheFile(cacheResultUrl, cacheResult);
- cacheResult = null;
- cacheResultUrl = null;
- return true;
- }
-
- /**
- * Perform an HTTP request on the network. The underlying
- * HttpURLConnection is connected to the remote server and the
- * response headers are received.
- * @return True if the connection succeeded and headers have been
- * received. False on connection failure.
- */
- public boolean connectToRemote() {
- synchronized (this) {
- // Transfer a snapshot of our internally maintained map of request
- // headers to the connection object.
- applyRequestHeadersToConnection();
- // Note blocking I/O so abort() can interrupt us.
- inBlockingOperation = true;
- }
- boolean success;
- try {
- if (logEnabled)
- log("Connecting to remote");
- connection.connect();
- if (logEnabled)
- log("Connected");
- success = true;
- } catch (IOException e) {
- log("Got IOException in connect(): " + e.toString());
- success = false;
- } finally {
- synchronized (this) {
- // No longer blocking.
- inBlockingOperation = false;
- }
- }
- return success;
- }
-
- /**
- * Receive all headers from the server and populate
- * responseHeaders. This converts from the slightly odd format
- * returned by java.net.HttpURLConnection to a simpler
- * java.util.Map.
- * @return True if headers are successfully received, False on
- * connection error.
- */
- public synchronized boolean parseHeaders() {
- responseHeaders = new HashMap<String, String[]>();
- /* HttpURLConnection contains a null terminated list of
- * key->value response pairs. If the key is null, then the value
- * contains the complete status line. If both key and value are
- * null for an index, we've reached the end.
- */
- for (int i = 0; ; ++i) {
- String key = connection.getHeaderFieldKey(i);
- String value = connection.getHeaderField(i);
- if (logEnabled)
- log("header " + key + " -> " + value);
- if (key == null && value == null) {
- // End of list.
- break;
- } else if (key == null) {
- // The pair with null key has the complete status line in
- // the value, e.g "HTTP/1.0 200 OK".
- responseLine = value;
- } else if (value != null) {
- // If key and value are non-null, this is a response pair, e.g
- // "Content-Length" -> "5". Use setResponseHeader() to
- // correctly deal with case-insensitivity of the key.
- setResponseHeader(key, value);
- } else {
- // The key is non-null but value is null. Unexpected
- // condition.
- return false;
- }
- }
- return true;
- }
-
- /**
- * Receive the next sequential bytes of the response body after
- * successful connection. This will receive up to the size of the
- * provided byte array. If there is no body, this will return 0
- * bytes on the first call after connection.
- * @param buf A pre-allocated byte array to receive data into.
- * @return The number of bytes from the start of the array which
- * have been filled, 0 on EOF, or negative on error.
- */
- public int receive(byte[] buf) {
- if (inputStream == null) {
- // If this is the first call, setup the InputStream. This may
- // fail if there were headers, but no body returned by the
- // server.
- try {
- inputStream = connection.getInputStream();
- } catch (IOException inputException) {
- log("Failed to connect InputStream: " + inputException);
- // Not unexpected. For example, 404 response return headers,
- // and sometimes a body with a detailed error. Try the error
- // stream.
- inputStream = connection.getErrorStream();
- if (inputStream == null) {
- // No error stream either. Treat as a 0 byte response.
- log("No InputStream");
- return 0; // EOF.
- }
- }
- }
- synchronized (this) {
- // Note blocking I/O so abort() can interrupt us.
- inBlockingOperation = true;
- }
- int ret;
- try {
- int got = inputStream.read(buf);
- if (got > 0) {
- // Got some bytes, not EOF.
- ret = got;
- } else {
- // EOF.
- inputStream.close();
- ret = 0;
- }
- } catch (IOException e) {
- // An abort() interrupts us by calling close() on our stream.
- log("Got IOException in inputStream.read(): " + e.toString());
- ret = -1;
- } finally {
- synchronized (this) {
- // No longer blocking.
- inBlockingOperation = false;
- }
- }
- return ret;
- }
-
- /**
- * For POST method requests, send a stream of data provided by the
- * native side in repeated callbacks.
- * @param data A byte array containing the data to sent, or null
- * if indicating EOF.
- * @param bytes The number of bytes from the start of the array to
- * send, or 0 if indicating EOF.
- * @return True if all bytes were successfully sent, false on error.
- */
- public boolean sendPostData(byte[] data, int bytes) {
- synchronized (this) {
- // Note blocking I/O so abort() can interrupt us.
- inBlockingOperation = true;
- }
- boolean success;
- try {
- OutputStream outputStream = connection.getOutputStream();
- if (data == null && bytes == 0) {
- outputStream.close();
- } else {
- outputStream.write(data, 0, bytes);
- }
- success = true;
- } catch (IOException e) {
- log("Got IOException in post: " + e.toString());
- success = false;
- } finally {
- synchronized (this) {
- // No longer blocking.
- inBlockingOperation = false;
- }
- }
- return success;
- }
-}
diff --git a/core/java/android/webkit/gears/UrlInterceptHandlerGears.java b/core/java/android/webkit/gears/UrlInterceptHandlerGears.java
index 288240e..2a5cbe9 100644
--- a/core/java/android/webkit/gears/UrlInterceptHandlerGears.java
+++ b/core/java/android/webkit/gears/UrlInterceptHandlerGears.java
@@ -64,11 +64,11 @@ public class UrlInterceptHandlerGears implements UrlInterceptHandler {
/** The unmodified (case-sensitive) key in the headers map is the
* same index as used by HttpRequestAndroid. */
public static final int HEADERS_MAP_INDEX_KEY =
- HttpRequestAndroid.HEADERS_MAP_INDEX_KEY;
+ ApacheHttpRequestAndroid.HEADERS_MAP_INDEX_KEY;
/** The associated value in the headers map is the same index as
* used by HttpRequestAndroid. */
public static final int HEADERS_MAP_INDEX_VALUE =
- HttpRequestAndroid.HEADERS_MAP_INDEX_VALUE;
+ ApacheHttpRequestAndroid.HEADERS_MAP_INDEX_VALUE;
/**
* Object passed to the native side, containing information about
@@ -382,7 +382,7 @@ public class UrlInterceptHandlerGears implements UrlInterceptHandler {
// browser's cache for too long.
long now_ms = System.currentTimeMillis();
String expires = DateUtils.formatDate(new Date(now_ms + CACHE_EXPIRY_MS));
- response.setResponseHeader(HttpRequestAndroid.KEY_EXPIRES, expires);
+ response.setResponseHeader(ApacheHttpRequestAndroid.KEY_EXPIRES, expires);
// The browser is only interested in a small subset of headers,
// contained in a Headers object. Iterate the map of all headers
// and add them to Headers.
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index c012e25..f362e22 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -41,7 +41,7 @@ import android.view.ViewConfiguration;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
-import android.view.WindowManagerImpl;
+import android.view.inputmethod.InputMethodManager;
import android.view.ContextMenu.ContextMenuInfo;
import com.android.internal.R;
@@ -425,6 +425,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private int mTouchSlop;
+ private float mDensityScale;
+
/**
* Interface definition for a callback to be invoked when the list or grid
* has been scrolled.
@@ -567,7 +569,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
*/
@Override
protected boolean isVerticalScrollBarHidden() {
- return mFastScroller != null ? mFastScroller.isVisible() : false;
+ return mFastScroller != null && mFastScroller.isVisible();
}
/**
@@ -709,6 +711,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
setScrollingCacheEnabled(true);
mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
+ mDensityScale = getContext().getResources().getDisplayMetrics().density;
}
private void useDefaultSelector() {
@@ -891,14 +894,26 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
// Don't restore the type filter window when there is no keyboard
- int keyboardHidden = getContext().getResources().getConfiguration().keyboardHidden;
- if (keyboardHidden != Configuration.KEYBOARDHIDDEN_YES) {
+ if (acceptFilter()) {
String filterText = ss.filter;
setFilterText(filterText);
}
+
requestLayout();
}
+ private boolean acceptFilter() {
+ final Context context = mContext;
+ final Configuration configuration = context.getResources().getConfiguration();
+ final boolean keyboardShowing = configuration.keyboardHidden !=
+ Configuration.KEYBOARDHIDDEN_YES;
+ final boolean hasKeyboard = configuration.keyboard != Configuration.KEYBOARD_NOKEYS;
+ final InputMethodManager inputManager = (InputMethodManager)
+ context.getSystemService(Context.INPUT_METHOD_SERVICE);
+ return (hasKeyboard && keyboardShowing) ||
+ (!hasKeyboard && !inputManager.isFullscreenMode());
+ }
+
/**
* Sets the initial value for the text filter.
* @param filterText The text to use for the filter.
@@ -906,6 +921,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* @see #setTextFilterEnabled
*/
public void setFilterText(String filterText) {
+ // TODO: Should we check for acceptFilter()?
if (mTextFilterEnabled && filterText != null && filterText.length() > 0) {
createTextFilter(false);
// This is going to call our listener onTextChanged, but we might not
@@ -1076,6 +1092,24 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mInLayout = false;
}
+ /**
+ * @hide
+ */
+ @Override
+ protected boolean setFrame(int left, int top, int right, int bottom) {
+ final boolean changed = super.setFrame(left, top, right, bottom);
+
+ // Reposition the popup when the frame has changed. This includes
+ // translating the widget, not just changing its dimension. The
+ // filter popup needs to follow the widget.
+ if (mFiltered && changed && getWindowVisibility() == View.VISIBLE && mPopup != null &&
+ mPopup.isShowing()) {
+ positionPopup(true);
+ }
+
+ return changed;
+ }
+
protected void layoutChildren() {
}
@@ -2587,10 +2621,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
clearScrollingCache();
mSpecificTop = selectedTop;
selectedPos = lookForSelectablePosition(selectedPos, down);
- if (selectedPos >= 0) {
+ if (selectedPos >= firstPosition && selectedPos <= getLastVisiblePosition()) {
mLayoutMode = LAYOUT_SPECIFIC;
setSelectionInt(selectedPos);
invokeOnItemScrollListener();
+ } else {
+ selectedPos = INVALID_POSITION;
}
reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
@@ -2727,19 +2763,27 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private void showPopup() {
// Make sure we have a window before showing the popup
if (getWindowVisibility() == View.VISIBLE) {
- int screenHeight = WindowManagerImpl.getDefault().getDefaultDisplay().getHeight();
- final int[] xy = new int[2];
- getLocationOnScreen(xy);
- // TODO: The 20 below should come from the theme and be expressed in dip
- final float scale = getContext().getResources().getDisplayMetrics().density;
- int bottomGap = screenHeight - xy[1] - getHeight() + (int) (scale * 20);
- mPopup.showAtLocation(this, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL,
- xy[0], bottomGap);
+ positionPopup(false);
// Make sure we get focus if we are showing the popup
checkFocus();
}
}
+ private void positionPopup(boolean update) {
+ int screenHeight = getResources().getDisplayMetrics().heightPixels;
+ final int[] xy = new int[2];
+ getLocationOnScreen(xy);
+ // TODO: The 20 below should come from the theme and be expressed in dip
+ // TODO: And the gravity should be defined in the theme as well
+ final int bottomGap = screenHeight - xy[1] - getHeight() + (int) (mDensityScale * 20);
+ if (!update) {
+ mPopup.showAtLocation(this, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL,
+ xy[0], bottomGap);
+ } else {
+ mPopup.update(xy[0], bottomGap, -1, -1);
+ }
+ }
+
/**
* What is the distance between the source and destination rectangles given the direction of
* focus navigation between them? The direction basically helps figure out more quickly what is
@@ -2831,7 +2875,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
break;
}
- if (okToSend) {
+ if (okToSend && acceptFilter()) {
createTextFilter(true);
KeyEvent forwardEvent = event;
@@ -2873,6 +2917,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mTextFilter.addTextChangedListener(this);
p.setFocusable(false);
p.setTouchable(false);
+ p.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
p.setContentView(mTextFilter);
p.setWidth(LayoutParams.WRAP_CONTENT);
p.setHeight(LayoutParams.WRAP_CONTENT);
diff --git a/core/java/android/widget/Chronometer.java b/core/java/android/widget/Chronometer.java
index 7086ae2..369221e 100644
--- a/core/java/android/widget/Chronometer.java
+++ b/core/java/android/widget/Chronometer.java
@@ -46,6 +46,18 @@ import java.util.Locale;
public class Chronometer extends TextView {
private static final String TAG = "Chronometer";
+ /**
+ * A callback that notifies when the chronometer has incremented on its own.
+ */
+ public interface OnChronometerTickListener {
+
+ /**
+ * Notification that the chronometer has changed.
+ */
+ void onChronometerTick(Chronometer chronometer);
+
+ }
+
private long mBase;
private boolean mVisible;
private boolean mStarted;
@@ -56,6 +68,7 @@ public class Chronometer extends TextView {
private Locale mFormatterLocale;
private Object[] mFormatterArgs = new Object[1];
private StringBuilder mFormatBuilder;
+ private OnChronometerTickListener mOnChronometerTickListener;
/**
* Initialize this Chronometer object.
@@ -99,6 +112,7 @@ public class Chronometer extends TextView {
*
* @param base Use the {@link SystemClock#elapsedRealtime} time base.
*/
+ @android.view.RemotableViewMethod
public void setBase(long base) {
mBase = base;
updateText(SystemClock.elapsedRealtime());
@@ -122,6 +136,7 @@ public class Chronometer extends TextView {
*
* @param format the format string.
*/
+ @android.view.RemotableViewMethod
public void setFormat(String format) {
mFormat = format;
if (format != null && mFormatBuilder == null) {
@@ -137,6 +152,23 @@ public class Chronometer extends TextView {
}
/**
+ * Sets the listener to be called when the chronometer changes.
+ *
+ * @param listener The listener.
+ */
+ public void setOnChronometerTickListener(OnChronometerTickListener listener) {
+ mOnChronometerTickListener = listener;
+ }
+
+ /**
+ * @return The listener (may be null) that is listening for chronometer change
+ * events.
+ */
+ public OnChronometerTickListener getOnChronometerTickListener() {
+ return mOnChronometerTickListener;
+ }
+
+ /**
* Start counting up. This does not affect the base as set from {@link #setBase}, just
* the view display.
*
@@ -161,6 +193,15 @@ public class Chronometer extends TextView {
updateRunning();
}
+ /**
+ * The same as calling {@link #start} or {@link #stop}.
+ */
+ @android.view.RemotableViewMethod
+ public void setStarted(boolean started) {
+ mStarted = started;
+ updateRunning();
+ }
+
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
@@ -216,8 +257,15 @@ public class Chronometer extends TextView {
public void handleMessage(Message m) {
if (mStarted) {
updateText(SystemClock.elapsedRealtime());
+ dispatchChronometerTick();
sendMessageDelayed(Message.obtain(), 1000);
}
}
};
+
+ void dispatchChronometerTick() {
+ if (mOnChronometerTickListener != null) {
+ mOnChronometerTickListener.onChronometerTick(this);
+ }
+ }
}
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index b4ed3ba..8aafee2 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -93,6 +93,7 @@ public class FrameLayout extends ViewGroup {
*
* @attr ref android.R.styleable#FrameLayout_foregroundGravity
*/
+ @android.view.RemotableViewMethod
public void setForegroundGravity(int foregroundGravity) {
if (mForegroundGravity != foregroundGravity) {
if ((foregroundGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) {
@@ -348,6 +349,7 @@ public class FrameLayout extends ViewGroup {
*
* @attr ref android.R.styleable#FrameLayout_measureAllChildren
*/
+ @android.view.RemotableViewMethod
public void setMeasureAllChildren(boolean measureAll) {
mMeasureAllChildren = measureAll;
}
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 4ae322e..94d1bd1 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -193,6 +193,7 @@ public class ImageView extends View {
*
* @attr ref android.R.styleable#ImageView_adjustViewBounds
*/
+ @android.view.RemotableViewMethod
public void setAdjustViewBounds(boolean adjustViewBounds) {
mAdjustViewBounds = adjustViewBounds;
if (adjustViewBounds) {
@@ -217,6 +218,7 @@ public class ImageView extends View {
*
* @attr ref android.R.styleable#ImageView_maxWidth
*/
+ @android.view.RemotableViewMethod
public void setMaxWidth(int maxWidth) {
mMaxWidth = maxWidth;
}
@@ -238,6 +240,7 @@ public class ImageView extends View {
*
* @attr ref android.R.styleable#ImageView_maxHeight
*/
+ @android.view.RemotableViewMethod
public void setMaxHeight(int maxHeight) {
mMaxHeight = maxHeight;
}
@@ -256,6 +259,7 @@ public class ImageView extends View {
*
* @attr ref android.R.styleable#ImageView_src
*/
+ @android.view.RemotableViewMethod
public void setImageResource(int resId) {
if (mUri != null || mResource != resId) {
updateDrawable(null);
@@ -272,6 +276,7 @@ public class ImageView extends View {
*
* @param uri The Uri of an image
*/
+ @android.view.RemotableViewMethod
public void setImageURI(Uri uri) {
if (mResource != 0 ||
(mUri != uri &&
@@ -306,6 +311,7 @@ public class ImageView extends View {
*
* @param bm The bitmap to set
*/
+ @android.view.RemotableViewMethod
public void setImageBitmap(Bitmap bm) {
// if this is used frequently, may handle bitmaps explicitly
// to reduce the intermediate drawable object
@@ -327,6 +333,7 @@ public class ImageView extends View {
resizeFromDrawable();
}
+ @android.view.RemotableViewMethod
public void setImageLevel(int level) {
mLevel = level;
if (mDrawable != null) {
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 85a7339..a9822f8 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -136,6 +136,7 @@ public class LinearLayout extends ViewGroup {
*
* @attr ref android.R.styleable#LinearLayout_baselineAligned
*/
+ @android.view.RemotableViewMethod
public void setBaselineAligned(boolean baselineAligned) {
mBaselineAligned = baselineAligned;
}
@@ -208,6 +209,7 @@ public class LinearLayout extends ViewGroup {
*
* @attr ref android.R.styleable#LinearLayout_baselineAlignedChildIndex
*/
+ @android.view.RemotableViewMethod
public void setBaselineAlignedChildIndex(int i) {
if ((i < 0) || (i >= getChildCount())) {
throw new IllegalArgumentException("base aligned child index out "
@@ -265,6 +267,7 @@ public class LinearLayout extends ViewGroup {
* to 0.0f if the weight sum should be computed from the children's
* layout_weight
*/
+ @android.view.RemotableViewMethod
public void setWeightSum(float weightSum) {
mWeightSum = Math.max(0.0f, weightSum);
}
@@ -1149,6 +1152,7 @@ public class LinearLayout extends ViewGroup {
*
* @attr ref android.R.styleable#LinearLayout_gravity
*/
+ @android.view.RemotableViewMethod
public void setGravity(int gravity) {
if (mGravity != gravity) {
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) {
@@ -1164,6 +1168,7 @@ public class LinearLayout extends ViewGroup {
}
}
+ @android.view.RemotableViewMethod
public void setHorizontalGravity(int horizontalGravity) {
final int gravity = horizontalGravity & Gravity.HORIZONTAL_GRAVITY_MASK;
if ((mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != gravity) {
@@ -1172,6 +1177,7 @@ public class LinearLayout extends ViewGroup {
}
}
+ @android.view.RemotableViewMethod
public void setVerticalGravity(int verticalGravity) {
final int gravity = verticalGravity & Gravity.VERTICAL_GRAVITY_MASK;
if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != gravity) {
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 9c7f600..4e5989c 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -2179,6 +2179,10 @@ public class ListView extends AbsListView {
&& !isViewAncestorOf(selectedView, this)) {
selectedView = null;
hideSelector();
+
+ // but we don't want to set the ressurect position (that would make subsequent
+ // unhandled key events bring back the item we just scrolled off!)
+ mResurrectToPosition = INVALID_POSITION;
}
if (needToRedraw) {
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index dada105..4a5cea1 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -24,6 +24,8 @@ import android.view.View;
import android.view.WindowManager;
import android.view.Gravity;
import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnScrollChangedListener;
import android.view.View.OnTouchListener;
import android.graphics.PixelFormat;
import android.graphics.Rect;
@@ -33,6 +35,8 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
+import java.lang.ref.WeakReference;
+
/**
* <p>A popup window that can be used to display an arbitrary view. The popup
* windows is a floating container that appears on top of the current
@@ -109,7 +113,23 @@ public class PopupWindow {
private static final int[] ABOVE_ANCHOR_STATE_SET = new int[] {
com.android.internal.R.attr.state_above_anchor
};
-
+
+ private WeakReference<View> mAnchor;
+ private OnScrollChangedListener mOnScrollChangedListener =
+ new OnScrollChangedListener() {
+ public void onScrollChanged() {
+ View anchor = mAnchor.get();
+ if (anchor != null && mPopupView != null) {
+ WindowManager.LayoutParams p = (WindowManager.LayoutParams)
+ mPopupView.getLayoutParams();
+
+ mAboveAnchor = findDropDownPosition(anchor, p, mAnchorXoff, mAnchorYoff);
+ update(p.x, p.y, -1, -1, true);
+ }
+ }
+ };
+ private int mAnchorXoff, mAnchorYoff;
+
/**
* <p>Create a new empty, non focusable popup window of dimension (0,0).</p>
*
@@ -579,6 +599,8 @@ public class PopupWindow {
return;
}
+ unregisterForScrollChanged();
+
mIsShowing = true;
mIsDropdown = false;
@@ -617,6 +639,8 @@ public class PopupWindow {
* the popup in its entirety, this method tries to find a parent scroll
* view to scroll. If no parent scroll view can be scrolled, the bottom-left
* corner of the popup is pinned at the top left corner of the anchor view.</p>
+ * <p>If the view later scrolls to move <code>anchor</code> to a different
+ * location, the popup will be moved correspondingly.</p>
*
* @param anchor the view on which to pin the popup window
*
@@ -627,6 +651,8 @@ public class PopupWindow {
return;
}
+ registerForScrollChanged(anchor, xoff, yoff);
+
mIsShowing = true;
mIsDropdown = true;
@@ -894,6 +920,8 @@ public class PopupWindow {
*/
public void dismiss() {
if (isShowing() && mPopupView != null) {
+ unregisterForScrollChanged();
+
mWindowManager.removeView(mPopupView);
if (mPopupView != mContentView && mPopupView instanceof ViewGroup) {
((ViewGroup) mPopupView).removeView(mContentView);
@@ -962,6 +990,25 @@ public class PopupWindow {
* @param height the new height, can be -1 to ignore
*/
public void update(int x, int y, int width, int height) {
+ update(x, y, width, height, false);
+ }
+
+ /**
+ * <p>Updates the position and the dimension of the popup window. Width and
+ * height can be set to -1 to update location only. Calling this function
+ * also updates the window with the current popup state as
+ * described for {@link #update()}.</p>
+ *
+ * @param x the new x location
+ * @param y the new y location
+ * @param width the new width, can be -1 to ignore
+ * @param height the new height, can be -1 to ignore
+ * @param force reposition the window even if the specified position
+ * already seems to correspond to the LayoutParams
+ *
+ * @hide pending API council approval
+ */
+ public void update(int x, int y, int width, int height, boolean force) {
if (width != -1) {
mLastWidth = width;
setWidth(width);
@@ -979,7 +1026,7 @@ public class PopupWindow {
WindowManager.LayoutParams p = (WindowManager.LayoutParams)
mPopupView.getLayoutParams();
- boolean update = false;
+ boolean update = force;
final int finalWidth = mWidthMode < 0 ? mWidthMode : mLastWidth;
if (width != -1 && p.width != finalWidth) {
@@ -1039,6 +1086,8 @@ public class PopupWindow {
* height can be set to -1 to update location only. Calling this function
* also updates the window with the current popup state as
* described for {@link #update()}.</p>
+ * <p>If the view later scrolls to move <code>anchor</code> to a different
+ * location, the popup will be moved correspondingly.</p>
*
* @param anchor the popup's anchor view
* @param xoff x offset from the view's left edge
@@ -1051,6 +1100,12 @@ public class PopupWindow {
return;
}
+ WeakReference<View> oldAnchor = mAnchor;
+ if (oldAnchor == null || oldAnchor.get() != anchor ||
+ mAnchorXoff != xoff || mAnchorYoff != yoff) {
+ registerForScrollChanged(anchor, xoff, yoff);
+ }
+
WindowManager.LayoutParams p = (WindowManager.LayoutParams)
mPopupView.getLayoutParams();
@@ -1065,10 +1120,10 @@ public class PopupWindow {
mPopupHeight = height;
}
- findDropDownPosition(anchor, p, xoff, yoff);
+ mAboveAnchor = findDropDownPosition(anchor, p, xoff, yoff);
update(p.x, p.y, width, height);
}
-
+
/**
* Listener that is called when this popup window is dismissed.
*/
@@ -1078,7 +1133,33 @@ public class PopupWindow {
*/
public void onDismiss();
}
-
+
+ private void unregisterForScrollChanged() {
+ WeakReference<View> anchorRef = mAnchor;
+ View anchor = null;
+ if (anchorRef != null) {
+ anchor = anchorRef.get();
+ }
+ if (anchor != null) {
+ ViewTreeObserver vto = anchor.getViewTreeObserver();
+ vto.removeOnScrollChangedListener(mOnScrollChangedListener);
+ }
+ mAnchor = null;
+ }
+
+ private void registerForScrollChanged(View anchor, int xoff, int yoff) {
+ unregisterForScrollChanged();
+
+ mAnchor = new WeakReference<View>(anchor);
+ ViewTreeObserver vto = anchor.getViewTreeObserver();
+ if (vto != null) {
+ vto.addOnScrollChangedListener(mOnScrollChangedListener);
+ }
+
+ mAnchorXoff = xoff;
+ mAnchorYoff = yoff;
+ }
+
private class PopupViewContainer extends FrameLayout {
public PopupViewContainer(Context context) {
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 434e9f3..dd2570a 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -344,6 +344,7 @@ public class ProgressBar extends View {
*
* @param indeterminate true to enable the indeterminate mode
*/
+ @android.view.RemotableViewMethod
public synchronized void setIndeterminate(boolean indeterminate) {
if ((!mOnlyIndeterminate || !mIndeterminate) && indeterminate != mIndeterminate) {
mIndeterminate = indeterminate;
@@ -529,6 +530,7 @@ public class ProgressBar extends View {
setProgress(progress, false);
}
+ @android.view.RemotableViewMethod
synchronized void setProgress(int progress, boolean fromUser) {
if (mIndeterminate) {
return;
@@ -560,6 +562,7 @@ public class ProgressBar extends View {
* @see #getSecondaryProgress()
* @see #incrementSecondaryProgressBy(int)
*/
+ @android.view.RemotableViewMethod
public synchronized void setSecondaryProgress(int secondaryProgress) {
if (mIndeterminate) {
return;
@@ -633,6 +636,7 @@ public class ProgressBar extends View {
* @see #setProgress(int)
* @see #setSecondaryProgress(int)
*/
+ @android.view.RemotableViewMethod
public synchronized void setMax(int max) {
if (max < 0) {
max = 0;
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 9ded52b..ba63ec3 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -168,6 +168,7 @@ public class RelativeLayout extends ViewGroup {
*
* @attr ref android.R.styleable#RelativeLayout_ignoreGravity
*/
+ @android.view.RemotableViewMethod
public void setIgnoreGravity(int viewId) {
mIgnoreGravity = viewId;
}
@@ -183,6 +184,7 @@ public class RelativeLayout extends ViewGroup {
*
* @attr ref android.R.styleable#RelativeLayout_gravity
*/
+ @android.view.RemotableViewMethod
public void setGravity(int gravity) {
if (mGravity != gravity) {
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == 0) {
@@ -198,6 +200,7 @@ public class RelativeLayout extends ViewGroup {
}
}
+ @android.view.RemotableViewMethod
public void setHorizontalGravity(int horizontalGravity) {
final int gravity = horizontalGravity & Gravity.HORIZONTAL_GRAVITY_MASK;
if ((mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) != gravity) {
@@ -206,6 +209,7 @@ public class RelativeLayout extends ViewGroup {
}
}
+ @android.view.RemotableViewMethod
public void setVerticalGravity(int verticalGravity) {
final int gravity = verticalGravity & Gravity.VERTICAL_GRAVITY_MASK;
if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != gravity) {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 25afee8..e000d2e 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -31,6 +31,7 @@ import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
+import android.view.RemotableViewMethod;
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater.Filter;
@@ -38,10 +39,13 @@ import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+import java.lang.Class;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -80,19 +84,22 @@ public class RemoteViews implements Parcelable, Filter {
/**
- * This annotation indicates that a subclass of View is alllowed to be used with the
- * {@link android.widget.RemoteViews} mechanism.
+ * This annotation indicates that a subclass of View is alllowed to be used
+ * with the {@link android.widget.RemoteViews} mechanism.
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface RemoteView {
}
-
+
/**
* Exception to send when something goes wrong executing an action
*
*/
public static class ActionException extends RuntimeException {
+ public ActionException(Exception ex) {
+ super(ex);
+ }
public ActionException(String message) {
super(message);
}
@@ -110,274 +117,7 @@ public class RemoteViews implements Parcelable, Filter {
return 0;
}
};
-
- /**
- * Equivalent to calling View.setVisibility
- */
- private class SetViewVisibility extends Action {
- public SetViewVisibility(int id, int vis) {
- viewId = id;
- visibility = vis;
- }
-
- public SetViewVisibility(Parcel parcel) {
- viewId = parcel.readInt();
- visibility = parcel.readInt();
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(TAG);
- dest.writeInt(viewId);
- dest.writeInt(visibility);
- }
-
- @Override
- public void apply(View root) {
- View target = root.findViewById(viewId);
- if (target != null) {
- target.setVisibility(visibility);
- }
- }
-
- private int viewId;
- private int visibility;
- public final static int TAG = 0;
- }
-
- /**
- * Equivalent to calling TextView.setText
- */
- private class SetTextViewText extends Action {
- public SetTextViewText(int id, CharSequence t) {
- viewId = id;
- text = t;
- }
-
- public SetTextViewText(Parcel parcel) {
- viewId = parcel.readInt();
- text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(TAG);
- dest.writeInt(viewId);
- TextUtils.writeToParcel(text, dest, flags);
- }
-
- @Override
- public void apply(View root) {
- TextView target = (TextView) root.findViewById(viewId);
- if (target != null) {
- target.setText(text);
- }
- }
-
- int viewId;
- CharSequence text;
- public final static int TAG = 1;
- }
-
- /**
- * Equivalent to calling ImageView.setResource
- */
- private class SetImageViewResource extends Action {
- public SetImageViewResource(int id, int src) {
- viewId = id;
- srcId = src;
- }
-
- public SetImageViewResource(Parcel parcel) {
- viewId = parcel.readInt();
- srcId = parcel.readInt();
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(TAG);
- dest.writeInt(viewId);
- dest.writeInt(srcId);
- }
-
- @Override
- public void apply(View root) {
- ImageView target = (ImageView) root.findViewById(viewId);
- Drawable d = mContext.getResources().getDrawable(srcId);
- if (target != null) {
- target.setImageDrawable(d);
- }
- }
-
- int viewId;
- int srcId;
- public final static int TAG = 2;
- }
-
- /**
- * Equivalent to calling ImageView.setImageURI
- */
- private class SetImageViewUri extends Action {
- public SetImageViewUri(int id, Uri u) {
- viewId = id;
- uri = u;
- }
-
- public SetImageViewUri(Parcel parcel) {
- viewId = parcel.readInt();
- uri = Uri.CREATOR.createFromParcel(parcel);
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(TAG);
- dest.writeInt(viewId);
- Uri.writeToParcel(dest, uri);
- }
-
- @Override
- public void apply(View root) {
- ImageView target = (ImageView) root.findViewById(viewId);
- if (target != null) {
- target.setImageURI(uri);
- }
- }
-
- int viewId;
- Uri uri;
- public final static int TAG = 3;
- }
-
- /**
- * Equivalent to calling ImageView.setImageBitmap
- */
- private class SetImageViewBitmap extends Action {
- public SetImageViewBitmap(int id, Bitmap src) {
- viewId = id;
- bitmap = src;
- }
-
- public SetImageViewBitmap(Parcel parcel) {
- viewId = parcel.readInt();
- bitmap = Bitmap.CREATOR.createFromParcel(parcel);
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(TAG);
- dest.writeInt(viewId);
- if (bitmap != null) {
- bitmap.writeToParcel(dest, flags);
- }
- }
-
- @Override
- public void apply(View root) {
- if (bitmap != null) {
- ImageView target = (ImageView) root.findViewById(viewId);
- Drawable d = new BitmapDrawable(bitmap);
- if (target != null) {
- target.setImageDrawable(d);
- }
- }
- }
- int viewId;
- Bitmap bitmap;
- public final static int TAG = 4;
- }
-
- /**
- * Equivalent to calling Chronometer.setBase, Chronometer.setFormat,
- * and Chronometer.start/stop.
- */
- private class SetChronometer extends Action {
- public SetChronometer(int id, long base, String format, boolean running) {
- this.viewId = id;
- this.base = base;
- this.format = format;
- this.running = running;
- }
-
- public SetChronometer(Parcel parcel) {
- viewId = parcel.readInt();
- base = parcel.readLong();
- format = parcel.readString();
- running = parcel.readInt() != 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(TAG);
- dest.writeInt(viewId);
- dest.writeLong(base);
- dest.writeString(format);
- dest.writeInt(running ? 1 : 0);
- }
-
- @Override
- public void apply(View root) {
- Chronometer target = (Chronometer) root.findViewById(viewId);
- if (target != null) {
- target.setBase(base);
- target.setFormat(format);
- if (running) {
- target.start();
- } else {
- target.stop();
- }
- }
- }
-
- int viewId;
- boolean running;
- long base;
- String format;
-
- public final static int TAG = 5;
- }
-
- /**
- * Equivalent to calling ProgressBar.setMax, ProgressBar.setProgress and
- * ProgressBar.setIndeterminate
- */
- private class SetProgressBar extends Action {
- public SetProgressBar(int id, int max, int progress, boolean indeterminate) {
- this.viewId = id;
- this.progress = progress;
- this.max = max;
- this.indeterminate = indeterminate;
- }
-
- public SetProgressBar(Parcel parcel) {
- viewId = parcel.readInt();
- progress = parcel.readInt();
- max = parcel.readInt();
- indeterminate = parcel.readInt() != 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(TAG);
- dest.writeInt(viewId);
- dest.writeInt(progress);
- dest.writeInt(max);
- dest.writeInt(indeterminate ? 1 : 0);
- }
-
- @Override
- public void apply(View root) {
- ProgressBar target = (ProgressBar) root.findViewById(viewId);
- if (target != null) {
- target.setIndeterminate(indeterminate);
- if (!indeterminate) {
- target.setMax(max);
- target.setProgress(progress);
- }
- }
- }
-
- int viewId;
- boolean indeterminate;
- int progress;
- int max;
-
- public final static int TAG = 6;
- }
-
/**
* Equivalent to calling
* {@link android.view.View#setOnClickListener(android.view.View.OnClickListener)}
@@ -421,7 +161,7 @@ public class RemoteViews implements Parcelable, Filter {
int viewId;
PendingIntent pendingIntent;
- public final static int TAG = 7;
+ public final static int TAG = 1;
}
/**
@@ -511,92 +251,215 @@ public class RemoteViews implements Parcelable, Filter {
PorterDuff.Mode filterMode;
int level;
- public final static int TAG = 8;
+ public final static int TAG = 3;
}
/**
- * Equivalent to calling {@link android.widget.TextView#setTextColor(int)}.
+ * Base class for the reflection actions.
*/
- private class SetTextColor extends Action {
- public SetTextColor(int id, int color) {
- this.viewId = id;
- this.color = color;
- }
-
- public SetTextColor(Parcel parcel) {
- viewId = parcel.readInt();
- color = parcel.readInt();
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(TAG);
- dest.writeInt(viewId);
- dest.writeInt(color);
- }
-
- @Override
- public void apply(View root) {
- final View target = root.findViewById(viewId);
- if (target instanceof TextView) {
- final TextView textView = (TextView) target;
- textView.setTextColor(color);
+ private class ReflectionAction extends Action {
+ static final int TAG = 2;
+
+ static final int BOOLEAN = 1;
+ static final int BYTE = 2;
+ static final int SHORT = 3;
+ static final int INT = 4;
+ static final int LONG = 5;
+ static final int FLOAT = 6;
+ static final int DOUBLE = 7;
+ static final int CHAR = 8;
+ static final int STRING = 9;
+ static final int CHAR_SEQUENCE = 10;
+ static final int URI = 11;
+ static final int BITMAP = 12;
+
+ int viewId;
+ String methodName;
+ int type;
+ Object value;
+
+ ReflectionAction(int viewId, String methodName, int type, Object value) {
+ this.viewId = viewId;
+ this.methodName = methodName;
+ this.type = type;
+ this.value = value;
+ }
+
+ ReflectionAction(Parcel in) {
+ this.viewId = in.readInt();
+ this.methodName = in.readString();
+ this.type = in.readInt();
+ if (false) {
+ Log.d("RemoteViews", "read viewId=0x" + Integer.toHexString(this.viewId)
+ + " methodName=" + this.methodName + " type=" + this.type);
+ }
+ switch (this.type) {
+ case BOOLEAN:
+ this.value = in.readInt() != 0;
+ break;
+ case BYTE:
+ this.value = in.readByte();
+ break;
+ case SHORT:
+ this.value = (short)in.readInt();
+ break;
+ case INT:
+ this.value = in.readInt();
+ break;
+ case LONG:
+ this.value = in.readLong();
+ break;
+ case FLOAT:
+ this.value = in.readFloat();
+ break;
+ case DOUBLE:
+ this.value = in.readDouble();
+ break;
+ case CHAR:
+ this.value = (char)in.readInt();
+ break;
+ case STRING:
+ this.value = in.readString();
+ break;
+ case CHAR_SEQUENCE:
+ this.value = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ break;
+ case URI:
+ this.value = Uri.CREATOR.createFromParcel(in);
+ break;
+ case BITMAP:
+ this.value = Bitmap.CREATOR.createFromParcel(in);
+ break;
+ default:
+ break;
}
}
-
- int viewId;
- int color;
- public final static int TAG = 9;
- }
-
- /**
- * Equivalent to calling {@link android.widget.ViewFlipper#startFlipping()}
- * or {@link android.widget.ViewFlipper#stopFlipping()} along with
- * {@link android.widget.ViewFlipper#setFlipInterval(int)}.
- */
- private class SetFlipping extends Action {
- public SetFlipping(int id, boolean flipping, int milliseconds) {
- this.viewId = id;
- this.flipping = flipping;
- this.milliseconds = milliseconds;
- }
-
- public SetFlipping(Parcel parcel) {
- viewId = parcel.readInt();
- flipping = parcel.readInt() != 0;
- milliseconds = parcel.readInt();
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(TAG);
+ out.writeInt(this.viewId);
+ out.writeString(this.methodName);
+ out.writeInt(this.type);
+ if (false) {
+ Log.d("RemoteViews", "write viewId=0x" + Integer.toHexString(this.viewId)
+ + " methodName=" + this.methodName + " type=" + this.type);
+ }
+ switch (this.type) {
+ case BOOLEAN:
+ out.writeInt(((Boolean)this.value).booleanValue() ? 1 : 0);
+ break;
+ case BYTE:
+ out.writeByte(((Byte)this.value).byteValue());
+ break;
+ case SHORT:
+ out.writeInt(((Short)this.value).shortValue());
+ break;
+ case INT:
+ out.writeInt(((Integer)this.value).intValue());
+ break;
+ case LONG:
+ out.writeLong(((Long)this.value).longValue());
+ break;
+ case FLOAT:
+ out.writeFloat(((Float)this.value).floatValue());
+ break;
+ case DOUBLE:
+ out.writeDouble(((Double)this.value).doubleValue());
+ break;
+ case CHAR:
+ out.writeInt((int)((Character)this.value).charValue());
+ break;
+ case STRING:
+ out.writeString((String)this.value);
+ break;
+ case CHAR_SEQUENCE:
+ TextUtils.writeToParcel((CharSequence)this.value, out, flags);
+ break;
+ case URI:
+ ((Uri)this.value).writeToParcel(out, flags);
+ break;
+ case BITMAP:
+ ((Bitmap)this.value).writeToParcel(out, flags);
+ break;
+ default:
+ break;
+ }
}
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(TAG);
- dest.writeInt(viewId);
- dest.writeInt(flipping ? 1 : 0);
- dest.writeInt(milliseconds);
+
+ private Class getParameterType() {
+ switch (this.type) {
+ case BOOLEAN:
+ return boolean.class;
+ case BYTE:
+ return byte.class;
+ case SHORT:
+ return short.class;
+ case INT:
+ return int.class;
+ case LONG:
+ return long.class;
+ case FLOAT:
+ return float.class;
+ case DOUBLE:
+ return double.class;
+ case CHAR:
+ return char.class;
+ case STRING:
+ return String.class;
+ case CHAR_SEQUENCE:
+ return CharSequence.class;
+ case URI:
+ return Uri.class;
+ case BITMAP:
+ return Bitmap.class;
+ default:
+ return null;
+ }
}
-
+
@Override
public void apply(View root) {
- final View target = root.findViewById(viewId);
- if (target instanceof ViewFlipper) {
- final ViewFlipper flipper = (ViewFlipper) target;
- if (milliseconds != -1) {
- flipper.setFlipInterval(milliseconds);
- }
- if (flipping) {
- flipper.startFlipping();
- } else {
- flipper.stopFlipping();
+ final View view = root.findViewById(viewId);
+ if (view == null) {
+ throw new ActionException("can't find view: 0x" + Integer.toHexString(viewId));
+ }
+
+ Class param = getParameterType();
+ if (param == null) {
+ throw new ActionException("bad type: " + this.type);
+ }
+
+ Class klass = view.getClass();
+ Method method = null;
+ try {
+ method = klass.getMethod(this.methodName, getParameterType());
+ }
+ catch (NoSuchMethodException ex) {
+ throw new ActionException("view: " + klass.getName() + " doesn't have method: "
+ + this.methodName + "(" + param.getName() + ")");
+ }
+
+ if (!method.isAnnotationPresent(RemotableViewMethod.class)) {
+ throw new ActionException("view: " + klass.getName()
+ + " can't use method with RemoteViews: "
+ + this.methodName + "(" + param.getName() + ")");
+ }
+
+ try {
+ if (false) {
+ Log.d("RemoteViews", "view: " + klass.getName() + " calling method: "
+ + this.methodName + "(" + param.getName() + ") with "
+ + (this.value == null ? "null" : this.value.getClass().getName()));
}
+ method.invoke(view, this.value);
+ }
+ catch (Exception ex) {
+ throw new ActionException(ex);
}
}
-
- int viewId;
- boolean flipping;
- int milliseconds;
-
- public final static int TAG = 10;
}
+
/**
* Create a new RemoteViews object that will display the views contained
* in the specified layout file.
@@ -623,41 +486,17 @@ public class RemoteViews implements Parcelable, Filter {
for (int i=0; i<count; i++) {
int tag = parcel.readInt();
switch (tag) {
- case SetViewVisibility.TAG:
- mActions.add(new SetViewVisibility(parcel));
- break;
- case SetTextViewText.TAG:
- mActions.add(new SetTextViewText(parcel));
- break;
- case SetImageViewResource.TAG:
- mActions.add(new SetImageViewResource(parcel));
- break;
- case SetImageViewUri.TAG:
- mActions.add(new SetImageViewUri(parcel));
- break;
- case SetImageViewBitmap.TAG:
- mActions.add(new SetImageViewBitmap(parcel));
- break;
- case SetChronometer.TAG:
- mActions.add(new SetChronometer(parcel));
- break;
- case SetProgressBar.TAG:
- mActions.add(new SetProgressBar(parcel));
- break;
case SetOnClickPendingIntent.TAG:
mActions.add(new SetOnClickPendingIntent(parcel));
break;
case SetDrawableParameters.TAG:
mActions.add(new SetDrawableParameters(parcel));
break;
- case SetTextColor.TAG:
- mActions.add(new SetTextColor(parcel));
- break;
- case SetFlipping.TAG:
- mActions.add(new SetFlipping(parcel));
+ case ReflectionAction.TAG:
+ mActions.add(new ReflectionAction(parcel));
break;
default:
- throw new ActionException("Tag " + tag + "not found");
+ throw new ActionException("Tag " + tag + " not found");
}
}
}
@@ -690,7 +529,7 @@ public class RemoteViews implements Parcelable, Filter {
* @param visibility The new visibility for the view
*/
public void setViewVisibility(int viewId, int visibility) {
- addAction(new SetViewVisibility(viewId, visibility));
+ setInt(viewId, "setVisibility", visibility);
}
/**
@@ -700,7 +539,7 @@ public class RemoteViews implements Parcelable, Filter {
* @param text The new text for the view
*/
public void setTextViewText(int viewId, CharSequence text) {
- addAction(new SetTextViewText(viewId, text));
+ setCharSequence(viewId, "setText", text);
}
/**
@@ -710,7 +549,7 @@ public class RemoteViews implements Parcelable, Filter {
* @param srcId The new resource id for the drawable
*/
public void setImageViewResource(int viewId, int srcId) {
- addAction(new SetImageViewResource(viewId, srcId));
+ setInt(viewId, "setImageResource", srcId);
}
/**
@@ -720,7 +559,7 @@ public class RemoteViews implements Parcelable, Filter {
* @param uri The Uri for the image
*/
public void setImageViewUri(int viewId, Uri uri) {
- addAction(new SetImageViewUri(viewId, uri));
+ setUri(viewId, "setImageURI", uri);
}
/**
@@ -730,7 +569,7 @@ public class RemoteViews implements Parcelable, Filter {
* @param bitmap The new Bitmap for the drawable
*/
public void setImageViewBitmap(int viewId, Bitmap bitmap) {
- addAction(new SetImageViewBitmap(viewId, bitmap));
+ setBitmap(viewId, "setImageBitmap", bitmap);
}
/**
@@ -745,16 +584,20 @@ public class RemoteViews implements Parcelable, Filter {
* {@link android.os.SystemClock#elapsedRealtime SystemClock.elapsedRealtime()}.
* @param format The Chronometer format string, or null to
* simply display the timer value.
- * @param running True if you want the clock to be running, false if not.
+ * @param started True if you want the clock to be started, false if not.
*/
- public void setChronometer(int viewId, long base, String format, boolean running) {
- addAction(new SetChronometer(viewId, base, format, running));
+ public void setChronometer(int viewId, long base, String format, boolean started) {
+ setLong(viewId, "setBase", base);
+ setString(viewId, "setFormat", format);
+ setBoolean(viewId, "setStarted", started);
}
/**
* Equivalent to calling {@link ProgressBar#setMax ProgressBar.setMax},
* {@link ProgressBar#setProgress ProgressBar.setProgress}, and
* {@link ProgressBar#setIndeterminate ProgressBar.setIndeterminate}
+ *
+ * If indeterminate is true, then the values for max and progress are ignored.
*
* @param viewId The id of the view whose text should change
* @param max The 100% value for the progress bar
@@ -764,7 +607,11 @@ public class RemoteViews implements Parcelable, Filter {
*/
public void setProgressBar(int viewId, int max, int progress,
boolean indeterminate) {
- addAction(new SetProgressBar(viewId, max, progress, indeterminate));
+ setBoolean(viewId, "setIndeterminate", indeterminate);
+ if (!indeterminate) {
+ setInt(viewId, "setMax", max);
+ setInt(viewId, "setProgress", progress);
+ }
}
/**
@@ -780,6 +627,7 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * @hide
* Equivalent to calling a combination of {@link Drawable#setAlpha(int)},
* {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)},
* and/or {@link Drawable#setLevel(int)} on the {@link Drawable} of a given
@@ -818,23 +666,55 @@ public class RemoteViews implements Parcelable, Filter {
* focused) to be this color.
*/
public void setTextColor(int viewId, int color) {
- addAction(new SetTextColor(viewId, color));
+ setInt(viewId, "setTextColor", color);
}
- /**
- * Equivalent to calling {@link android.widget.ViewFlipper#startFlipping()}
- * or {@link android.widget.ViewFlipper#stopFlipping()} along with
- * {@link android.widget.ViewFlipper#setFlipInterval(int)}.
- *
- * @param viewId The id of the view to apply changes to
- * @param flipping True means we should
- * {@link android.widget.ViewFlipper#startFlipping()}, otherwise
- * {@link android.widget.ViewFlipper#stopFlipping()}.
- * @param milliseconds How long to wait before flipping to the next view, or
- * -1 to leave unchanged.
- */
- public void setFlipping(int viewId, boolean flipping, int milliseconds) {
- addAction(new SetFlipping(viewId, flipping, milliseconds));
+ public void setBoolean(int viewId, String methodName, boolean value) {
+ addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BOOLEAN, value));
+ }
+
+ public void setByte(int viewId, String methodName, byte value) {
+ addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BYTE, value));
+ }
+
+ public void setShort(int viewId, String methodName, short value) {
+ addAction(new ReflectionAction(viewId, methodName, ReflectionAction.SHORT, value));
+ }
+
+ public void setInt(int viewId, String methodName, int value) {
+ addAction(new ReflectionAction(viewId, methodName, ReflectionAction.INT, value));
+ }
+
+ public void setLong(int viewId, String methodName, long value) {
+ addAction(new ReflectionAction(viewId, methodName, ReflectionAction.LONG, value));
+ }
+
+ public void setFloat(int viewId, String methodName, float value) {
+ addAction(new ReflectionAction(viewId, methodName, ReflectionAction.FLOAT, value));
+ }
+
+ public void setDouble(int viewId, String methodName, double value) {
+ addAction(new ReflectionAction(viewId, methodName, ReflectionAction.DOUBLE, value));
+ }
+
+ public void setChar(int viewId, String methodName, char value) {
+ addAction(new ReflectionAction(viewId, methodName, ReflectionAction.CHAR, value));
+ }
+
+ public void setString(int viewId, String methodName, String value) {
+ addAction(new ReflectionAction(viewId, methodName, ReflectionAction.STRING, value));
+ }
+
+ public void setCharSequence(int viewId, String methodName, CharSequence value) {
+ addAction(new ReflectionAction(viewId, methodName, ReflectionAction.CHAR_SEQUENCE, value));
+ }
+
+ public void setUri(int viewId, String methodName, Uri value) {
+ addAction(new ReflectionAction(viewId, methodName, ReflectionAction.URI, value));
+ }
+
+ public void setBitmap(int viewId, String methodName, Bitmap value) {
+ addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BITMAP, value));
}
/**
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index da4a077..dc2c70d 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -405,7 +405,7 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
* Specify a label and icon as the tab indicator.
*/
public TabSpec setIndicator(CharSequence label, Drawable icon) {
- mIndicatorStrategy = new LabelAndIconIndicatorStategy(label, icon);
+ mIndicatorStrategy = new LabelAndIconIndicatorStrategy(label, icon);
return this;
}
@@ -497,12 +497,12 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1");
/**
* How we create a tab indicator that has a label and an icon
*/
- private class LabelAndIconIndicatorStategy implements IndicatorStrategy {
+ private class LabelAndIconIndicatorStrategy implements IndicatorStrategy {
private final CharSequence mLabel;
private final Drawable mIcon;
- private LabelAndIconIndicatorStategy(CharSequence label, Drawable icon) {
+ private LabelAndIconIndicatorStrategy(CharSequence label, Drawable icon) {
mLabel = label;
mIcon = icon;
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2ae5d4e..bdc54ff 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -87,6 +87,7 @@ import android.view.ViewDebug;
import android.view.ViewTreeObserver;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.AnimationUtils;
+import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
@@ -1521,6 +1522,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_textSize
*/
+ @android.view.RemotableViewMethod
public void setTextSize(float size) {
setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
}
@@ -1572,6 +1574,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_textScaleX
*/
+ @android.view.RemotableViewMethod
public void setTextScaleX(float size) {
if (size != mTextPaint.getTextScaleX()) {
mTextPaint.setTextScaleX(size);
@@ -1620,6 +1623,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_textColor
*/
+ @android.view.RemotableViewMethod
public void setTextColor(int color) {
mTextColor = ColorStateList.valueOf(color);
updateTextColors();
@@ -1662,6 +1666,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_textColorHighlight
*/
+ @android.view.RemotableViewMethod
public void setHighlightColor(int color) {
if (mHighlightColor != color) {
mHighlightColor = color;
@@ -1703,6 +1708,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_autoLink
*/
+ @android.view.RemotableViewMethod
public final void setAutoLinkMask(int mask) {
mAutoLinkMask = mask;
}
@@ -1715,6 +1721,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_linksClickable
*/
+ @android.view.RemotableViewMethod
public final void setLinksClickable(boolean whether) {
mLinksClickable = whether;
}
@@ -1751,6 +1758,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_textColorHint
*/
+ @android.view.RemotableViewMethod
public final void setHintTextColor(int color) {
mHintTextColor = ColorStateList.valueOf(color);
updateTextColors();
@@ -1789,6 +1797,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_textColorLink
*/
+ @android.view.RemotableViewMethod
public final void setLinkTextColor(int color) {
mLinkTextColor = ColorStateList.valueOf(color);
updateTextColors();
@@ -1876,6 +1885,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* reflows the text if they are different from the old flags.
* @see Paint#setFlags
*/
+ @android.view.RemotableViewMethod
public void setPaintFlags(int flags) {
if (mTextPaint.getFlags() != flags) {
mTextPaint.setFlags(flags);
@@ -1909,6 +1919,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_minLines
*/
+ @android.view.RemotableViewMethod
public void setMinLines(int minlines) {
mMinimum = minlines;
mMinMode = LINES;
@@ -1922,6 +1933,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_minHeight
*/
+ @android.view.RemotableViewMethod
public void setMinHeight(int minHeight) {
mMinimum = minHeight;
mMinMode = PIXELS;
@@ -1935,6 +1947,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_maxLines
*/
+ @android.view.RemotableViewMethod
public void setMaxLines(int maxlines) {
mMaximum = maxlines;
mMaxMode = LINES;
@@ -1948,6 +1961,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_maxHeight
*/
+ @android.view.RemotableViewMethod
public void setMaxHeight(int maxHeight) {
mMaximum = maxHeight;
mMaxMode = PIXELS;
@@ -1961,6 +1975,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_lines
*/
+ @android.view.RemotableViewMethod
public void setLines(int lines) {
mMaximum = mMinimum = lines;
mMaxMode = mMinMode = LINES;
@@ -1976,6 +1991,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_height
*/
+ @android.view.RemotableViewMethod
public void setHeight(int pixels) {
mMaximum = mMinimum = pixels;
mMaxMode = mMinMode = PIXELS;
@@ -1989,6 +2005,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_minEms
*/
+ @android.view.RemotableViewMethod
public void setMinEms(int minems) {
mMinWidth = minems;
mMinWidthMode = EMS;
@@ -2002,6 +2019,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_minWidth
*/
+ @android.view.RemotableViewMethod
public void setMinWidth(int minpixels) {
mMinWidth = minpixels;
mMinWidthMode = PIXELS;
@@ -2015,6 +2033,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_maxEms
*/
+ @android.view.RemotableViewMethod
public void setMaxEms(int maxems) {
mMaxWidth = maxems;
mMaxWidthMode = EMS;
@@ -2028,6 +2047,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_maxWidth
*/
+ @android.view.RemotableViewMethod
public void setMaxWidth(int maxpixels) {
mMaxWidth = maxpixels;
mMaxWidthMode = PIXELS;
@@ -2041,6 +2061,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_ems
*/
+ @android.view.RemotableViewMethod
public void setEms(int ems) {
mMaxWidth = mMinWidth = ems;
mMaxWidthMode = mMinWidthMode = EMS;
@@ -2056,6 +2077,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_width
*/
+ @android.view.RemotableViewMethod
public void setWidth(int pixels) {
mMaxWidth = mMinWidth = pixels;
mMaxWidthMode = mMinWidthMode = PIXELS;
@@ -2321,6 +2343,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_freezesText
*/
+ @android.view.RemotableViewMethod
public void setFreezesText(boolean freezesText) {
mFreezesText = freezesText;
}
@@ -2366,6 +2389,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_text
*/
+ @android.view.RemotableViewMethod
public final void setText(CharSequence text) {
setText(text, mBufferType);
}
@@ -2378,6 +2402,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @see #setText(CharSequence)
*/
+ @android.view.RemotableViewMethod
public final void setTextKeepState(CharSequence text) {
setTextKeepState(text, mBufferType);
}
@@ -2648,6 +2673,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
+ @android.view.RemotableViewMethod
public final void setText(int resid) {
setText(getContext().getResources().getText(resid));
}
@@ -2666,6 +2692,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_hint
*/
+ @android.view.RemotableViewMethod
public final void setHint(CharSequence hint) {
mHint = TextUtils.stringOrSpannedString(hint);
@@ -2686,6 +2713,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_hint
*/
+ @android.view.RemotableViewMethod
public final void setHint(int resid) {
setHint(getContext().getResources().getText(resid));
}
@@ -2896,6 +2924,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* <code>error</code> is <code>null</code>, the error message and icon
* will be cleared.
*/
+ @android.view.RemotableViewMethod
public void setError(CharSequence error) {
if (error == null) {
setError(null, null);
@@ -2954,10 +2983,28 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mPopup == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
- TextView err = (TextView) inflater.inflate(com.android.internal.R.layout.textview_hint,
+ final TextView err = (TextView) inflater.inflate(com.android.internal.R.layout.textview_hint,
null);
- mPopup = new PopupWindow(err, 200, 50);
+ mPopup = new PopupWindow(err, 200, 50) {
+ private boolean mAbove = false;
+
+ @Override
+ public void update(int x, int y, int w, int h, boolean force) {
+ super.update(x, y, w, h, force);
+
+ boolean above = isAboveAnchor();
+ if (above != mAbove) {
+ mAbove = above;
+
+ if (above) {
+ err.setBackgroundResource(com.android.internal.R.drawable.popup_inline_error_above);
+ } else {
+ err.setBackgroundResource(com.android.internal.R.drawable.popup_inline_error);
+ }
+ }
+ }
+ };
mPopup.setFocusable(false);
}
@@ -5094,6 +5141,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_singleLine
*/
+ @android.view.RemotableViewMethod
public void setSingleLine(boolean singleLine) {
if ((mInputType&EditorInfo.TYPE_MASK_CLASS)
== EditorInfo.TYPE_CLASS_TEXT) {
@@ -5168,6 +5216,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_selectAllOnFocus
*/
+ @android.view.RemotableViewMethod
public void setSelectAllOnFocus(boolean selectAllOnFocus) {
mSelectAllOnFocus = selectAllOnFocus;
@@ -5181,6 +5230,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @attr ref android.R.styleable#TextView_cursorVisible
*/
+ @android.view.RemotableViewMethod
public void setCursorVisible(boolean visible) {
mCursorVisible = visible;
invalidate();
@@ -5730,6 +5780,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
startStopMarquee(hasWindowFocus);
}
+ /**
+ * Use {@link BaseInputConnection#removeComposingSpans
+ * BaseInputConnection.removeComposingSpans()} to remove any IME composing
+ * state from this text view.
+ */
+ public void clearComposingText() {
+ if (mText instanceof Spannable) {
+ BaseInputConnection.removeComposingSpans((Spannable)mText);
+ }
+ }
+
@Override
public void setSelected(boolean selected) {
boolean wasSelected = isSelected();
diff --git a/core/java/android/widget/ViewFlipper.java b/core/java/android/widget/ViewFlipper.java
index e20bfdf..8a7946b 100644
--- a/core/java/android/widget/ViewFlipper.java
+++ b/core/java/android/widget/ViewFlipper.java
@@ -31,7 +31,6 @@ import android.widget.RemoteViews.RemoteView;
*
* @attr ref android.R.styleable#ViewFlipper_flipInterval
*/
-@RemoteView
public class ViewFlipper extends ViewAnimator {
private int mFlipInterval = 3000;
private boolean mKeepFlipping = false;
@@ -56,6 +55,7 @@ public class ViewFlipper extends ViewAnimator {
* @param milliseconds
* time in milliseconds
*/
+ @android.view.RemotableViewMethod
public void setFlipInterval(int milliseconds) {
mFlipInterval = milliseconds;
}
diff --git a/core/java/android/widget/ZoomRing.java b/core/java/android/widget/ZoomRing.java
index be3b1fb..22881b3 100644
--- a/core/java/android/widget/ZoomRing.java
+++ b/core/java/android/widget/ZoomRing.java
@@ -7,7 +7,11 @@ import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RotateDrawable;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
@@ -19,10 +23,8 @@ import android.view.ViewConfiguration;
public class ZoomRing extends View {
// TODO: move to ViewConfiguration?
- static final int DOUBLE_TAP_DISMISS_TIMEOUT = ViewConfiguration.getJumpTapTimeout();
+ static final int DOUBLE_TAP_DISMISS_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();
// TODO: get from theme
- private static final int DISABLED_ALPHA = 160;
-
private static final String TAG = "ZoomRing";
// TODO: Temporary until the trail is done
@@ -32,15 +34,26 @@ public class ZoomRing extends View {
private static final int THUMB_DISTANCE = 63;
/** To avoid floating point calculations, we multiply radians by this value. */
- public static final int RADIAN_INT_MULTIPLIER = 100000000;
+ public static final int RADIAN_INT_MULTIPLIER = 10000;
+ public static final int RADIAN_INT_ERROR = 100;
/** PI using our multiplier. */
public static final int PI_INT_MULTIPLIED = (int) (Math.PI * RADIAN_INT_MULTIPLIER);
+ public static final int TWO_PI_INT_MULTIPLIED = PI_INT_MULTIPLIED * 2;
/** PI/2 using our multiplier. */
private static final int HALF_PI_INT_MULTIPLIED = PI_INT_MULTIPLIED / 2;
private int mZeroAngle = HALF_PI_INT_MULTIPLIED * 3;
+
+ private static final int THUMB_GRAB_SLOP = PI_INT_MULTIPLIED / 8;
+ private static final int THUMB_DRAG_SLOP = PI_INT_MULTIPLIED / 12;
- private static final int THUMB_GRAB_SLOP = PI_INT_MULTIPLIED / 4;
+ /**
+ * Includes error because we compare this to the result of
+ * getDelta(getClosestTickeAngle(..), oldAngle) which ends up having some
+ * rounding error.
+ */
+ private static final int MAX_ABS_JUMP_DELTA_ANGLE = (2 * PI_INT_MULTIPLIED / 3) +
+ RADIAN_INT_ERROR;
/** The cached X of our center. */
private int mCenterX;
@@ -49,10 +62,13 @@ public class ZoomRing extends View {
/** The angle of the thumb (in int radians) */
private int mThumbAngle;
- private boolean mIsThumbAngleValid;
private int mThumbHalfWidth;
private int mThumbHalfHeight;
-
+
+ private int mThumbCwBound = Integer.MIN_VALUE;
+ private int mThumbCcwBound = Integer.MIN_VALUE;
+ private boolean mEnforceMaxAbsJump = true;
+
/** The inner radius of the track. */
private int mBoundInnerRadiusSquared = 0;
/** The outer radius of the track. */
@@ -63,8 +79,23 @@ public class ZoomRing extends View {
private boolean mDrawThumb = true;
private Drawable mThumbDrawable;
-
+
+ /** Shown beneath the thumb if we can still zoom in. */
+ private Drawable mThumbPlusArrowDrawable;
+ /** Shown beneath the thumb if we can still zoom out. */
+ private Drawable mThumbMinusArrowDrawable;
+ private static final int THUMB_ARROWS_FADE_DURATION = 300;
+ private long mThumbArrowsFadeStartTime;
+ private int mThumbArrowsAlpha = 255;
+
private static final int MODE_IDLE = 0;
+
+ /**
+ * User has his finger down somewhere on the ring (besides the thumb) and we
+ * are waiting for him to move the slop amount before considering him in the
+ * drag thumb state.
+ */
+ private static final int MODE_WAITING_FOR_DRAG_THUMB = 5;
private static final int MODE_DRAG_THUMB = 1;
/**
* User has his finger down, but we are waiting for him to pass the touch
@@ -74,24 +105,47 @@ public class ZoomRing extends View {
private static final int MODE_WAITING_FOR_MOVE_ZOOM_RING = 4;
private static final int MODE_MOVE_ZOOM_RING = 2;
private static final int MODE_TAP_DRAG = 3;
+ /** Ignore the touch interaction. Reset to MODE_IDLE after up/cancel. */
+ private static final int MODE_IGNORE_UNTIL_UP = 6;
private int mMode;
- private long mPreviousDownTime;
+ private long mPreviousUpTime;
private int mPreviousDownX;
private int mPreviousDownY;
- private Disabler mDisabler = new Disabler();
-
+ private int mWaitingForDragThumbDownAngle;
+
private OnZoomRingCallback mCallback;
private int mPreviousCallbackAngle;
private int mCallbackThreshold = Integer.MAX_VALUE;
private boolean mResetThumbAutomatically = true;
private int mThumbDragStartAngle;
+
private final int mTouchSlop;
+
private Drawable mTrail;
private double mAcculumalatedTrailAngle;
-
+
+ private Scroller mThumbScroller;
+
+ private static final int MSG_THUMB_SCROLLER_TICK = 1;
+ private static final int MSG_THUMB_ARROWS_FADE_TICK = 2;
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_THUMB_SCROLLER_TICK:
+ onThumbScrollerTick();
+ break;
+
+ case MSG_THUMB_ARROWS_FADE_TICK:
+ onThumbArrowsFadeTick();
+ break;
+ }
+ }
+ };
+
public ZoomRing(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
@@ -101,6 +155,10 @@ public class ZoomRing extends View {
// TODO get drawables from style instead
Resources res = context.getResources();
mThumbDrawable = res.getDrawable(R.drawable.zoom_ring_thumb);
+ mThumbPlusArrowDrawable = res.getDrawable(R.drawable.zoom_ring_thumb_plus_arrow_rotatable).
+ mutate();
+ mThumbMinusArrowDrawable = res.getDrawable(R.drawable.zoom_ring_thumb_minus_arrow_rotatable).
+ mutate();
if (DRAW_TRAIL) {
mTrail = res.getDrawable(R.drawable.zoom_ring_trail).mutate();
}
@@ -108,7 +166,7 @@ public class ZoomRing extends View {
// TODO: add padding to drawable
setBackgroundResource(R.drawable.zoom_ring_track);
// TODO get from style
- setBounds(30, Integer.MAX_VALUE);
+ setRingBounds(30, Integer.MAX_VALUE);
mThumbHalfHeight = mThumbDrawable.getIntrinsicHeight() / 2;
mThumbHalfWidth = mThumbDrawable.getIntrinsicWidth() / 2;
@@ -134,7 +192,7 @@ public class ZoomRing extends View {
}
// TODO: from XML too
- public void setBounds(int innerRadius, int outerRadius) {
+ public void setRingBounds(int innerRadius, int outerRadius) {
mBoundInnerRadiusSquared = innerRadius * innerRadius;
if (mBoundInnerRadiusSquared < innerRadius) {
// Prevent overflow
@@ -148,7 +206,64 @@ public class ZoomRing extends View {
}
}
+ public void setThumbClockwiseBound(int angle) {
+ if (angle < 0) {
+ mThumbCwBound = Integer.MIN_VALUE;
+ } else {
+ mThumbCwBound = getClosestTickAngle(angle);
+ }
+ setEnforceMaxAbsJump();
+ }
+
+ public void setThumbCounterclockwiseBound(int angle) {
+ if (angle < 0) {
+ mThumbCcwBound = Integer.MIN_VALUE;
+ } else {
+ mThumbCcwBound = getClosestTickAngle(angle);
+ }
+ setEnforceMaxAbsJump();
+ }
+
+ private void setEnforceMaxAbsJump() {
+ // If there are bounds in both direction, there is no reason to restrict
+ // the amount that a user can absolute jump to
+ mEnforceMaxAbsJump =
+ mThumbCcwBound == Integer.MIN_VALUE || mThumbCwBound == Integer.MIN_VALUE;
+ }
+
+ public int getThumbAngle() {
+ return mThumbAngle;
+ }
+
public void setThumbAngle(int angle) {
+ angle = getValidAngle(angle);
+ mPreviousCallbackAngle = getClosestTickAngle(angle);
+ setThumbAngleAuto(angle, false, false);
+ }
+
+ /**
+ * Sets the thumb angle. If already animating, will continue the animation,
+ * otherwise it will do a direct jump.
+ *
+ * @param angle
+ * @param useDirection Whether to use the ccw parameter
+ * @param ccw Whether going counterclockwise (only used if useDirection is true)
+ */
+ private void setThumbAngleAuto(int angle, boolean useDirection, boolean ccw) {
+ if (mThumbScroller == null
+ || mThumbScroller.isFinished()
+ || Math.abs(getDelta(angle, getThumbScrollerAngle())) < THUMB_GRAB_SLOP) {
+ setThumbAngleInt(angle);
+ } else {
+ if (useDirection) {
+ setThumbAngleAnimated(angle, 0, ccw);
+ } else {
+ setThumbAngleAnimated(angle, 0);
+ }
+ }
+ }
+
+ private void setThumbAngleInt(int angle) {
mThumbAngle = angle;
int unoffsetAngle = angle + mZeroAngle;
int thumbCenterX = (int) (Math.cos(1f * unoffsetAngle / RADIAN_INT_MULTIPLIER) *
@@ -161,6 +276,10 @@ public class ZoomRing extends View {
thumbCenterX + mThumbHalfWidth,
thumbCenterY + mThumbHalfHeight);
+ if (mThumbArrowsAlpha > 0) {
+ setThumbArrowsAngle(angle);
+ }
+
if (DRAW_TRAIL) {
double degrees;
degrees = Math.min(359.0, Math.abs(mAcculumalatedTrailAngle));
@@ -174,10 +293,66 @@ public class ZoomRing extends View {
invalidate();
}
+
+ /**
+ *
+ * @param angle
+ * @param duration The animation duration, or 0 for the default duration.
+ */
+ public void setThumbAngleAnimated(int angle, int duration) {
+ // The angle when going from the current angle to the new angle
+ int deltaAngle = getDelta(mThumbAngle, angle);
+ // Counter clockwise if the new angle is more the current angle
+ boolean counterClockwise = deltaAngle > 0;
+
+ if (deltaAngle > PI_INT_MULTIPLIED || deltaAngle < -PI_INT_MULTIPLIED) {
+ // It's quicker to go the other direction
+ counterClockwise = !counterClockwise;
+ }
+
+ setThumbAngleAnimated(angle, duration, counterClockwise);
+ }
+
+ public void setThumbAngleAnimated(int angle, int duration, boolean counterClockwise) {
+ if (mThumbScroller == null) {
+ mThumbScroller = new Scroller(mContext);
+ }
+
+ int startAngle = mThumbAngle;
+ int endAngle = getValidAngle(angle);
+ int deltaAngle = getDelta(startAngle, endAngle, counterClockwise);
+ if (startAngle + deltaAngle < 0) {
+ // Keep our angles positive
+ startAngle += TWO_PI_INT_MULTIPLIED;
+ }
+
+ if (!mThumbScroller.isFinished()) {
+ duration = mThumbScroller.getDuration() - mThumbScroller.timePassed();
+ } else if (duration == 0) {
+ duration = getAnimationDuration(deltaAngle);
+ }
+ mThumbScroller.startScroll(startAngle, 0, deltaAngle, 0, duration);
+ onThumbScrollerTick();
+ }
+
+ private int getAnimationDuration(int deltaAngle) {
+ if (deltaAngle < 0) deltaAngle *= -1;
+ return 300 + deltaAngle * 300 / RADIAN_INT_MULTIPLIER;
+ }
+
+ private void onThumbScrollerTick() {
+ if (!mThumbScroller.computeScrollOffset()) return;
+ setThumbAngleInt(getThumbScrollerAngle());
+ mHandler.sendEmptyMessage(MSG_THUMB_SCROLLER_TICK);
+ }
+ private int getThumbScrollerAngle() {
+ return mThumbScroller.getCurrX() % TWO_PI_INT_MULTIPLIED;
+ }
+
public void resetThumbAngle(int angle) {
mPreviousCallbackAngle = angle;
- setThumbAngle(angle);
+ setThumbAngleInt(angle);
}
public void resetThumbAngle() {
@@ -185,7 +360,7 @@ public class ZoomRing extends View {
resetThumbAngle(0);
}
}
-
+
public void setResetThumbAutomatically(boolean resetThumbAutomatically) {
mResetThumbAutomatically = resetThumbAutomatically;
}
@@ -214,6 +389,9 @@ public class ZoomRing extends View {
if (DRAW_TRAIL) {
mTrail.setBounds(0, 0, right - left, bottom - top);
}
+
+ mThumbPlusArrowDrawable.setBounds(0, 0, right - left, bottom - top);
+ mThumbMinusArrowDrawable.setBounds(0, 0, right - left, bottom - top);
}
@Override
@@ -227,15 +405,13 @@ public class ZoomRing extends View {
mMode = MODE_IDLE;
mPreviousWidgetDragX = mPreviousWidgetDragY = Integer.MIN_VALUE;
mAcculumalatedTrailAngle = 0.0;
- mIsThumbAngleValid = false;
}
public void setTapDragMode(boolean tapDragMode, int x, int y) {
resetState();
mMode = tapDragMode ? MODE_TAP_DRAG : MODE_IDLE;
- mIsThumbAngleValid = false;
- if (tapDragMode && mCallback != null) {
+ if (tapDragMode) {
onThumbDragStarted(getAngle(x - mCenterX, y - mCenterY));
}
}
@@ -244,35 +420,44 @@ public class ZoomRing extends View {
switch (action) {
case MotionEvent.ACTION_DOWN:
- if (mPreviousDownTime + DOUBLE_TAP_DISMISS_TIMEOUT >= time) {
- if (mCallback != null) {
- mCallback.onZoomRingDismissed();
- }
- } else {
- mPreviousDownTime = time;
- mPreviousDownX = x;
- mPreviousDownY = y;
+ mCallback.onUserInteractionStarted();
+
+ if (time - mPreviousUpTime <= DOUBLE_TAP_DISMISS_TIMEOUT) {
+ mCallback.onZoomRingDismissed(true);
}
+
+ mPreviousDownX = x;
+ mPreviousDownY = y;
resetState();
- return true;
+ // Fall through to code below switch (since the down is used for
+ // jumping to the touched tick)
+ break;
case MotionEvent.ACTION_MOVE:
+ if (mMode == MODE_IGNORE_UNTIL_UP) return true;
+
// Fall through to code below switch
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
- if (mCallback != null) {
- if (mMode == MODE_MOVE_ZOOM_RING || mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) {
- mCallback.onZoomRingSetMovableHintVisible(false);
- if (mMode == MODE_MOVE_ZOOM_RING) {
- mCallback.onZoomRingMovingStopped();
- }
- } else if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG) {
- onThumbDragStopped(getAngle(x - mCenterX, y - mCenterY));
+ if (mMode == MODE_MOVE_ZOOM_RING || mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) {
+ mCallback.onZoomRingSetMovableHintVisible(false);
+ if (mMode == MODE_MOVE_ZOOM_RING) {
+ mCallback.onZoomRingMovingStopped();
+ }
+ } else if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG ||
+ mMode == MODE_WAITING_FOR_DRAG_THUMB) {
+ onThumbDragStopped();
+
+ if (mMode == MODE_DRAG_THUMB) {
+ // Animate back to a tick
+ setThumbAngleAnimated(mPreviousCallbackAngle, 0);
}
}
- mDisabler.setEnabling(true);
+
+ mPreviousUpTime = time;
+ mCallback.onUserInteractionStopped();
return true;
default:
@@ -283,18 +468,18 @@ public class ZoomRing extends View {
int localX = x - mCenterX;
int localY = y - mCenterY;
boolean isTouchingThumb = true;
- boolean isInBounds = true;
+ boolean isInRingBounds = true;
+
int touchAngle = getAngle(localX, localY);
-
int radiusSquared = localX * localX + localY * localY;
if (radiusSquared < mBoundInnerRadiusSquared ||
radiusSquared > mBoundOuterRadiusSquared) {
// Out-of-bounds
isTouchingThumb = false;
- isInBounds = false;
+ isInRingBounds = false;
}
- int deltaThumbAndTouch = getDelta(touchAngle, mThumbAngle);
+ int deltaThumbAndTouch = getDelta(mThumbAngle, touchAngle);
int absoluteDeltaThumbAndTouch = deltaThumbAndTouch >= 0 ?
deltaThumbAndTouch : -deltaThumbAndTouch;
if (isTouchingThumb &&
@@ -305,17 +490,68 @@ public class ZoomRing extends View {
if (mMode == MODE_IDLE) {
if (isTouchingThumb) {
+ // They grabbed the thumb
mMode = MODE_DRAG_THUMB;
+ onThumbDragStarted(touchAngle);
+
+ } else if (isInRingBounds) {
+ // They tapped somewhere else on the ring
+ int tickAngle = getClosestTickAngle(touchAngle);
+
+ int deltaThumbAndTick = getDelta(mThumbAngle, tickAngle);
+ int boundAngle = getBoundIfExceeds(mThumbAngle, deltaThumbAndTick);
+
+ if (mEnforceMaxAbsJump) {
+ // Enforcing the max jump
+ if (deltaThumbAndTick > MAX_ABS_JUMP_DELTA_ANGLE ||
+ deltaThumbAndTick < -MAX_ABS_JUMP_DELTA_ANGLE) {
+ // Trying to jump too far, ignore this touch interaction
+ mMode = MODE_IGNORE_UNTIL_UP;
+ return true;
+ }
+
+ // Make sure we only let them jump within bounds
+ if (boundAngle != Integer.MIN_VALUE) {
+ tickAngle = boundAngle;
+ }
+ } else {
+ // Not enforcing the max jump, but we have to make sure
+ // we're getting to the tapped angle by going through the
+ // in-bounds region
+ if (boundAngle != Integer.MIN_VALUE) {
+ // Going this direction hits a bound, let's go the opposite direction
+ boolean oldDirectionIsCcw = deltaThumbAndTick > 0;
+ deltaThumbAndTick = getDelta(mThumbAngle, tickAngle, !oldDirectionIsCcw);
+ boundAngle = getBoundIfExceeds(mThumbAngle, deltaThumbAndTick);
+ if (boundAngle != Integer.MIN_VALUE) {
+ Log
+ .d(
+ TAG,
+ "Tapped somewhere where the shortest distance goes through a bound, but then the opposite direction also went through a bound!");
+ }
+ }
+ }
+
+ mMode = MODE_WAITING_FOR_DRAG_THUMB;
+ mWaitingForDragThumbDownAngle = touchAngle;
+ boolean ccw = deltaThumbAndTick > 0;
+ setThumbAngleAnimated(tickAngle, 0, ccw);
+
+ // Our thumb scrolling animation takes us from mThumbAngle to tickAngle
+ onThumbDragStarted(mThumbAngle);
+ onThumbDragged(tickAngle, true, ccw);
+
} else {
+ // They tapped somewhere else
mMode = MODE_WAITING_FOR_MOVE_ZOOM_RING;
+ mCallback.onZoomRingSetMovableHintVisible(true);
}
- if (mCallback != null) {
- if (mMode == MODE_DRAG_THUMB) {
- onThumbDragStarted(touchAngle);
- } else if (mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) {
- mCallback.onZoomRingSetMovableHintVisible(true);
- }
+ } else if (mMode == MODE_WAITING_FOR_DRAG_THUMB) {
+ int deltaDownAngle = getDelta(mWaitingForDragThumbDownAngle, touchAngle);
+ if ((deltaDownAngle < -THUMB_DRAG_SLOP || deltaDownAngle > THUMB_DRAG_SLOP) &&
+ isDeltaInBounds(mWaitingForDragThumbDownAngle, deltaDownAngle)) {
+ mMode = MODE_DRAG_THUMB;
}
} else if (mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) {
@@ -323,19 +559,14 @@ public class ZoomRing extends View {
Math.abs(y - mPreviousDownY) > mTouchSlop) {
/* Make sure the user has moved the slop amount before going into that mode. */
mMode = MODE_MOVE_ZOOM_RING;
-
- if (mCallback != null) {
- mCallback.onZoomRingMovingStarted();
- }
+ mCallback.onZoomRingMovingStarted();
}
}
// Purposefully not an "else if"
if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG) {
- if (isInBounds) {
- onThumbDragged(touchAngle, mIsThumbAngleValid ? deltaThumbAndTouch : 0);
- } else {
- mIsThumbAngleValid = false;
+ if (isInRingBounds) {
+ onThumbDragged(touchAngle, false, false);
}
} else if (mMode == MODE_MOVE_ZOOM_RING) {
onZoomRingMoved(rawX, rawY);
@@ -344,55 +575,219 @@ public class ZoomRing extends View {
return true;
}
- private int getDelta(int angle1, int angle2) {
- int delta = angle1 - angle2;
-
- // Assume this is a result of crossing over the discontinuous 0 -> 2pi
- if (delta > PI_INT_MULTIPLIED || delta < -PI_INT_MULTIPLIED) {
- // Bring both the radians and previous angle onto a continuous range
- if (angle1 < HALF_PI_INT_MULTIPLIED) {
- // Same as deltaRadians = (radians + 2PI) - previousAngle
- delta += PI_INT_MULTIPLIED * 2;
- } else if (angle2 < HALF_PI_INT_MULTIPLIED) {
- // Same as deltaRadians = radians - (previousAngle + 2PI)
- delta -= PI_INT_MULTIPLIED * 2;
+ private boolean isDeltaInBounds(int startAngle, int deltaAngle) {
+ return getBoundIfExceeds(startAngle, deltaAngle) == Integer.MIN_VALUE;
+ }
+
+ private int getBoundIfExceeds(int startAngle, int deltaAngle) {
+ if (deltaAngle > 0) {
+ // Counterclockwise movement
+ if (mThumbCcwBound != Integer.MIN_VALUE &&
+ getDelta(startAngle, mThumbCcwBound, true) < deltaAngle) {
+ return mThumbCcwBound;
+ }
+ } else if (deltaAngle < 0) {
+ // Clockwise movement, both of these will be negative
+ int deltaThumbAndBound = getDelta(startAngle, mThumbCwBound, false);
+ if (mThumbCwBound != Integer.MIN_VALUE &&
+ deltaThumbAndBound > deltaAngle) {
+ // Tapped outside of the bound in that direction
+ return mThumbCwBound;
}
}
+
+ return Integer.MIN_VALUE;
+ }
+
+ private int getDelta(int startAngle, int endAngle, boolean useDirection, boolean ccw) {
+ return useDirection ? getDelta(startAngle, endAngle, ccw) : getDelta(startAngle, endAngle);
+ }
+
+ /**
+ * Gets the smallest delta between two angles, and infers the direction
+ * based on the shortest path between the two angles. If going from
+ * startAngle to endAngle is counterclockwise, the result will be positive.
+ * If it is clockwise, the result will be negative.
+ *
+ * @param startAngle The start angle.
+ * @param endAngle The end angle.
+ * @return The difference in angles.
+ */
+ private int getDelta(int startAngle, int endAngle) {
+ int largerAngle, smallerAngle;
+ if (endAngle > startAngle) {
+ largerAngle = endAngle;
+ smallerAngle = startAngle;
+ } else {
+ largerAngle = startAngle;
+ smallerAngle = endAngle;
+ }
- return delta;
+ int delta = largerAngle - smallerAngle;
+ if (delta <= PI_INT_MULTIPLIED) {
+ // If going clockwise, negate the delta
+ return startAngle == largerAngle ? -delta : delta;
+ } else {
+ // The other direction is the delta we want (it includes the
+ // discontinuous 0-2PI angle)
+ delta = TWO_PI_INT_MULTIPLIED - delta;
+ // If going clockwise, negate the delta
+ return startAngle == smallerAngle ? -delta : delta;
+ }
}
+ /**
+ * Gets the delta between two angles in the direction specified.
+ *
+ * @param startAngle The start angle.
+ * @param endAngle The end angle.
+ * @param counterClockwise The direction to take when computing the delta.
+ * @return The difference in angles in the given direction.
+ */
+ private int getDelta(int startAngle, int endAngle, boolean counterClockwise) {
+ int delta = endAngle - startAngle;
+
+ if (!counterClockwise && delta > 0) {
+ // Crossed the discontinuous 0/2PI angle, take the leftover slice of
+ // the pie and negate it
+ return -TWO_PI_INT_MULTIPLIED + delta;
+ } else if (counterClockwise && delta < 0) {
+ // Crossed the discontinuous 0/2PI angle, take the leftover slice of
+ // the pie (and ensure it is positive)
+ return TWO_PI_INT_MULTIPLIED + delta;
+ } else {
+ return delta;
+ }
+ }
+
private void onThumbDragStarted(int startAngle) {
+ setThumbArrowsVisible(false);
mThumbDragStartAngle = startAngle;
- mCallback.onZoomRingThumbDraggingStarted(startAngle);
+ mCallback.onZoomRingThumbDraggingStarted();
}
-
- private void onThumbDragged(int touchAngle, int deltaAngle) {
- mAcculumalatedTrailAngle += Math.toDegrees(deltaAngle / (double) RADIAN_INT_MULTIPLIER);
- int totalDeltaAngle = getDelta(touchAngle, mPreviousCallbackAngle);
- if (totalDeltaAngle > mCallbackThreshold
- || totalDeltaAngle < -mCallbackThreshold) {
- if (mCallback != null) {
- boolean canStillZoom = mCallback.onZoomRingThumbDragged(
- totalDeltaAngle / mCallbackThreshold,
- mThumbDragStartAngle, touchAngle);
- mDisabler.setEnabling(canStillZoom);
-
- if (canStillZoom) {
- // TODO: we're trying the haptics to see how it goes with
- // users, so we're ignoring the settings (for now)
- performHapticFeedback(HapticFeedbackConstants.ZOOM_RING_TICK,
- HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING |
- HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+
+ private void onThumbDragged(int touchAngle, boolean useDirection, boolean ccw) {
+ boolean animateThumbToNewAngle = false;
+
+ int totalDeltaAngle;
+ totalDeltaAngle = getDelta(mPreviousCallbackAngle, touchAngle, useDirection, ccw);
+ int fuzzyCallbackThreshold = (int) (mCallbackThreshold * 0.65f);
+ if (totalDeltaAngle >= fuzzyCallbackThreshold
+ || totalDeltaAngle <= -fuzzyCallbackThreshold) {
+
+ if (!useDirection) {
+ // Set ccw to match the direction found by getDelta
+ ccw = totalDeltaAngle > 0;
+ }
+
+ /*
+ * When the user slides the thumb through the tick that corresponds
+ * to a zoom bound, we don't want to abruptly stop there. Instead,
+ * let the user slide it to the next tick, and then animate it back
+ * to the original zoom bound tick. Because of this, we make sure
+ * the delta from the bound is more than halfway to the next tick.
+ * We make sure the bound is between the touch and the previous
+ * callback to ensure we just passed the bound.
+ */
+ int oldTouchAngle = touchAngle;
+ if (ccw && mThumbCcwBound != Integer.MIN_VALUE) {
+ int deltaCcwBoundAndTouch =
+ getDelta(mThumbCcwBound, touchAngle, useDirection, true);
+ if (deltaCcwBoundAndTouch >= mCallbackThreshold / 2) {
+ // The touch has past a bound
+ int deltaPreviousCbAndTouch = getDelta(mPreviousCallbackAngle,
+ touchAngle, useDirection, true);
+ if (deltaPreviousCbAndTouch >= deltaCcwBoundAndTouch) {
+ // The bound is between the previous callback angle and the touch
+ touchAngle = mThumbCcwBound;
+ // We're moving the touch BACK to the bound, so opposite direction
+ ccw = false;
+ }
+ }
+ } else if (!ccw && mThumbCwBound != Integer.MIN_VALUE) {
+ // See block above for general comments
+ int deltaCwBoundAndTouch =
+ getDelta(mThumbCwBound, touchAngle, useDirection, false);
+ if (deltaCwBoundAndTouch <= -mCallbackThreshold / 2) {
+ int deltaPreviousCbAndTouch = getDelta(mPreviousCallbackAngle,
+ touchAngle, useDirection, false);
+ /*
+ * Both of these will be negative since we got delta in
+ * clockwise direction, and we want the magnitude of
+ * deltaPreviousCbAndTouch to be greater than the magnitude
+ * of deltaCwBoundAndTouch
+ */
+ if (deltaPreviousCbAndTouch <= deltaCwBoundAndTouch) {
+ touchAngle = mThumbCwBound;
+ ccw = true;
+ }
+ }
+ }
+ if (touchAngle != oldTouchAngle) {
+ // We bounded the touch angle
+ totalDeltaAngle = getDelta(mPreviousCallbackAngle, touchAngle, useDirection, ccw);
+ animateThumbToNewAngle = true;
+ mMode = MODE_IGNORE_UNTIL_UP;
+ }
+
+
+ // Prevent it from jumping too far
+ if (mEnforceMaxAbsJump) {
+ if (totalDeltaAngle <= -MAX_ABS_JUMP_DELTA_ANGLE) {
+ totalDeltaAngle = -MAX_ABS_JUMP_DELTA_ANGLE;
+ animateThumbToNewAngle = true;
+ } else if (totalDeltaAngle >= MAX_ABS_JUMP_DELTA_ANGLE) {
+ totalDeltaAngle = MAX_ABS_JUMP_DELTA_ANGLE;
+ animateThumbToNewAngle = true;
}
}
- // Get the closest tick and lock on there
- mPreviousCallbackAngle = getClosestTickAngle(touchAngle);
+ /*
+ * We need to cover the edge case of a user grabbing the thumb,
+ * going into the center of the widget, and then coming out from the
+ * center to an angle that's slightly below the angle he's trying to
+ * hit. If we do int division, we'll end up with one level lower
+ * than the one he was going for.
+ */
+ int deltaLevels = Math.round((float) totalDeltaAngle / mCallbackThreshold);
+ if (deltaLevels != 0) {
+ boolean canStillZoom = mCallback.onZoomRingThumbDragged(
+ deltaLevels, mThumbDragStartAngle, touchAngle);
+
+ // TODO: we're trying the haptics to see how it goes with
+ // users, so we're ignoring the settings (for now)
+ performHapticFeedback(HapticFeedbackConstants.ZOOM_RING_TICK,
+ HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING |
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+
+ // Set the callback angle to the actual angle based on how many delta levels we gave
+ mPreviousCallbackAngle = getValidAngle(
+ mPreviousCallbackAngle + (deltaLevels * mCallbackThreshold));
+ }
}
- setThumbAngle(touchAngle);
- mIsThumbAngleValid = true;
+ int deltaAngle = getDelta(mThumbAngle, touchAngle, useDirection, ccw);
+ mAcculumalatedTrailAngle += Math.toDegrees(deltaAngle / (double) RADIAN_INT_MULTIPLIER);
+
+ if (animateThumbToNewAngle) {
+ if (useDirection) {
+ setThumbAngleAnimated(touchAngle, 0, ccw);
+ } else {
+ setThumbAngleAnimated(touchAngle, 0);
+ }
+ } else {
+ setThumbAngleAuto(touchAngle, useDirection, ccw);
+ }
+ }
+
+ private int getValidAngle(int invalidAngle) {
+ if (invalidAngle < 0) {
+ return (invalidAngle % TWO_PI_INT_MULTIPLIED) + TWO_PI_INT_MULTIPLIED;
+ } else if (invalidAngle >= TWO_PI_INT_MULTIPLIED) {
+ return invalidAngle % TWO_PI_INT_MULTIPLIED;
+ } else {
+ return invalidAngle;
+ }
}
private int getClosestTickAngle(int angle) {
@@ -403,12 +798,12 @@ public class ZoomRing extends View {
return smallerAngle;
} else {
// Closer to the bigger angle (premodding)
- return (smallerAngle + mCallbackThreshold) % (PI_INT_MULTIPLIED * 2);
+ return (smallerAngle + mCallbackThreshold) % TWO_PI_INT_MULTIPLIED;
}
}
- private void onThumbDragStopped(int stopAngle) {
- mCallback.onZoomRingThumbDraggingStopped(stopAngle);
+ private void onThumbDragStopped() {
+ mCallback.onZoomRingThumbDraggingStopped();
}
private void onZoomRingMoved(int x, int y) {
@@ -416,9 +811,7 @@ public class ZoomRing extends View {
int deltaX = x - mPreviousWidgetDragX;
int deltaY = y - mPreviousWidgetDragY;
- if (mCallback != null) {
- mCallback.onZoomRingMoved(deltaX, deltaY);
- }
+ mCallback.onZoomRingMoved(deltaX, deltaY);
}
mPreviousWidgetDragX = x;
@@ -429,11 +822,11 @@ public class ZoomRing extends View {
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
- if (!hasWindowFocus && mCallback != null) {
- mCallback.onZoomRingDismissed();
+ if (!hasWindowFocus) {
+ mCallback.onZoomRingDismissed(true);
}
}
-
+
private int getAngle(int localX, int localY) {
int radians = (int) (Math.atan2(localY, localX) * RADIAN_INT_MULTIPLIER);
@@ -458,45 +851,65 @@ public class ZoomRing extends View {
if (DRAW_TRAIL) {
mTrail.draw(canvas);
}
+
+ // If we aren't near the bounds, draw the corresponding arrows
+ int callbackAngle = mPreviousCallbackAngle;
+ if (callbackAngle < mThumbCwBound - RADIAN_INT_ERROR ||
+ callbackAngle > mThumbCwBound + RADIAN_INT_ERROR) {
+ mThumbPlusArrowDrawable.draw(canvas);
+ }
+ if (callbackAngle < mThumbCcwBound - RADIAN_INT_ERROR ||
+ callbackAngle > mThumbCcwBound + RADIAN_INT_ERROR) {
+ mThumbMinusArrowDrawable.draw(canvas);
+ }
mThumbDrawable.draw(canvas);
}
}
-
- private class Disabler implements Runnable {
- private static final int DELAY = 15;
- private static final float ENABLE_RATE = 1.05f;
- private static final float DISABLE_RATE = 0.95f;
-
- private int mAlpha = 255;
- private boolean mEnabling;
-
- public int getAlpha() {
- return mAlpha;
- }
-
- public void setEnabling(boolean enabling) {
- if ((enabling && mAlpha != 255) || (!enabling && mAlpha != DISABLED_ALPHA)) {
- mEnabling = enabling;
- post(this);
- }
+
+ private void setThumbArrowsAngle(int angle) {
+ int level = -angle * 10000 / ZoomRing.TWO_PI_INT_MULTIPLIED;
+ mThumbPlusArrowDrawable.setLevel(level);
+ mThumbMinusArrowDrawable.setLevel(level);
+ }
+
+ public void setThumbArrowsVisible(boolean visible) {
+ if (visible) {
+ mThumbArrowsAlpha = 255;
+ mThumbPlusArrowDrawable.setAlpha(255);
+ mThumbMinusArrowDrawable.setAlpha(255);
+ invalidate();
+ } else if (mThumbArrowsAlpha == 255) {
+ // Only start fade if we're fully visible (otherwise another fade is happening already)
+ mThumbArrowsFadeStartTime = SystemClock.elapsedRealtime();
+ onThumbArrowsFadeTick();
}
+ }
+
+ private void onThumbArrowsFadeTick() {
+ if (mThumbArrowsAlpha <= 0) return;
- public void run() {
- mAlpha *= mEnabling ? ENABLE_RATE : DISABLE_RATE;
- if (mAlpha < DISABLED_ALPHA) {
- mAlpha = DISABLED_ALPHA;
- } else if (mAlpha > 255) {
- mAlpha = 255;
- } else {
- // Still more to go
- postDelayed(this, DELAY);
- }
-
- getBackground().setAlpha(mAlpha);
- invalidate();
+ mThumbArrowsAlpha = (int)
+ (255 - (255 * (SystemClock.elapsedRealtime() - mThumbArrowsFadeStartTime)
+ / THUMB_ARROWS_FADE_DURATION));
+ if (mThumbArrowsAlpha < 0) mThumbArrowsAlpha = 0;
+ mThumbPlusArrowDrawable.setAlpha(mThumbArrowsAlpha);
+ mThumbMinusArrowDrawable.setAlpha(mThumbArrowsAlpha);
+ invalidateDrawable(mThumbPlusArrowDrawable);
+ invalidateDrawable(mThumbMinusArrowDrawable);
+
+ if (!mHandler.hasMessages(MSG_THUMB_ARROWS_FADE_TICK)) {
+ mHandler.sendEmptyMessage(MSG_THUMB_ARROWS_FADE_TICK);
}
}
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ setThumbArrowsAngle(mThumbAngle);
+ setThumbArrowsVisible(true);
+ }
+
public interface OnZoomRingCallback {
void onZoomRingSetMovableHintVisible(boolean visible);
@@ -504,11 +917,17 @@ public class ZoomRing extends View {
boolean onZoomRingMoved(int deltaX, int deltaY);
void onZoomRingMovingStopped();
- void onZoomRingThumbDraggingStarted(int startAngle);
+ void onZoomRingThumbDraggingStarted();
boolean onZoomRingThumbDragged(int numLevels, int startAngle, int curAngle);
- void onZoomRingThumbDraggingStopped(int endAngle);
+ void onZoomRingThumbDraggingStopped();
- void onZoomRingDismissed();
+ void onZoomRingDismissed(boolean dismissImmediately);
+
+ void onUserInteractionStarted();
+ void onUserInteractionStopped();
}
+ private static void printAngle(String angleName, int angle) {
+ Log.d(TAG, angleName + ": " + (long) angle * 180 / PI_INT_MULTIPLIED);
+ }
}
diff --git a/core/java/android/widget/ZoomRingController.java b/core/java/android/widget/ZoomRingController.java
index eb28767..31074b6 100644
--- a/core/java/android/widget/ZoomRingController.java
+++ b/core/java/android/widget/ZoomRingController.java
@@ -16,6 +16,8 @@
package android.widget;
+import android.app.AlertDialog;
+import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -27,7 +29,6 @@ import android.graphics.Rect;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
-import android.os.Vibrator;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
@@ -35,6 +36,7 @@ import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
+import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.animation.Animation;
@@ -46,12 +48,16 @@ import android.view.animation.DecelerateInterpolator;
/**
* TODO: Docs
*
+ * If you are using this with a custom View, please call
+ * {@link #setVisible(boolean) setVisible(false)} from the
+ * {@link View#onDetachedFromWindow}.
+ *
* @hide
*/
public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
View.OnTouchListener, View.OnKeyListener {
- private static final int SHOW_TUTORIAL_TOAST_DELAY = 1000;
+ private static final int ZOOM_RING_RADIUS_INSET = 10;
private static final int ZOOM_RING_RECENTERING_DURATION = 500;
@@ -69,9 +75,11 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
// TODO: scale px values based on latest from ViewConfiguration
private static final int SECOND_TAP_TIMEOUT = 500;
private static final int ZOOM_RING_DISMISS_DELAY = SECOND_TAP_TIMEOUT / 2;
- private static final int SECOND_TAP_SLOP = 70;
- private static final int SECOND_TAP_MOVE_SLOP = 15;
- private static final int MAX_PAN_GAP = 30;
+ // TODO: view config? at least scaled
+ private static final int MAX_PAN_GAP = 20;
+ private static final int MAX_INITIATE_PAN_GAP = 10;
+ // TODO view config
+ private static final int INITIATE_PAN_DELAY = 400;
private static final String SETTING_NAME_SHOWN_TOAST = "shown_zoom_ring_toast";
@@ -95,6 +103,23 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
private FrameLayout mContainer;
private LayoutParams mContainerLayoutParams;
+ /**
+ * The view (or null) that should receive touch events. This will get set if
+ * the touch down hits the container. It will be reset on the touch up.
+ */
+ private View mTouchTargetView;
+ /**
+ * The {@link #mTouchTargetView}'s location in window, set on touch down.
+ */
+ private int[] mTouchTargetLocationInWindow = new int[2];
+ /**
+ * If the zoom ring is dismissed but the user is still in a touch
+ * interaction, we set this to true. This will ignore all touch events until
+ * up/cancel, and then set the owner's touch listener to null.
+ */
+ private boolean mReleaseTouchListenerOnUp;
+
+
/*
* Tap-drag is an interaction where the user first taps and then (quickly)
* does the clockwise or counter-clockwise drag. In reality, this is: (down,
@@ -122,6 +147,8 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
/** Invokes panning of owner view if the zoom ring is touching an edge. */
private Panner mPanner = new Panner();
+ private long mTouchingEdgeStartTime;
+ private boolean mPanningEnabledForThisInteraction;
private ImageView mPanningArrows;
private Animation mPanningArrowsEnterAnimation;
@@ -162,26 +189,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
* the UI thread so it will be exceuted AFTER the layout. This is the logic.
*/
private Runnable mPostedVisibleInitializer;
-
- // TODO: need a better way to persist this value, becuase right now this
- // requires the WRITE_SETTINGS perimssion which the app may not have
-// private Runnable mShowTutorialToast = new Runnable() {
-// public void run() {
-// if (Settings.System.getInt(mContext.getContentResolver(),
-// SETTING_NAME_SHOWN_TOAST, 0) == 1) {
-// return;
-// }
-// try {
-// Settings.System.putInt(mContext.getContentResolver(), SETTING_NAME_SHOWN_TOAST, 1);
-// } catch (SecurityException e) {
-// // The app does not have permission to clear this flag, oh well!
-// }
-//
-// Toast.makeText(mContext,
-// com.android.internal.R.string.tutorial_double_tap_to_zoom_message,
-// Toast.LENGTH_LONG).show();
-// }
-// };
+
+ /**
+ * Only touch from the main thread.
+ */
+ private static Dialog sTutorialDialog;
+ private static long sTutorialShowTime;
+ private static final int TUTORIAL_MIN_DISPLAY_TIME = 2000;
private IntentFilter mConfigurationChangedFilter =
new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED);
@@ -230,38 +244,37 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mOwnerView = ownerView;
mZoomRing = new ZoomRing(context);
+ mZoomRing.setId(com.android.internal.R.id.zoomControls);
mZoomRing.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
- FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
+ FrameLayout.LayoutParams.WRAP_CONTENT,
+ Gravity.CENTER));
mZoomRing.setCallback(this);
createPanningArrows();
- mContainer = new FrameLayout(context);
- mContainer.setMeasureAllChildren(true);
- mContainer.setOnTouchListener(this);
-
- mContainer.addView(mZoomRing);
- mContainer.addView(mPanningArrows);
- mContainer.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
-
mContainerLayoutParams = new LayoutParams();
mContainerLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
- mContainerLayoutParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL |
+ mContainerLayoutParams.flags = LayoutParams.FLAG_NOT_TOUCHABLE |
LayoutParams.FLAG_NOT_FOCUSABLE |
- LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+ LayoutParams.FLAG_LAYOUT_NO_LIMITS;
mContainerLayoutParams.height = LayoutParams.WRAP_CONTENT;
mContainerLayoutParams.width = LayoutParams.WRAP_CONTENT;
mContainerLayoutParams.type = LayoutParams.TYPE_APPLICATION_PANEL;
- mContainerLayoutParams.format = PixelFormat.TRANSLUCENT;
+ mContainerLayoutParams.format = PixelFormat.TRANSPARENT;
// TODO: make a new animation for this
mContainerLayoutParams.windowAnimations = com.android.internal.R.style.Animation_Dialog;
+
+ mContainer = new FrameLayout(context);
+ mContainer.setLayoutParams(mContainerLayoutParams);
+ mContainer.setMeasureAllChildren(true);
+
+ mContainer.addView(mZoomRing);
+ mContainer.addView(mPanningArrows);
mScroller = new Scroller(context, new DecelerateInterpolator());
mViewConfig = ViewConfiguration.get(context);
-
-// mHandler.postDelayed(mShowTutorialToast, SHOW_TUTORIAL_TOAST_DELAY);
}
private void createPanningArrows() {
@@ -272,7 +285,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER));
- mPanningArrows.setVisibility(View.GONE);
+ mPanningArrows.setVisibility(View.INVISIBLE);
mPanningArrowsEnterAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.fade_in);
@@ -291,6 +304,17 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
public void setZoomCallbackThreshold(float callbackThreshold) {
mZoomRing.setCallbackThreshold((int) (callbackThreshold * ZoomRing.RADIAN_INT_MULTIPLIER));
}
+
+ /**
+ * Sets a drawable for the zoom ring track.
+ *
+ * @param drawable The drawable to use for the track.
+ * @hide Need a better way of doing this, but this one-off for browser so it
+ * can have its final look for the usability study
+ */
+ public void setZoomRingTrack(int drawable) {
+ mZoomRing.setBackgroundResource(drawable);
+ }
public void setCallback(OnZoomListener callback) {
mCallback = callback;
@@ -300,10 +324,26 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mZoomRing.setThumbAngle((int) (angle * ZoomRing.RADIAN_INT_MULTIPLIER));
}
+ public void setThumbAngleAnimated(float angle) {
+ mZoomRing.setThumbAngleAnimated((int) (angle * ZoomRing.RADIAN_INT_MULTIPLIER), 0);
+ }
+
public void setResetThumbAutomatically(boolean resetThumbAutomatically) {
mZoomRing.setResetThumbAutomatically(resetThumbAutomatically);
}
+ public void setThumbClockwiseBound(float angle) {
+ mZoomRing.setThumbClockwiseBound(angle >= 0 ?
+ (int) (angle * ZoomRing.RADIAN_INT_MULTIPLIER) :
+ Integer.MIN_VALUE);
+ }
+
+ public void setThumbCounterclockwiseBound(float angle) {
+ mZoomRing.setThumbCounterclockwiseBound(angle >= 0 ?
+ (int) (angle * ZoomRing.RADIAN_INT_MULTIPLIER) :
+ Integer.MIN_VALUE);
+ }
+
public boolean isVisible() {
return mIsZoomRingVisible;
}
@@ -321,12 +361,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
if (mIsZoomRingVisible == visible) {
return;
}
+ mIsZoomRingVisible = visible;
if (visible) {
if (mContainerLayoutParams.token == null) {
mContainerLayoutParams.token = mOwnerView.getWindowToken();
}
-
+
mWindowManager.addView(mContainer, mContainerLayoutParams);
if (mPostedVisibleInitializer == null) {
@@ -340,6 +381,10 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
// probably can only be retrieved after it's measured, which happens
// after it's added).
mWindowManager.updateViewLayout(mContainer, mContainerLayoutParams);
+
+ if (mCallback != null) {
+ mCallback.onVisibilityChanged(true);
+ }
}
};
}
@@ -349,24 +394,49 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
// Handle configuration changes when visible
mContext.registerReceiver(mConfigurationChangedReceiver, mConfigurationChangedFilter);
- // Steal key events from the owner
+ // Steal key/touches events from the owner
mOwnerView.setOnKeyListener(this);
+ mOwnerView.setOnTouchListener(this);
+ mReleaseTouchListenerOnUp = false;
} else {
- // Don't want to steal any more keys
+ // Don't want to steal any more keys/touches
mOwnerView.setOnKeyListener(null);
+ if (mTouchTargetView != null) {
+ // We are still stealing the touch events for this touch
+ // sequence, so release the touch listener later
+ mReleaseTouchListenerOnUp = true;
+ } else {
+ mOwnerView.setOnTouchListener(null);
+ }
// No longer care about configuration changes
mContext.unregisterReceiver(mConfigurationChangedReceiver);
mWindowManager.removeView(mContainer);
- }
-
- mIsZoomRingVisible = visible;
- if (mCallback != null) {
- mCallback.onVisibilityChanged(visible);
+ if (mCallback != null) {
+ mCallback.onVisibilityChanged(false);
+ }
}
+
+ }
+
+ /**
+ * TODO: docs
+ *
+ * Notes:
+ * - Touch dispatching is different. Only direct children who are clickable are eligble for touch events.
+ * - Please ensure you set your View to INVISIBLE not GONE when hiding it.
+ *
+ * @return
+ */
+ public FrameLayout getContainer() {
+ return mContainer;
+ }
+
+ public int getZoomRingId() {
+ return mZoomRing.getId();
}
private void dismissZoomRingDelayed(int delay) {
@@ -484,77 +554,8 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mOwnerViewBounds, mTempRect);
mCenteredContainerX = mTempRect.left;
mCenteredContainerY = mTempRect.top;
-
}
- // MOVE ALL THIS TO GESTURE DETECTOR
-// public boolean onTouch(View v, MotionEvent event) {
-// int action = event.getAction();
-//
-// if (mListenForInvocation) {
-// switch (mTouchMode) {
-// case TOUCH_MODE_IDLE: {
-// if (action == MotionEvent.ACTION_DOWN) {
-// setFirstTap(event);
-// }
-// break;
-// }
-//
-// case TOUCH_MODE_WAITING_FOR_SECOND_TAP: {
-// switch (action) {
-// case MotionEvent.ACTION_DOWN:
-// if (isSecondTapWithinSlop(event)) {
-// handleDoubleTapEvent(event);
-// } else {
-// setFirstTap(event);
-// }
-// break;
-//
-// case MotionEvent.ACTION_MOVE:
-// int deltaX = (int) event.getX() - mFirstTapX;
-// if (deltaX < -SECOND_TAP_MOVE_SLOP ||
-// deltaX > SECOND_TAP_MOVE_SLOP) {
-// mTouchMode = TOUCH_MODE_IDLE;
-// } else {
-// int deltaY = (int) event.getY() - mFirstTapY;
-// if (deltaY < -SECOND_TAP_MOVE_SLOP ||
-// deltaY > SECOND_TAP_MOVE_SLOP) {
-// mTouchMode = TOUCH_MODE_IDLE;
-// }
-// }
-// break;
-// }
-// break;
-// }
-//
-// case TOUCH_MODE_WAITING_FOR_TAP_DRAG_MOVEMENT:
-// case TOUCH_MODE_FORWARDING_FOR_TAP_DRAG: {
-// handleDoubleTapEvent(event);
-// break;
-// }
-// }
-//
-// if (action == MotionEvent.ACTION_CANCEL) {
-// mTouchMode = TOUCH_MODE_IDLE;
-// }
-// }
-//
-// return false;
-// }
-//
-// private void setFirstTap(MotionEvent event) {
-// mFirstTapTime = event.getEventTime();
-// mFirstTapX = (int) event.getX();
-// mFirstTapY = (int) event.getY();
-// mTouchMode = TOUCH_MODE_WAITING_FOR_SECOND_TAP;
-// }
-//
-// private boolean isSecondTapWithinSlop(MotionEvent event) {
-// return mFirstTapTime + SECOND_TAP_TIMEOUT > event.getEventTime() &&
-// Math.abs((int) event.getX() - mFirstTapX) < SECOND_TAP_SLOP &&
-// Math.abs((int) event.getY() - mFirstTapY) < SECOND_TAP_SLOP;
-// }
-
/**
* Centers the point (in owner view's coordinates).
*/
@@ -575,16 +576,28 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
public void onZoomRingSetMovableHintVisible(boolean visible) {
setPanningArrowsVisible(visible);
}
+
+ public void onUserInteractionStarted() {
+ mHandler.removeMessages(MSG_DISMISS_ZOOM_RING);
+ }
+
+ public void onUserInteractionStopped() {
+ dismissZoomRingDelayed(ZOOM_CONTROLS_TIMEOUT);
+ }
public void onZoomRingMovingStarted() {
- mHandler.removeMessages(MSG_DISMISS_ZOOM_RING);
mScroller.abortAnimation();
+ mPanningEnabledForThisInteraction = false;
+ mTouchingEdgeStartTime = 0;
+ if (mCallback != null) {
+ mCallback.onBeginPan();
+ }
}
private void setPanningArrowsVisible(boolean visible) {
mPanningArrows.startAnimation(visible ? mPanningArrowsEnterAnimation
: mPanningArrowsExitAnimation);
- mPanningArrows.setVisibility(visible ? View.VISIBLE : View.GONE);
+ mPanningArrows.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
}
public boolean onZoomRingMoved(int deltaX, int deltaY) {
@@ -611,37 +624,73 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mWindowManager.updateViewLayout(mContainer, lp);
// Check for pan
+ boolean horizontalPanning = true;
int leftGap = newZoomRingX - ownerBounds.left;
if (leftGap < MAX_PAN_GAP) {
- mPanner.setHorizontalStrength(-getStrengthFromGap(leftGap));
+ if (shouldPan(leftGap)) {
+ mPanner.setHorizontalStrength(-getStrengthFromGap(leftGap));
+ }
} else {
int rightGap = ownerBounds.right - (lp.x + mZoomRingWidth + zoomRingLeft);
if (rightGap < MAX_PAN_GAP) {
- mPanner.setHorizontalStrength(getStrengthFromGap(rightGap));
+ if (shouldPan(rightGap)) {
+ mPanner.setHorizontalStrength(getStrengthFromGap(rightGap));
+ }
} else {
mPanner.setHorizontalStrength(0);
+ horizontalPanning = false;
}
}
int topGap = newZoomRingY - ownerBounds.top;
if (topGap < MAX_PAN_GAP) {
- mPanner.setVerticalStrength(-getStrengthFromGap(topGap));
+ if (shouldPan(topGap)) {
+ mPanner.setVerticalStrength(-getStrengthFromGap(topGap));
+ }
} else {
int bottomGap = ownerBounds.bottom - (lp.y + mZoomRingHeight + zoomRingTop);
if (bottomGap < MAX_PAN_GAP) {
- mPanner.setVerticalStrength(getStrengthFromGap(bottomGap));
+ if (shouldPan(bottomGap)) {
+ mPanner.setVerticalStrength(getStrengthFromGap(bottomGap));
+ }
} else {
mPanner.setVerticalStrength(0);
+ if (!horizontalPanning) {
+ // Neither are panning, reset any timer to start pan mode
+ mTouchingEdgeStartTime = 0;
+ }
}
}
return true;
}
+ private boolean shouldPan(int gap) {
+ if (mPanningEnabledForThisInteraction) return true;
+
+ if (gap < MAX_INITIATE_PAN_GAP) {
+ long time = SystemClock.elapsedRealtime();
+ if (mTouchingEdgeStartTime != 0 &&
+ mTouchingEdgeStartTime + INITIATE_PAN_DELAY < time) {
+ mPanningEnabledForThisInteraction = true;
+ return true;
+ } else if (mTouchingEdgeStartTime == 0) {
+ mTouchingEdgeStartTime = time;
+ } else {
+ }
+ } else {
+ // Moved away from the initiate pan gap, so reset the timer
+ mTouchingEdgeStartTime = 0;
+ }
+ return false;
+ }
+
public void onZoomRingMovingStopped() {
- dismissZoomRingDelayed(ZOOM_CONTROLS_TIMEOUT);
mPanner.stop();
- setPanningArrowsVisible(false);
+ setPanningArrowsVisible(false);
+ if (mCallback != null) {
+ mCallback.onEndPan();
+ }
}
private int getStrengthFromGap(int gap) {
@@ -649,10 +698,9 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
(MAX_PAN_GAP - gap) * 100 / MAX_PAN_GAP;
}
- public void onZoomRingThumbDraggingStarted(int startAngle) {
- mHandler.removeMessages(MSG_DISMISS_ZOOM_RING);
+ public void onZoomRingThumbDraggingStarted() {
if (mCallback != null) {
- mCallback.onBeginDrag((float) startAngle / ZoomRing.RADIAN_INT_MULTIPLIER);
+ mCallback.onBeginDrag();
}
}
@@ -674,25 +722,122 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
return false;
}
- public void onZoomRingThumbDraggingStopped(int endAngle) {
- dismissZoomRingDelayed(ZOOM_CONTROLS_TIMEOUT);
+ public void onZoomRingThumbDraggingStopped() {
if (mCallback != null) {
- mCallback.onEndDrag((float) endAngle / ZoomRing.RADIAN_INT_MULTIPLIER);
+ mCallback.onEndDrag();
}
}
- public void onZoomRingDismissed() {
- dismissZoomRingDelayed(ZOOM_RING_DISMISS_DELAY);
+ public void onZoomRingDismissed(boolean dismissImmediately) {
+ if (dismissImmediately) {
+ mHandler.removeMessages(MSG_DISMISS_ZOOM_RING);
+ setVisible(false);
+ } else {
+ dismissZoomRingDelayed(ZOOM_RING_DISMISS_DELAY);
+ }
}
-
+
+ public void onRingDown(int tickAngle, int touchAngle) {
+ }
+
public boolean onTouch(View v, MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
- // If the user touches outside of the zoom ring, dismiss the zoom ring
- dismissZoomRingDelayed(ZOOM_RING_DISMISS_DELAY);
+ if (sTutorialDialog != null && sTutorialDialog.isShowing() &&
+ SystemClock.elapsedRealtime() - sTutorialShowTime >= TUTORIAL_MIN_DISPLAY_TIME) {
+ finishZoomTutorial();
+ }
+
+ int action = event.getAction();
+
+ if (mReleaseTouchListenerOnUp) {
+ // The ring was dismissed but we need to throw away all events until the up
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ mOwnerView.setOnTouchListener(null);
+ mReleaseTouchListenerOnUp = false;
+ }
+
+ // Eat this event
return true;
}
- return false;
+ View targetView = mTouchTargetView;
+
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ targetView = mTouchTargetView =
+ getViewForTouch((int) event.getRawX(), (int) event.getRawY());
+ if (targetView != null) {
+ targetView.getLocationInWindow(mTouchTargetLocationInWindow);
+ }
+ break;
+
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mTouchTargetView = null;
+ break;
+ }
+
+ if (targetView != null) {
+ // The upperleft corner of the target view in raw coordinates
+ int targetViewRawX = mContainerLayoutParams.x + mTouchTargetLocationInWindow[0];
+ int targetViewRawY = mContainerLayoutParams.y + mTouchTargetLocationInWindow[1];
+
+ MotionEvent containerEvent = MotionEvent.obtain(event);
+ // Convert the motion event into the target view's coordinates (from
+ // owner view's coordinates)
+ containerEvent.offsetLocation(mOwnerViewBounds.left - targetViewRawX,
+ mOwnerViewBounds.top - targetViewRawY);
+ boolean retValue = targetView.dispatchTouchEvent(containerEvent);
+ containerEvent.recycle();
+ return retValue;
+
+ } else {
+ if (action == MotionEvent.ACTION_DOWN) {
+ dismissZoomRingDelayed(ZOOM_RING_DISMISS_DELAY);
+ }
+
+ return false;
+ }
+ }
+
+ /**
+ * Returns the View that should receive a touch at the given coordinates.
+ *
+ * @param rawX The raw X.
+ * @param rawY The raw Y.
+ * @return The view that should receive the touches, or null if there is not one.
+ */
+ private View getViewForTouch(int rawX, int rawY) {
+ // Check to see if it is touching the ring
+ int containerCenterX = mContainerLayoutParams.x + mContainer.getWidth() / 2;
+ int containerCenterY = mContainerLayoutParams.y + mContainer.getHeight() / 2;
+ int distanceFromCenterX = rawX - containerCenterX;
+ int distanceFromCenterY = rawY - containerCenterY;
+ int zoomRingRadius = mZoomRingWidth / 2 - ZOOM_RING_RADIUS_INSET;
+ if (distanceFromCenterX * distanceFromCenterX +
+ distanceFromCenterY * distanceFromCenterY <=
+ zoomRingRadius * zoomRingRadius) {
+ return mZoomRing;
+ }
+
+ // Check to see if it is touching any other clickable View.
+ // Reverse order so the child drawn on top gets first dibs.
+ int containerCoordsX = rawX - mContainerLayoutParams.x;
+ int containerCoordsY = rawY - mContainerLayoutParams.y;
+ Rect frame = mTempRect;
+ for (int i = mContainer.getChildCount() - 1; i >= 0; i--) {
+ View child = mContainer.getChildAt(i);
+ if (child == mZoomRing || child.getVisibility() != View.VISIBLE ||
+ !child.isClickable()) {
+ continue;
+ }
+
+ child.getHitRect(frame);
+ if (frame.contains(containerCoordsX, containerCoordsY)) {
+ return child;
+ }
+ }
+
+ return null;
}
/** Steals key events from the owner view. */
@@ -707,6 +852,8 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
case KeyEvent.KEYCODE_DPAD_DOWN:
// Keep the zoom alive a little longer
dismissZoomRingDelayed(ZOOM_CONTROLS_TIMEOUT);
+ // They started zooming, hide the thumb arrows
+ mZoomRing.setThumbArrowsVisible(false);
if (mCallback != null && event.getAction() == KeyEvent.ACTION_DOWN) {
mCallback.onSimpleZoom(keyCode == KeyEvent.KEYCODE_DPAD_UP);
@@ -734,9 +881,14 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
ensureZoomRingIsCentered();
}
+ /*
+ * This is static so Activities can call this instead of the Views
+ * (Activities usually do not have a reference to the ZoomRingController
+ * instance.)
+ */
/**
* Shows a "tutorial" (some text) to the user teaching her the new zoom
- * invocation method.
+ * invocation method. Must call from the main thread.
* <p>
* It checks the global system setting to ensure this has not been seen
* before. Furthermore, if the application does not have privilege to write
@@ -757,20 +909,45 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
return;
}
+ if (sTutorialDialog != null && sTutorialDialog.isShowing()) {
+ sTutorialDialog.dismiss();
+ }
+
+ sTutorialDialog = new AlertDialog.Builder(context)
+ .setMessage(
+ com.android.internal.R.string.tutorial_double_tap_to_zoom_message_short)
+ .setIcon(0)
+ .create();
+
+ Window window = sTutorialDialog.getWindow();
+ window.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
+ window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND |
+ WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+ window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
+ WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
+
+ sTutorialDialog.show();
+ sTutorialShowTime = SystemClock.elapsedRealtime();
+ }
+
+ public void finishZoomTutorial() {
+ if (sTutorialDialog == null) return;
+
+ sTutorialDialog.dismiss();
+ sTutorialDialog = null;
+
+ // Record that they have seen the tutorial
try {
- Settings.System.putInt(cr, SETTING_NAME_SHOWN_TOAST, 1);
+ Settings.System.putInt(mContext.getContentResolver(), SETTING_NAME_SHOWN_TOAST, 1);
} catch (SecurityException e) {
/*
* The app does not have permission to clear this global flag, make
* sure the user does not see the message when he comes back to this
* same app at least.
*/
+ SharedPreferences sp = mContext.getSharedPreferences("_zoom", Context.MODE_PRIVATE);
sp.edit().putInt(SETTING_NAME_SHOWN_TOAST, 1).commit();
}
-
- Toast.makeText(context,
- com.android.internal.R.string.tutorial_double_tap_to_zoom_message_short,
- Toast.LENGTH_LONG).show();
}
private class Panner implements Runnable {
@@ -861,12 +1038,14 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
}
public interface OnZoomListener {
- void onBeginDrag(float startAngle);
+ void onBeginDrag();
boolean onDragZoom(int deltaZoomLevel, int centerX, int centerY, float startAngle,
float curAngle);
- void onEndDrag(float endAngle);
+ void onEndDrag();
void onSimpleZoom(boolean deltaZoomLevel);
+ void onBeginPan();
boolean onPan(int deltaX, int deltaY);
+ void onEndPan();
void onCenter(int x, int y);
void onVisibilityChanged(boolean visible);
}
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index eb232c7..b502a6c 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -19,13 +19,11 @@ package com.android.internal.app;
import com.android.internal.os.BatteryStatsImpl;
interface IBatteryStats {
- BatteryStatsImpl getStatistics();
+ byte[] getStatistics();
void noteStartWakelock(int uid, String name, int type);
void noteStopWakelock(int uid, String name, int type);
- void noteStartSensor(int uid, String name, int sensor);
- void noteStopSensor(int uid, String name, int sensor);
- void noteRequestGpsOn(int uid);
- void noteRequestGpsOff(int uid);
+ void noteStartSensor(int uid, int sensor);
+ void noteStopSensor(int uid, int sensor);
void noteStartGps(int uid);
void noteStopGps(int uid);
void noteScreenOn();
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index cbb65dc..558a122 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -31,7 +31,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
/**
@@ -39,7 +38,7 @@ import java.util.Map;
* battery life. All times are represented in microseconds except where indicated
* otherwise.
*/
-public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
+public final class BatteryStatsImpl extends BatteryStats {
private static final String TAG = "BatteryStatsImpl";
@@ -47,7 +46,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 15;
+ private static final int VERSION = 23;
private final File mFile;
private final File mBackupFile;
@@ -65,8 +64,13 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
final ArrayList<Timer> mPartialTimers = new ArrayList<Timer>();
final ArrayList<Timer> mFullTimers = new ArrayList<Timer>();
final ArrayList<Timer> mWindowTimers = new ArrayList<Timer>();
- final ArrayList<Timer> mSensorTimers = new ArrayList<Timer>();
+ final SparseArray<ArrayList<Timer>> mSensorTimers
+ = new SparseArray<ArrayList<Timer>>();
+ // These are the objects that will want to do something when the device
+ // is unplugged from power.
+ final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
+
int mStartCount;
long mBatteryUptime;
@@ -90,6 +94,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
* in to power.
*/
boolean mOnBattery;
+ boolean mOnBatteryInternal;
long mTrackBatteryPastUptime;
long mTrackBatteryUptimeStart;
long mTrackBatteryPastRealtime;
@@ -98,8 +103,6 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
long mUnpluggedBatteryUptime;
long mUnpluggedBatteryRealtime;
- HashSet<Integer> mGpsRequesters = new HashSet<Integer>();
-
long mLastWriteTime = 0; // Milliseconds
// For debugging
@@ -107,87 +110,100 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
mFile = mBackupFile = null;
}
+ public static interface Unpluggable {
+ void unplug(long batteryUptime, long batteryRealtime);
+ void plug(long batteryUptime, long batteryRealtime);
+ }
+
/**
* State for keeping track of timing information.
*/
- public static final class Timer extends BatteryStats.Timer {
- ArrayList<Timer> mTimerPool;
+ public static final class Timer extends BatteryStats.Timer implements Unpluggable {
+ final int mType;
+ final ArrayList<Timer> mTimerPool;
- int mType;
int mNesting;
int mCount;
int mLoadedCount;
int mLastCount;
+ int mUnpluggedCount;
- // Times are in microseconds for better accuracy when dividing by the lock count
+ // Times are in microseconds for better accuracy when dividing by the
+ // lock count, and are in "battery realtime" units.
- long mTotalTime; // Add mUnpluggedTotalTime to get true value
+ long mTotalTime;
long mLoadedTotalTime;
long mLastTotalTime;
- long mStartTime;
long mUpdateTime;
/**
* The value of mTotalTime when unplug() was last called, initially 0.
*/
- long mTotalTimeAtLastUnplug;
+ long mUnpluggedTotalTime;
- /** Constructor used for unmarshalling only. */
- Timer() {}
+ Timer(int type, ArrayList<Timer> timerPool,
+ ArrayList<Unpluggable> unpluggables, Parcel in) {
+ mType = type;
+ mTimerPool = timerPool;
+ mCount = in.readInt();
+ mLoadedCount = in.readInt();
+ mLastCount = in.readInt();
+ mUnpluggedCount = in.readInt();
+ mTotalTime = in.readLong();
+ mLoadedTotalTime = in.readLong();
+ mLastTotalTime = in.readLong();
+ mUpdateTime = in.readLong();
+ mUnpluggedTotalTime = in.readLong();
+ unpluggables.add(this);
+ }
- Timer(int type, ArrayList<Timer> timerPool) {
+ Timer(int type, ArrayList<Timer> timerPool,
+ ArrayList<Unpluggable> unpluggables) {
mType = type;
mTimerPool = timerPool;
+ unpluggables.add(this);
}
- public void writeToParcel(Parcel out) {
- out.writeInt(mType);
- out.writeInt(mNesting);
+ public void writeToParcel(Parcel out, long batteryRealtime) {
out.writeInt(mCount);
out.writeInt(mLoadedCount);
out.writeInt(mLastCount);
- out.writeLong(mTotalTime);
+ out.writeInt(mUnpluggedCount);
+ out.writeLong(computeRunTimeLocked(batteryRealtime));
out.writeLong(mLoadedTotalTime);
out.writeLong(mLastTotalTime);
- out.writeLong(mStartTime);
out.writeLong(mUpdateTime);
- out.writeLong(mTotalTimeAtLastUnplug);
+ out.writeLong(mUnpluggedTotalTime);
}
- public void readFromParcel(Parcel in) {
- mType = in.readInt();
- mNesting = in.readInt();
- mCount = in.readInt();
- mLoadedCount = in.readInt();
- mLastCount = in.readInt();
- mTotalTime = in.readLong();
- mLoadedTotalTime = in.readLong();
- mLastTotalTime = in.readLong();
- mStartTime = in.readLong();
- mUpdateTime = in.readLong();
- mTotalTimeAtLastUnplug = in.readLong();
- }
-
- private void unplug() {
- mTotalTimeAtLastUnplug += mTotalTime;
- mTotalTime = 0;
+ public void unplug(long batteryUptime, long batteryRealtime) {
+ mUnpluggedTotalTime = computeRunTimeLocked(batteryRealtime);
+ mUnpluggedCount = mCount;
}
+ public void plug(long batteryUptime, long batteryRealtime) {
+ if (mNesting > 0) {
+ mTotalTime = computeRunTimeLocked(batteryRealtime);
+ mUpdateTime = batteryRealtime;
+ }
+ }
+
/**
* Writes a possibly null Timer to a Parcel.
*
* @param out the Parcel to be written to.
* @param timer a Timer, or null.
*/
- public static void writeTimerToParcel(Parcel out, Timer timer) {
+ public static void writeTimerToParcel(Parcel out, Timer timer,
+ long batteryRealtime) {
if (timer == null) {
out.writeInt(0); // indicates null
return;
}
out.writeInt(1); // indicates non-null
- timer.writeToParcel(out);
+ timer.writeToParcel(out, batteryRealtime);
}
@Override
@@ -197,10 +213,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
val = mLastTotalTime;
} else {
val = computeRunTimeLocked(now);
- if (which != STATS_UNPLUGGED) {
- val += mTotalTimeAtLastUnplug;
- }
- if ((which == STATS_CURRENT) || (which == STATS_UNPLUGGED)) {
+ if (which == STATS_UNPLUGGED) {
+ val -= mUnpluggedTotalTime;
+ } else if (which != STATS_TOTAL) {
val -= mLoadedTotalTime;
}
}
@@ -215,7 +230,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
val = mLastCount;
} else {
val = mCount;
- if ((which == STATS_CURRENT) || (which == STATS_UNPLUGGED)) {
+ if (which == STATS_UNPLUGGED) {
+ val -= mUnpluggedCount;
+ } else if (which != STATS_TOTAL) {
val -= mLoadedCount;
}
}
@@ -223,12 +240,23 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
return val;
}
+ public void logState() {
+ Log.i("foo", "mNesting=" + mNesting + " mCount=" + mCount
+ + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
+ + " mUnpluggedCount=" + mUnpluggedCount);
+ Log.i("foo", "mTotalTime=" + mTotalTime
+ + " mLoadedTotalTime=" + mLoadedTotalTime);
+ Log.i("foo", "mLastTotalTime=" + mLastTotalTime
+ + " mUpdateTime=" + mUpdateTime);
+ }
+
void startRunningLocked(BatteryStatsImpl stats) {
if (mNesting++ == 0) {
- mStartTime = mUpdateTime =
- stats.getBatteryUptimeLocked(SystemClock.elapsedRealtime() * 1000);
- // Accumulate time to all other active counters with the current value of mCount
- refreshTimersLocked(stats);
+ mUpdateTime = stats.getBatteryRealtimeLocked(
+ SystemClock.elapsedRealtime() * 1000);
+ // Accumulate time to all currently active timers before adding
+ // this new one to the pool.
+ refreshTimersLocked(stats, mTimerPool);
// Add this timer to the active pool
mTimerPool.add(this);
// Increment the count
@@ -242,38 +270,34 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
return;
}
if (--mNesting == 0) {
- // Accumulate time to all active counters with the current value of mCount
- refreshTimersLocked(stats);
+ // Accumulate time to all active counters, scaled by the total
+ // active in the pool, before taking this one out of the pool.
+ refreshTimersLocked(stats, mTimerPool);
// Remove this timer from the active pool
mTimerPool.remove(this);
- // Decrement the count
- mCount--;
}
}
// Update the total time for all other running Timers with the same type as this Timer
// due to a change in timer count
- private void refreshTimersLocked(BatteryStatsImpl stats) {
- for (Timer t : mTimerPool) {
- t.updateTimeLocked(stats);
- }
- }
-
- /**
- * Update totalTime and reset updateTime
- * @param stats
- */
- private void updateTimeLocked(BatteryStatsImpl stats) {
- long realtime = SystemClock.elapsedRealtime() * 1000;
- long heldTime = stats.getBatteryUptimeLocked(realtime) - mUpdateTime;
- if (heldTime > 0) {
- mTotalTime += heldTime / mCount;
+ private static void refreshTimersLocked(final BatteryStatsImpl stats,
+ final ArrayList<Timer> pool) {
+ final long realtime = SystemClock.elapsedRealtime() * 1000;
+ final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
+ final int N = pool.size();
+ for (int i=N-1; i>= 0; i--) {
+ final Timer t = pool.get(i);
+ long heldTime = batteryRealtime - t.mUpdateTime;
+ if (heldTime > 0) {
+ t.mTotalTime += heldTime / N;
+ }
+ t.mUpdateTime = batteryRealtime;
}
- mUpdateTime = stats.getBatteryUptimeLocked(realtime);
}
- private long computeRunTimeLocked(long curBatteryUptime) {
- return mTotalTime + (mNesting > 0 ? (curBatteryUptime - mUpdateTime) / mCount : 0);
+ private long computeRunTimeLocked(long curBatteryRealtime) {
+ return mTotalTime + (mNesting > 0
+ ? (curBatteryRealtime - mUpdateTime) / mTimerPool.size() : 0);
}
void writeSummaryFromParcelLocked(Parcel out, long curBatteryUptime) {
@@ -295,53 +319,41 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
}
}
- public void unplugTcpCounters() {
- final int NU = mUidStats.size();
- for (int iu = 0; iu < NU; iu++) {
+ public void doUnplug(long batteryUptime, long batteryRealtime) {
+ for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
Uid u = mUidStats.valueAt(iu);
- u.mTcpBytesReceivedAtLastUnplug = u.getTcpBytesReceived(STATS_TOTAL);
- u.mTcpBytesSentAtLastUnplug = u.getTcpBytesSent(STATS_TOTAL);
+ u.mStartedTcpBytesReceived = NetStat.getUidRxBytes(u.mUid);
+ u.mStartedTcpBytesSent = NetStat.getUidTxBytes(u.mUid);
+ u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
+ u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
+ }
+ for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
+ mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
}
}
- public void unplugTimers() {
- ArrayList<Timer> timers;
-
- timers = mPartialTimers;
- for (int i = timers.size() - 1; i >= 0; i--) {
- timers.get(i).unplug();
- }
- timers = mFullTimers;
- for (int i = timers.size() - 1; i >= 0; i--) {
- timers.get(i).unplug();
- }
- timers = mWindowTimers;
- for (int i = timers.size() - 1; i >= 0; i--) {
- timers.get(i).unplug();
+ public void doPlug(long batteryUptime, long batteryRealtime) {
+ for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
+ Uid u = mUidStats.valueAt(iu);
+ if (u.mStartedTcpBytesReceived >= 0) {
+ u.mCurrentTcpBytesReceived = u.computeCurrentTcpBytesReceived();
+ u.mStartedTcpBytesReceived = -1;
+ }
+ if (u.mStartedTcpBytesSent >= 0) {
+ u.mCurrentTcpBytesSent = u.computeCurrentTcpBytesSent();
+ u.mStartedTcpBytesSent = -1;
+ }
}
- timers = mSensorTimers;
- for (int i = timers.size() - 1; i >= 0; i--) {
- timers.get(i).unplug();
+ for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
+ mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
}
}
public void noteStartGps(int uid) {
- mGpsRequesters.add(uid);
mUidStats.get(uid).noteStartGps();
}
public void noteStopGps(int uid) {
- mGpsRequesters.remove(uid);
- mUidStats.get(uid).noteStopGps();
- }
-
- public void noteRequestGpsOn(int uid) {
- mGpsRequesters.add(uid);
- mUidStats.get(uid).noteStartGps();
- }
-
- public void noteRequestGpsOff(int uid) {
- mGpsRequesters.remove(uid);
mUidStats.get(uid).noteStopGps();
}
@@ -349,7 +361,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
* When the device screen or battery state changes, update the appropriate "screen on time"
* counter.
*/
- private void updateScreenOnTime(boolean screenOn) {
+ private void updateScreenOnTimeLocked(boolean screenOn) {
if (!mScreenOn) {
Log.w(TAG, "updateScreenOnTime without mScreenOn, ignored");
return;
@@ -366,17 +378,17 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
}
}
- public void noteScreenOn() {
+ public void noteScreenOnLocked() {
mScreenOn = true;
mLastScreenOnTimeMillis = SystemClock.elapsedRealtime();
}
- public void noteScreenOff() {
+ public void noteScreenOffLocked() {
if (!mScreenOn) {
Log.w(TAG, "noteScreenOff without mScreenOn, ignored");
return;
}
- updateScreenOnTime(false);
+ updateScreenOnTimeLocked(false);
mScreenOn = false;
}
@@ -388,8 +400,11 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
return mPluggedScreenOnTimeMillis;
}
- @Override
- public SparseArray<? extends BatteryStats.Uid> getUidStats() {
+ @Override public boolean getIsOnBattery() {
+ return mOnBattery;
+ }
+
+ @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
return mUidStats;
}
@@ -401,11 +416,16 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
final int mUid;
long mLoadedTcpBytesReceived;
long mLoadedTcpBytesSent;
+ long mCurrentTcpBytesReceived;
+ long mCurrentTcpBytesSent;
long mTcpBytesReceivedAtLastUnplug;
long mTcpBytesSentAtLastUnplug;
- private final byte[] mBuf = new byte[16];
-
+ // These are not saved/restored when parcelling, since we want
+ // to return from the parcel with a snapshot of the state.
+ long mStartedTcpBytesReceived = -1;
+ long mStartedTcpBytesSent = -1;
+
/**
* The statistics we have collected for this uid's wake locks.
*/
@@ -455,51 +475,56 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
}
public long getTcpBytesReceived(int which) {
- long current = NetStat.getUidRxBytes(mUid);
-
- if (which == STATS_CURRENT) {
- return current;
- } else if (which == STATS_LAST) {
+ if (which == STATS_LAST) {
return mLoadedTcpBytesReceived;
- } else if (which == STATS_UNPLUGGED) {
- return current - mTcpBytesReceivedAtLastUnplug;
- } else if (which == STATS_TOTAL) {
- return mLoadedTcpBytesReceived + current;
} else {
- throw new IllegalArgumentException("which = " + which);
+ long current = computeCurrentTcpBytesReceived();
+ if (which == STATS_UNPLUGGED) {
+ current -= mTcpBytesReceivedAtLastUnplug;
+ } else if (which == STATS_TOTAL) {
+ current += mLoadedTcpBytesReceived;
+ }
+ return current;
}
}
+ public long computeCurrentTcpBytesReceived() {
+ return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
+ ? (NetStat.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
+ }
+
public long getTcpBytesSent(int which) {
- long current = NetStat.getUidTxBytes(mUid);
-
- if (which == STATS_CURRENT) {
- return current;
- } else if (which == STATS_LAST) {
+ if (which == STATS_LAST) {
return mLoadedTcpBytesSent;
- } else if (which == STATS_UNPLUGGED) {
- return current - mTcpBytesSentAtLastUnplug;
- } else if (which == STATS_TOTAL) {
- return mLoadedTcpBytesSent + current;
} else {
- throw new IllegalArgumentException("which = " + which);
+ long current = computeCurrentTcpBytesSent();
+ if (which == STATS_UNPLUGGED) {
+ current -= mTcpBytesSentAtLastUnplug;
+ } else if (which == STATS_TOTAL) {
+ current += mLoadedTcpBytesSent;
+ }
+ return current;
}
}
-
- void writeToParcelLocked(Parcel out) {
+
+ public long computeCurrentTcpBytesSent() {
+ return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
+ ? (NetStat.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
+ }
+
+ void writeToParcelLocked(Parcel out, long batteryRealtime) {
out.writeInt(mWakelockStats.size());
for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
out.writeString(wakelockEntry.getKey());
Uid.Wakelock wakelock = wakelockEntry.getValue();
- wakelock.writeToParcelLocked(out);
+ wakelock.writeToParcelLocked(out, batteryRealtime);
}
out.writeInt(mSensorStats.size());
for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
out.writeInt(sensorEntry.getKey());
- out.writeString(sensorEntry.getValue().getName());
Uid.Sensor sensor = sensorEntry.getValue();
- sensor.writeToParcelLocked(out);
+ sensor.writeToParcelLocked(out, batteryRealtime);
}
out.writeInt(mProcessStats.size());
@@ -518,17 +543,19 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
out.writeLong(mLoadedTcpBytesReceived);
out.writeLong(mLoadedTcpBytesSent);
+ out.writeLong(computeCurrentTcpBytesReceived());
+ out.writeLong(computeCurrentTcpBytesSent());
out.writeLong(mTcpBytesReceivedAtLastUnplug);
out.writeLong(mTcpBytesSentAtLastUnplug);
}
- void readFromParcelLocked(Parcel in) {
+ void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
int numWakelocks = in.readInt();
mWakelockStats.clear();
for (int j = 0; j < numWakelocks; j++) {
String wakelockName = in.readString();
Uid.Wakelock wakelock = new Wakelock();
- wakelock.readFromParcelLocked(in);
+ wakelock.readFromParcelLocked(unpluggables, in);
mWakelockStats.put(wakelockName, wakelock);
}
@@ -536,9 +563,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
mSensorStats.clear();
for (int k = 0; k < numSensors; k++) {
int sensorNumber = in.readInt();
- String name = in.readString();
- Uid.Sensor sensor = new Sensor(name);
- sensor.readFromParcelLocked(in);
+ Uid.Sensor sensor = new Sensor(sensorNumber);
+ sensor.readFromParcelLocked(mUnpluggables, in);
mSensorStats.put(sensorNumber, sensor);
}
@@ -562,6 +588,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
mLoadedTcpBytesReceived = in.readLong();
mLoadedTcpBytesSent = in.readLong();
+ mCurrentTcpBytesReceived = in.readLong();
+ mCurrentTcpBytesSent = in.readLong();
mTcpBytesReceivedAtLastUnplug = in.readLong();
mTcpBytesSentAtLastUnplug = in.readLong();
}
@@ -573,17 +601,17 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
/**
* How long (in ms) this uid has been keeping the device partially awake.
*/
- Timer wakeTimePartial;
+ Timer mTimerPartial;
/**
* How long (in ms) this uid has been keeping the device fully awake.
*/
- Timer wakeTimeFull;
+ Timer mTimerFull;
/**
* How long (in ms) this uid has had a window keeping the device awake.
*/
- Timer wakeTimeWindow;
+ Timer mTimerWindow;
/**
* Reads a possibly null Timer from a Parcel. The timer is associated with the
@@ -592,103 +620,85 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
* @param in the Parcel to be read from.
* return a new Timer, or null.
*/
- private Timer readTimerFromParcel(Parcel in) {
+ private Timer readTimerFromParcel(int type, ArrayList<Timer> pool,
+ ArrayList<Unpluggable> unpluggables, Parcel in) {
if (in.readInt() == 0) {
return null;
}
- Timer timer = new Timer();
- timer.readFromParcel(in);
- // Set the timer pool for the timer according to its type
- switch (timer.mType) {
- case WAKE_TYPE_PARTIAL:
- timer.mTimerPool = mPartialTimers;
- break;
- case WAKE_TYPE_FULL:
- timer.mTimerPool = mFullTimers;
- break;
- case WAKE_TYPE_WINDOW:
- timer.mTimerPool = mWindowTimers;
- break;
- }
- // If the timer is active, add it to the pool
- if (timer.mNesting > 0) {
- timer.mTimerPool.add(timer);
- }
- return timer;
+ return new Timer(type, pool, unpluggables, in);
}
- void readFromParcelLocked(Parcel in) {
- wakeTimePartial = readTimerFromParcel(in);
- wakeTimeFull = readTimerFromParcel(in);
- wakeTimeWindow = readTimerFromParcel(in);
+ void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
+ mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
+ mPartialTimers, unpluggables, in);
+ mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
+ mFullTimers, unpluggables, in);
+ mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
+ mWindowTimers, unpluggables, in);
}
- void writeToParcelLocked(Parcel out) {
- Timer.writeTimerToParcel(out, wakeTimePartial);
- Timer.writeTimerToParcel(out, wakeTimeFull);
- Timer.writeTimerToParcel(out, wakeTimeWindow);
+ void writeToParcelLocked(Parcel out, long batteryRealtime) {
+ Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
+ Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
+ Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
}
@Override
public Timer getWakeTime(int type) {
switch (type) {
- case WAKE_TYPE_FULL: return wakeTimeFull;
- case WAKE_TYPE_PARTIAL: return wakeTimePartial;
- case WAKE_TYPE_WINDOW: return wakeTimeWindow;
+ case WAKE_TYPE_FULL: return mTimerFull;
+ case WAKE_TYPE_PARTIAL: return mTimerPartial;
+ case WAKE_TYPE_WINDOW: return mTimerWindow;
default: throw new IllegalArgumentException("type = " + type);
}
}
}
public final class Sensor extends BatteryStats.Uid.Sensor {
- static final int GPS = -10000; // Treat GPS as a sensor
- final String mName;
- Timer sensorTime;
+ final int mHandle;
+ Timer mTimer;
- public Sensor(String name) {
- mName = name;
+ public Sensor(int handle) {
+ mHandle = handle;
}
- private Timer readTimerFromParcel(Parcel in) {
+ private Timer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
+ Parcel in) {
if (in.readInt() == 0) {
return null;
}
- Timer timer = new Timer();
- timer.readFromParcel(in);
- // Set the timer pool for the timer
- timer.mTimerPool = mSensorTimers;
-
- // If the timer is active, add it to the pool
- if (timer.mNesting > 0) {
- timer.mTimerPool.add(timer);
+ ArrayList<Timer> pool = mSensorTimers.get(mHandle);
+ if (pool == null) {
+ pool = new ArrayList<Timer>();
+ mSensorTimers.put(mHandle, pool);
}
- return timer;
+ return new Timer(0, pool, unpluggables, in);
}
- void readFromParcelLocked(Parcel in) {
- sensorTime = readTimerFromParcel(in);
+ void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
+ mTimer = readTimerFromParcel(unpluggables, in);
}
- void writeToParcelLocked(Parcel out) {
- Timer.writeTimerToParcel(out, sensorTime);
+ void writeToParcelLocked(Parcel out, long batteryRealtime) {
+ Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
}
@Override
public Timer getSensorTime() {
- return sensorTime;
+ return mTimer;
}
- public String getName() {
- return mName;
+ public int getHandle() {
+ return mHandle;
}
}
/**
* The statistics associated with a particular process.
*/
- public final class Proc extends BatteryStats.Uid.Proc {
+ public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
/**
* Total time (in 1/100 sec) spent executing in user code.
*/
@@ -734,6 +744,34 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
*/
int mLastStarts;
+ /**
+ * The amount of user time when last unplugged.
+ */
+ long mUnpluggedUserTime;
+
+ /**
+ * The amount of system time when last unplugged.
+ */
+ long mUnpluggedSystemTime;
+
+ /**
+ * The number of times the process has started before unplugged.
+ */
+ int mUnpluggedStarts;
+
+ Proc() {
+ mUnpluggables.add(this);
+ }
+
+ public void unplug(long batteryUptime, long batteryRealtime) {
+ mUnpluggedUserTime = mUserTime;
+ mUnpluggedSystemTime = mSystemTime;
+ mUnpluggedStarts = mStarts;
+ }
+
+ public void plug(long batteryUptime, long batteryRealtime) {
+ }
+
void writeToParcelLocked(Parcel out) {
out.writeLong(mUserTime);
out.writeLong(mSystemTime);
@@ -744,6 +782,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
out.writeLong(mLastUserTime);
out.writeLong(mLastSystemTime);
out.writeInt(mLastStarts);
+ out.writeLong(mUnpluggedUserTime);
+ out.writeLong(mUnpluggedSystemTime);
+ out.writeInt(mUnpluggedStarts);
}
void readFromParcelLocked(Parcel in) {
@@ -756,6 +797,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
mLastUserTime = in.readLong();
mLastSystemTime = in.readLong();
mLastStarts = in.readInt();
+ mUnpluggedUserTime = in.readLong();
+ mUnpluggedSystemTime = in.readLong();
+ mUnpluggedStarts = in.readInt();
}
public BatteryStatsImpl getBatteryStats() {
@@ -780,6 +824,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
val = mUserTime;
if (which == STATS_CURRENT) {
val -= mLoadedUserTime;
+ } else if (which == STATS_UNPLUGGED) {
+ val -= mUnpluggedUserTime;
}
}
return val;
@@ -794,6 +840,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
val = mSystemTime;
if (which == STATS_CURRENT) {
val -= mLoadedSystemTime;
+ } else if (which == STATS_UNPLUGGED) {
+ val -= mUnpluggedSystemTime;
}
}
return val;
@@ -808,6 +856,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
val = mStarts;
if (which == STATS_CURRENT) {
val -= mLoadedStarts;
+ } else if (which == STATS_UNPLUGGED) {
+ val -= mUnpluggedStarts;
}
}
return val;
@@ -817,7 +867,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
/**
* The statistics associated with a particular package.
*/
- public final class Pkg extends BatteryStats.Uid.Pkg {
+ public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
/**
* Number of times this package has done something that could wake up the
* device from sleep.
@@ -837,14 +887,32 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
int mLastWakeups;
/**
+ * Number of things that could wake up the device as of the
+ * last run.
+ */
+ int mUnpluggedWakeups;
+
+ /**
* The statics we have collected for this package's services.
*/
final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
+ Pkg() {
+ mUnpluggables.add(this);
+ }
+
+ public void unplug(long batteryUptime, long batteryRealtime) {
+ mUnpluggedWakeups = mWakeups;
+ }
+
+ public void plug(long batteryUptime, long batteryRealtime) {
+ }
+
void readFromParcelLocked(Parcel in) {
mWakeups = in.readInt();
mLoadedWakeups = in.readInt();
mLastWakeups = in.readInt();
+ mUnpluggedWakeups = in.readInt();
int numServs = in.readInt();
mServiceStats.clear();
@@ -861,6 +929,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
out.writeInt(mWakeups);
out.writeInt(mLoadedWakeups);
out.writeInt(mLastWakeups);
+ out.writeInt(mUnpluggedWakeups);
out.writeInt(mServiceStats.size());
for (Map.Entry<String, Uid.Pkg.Serv> servEntry : mServiceStats.entrySet()) {
@@ -885,6 +954,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
val = mWakeups;
if (which == STATS_CURRENT) {
val -= mLoadedWakeups;
+ } else if (which == STATS_UNPLUGGED) {
+ val -= mUnpluggedWakeups;
}
}
@@ -894,9 +965,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
/**
* The statistics associated with a particular service.
*/
- public final class Serv extends BatteryStats.Uid.Pkg.Serv {
+ public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
/**
- * Total time (ms) the service has been left started.
+ * Total time (ms in battery uptime) the service has been left started.
*/
long mStartTime;
@@ -917,13 +988,13 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
int mStarts;
/**
- * Total time (ms) the service has been left launched.
+ * Total time (ms in battery uptime) the service has been left launched.
*/
long mLaunchedTime;
/**
* If service has been launched and not yet exited, this is
- * when it was launched.
+ * when it was launched (ms in battery uptime).
*/
long mLaunchedSince;
@@ -938,7 +1009,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
int mLaunches;
/**
- * The amount of time spent started loaded from a previous save.
+ * The amount of time spent started loaded from a previous save
+ * (ms in battery uptime).
*/
long mLoadedStartTime;
@@ -953,7 +1025,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
int mLoadedLaunches;
/**
- * The amount of time spent started as of the last run.
+ * The amount of time spent started as of the last run (ms
+ * in battery uptime).
*/
long mLastStartTime;
@@ -967,6 +1040,35 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
*/
int mLastLaunches;
+ /**
+ * The amount of time spent started when last unplugged (ms
+ * in battery uptime).
+ */
+ long mUnpluggedStartTime;
+
+ /**
+ * The number of starts when last unplugged.
+ */
+ int mUnpluggedStarts;
+
+ /**
+ * The number of launches when last unplugged.
+ */
+ int mUnpluggedLaunches;
+
+ Serv() {
+ mUnpluggables.add(this);
+ }
+
+ public void unplug(long batteryUptime, long batteryRealtime) {
+ mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
+ mUnpluggedStarts = mStarts;
+ mUnpluggedLaunches = mLaunches;
+ }
+
+ public void plug(long batteryUptime, long batteryRealtime) {
+ }
+
void readFromParcelLocked(Parcel in) {
mStartTime = in.readLong();
mRunningSince = in.readLong();
@@ -982,6 +1084,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
mLastStartTime = in.readLong();
mLastStarts = in.readInt();
mLastLaunches = in.readInt();
+ mUnpluggedStartTime = in.readLong();
+ mUnpluggedStarts = in.readInt();
+ mUnpluggedLaunches = in.readInt();
}
void writeToParcelLocked(Parcel out) {
@@ -999,6 +1104,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
out.writeLong(mLastStartTime);
out.writeInt(mLastStarts);
out.writeInt(mLastLaunches);
+ out.writeLong(mUnpluggedStartTime);
+ out.writeInt(mUnpluggedStarts);
+ out.writeInt(mUnpluggedLaunches);
}
long getLaunchTimeToNowLocked(long batteryUptime) {
@@ -1065,6 +1173,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
val = mLaunches;
if (which == STATS_CURRENT) {
val -= mLoadedLaunches;
+ } else if (which == STATS_UNPLUGGED) {
+ val -= mUnpluggedLaunches;
}
}
@@ -1080,6 +1190,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
val = getStartTimeToNowLocked(now);
if (which == STATS_CURRENT) {
val -= mLoadedStartTime;
+ } else if (which == STATS_UNPLUGGED) {
+ val -= mUnpluggedStartTime;
}
}
@@ -1095,6 +1207,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
val = mStarts;
if (which == STATS_CURRENT) {
val -= mLoadedStarts;
+ } else if (which == STATS_UNPLUGGED) {
+ val -= mUnpluggedStarts;
}
}
@@ -1167,24 +1281,24 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
Timer t = null;
switch (type) {
case WAKE_TYPE_PARTIAL:
- t = wl.wakeTimePartial;
+ t = wl.mTimerPartial;
if (t == null) {
- t = new Timer(WAKE_TYPE_PARTIAL, mPartialTimers);
- wl.wakeTimePartial = t;
+ t = new Timer(WAKE_TYPE_PARTIAL, mPartialTimers, mUnpluggables);
+ wl.mTimerPartial = t;
}
return t;
case WAKE_TYPE_FULL:
- t = wl.wakeTimeFull;
+ t = wl.mTimerFull;
if (t == null) {
- t = new Timer(WAKE_TYPE_FULL, mFullTimers);
- wl.wakeTimeFull = t;
+ t = new Timer(WAKE_TYPE_FULL, mFullTimers, mUnpluggables);
+ wl.mTimerFull = t;
}
return t;
case WAKE_TYPE_WINDOW:
- t = wl.wakeTimeWindow;
+ t = wl.mTimerWindow;
if (t == null) {
- t = new Timer(WAKE_TYPE_WINDOW, mWindowTimers);
- wl.wakeTimeWindow = t;
+ t = new Timer(WAKE_TYPE_WINDOW, mWindowTimers, mUnpluggables);
+ wl.mTimerWindow = t;
}
return t;
default:
@@ -1192,21 +1306,26 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
}
}
- public Timer getSensorTimerLocked(String name, int sensor, boolean create) {
- Integer sId = Integer.valueOf(sensor);
- Sensor se = mSensorStats.get(sId);
+ public Timer getSensorTimerLocked(int sensor, boolean create) {
+ Sensor se = mSensorStats.get(sensor);
if (se == null) {
if (!create) {
return null;
}
- se = new Sensor(name);
- mSensorStats.put(sId, se);
+ se = new Sensor(sensor);
+ mSensorStats.put(sensor, se);
}
- Timer t = se.sensorTime;
- if (t == null) {
- t = new Timer(BatteryStats.SENSOR, mSensorTimers);
- se.sensorTime = t;
+ Timer t = se.mTimer;
+ if (t != null) {
+ return t;
}
+ ArrayList<Timer> timers = mSensorTimers.get(sensor);
+ if (timers == null) {
+ timers = new ArrayList<Timer>();
+ mSensorTimers.put(sensor, timers);
+ }
+ t = new Timer(BatteryStats.SENSOR, timers, mUnpluggables);
+ se.mTimer = t;
return t;
}
@@ -1224,30 +1343,30 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
}
}
- public void noteStartSensor(String name, int sensor) {
- Timer t = getSensorTimerLocked(name, sensor, true);
+ public void noteStartSensor(int sensor) {
+ Timer t = getSensorTimerLocked(sensor, true);
if (t != null) {
t.startRunningLocked(BatteryStatsImpl.this);
}
}
- public void noteStopSensor(String name, int sensor) {
+ public void noteStopSensor(int sensor) {
// Don't create a timer if one doesn't already exist
- Timer t = getSensorTimerLocked(name, sensor, false);
+ Timer t = getSensorTimerLocked(sensor, false);
if (t != null) {
t.stopRunningLocked(BatteryStatsImpl.this);
}
}
public void noteStartGps() {
- Timer t = getSensorTimerLocked("GPS", Sensor.GPS, true);
+ Timer t = getSensorTimerLocked(Sensor.GPS, true);
if (t != null) {
t.startRunningLocked(BatteryStatsImpl.this);
}
}
public void noteStopGps() {
- Timer t = getSensorTimerLocked("GPS", Sensor.GPS, false);
+ Timer t = getSensorTimerLocked(Sensor.GPS, false);
if (t != null) {
t.stopRunningLocked(BatteryStatsImpl.this);
}
@@ -1262,12 +1381,11 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
mFile = new File(filename);
mBackupFile = new File(filename + ".bak");
mStartCount++;
- mOnBattery = true;
+ mOnBattery = mOnBatteryInternal = false;
mTrackBatteryPastUptime = 0;
mTrackBatteryPastRealtime = 0;
mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
-
mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
}
@@ -1290,25 +1408,25 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
synchronized(this) {
if (mOnBattery != onBattery) {
if (mScreenOn) {
- updateScreenOnTime(true);
+ updateScreenOnTimeLocked(true);
}
+ mOnBattery = mOnBatteryInternal = onBattery;
+
long uptime = SystemClock.uptimeMillis() * 1000;
long mSecRealtime = SystemClock.elapsedRealtime();
long realtime = mSecRealtime * 1000;
if (onBattery) {
- mTrackBatteryUptimeStart = getBatteryUptime(uptime);
- mTrackBatteryRealtimeStart = getBatteryRealtime(realtime);
- unplugTcpCounters();
- unplugTimers();
-
- mUnpluggedBatteryUptime = getBatteryUptime(uptime);
- mUnpluggedBatteryRealtime = getBatteryRealtime(realtime);
+ mTrackBatteryUptimeStart = uptime;
+ mTrackBatteryRealtimeStart = realtime;
+ mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
+ mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
+ doUnplug(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
} else {
mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
+ doPlug(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
}
- mOnBattery = onBattery;
if ((mLastWriteTime + (60 * 1000)) < mSecRealtime) {
if (mFile != null) {
writeLocked();
@@ -1359,7 +1477,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
case STATS_CURRENT:
return uptime;
case STATS_UNPLUGGED:
- return uptime - mUnpluggedBatteryUptime;
+ return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
}
return 0;
}
@@ -1381,7 +1499,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
long getBatteryUptimeLocked(long curTime) {
long time = mTrackBatteryPastUptime;
- if (mOnBattery) {
+ if (mOnBatteryInternal) {
time += curTime - mTrackBatteryUptimeStart;
}
return time;
@@ -1398,7 +1516,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
long getBatteryRealtimeLocked(long curTime) {
long time = mTrackBatteryPastRealtime;
- if (mOnBattery) {
+ if (mOnBatteryInternal) {
time += curTime - mTrackBatteryRealtimeStart;
}
return time;
@@ -1554,8 +1672,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
private void readSummaryFromParcel(Parcel in) {
final int version = in.readInt();
if (version != VERSION) {
- Log.e("BatteryStats", "readFromParcel: version got " + version
- + ", expected " + VERSION);
+ Log.w("BatteryStats", "readFromParcel: version got " + version
+ + ", expected " + VERSION + "; erasing old stats");
return;
}
@@ -1570,11 +1688,9 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
mLastRealtime = in.readLong();
mStartCount++;
- if (version >= 14) {
- mBatteryScreenOnTimeMillis = in.readLong();
- mPluggedScreenOnTimeMillis = in.readLong();
- mScreenOn = false;
- }
+ mBatteryScreenOnTimeMillis = in.readLong();
+ mPluggedScreenOnTimeMillis = in.readLong();
+ mScreenOn = false;
final int NU = in.readInt();
for (int iu = 0; iu < NU; iu++) {
@@ -1596,22 +1712,16 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
}
}
- if (version >= 12) {
- int NSE = in.readInt();
- for (int is = 0; is < NSE; is++) {
- int seNumber = in.readInt();
- String seName = "<unknown>";
- if (version >= 14) {
- seName = in.readString();
- }
- if (in.readInt() != 0) {
- u.getSensorTimerLocked(seName, seNumber, true)
- .readSummaryFromParcelLocked(in);
- }
+ int NP = in.readInt();
+ for (int is = 0; is < NP; is++) {
+ int seNumber = in.readInt();
+ if (in.readInt() != 0) {
+ u.getSensorTimerLocked(seNumber, true)
+ .readSummaryFromParcelLocked(in);
}
}
- int NP = in.readInt();
+ NP = in.readInt();
for (int ip = 0; ip < NP; ip++) {
String procName = in.readString();
Uid.Proc p = u.getProcessStatsLocked(procName);
@@ -1642,10 +1752,8 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
}
}
- if (version >= 14) {
- u.mLoadedTcpBytesReceived = in.readLong();
- u.mLoadedTcpBytesSent = in.readLong();
- }
+ u.mLoadedTcpBytesReceived = in.readLong();
+ u.mLoadedTcpBytesSent = in.readLong();
}
}
@@ -1685,24 +1793,24 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
out.writeInt(NW);
if (NW > 0) {
for (Map.Entry<String, BatteryStatsImpl.Uid.Wakelock> ent
- : u.mWakelockStats.entrySet()) {
+ : u.mWakelockStats.entrySet()) {
out.writeString(ent.getKey());
Uid.Wakelock wl = ent.getValue();
- if (wl.wakeTimeFull != null) {
+ if (wl.mTimerFull != null) {
out.writeInt(1);
- wl.wakeTimeFull.writeSummaryFromParcelLocked(out, NOW);
+ wl.mTimerFull.writeSummaryFromParcelLocked(out, NOW);
} else {
out.writeInt(0);
}
- if (wl.wakeTimePartial != null) {
+ if (wl.mTimerPartial != null) {
out.writeInt(1);
- wl.wakeTimePartial.writeSummaryFromParcelLocked(out, NOW);
+ wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOW);
} else {
out.writeInt(0);
}
- if (wl.wakeTimeWindow != null) {
+ if (wl.mTimerWindow != null) {
out.writeInt(1);
- wl.wakeTimeWindow.writeSummaryFromParcelLocked(out, NOW);
+ wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOW);
} else {
out.writeInt(0);
}
@@ -1713,13 +1821,12 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
out.writeInt(NSE);
if (NSE > 0) {
for (Map.Entry<Integer, BatteryStatsImpl.Uid.Sensor> ent
- : u.mSensorStats.entrySet()) {
+ : u.mSensorStats.entrySet()) {
out.writeInt(ent.getKey());
Uid.Sensor se = ent.getValue();
- out.writeString(se.getName());
- if (se.sensorTime != null) {
+ if (se.mTimer != null) {
out.writeInt(1);
- se.sensorTime.writeSummaryFromParcelLocked(out, NOW);
+ se.mTimer.writeSummaryFromParcelLocked(out, NOW);
} else {
out.writeInt(0);
}
@@ -1800,6 +1907,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
mRealtimeStart = in.readLong();
mLastRealtime = in.readLong();
mOnBattery = in.readInt() != 0;
+ mOnBatteryInternal = false; // we are no longer really running.
mTrackBatteryPastUptime = in.readLong();
mTrackBatteryUptimeStart = in.readLong();
mTrackBatteryPastRealtime = in.readLong();
@@ -1815,7 +1923,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
for (int i = 0; i < numUids; i++) {
int uid = in.readInt();
Uid u = new Uid(uid);
- u.readFromParcelLocked(in);
+ u.readFromParcelLocked(mUnpluggables, in);
mUidStats.append(uid, u);
}
}
@@ -1826,6 +1934,11 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
@SuppressWarnings("unused")
void writeToParcelLocked(Parcel out, int flags) {
+ final long uSecUptime = SystemClock.uptimeMillis() * 1000;
+ final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
+ final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
+ final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
+
out.writeInt(MAGIC);
out.writeInt(mStartCount);
out.writeLong(mBatteryUptime);
@@ -1853,7 +1966,7 @@ public final class BatteryStatsImpl extends BatteryStats implements Parcelable {
out.writeInt(mUidStats.keyAt(i));
Uid uid = mUidStats.valueAt(i);
- uid.writeToParcelLocked(out);
+ uid.writeToParcelLocked(out, batteryRealtime);
}
}
diff --git a/core/java/com/android/internal/os/HandlerThread.java b/core/java/com/android/internal/os/HandlerThread.java
deleted file mode 100644
index 1de6bfd..0000000
--- a/core/java/com/android/internal/os/HandlerThread.java
+++ /dev/null
@@ -1,91 +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 com.android.internal.os;
-
-import android.os.Handler;
-import android.os.HandlerInterface;
-import android.os.Looper;
-
-/**
- * Handy class for starting a new thread containing a Handler
- * @hide
- * @deprecated
- */
-public class HandlerThread extends Thread
-{
- Runnable mSetup;
- HandlerInterface mhi;
- Handler mh;
- Throwable mtr;
- final Object mMonitor = new Object();
-
- public
- HandlerThread(HandlerInterface h, Runnable setup, String name)
- {
- super(name);
-
- mhi = h;
- mSetup = setup;
-
- synchronized (mMonitor) {
- start();
- while (mh == null && mtr == null) {
- try {
- mMonitor.wait();
- } catch (InterruptedException ex) {
- }
- }
- }
-
- if (mtr != null) {
- throw new RuntimeException("exception while starting", mtr);
- }
- }
-
- @Override
- public void
- run()
- {
- synchronized(mMonitor) {
- try {
- Looper.prepare();
- mh = new HandlerHelper (mhi);
-
- if (mSetup != null) {
- mSetup.run();
- mSetup = null;
- }
- } catch (RuntimeException exc) {
- mtr = exc;
- }
-
- mMonitor.notify();
- }
-
- if (mtr == null) {
- Looper.loop();
- }
- }
-
- public Handler
- getHandler()
- {
- return mh;
- }
-
-}
-
diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java
index ac72a20..4f98cee 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -1,7 +1,5 @@
package com.android.internal.view;
-import com.android.internal.view.IInputContext;
-
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -324,7 +322,7 @@ public class IInputConnectionWrapper extends IInputContext.Stub {
Log.w(TAG, "showStatusIcon on inactive InputConnection");
return;
}
- ic.reportFullscreenMode(msg.arg1 != 1);
+ ic.reportFullscreenMode(msg.arg1 == 1);
return;
}
case DO_PERFORM_PRIVATE_COMMAND: {
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index 648d944..44cf0ed 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -96,4 +96,21 @@ public class EditableInputConnection extends BaseInputConnection {
mTextView.onPrivateIMECommand(action, data);
return true;
}
+
+ @Override
+ public boolean commitText(CharSequence text, int newCursorPosition) {
+ if (mTextView == null) {
+ return super.commitText(text, newCursorPosition);
+ }
+
+ CharSequence errorBefore = mTextView.getError();
+ boolean success = super.commitText(text, newCursorPosition);
+ CharSequence errorAfter = mTextView.getError();
+
+ if (errorAfter != null && errorBefore == errorAfter) {
+ mTextView.setError(null, null);
+ }
+
+ return success;
+ }
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index ed1cd58..c8b3ad4 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -77,11 +77,10 @@ public class LockPatternUtils {
public static final int MIN_PATTERN_REGISTER_FAIL = 3;
private final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently";
+ private final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline";
private final ContentResolver mContentResolver;
- private long mLockoutDeadline = 0;
-
private static String sLockPatternFilename;
/**
@@ -270,12 +269,14 @@ public class LockPatternUtils {
}
/**
- * Store the lockout deadline, meaning the user can't attempt his/her unlock
- * pattern until the deadline has passed. Does not persist across reboots.
- * @param deadline The elapsed real time in millis in future.
+ * Set and store the lockout deadline, meaning the user can't attempt his/her unlock
+ * pattern until the deadline has passed.
+ * @return the chosen deadline.
*/
- public void setLockoutAttemptDeadline(long deadline) {
- mLockoutDeadline = deadline;
+ public long setLockoutAttemptDeadline() {
+ final long deadline = SystemClock.elapsedRealtime() + FAILED_ATTEMPT_TIMEOUT_MS;
+ setLong(LOCKOUT_ATTEMPT_DEADLINE, deadline);
+ return deadline;
}
/**
@@ -284,7 +285,12 @@ public class LockPatternUtils {
* enter a pattern.
*/
public long getLockoutAttemptDeadline() {
- return (mLockoutDeadline <= SystemClock.elapsedRealtime()) ? 0 : mLockoutDeadline;
+ final long deadline = getLong(LOCKOUT_ATTEMPT_DEADLINE, 0L);
+ final long now = SystemClock.elapsedRealtime();
+ if (deadline < now || deadline > (now + FAILED_ATTEMPT_TIMEOUT_MS)) {
+ return 0L;
+ }
+ return deadline;
}
/**
@@ -341,5 +347,13 @@ public class LockPatternUtils {
enabled ? 1 : 0);
}
+ private long getLong(String systemSettingKey, long def) {
+ return android.provider.Settings.System.getLong(mContentResolver, systemSettingKey, def);
+ }
+
+ private void setLong(String systemSettingKey, long value) {
+ android.provider.Settings.System.putLong(mContentResolver, systemSettingKey, value);
+ }
+
}
diff --git a/core/java/com/android/internal/widget/TextProgressBar.java b/core/java/com/android/internal/widget/TextProgressBar.java
new file mode 100644
index 0000000..d068865
--- /dev/null
+++ b/core/java/com/android/internal/widget/TextProgressBar.java
@@ -0,0 +1,177 @@
+/*
+ * 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.internal.widget;
+
+import android.content.Context;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Chronometer;
+import android.widget.Chronometer.OnChronometerTickListener;
+import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
+import android.widget.RemoteViews.RemoteView;
+
+/**
+ * Container that links together a {@link ProgressBar} and {@link Chronometer}
+ * as children. It subscribes to {@link Chronometer#OnChronometerTickListener}
+ * and updates the {@link ProgressBar} based on a preset finishing time.
+ * <p>
+ * This widget expects to contain two children with specific ids
+ * {@link android.R.id.progress} and {@link android.R.id.text1}.
+ * <p>
+ * If the {@link Chronometer} {@link android.R.attr#layout_width} is
+ * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}, then the
+ * {@link android.R.attr#gravity} will be used to automatically move it with
+ * respect to the {@link ProgressBar} position. For example, if
+ * {@link android.view.Gravity#LEFT} then the {@link Chronometer} will be placed
+ * just ahead of the leading edge of the {@link ProgressBar} position.
+ */
+@RemoteView
+public class TextProgressBar extends RelativeLayout implements OnChronometerTickListener {
+ public static final String TAG = "TextProgressBar";
+
+ static final int CHRONOMETER_ID = android.R.id.text1;
+ static final int PROGRESSBAR_ID = android.R.id.progress;
+
+ Chronometer mChronometer = null;
+ ProgressBar mProgressBar = null;
+
+ long mDurationBase = -1;
+ int mDuration = -1;
+
+ boolean mChronometerFollow = false;
+ int mChronometerGravity = Gravity.NO_GRAVITY;
+
+ public TextProgressBar(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public TextProgressBar(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public TextProgressBar(Context context) {
+ super(context);
+ }
+
+ /**
+ * Catch any interesting children when they are added.
+ */
+ @Override
+ public void addView(View child, int index, ViewGroup.LayoutParams params) {
+ super.addView(child, index, params);
+
+ int childId = child.getId();
+ if (childId == CHRONOMETER_ID && child instanceof Chronometer) {
+ mChronometer = (Chronometer) child;
+ mChronometer.setOnChronometerTickListener(this);
+
+ // Check if Chronometer should move with with ProgressBar
+ mChronometerFollow = (params.width == ViewGroup.LayoutParams.WRAP_CONTENT);
+ mChronometerGravity = (mChronometer.getGravity() & Gravity.HORIZONTAL_GRAVITY_MASK);
+
+ } else if (childId == PROGRESSBAR_ID && child instanceof ProgressBar) {
+ mProgressBar = (ProgressBar) child;
+ }
+ }
+
+ /**
+ * Set the expected termination time of the running {@link Chronometer}.
+ * This value is used to adjust the {@link ProgressBar} against the elapsed
+ * time.
+ * <p>
+ * Call this <b>after</b> adjusting the {@link Chronometer} base, if
+ * necessary.
+ *
+ * @param durationBase Use the {@link SystemClock#elapsedRealtime} time
+ * base.
+ */
+ public void setDurationBase(long durationBase) {
+ mDurationBase = durationBase;
+
+ if (mProgressBar == null || mChronometer == null) {
+ throw new RuntimeException("Expecting child ProgressBar with id " +
+ "'android.R.id.progress' and Chronometer id 'android.R.id.text1'");
+ }
+
+ // Update the ProgressBar maximum relative to Chronometer base
+ mDuration = (int) (durationBase - mChronometer.getBase());
+ mProgressBar.setMax(mDuration);
+
+ }
+
+ /**
+ * Callback when {@link Chronometer} changes, indicating that we should
+ * update the {@link ProgressBar} and change the layout if necessary.
+ */
+ public void onChronometerTick(Chronometer chronometer) {
+ if (mProgressBar == null) {
+ throw new RuntimeException(
+ "Expecting child ProgressBar with id 'android.R.id.progress'");
+ }
+
+ // Stop Chronometer if we're past duration
+ long now = SystemClock.elapsedRealtime();
+ if (now >= mDurationBase) {
+ mChronometer.stop();
+ }
+
+ // Update the ProgressBar status
+ int remaining = (int) (mDurationBase - now);
+ mProgressBar.setProgress(mDuration - remaining);
+
+ // Move the Chronometer if gravity is set correctly
+ if (mChronometerFollow) {
+ RelativeLayout.LayoutParams params;
+
+ // Calculate estimate of ProgressBar leading edge position
+ params = (RelativeLayout.LayoutParams) mProgressBar.getLayoutParams();
+ int contentWidth = mProgressBar.getWidth() - (params.leftMargin + params.rightMargin);
+ int leadingEdge = ((contentWidth * mProgressBar.getProgress()) /
+ mProgressBar.getMax()) + params.leftMargin;
+
+ // Calculate any adjustment based on gravity
+ int adjustLeft = 0;
+ int textWidth = mChronometer.getWidth();
+ if (mChronometerGravity == Gravity.RIGHT) {
+ adjustLeft = -textWidth;
+ } else if (mChronometerGravity == Gravity.CENTER_HORIZONTAL) {
+ adjustLeft = -(textWidth / 2);
+ }
+
+ // Limit margin to keep text inside ProgressBar bounds
+ leadingEdge += adjustLeft;
+ int rightLimit = contentWidth - params.rightMargin - textWidth;
+ if (leadingEdge < params.leftMargin) {
+ leadingEdge = params.leftMargin;
+ } else if (leadingEdge > rightLimit) {
+ leadingEdge = rightLimit;
+ }
+
+ params = (RelativeLayout.LayoutParams) mChronometer.getLayoutParams();
+ params.leftMargin = leadingEdge;
+
+ // Request layout to move Chronometer
+ mChronometer.requestLayout();
+
+ }
+ }
+}
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 79965b9..2f1f9b8 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -51,9 +51,9 @@ struct fields_t {
static fields_t fields;
static Mutex sLock;
+static jclass sCameraClass;
struct callback_cookie {
- jclass camera_class;
jobject camera_ref;
};
@@ -87,7 +87,7 @@ static void err_callback(status_t err, void *cookie)
}
LOGV("err_callback: camera_ref=%x, cookie=%x", (int)c->camera_ref, (int)cookie);
- env->CallStaticVoidMethod(c->camera_class, fields.post_event,
+ env->CallStaticVoidMethod(sCameraClass, fields.post_event,
c->camera_ref, kErrorCallback, error, 0, NULL);
}
@@ -115,7 +115,6 @@ static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobj
jniThrowException(env, "java/lang/Exception", NULL);
return;
}
- cookie->camera_class = (jclass)env->NewGlobalRef(clazz);
// We use a weak reference so the Camera object can be garbage collected.
// The reference is only used as a proxy for callbacks.
@@ -157,7 +156,6 @@ static void android_hardware_Camera_release(JNIEnv *env, jobject thiz)
if (cookie) {
env->DeleteGlobalRef(cookie->camera_ref);
- env->DeleteGlobalRef(cookie->camera_class);
delete cookie;
env->SetIntField(thiz, fields.listener_context, 0);
}
@@ -207,7 +205,7 @@ static void preview_callback(const sp<IMemory>& mem, void *cookie)
obj = array;
- env->CallStaticVoidMethod(c->camera_class, fields.post_event,
+ env->CallStaticVoidMethod(sCameraClass, fields.post_event,
c->camera_ref, kPreviewCallback, arg1, arg2, obj);
env->DeleteLocalRef(array);
}
@@ -270,13 +268,11 @@ static void autofocus_callback_impl(bool success, void *cookie)
return;
}
callback_cookie *c = (callback_cookie *)cookie;
- env->CallStaticVoidMethod(c->camera_class, fields.post_event,
+ env->CallStaticVoidMethod(sCameraClass, fields.post_event,
c->camera_ref, kAutoFocusCallback,
success, 0, NULL);
}
-
-
static void android_hardware_Camera_autoFocus(JNIEnv *env, jobject thiz)
{
sp<Camera> c = get_native_camera(env, thiz);
@@ -301,7 +297,7 @@ static void jpeg_callback(const sp<IMemory>& mem, void *cookie)
jobject obj = NULL;
if (mem == NULL) {
- env->CallStaticVoidMethod(c->camera_class, fields.post_event,
+ env->CallStaticVoidMethod(sCameraClass, fields.post_event,
c->camera_ref, kJpegCallback, arg1, arg2, NULL);
return;
}
@@ -331,7 +327,7 @@ static void jpeg_callback(const sp<IMemory>& mem, void *cookie)
obj = array;
- env->CallStaticVoidMethod(c->camera_class, fields.post_event,
+ env->CallStaticVoidMethod(sCameraClass, fields.post_event,
c->camera_ref, kJpegCallback, arg1, arg2, obj);
env->DeleteLocalRef(array);
}
@@ -344,7 +340,7 @@ static void shutter_callback_impl(void *cookie)
return;
}
callback_cookie *c = (callback_cookie *)cookie;
- env->CallStaticVoidMethod(c->camera_class, fields.post_event,
+ env->CallStaticVoidMethod(sCameraClass, fields.post_event,
c->camera_ref, kShutterCallback, 0, 0, NULL);
}
@@ -357,7 +353,7 @@ static void raw_callback(const sp<IMemory>& mem __attribute__((unused)),
return;
}
callback_cookie *c = (callback_cookie *)cookie;
- env->CallStaticVoidMethod(c->camera_class, fields.post_event,
+ env->CallStaticVoidMethod(sCameraClass, fields.post_event,
c->camera_ref, kRawCallback, 0, 0, NULL);
}
@@ -524,6 +520,7 @@ int register_android_hardware_Camera(JNIEnv *env)
return -1;
jclass clazz = env->FindClass("android/hardware/Camera");
+ sCameraClass = (jclass)env->NewGlobalRef(clazz);
fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
"(Ljava/lang/Object;IIILjava/lang/Object;)V");
if (fields.post_event == NULL) {
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 6ca821d..d9effee 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
#define LOG_TAG "AudioTrack-JNI"
@@ -164,8 +164,8 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
jint streamType, jint sampleRateInHertz, jint nbChannels,
jint audioFormat, jint buffSizeInBytes, jint memoryMode)
{
- //LOGV("sampleRate=%d, audioFormat(from Java)=%d, nbChannels=%d, buffSize=%d",
- // sampleRateInHertz, audioFormat, nbChannels, buffSizeInBytes);
+ LOGV("sampleRate=%d, audioFormat(from Java)=%d, nbChannels=%d, buffSize=%d",
+ sampleRateInHertz, audioFormat, nbChannels, buffSizeInBytes);
int afSampleRate;
int afFrameCount;
@@ -210,7 +210,20 @@ android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_th
LOGE("Error creating AudioTrack: unsupported audio format.");
return AUDIOTRACK_ERROR_SETUP_INVALIDFORMAT;
}
-
+
+ // for the moment 8bitPCM in MODE_STATIC is not supported natively in the AudioTrack C++ class
+ // so we declare everything as 16bitPCM, the 8->16bit conversion for MODE_STATIC will be handled
+ // in android_media_AudioTrack_native_write()
+ if ((audioFormat == javaAudioTrackFields.PCM8)
+ && (memoryMode == javaAudioTrackFields.MODE_STATIC)) {
+ LOGV("android_media_AudioTrack_native_setup(): requesting MODE_STATIC for 8bit \
+ buff size of %dbytes, switching to 16bit, buff size of %dbytes",
+ buffSizeInBytes, 2*buffSizeInBytes);
+ audioFormat = javaAudioTrackFields.PCM16;
+ // we will need twice the memory to store the data
+ buffSizeInBytes *= 2;
+ }
+
// compute the frame count
int bytesPerSample = audioFormat == javaAudioTrackFields.PCM16 ? 2 : 1;
int format = audioFormat == javaAudioTrackFields.PCM16 ?
@@ -387,13 +400,13 @@ android_media_AudioTrack_set_volume(JNIEnv *env, jobject thiz, jfloat leftVol, j
// ----------------------------------------------------------------------------
static void android_media_AudioTrack_native_finalize(JNIEnv *env, jobject thiz) {
- LOGV("android_media_AudioTrack_native_finalize jobject: %x\n", (int)thiz);
+ //LOGV("android_media_AudioTrack_native_finalize jobject: %x\n", (int)thiz);
// delete the AudioTrack object
AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
thiz, javaAudioTrackFields.nativeTrackInJavaObj);
if (lpTrack) {
- LOGV("deleting lpTrack: %x\n", (int)lpTrack);
+ //LOGV("deleting lpTrack: %x\n", (int)lpTrack);
lpTrack->stop();
delete lpTrack;
}
@@ -402,7 +415,7 @@ static void android_media_AudioTrack_native_finalize(JNIEnv *env, jobject thiz)
AudioTrackJniStorage* pJniStorage = (AudioTrackJniStorage *)env->GetIntField(
thiz, javaAudioTrackFields.jniData);
if (pJniStorage) {
- LOGV("deleting pJniStorage: %x\n", (int)pJniStorage);
+ //LOGV("deleting pJniStorage: %x\n", (int)pJniStorage);
delete pJniStorage;
}
}
@@ -422,7 +435,8 @@ static void android_media_AudioTrack_native_release(JNIEnv *env, jobject thiz)
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_native_write(JNIEnv *env, jobject thiz,
jbyteArray javaAudioData,
- jint offsetInBytes, jint sizeInBytes) {
+ jint offsetInBytes, jint sizeInBytes,
+ jint javaAudioFormat) {
jbyte* cAudioData = NULL;
AudioTrack *lpTrack = NULL;
//LOGV("android_media_AudioTrack_native_write(offset=%d, sizeInBytes=%d) called",
@@ -453,8 +467,22 @@ static jint android_media_AudioTrack_native_write(JNIEnv *env, jobject thiz,
if (lpTrack->sharedBuffer() == 0) {
written = lpTrack->write(cAudioData + offsetInBytes, sizeInBytes);
} else {
- memcpy(lpTrack->sharedBuffer()->pointer(), cAudioData + offsetInBytes, sizeInBytes);
- written = sizeInBytes;
+ if (javaAudioFormat == javaAudioTrackFields.PCM16) {
+ memcpy(lpTrack->sharedBuffer()->pointer(), cAudioData + offsetInBytes, sizeInBytes);
+ written = sizeInBytes;
+ } else if (javaAudioFormat == javaAudioTrackFields.PCM8) {
+ // cAudioData contains 8bit data we need to expand to 16bit before copying
+ // to the shared memory
+ int count = sizeInBytes;
+ int16_t *dst = (int16_t *)lpTrack->sharedBuffer()->pointer();
+ const int8_t *src = (const int8_t *)(cAudioData + offsetInBytes);
+ while(count--) {
+ *dst++ = (int16_t)(*src++^0x80) << 8;
+ }
+ // even though we wrote 2*sizeInBytes, we only report sizeInBytes as written to hide
+ // the 8bit mixer restriction from the user of this function
+ written = sizeInBytes;
+ }
}
env->ReleasePrimitiveArrayCritical(javaAudioData, cAudioData, 0);
@@ -468,10 +496,12 @@ static jint android_media_AudioTrack_native_write(JNIEnv *env, jobject thiz,
// ----------------------------------------------------------------------------
static jint android_media_AudioTrack_native_write_short(JNIEnv *env, jobject thiz,
jshortArray javaAudioData,
- jint offsetInShorts, jint sizeInShorts) {
+ jint offsetInShorts, jint sizeInShorts,
+ jint javaAudioFormat) {
return (android_media_AudioTrack_native_write(env, thiz,
(jbyteArray) javaAudioData,
- offsetInShorts*2, sizeInShorts*2)
+ offsetInShorts*2, sizeInShorts*2,
+ javaAudioFormat)
/ 2);
}
@@ -676,6 +706,7 @@ static jint android_media_AudioTrack_get_output_sample_rate(JNIEnv *env, jobjec
// ----------------------------------------------------------------------------
// returns the minimum required size for the successful creation of a streaming AudioTrack
+// returns -1 if there was an error querying the hardware.
static jint android_media_AudioTrack_get_min_buff_size(JNIEnv *env, jobject thiz,
jint sampleRateInHertz, jint nbChannels, jint audioFormat) {
int afSamplingRate;
@@ -715,8 +746,8 @@ static JNINativeMethod gMethods[] = {
(void *)android_media_AudioTrack_native_setup},
{"native_finalize", "()V", (void *)android_media_AudioTrack_native_finalize},
{"native_release", "()V", (void *)android_media_AudioTrack_native_release},
- {"native_write_byte", "([BII)I", (void *)android_media_AudioTrack_native_write},
- {"native_write_short", "([SII)I", (void *)android_media_AudioTrack_native_write_short},
+ {"native_write_byte", "([BIII)I", (void *)android_media_AudioTrack_native_write},
+ {"native_write_short", "([SIII)I", (void *)android_media_AudioTrack_native_write_short},
{"native_setVolume", "(FF)V", (void *)android_media_AudioTrack_set_volume},
{"native_get_native_frame_count",
"()I", (void *)android_media_AudioTrack_get_native_frame_count},
diff --git a/core/jni/android_media_JetPlayer.cpp b/core/jni/android_media_JetPlayer.cpp
index fe60943..e345af6 100644
--- a/core/jni/android_media_JetPlayer.cpp
+++ b/core/jni/android_media_JetPlayer.cpp
@@ -81,7 +81,7 @@ android_media_JetPlayer_setup(JNIEnv *env, jobject thiz, jobject weak_this,
jint maxTracks, jint trackBufferSize)
{
//LOGV("android_media_JetPlayer_setup(): entering.");
- JetPlayer* lpJet = new JetPlayer(weak_this, maxTracks, trackBufferSize);
+ JetPlayer* lpJet = new JetPlayer(env->NewGlobalRef(weak_this), maxTracks, trackBufferSize);
EAS_RESULT result = lpJet->init();
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index a7a0428..a6b63d8 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -117,22 +117,25 @@ static void read_mapinfo(FILE *fp, stats_t* stats)
line[--len] = 0;
/* ignore guard pages */
- if (len > 18 && line[18] == '-') skip = true;
+ if (len > 18 && line[17] == '-') skip = true;
start = strtoul(line, 0, 16);
- if (strstr("[heap]", line)) {
+ if (strstr(line, "[heap]")) {
isNativeHeap = 1;
- } else if (strstr("/dalvik-LinearAlloc", line)) {
+ } else if (strstr(line, "/dalvik-LinearAlloc")) {
isDalvikHeap = 1;
- } else if (strstr("/mspace/dalvik-heap", line)) {
+ } else if (strstr(line, "/mspace/dalvik-heap")) {
isDalvikHeap = 1;
- } else if (strstr("/dalvik-heap-bitmap/", line)) {
+ } else if (strstr(line, "/dalvik-heap-bitmap/")) {
isDalvikHeap = 1;
- } else if (strstr("/tmp/sqlite-heap", line)) {
+ } else if (strstr(line, "/tmp/sqlite-heap")) {
isSqliteHeap = 1;
}
+ //LOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap,
+ // isSqliteHeap, line);
+
while (true) {
if (fgets(line, 1024, fp) == 0) {
done = true;
diff --git a/core/jni/android_server_BluetoothDeviceService.cpp b/core/jni/android_server_BluetoothDeviceService.cpp
index 0936310..796da15 100644
--- a/core/jni/android_server_BluetoothDeviceService.cpp
+++ b/core/jni/android_server_BluetoothDeviceService.cpp
@@ -515,24 +515,39 @@ static jboolean cancelBondingProcessNative(JNIEnv *env, jobject object,
static jboolean removeBondingNative(JNIEnv *env, jobject object, jstring address) {
LOGV(__FUNCTION__);
+ jboolean result = JNI_FALSE;
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
const char *c_address = env->GetStringUTFChars(address, NULL);
LOGV("... address = %s", c_address);
+ DBusError err;
+ dbus_error_init(&err);
DBusMessage *reply =
- dbus_func_args_timeout(env, nat->conn, -1, nat->adapter,
- DBUS_CLASS_NAME, "RemoveBonding",
- DBUS_TYPE_STRING, &c_address,
- DBUS_TYPE_INVALID);
- env->ReleaseStringUTFChars(address, c_address);
- if (reply) {
- dbus_message_unref(reply);
+ dbus_func_args_error(env, nat->conn, &err, nat->adapter,
+ DBUS_CLASS_NAME, "RemoveBonding",
+ DBUS_TYPE_STRING, &c_address,
+ DBUS_TYPE_INVALID);
+ if (dbus_error_is_set(&err)) {
+ if (dbus_error_has_name(&err,
+ BLUEZ_DBUS_BASE_IFC ".Error.DoesNotExist")) {
+ LOGW("%s: Warning: %s (%s)", __FUNCTION__, err.message,
+ c_address);
+ result = JNI_TRUE;
+ } else {
+ LOGE("%s: D-Bus error %s (%s)", __FUNCTION__, err.name,
+ err.message);
+ }
+ } else {
+ result = JNI_TRUE;
}
- return JNI_TRUE;
+
+ env->ReleaseStringUTFChars(address, c_address);
+ dbus_error_free(&err);
+ if (reply) dbus_message_unref(reply);
}
#endif
- return JNI_FALSE;
+ return result;
}
static jobjectArray listBondingsNative(JNIEnv *env, jobject object) {
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index e5ae2ea..9100e81 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -755,17 +755,22 @@ void onCreateBondingResult(DBusMessage *msg, void *user) {
// already bonded
LOGV("... error = %s (%s)\n", err.name, err.message);
result = BOND_RESULT_SUCCESS;
+ } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.InProgress")) {
+ // don't make the java callback
+ LOGV("... error = %s (%s)\n", err.name, err.message);
+ goto done;
} else {
LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
result = BOND_RESULT_ERROR;
}
- dbus_error_free(&err);
}
env->CallVoidMethod(event_loop_nat->me,
method_onCreateBondingResult,
env->NewStringUTF(address),
result);
+done:
+ dbus_error_free(&err);
free(user);
}
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index f09bd4c..8baaa84 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -212,7 +212,9 @@ static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect)
dirty.top = env->GetIntField(dirtyRect, ro.t);
dirty.right = env->GetIntField(dirtyRect, ro.r);
dirty.bottom= env->GetIntField(dirtyRect, ro.b);
- dirtyRegion.set(dirty);
+ if (dirty.left < dirty.right && dirty.top < dirty.bottom) {
+ dirtyRegion.set(dirty);
+ }
} else {
dirtyRegion.set(Rect(0x3FFF,0x3FFF));
}
@@ -246,6 +248,14 @@ static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect)
int saveCount = nativeCanvas->save();
env->SetIntField(clazz, so.saveCount, saveCount);
+ if (dirtyRect) {
+ Rect bounds(dirtyRegion.bounds());
+ env->SetIntField(dirtyRect, ro.l, bounds.left);
+ env->SetIntField(dirtyRect, ro.t, bounds.top);
+ env->SetIntField(dirtyRect, ro.r, bounds.right);
+ env->SetIntField(dirtyRect, ro.b, bounds.bottom);
+ }
+
return canvas;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 0e8d3fd..2c3b590 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -18,7 +18,8 @@
*/
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android" android:sharedUserId="android.uid.system">
+ package="android" android:sharedUserId="android.uid.system"
+ android:sharedUserLabel="@string/android_system_label">
<!-- ====================================== -->
<!-- Permissions for things that cost money -->
@@ -946,7 +947,7 @@
<application android:process="system"
android:persistent="true"
android:hasCode="false"
- android:label="Android System"
+ android:label="@string/android_system_label"
android:allowClearUserData="false"
android:icon="@drawable/ic_launcher_android">
<activity android:name="com.android.internal.app.ChooserActivity"
diff --git a/core/res/res/drawable-land/title_bar.9.png b/core/res/res/drawable-land/title_bar.9.png
index 63ad916..a48d967 100644
--- a/core/res/res/drawable-land/title_bar.9.png
+++ b/core/res/res/drawable-land/title_bar.9.png
Binary files differ
diff --git a/core/res/res/drawable-land/title_bar_tall.png b/core/res/res/drawable-land/title_bar_tall.png
index 670decc..16290fb 100644
--- a/core/res/res/drawable-land/title_bar_tall.png
+++ b/core/res/res/drawable-land/title_bar_tall.png
Binary files differ
diff --git a/core/res/res/drawable/popup_inline_error_above.9.png b/core/res/res/drawable/popup_inline_error_above.9.png
new file mode 100644
index 0000000..2e601d0
--- /dev/null
+++ b/core/res/res/drawable/popup_inline_error_above.9.png
Binary files differ
diff --git a/core/res/res/drawable/scrollbar_handle_accelerated_anim2.9.png b/core/res/res/drawable/scrollbar_handle_accelerated_anim2.9.png
index d96cb3f..85caddd 100755
--- a/core/res/res/drawable/scrollbar_handle_accelerated_anim2.9.png
+++ b/core/res/res/drawable/scrollbar_handle_accelerated_anim2.9.png
Binary files differ
diff --git a/core/res/res/drawable/sym_action_call.png b/core/res/res/drawable/sym_action_call.png
index bcd9010..a442758 100644
--- a/core/res/res/drawable/sym_action_call.png
+++ b/core/res/res/drawable/sym_action_call.png
Binary files differ
diff --git a/core/res/res/drawable/sym_action_chat.png b/core/res/res/drawable/sym_action_chat.png
index 625e0e8..9f6419e 100644
--- a/core/res/res/drawable/sym_action_chat.png
+++ b/core/res/res/drawable/sym_action_chat.png
Binary files differ
diff --git a/core/res/res/drawable/sym_action_email.png b/core/res/res/drawable/sym_action_email.png
index 5f79e92..5fea417 100644
--- a/core/res/res/drawable/sym_action_email.png
+++ b/core/res/res/drawable/sym_action_email.png
Binary files differ
diff --git a/core/res/res/drawable/sym_action_map.png b/core/res/res/drawable/sym_action_map.png
deleted file mode 100644
index b45b7a8..0000000
--- a/core/res/res/drawable/sym_action_map.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/sym_action_sms.png b/core/res/res/drawable/sym_action_sms.png
deleted file mode 100644
index 50ce0ea..0000000
--- a/core/res/res/drawable/sym_action_sms.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/title_bar.9.png b/core/res/res/drawable/title_bar.9.png
index 44c3179..482d82e 100644
--- a/core/res/res/drawable/title_bar.9.png
+++ b/core/res/res/drawable/title_bar.9.png
Binary files differ
diff --git a/core/res/res/drawable/title_bar_tall.png b/core/res/res/drawable/title_bar_tall.png
index 09f5447..cd565dc 100644
--- a/core/res/res/drawable/title_bar_tall.png
+++ b/core/res/res/drawable/title_bar_tall.png
Binary files differ
diff --git a/core/res/res/drawable/zoom_ring_overview_tab.9.png b/core/res/res/drawable/zoom_ring_overview_tab.9.png
new file mode 100644
index 0000000..4056f73
--- /dev/null
+++ b/core/res/res/drawable/zoom_ring_overview_tab.9.png
Binary files differ
diff --git a/core/res/res/drawable/zoom_ring_thumb.png b/core/res/res/drawable/zoom_ring_thumb.png
index 4cc5f6f..1002724 100644
--- a/core/res/res/drawable/zoom_ring_thumb.png
+++ b/core/res/res/drawable/zoom_ring_thumb.png
Binary files differ
diff --git a/core/res/res/drawable/zoom_ring_thumb_minus_arrow.png b/core/res/res/drawable/zoom_ring_thumb_minus_arrow.png
new file mode 100644
index 0000000..c7b87ef
--- /dev/null
+++ b/core/res/res/drawable/zoom_ring_thumb_minus_arrow.png
Binary files differ
diff --git a/core/res/res/drawable/zoom_ring_thumb_minus_arrow_rotatable.xml b/core/res/res/drawable/zoom_ring_thumb_minus_arrow_rotatable.xml
new file mode 100644
index 0000000..f2d495b
--- /dev/null
+++ b/core/res/res/drawable/zoom_ring_thumb_minus_arrow_rotatable.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<rotate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fromDegrees="0"
+ android:toDegrees="360"
+ android:drawable="@drawable/zoom_ring_thumb_minus_arrow" />
diff --git a/core/res/res/drawable/zoom_ring_thumb_plus_arrow.png b/core/res/res/drawable/zoom_ring_thumb_plus_arrow.png
new file mode 100644
index 0000000..0591d39
--- /dev/null
+++ b/core/res/res/drawable/zoom_ring_thumb_plus_arrow.png
Binary files differ
diff --git a/core/res/res/drawable/zoom_ring_thumb_plus_arrow_rotatable.xml b/core/res/res/drawable/zoom_ring_thumb_plus_arrow_rotatable.xml
new file mode 100644
index 0000000..b77eaa4
--- /dev/null
+++ b/core/res/res/drawable/zoom_ring_thumb_plus_arrow_rotatable.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<rotate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fromDegrees="0"
+ android:toDegrees="360"
+ android:drawable="@drawable/zoom_ring_thumb_plus_arrow" />
diff --git a/core/res/res/drawable/zoom_ring_track.png b/core/res/res/drawable/zoom_ring_track.png
index 91d91f4..60a15b7 100644
--- a/core/res/res/drawable/zoom_ring_track.png
+++ b/core/res/res/drawable/zoom_ring_track.png
Binary files differ
diff --git a/core/res/res/drawable/zoom_ring_track_absolute.png b/core/res/res/drawable/zoom_ring_track_absolute.png
new file mode 100644
index 0000000..6b38c53
--- /dev/null
+++ b/core/res/res/drawable/zoom_ring_track_absolute.png
Binary files differ
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index e0c0a64..672c4b9 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_reboot">"Umožňuje aplikaci vynutit restartování telefonu."</string>
<string name="permlab_mount_unmount_filesystems">"připojení a odpojení souborových systémů"</string>
<string name="permdesc_mount_unmount_filesystems">"Umožňuje aplikaci připojit či odpojit souborové systémy ve vyměnitelných úložištích."</string>
- <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
- <skip />
- <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
- <skip />
+ <string name="permlab_mount_format_filesystems">"formátovat externí úložiště"</string>
+ <string name="permdesc_mount_format_filesystems">"Umožňuje aplikaci formátovat vyměnitelná úložiště."</string>
<string name="permlab_vibrate">"ovládání vibrací"</string>
<string name="permdesc_vibrate">"Umožňuje aplikaci ovládat vibrace."</string>
<string name="permlab_flashlight">"ovládání kontrolky"</string>
@@ -280,10 +278,8 @@
<string name="permdesc_locationUpdates">"Umožňuje povolit či zakázat aktualizace polohy prostřednictvím bezdrátového připojení. Aplikace toto nastavení obvykle nepoužívají."</string>
<string name="permlab_checkinProperties">"přístup k vlastnostem Checkin"</string>
<string name="permdesc_checkinProperties">"Umožňuje čtení i zápis vlastností nahraných službou Checkin. Běžné aplikace toto nastavení obvykle nevyužívají."</string>
- <!-- no translation found for permlab_bindGadget (2519859363977647275) -->
- <skip />
- <!-- no translation found for permdesc_bindGadget (7865866514555126333) -->
- <skip />
+ <string name="permlab_bindGadget">"zvolit gadgety"</string>
+ <string name="permdesc_bindGadget">"Umožňuje aplikaci sdělit systému, které aplikace mohou použít které gadgety. Aplikace s tímto oprávněním mohou zpřístupnit osobní údaje jiným aplikacím. Není určeno pro normální aplikace."</string>
<string name="permlab_modifyPhoneState">"změny stavu telefonu"</string>
<string name="permdesc_modifyPhoneState">"Umožňuje aplikaci ovládat telefonní funkce zařízení. Aplikace s tímto oprávněním může přepínat sítě nebo zapnout či vypnout bezdrátové připojení telefonu bez vašeho svolení."</string>
<string name="permlab_readPhoneState">"zjistit stav telefonu"</string>
@@ -312,10 +308,8 @@
<string name="permdesc_writeApnSettings">"Umožňuje aplikaci změnit nastavení APN, jako je například proxy či port APN."</string>
<string name="permlab_changeNetworkState">"změna připojení k síti"</string>
<string name="permdesc_changeNetworkState">"Umožňuje aplikaci změnit stav připojení k síti."</string>
- <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
- <skip />
- <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
- <skip />
+ <string name="permlab_changeBackgroundDataSetting">"změnit nastavení použití dat na pozadí"</string>
+ <string name="permdesc_changeBackgroundDataSetting">"Umožňuje aplikaci změnit nastavení použití dat na pozadí."</string>
<string name="permlab_accessWifiState">"zobrazení stavu WiFi"</string>
<string name="permdesc_accessWifiState">"Umožňuje aplikaci zobrazit informace o stavu připojení WiFi."</string>
<string name="permlab_changeWifiState">"Změnit stav WiFi"</string>
@@ -336,14 +330,10 @@
<string name="permdesc_subscribedFeedsRead">"Umožňuje aplikaci získat podrobnosti o aktuálně synchronizovaných zdrojích."</string>
<string name="permlab_subscribedFeedsWrite">"zápis odebíraných zdrojů"</string>
<string name="permdesc_subscribedFeedsWrite">"Umožňuje aplikaci upravit vaše aktuálně synchronizované zdroje. To může škodlivým aplikacím umožnit změnu vašich synchronizovaných zdrojů."</string>
- <!-- no translation found for permlab_readDictionary (432535716804748781) -->
- <skip />
- <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
- <skip />
- <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
- <skip />
- <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
- <skip />
+ <string name="permlab_readDictionary">"číst slovník definovaný uživatelem"</string>
+ <string name="permdesc_readDictionary">"Umožní aplikaci číst soukromá slova, jména a fráze, která uživatel mohl uložit do svého slovníku."</string>
+ <string name="permlab_writeDictionary">"zapisovat do slovníku definovaného uživatelem"</string>
+ <string name="permdesc_writeDictionary">"Umožní aplikaci zapisovat nová slova do uživatelského slovníku."</string>
<string-array name="phoneTypes">
<item>"Domů"</item>
<item>"Mobil"</item>
@@ -440,12 +430,9 @@
<string name="factorytest_not_system">"Test FACTORY_TEST lze provést pouze u balíčků nainstalovaných ve složce /system/app."</string>
<string name="factorytest_no_action">"Nebyl nalezen žádný balíček umožňující test FACTORY_TEST."</string>
<string name="factorytest_reboot">"Restartovat"</string>
- <!-- no translation found for js_dialog_title (8143918455087008109) -->
- <skip />
- <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
- <skip />
- <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
- <skip />
+ <string name="js_dialog_title">"Stránka <xliff:g id="TITLE">%s</xliff:g> uvádí:"</string>
+ <string name="js_dialog_title_default">"JavaScript"</string>
+ <string name="js_dialog_before_unload">"Chcete opustit tuto stránku?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Vyberte OK, chcete-li pokračovat, nebo Zrušit, chcete-li na stránce zůstat."</string>
<string name="save_password_label">"Potvrdit"</string>
<string name="save_password_message">"Chcete, aby si prohlížeč zapamatoval toto heslo?"</string>
<string name="save_password_notnow">"Nyní ne"</string>
@@ -496,22 +483,38 @@
<item quantity="one">"zítra"</item>
<item quantity="other">"zbývající počet dní: <xliff:g id="COUNT">%d</xliff:g>"</item>
</plurals>
- <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) -->
- <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) -->
- <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) -->
- <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) -->
- <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) -->
- <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) -->
- <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) -->
- <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) -->
- <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) -->
- <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) -->
- <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) -->
- <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) -->
- <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) -->
- <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) -->
- <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) -->
- <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) -->
+ <plurals name="abbrev_num_seconds_ago">
+ <item quantity="one">"před 1 s"</item>
+ <item quantity="other">"před <xliff:g id="COUNT">%d</xliff:g> s"</item>
+ </plurals>
+ <plurals name="abbrev_num_minutes_ago">
+ <item quantity="one">"před 1 min."</item>
+ <item quantity="other">"před <xliff:g id="COUNT">%d</xliff:g> min."</item>
+ </plurals>
+ <plurals name="abbrev_num_hours_ago">
+ <item quantity="one">"před 1 hodinou"</item>
+ <item quantity="other">"před <xliff:g id="COUNT">%d</xliff:g> hod."</item>
+ </plurals>
+ <plurals name="abbrev_num_days_ago">
+ <item quantity="one">"včera"</item>
+ <item quantity="other">"před <xliff:g id="COUNT">%d</xliff:g> dny"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_seconds">
+ <item quantity="one">"za 1 s"</item>
+ <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> s"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_minutes">
+ <item quantity="one">"za 1 min."</item>
+ <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> min."</item>
+ </plurals>
+ <plurals name="abbrev_in_num_hours">
+ <item quantity="one">"za 1 hodinu"</item>
+ <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> hod."</item>
+ </plurals>
+ <plurals name="abbrev_in_num_days">
+ <item quantity="one">"zítra"</item>
+ <item quantity="other">"zbývající počet dní: <xliff:g id="COUNT">%d</xliff:g>"</item>
+ </plurals>
<string name="preposition_for_date">"%s"</string>
<string name="preposition_for_time">"%s"</string>
<string name="preposition_for_year">"v roce %s"</string>
@@ -553,17 +556,15 @@
<string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <!-- no translation found for date_time (6104442718633642836) -->
- <skip />
- <!-- no translation found for relative_time (1818557177829411417) -->
- <skip />
+ <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"poledne"</string>
<string name="Noon">"Poledne"</string>
<string name="midnight">"půlnoc"</string>
@@ -691,8 +692,7 @@
<string name="paste">"Vložit"</string>
<string name="copyUrl">"Kopírovat adresu URL"</string>
<string name="inputMethod">"Metoda zadávání dat"</string>
- <!-- no translation found for addToDictionary (726256909274177272) -->
- <skip />
+ <string name="addToDictionary">"Přidat „%s“ do slovníku"</string>
<string name="editTextMenuTitle">"Úpravy textu"</string>
<string name="low_internal_storage_view_title">"Málo paměti"</string>
<string name="low_internal_storage_view_text">"V telefonu zbývá málo místa pro ukládání dat."</string>
@@ -700,8 +700,7 @@
<string name="cancel">"Zrušit"</string>
<string name="yes">"OK"</string>
<string name="no">"Zrušit"</string>
- <!-- no translation found for dialog_alert_title (2049658708609043103) -->
- <skip />
+ <string name="dialog_alert_title">"Upozornění"</string>
<string name="capital_on">"ZAPNUTO"</string>
<string name="capital_off">"VYPNOUT"</string>
<string name="whichApplication">"Dokončit akci pomocí aplikace"</string>
@@ -725,8 +724,7 @@
<string name="volume_music">"Hlasitost médií"</string>
<string name="volume_music_hint_playing_through_bluetooth">"Přehrávání pomocí rozhraní Bluetooth"</string>
<string name="volume_call">"Hlasitost hovoru"</string>
- <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
- <skip />
+ <string name="volume_bluetooth_call">"Hlasitost příchozích hovorů při připojení Bluetooth"</string>
<string name="volume_alarm">"Hlasitost upozornění a budíku"</string>
<string name="volume_notification">"Hlasitost oznámení"</string>
<string name="volume_unknown">"Hlasitost"</string>
@@ -762,60 +760,35 @@
<string name="usb_storage_error_message">"Při používání vaší karty SD jako úložiště USB došlo k problému."</string>
<string name="usb_storage_notification_title">"USB připojeno"</string>
<string name="usb_storage_notification_message">"Vyberte, chcete-li kopírovat soubory do nebo z počítače."</string>
- <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
- <skip />
- <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
- <skip />
- <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
- <skip />
- <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
- <skip />
- <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
- <skip />
- <!-- no translation found for extmedia_format_title (8663247929551095854) -->
- <skip />
- <!-- no translation found for extmedia_format_message (3621369962433523619) -->
- <skip />
- <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
- <skip />
+ <string name="usb_storage_stop_notification_title">"Vypnout úložiště USB"</string>
+ <string name="usb_storage_stop_notification_message">"Vyberte, chcete-li vypnout úložiště USB."</string>
+ <string name="usb_storage_stop_title">"Vypnout úložiště USB"</string>
+ <string name="usb_storage_stop_message">"Před vypnutím úložiště USB se přesvědčte, zda byl hostitel USB odpojen. Úložiště USB vypnete volbou Vypnout."</string>
+ <string name="usb_storage_stop_button_mount">"Vypnout"</string>
+ <string name="usb_storage_stop_button_unmount">"Zrušit"</string>
+ <string name="usb_storage_stop_error_message">"Při vypínání úložiště USB došlo k problémům. Zkontrolujte, zda byl hostitel USB odpojen, a zkuste to znovu."</string>
+ <string name="extmedia_format_title">"Formátovat kartu SD"</string>
+ <string name="extmedia_format_message">"Opravdu chcete kartu SD naformátovat? Všechna data na kartě budou ztracena."</string>
+ <string name="extmedia_format_button_format">"Formátovat"</string>
<string name="select_input_method">"Výběr metody zadávání dat"</string>
<string name="fast_scroll_alphabet">"AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
<string name="fast_scroll_numeric_alphabet">"0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
- <!-- no translation found for candidates_style (4333913089637062257) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
- <skip />
- <!-- no translation found for activity_list_empty (4168820609403385789) -->
- <skip />
- <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
- <skip />
- <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
- <skip />
+ <string name="candidates_style"><u>"kandidáti"</u></string>
+ <string name="ext_media_checking_notification_title">"Příprava karty SD"</string>
+ <string name="ext_media_checking_notification_message">"Kontrola chyb"</string>
+ <string name="ext_media_nofs_notification_title">"Prázdná karta SD"</string>
+ <string name="ext_media_nofs_notification_message">"Karta SD je prázdná nebo používá nepodporovaný systém souborů."</string>
+ <string name="ext_media_unmountable_notification_title">"Poškozená karta SD"</string>
+ <string name="ext_media_unmountable_notification_message">"Karta SD je poškozena. Pravděpodobně ji bude nutné znovu formátovat."</string>
+ <string name="ext_media_badremoval_notification_title">"Karta SD byla neočekávaně odebrána"</string>
+ <string name="ext_media_badremoval_notification_message">"Chcete-li zabránit ztrátě dat, kartu SD před odebráním odpojte."</string>
+ <string name="ext_media_safe_unmount_notification_title">"Kartu SD je možné bezpečně odebrat"</string>
+ <string name="ext_media_safe_unmount_notification_message">"Kartu SD lze nyní bezpečně vyjmout."</string>
+ <string name="ext_media_nomedia_notification_title">"Karta SD byla odstraněna"</string>
+ <string name="ext_media_nomedia_notification_message">"Karta SD byla odebrána. Chcete-li zvětšit úložiště svého zařízení, vložte kartu SD."</string>
+ <string name="activity_list_empty">"Nebyly nalezeny žádné odpovídající aktivity."</string>
+ <string name="permlab_pkgUsageStats">"aktualizovat statistiku použití součástí"</string>
+ <string name="permdesc_pkgUsageStats">"Umožňuje změnu shromážděných statistických údajů o použití součástí. Není určeno pro běžné aplikace."</string>
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) -->
<skip />
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index d9c4174..113c226 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_reboot">"Ermöglicht der Anwendung, einen Neustart des Telefons zu erzwingen."</string>
<string name="permlab_mount_unmount_filesystems">"Dateisysteme bereitstellen oder Bereitstellung aufheben"</string>
<string name="permdesc_mount_unmount_filesystems">"Ermöglicht der Anwendung, Dateisysteme für austauschbare Speicherplätze bereitzustellen oder die Bereitstellung aufzuheben."</string>
- <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
- <skip />
- <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
- <skip />
+ <string name="permlab_mount_format_filesystems">"Externen Speicher formatieren"</string>
+ <string name="permdesc_mount_format_filesystems">"Erlaubt der Anwendung, austauschbaren Speicher zu formatieren."</string>
<string name="permlab_vibrate">"Vibrationsalarm steuern"</string>
<string name="permdesc_vibrate">"Ermöglicht der Anwendung, den Vibrationsalarm zu steuern."</string>
<string name="permlab_flashlight">"Lichtanzeige steuern"</string>
@@ -280,10 +278,8 @@
<string name="permdesc_locationUpdates">"Ermöglicht die Aktivierung/Deaktivierung der Radio-Benachrichtigungen über Standort-Updates. Nicht für normale Anwendungen vorgesehen."</string>
<string name="permlab_checkinProperties">"Auf Check-In-Eigenschaften zugreifen"</string>
<string name="permdesc_checkinProperties">"Ermöglicht den Schreib-/Lesezugriff auf vom Check-In-Service hochgeladene Elemente. Nicht für normale Anwendungen vorgesehen."</string>
- <!-- no translation found for permlab_bindGadget (2519859363977647275) -->
- <skip />
- <!-- no translation found for permdesc_bindGadget (7865866514555126333) -->
- <skip />
+ <string name="permlab_bindGadget">"Gadgets auswählen"</string>
+ <string name="permdesc_bindGadget">"Bei dieser Option meldet die Anwendung dem System, welche Gadgets von welcher Anwendung verwendet werden können. Mit dieser Genehmigung können Anwendungen anderen Anwendungen Zugriff auf persönliche Daten geben. Nicht für normale Anwendungen vorgesehen."</string>
<string name="permlab_modifyPhoneState">"Telefonstatus ändern"</string>
<string name="permdesc_modifyPhoneState">"Ermöglicht einer Anwendung, die Telefonfunktionen des Gerätes zu steuern. Eine Anwendung mit dieser Berechtigung kann unter anderem das Netzwerk wechseln oder das Radio des Telefons ein- und ausschalten, ohne Sie darüber zu informieren."</string>
<string name="permlab_readPhoneState">"Telefonstatus lesen"</string>
@@ -312,10 +308,8 @@
<string name="permdesc_writeApnSettings">"Ermöglicht einer Anwendung, die APN-Einstellungen wie Proxy und Port eines Zugriffspunkts zu ändern."</string>
<string name="permlab_changeNetworkState">"Netzwerkkonnektivität ändern"</string>
<string name="permdesc_changeNetworkState">"Ermöglicht einer Anwendung, den Status der Netzwerkkonnektivität zu ändern."</string>
- <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
- <skip />
- <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
- <skip />
+ <string name="permlab_changeBackgroundDataSetting">"Einstellung zur Verwendung von Hintergrunddaten ändern"</string>
+ <string name="permdesc_changeBackgroundDataSetting">"Ermöglicht einer Anwendung, die Einstellung der Verwendung von Hintergrunddaten zu ändern."</string>
<string name="permlab_accessWifiState">"WLAN-Status anzeigen"</string>
<string name="permdesc_accessWifiState">"Ermöglicht einer Anwendung, die Informationen zum WLAN-Status einzusehen."</string>
<string name="permlab_changeWifiState">"WLAN-Status ändern"</string>
@@ -336,14 +330,10 @@
<string name="permdesc_subscribedFeedsRead">"Ermöglicht einer Anwendung, Details zu den zurzeit synchronisierten Feeds abzurufen."</string>
<string name="permlab_subscribedFeedsWrite">"Abonnierte Feeds schreiben"</string>
<string name="permdesc_subscribedFeedsWrite">"Ermöglicht einer Anwendung, Änderungen an den kürzlich synchronisierten Feeds vorzunehmen. Schädliche Anwendungen könnten so Ihre synchronisierten Feeds ändern."</string>
- <!-- no translation found for permlab_readDictionary (432535716804748781) -->
- <skip />
- <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
- <skip />
- <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
- <skip />
- <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
- <skip />
+ <string name="permlab_readDictionary">"Nutzerdefiniertes Wörterbuch lesen"</string>
+ <string name="permdesc_readDictionary">"Erlaubt einer Anwendung, alle privaten Wörter, Namen und Ausdrücke zu lesen, die ein Nutzer in seinem Wörterbuch gespeichert hat."</string>
+ <string name="permlab_writeDictionary">"in nutzerdefiniertes Wörterbuch schreiben"</string>
+ <string name="permdesc_writeDictionary">"Erlaubt einer Anwendung, neue Wörter in das Wörterbuch des Nutzers zu schreiben."</string>
<string-array name="phoneTypes">
<item>"Privat"</item>
<item>"Mobil"</item>
@@ -440,12 +430,9 @@
<string name="factorytest_not_system">"Die Aktion FACTORY_TEST wird nur für unter \"/system/app\" gespeicherte Pakete unterstützt."</string>
<string name="factorytest_no_action">"Es wurden kein Paket mit der Aktion FACTORY_TEST gefunden."</string>
<string name="factorytest_reboot">"Neu booten"</string>
- <!-- no translation found for js_dialog_title (8143918455087008109) -->
- <skip />
- <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
- <skip />
- <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
- <skip />
+ <string name="js_dialog_title">"Die Seite auf \'<xliff:g id="TITLE">%s</xliff:g>\' sagt:"</string>
+ <string name="js_dialog_title_default">"JavaScript"</string>
+ <string name="js_dialog_before_unload">"Von dieser Seite navigieren?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Wählen Sie \"OK\", um fortzufahren, oder wählen Sie \"Abbrechen\", um auf der aktuellen Seite zu bleiben."</string>
<string name="save_password_label">"Bestätigen"</string>
<string name="save_password_message">"Möchten Sie, dass der Browser dieses Passwort speichert?"</string>
<string name="save_password_notnow">"Nicht jetzt"</string>
@@ -496,22 +483,38 @@
<item quantity="one">"morgen"</item>
<item quantity="other">"in <xliff:g id="COUNT">%d</xliff:g> Tagen"</item>
</plurals>
- <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) -->
- <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) -->
- <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) -->
- <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) -->
- <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) -->
- <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) -->
- <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) -->
- <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) -->
- <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) -->
- <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) -->
- <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) -->
- <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) -->
- <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) -->
- <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) -->
- <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) -->
- <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) -->
+ <plurals name="abbrev_num_seconds_ago">
+ <item quantity="one">"vor 1 Sekunde"</item>
+ <item quantity="other">"Vor <xliff:g id="COUNT">%d</xliff:g> Sekunden"</item>
+ </plurals>
+ <plurals name="abbrev_num_minutes_ago">
+ <item quantity="one">"vor 1 Minute"</item>
+ <item quantity="other">"vor <xliff:g id="COUNT">%d</xliff:g> Minuten"</item>
+ </plurals>
+ <plurals name="abbrev_num_hours_ago">
+ <item quantity="one">"Vor 1 Stunde"</item>
+ <item quantity="other">"Vor <xliff:g id="COUNT">%d</xliff:g> Stunden"</item>
+ </plurals>
+ <plurals name="abbrev_num_days_ago">
+ <item quantity="one">"Gestern"</item>
+ <item quantity="other">"Vor <xliff:g id="COUNT">%d</xliff:g> Tagen"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_seconds">
+ <item quantity="one">"in 1 Sekunde"</item>
+ <item quantity="other">"in <xliff:g id="COUNT">%d</xliff:g> Sekunden"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_minutes">
+ <item quantity="one">"in 1 Minute"</item>
+ <item quantity="other">"in <xliff:g id="COUNT">%d</xliff:g> Minuten"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_hours">
+ <item quantity="one">"in 1 Stunde"</item>
+ <item quantity="other">"In <xliff:g id="COUNT">%d</xliff:g> Stunden"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_days">
+ <item quantity="one">"morgen"</item>
+ <item quantity="other">"in <xliff:g id="COUNT">%d</xliff:g> Tagen"</item>
+ </plurals>
<string name="preposition_for_date">"am %s"</string>
<string name="preposition_for_time">"am %s"</string>
<string name="preposition_for_year">"in %s"</string>
@@ -542,8 +545,7 @@
<string name="VideoView_error_title">"Video kann nicht wiedergegeben werden."</string>
<string name="VideoView_error_text_unknown">"Dieses Video kann leider nicht abgespielt werden."</string>
<string name="VideoView_error_button">"OK"</string>
- <!-- no translation found for am (4885350190794996052) -->
- <skip />
+ <string name="am">"AM"</string>
<string name="pm">".."</string>
<string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
@@ -554,17 +556,15 @@
<string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <!-- no translation found for date_time (6104442718633642836) -->
- <skip />
- <!-- no translation found for relative_time (1818557177829411417) -->
- <skip />
+ <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'. '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"Mittag"</string>
<string name="Noon">"Mittag"</string>
<string name="midnight">"Mitternacht"</string>
@@ -692,8 +692,7 @@
<string name="paste">"Einfügen"</string>
<string name="copyUrl">"URL kopieren"</string>
<string name="inputMethod">"Eingabemethode"</string>
- <!-- no translation found for addToDictionary (726256909274177272) -->
- <skip />
+ <string name="addToDictionary">"\"%s\" dem Wörterbuch hinzufügen"</string>
<string name="editTextMenuTitle">"Text bearbeiten"</string>
<string name="low_internal_storage_view_title">"Geringer Speicher"</string>
<string name="low_internal_storage_view_text">"Kaum noch freier Telefonspeicher verfügbar."</string>
@@ -701,8 +700,7 @@
<string name="cancel">"Abbrechen"</string>
<string name="yes">"OK"</string>
<string name="no">"Abbrechen"</string>
- <!-- no translation found for dialog_alert_title (2049658708609043103) -->
- <skip />
+ <string name="dialog_alert_title">"Achtung"</string>
<string name="capital_on">"EIN"</string>
<string name="capital_off">"AUS"</string>
<string name="whichApplication">"Aktion beenden mit"</string>
@@ -726,8 +724,7 @@
<string name="volume_music">"Medienlautstärke"</string>
<string name="volume_music_hint_playing_through_bluetooth">"Wiedergabe durch Bluetooth"</string>
<string name="volume_call">"Hörerlautstärke"</string>
- <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
- <skip />
+ <string name="volume_bluetooth_call">"Lautstärke bei eingehendem Bluetooth-Anruf"</string>
<string name="volume_alarm">"Lautstärke für Alarm"</string>
<string name="volume_notification">"Benachrichtigungslautstärke"</string>
<string name="volume_unknown">"Lautstärke"</string>
@@ -763,60 +760,35 @@
<string name="usb_storage_error_message">"Bei der Verwendung Ihrer SD-Karte als USB-Speicher ist ein Problem aufgetreten."</string>
<string name="usb_storage_notification_title">"USB-Verbindung"</string>
<string name="usb_storage_notification_message">"Wählen Sie die Dateien aus, die von Ihrem oder auf Ihren Computer kopiert werden sollen."</string>
- <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
- <skip />
- <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
- <skip />
- <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
- <skip />
- <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
- <skip />
- <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
- <skip />
- <!-- no translation found for extmedia_format_title (8663247929551095854) -->
- <skip />
- <!-- no translation found for extmedia_format_message (3621369962433523619) -->
- <skip />
- <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
- <skip />
+ <string name="usb_storage_stop_notification_title">"USB-Speicher deaktivieren"</string>
+ <string name="usb_storage_stop_notification_message">"Auswählen, um USB-Speicher zu deaktivieren."</string>
+ <string name="usb_storage_stop_title">"USB-Speicher deaktivieren"</string>
+ <string name="usb_storage_stop_message">"Bevor Sie den USB-Speicher deaktivieren, stellen Sie sicher, dass Sie Ihn vom USB-Host getrennt haben. Wählen Sie \"Deaktivieren\", um den USB-Speicher zu deaktivieren."</string>
+ <string name="usb_storage_stop_button_mount">"Ausschalten"</string>
+ <string name="usb_storage_stop_button_unmount">"Abbrechen"</string>
+ <string name="usb_storage_stop_error_message">"Wir haben beim Deaktivieren des USB-Speichers ein Problem festgestellt. Überprüfen Sie, ob Sie den USB-Host getrennt haben, und versuchen Sie es erneut."</string>
+ <string name="extmedia_format_title">"SD-Karte formatieren"</string>
+ <string name="extmedia_format_message">"Möchten Sie die SD-Karte wirklich formatieren? Alle Daten auf Ihrer Karte gehen dann verloren."</string>
+ <string name="extmedia_format_button_format">"Format"</string>
<string name="select_input_method">"Eingabemethode auswählen"</string>
<string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
- <!-- no translation found for candidates_style (4333913089637062257) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
- <skip />
- <!-- no translation found for activity_list_empty (4168820609403385789) -->
- <skip />
- <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
- <skip />
- <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
- <skip />
+ <string name="candidates_style"><u>"Kandidaten"</u></string>
+ <string name="ext_media_checking_notification_title">"SD-Karte wird vorbereitet"</string>
+ <string name="ext_media_checking_notification_message">"Nach Fehlern wird gesucht"</string>
+ <string name="ext_media_nofs_notification_title">"SD-Karte leer"</string>
+ <string name="ext_media_nofs_notification_message">"Die SD-Karte ist leer oder verwendet ein Dateisystem, das nicht unterstützt wird."</string>
+ <string name="ext_media_unmountable_notification_title">"Beschädigte SD-Karte"</string>
+ <string name="ext_media_unmountable_notification_message">"Die SD-Karte ist beschädigt. Sie müssen Ihre Karte eventuell neu formatieren."</string>
+ <string name="ext_media_badremoval_notification_title">"SD-Karte unerwartet entfernt"</string>
+ <string name="ext_media_badremoval_notification_message">"SD-Karte vor dem Entnehmen trennen, um Datenverlust zu vermeiden."</string>
+ <string name="ext_media_safe_unmount_notification_title">"SD-Karte\nkann entfernt werden."</string>
+ <string name="ext_media_safe_unmount_notification_message">"Die SD-Karte kann jetzt entfernt werden."</string>
+ <string name="ext_media_nomedia_notification_title">"SD-Karte entfernt"</string>
+ <string name="ext_media_nomedia_notification_message">"Die SD-Karte wurde entfernt. Legen Sie eine neue SD-Karte ein, um den Speicherplatz Ihres Geräts zu erweitern."</string>
+ <string name="activity_list_empty">"Keine passenden Aktivitäten gefunden"</string>
+ <string name="permlab_pkgUsageStats">"Nutzungsstatistik der Komponente aktualisieren"</string>
+ <string name="permdesc_pkgUsageStats">"Ermöglicht die Änderung von gesammelten Nutzungsstatistiken der Komponente. Nicht für normale Anwendungen vorgesehen."</string>
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) -->
<skip />
</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index b9df983..9da879b 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -710,7 +710,7 @@
<!-- no translation found for lockscreen_glogin_invalid_input (4881057177478491580) -->
<skip />
<!-- no translation found for status_bar_time_format (2168573805413119180) -->
- <skip />
+ <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
<!-- no translation found for hour_minute_ampm (1850330605794978742) -->
<skip />
<!-- no translation found for hour_minute_cap_ampm (1122840227537374196) -->
@@ -861,34 +861,38 @@
<skip />
<!-- no translation found for pm (7206933220587555766) -->
<skip />
- <!-- no translation found for numeric_date (5120078478872821100) -->
+ <!-- from values-de/strings.xml and removal of all the german craziyness-->
<skip />
+ <!-- no translation found for numeric_date (5120078478872821100) -->
+ <string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for wday1_date1_time1_wday2_date2_time2 (7066878981949584861) -->
- <skip />
+ <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<!-- no translation found for wday1_date1_wday2_date2 (8671068747172261907) -->
+ <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
+ <!-- no translation found for numeric_date (5537215108967329745) -->
<skip />
<!-- no translation found for date1_time1_date2_time2 (3645498975775629615) -->
- <skip />
+ <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<!-- no translation found for date1_date2 (377057563556488062) -->
- <skip />
+ <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<!-- no translation found for time1_time2 (3173474242109288305) -->
- <skip />
+ <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
<!-- no translation found for time_wday_date (8928955562064570313) -->
- <skip />
+ <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<!-- no translation found for wday_date (8794741400546136975) -->
- <skip />
+ <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<!-- no translation found for time_date (1922644512833014496) -->
- <skip />
+ <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<!-- no translation found for time_wday (1422050241301754712) -->
<skip />
<!-- no translation found for full_date_month_first (6011143962222283357) -->
<skip />
<!-- no translation found for full_date_day_first (8621594762705478189) -->
- <skip />
+ <string name="full_date_day_first">"<xliff:g id="DAY">dd</xliff:g> <xliff:g id="MONTH">MMMM</xliff:g> <xliff:g id="YEAR">yyyy</xliff:g>"</string>
<!-- no translation found for medium_date_month_first (48990963718825728) -->
<skip />
<!-- no translation found for medium_date_day_first (2898992016440387123) -->
- <skip />
+ <string name="medium_date_day_first">"<xliff:g id="DAY">dd</xliff:g> <xliff:g id="MONTH">MMM</xliff:g> <xliff:g id="YEAR">yyyy</xliff:g>"</string>
<!-- no translation found for twelve_hour_time_format (6015557937879492156) -->
<skip />
<!-- no translation found for twenty_four_hour_time_format (5176807998669709535) -->
@@ -902,71 +906,73 @@
<!-- no translation found for Midnight (1260172107848123187) -->
<skip />
<!-- no translation found for month_day (3356633704511426364) -->
- <skip />
+ <string name="month_day">"<xliff:g id="day" example="9">%-d</xliff:g> <xliff:g id="month" example="October">%B</xliff:g>"</string>
<!-- no translation found for month (3017405760734206414) -->
<skip />
<!-- no translation found for month_day_year (2435948225709176752) -->
- <skip />
+ <string name="month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for month_year (6228414124777343135) -->
<skip />
<!-- no translation found for time_of_day (8375993139317154157) -->
- <skip />
+ <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
<!-- no translation found for date_and_time (9197690194373107109) -->
<skip />
<!-- no translation found for same_year_md1_md2 (9199324363135981317) -->
- <skip />
+ <string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_md1_wday2_md2 (6006392413355305178) -->
- <skip />
+ <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
+ <!-- no translation found for date_and_time (353898423108629694) -->
+ <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for same_year_mdy1_mdy2 (1576657593937827090) -->
- <skip />
+ <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_mdy1_wday2_mdy2 (9135935796468891580) -->
- <skip />
+ <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
<!-- no translation found for same_year_md1_time1_md2_time2 (2172964106375558081) -->
- <skip />
+ <string name="same_year_md1_time1_md2_time2">" <xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_md1_time1_wday2_md2_time2 (1702879534101786310) -->
- <skip />
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_year_mdy1_time1_mdy2_time2 (2476443311723358767) -->
- <skip />
+ <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_mdy1_time1_wday2_mdy2_time2 (1564837340334069879) -->
- <skip />
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_md1_md2 (8908376522875100300) -->
- <skip />
+ <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_md1_wday2_md2 (3239690882018292077) -->
- <skip />
+ <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for numeric_mdy1_mdy2 (8883797176939233525) -->
- <skip />
+ <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_mdy1_wday2_mdy2 (4150475769255828954) -->
- <skip />
+ <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
<!-- no translation found for numeric_md1_time1_md2_time2 (3624746590607741419) -->
- <skip />
+ <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_md1_time1_wday2_md2_time2 (4258040955467298134) -->
- <skip />
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_mdy1_time1_mdy2_time2 (3598215409314517987) -->
- <skip />
+ <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_mdy1_time1_wday2_mdy2_time2 (264076937155877259) -->
- <skip />
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_md1_md2 (2393563617438036111) -->
- <skip />
+ <string name="same_month_md1_md2">"<xliff:g id="DAY1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="DAY2" example="3">%8$s</xliff:g> <xliff:g id="MONTH1" example="Oct">%2$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_md1_wday2_md2 (1208946773794057819) -->
- <skip />
+ <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for same_month_mdy1_mdy2 (3713236637869030492) -->
- <skip />
+ <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="DAY2" example="3">%8$s</xliff:g> <xliff:g id="MONTH1" example="Oct">%2$s</xliff:g> <xliff:g id="YEAR2" example="2007">%9$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_mdy1_wday2_mdy2 (389638922479870472) -->
- <skip />
+ <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
<!-- no translation found for same_month_md1_time1_md2_time2 (7477075526337542685) -->
- <skip />
+ <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_md1_time1_wday2_md2_time2 (3516978303779391173) -->
- <skip />
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_mdy1_time1_mdy2_time2 (7320410992514057310) -->
- <skip />
+ <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_mdy1_time1_wday2_mdy2_time2 (1332950588774239228) -->
- <skip />
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month_day_year (5767271534015320250) -->
- <skip />
+ <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for abbrev_month_year (8058929633673942490) -->
<skip />
<!-- no translation found for abbrev_month_day (458867920693482757) -->
- <skip />
+ <string name="abbrev_month_day">"<xliff:g id="day" example="31">%-d</xliff:g> <xliff:g id="month" example="Oct">%b</xliff:g>"</string>
<!-- no translation found for abbrev_month (1674509986330181349) -->
<skip />
<!-- no translation found for day_of_week_long_sunday (9057662850446501884) -->
@@ -1112,9 +1118,9 @@
<!-- no translation found for month_shortest_december (6213739417171334040) -->
<skip />
<!-- no translation found for elapsed_time_short_format_mm_ss (1294409362352514646) -->
- <skip />
+ <string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<!-- no translation found for elapsed_time_short_format_h_mm_ss (2997059666628785039) -->
- <skip />
+ <string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<!-- no translation found for selectAll (691691810023908884) -->
<skip />
<!-- no translation found for cut (5845613239192595662) -->
diff --git a/core/res/res/values-en-rSG/strings.xml b/core/res/res/values-en-rSG/strings.xml
index b9df983..6850a5d 100644
--- a/core/res/res/values-en-rSG/strings.xml
+++ b/core/res/res/values-en-rSG/strings.xml
@@ -710,7 +710,7 @@
<!-- no translation found for lockscreen_glogin_invalid_input (4881057177478491580) -->
<skip />
<!-- no translation found for status_bar_time_format (2168573805413119180) -->
- <skip />
+ <string name="status_bar_time_format">"<xliff:g id="HOUR">h</xliff:g>:<xliff:g id="MINUTE">mm</xliff:g> <xliff:g id="AMPM">AA</xliff:g>"</string>
<!-- no translation found for hour_minute_ampm (1850330605794978742) -->
<skip />
<!-- no translation found for hour_minute_cap_ampm (1122840227537374196) -->
@@ -861,34 +861,35 @@
<skip />
<!-- no translation found for pm (7206933220587555766) -->
<skip />
- <!-- no translation found for numeric_date (5120078478872821100) -->
- <skip />
+ <!-- copied from values-de/strings.xml with the crazyness of the . removed-->
<!-- no translation found for wday1_date1_time1_wday2_date2_time2 (7066878981949584861) -->
- <skip />
+ <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<!-- no translation found for wday1_date1_wday2_date2 (8671068747172261907) -->
- <skip />
+ <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string>
+ <!-- no translation found for numeric_date (5537215108967329745) -->
+ <string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for date1_time1_date2_time2 (3645498975775629615) -->
- <skip />
+ <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<!-- no translation found for date1_date2 (377057563556488062) -->
- <skip />
+ <string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>"</string>
<!-- no translation found for time1_time2 (3173474242109288305) -->
- <skip />
+ <string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g> – <xliff:g id="TIME2">%2$s</xliff:g>"</string>
<!-- no translation found for time_wday_date (8928955562064570313) -->
- <skip />
+ <string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<!-- no translation found for wday_date (8794741400546136975) -->
- <skip />
+ <string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<!-- no translation found for time_date (1922644512833014496) -->
- <skip />
+ <string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<!-- no translation found for time_wday (1422050241301754712) -->
- <skip />
+ <string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
<!-- no translation found for full_date_month_first (6011143962222283357) -->
<skip />
<!-- no translation found for full_date_day_first (8621594762705478189) -->
- <skip />
+ <string name="full_date_day_first">"<xliff:g id="DAY">dd</xliff:g> <xliff:g id="MONTH">MMMM</xliff:g> <xliff:g id="YEAR">yyyy</xliff:g>"</string>
<!-- no translation found for medium_date_month_first (48990963718825728) -->
<skip />
<!-- no translation found for medium_date_day_first (2898992016440387123) -->
- <skip />
+ <string name="medium_date_day_first">"<xliff:g id="DAY">dd</xliff:g> <xliff:g id="MONTH">MMM</xliff:g> <xliff:g id="YEAR">yyyy</xliff:g>"</string>
<!-- no translation found for twelve_hour_time_format (6015557937879492156) -->
<skip />
<!-- no translation found for twenty_four_hour_time_format (5176807998669709535) -->
@@ -902,71 +903,71 @@
<!-- no translation found for Midnight (1260172107848123187) -->
<skip />
<!-- no translation found for month_day (3356633704511426364) -->
- <skip />
+ <string name="month_day">"<xliff:g id="day" example="9">%-d</xliff:g> <xliff:g id="month" example="October">%B</xliff:g>"</string>
<!-- no translation found for month (3017405760734206414) -->
<skip />
<!-- no translation found for month_day_year (2435948225709176752) -->
- <skip />
+ <string name="month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for month_year (6228414124777343135) -->
<skip />
<!-- no translation found for time_of_day (8375993139317154157) -->
- <skip />
+ <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
<!-- no translation found for date_and_time (9197690194373107109) -->
- <skip />
+ <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for same_year_md1_md2 (9199324363135981317) -->
- <skip />
+ <string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_md1_wday2_md2 (6006392413355305178) -->
- <skip />
+ <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for same_year_mdy1_mdy2 (1576657593937827090) -->
- <skip />
+ <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_mdy1_wday2_mdy2 (9135935796468891580) -->
- <skip />
+ <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string>
<!-- no translation found for same_year_md1_time1_md2_time2 (2172964106375558081) -->
<skip />
<!-- no translation found for same_year_wday1_md1_time1_wday2_md2_time2 (1702879534101786310) -->
- <skip />
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_year_mdy1_time1_mdy2_time2 (2476443311723358767) -->
- <skip />
+ <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_year_wday1_mdy1_time1_wday2_mdy2_time2 (1564837340334069879) -->
- <skip />
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_md1_md2 (8908376522875100300) -->
- <skip />
+ <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_md1_wday2_md2 (3239690882018292077) -->
- <skip />
+ <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for numeric_mdy1_mdy2 (8883797176939233525) -->
- <skip />
+ <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_mdy1_wday2_mdy2 (4150475769255828954) -->
- <skip />
+ <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string>
<!-- no translation found for numeric_md1_time1_md2_time2 (3624746590607741419) -->
- <skip />
+ <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_md1_time1_wday2_md2_time2 (4258040955467298134) -->
- <skip />
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_mdy1_time1_mdy2_time2 (3598215409314517987) -->
- <skip />
+ <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for numeric_wday1_mdy1_time1_wday2_mdy2_time2 (264076937155877259) -->
- <skip />
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_md1_md2 (2393563617438036111) -->
- <skip />
+ <string name="same_month_md1_md2">"<xliff:g id="DAY1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="DAY2" example="3">%8$s</xliff:g> <xliff:g id="MONTH1" example="Oct">%2$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_md1_wday2_md2 (1208946773794057819) -->
- <skip />
+ <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>"</string>
<!-- no translation found for same_month_mdy1_mdy2 (3713236637869030492) -->
- <skip />
+ <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1" example="31">%3$s</xliff:g> \u2013 <xliff:g id="DAY2" example="3">%8$s</xliff:g> <xliff:g id="MONTH1" example="Oct">%2$s</xliff:g> <xliff:g id="YEAR2" example="2007">%9$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_mdy1_wday2_mdy2 (389638922479870472) -->
- <skip />
+ <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string>
<!-- no translation found for same_month_md1_time1_md2_time2 (7477075526337542685) -->
- <skip />
+ <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_md1_time1_wday2_md2_time2 (3516978303779391173) -->
- <skip />
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_mdy1_time1_mdy2_time2 (7320410992514057310) -->
- <skip />
+ <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for same_month_wday1_mdy1_time1_wday2_mdy2_time2 (1332950588774239228) -->
- <skip />
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g> <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g> <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string>
<!-- no translation found for abbrev_month_day_year (5767271534015320250) -->
- <skip />
+ <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string>
<!-- no translation found for abbrev_month_year (8058929633673942490) -->
<skip />
<!-- no translation found for abbrev_month_day (458867920693482757) -->
- <skip />
+ <string name="abbrev_month_day">"<xliff:g id="day" example="31">%-d</xliff:g> <xliff:g id="month" example="Oct">%b</xliff:g>"</string>
<!-- no translation found for abbrev_month (1674509986330181349) -->
<skip />
<!-- no translation found for day_of_week_long_sunday (9057662850446501884) -->
@@ -1112,9 +1113,9 @@
<!-- no translation found for month_shortest_december (6213739417171334040) -->
<skip />
<!-- no translation found for elapsed_time_short_format_mm_ss (1294409362352514646) -->
- <skip />
+ <string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
<!-- no translation found for elapsed_time_short_format_h_mm_ss (2997059666628785039) -->
- <skip />
+ <string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
<!-- no translation found for selectAll (691691810023908884) -->
<skip />
<!-- no translation found for cut (5845613239192595662) -->
diff --git a/core/res/res/values-es-rES/arrays.xml b/core/res/res/values-es-rES/arrays.xml
new file mode 100644
index 0000000..7f5667c
--- /dev/null
+++ b/core/res/res/values-es-rES/arrays.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+
+ <!-- Do not translate. -->
+ <integer-array name="maps_starting_lat_lng">
+ <item>40413496</item>
+ <item>-3713379</item>
+ </integer-array>
+ <!-- Do not translate. -->
+ <integer-array name="maps_starting_zoom">
+ <item>6</item>
+ </integer-array>
+
+</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index dc17445..dc3fcd5 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -149,7 +149,7 @@
<string name="permlab_setDebugApp">"habilitar depuración de aplicación"</string>
<string name="permdesc_setDebugApp">"Permite que una aplicación active la depuración de otra aplicación. Las aplicaciones malintencionadas pueden utilizar este permiso para desactivar otras aplicaciones."</string>
<string name="permlab_changeConfiguration">"cambiar la configuración de la interfaz de usuario"</string>
- <string name="permdesc_changeConfiguration">"Permite que una aplicación cambie la configuración actual como, por ejemplo, la configuración regional o el tamaño de fuente general."</string>
+ <string name="permdesc_changeConfiguration">"Permite que una aplicación cambie la configuración actual como, por ejemplo, la configuración local o el tamaño de fuente general."</string>
<string name="permlab_restartPackages">"reiniciar otras aplicaciones"</string>
<string name="permdesc_restartPackages">"Permite que una aplicación reinicie de forma forzosa otras aplicaciones."</string>
<string name="permlab_setProcessForeground">"impedir su interrupción"</string>
@@ -262,10 +262,8 @@
<string name="permdesc_reboot">"Permite que la aplicación fuerce al teléfono a reiniciarse."</string>
<string name="permlab_mount_unmount_filesystems">"montar y desmontar sistemas de archivos"</string>
<string name="permdesc_mount_unmount_filesystems">"Permite que las aplicaciones monten y desmonten sistemas de archivos para un almacenamiento extraíble."</string>
- <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
- <skip />
- <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
- <skip />
+ <string name="permlab_mount_format_filesystems">"formatear almacenamiento externo"</string>
+ <string name="permdesc_mount_format_filesystems">"Permite a la aplicación formatear un almacenamiento extraíble."</string>
<string name="permlab_vibrate">"controlar vibración"</string>
<string name="permdesc_vibrate">"Permite que la aplicación controle la función de vibración."</string>
<string name="permlab_flashlight">"controlar linterna"</string>
@@ -280,10 +278,8 @@
<string name="permdesc_locationUpdates">"Permite habilitar/inhabilitar las notificaciones de actualización de la ubicación de la radio. No está destinado al uso por parte de aplicaciones normales."</string>
<string name="permlab_checkinProperties">"acceder a propiedades de registro"</string>
<string name="permdesc_checkinProperties">"Permite el acceso de lectura/escritura a las propiedades cargadas por el servicio de registro. No está destinado al uso por parte de aplicaciones normales."</string>
- <!-- no translation found for permlab_bindGadget (2519859363977647275) -->
- <skip />
- <!-- no translation found for permdesc_bindGadget (7865866514555126333) -->
- <skip />
+ <string name="permlab_bindGadget">"seleccionar gadgets"</string>
+ <string name="permdesc_bindGadget">"Permite a la aplicación indicar al sistema qué gadgets puede utilizar cada aplicación. Con este permiso, las aplicaciones pueden permitir a otras aplicaciones acceder a datos personales. No está destinado al uso por parte de aplicaciones normales."</string>
<string name="permlab_modifyPhoneState">"modificar estado del teléfono"</string>
<string name="permdesc_modifyPhoneState">"Permite que la aplicación controle las funciones de teléfono del dispositivo. Una aplicación con este permiso puede cambiar redes, activar y desactivar la radio, etc., sin necesidad de notificar al usuario."</string>
<string name="permlab_readPhoneState">"leer el estado del teléfono"</string>
@@ -312,10 +308,8 @@
<string name="permdesc_writeApnSettings">"Permite que una aplicación modifique los valores de configuración de un APN como, por ejemplo, el proxy y el puerto de cualquier APN."</string>
<string name="permlab_changeNetworkState">"cambiar la conectividad de red"</string>
<string name="permdesc_changeNetworkState">"Permite que una aplicación cambie la conectividad de red de estado."</string>
- <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
- <skip />
- <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
- <skip />
+ <string name="permlab_changeBackgroundDataSetting">"cambiar configuración de uso de datos de referencia"</string>
+ <string name="permdesc_changeBackgroundDataSetting">"Permite a una aplicación cambiar la configuración de uso de los datos de referencia."</string>
<string name="permlab_accessWifiState">"ver estado de la conectividad Wi-Fi"</string>
<string name="permdesc_accessWifiState">"Permite que una aplicación vea la información sobre el estado de la conectividad Wi-Fi."</string>
<string name="permlab_changeWifiState">"cambiar estado de Wi-Fi"</string>
@@ -336,14 +330,10 @@
<string name="permdesc_subscribedFeedsRead">"Permite que una aplicación obtenga detalles sobre los feeds sincronizados en este momento."</string>
<string name="permlab_subscribedFeedsWrite">"escribir feeds a los que está suscrito el usuario"</string>
<string name="permdesc_subscribedFeedsWrite">"Permite que una aplicación modifique los feeds sincronizados actualmente. Este permiso podría provocar que una aplicación malintencionada cambie los feeds sincronizados."</string>
- <!-- no translation found for permlab_readDictionary (432535716804748781) -->
- <skip />
- <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
- <skip />
- <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
- <skip />
- <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
- <skip />
+ <string name="permlab_readDictionary">"leer diccionario definido por el usuario"</string>
+ <string name="permdesc_readDictionary">"Permite a una aplicación leer cualquier frase, palabra o nombre privado que el usuario haya almacenado en su diccionario."</string>
+ <string name="permlab_writeDictionary">"escribir en el diccionario definido por el usuario"</string>
+ <string name="permdesc_writeDictionary">"Permite a una aplicación escribir palabras nuevas en el diccionario del usuario."</string>
<string-array name="phoneTypes">
<item>"Casa"</item>
<item>"Móvil"</item>
@@ -355,7 +345,7 @@
<item>"Personalizar"</item>
</string-array>
<string-array name="emailAddressTypes">
- <item>"Casa"</item>
+ <item>"Personal?????"</item>
<item>"Trabajo"</item>
<item>"Otra"</item>
<item>"Personalizar"</item>
@@ -389,12 +379,12 @@
</string-array>
<string name="keyguard_password_enter_pin_code">"Introduce el código PIN"</string>
<string name="keyguard_password_wrong_pin_code">"El código PIN es incorrecto."</string>
- <string name="keyguard_label_text">"Para desbloquear el teléfono, pulsa \"Menú\" y, a continuación, pulsa 0."</string>
+ <string name="keyguard_label_text">"Para desbloquear el teléfono, pulsa MENU y, a continuación, pulsa 0."</string>
<string name="emergency_call_dialog_number_for_display">"Número de emergencia"</string>
<string name="lockscreen_carrier_default">"(Sin servicio)"</string>
- <string name="lockscreen_screen_locked">"Pantalla bloqueada."</string>
- <string name="lockscreen_instructions_when_pattern_enabled">"Pulsa \"Menú\" para desbloquear el teléfono o realizar una llamada de emergencia."</string>
- <string name="lockscreen_instructions_when_pattern_disabled">"Pulsa \"Menú\" para desbloquear el teléfono."</string>
+ <string name="lockscreen_screen_locked">"Pantalla bloqueada"</string>
+ <string name="lockscreen_instructions_when_pattern_enabled">"Pulsa MENU para desbloquear el teléfono o realizar una llamada de emergencia."</string>
+ <string name="lockscreen_instructions_when_pattern_disabled">"Pulsa MENU para desbloquear el teléfono."</string>
<string name="lockscreen_pattern_instructions">"Crear patrón para desbloquear"</string>
<string name="lockscreen_emergency_call">"Llamada de emergencia"</string>
<string name="lockscreen_pattern_correct">"Correcto"</string>
@@ -440,12 +430,9 @@
<string name="factorytest_not_system">"La acción FACTORY_TEST sólo es compatible con los paquetes instalados en /system/app."</string>
<string name="factorytest_no_action">"No se ha encontrado ningún paquete que proporcione la acción FACTORY_TEST."</string>
<string name="factorytest_reboot">"Reiniciar"</string>
- <!-- no translation found for js_dialog_title (8143918455087008109) -->
- <skip />
- <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
- <skip />
- <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
- <skip />
+ <string name="js_dialog_title">"La página \"<xliff:g id="TITLE">%s</xliff:g>\" dice:"</string>
+ <string name="js_dialog_title_default">"JavaScript"</string>
+ <string name="js_dialog_before_unload">"¿Quieres salir de esta página?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Selecciona \"Aceptar\" para continuar o \"Cancelar\" para permanecer en la página actual."</string>
<string name="save_password_label">"Confirmar"</string>
<string name="save_password_message">"¿Deseas que el navegador recuerde esta contraseña?"</string>
<string name="save_password_notnow">"Ahora no"</string>
@@ -454,7 +441,7 @@
<string name="open_permission_deny">"No dispones de permiso para abrir esta página."</string>
<string name="text_copied">"Texto copiado al portapapeles."</string>
<string name="more_item_label">"Más"</string>
- <string name="prepend_shortcut_label">"\"Menú\"+"</string>
+ <string name="prepend_shortcut_label">"MENU+"</string>
<string name="menu_space_shortcut_label">"espacio"</string>
<string name="menu_enter_shortcut_label">"intro"</string>
<string name="menu_delete_shortcut_label">"suprimir"</string>
@@ -496,22 +483,38 @@
<item quantity="one">"mañana"</item>
<item quantity="other">"dentro de <xliff:g id="COUNT">%d</xliff:g> días"</item>
</plurals>
- <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) -->
- <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) -->
- <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) -->
- <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) -->
- <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) -->
- <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) -->
- <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) -->
- <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) -->
- <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) -->
- <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) -->
- <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) -->
- <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) -->
- <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) -->
- <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) -->
- <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) -->
- <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) -->
+ <plurals name="abbrev_num_seconds_ago">
+ <item quantity="one">"hace 1 segundo"</item>
+ <item quantity="other">"hace <xliff:g id="COUNT">%d</xliff:g> segundos"</item>
+ </plurals>
+ <plurals name="abbrev_num_minutes_ago">
+ <item quantity="one">"hace 1 minuto"</item>
+ <item quantity="other">"hace <xliff:g id="COUNT">%d</xliff:g> minutos"</item>
+ </plurals>
+ <plurals name="abbrev_num_hours_ago">
+ <item quantity="one">"hace 1 hora"</item>
+ <item quantity="other">"hace <xliff:g id="COUNT">%d</xliff:g> horas"</item>
+ </plurals>
+ <plurals name="abbrev_num_days_ago">
+ <item quantity="one">"ayer"</item>
+ <item quantity="other">"hace <xliff:g id="COUNT">%d</xliff:g> días"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_seconds">
+ <item quantity="one">"dentro de 1 segundo"</item>
+ <item quantity="other">"dentro de <xliff:g id="COUNT">%d</xliff:g> segundos"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_minutes">
+ <item quantity="one">"dentro de 1 minuto"</item>
+ <item quantity="other">"dentro de <xliff:g id="COUNT">%d</xliff:g> minutos"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_hours">
+ <item quantity="one">"dentro de 1 hora"</item>
+ <item quantity="other">"dentro de <xliff:g id="COUNT">%d</xliff:g> horas"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_days">
+ <item quantity="one">"mañana"</item>
+ <item quantity="other">"dentro de <xliff:g id="COUNT">%d</xliff:g> días"</item>
+ </plurals>
<string name="preposition_for_date">"el %s"</string>
<string name="preposition_for_time">"a las %s"</string>
<string name="preposition_for_year">"en %s"</string>
@@ -553,17 +556,15 @@
<string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <!-- no translation found for date_time (6104442718633642836) -->
- <skip />
- <!-- no translation found for relative_time (1818557177829411417) -->
- <skip />
+ <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="MONTH">MMMM</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first">"<xliff:g id="MONTH">MMMM</xliff:g>' de '<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first">"<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="MONTH">MMM</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="MONTH">MMMM</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="full_date_day_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' de '<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' de '<xliff:g id="MONTH">MMM</xliff:g>' de '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"mediodía"</string>
<string name="Noon">"Mediodía"</string>
<string name="midnight">"medianoche"</string>
@@ -691,8 +692,7 @@
<string name="paste">"Pegar"</string>
<string name="copyUrl">"Copiar URL"</string>
<string name="inputMethod">"Método de introducción de texto"</string>
- <!-- no translation found for addToDictionary (726256909274177272) -->
- <skip />
+ <string name="addToDictionary">"Añadir \"%s\" al diccionario"</string>
<string name="editTextMenuTitle">"Editar texto"</string>
<string name="low_internal_storage_view_title">"Poco espacio"</string>
<string name="low_internal_storage_view_text">"Se está agotando el espacio de almacenamiento del teléfono."</string>
@@ -700,8 +700,7 @@
<string name="cancel">"Cancelar"</string>
<string name="yes">"Aceptar"</string>
<string name="no">"Cancelar"</string>
- <!-- no translation found for dialog_alert_title (2049658708609043103) -->
- <skip />
+ <string name="dialog_alert_title">"Atención"</string>
<string name="capital_on">"Activado"</string>
<string name="capital_off">"Desconectado"</string>
<string name="whichApplication">"Completar acción utilizando"</string>
@@ -725,8 +724,7 @@
<string name="volume_music">"Volumen multimedia"</string>
<string name="volume_music_hint_playing_through_bluetooth">"Reproduciendo a través de Bluetooth"</string>
<string name="volume_call">"Volumen de la llamada"</string>
- <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
- <skip />
+ <string name="volume_bluetooth_call">"Volumen de la llamada de Bluetooth"</string>
<string name="volume_alarm">"Volumen de alarma"</string>
<string name="volume_notification">"Volumen de notificaciones"</string>
<string name="volume_unknown">"Volumen"</string>
@@ -762,60 +760,35 @@
<string name="usb_storage_error_message">"Se ha producido un problema al intentar utilizar la tarjeta SD para el almacenamiento USB."</string>
<string name="usb_storage_notification_title">"Conectado por USB"</string>
<string name="usb_storage_notification_message">"Seleccionar para copiar archivos al/desde el equipo"</string>
- <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
- <skip />
- <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
- <skip />
- <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
- <skip />
- <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
- <skip />
- <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
- <skip />
- <!-- no translation found for extmedia_format_title (8663247929551095854) -->
- <skip />
- <!-- no translation found for extmedia_format_message (3621369962433523619) -->
- <skip />
- <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
- <skip />
+ <string name="usb_storage_stop_notification_title">"Desactivar almacenamiento USB"</string>
+ <string name="usb_storage_stop_notification_message">"Selecciona esta opción para desactivar el almacenamiento USB."</string>
+ <string name="usb_storage_stop_title">"Desactivar almacenamiento USB"</string>
+ <string name="usb_storage_stop_message">"Antes de desactivar el almacenamiento USB, asegúrate de haber desmontado el host USB. Selecciona \"Desactivar\" para desactivar el almacenamiento USB."</string>
+ <string name="usb_storage_stop_button_mount">"Desactivar"</string>
+ <string name="usb_storage_stop_button_unmount">"Cancelar"</string>
+ <string name="usb_storage_stop_error_message">"Se ha producido un problema al desactivar el almacenamiento USB. Asegúrate de que has desmontado el host USB e inténtalo de nuevo."</string>
+ <string name="extmedia_format_title">"Formatear tarjeta SD"</string>
+ <string name="extmedia_format_message">"¿Estás seguro de que quieres formatear la tarjeta SD? Se perderán todos los datos de la tarjeta."</string>
+ <string name="extmedia_format_button_format">"Formato"</string>
<string name="select_input_method">"Seleccionar método de introducción de texto"</string>
<string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
- <!-- no translation found for candidates_style (4333913089637062257) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
- <skip />
- <!-- no translation found for activity_list_empty (4168820609403385789) -->
- <skip />
- <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
- <skip />
- <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
- <skip />
+ <string name="candidates_style"><u>"candidatos"</u></string>
+ <string name="ext_media_checking_notification_title">"Preparando tarjeta SD"</string>
+ <string name="ext_media_checking_notification_message">"Comprobando errores"</string>
+ <string name="ext_media_nofs_notification_title">"Tarjeta SD vacía"</string>
+ <string name="ext_media_nofs_notification_message">"La tarjeta SD está vacía o utiliza un sistema de archivos incompatible."</string>
+ <string name="ext_media_unmountable_notification_title">"Tarjeta SD dañada"</string>
+ <string name="ext_media_unmountable_notification_message">"La tarjeta SD está dañada. Es posible que sea necesario volver a formatearla."</string>
+ <string name="ext_media_badremoval_notification_title">"La tarjeta SD se ha extraído inesperadamente."</string>
+ <string name="ext_media_badremoval_notification_message">"Desmonta la tarjeta SD antes de extraerla para evitar la pérdida de datos."</string>
+ <string name="ext_media_safe_unmount_notification_title">"Es seguro extraer la tarjeta SD."</string>
+ <string name="ext_media_safe_unmount_notification_message">"Ya puedes extraer la tarjeta SD de forma segura."</string>
+ <string name="ext_media_nomedia_notification_title">"Tarjeta SD extraída"</string>
+ <string name="ext_media_nomedia_notification_message">"La tarjeta SD se ha extraído. Inserta una nueva tarjeta SD para aumentar la capacidad de almacenamiento de tu dispositivo."</string>
+ <string name="activity_list_empty">"No se ha encontrado ninguna actividad coincidente."</string>
+ <string name="permlab_pkgUsageStats">"actualizar estadísticas de uso de componentes"</string>
+ <string name="permdesc_pkgUsageStats">"Permite la modificación de estadísticas recopiladas sobre el uso de componentes. No está destinado al uso por parte de aplicaciones normales."</string>
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) -->
<skip />
</resources>
diff --git a/core/res/res/values-fr-rFR/arrays.xml b/core/res/res/values-fr-rFR/arrays.xml
new file mode 100644
index 0000000..504ab0f
--- /dev/null
+++ b/core/res/res/values-fr-rFR/arrays.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+
+ <!-- Do not translate. -->
+ <integer-array name="maps_starting_lat_lng">
+ <item>48850258</item>
+ <item>2351074</item>
+ </integer-array>
+ <!-- Do not translate. -->
+ <integer-array name="maps_starting_zoom">
+ <item>6</item>
+ </integer-array>
+
+</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 95e3052..45b8f03 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -38,7 +38,7 @@
<string name="badPin">"L\'ancien code PIN saisi est incorrect."</string>
<string name="badPuk">"Le code PUK saisi est incorrect."</string>
<string name="mismatchPin">"Les codes PIN saisis ne correspondent pas."</string>
- <string name="invalidPin">"Saisissez un code PIN comptant 4 à 8 chiffres."</string>
+ <string name="invalidPin">"Le code PIN doit compter de 4 à 8 chiffres."</string>
<string name="needPuk">"Votre carte SIM est verrouillée par code PUK. Saisissez le code PUK pour la déverrouiller."</string>
<string name="needPuk2">"Saisissez le code PUK2 pour débloquer la carte SIM."</string>
<string name="ClipMmi">"Identifiant d\'appelant entrant"</string>
@@ -95,7 +95,7 @@
<string name="screen_lock">"Verrouillage de l\'écran"</string>
<string name="power_off">"Éteindre"</string>
<string name="shutdown_progress">"Arrêt en cours..."</string>
- <string name="shutdown_confirm">"Votre téléphone va s\'éteindra."</string>
+ <string name="shutdown_confirm">"Votre téléphone va s\'éteindre."</string>
<string name="no_recent_tasks">"Aucune application récente"</string>
<string name="global_actions">"Options du téléphone"</string>
<string name="global_action_lock">"Verrouillage de l\'écran"</string>
@@ -109,8 +109,8 @@
<string name="permgrouplab_messages">"Vos messages"</string>
<string name="permgroupdesc_messages">"Permet de lire et rédiger vos SMS, e-mails et autres messages."</string>
<string name="permgrouplab_personalInfo">"Vos informations personnelles"</string>
- <string name="permgroupdesc_personalInfo">"Accédez directement aux contacts et au calendrier enregistrés sur votre téléphone."</string>
- <string name="permgrouplab_location">"Votre position géographique"</string>
+ <string name="permgroupdesc_personalInfo">"Accédez directement aux contacts et à l\'agenda enregistrés sur votre téléphone."</string>
+ <string name="permgrouplab_location">"Votre position"</string>
<string name="permgroupdesc_location">"Suivre votre position géographique"</string>
<string name="permgrouplab_network">"Communications réseau"</string>
<string name="permgroupdesc_network">"Permet à des applications d\'accéder à différentes fonctionnalités du réseau."</string>
@@ -213,7 +213,7 @@
<string name="permlab_diagnostic">"Lire/écrire dans les ressources appartenant aux diagnostics"</string>
<string name="permdesc_diagnostic">"Permet à une application de lire et d\'éditer toute ressource appartenant au groupe de diagnostics (par exemple, les fichiers in/dev). Ceci peut affecter la stabilité et la sécurité du système. Cette fonctionnalité est UNIQUEMENT réservée aux diagnostics matériels effectués par le fabricant ou l\'opérateur."</string>
<string name="permlab_changeComponentState">"Activer ou désactiver des éléments de l\'application"</string>
- <string name="permdesc_changeComponentState">"Permet à une application de modifier l\'état d\'activation/désactivation d\'un élément d\'une autre application. Des applications malveillantes peuvent utiliser cette fonctionnalité pour désactiver des options importantes du téléphone. Soyez prudent en utilisant cette autorisation, car il est possible que certains éléments deviennent instables, incohérents ou inutilisables."</string>
+ <string name="permdesc_changeComponentState">"Permet à une application d\'envoyer une notification lors de la réception d\'un message WAP PUSH. Des applications malveillantes peuvent utiliser cette fonctionnalité pour créer de faux accusés de réception de MMS ou remplacer le contenu de toute page Web par des données malveillantes."</string>
<string name="permlab_setPreferredApplications">"Définir les applications préférées"</string>
<string name="permdesc_setPreferredApplications">"Permet à une application de modifier vos applications préférées. Des applications malveillantes peuvent utiliser cette fonctionnalité pour modifier discrètement les applications en cours d\'exécution, en imitant vos applications existantes afin de récupérer des données personnelles vous concernant."</string>
<string name="permlab_writeSettings">"Modifier les paramètres généraux du système"</string>
@@ -223,7 +223,7 @@
<string name="permlab_writeGservices">"Modifier la carte des services Google"</string>
<string name="permdesc_writeGservices">"Permet à une application de modifier la carte des services Google. Les applications normales n\'utilisent pas cette fonctionnalité."</string>
<string name="permlab_receiveBootCompleted">"Lancer automatiquement au démarrage"</string>
- <string name="permdesc_receiveBootCompleted">"Permet à une application de se lancer dès la fin du démarrage du système. Ceci peut rallonger le temps de démarrage requis par le téléphone. L\'application étant alors constamment en cours d\'exécution, le fonctionnement général du téléphone risque d\'être ralenti."</string>
+ <string name="permdesc_receiveBootCompleted">"Permet à une application de se lancer dès la fin du démarrage du système. Cela peut rallonger le temps de démarrage requis par le téléphone. L\'application étant alors constamment en cours d\'exécution, le fonctionnement général du téléphone risque d\'être ralenti."</string>
<string name="permlab_broadcastSticky">"Envoyer une diffusion persistante"</string>
<string name="permdesc_broadcastSticky">"Permet à une application d\'envoyer des diffusions \"persistantes\", qui perdurent après la fin de la diffusion. Des applications malveillantes peuvent ainsi ralentir le téléphone ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
<string name="permlab_readContacts">"Lire les données des contacts"</string>
@@ -234,17 +234,17 @@
<string name="permdesc_writeOwnerData">"Permet à une application de modifier les données du propriétaire du téléphone enregistrées sur votre appareil. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier ces données."</string>
<string name="permlab_readOwnerData">"Lire des données du propriétaire"</string>
<string name="permdesc_readOwnerData">"Permet à une application de lire les données du propriétaire du téléphone enregistrées sur votre appareil. Des applications malveillantes peuvent utiliser cette fonctionnalité pour lire ces données."</string>
- <string name="permlab_readCalendar">"Lire les données du calendrier"</string>
- <string name="permdesc_readCalendar">"Permet à une application de lire tous les événements du calendrier enregistrés sur votre téléphone. Des applications malveillantes peuvent utiliser cette fonctionnalité pour envoyer les événements de votre calendrier à d\'autres personnes."</string>
- <string name="permlab_writeCalendar">"Écrire les données du calendrier"</string>
- <string name="permdesc_writeCalendar">"Permet à une application de modifier les événements du calendrier enregistrés sur votre téléphone. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier les données de votre calendrier."</string>
+ <string name="permlab_readCalendar">"Lire les données de l\'agenda"</string>
+ <string name="permdesc_readCalendar">"Permet à une application de lire tous les événements de l\'agenda enregistrés sur votre téléphone. Des applications malveillantes peuvent utiliser cette fonctionnalité pour envoyer les événements de votre agenda à d\'autres personnes."</string>
+ <string name="permlab_writeCalendar">"Écrire les données de l\'agenda"</string>
+ <string name="permdesc_writeCalendar">"Permet à une application de modifier les événements de l\'agenda enregistrés sur votre téléphone. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier les données de votre agenda."</string>
<string name="permlab_accessMockLocation">"Créer des sources géographiques fictives à des fins de test"</string>
<string name="permdesc_accessMockLocation">"Permet de créer des sources de position géographique fictives à des fins de test. Des applications malveillantes peuvent utiliser cette fonctionnalité pour remplacer la position géographique et/ou l\'état fournis par des sources réelles comme le GPS ou les fournisseurs d\'accès."</string>
<string name="permlab_accessLocationExtraCommands">"Accéder à des commandes de fournisseur de position géographique supplémentaires"</string>
<string name="permdesc_accessLocationExtraCommands">"Permet d\'accéder à des commandes de fournisseur de position géographique supplémentaires. Des applications malveillantes peuvent utiliser cette fonctionnalité pour interférer avec l\'utilisation du GPS ou d\'autres sources de positionnement géographique."</string>
- <string name="permlab_accessFineLocation">"Position géographique précise (GPS)"</string>
+ <string name="permlab_accessFineLocation">"Position géo. OK (GPS)"</string>
<string name="permdesc_accessFineLocation">"Permet d\'accéder à des sources de positionnement géographique précises comme le Global Positioning System (GPS) sur le téléphone, lorsque ces services sont disponibles. Des applications malveillantes peuvent utiliser cette fonctionnalité pour déterminer l\'endroit où vous vous trouvez et augmenter la consommation de la batterie de votre téléphone."</string>
- <string name="permlab_accessCoarseLocation">"Position géographique approximative (selon le réseau)"</string>
+ <string name="permlab_accessCoarseLocation">"Position géo. approximative (selon le réseau)"</string>
<string name="permdesc_accessCoarseLocation">"Accéder à des sources de positionnement géographique approximatif (par ex. des bases de données de réseaux mobiles) pour déterminer la position géographique du téléphone, lorsque cette option est disponible. Des applications malveillantes peuvent utiliser cette fonctionnalité pour déterminer approximativement l\'endroit où vous vous trouvez."</string>
<string name="permlab_accessSurfaceFlinger">"Accéder à SurfaceFlinger"</string>
<string name="permdesc_accessSurfaceFlinger">"Permet à certaines applications d\'utiliser les fonctionnalités SurfaceFlinger de bas niveau."</string>
@@ -262,10 +262,8 @@
<string name="permdesc_reboot">"Permet à l\'application de forcer le redémarrage du téléphone."</string>
<string name="permlab_mount_unmount_filesystems">"Monter et démonter des systèmes de fichiers"</string>
<string name="permdesc_mount_unmount_filesystems">"Permet à l\'application de monter et démonter des systèmes de fichiers pour des périphériques de stockage amovibles."</string>
- <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
- <skip />
- <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
- <skip />
+ <string name="permlab_mount_format_filesystems">"formater le périphérique de stockage externe"</string>
+ <string name="permdesc_mount_format_filesystems">"Permet à l\'application de formater le périphérique de stockage amovible."</string>
<string name="permlab_vibrate">"Contrôler le vibreur"</string>
<string name="permdesc_vibrate">"Permet à l\'application de contrôler le vibreur."</string>
<string name="permlab_flashlight">"Contrôler la lampe de poche"</string>
@@ -280,10 +278,8 @@
<string name="permdesc_locationUpdates">"Permet l\'activation/la désactivation des notifications de mises à jour de la position géographique provenant de la radio. Les applications normales n\'utilisent pas cette fonctionnalité."</string>
<string name="permlab_checkinProperties">"Accéder aux propriétés d\'enregistrement"</string>
<string name="permdesc_checkinProperties">"Permet un accès en lecture/écriture à des propriétés envoyées par le service d\'inscription. Les applications normales n\'utilisent pas cette fonctionnalité."</string>
- <!-- no translation found for permlab_bindGadget (2519859363977647275) -->
- <skip />
- <!-- no translation found for permdesc_bindGadget (7865866514555126333) -->
- <skip />
+ <string name="permlab_bindGadget">"choisir les gadgets"</string>
+ <string name="permdesc_bindGadget">"Permet à l\'application de signaler au système quels gadgets peuvent être utilisés pour quelle application. Cette autorisation permet aux applications de fournir l\'accès à des données personnelles à d\'autres applications. Cette option n\'est pas utilisée par les applications standard."</string>
<string name="permlab_modifyPhoneState">"Modifier l\'état du téléphone"</string>
<string name="permdesc_modifyPhoneState">"Permet à une application de contrôler les fonctionnalités téléphoniques de l\'appareil. Une application bénéficiant de cette autorisation peut changer de réseau, éteindre et allumer la radio du téléphone, etc., sans vous en notifier."</string>
<string name="permlab_readPhoneState">"Lire l\'état du téléphone"</string>
@@ -312,10 +308,8 @@
<string name="permdesc_writeApnSettings">"Permet à une application de modifier les paramètres APN (Nom des points d\'accès), comme le proxy ou le port de tout APN."</string>
<string name="permlab_changeNetworkState">"Modifier la connectivité du réseau"</string>
<string name="permdesc_changeNetworkState">"Permet à une application de modifier la connectivité du réseau."</string>
- <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
- <skip />
- <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
- <skip />
+ <string name="permlab_changeBackgroundDataSetting">"modifier le paramètre d\'utilisation des données en arrière-plan"</string>
+ <string name="permdesc_changeBackgroundDataSetting">"Permet à une application de modifier le paramètre d\'utilisation des données en arrière-plan."</string>
<string name="permlab_accessWifiState">"Afficher l\'état du Wi-Fi"</string>
<string name="permdesc_accessWifiState">"Permet à une application d\'afficher des informations concernant l\'état du Wi-Fi."</string>
<string name="permlab_changeWifiState">"Modifier l\'état du Wi-Fi"</string>
@@ -336,16 +330,12 @@
<string name="permdesc_subscribedFeedsRead">"Permet à une application d\'obtenir des informations sur les flux récemment synchronisés."</string>
<string name="permlab_subscribedFeedsWrite">"Écrire les flux auxquels vous êtes abonné"</string>
<string name="permdesc_subscribedFeedsWrite">"Permet à une application de modifier vos flux synchronisés actuels. Cette fonctionnalité peut permettre à des applications malveillantes de modifier vos flux synchronisés."</string>
- <!-- no translation found for permlab_readDictionary (432535716804748781) -->
- <skip />
- <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
- <skip />
- <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
- <skip />
- <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
- <skip />
+ <string name="permlab_readDictionary">"lire le dictionnaire défini par l\'utilisateur"</string>
+ <string name="permdesc_readDictionary">"Permet à une application de lire tous les mots, noms et expressions que l\'utilisateur a pu enregistrer dans son dictionnaire personnel."</string>
+ <string name="permlab_writeDictionary">"enregistrer dans le dictionnaire défini par l\'utilisateur"</string>
+ <string name="permdesc_writeDictionary">"Permet à une application d\'enregistrer de nouveaux mots dans le dictionnaire personnel de l\'utilisateur."</string>
<string-array name="phoneTypes">
- <item>"Accueil"</item>
+ <item>"Domicile"</item>
<item>"Mobile"</item>
<item>"Bureau"</item>
<item>"Télécopie bureau"</item>
@@ -355,19 +345,19 @@
<item>"Personnalisé"</item>
</string-array>
<string-array name="emailAddressTypes">
- <item>"Accueil"</item>
+ <item>"Domicile"</item>
<item>"Bureau"</item>
<item>"Autre"</item>
<item>"Personnalisée"</item>
</string-array>
<string-array name="postalAddressTypes">
- <item>"Accueil"</item>
+ <item>"Domicile"</item>
<item>"Bureau"</item>
<item>"Autre"</item>
<item>"Personnalisée"</item>
</string-array>
<string-array name="imAddressTypes">
- <item>"Accueil"</item>
+ <item>"Domicile"</item>
<item>"Bureau"</item>
<item>"Autre"</item>
<item>"Personnalisé"</item>
@@ -387,14 +377,14 @@
<item>"ICQ"</item>
<item>"Jabber"</item>
</string-array>
- <string name="keyguard_password_enter_pin_code">"Saisir le code PIN"</string>
+ <string name="keyguard_password_enter_pin_code">"Saisissez le code PIN"</string>
<string name="keyguard_password_wrong_pin_code">"Le code PIN est incorrect !"</string>
- <string name="keyguard_label_text">"Pour débloquer le clavier, appuyez sur Menu puis sur 0."</string>
+ <string name="keyguard_label_text">"Pour débloquer le clavier, appuyez sur \"Menu\" puis sur 0."</string>
<string name="emergency_call_dialog_number_for_display">"Numéro d\'urgence"</string>
<string name="lockscreen_carrier_default">"(Aucun service)"</string>
<string name="lockscreen_screen_locked">"Écran verrouillé"</string>
- <string name="lockscreen_instructions_when_pattern_enabled">"Appuyez sur Menu pour débloquer le téléphone ou appeler un numéro d\'urgence"</string>
- <string name="lockscreen_instructions_when_pattern_disabled">"Appuyez sur Menu pour déverrouiller le téléphone."</string>
+ <string name="lockscreen_instructions_when_pattern_enabled">"Appuyez sur \"Menu\" pour débloquer le téléphone ou appeler un numéro d\'urgence"</string>
+ <string name="lockscreen_instructions_when_pattern_disabled">"Appuyez sur \"Menu\" pour déverrouiller le téléphone."</string>
<string name="lockscreen_pattern_instructions">"Dessinez un motif pour déverrouiller le téléphone"</string>
<string name="lockscreen_emergency_call">"Appel d\'urgence"</string>
<string name="lockscreen_pattern_correct">"Combinaison correcte !"</string>
@@ -440,12 +430,9 @@
<string name="factorytest_not_system">"L\'action FACTORY_TEST est uniquement prise en charge pour les paquets de données installés dans in/system/app."</string>
<string name="factorytest_no_action">"Impossible de trouver un paquet proposant l\'action FACTORY_TEST."</string>
<string name="factorytest_reboot">"Redémarrer"</string>
- <!-- no translation found for js_dialog_title (8143918455087008109) -->
- <skip />
- <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
- <skip />
- <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
- <skip />
+ <string name="js_dialog_title">"La page \"<xliff:g id="TITLE">%s</xliff:g>\" affirme :"</string>
+ <string name="js_dialog_title_default">"JavaScript"</string>
+ <string name="js_dialog_before_unload">"Vous souhaitez quitter cette page ?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Sélectionnez OK pour continuer ou Annuler pour rester sur la page actuelle."</string>
<string name="save_password_label">"Confirmer"</string>
<string name="save_password_message">"Voulez-vous que le navigateur se souvienne de ce mot de passe ?"</string>
<string name="save_password_notnow">"Pas maintenant"</string>
@@ -496,22 +483,38 @@
<item quantity="one">"demain"</item>
<item quantity="other">"dans <xliff:g id="COUNT">%d</xliff:g> jours"</item>
</plurals>
- <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) -->
- <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) -->
- <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) -->
- <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) -->
- <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) -->
- <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) -->
- <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) -->
- <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) -->
- <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) -->
- <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) -->
- <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) -->
- <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) -->
- <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) -->
- <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) -->
- <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) -->
- <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) -->
+ <plurals name="abbrev_num_seconds_ago">
+ <item quantity="one">"il y a 1 seconde"</item>
+ <item quantity="other">"il y a <xliff:g id="COUNT">%d</xliff:g> secondes"</item>
+ </plurals>
+ <plurals name="abbrev_num_minutes_ago">
+ <item quantity="one">"il y a 1 minute"</item>
+ <item quantity="other">"il y a <xliff:g id="COUNT">%d</xliff:g> minutes"</item>
+ </plurals>
+ <plurals name="abbrev_num_hours_ago">
+ <item quantity="one">"il y a 1 heure"</item>
+ <item quantity="other">"Il y a <xliff:g id="COUNT">%d</xliff:g> heures"</item>
+ </plurals>
+ <plurals name="abbrev_num_days_ago">
+ <item quantity="one">"hier"</item>
+ <item quantity="other">"Il y a <xliff:g id="COUNT">%d</xliff:g> jours"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_seconds">
+ <item quantity="one">"dans 1 seconde"</item>
+ <item quantity="other">"dans <xliff:g id="COUNT">%d</xliff:g> secondes"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_minutes">
+ <item quantity="one">"dans 1 minute"</item>
+ <item quantity="other">"dans <xliff:g id="COUNT">%d</xliff:g> minutes"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_hours">
+ <item quantity="one">"dans 1 heure"</item>
+ <item quantity="other">"dans <xliff:g id="COUNT">%d</xliff:g> heures"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_days">
+ <item quantity="one">"demain"</item>
+ <item quantity="other">"dans <xliff:g id="COUNT">%d</xliff:g> jours"</item>
+ </plurals>
<string name="preposition_for_date">"%s"</string>
<string name="preposition_for_time">"à %s"</string>
<string name="preposition_for_year">"en %s"</string>
@@ -553,17 +556,15 @@
<string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <!-- no translation found for date_time (6104442718633642836) -->
- <skip />
- <!-- no translation found for relative_time (1818557177829411417) -->
- <skip />
+ <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"midi"</string>
<string name="Noon">"Midi"</string>
<string name="midnight">"minuit"</string>
@@ -691,8 +692,7 @@
<string name="paste">"Coller"</string>
<string name="copyUrl">"Copier l\'URL"</string>
<string name="inputMethod">"Mode de saisie"</string>
- <!-- no translation found for addToDictionary (726256909274177272) -->
- <skip />
+ <string name="addToDictionary">"Ajouter \"%s\" au dictionnaire"</string>
<string name="editTextMenuTitle">"Modifier le texte"</string>
<string name="low_internal_storage_view_title">"Espace disponible faible"</string>
<string name="low_internal_storage_view_text">"La mémoire du téléphone commence à être pleine."</string>
@@ -700,8 +700,7 @@
<string name="cancel">"Annuler"</string>
<string name="yes">"OK"</string>
<string name="no">"Annuler"</string>
- <!-- no translation found for dialog_alert_title (2049658708609043103) -->
- <skip />
+ <string name="dialog_alert_title">"Attention"</string>
<string name="capital_on">"ON"</string>
<string name="capital_off">"OFF"</string>
<string name="whichApplication">"Terminer l\'action avec"</string>
@@ -725,8 +724,7 @@
<string name="volume_music">"Volume des médias"</string>
<string name="volume_music_hint_playing_through_bluetooth">"Lecture via Bluetooth"</string>
<string name="volume_call">"Volume des appels entrants"</string>
- <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
- <skip />
+ <string name="volume_bluetooth_call">"Volume d\'appels entrants sur Bluetooth"</string>
<string name="volume_alarm">"Volume de l\'alarme"</string>
<string name="volume_notification">"Volume des notifications"</string>
<string name="volume_unknown">"Volume"</string>
@@ -762,60 +760,35 @@
<string name="usb_storage_error_message">"Un problème est survenu lors de l\'utilisation de votre carte SD en tant que périphérique de stockage USB."</string>
<string name="usb_storage_notification_title">"Connecté avec un câble USB"</string>
<string name="usb_storage_notification_message">"Sélectionnez cette option pour copier des fichiers vers/à partir de votre ordinateur."</string>
- <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
- <skip />
- <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
- <skip />
- <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
- <skip />
- <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
- <skip />
- <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
- <skip />
- <!-- no translation found for extmedia_format_title (8663247929551095854) -->
- <skip />
- <!-- no translation found for extmedia_format_message (3621369962433523619) -->
- <skip />
- <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
- <skip />
+ <string name="usb_storage_stop_notification_title">"Éteindre le périphérique de stockage USB"</string>
+ <string name="usb_storage_stop_notification_message">"Sélectionner pour éteindre le périphérique de stockage USB"</string>
+ <string name="usb_storage_stop_title">"Éteindre le périphérique de stockage USB"</string>
+ <string name="usb_storage_stop_message">"Avant d\'éteindre le périphérique de stockage USB, assurez-vous d\'avoir désactivé l\'hôte USB. Sélectionnez \"Éteindre\" pour éteindre le périphérique de stockage USB."</string>
+ <string name="usb_storage_stop_button_mount">"Éteindre"</string>
+ <string name="usb_storage_stop_button_unmount">"Annuler"</string>
+ <string name="usb_storage_stop_error_message">"Un problème est survenu lors de la mise hors tension du périphérique de stockage USB. Assurez-vous que l\'hôte USB a bien été désactivé, puis essayez à nouveau."</string>
+ <string name="extmedia_format_title">"Formater la carte SD"</string>
+ <string name="extmedia_format_message">"Voulez-vous vraiment formater la carte SD ? Toutes les données de cette carte seront perdues."</string>
+ <string name="extmedia_format_button_format">"Format"</string>
<string name="select_input_method">"Sélectionner un mode de saisie"</string>
<string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
- <!-- no translation found for candidates_style (4333913089637062257) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
- <skip />
- <!-- no translation found for activity_list_empty (4168820609403385789) -->
- <skip />
- <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
- <skip />
- <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
- <skip />
+ <string name="candidates_style"><u>"candidats"</u></string>
+ <string name="ext_media_checking_notification_title">"Préparation de la carte SD"</string>
+ <string name="ext_media_checking_notification_message">"Recherche d\'erreurs"</string>
+ <string name="ext_media_nofs_notification_title">"Carte SD vide"</string>
+ <string name="ext_media_nofs_notification_message">"La carte SD est vide ou utilise un système de fichiers non pris en charge."</string>
+ <string name="ext_media_unmountable_notification_title">"Carte SD endommagée"</string>
+ <string name="ext_media_unmountable_notification_message">"La carte SD est endommagée. Vous devez peut-être reformater votre carte."</string>
+ <string name="ext_media_badremoval_notification_title">"Carte SD retirée inopinément"</string>
+ <string name="ext_media_badremoval_notification_message">"Désactiver la carte SD avant de la retirer pour éviter toute perte de données."</string>
+ <string name="ext_media_safe_unmount_notification_title">"La carte SD peut être retirée en toute sécurité"</string>
+ <string name="ext_media_safe_unmount_notification_message">"Vous pouvez désormais retirer la carte SD en toute sécurité."</string>
+ <string name="ext_media_nomedia_notification_title">"Carte SD manquante"</string>
+ <string name="ext_media_nomedia_notification_message">"La carte SD a été retirée. Insérez une autre carte pour augmenter la capacité de stockage de votre appareil."</string>
+ <string name="activity_list_empty">"Aucune activité correspondante trouvée"</string>
+ <string name="permlab_pkgUsageStats">"mettre à jour les données statistiques du composant"</string>
+ <string name="permdesc_pkgUsageStats">"Permet de modifier les données statistiques collectées du composant. Cette option n\'est pas utilisée par les applications standard."</string>
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) -->
<skip />
</resources>
diff --git a/core/res/res/values-it-rIT/arrays.xml b/core/res/res/values-it-rIT/arrays.xml
new file mode 100644
index 0000000..92e5260
--- /dev/null
+++ b/core/res/res/values-it-rIT/arrays.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** Copyright 2006, Google Inc.
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources>
+
+ <!-- Do not translate. -->
+ <integer-array name="maps_starting_lat_lng">
+ <item>41795888</item>
+ <item>12480469</item>
+ </integer-array>
+ <!-- Do not translate. -->
+ <integer-array name="maps_starting_zoom">
+ <item>6</item>
+ </integer-array>
+
+</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 2cf7b43..2ac9699 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_reboot">"Consente all\'applicazione di imporre il riavvio del telefono."</string>
<string name="permlab_mount_unmount_filesystems">"montare e smontare filesystem"</string>
<string name="permdesc_mount_unmount_filesystems">"Consente montaggio e smontaggio da parte dell\'applicazione dei filesystem degli archivi rimovibili."</string>
- <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
- <skip />
- <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
- <skip />
+ <string name="permlab_mount_format_filesystems">"formatta archivio esterno"</string>
+ <string name="permdesc_mount_format_filesystems">"Consente all\'applicazione di formattare l\'archivio rimovibile."</string>
<string name="permlab_vibrate">"controllare la vibrazione"</string>
<string name="permdesc_vibrate">"Consente all\'applicazione di controllare la vibrazione."</string>
<string name="permlab_flashlight">"controllare il flash"</string>
@@ -280,10 +278,8 @@
<string name="permdesc_locationUpdates">"Consente l\'attivazione/disattivazione delle notifiche di aggiornamento della posizione. Da non usare per normali applicazioni."</string>
<string name="permlab_checkinProperties">"accedere a proprietà di archiviazione"</string>
<string name="permdesc_checkinProperties">"Consente l\'accesso di lettura/scrittura alle proprietà caricate dal servizio di archiviazione. Da non usare per normali applicazioni."</string>
- <!-- no translation found for permlab_bindGadget (2519859363977647275) -->
- <skip />
- <!-- no translation found for permdesc_bindGadget (7865866514555126333) -->
- <skip />
+ <string name="permlab_bindGadget">"scegliere gadget"</string>
+ <string name="permdesc_bindGadget">"Consente all\'applicazione di indicare al sistema quali gadget possono essere utilizzati e da quale applicazione. Con questa autorizzazione, le applicazioni possono consentire ad altre applicazioni di accedere a dati personali. Da non usare per normali applicazioni."</string>
<string name="permlab_modifyPhoneState">"modificare lo stato del telefono"</string>
<string name="permdesc_modifyPhoneState">"Consente all\'applicazione di controllare le funzioni telefoniche del dispositivo. Un\'applicazione con questa autorizzazione può cambiare rete, accendere e spegnere il modulo radio del telefono e così via, il tutto automaticamente."</string>
<string name="permlab_readPhoneState">"leggere lo stato del telefono"</string>
@@ -312,10 +308,8 @@
<string name="permdesc_writeApnSettings">"Consente a un\'applicazione di modificare le impostazioni APN, come proxy e porta di qualsiasi APN."</string>
<string name="permlab_changeNetworkState">"cambiare connettività di rete"</string>
<string name="permdesc_changeNetworkState">"Consente a un\'applicazione di modificare lo stato di connettività di rete."</string>
- <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
- <skip />
- <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
- <skip />
+ <string name="permlab_changeBackgroundDataSetting">"cambiare l\'impostazione di utilizzo dei dati in background"</string>
+ <string name="permdesc_changeBackgroundDataSetting">"Consente a un\'applicazione di cambiare l\'impostazione di utilizzo dei dati in background."</string>
<string name="permlab_accessWifiState">"visualizzare lo stato Wi-Fi"</string>
<string name="permdesc_accessWifiState">"Consente a un\'applicazione di visualizzare le informazioni relative allo stato della connessione Wi-Fi."</string>
<string name="permlab_changeWifiState">"cambiare stato Wi-Fi"</string>
@@ -336,14 +330,10 @@
<string name="permdesc_subscribedFeedsRead">"Consente a un\'applicazione di ottenere dettagli sui feed attualmente sincronizzati."</string>
<string name="permlab_subscribedFeedsWrite">"scrivere feed sottoscritti"</string>
<string name="permdesc_subscribedFeedsWrite">"Consente la modifica da parte di un\'applicazione dei feed attualmente sincronizzati. Le applicazioni dannose potrebbero essere in grado di modificare i feed sincronizzati."</string>
- <!-- no translation found for permlab_readDictionary (432535716804748781) -->
- <skip />
- <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
- <skip />
- <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
- <skip />
- <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
- <skip />
+ <string name="permlab_readDictionary">"leggi dizionario definito dall\'utente"</string>
+ <string name="permdesc_readDictionary">"Consente a un\'applicazione di leggere parole, nomi e frasi private che l\'utente potrebbe aver memorizzato nel dizionario utente."</string>
+ <string name="permlab_writeDictionary">"scrivi nel dizionario definito dall\'utente"</string>
+ <string name="permdesc_writeDictionary">"Consente a un\'applicazione di scrivere nuove parole nel dizionario utente."</string>
<string-array name="phoneTypes">
<item>"Casa"</item>
<item>"Cellulare"</item>
@@ -440,12 +430,9 @@
<string name="factorytest_not_system">"L\'azione FACTORY_TEST è supportata soltanto per i pacchetti installati in /system/app."</string>
<string name="factorytest_no_action">"Nessun pacchetto trovato che fornisca l\'azione FACTORY_TEST."</string>
<string name="factorytest_reboot">"Riavvia"</string>
- <!-- no translation found for js_dialog_title (8143918455087008109) -->
- <skip />
- <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
- <skip />
- <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
- <skip />
+ <string name="js_dialog_title">"La pagina all\'indirizzo <xliff:g id="TITLE">%s</xliff:g> indica:"</string>
+ <string name="js_dialog_title_default">"JavaScript"</string>
+ <string name="js_dialog_before_unload">"Uscire da questa pagina?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Seleziona OK per continuare o Annulla per rimanere nella pagina corrente."</string>
<string name="save_password_label">"Conferma"</string>
<string name="save_password_message">"Memorizzare la password nel browser?"</string>
<string name="save_password_notnow">"Non ora"</string>
@@ -496,22 +483,38 @@
<item quantity="one">"domani"</item>
<item quantity="other">"tra <xliff:g id="COUNT">%d</xliff:g> giorni"</item>
</plurals>
- <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) -->
- <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) -->
- <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) -->
- <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) -->
- <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) -->
- <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) -->
- <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) -->
- <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) -->
- <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) -->
- <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) -->
- <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) -->
- <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) -->
- <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) -->
- <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) -->
- <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) -->
- <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) -->
+ <plurals name="abbrev_num_seconds_ago">
+ <item quantity="one">"1 sec fa"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> sec fa"</item>
+ </plurals>
+ <plurals name="abbrev_num_minutes_ago">
+ <item quantity="one">"1 min fa"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> min fa"</item>
+ </plurals>
+ <plurals name="abbrev_num_hours_ago">
+ <item quantity="one">"1 ora fa"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> ore fa"</item>
+ </plurals>
+ <plurals name="abbrev_num_days_ago">
+ <item quantity="one">"ieri"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> giorni fa"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_seconds">
+ <item quantity="one">"tra 1 sec"</item>
+ <item quantity="other">"tra <xliff:g id="COUNT">%d</xliff:g> sec"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_minutes">
+ <item quantity="one">"tra 1 min"</item>
+ <item quantity="other">"tra <xliff:g id="COUNT">%d</xliff:g> min"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_hours">
+ <item quantity="one">"tra 1 ora"</item>
+ <item quantity="other">"tra <xliff:g id="COUNT">%d</xliff:g> ore"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_days">
+ <item quantity="one">"domani"</item>
+ <item quantity="other">"tra <xliff:g id="COUNT">%d</xliff:g> giorni"</item>
+ </plurals>
<string name="preposition_for_date">"il %s"</string>
<string name="preposition_for_time">"alle %s"</string>
<string name="preposition_for_year">"nel %s"</string>
@@ -553,17 +556,15 @@
<string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <!-- no translation found for date_time (6104442718633642836) -->
- <skip />
- <!-- no translation found for relative_time (1818557177829411417) -->
- <skip />
+ <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"mezzogiorno"</string>
<string name="Noon">"Mezzogiorno"</string>
<string name="midnight">"mezzanotte"</string>
@@ -691,8 +692,7 @@
<string name="paste">"Incolla"</string>
<string name="copyUrl">"Copia URL"</string>
<string name="inputMethod">"Metodo inserimento"</string>
- <!-- no translation found for addToDictionary (726256909274177272) -->
- <skip />
+ <string name="addToDictionary">"Aggiungi \"%s\" al dizionario"</string>
<string name="editTextMenuTitle">"Modifica testo"</string>
<string name="low_internal_storage_view_title">"Spazio in esaurimento"</string>
<string name="low_internal_storage_view_text">"Spazio di archiviazione del telefono in esaurimento."</string>
@@ -700,8 +700,7 @@
<string name="cancel">"Annulla"</string>
<string name="yes">"OK"</string>
<string name="no">"Annulla"</string>
- <!-- no translation found for dialog_alert_title (2049658708609043103) -->
- <skip />
+ <string name="dialog_alert_title">"Attenzione"</string>
<string name="capital_on">"ON"</string>
<string name="capital_off">"OFF"</string>
<string name="whichApplication">"Completa l\'azione con"</string>
@@ -725,8 +724,7 @@
<string name="volume_music">"Volume media"</string>
<string name="volume_music_hint_playing_through_bluetooth">"Riproduzione tramite Bluetooth"</string>
<string name="volume_call">"Volume chiamate"</string>
- <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
- <skip />
+ <string name="volume_bluetooth_call">"Volume chiamate Bluetooth"</string>
<string name="volume_alarm">"Volume allarme"</string>
<string name="volume_notification">"Volume notifiche"</string>
<string name="volume_unknown">"Volume"</string>
@@ -762,60 +760,35 @@
<string name="usb_storage_error_message">"Problema di utilizzo della scheda SD per l\'archiviazione USB."</string>
<string name="usb_storage_notification_title">"USB collegata"</string>
<string name="usb_storage_notification_message">"Seleziona per copiare file sul/dal computer in uso."</string>
- <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
- <skip />
- <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
- <skip />
- <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
- <skip />
- <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
- <skip />
- <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
- <skip />
- <!-- no translation found for extmedia_format_title (8663247929551095854) -->
- <skip />
- <!-- no translation found for extmedia_format_message (3621369962433523619) -->
- <skip />
- <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
- <skip />
+ <string name="usb_storage_stop_notification_title">"Disattiva archivio USB"</string>
+ <string name="usb_storage_stop_notification_message">"Seleziona per disattivare archivio USB."</string>
+ <string name="usb_storage_stop_title">"Disattiva archivio USB"</string>
+ <string name="usb_storage_stop_message">"Prima di disattivare l\'archivio USB, verifica di aver smontato l\'host USB. A tale scopo, seleziona \"Disattiva\"."</string>
+ <string name="usb_storage_stop_button_mount">"Disattiva"</string>
+ <string name="usb_storage_stop_button_unmount">"Annulla"</string>
+ <string name="usb_storage_stop_error_message">"Abbiamo riscontrato un problema disattivando l\'archivio USB. Verifica di aver smontato l\'host USB e riprova."</string>
+ <string name="extmedia_format_title">"Formatta scheda SD"</string>
+ <string name="extmedia_format_message">"Formattare la scheda SD? Tutti i dati sulla scheda verranno persi."</string>
+ <string name="extmedia_format_button_format">"Formatta"</string>
<string name="select_input_method">"Seleziona metodo di inserimento"</string>
<string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
- <!-- no translation found for candidates_style (4333913089637062257) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
- <skip />
- <!-- no translation found for activity_list_empty (4168820609403385789) -->
- <skip />
- <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
- <skip />
- <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
- <skip />
+ <string name="candidates_style"><u>"candidati"</u></string>
+ <string name="ext_media_checking_notification_title">"Preparazione scheda SD"</string>
+ <string name="ext_media_checking_notification_message">"Ricerca errori"</string>
+ <string name="ext_media_nofs_notification_title">"Scheda SD vuota"</string>
+ <string name="ext_media_nofs_notification_message">"La scheda SD è vuota o utilizza un file system non supportato."</string>
+ <string name="ext_media_unmountable_notification_title">"Scheda SD danneggiata"</string>
+ <string name="ext_media_unmountable_notification_message">"La scheda SD è danneggiata. Potrebbe essere necessario riformattarla."</string>
+ <string name="ext_media_badremoval_notification_title">"Rimozione imprevista della scheda SD"</string>
+ <string name="ext_media_badremoval_notification_message">"Smonta scheda SD prima della rimozione per evitare la perdita di dati."</string>
+ <string name="ext_media_safe_unmount_notification_title">"È possibile rimuovere la scheda SD"</string>
+ <string name="ext_media_safe_unmount_notification_message">"È ora possibile rimuovere la scheda SD in modo sicuro."</string>
+ <string name="ext_media_nomedia_notification_title">"Scheda SD rimossa"</string>
+ <string name="ext_media_nomedia_notification_message">"Scheda SD rimossa. Inserisci una nuova scheda SD per aumentare la memoria del dispositivo."</string>
+ <string name="activity_list_empty">"Nessuna attività corrispondente trovata"</string>
+ <string name="permlab_pkgUsageStats">"aggiornare le statistiche di utilizzo dei componenti"</string>
+ <string name="permdesc_pkgUsageStats">"Consente la modifica delle statistiche di utilizzo dei componenti raccolte. Da non usare per normali applicazioni."</string>
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) -->
<skip />
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 24e3cb6..1fa3eee 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -21,10 +21,10 @@
<string name="gigabyteShort">"GB"</string>
<string name="terabyteShort">"TB"</string>
<string name="petabyteShort">"PB"</string>
- <string name="untitled">"&lt;無題&gt;"</string>
+ <string name="untitled">"&lt;新規&gt;"</string>
<string name="ellipsis">"..."</string>
- <string name="emptyPhoneNumber">"(電話番号なし)"</string>
- <string name="unknownName">"(不明)"</string>
+ <string name="emptyPhoneNumber">"(電話番号なし)"</string>
+ <string name="unknownName">"(名前)"</string>
<string name="defaultVoiceMailAlphaTag">"ボイスメール"</string>
<string name="defaultMsisdnAlphaTag">"MSISDN1"</string>
<string name="mmiError">"接続に問題があるか、MMIコードが正しくありません。"</string>
@@ -48,11 +48,11 @@
<string name="BaMmi">"発信制限"</string>
<string name="PwdMmi">"パスワードの変更"</string>
<string name="PinMmi">"PINの変更"</string>
- <string name="CLIRDefaultOnNextCallOn">"デフォルトでは発信者番号は非通知です。次の通話でも非通知です。"</string>
- <string name="CLIRDefaultOnNextCallOff">"デフォルトでは発信者番号は非通知ですが、次の通話では通知されます。"</string>
- <string name="CLIRDefaultOffNextCallOn">"デフォルトでは発信者番号は通知されますが、次の通話では非通知です。"</string>
- <string name="CLIRDefaultOffNextCallOff">"デフォルトでは発信者番号は通知されます。次の通話でも通知されます。"</string>
- <string name="serviceNotProvisioned">"サービスは提供されません。"</string>
+ <string name="CLIRDefaultOnNextCallOn">"既定: 発信者番号非通知、次の発信: 非通知"</string>
+ <string name="CLIRDefaultOnNextCallOff">"既定: 発信者番号非通知、次の発信: 通知"</string>
+ <string name="CLIRDefaultOffNextCallOn">"既定: 発信者番号通知、次の発信: 非通知"</string>
+ <string name="CLIRDefaultOffNextCallOff">"既定: 発信者番号通知、次の発信: 通知"</string>
+ <string name="serviceNotProvisioned">"提供可能なサービスがありません。"</string>
<string name="CLIRPermanent">"発信者番号の設定は変更できません。"</string>
<string name="serviceClassVoice">"音声"</string>
<string name="serviceClassData">"データ"</string>
@@ -90,15 +90,15 @@
<string name="me">"自分"</string>
<string name="power_dialog">"携帯電話オプション"</string>
<string name="silent_mode">"マナーモード"</string>
- <string name="turn_on_radio">"ワイヤレスをオン"</string>
- <string name="turn_off_radio">"ワイヤレスオフ"</string>
+ <string name="turn_on_radio">"ワイヤレス接続をONにする"</string>
+ <string name="turn_off_radio">"ワイヤレス接続をOFFにする"</string>
<string name="screen_lock">"画面をロック"</string>
<string name="power_off">"電源オフ"</string>
<string name="shutdown_progress">"シャットダウン中..."</string>
<string name="shutdown_confirm">"携帯電話の電源をオフにします。"</string>
<string name="no_recent_tasks">"最近使ったアプリケーションはありません。"</string>
<string name="global_actions">"携帯電話オプション"</string>
- <string name="global_action_lock">"画面をロック"</string>
+ <string name="global_action_lock">"画面ロック"</string>
<string name="global_action_power_off">"電源オフ"</string>
<string name="global_action_toggle_silent_mode">"マナーモード"</string>
<string name="global_action_silent_mode_on_status">"音声オフ"</string>
@@ -109,27 +109,27 @@
<string name="permgrouplab_messages">"送受信したメッセージ"</string>
<string name="permgroupdesc_messages">"SMS、メールなどのメッセージの読み書き"</string>
<string name="permgrouplab_personalInfo">"個人情報"</string>
- <string name="permgroupdesc_personalInfo">"携帯電話に保存した連絡先とカレンダーに直接アクセス"</string>
+ <string name="permgroupdesc_personalInfo">"端末の連絡先とカレンダーに直接アクセス"</string>
<string name="permgrouplab_location">"現在地"</string>
- <string name="permgroupdesc_location">"現在地を監視"</string>
+ <string name="permgroupdesc_location">"現在地を追跡"</string>
<string name="permgrouplab_network">"ネットワーク通信"</string>
<string name="permgroupdesc_network">"ネットワークのさまざまな機能へのアクセスをアプリケーションに許可します。"</string>
<string name="permgrouplab_accounts">"Googleアカウント"</string>
<string name="permgroupdesc_accounts">"利用可能なGoogleアカウントへのアクセス"</string>
<string name="permgrouplab_hardwareControls">"ハードウェアの制御"</string>
<string name="permgroupdesc_hardwareControls">"携帯電話のハードウェアに直接アクセスします。"</string>
- <string name="permgrouplab_phoneCalls">"電話の発信"</string>
+ <string name="permgrouplab_phoneCalls">"電話/通話"</string>
<string name="permgroupdesc_phoneCalls">"通話の監視、記録、処理"</string>
<string name="permgrouplab_systemTools">"システムツール"</string>
<string name="permgroupdesc_systemTools">"システムの低レベルのアクセスと制御"</string>
<string name="permgrouplab_developmentTools">"開発ツール"</string>
<string name="permgroupdesc_developmentTools">"アプリケーションのデベロッパーにのみ必要な機能です。"</string>
- <string name="permlab_statusBar">"ステータスバーを無効にしたり変更する"</string>
- <string name="permdesc_statusBar">"ステータスバーの無効化や、システムアイコンの追加や削除をアプリケーションに許可します。"</string>
+ <string name="permlab_statusBar">"ステータスバーの無効化や変更"</string>
+ <string name="permdesc_statusBar">"ステータスバーの無効化やシステムアイコンの追加や削除をアプリケーションに許可します。"</string>
<string name="permlab_expandStatusBar">"ステータスバーの拡大/縮小"</string>
<string name="permdesc_expandStatusBar">"ステータスバーの拡大や縮小をアプリケーションに許可します。"</string>
<string name="permlab_processOutgoingCalls">"発信の傍受"</string>
- <string name="permdesc_processOutgoingCalls">"発信を処理して、ダイヤルする番号を変更することをアプリケーションに許可します。悪意のあるアプリケーションが発信を監視、転送、阻止する恐れがあります。"</string>
+ <string name="permdesc_processOutgoingCalls">"通話の発信とダイヤルする番号の変更とをアプリケーションに許可します。悪意のあるアプリケーションが発信を監視、転送、阻止する恐れがあります。"</string>
<string name="permlab_receiveSms">"SMSの受信"</string>
<string name="permdesc_receiveSms">"SMSメッセージの受信と処理をアプリケーションに許可します。悪意のあるアプリケーションがメッセージを監視したり、表示せずに削除する恐れがあります。"</string>
<string name="permlab_receiveMms">"MMSの受信"</string>
@@ -137,7 +137,7 @@
<string name="permlab_sendSms">"SMSメッセージの送信"</string>
<string name="permdesc_sendSms">"SMSメッセージの送信をアプリケーションに許可します。悪意のあるアプリケーションが確認なしでメッセージを送信し、料金が発生する恐れがあります。"</string>
<string name="permlab_readSms">"SMSやMMSの読み取り"</string>
- <string name="permdesc_readSms">"携帯電話またはSIMカードに保存したSMSメッセージの読み取りをアプリケーションに許可します。悪意のあるアプリケーションが機密メッセージを読み取る恐れがあります。"</string>
+ <string name="permdesc_readSms">"携帯電話やSIMカードに保存したSMSメッセージの読み取りをアプリケーションに許可します。悪意のあるアプリケーションが機密メッセージを読み取る恐れがあります。"</string>
<string name="permlab_writeSms">"SMSやMMSの編集"</string>
<string name="permdesc_writeSms">"携帯電話やSIMカードに保存したSMSメッセージへの書き込みをアプリケーションに許可します。悪意のあるアプリケーションがメッセージを削除する恐れがあります。"</string>
<string name="permlab_receiveWapPush">"WAPの受信"</string>
@@ -147,9 +147,9 @@
<string name="permlab_reorderTasks">"実行中のアプリケーションの順序の変更"</string>
<string name="permdesc_reorderTasks">"タスクをフォアグラウンドやバックグラウンドに移動することをアプリケーションに許可します。悪意のあるアプリケーションが優先されて、コントロールできなくなる恐れがあります。"</string>
<string name="permlab_setDebugApp">"アプリケーションのデバッグを有効にする"</string>
- <string name="permdesc_setDebugApp">"別のアプリケーションをデバッグモードにすることをアプリケーションに許可します。これにより悪意のあるアプリケーションが、別のアプリケーションを終了させる恐れがあります。"</string>
+ <string name="permdesc_setDebugApp">"別のアプリケーションをデバッグモードにすることをアプリケーションに許可します。悪意のあるアプリケーションが別のアプリケーションを終了させる恐れがあります。"</string>
<string name="permlab_changeConfiguration">"UI設定の変更"</string>
- <string name="permdesc_changeConfiguration">"ロケールや全体のフォントのサイズなど、現在の設定の変更をアプリケーションに許可します。"</string>
+ <string name="permdesc_changeConfiguration">"地域/言語やフォントのサイズなど、現在の設定の変更をアプリケーションに許可します。"</string>
<string name="permlab_restartPackages">"他のアプリケーションの再起動"</string>
<string name="permdesc_restartPackages">"他のアプリケーションの強制的な再起動をアプリケーションに許可します。"</string>
<string name="permlab_setProcessForeground">"停止の阻止"</string>
@@ -157,47 +157,47 @@
<string name="permlab_forceBack">"アプリケーションの強制終了"</string>
<string name="permdesc_forceBack">"フォアグラウンドで実行されている操作を強制終了して戻ることをアプリケーションに許可します。通常のアプリケーションではまったく必要ありません。"</string>
<string name="permlab_dump">"システムの内部状態の取得"</string>
- <string name="permdesc_dump">"システムの内部状態の取得をアプリケーションに許可します。悪意のあるアプリケーションが、通常は必要のない、広範囲にわたる非公開の機密情報を取得する恐れがあります。"</string>
+ <string name="permdesc_dump">"システムの内部状態の取得をアプリケーションに許可します。悪意のあるアプリケーションが、通常は必要としない広範囲にわたる非公開の機密情報を取得する恐れがあります。"</string>
<string name="permlab_addSystemService">"低レベルサービスの公開"</string>
<string name="permdesc_addSystemService">"独自の低レベルのシステムサービスを公開することをアプリケーションに許可します。悪意のあるアプリケーションがシステムを乗っ取って、データの盗用や破壊をする恐れがあります。"</string>
<string name="permlab_runSetActivityWatcher">"起動中のすべてのアプリケーションの監視と制御"</string>
<string name="permdesc_runSetActivityWatcher">"システムが起動する操作の監視と制御をアプリケーションに許可します。悪意のあるアプリケーションがシステムを完全に破壊する恐れがあります。この許可は開発にのみ必要で、携帯電話の通常の使用にはまったく必要ありません。"</string>
<string name="permlab_broadcastPackageRemoved">"パッケージ削除ブロードキャストの送信"</string>
- <string name="permdesc_broadcastPackageRemoved">"アプリケーションパッケージの削除通知を配信することをアプリケーションに許可します。これにより悪意のあるアプリケーションが、他の実行中のアプリケーションを強制終了する恐れがあります。"</string>
+ <string name="permdesc_broadcastPackageRemoved">"アプリケーションパッケージの削除の通知を配信することをアプリケーションに許可します。悪意のあるアプリケーションが他の実行中のアプリケーションを強制終了する恐れがあります。"</string>
<string name="permlab_broadcastSmsReceived">"SMS受信ブロードキャストの送信"</string>
- <string name="permdesc_broadcastSmsReceived">"SMSメッセージの受信通知の配信をアプリケーションに許可します。これにより悪意のあるアプリケーションが、受信SMSメッセージを偽造する恐れがあります。"</string>
+ <string name="permdesc_broadcastSmsReceived">"SMSメッセージの受信通知の配信をアプリケーションに許可します。悪意のあるアプリケーションが受信SMSメッセージを偽造する恐れがあります。"</string>
<string name="permlab_broadcastWapPush">"WAP-PUSH受信ブロードキャストの送信"</string>
- <string name="permdesc_broadcastWapPush">"WAP PUSHメッセージの受信通知を配信することをアプリケーションに許可します。これにより悪意のあるアプリケーションが、MMS受信メッセージを偽造したり、ウェブページのコンテンツを密かに改ざんしたりする恐れがあります。"</string>
+ <string name="permdesc_broadcastWapPush">"WAP PUSHメッセージの受信の通知を配信することをアプリケーションに許可します。悪意のあるアプリケーションがMMS受信メッセージを偽造したり、ウェブページのコンテンツを密かに改ざんする恐れがあります。"</string>
<string name="permlab_setProcessLimit">"実行中のプロセスの数を制限"</string>
<string name="permdesc_setProcessLimit">"実行するプロセス数の上限の制御をアプリケーションに許可します。通常のアプリケーションにはまったく必要ありません。"</string>
<string name="permlab_setAlwaysFinish">"バックグラウンドアプリケーションをすべて終了する"</string>
<string name="permdesc_setAlwaysFinish">"バックグラウンドになり次第必ず操作を終了させるかどうかの制御をアプリケーションに許可します。通常のアプリケーションではまったく必要ありません。"</string>
<string name="permlab_fotaUpdate">"システムアップデートの自動インストール"</string>
- <string name="permdesc_fotaUpdate">"保留中のシステムアップデートに関する通知を受信してインストールを開始することをアプリケーションに許可します。これにより悪意のあるアプリケーションが、許可なく更新を行ってシステムを破壊したり、更新処理を妨害する恐れがあります。"</string>
- <string name="permlab_batteryStats">"バッテリ統計の変更"</string>
- <string name="permdesc_batteryStats">"収集されたバッテリの統計の変更を許可します。通常のアプリケーションでは使用しません。"</string>
+ <string name="permdesc_fotaUpdate">"保留中のシステムアップデートに関する通知の受信とインストールの開始をアプリケーションに許可します。悪意のあるアプリケーションが許可なく更新を行ってシステムを破壊したり、更新処理を妨害する恐れがあります。"</string>
+ <string name="permlab_batteryStats">"電池統計情報の変国"</string>
+ <string name="permdesc_batteryStats">"収集した電池統計情報の変更を許可します。通常のアプリケーションでは使用しません。"</string>
<string name="permlab_internalSystemWindow">"未許可のウィンドウの表示"</string>
<string name="permdesc_internalSystemWindow">"内部システムのユーザーインターフェースで使用するためのウィンドウ作成を許可します。通常のアプリケーションでは使用しません。"</string>
<string name="permlab_systemAlertWindow">"システムレベルの警告の表示"</string>
- <string name="permdesc_systemAlertWindow">"システムの警告ウィンドウをアプリケーションで表示できるようにします。悪意のあるアプリケーションが携帯電話の画面全体を偽装する恐れがあります。"</string>
- <string name="permlab_setAnimationScale">"アニメーション全般の速度の変更"</string>
+ <string name="permdesc_systemAlertWindow">"システムの警告ウィンドウの表示をアプリケーションに許可します。悪意のあるアプリケーションが携帯電話の画面全体を偽装する恐れがあります。"</string>
+ <string name="permlab_setAnimationScale">"アニメーションのプリセット速度の変更"</string>
<string name="permdesc_setAnimationScale">"いつでもアニメーション全般の速度を変更する (アニメーションを速くまたは遅くする) ことをアプリケーションに許可します。"</string>
<string name="permlab_manageAppTokens">"アプリケーショントークンの管理"</string>
<string name="permdesc_manageAppTokens">"通常のZ-orderingを回避して、独自のトークンを作成、管理することをアプリケーションに許可します。通常のアプリケーションではまったく必要ありません。"</string>
<string name="permlab_injectEvents">"キーを押してボタンをコントロール"</string>
<string name="permdesc_injectEvents">"入力イベント (キーを押すなど) を別のアプリケーションに伝えることをアプリケーションに許可します。これにより悪意のあるアプリケーションが、携帯電話を乗っ取る恐れがあります。"</string>
<string name="permlab_readInputState">"入力や操作の記録"</string>
- <string name="permdesc_readInputState">"別のアプリケーションへの入力 (パスワードなど) でもキー入力を監視することをアプリケーションに許可します。通常のアプリケーションではまったく必要ありません。"</string>
+ <string name="permdesc_readInputState">"別のアプリケーションへの入力(パスワードなど)でもキー入力を監視することをアプリケーションに許可します。通常のアプリケーションではまったく必要ありません。"</string>
<string name="permlab_bindInputMethod">"入力方法に関連付ける"</string>
<string name="permdesc_bindInputMethod">"入力方法のトップレベルインターフェースに関連付けることを所有者に許可します。通常のアプリケーションにはまったく必要ありません。"</string>
<string name="permlab_setOrientation">"画面の向きの変更"</string>
<string name="permdesc_setOrientation">"いつでも画面の回転を変更することをアプリケーションに許可します。通常のアプリケーションにはまったく必要ありません。"</string>
<string name="permlab_signalPersistentProcesses">"Linuxのシグナルをアプリケーションに送信"</string>
- <string name="permdesc_signalPersistentProcesses">"すべての永続プロセスに特定の信号を送信するリクエストをアプリケーションに許可します。"</string>
+ <string name="permdesc_signalPersistentProcesses">"受信した電波を継続プロセスに送信することをアプリケーションに許可します。"</string>
<string name="permlab_persistentActivity">"アプリケーションを常に実行する"</string>
<string name="permdesc_persistentActivity">"自身を部分的に永続させて、他のアプリケーション用にはその領域をシステムに使わせないようにすることをアプリケーションに許可します。"</string>
<string name="permlab_deletePackages">"アプリケーションの削除"</string>
- <string name="permdesc_deletePackages">"Androidパッケージの削除をアプリケーションに許可します。これにより悪意のあるアプリケーションが、重要なアプリケーションを削除する恐れがあります。"</string>
+ <string name="permdesc_deletePackages">"Androidパッケージの削除をアプリケーションに許可します。悪意のあるアプリケーションが、重要なアプリケーションを削除する恐れがあります。"</string>
<string name="permlab_clearAppUserData">"他のアプリケーションのデータを削除"</string>
<string name="permdesc_clearAppUserData">"ユーザーデータの消去をアプリケーションに許可します。"</string>
<string name="permlab_deleteCacheFiles">"他のアプリケーションのキャッシュを削除"</string>
@@ -205,46 +205,46 @@
<string name="permlab_getPackageSize">"アプリケーションのメモリ容量の計測"</string>
<string name="permdesc_getPackageSize">"アプリケーションのコード、データ、キャッシュのサイズを取得することを許可します。"</string>
<string name="permlab_installPackages">"アプリケーションを直接インストール"</string>
- <string name="permdesc_installPackages">"Androidパッケージを新たにインストールまたは更新することをアプリケーションに許可します。これにより悪意のあるアプリケーションが、勝手に強力な権限を持つ新しいアプリケーションを追加する恐れがあります。"</string>
+ <string name="permdesc_installPackages">"Androidパッケージのインストール/更新をアプリケーションに許可します。悪意のあるアプリケーションが、勝手に強力な権限を持つ新しいアプリケーションを追加する恐れがあります。"</string>
<string name="permlab_clearAppCache">"アプリケーションキャッシュデータの削除"</string>
<string name="permdesc_clearAppCache">"アプリケーションのキャッシュディレクトリからファイルを削除して携帯電話のメモリを解放することをアプリケーションに許可します。通常、アクセスはシステムプロセスのみに制限されます。"</string>
<string name="permlab_readLogs">"システムログファイルの読み取り"</string>
<string name="permdesc_readLogs">"システムのさまざまなログファイルの読み取りをアプリケーションに許可します。これにより携帯電話の使用状況に関する全般情報が取得されますが、個人情報や非公開情報が含まれることはありません。"</string>
<string name="permlab_diagnostic">"diagが所有するリソースの読み書き"</string>
- <string name="permdesc_diagnostic">"diagグループが所有するリソース (/dev内のファイルなど) への読み書きをアプリケーションに許可します。これはシステムの安定性とセキュリティに影響する恐れがあります。メーカーまたはオペレータによるハードウェア固有の診断以外には使用しないでください。"</string>
+ <string name="permdesc_diagnostic">"diagグループが所有するリソース(例:/dev内のファイル)への読み書きをアプリケーションに許可します。システムの安定性とセキュリティに影響する恐れがあります。メーカー/オペレーターによるハードウェア固有の診断以外には使用しないでください。"</string>
<string name="permlab_changeComponentState">"アプリケーションのコンポーネントを有効/無効にする"</string>
<string name="permdesc_changeComponentState">"別アプリケーションのコンポーネントの有効/無効を変更することをアプリケーションに許可します。これにより悪意のあるアプリケーションが、携帯電話の重要な機能を無効にする恐れがあります。アプリケーションコンポーネントが利用できない、整合性が取れない、または不安定な状態になる恐れがあるので、許可には注意が必要です。"</string>
<string name="permlab_setPreferredApplications">"優先アプリケーションの設定"</string>
- <string name="permdesc_setPreferredApplications">"優先アプリケーションを変更することをアプリケーションに許可します。これにより悪意のあるアプリケーションが、実行中のアプリケーションを密かに変更し、既存のアプリケーションになりすまして、非公開データを収集する恐れがあります。"</string>
- <string name="permlab_writeSettings">"システム全般の設定の変更"</string>
+ <string name="permdesc_setPreferredApplications">"優先アプリケーションを変更することをアプリケーションに許可します。悪意のあるアプリケーションが実行中のアプリケーションを密かに変更し、既存のアプリケーションになりすまして非公開データを収集する恐れがあります。"</string>
+ <string name="permlab_writeSettings">"システムの全般設定の変更"</string>
<string name="permdesc_writeSettings">"システム設定データの変更をアプリケーションに許可します。悪意のあるアプリケーションがシステム設定を破壊する恐れがあります。"</string>
<string name="permlab_writeSecureSettings">"システムのセキュリティ設定の変更"</string>
<string name="permdesc_writeSecureSettings">"システムのセキュリティ設定の変更をアプリケーションに許可します。通常のアプリケーションでは使用しません。"</string>
<string name="permlab_writeGservices">"Googleサービスの地図の変更"</string>
<string name="permdesc_writeGservices">"Googleサービスマップの変更をアプリケーションに許可します。通常のアプリケーションでは使用しません。"</string>
<string name="permlab_receiveBootCompleted">"起動時に自動的に開始"</string>
- <string name="permdesc_receiveBootCompleted">"システムの起動直後に自動的に起動することをアプリケーションに許可します。これにより携帯電話の起動に時間がかかるようになります。また、アプリケーションが常に実行中となるため、携帯電話の全体的な動作が遅くなります。"</string>
+ <string name="permdesc_receiveBootCompleted">"システムの起動後に自動的に起動することをアプリケーションに許可します。携帯電話の起動に時間がかかるようになり、アプリケーションが常に実行されるために携帯電話の全体的な動作が遅くなります。"</string>
<string name="permlab_broadcastSticky">"stickyブロードキャストの配信"</string>
<string name="permdesc_broadcastSticky">"配信が終了してもメモリに残るようなstickyブロードキャストをアプリケーションに許可します。悪意のあるアプリケーションがメモリを使いすぎて、携帯電話の動作が遅くなったり、不安定になる恐れがあります。"</string>
<string name="permlab_readContacts">"連絡先データの読み取り"</string>
- <string name="permdesc_readContacts">"携帯電話に保存した連絡先 (アドレス) データをアプリケーションですべて読み取れるようにします。これにより悪意のあるアプリケーションが、そのデータを他人に送信する恐れがあります。"</string>
+ <string name="permdesc_readContacts">"端末に保存した連絡先(アドレス)データの読み取りをアプリケーションに許可します。悪意のあるアプリケーションがデータを他人に送信する恐れがあります。"</string>
<string name="permlab_writeContacts">"連絡先データの書き込み"</string>
- <string name="permdesc_writeContacts">"携帯電話に保存した連絡先 (アドレス) データの変更をアプリケーションに許可します。これにより悪意のあるアプリケーションが、連絡先データを消去や変更する恐れがあります。"</string>
+ <string name="permdesc_writeContacts">"端末に保存した連絡先(アドレス)データの変更をアプリケーションに許可します。悪意のあるアプリケーションが連絡先データを消去/変更する恐れがあります。"</string>
<string name="permlab_writeOwnerData">"所有者データの書き込み"</string>
- <string name="permdesc_writeOwnerData">"携帯電話に保存した所有者のデータの変更をアプリケーションに許可します。これにより悪意のあるアプリケーションが、所有者のデータを消去または変更する恐れがあります。"</string>
+ <string name="permdesc_writeOwnerData">"端末に保存した所有者のデータの変更をアプリケーションに許可します。悪意のあるアプリケーションが所有者のデータを消去/変更する恐れがあります。"</string>
<string name="permlab_readOwnerData">"所有者データの読み取り"</string>
- <string name="permdesc_readOwnerData">"携帯電話に保存した所有者データの読み取りをアプリケーションに許可します。これにより悪意のあるアプリケーションが、所有者データを読み取る恐れがあります。"</string>
+ <string name="permdesc_readOwnerData">"携帯電話に保存した所有者データの読み取りをアプリケーションに許可します。悪意のあるアプリケーションが所有者データを読み取る恐れがあります。"</string>
<string name="permlab_readCalendar">"カレンダーデータの読み取り"</string>
- <string name="permdesc_readCalendar">"携帯電話に保存したカレンダーのイベントをアプリケーションですべて読み取れるようにします。悪意のあるアプリケーションではこれを利用して、カレンダーのイベントを他人に送信できます。"</string>
+ <string name="permdesc_readCalendar">"端末に保存したカレンダーの予定の読み取りをアプリケーションに許可します。悪意のあるアプリケーションがカレンダーの予定を他人に送信する恐れがあります。"</string>
<string name="permlab_writeCalendar">"カレンダーデータの書き込み"</string>
- <string name="permdesc_writeCalendar">"携帯電話に保存したカレンダーイベントの変更をアプリケーションに許可します。これにより悪意のあるアプリケーションが、カレンダーデータを消去や変更する恐れがあります。"</string>
+ <string name="permdesc_writeCalendar">"端末に保存したカレンダーの予定の変更をアプリケーションに許可します。悪意のあるアプリケーションが、カレンダーデータを消去/変更する恐れがあります。"</string>
<string name="permlab_accessMockLocation">"仮の位置情報でテスト"</string>
<string name="permdesc_accessMockLocation">"テスト用に仮の位置情報源を作成します。これにより悪意のあるアプリケーションが、GPS、ネットワークプロバイダなどから返される本当の位置情報や状況を改ざんする恐れがあります。"</string>
<string name="permlab_accessLocationExtraCommands">"位置情報プロバイダのその他のコマンドへのアクセス"</string>
- <string name="permdesc_accessLocationExtraCommands">"位置情報プロバイダのその他のコマンドにアクセスします。これにより悪意のあるアプリケーションが、GPSなどの位置情報源の動作を妨害する恐れがあります。"</string>
- <string name="permlab_accessFineLocation">"正確な (GPS) 位置"</string>
- <string name="permdesc_accessFineLocation">"GPSなど、携帯電話の正確な位置情報源に、可能な場合アクセスします。これにより悪意のあるアプリケーションが、ユーザーの現在地を特定したり、バッテリの消費を増やしたりする恐れがあります。"</string>
- <string name="permlab_accessCoarseLocation">"おおよその (ネットワーク情報による) 位置"</string>
+ <string name="permdesc_accessLocationExtraCommands">"位置情報提供元の追加コマンドにアクセスします。悪意のあるアプリケーションがGPSなどの位置提供の動作を妨害する恐れがあります。"</string>
+ <string name="permlab_accessFineLocation">"精細な位置情報(GPS)"</string>
+ <string name="permdesc_accessFineLocation">"GPSなど携帯電話の位置情報にアクセスします(可能な場合)。今いる場所が悪意のあるアプリケーションに検出されたり、バッテリーの消費が増える恐れがあります。"</string>
+ <string name="permlab_accessCoarseLocation">"おおよその位置情報(ネットワーク基地局)"</string>
<string name="permdesc_accessCoarseLocation">"セルラーネットワークデータベースなど、携帯電話のおおよその位置を特定する情報源が利用可能な場合にアクセスします。これにより悪意のあるアプリケーションが、ユーザーのおおよその位置を特定できる恐れがあります。"</string>
<string name="permlab_accessSurfaceFlinger">"SurfaceFlingerへのアクセス"</string>
<string name="permdesc_accessSurfaceFlinger">"SurfaceFlingerの低レベルの機能の使用をアプリケーションに許可します。"</string>
@@ -255,41 +255,37 @@
<string name="permlab_recordAudio">"録音"</string>
<string name="permdesc_recordAudio">"オーディオ録音パスへのアクセスをアプリケーションに許可します。"</string>
<string name="permlab_camera">"写真の撮影"</string>
- <string name="permdesc_camera">"カメラで写真を撮ることをアプリケーションに許可します。これによりアプリケーションは、カメラに写る画像をいつでも収集できます。"</string>
- <string name="permlab_brick">"携帯電話を永久に使用できなくする"</string>
+ <string name="permdesc_camera">"カメラでの写真撮影をアプリケーションに許可します。アプリケーションはカメラから画像をいつでも収集できます。"</string>
+ <string name="permlab_brick">"端末を永続的に無効にする"</string>
<string name="permdesc_brick">"携帯電話全体を永続的に無効にすることをアプリケーションに許可します。この許可は非常に危険です。"</string>
- <string name="permlab_reboot">"携帯電話の再起動"</string>
- <string name="permdesc_reboot">"携帯電話の強制的な再起動をアプリケーションに許可します。"</string>
+ <string name="permlab_reboot">"端末の再起動"</string>
+ <string name="permdesc_reboot">"端末の強制的な再起動をアプリケーションに許可します。"</string>
<string name="permlab_mount_unmount_filesystems">"ファイルシステムのマウントとマウント解除"</string>
<string name="permdesc_mount_unmount_filesystems">"リムーバブルメモリのファイルシステムのマウントとマウント解除をアプリケーションに許可します。"</string>
- <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
- <skip />
- <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
- <skip />
- <string name="permlab_vibrate">"バイブレータの制御"</string>
- <string name="permdesc_vibrate">"バイブレータのコントロールをアプリケーションに許可します。"</string>
+ <string name="permlab_mount_format_filesystems">"外部ストレージのフォーマット"</string>
+ <string name="permdesc_mount_format_filesystems">"アプリケーションがリムーバブルストレージをフォーマットすることを許可します。"</string>
+ <string name="permlab_vibrate">"バイブレーション制御"</string>
+ <string name="permdesc_vibrate">"バイブレーションの制御をアプリケーションに許可します。"</string>
<string name="permlab_flashlight">"ライトのコントロール"</string>
<string name="permdesc_flashlight">"ライトの制御をアプリケーションに許可します。"</string>
<string name="permlab_hardware_test">"ハードウェアのテスト"</string>
<string name="permdesc_hardware_test">"ハードウェアのテストのためにさまざまな周辺機器を制御することをアプリケーションに許可します。"</string>
- <string name="permlab_callPhone">"電話番号に直接発信"</string>
- <string name="permdesc_callPhone">"電話を自動でかけることをアプリケーションに許可します。悪意のあるアプリケーションが予想外の電話をかけて、料金が発生する恐れがあります。緊急電話番号への通話は許可しません。"</string>
- <string name="permlab_callPrivileged">"あらゆる電話番号に直接発信"</string>
- <string name="permdesc_callPrivileged">"緊急電話を含めてあらゆる電話番号に自動発信することをアプリケーションに許可します。悪意のあるアプリケーションが緊急サービスに不要かつ不正な通話をする恐れがあります。"</string>
- <string name="permlab_locationUpdates">"位置の更新通知の制御"</string>
+ <string name="permlab_callPhone">"電話番号発信"</string>
+ <string name="permdesc_callPhone">"アプリケーションが電話を自動発信することを許可します。悪意のあるアプリケーションが意図しない電話をかけて料金が発生する恐れがあります。緊急呼への発信は許可しません。"</string>
+ <string name="permlab_callPrivileged">"電話番号発信"</string>
+ <string name="permdesc_callPrivileged">"緊急呼を含めあらゆる電話番号に自動発信することをアプリケーションに許可します。悪意のあるアプリケーションが緊急サービスに不正な通報をする恐れがあります。"</string>
+ <string name="permlab_locationUpdates">"位置情報の更新通知"</string>
<string name="permdesc_locationUpdates">"無線通信からの位置更新通知を有効/無効にすることを許可します。通常のアプリケーションでは使用しません。"</string>
<string name="permlab_checkinProperties">"チェックインプロパティへのアクセス"</string>
<string name="permdesc_checkinProperties">"チェックインサービスがアップロードしたプロパティへの読み書きを許可します。通常のアプリケーションでは使用しません。"</string>
- <!-- no translation found for permlab_bindGadget (2519859363977647275) -->
- <skip />
- <!-- no translation found for permdesc_bindGadget (7865866514555126333) -->
- <skip />
- <string name="permlab_modifyPhoneState">"携帯電話の状態の変更"</string>
- <string name="permdesc_modifyPhoneState">"携帯端末の電話機能のコントロールをアプリケーションに許可します。この許可を受けたアプリケーションは、ネットワークの切り替え、携帯電話の無線通信のオン/オフなどを通知せずに行うことができます。"</string>
- <string name="permlab_readPhoneState">"携帯電話の状態の読み取り"</string>
- <string name="permdesc_readPhoneState">"携帯端末の電話機能へのアクセスをアプリケーションに許可します。これを許可されたアプリケーションは、この携帯電話の電話番号、通話中かどうか、通話相手の電話番号などを特定できます。"</string>
- <string name="permlab_wakeLock">"携帯電話をスリープ状態にしない"</string>
- <string name="permdesc_wakeLock">"携帯電話をスリープ状態にしないようにすることをアプリケーションに許可します。"</string>
+ <string name="permlab_bindGadget">"ガジェットの選択"</string>
+ <string name="permdesc_bindGadget">"特定のアプリケーションで使用可能なガジェットをシステムに指定することをアプリケーションに許可します。この許可を受けたアプリケーションは、他のアプリケーションに個人データへのアクセスを許可することができます。通常のアプリケーションでは使用しません。"</string>
+ <string name="permlab_modifyPhoneState">"端末ステータスの変更"</string>
+ <string name="permdesc_modifyPhoneState">"端末の電話機能のコントロールをアプリケーションに許可します。アプリケーションは、ネットワークの切り替え、携帯電話の無線通信のオン/オフなどを通知せずに行うことができます。"</string>
+ <string name="permlab_readPhoneState">"端末ステータスの読み取り"</string>
+ <string name="permdesc_readPhoneState">"端末の電話機能へのアクセスをアプリケーションに許可します。アプリケーションは、この携帯電話の電話番号、通話中かどうか、通話相手の電話番号などを特定できます。"</string>
+ <string name="permlab_wakeLock">"端末のスリープを無効にする"</string>
+ <string name="permdesc_wakeLock">"端末のスリープを無効にすることをアプリケーションに許可します。"</string>
<string name="permlab_devicePower">"携帯電話の電源のオン/オフ"</string>
<string name="permdesc_devicePower">"携帯電話の電源のオン/オフをアプリケーションに許可します。"</string>
<string name="permlab_factoryTest">"出荷時試験モードでの実行"</string>
@@ -298,82 +294,76 @@
<string name="permdesc_setWallpaper">"システムの壁紙の設定をアプリケーションに許可します。"</string>
<string name="permlab_setWallpaperHints">"壁紙サイズのヒントの設定"</string>
<string name="permdesc_setWallpaperHints">"システムの壁紙サイズのヒントの設定をアプリケーションに許可します。"</string>
- <string name="permlab_masterClear">"システムを出荷時のデフォルトにリセット"</string>
+ <string name="permlab_masterClear">"システムを出荷時設定にリセット"</string>
<string name="permdesc_masterClear">"データ、設定、インストールしたアプリケーションをすべて消去して、完全に出荷時の設定にシステムをリセットすることをアプリケーションに許可します。"</string>
<string name="permlab_setTimeZone">"タイムゾーンの設定"</string>
- <string name="permdesc_setTimeZone">"携帯電話のタイムゾーンの変更をアプリケーションに許可します。"</string>
+ <string name="permdesc_setTimeZone">"端末のタイムゾーンの変更をアプリケーションに許可します。"</string>
<string name="permlab_getAccounts">"既知のアカウントの取得"</string>
- <string name="permdesc_getAccounts">"携帯端末内にあるアカウントのリストの取得をアプリケーションに許可します。"</string>
+ <string name="permdesc_getAccounts">"端末内にあるアカウントのリストの取得をアプリケーションに許可します。"</string>
<string name="permlab_accessNetworkState">"ネットワーク状態の表示"</string>
<string name="permdesc_accessNetworkState">"すべてのネットワーク状態の表示をアプリケーションに許可します。"</string>
- <string name="permlab_createNetworkSockets">"インターネットへの完全なアクセス権"</string>
+ <string name="permlab_createNetworkSockets">"完全なインターネットアクセス"</string>
<string name="permdesc_createNetworkSockets">"ネットワークソケットの作成をアプリケーションに許可します。"</string>
<string name="permlab_writeApnSettings">"アクセスポイント名設定の書き込み"</string>
<string name="permdesc_writeApnSettings">"APNのプロキシやポートなどのAPN設定の変更をアプリケーションに許可します。"</string>
<string name="permlab_changeNetworkState">"ネットワーク接続の変更"</string>
<string name="permdesc_changeNetworkState">"ネットワークの接続状態の変更をアプリケーションに許可します。"</string>
- <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
- <skip />
- <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
- <skip />
+ <string name="permlab_changeBackgroundDataSetting">"バックグラウンドデータ使用の設定の変更"</string>
+ <string name="permdesc_changeBackgroundDataSetting">"バックグラウンドデータ使用の設定の変更をアプリケーションに許可します。"</string>
<string name="permlab_accessWifiState">"Wi-Fi状態の表示"</string>
<string name="permdesc_accessWifiState">"Wi-Fi状態に関する情報の表示をアプリケーションに許可します。"</string>
<string name="permlab_changeWifiState">"Wi-Fi状態の変更"</string>
<string name="permdesc_changeWifiState">"Wi-Fiアクセスポイントへの接続や接続の切断、設定されたWi-Fiネットワークの変更をアプリケーションに許可します。"</string>
<string name="permlab_bluetoothAdmin">"Bluetoothの管理"</string>
- <string name="permdesc_bluetoothAdmin">"ローカルのBluetooth電話を設定し、リモートデバイスを検出してペアに設定することをアプリケーションに許可します。"</string>
+ <string name="permdesc_bluetoothAdmin">"このBluetooth端末の設定、およびリモート端末を検出してペアに設定することをアプリケーションに許可します。"</string>
<string name="permlab_bluetooth">"Bluetooth接続の作成"</string>
- <string name="permdesc_bluetooth">"ローカルBluetooth電話の設定を表示し、デバイスをペアとして設定して接続を承認することをアプリケーションに許可します。"</string>
+ <string name="permdesc_bluetooth">"このBluetooth端末の設定表示、および別の端末をペアとして設定し接続を承認することをアプリケーションに許可します。"</string>
<string name="permlab_disableKeyguard">"キーロックを無効にする"</string>
<string name="permdesc_disableKeyguard">"キーロックや関連するパスワードセキュリティを無効にすることをアプリケーションに許可します。正当な利用の例では、かかってきた電話を受信する際にキーロックを無効にし、通話の終了時にキーロックを有効にし直します。"</string>
<string name="permlab_readSyncSettings">"同期設定の読み取り"</string>
- <string name="permdesc_readSyncSettings">"連絡先の同期が有効かどうかなど、同期設定の読み取りをアプリケーションに許可します。"</string>
+ <string name="permdesc_readSyncSettings">"連絡先の同期の有効/無効など、同期設定の読み取りをアプリケーションに許可します。"</string>
<string name="permlab_writeSyncSettings">"同期設定の書き込み"</string>
- <string name="permdesc_writeSyncSettings">"連絡先の同期が有効かどうかなど、同期設定の変更をアプリケーションに許可します。"</string>
+ <string name="permdesc_writeSyncSettings">"連絡先の同期の有効/無効など、同期設定の変更をアプリケーションに許可します。"</string>
<string name="permlab_readSyncStats">"同期統計の読み取り"</string>
- <string name="permdesc_readSyncStats">"同期状態 (同期履歴など) の読み取りをアプリケーションに許可します。"</string>
+ <string name="permdesc_readSyncStats">"同期状態(同期履歴など)の読み取りをアプリケーションに許可します。"</string>
<string name="permlab_subscribedFeedsRead">"登録したフィードの読み取り"</string>
<string name="permdesc_subscribedFeedsRead">"現在同期しているフィードの詳細の取得をアプリケーションに許可します。"</string>
<string name="permlab_subscribedFeedsWrite">"登録したフィードの書き込み"</string>
<string name="permdesc_subscribedFeedsWrite">"現在同期しているフィードの変更をアプリケーションに許可します。悪意のあるアプリケーションが同期フィードを変更する恐れがあります。"</string>
- <!-- no translation found for permlab_readDictionary (432535716804748781) -->
- <skip />
- <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
- <skip />
- <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
- <skip />
- <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
- <skip />
+ <string name="permlab_readDictionary">"ユーザー定義辞書の読み込み"</string>
+ <string name="permdesc_readDictionary">"アプリケーションがユーザー辞書に登録されている個人的な語句や名前を読み込むことを許可します。"</string>
+ <string name="permlab_writeDictionary">"ユーザー定義辞書への書き込み"</string>
+ <string name="permdesc_writeDictionary">"アプリケーションがユーザー辞書に新しい語句を書き込むことを許可します。"</string>
<string-array name="phoneTypes">
<item>"自宅"</item>
<item>"携帯"</item>
- <item>"勤務先"</item>
- <item>"勤務先FAX"</item>
- <item>"自宅FAX"</item>
+ <item>"仕事"</item>
+ <item>"FAX(仕事)"</item>
+ <item>"FAX(自宅)"</item>
<item>"ポケベル"</item>
<item>"その他"</item>
<item>"カスタム"</item>
</string-array>
<string-array name="emailAddressTypes">
<item>"自宅"</item>
- <item>"勤務先"</item>
+ <item>"仕事"</item>
<item>"その他"</item>
<item>"カスタム"</item>
</string-array>
<string-array name="postalAddressTypes">
<item>"自宅"</item>
- <item>"勤務先"</item>
+ <item>"仕事"</item>
<item>"その他"</item>
<item>"カスタム"</item>
</string-array>
<string-array name="imAddressTypes">
<item>"自宅"</item>
- <item>"勤務先"</item>
+ <item>"仕事"</item>
<item>"その他"</item>
<item>"カスタム"</item>
</string-array>
<string-array name="organizationTypes">
- <item>"勤務先"</item>
+ <item>"仕事"</item>
<item>"その他"</item>
<item>"カスタム"</item>
</string-array>
@@ -389,31 +379,31 @@
</string-array>
<string name="keyguard_password_enter_pin_code">"PINコードを入力"</string>
<string name="keyguard_password_wrong_pin_code">"PINコードが正しくありません。"</string>
- <string name="keyguard_label_text">"ロックを解除するには、Menu、0キーの順に押します。"</string>
- <string name="emergency_call_dialog_number_for_display">"緊急電話番号"</string>
- <string name="lockscreen_carrier_default">"(サービスなし)"</string>
- <string name="lockscreen_screen_locked">"画面がロックされています。"</string>
- <string name="lockscreen_instructions_when_pattern_enabled">"Menuキーを押してロックを解除するか、緊急電話をかけます。"</string>
- <string name="lockscreen_instructions_when_pattern_disabled">"ロックを解除するにはMenuキーを押します。"</string>
+ <string name="keyguard_label_text">"ロックを解除するにはMENU、0キーの順に押します。"</string>
+ <string name="emergency_call_dialog_number_for_display">"緊急呼番号"</string>
+ <string name="lockscreen_carrier_default">"(サービス登録なし)"</string>
+ <string name="lockscreen_screen_locked">"画面ロック中"</string>
+ <string name="lockscreen_instructions_when_pattern_enabled">"MENUキーでロック解除(または緊急呼)"</string>
+ <string name="lockscreen_instructions_when_pattern_disabled">"MENUキーでロック解除"</string>
<string name="lockscreen_pattern_instructions">"ロックを解除するパターンを入力"</string>
- <string name="lockscreen_emergency_call">"緊急電話"</string>
+ <string name="lockscreen_emergency_call">"緊急呼"</string>
<string name="lockscreen_pattern_correct">"一致しました"</string>
- <string name="lockscreen_pattern_wrong">"もう一度試してください"</string>
+ <string name="lockscreen_pattern_wrong">"やり直してください"</string>
<string name="lockscreen_plugged_in">"充電中 (<xliff:g id="NUMBER">%d%%</xliff:g>)"</string>
<string name="lockscreen_low_battery">"充電してください。"</string>
- <string name="lockscreen_missing_sim_message_short">"SIMカードがありません。"</string>
- <string name="lockscreen_missing_sim_message">"SIMカードが携帯電話に挿入されていません。"</string>
+ <string name="lockscreen_missing_sim_message_short">"SIMカードが挿入されていません"</string>
+ <string name="lockscreen_missing_sim_message">"SIMカードが挿入されていません"</string>
<string name="lockscreen_missing_sim_instructions">"SIMカードを挿入してください。"</string>
<string name="lockscreen_network_locked_message">"ネットワークがロックされました"</string>
<string name="lockscreen_sim_puk_locked_message">"SIMカードはPUKでロックされています。"</string>
<string name="lockscreen_sim_puk_locked_instructions">"お客様サポートにお問い合わせください。"</string>
<string name="lockscreen_sim_locked_message">"SIMカードはロックされています。"</string>
- <string name="lockscreen_sim_unlock_progress_dialog_message">"SIMカードのロックを解除中..."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message">"SIMカードのロック解除中..."</string>
<string name="lockscreen_too_many_failed_attempts_dialog_message">"ロック解除のパターンは<xliff:g id="NUMBER_0">%d</xliff:g>回とも正しく指定されていません。"\n\n"<xliff:g id="NUMBER_1">%d</xliff:g>秒後にもう一度指定してください。"</string>
<string name="lockscreen_failed_attempts_almost_glogin">"指定したパターンは<xliff:g id="NUMBER_0">%d</xliff:g>回とも正しくありません。あと<xliff:g id="NUMBER_1">%d</xliff:g>回指定に失敗すると、携帯電話のロックの解除にGoogleへのログインが必要になります。"\n\n"<xliff:g id="NUMBER_2">%d</xliff:g>秒後にもう一度指定してください。"</string>
- <string name="lockscreen_too_many_failed_attempts_countdown">"<xliff:g id="NUMBER">%d</xliff:g>秒後にもう一度試してください。"</string>
+ <string name="lockscreen_too_many_failed_attempts_countdown">"<xliff:g id="NUMBER">%d</xliff:g>秒後にやり直してください。"</string>
<string name="lockscreen_forgot_pattern_button_text">"パターンを忘れた場合"</string>
- <string name="lockscreen_glogin_too_many_attempts">"パターンの指定回数が多すぎる"</string>
+ <string name="lockscreen_glogin_too_many_attempts">"パターンのエラーが多すぎます"</string>
<string name="lockscreen_glogin_instructions">"ロックを解除するには、"\n"Googleアカウントでログインしてください。"</string>
<string name="lockscreen_glogin_username_hint">"ユーザー名 (メール)"</string>
<string name="lockscreen_glogin_password_hint">"パスワード"</string>
@@ -434,27 +424,24 @@
<skip />
<string name="battery_status_charging">"充電中..."</string>
<string name="battery_low_title">"充電してください"</string>
- <string name="battery_low_subtitle">"バッテリの残量が少なくなっています。"</string>
+ <string name="battery_low_subtitle">"電池が残り少なくなっています:"</string>
<string name="battery_low_percent_format">"残り<xliff:g id="NUMBER">%d%%</xliff:g>未満"</string>
<string name="factorytest_failed">"出荷時試験が失敗"</string>
<string name="factorytest_not_system">"FACTORY_TEST操作は、/system/appにインストールされたパッケージのみが対象です。"</string>
<string name="factorytest_no_action">"FACTORY_TEST操作を行うパッケージは見つかりませんでした。"</string>
<string name="factorytest_reboot">"再起動"</string>
- <!-- no translation found for js_dialog_title (8143918455087008109) -->
- <skip />
- <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
- <skip />
- <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
- <skip />
+ <string name="js_dialog_title">"ページ「<xliff:g id="TITLE">%s</xliff:g>」の記述:"</string>
+ <string name="js_dialog_title_default">"JavaScript"</string>
+ <string name="js_dialog_before_unload">"このページから移動しますか?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"続行する場合は[OK]、今のページに残る場合は[キャンセル]を選択してください。"</string>
<string name="save_password_label">"確認"</string>
<string name="save_password_message">"このパスワードをブラウザで保存しますか?"</string>
<string name="save_password_notnow">"今は保存しない"</string>
<string name="save_password_remember">"保存"</string>
<string name="save_password_never">"保存しない"</string>
<string name="open_permission_deny">"このページへのアクセスは許可されていません。"</string>
- <string name="text_copied">"テキストがクリップボードにコピーされました。"</string>
+ <string name="text_copied">"テキストをクリップボードにコピーしました。"</string>
<string name="more_item_label">"その他"</string>
- <string name="prepend_shortcut_label">"Menu+"</string>
+ <string name="prepend_shortcut_label">"MENU+"</string>
<string name="menu_space_shortcut_label">"Space"</string>
<string name="menu_enter_shortcut_label">"Enter"</string>
<string name="menu_delete_shortcut_label">"Del"</string>
@@ -496,22 +483,38 @@
<item quantity="one">"明日"</item>
<item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>日後"</item>
</plurals>
- <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) -->
- <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) -->
- <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) -->
- <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) -->
- <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) -->
- <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) -->
- <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) -->
- <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) -->
- <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) -->
- <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) -->
- <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) -->
- <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) -->
- <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) -->
- <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) -->
- <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) -->
- <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) -->
+ <plurals name="abbrev_num_seconds_ago">
+ <item quantity="one">"1秒前"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>秒前"</item>
+ </plurals>
+ <plurals name="abbrev_num_minutes_ago">
+ <item quantity="one">"1分前"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>分後"</item>
+ </plurals>
+ <plurals name="abbrev_num_hours_ago">
+ <item quantity="one">"1時間前"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>時間前"</item>
+ </plurals>
+ <plurals name="abbrev_num_days_ago">
+ <item quantity="one">"昨日"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>日前"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_seconds">
+ <item quantity="one">"1秒後"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>秒後"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_minutes">
+ <item quantity="one">"1分後"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>分後"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_hours">
+ <item quantity="one">"1時間後"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>時間後"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_days">
+ <item quantity="one">"明日"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>日後"</item>
+ </plurals>
<string name="preposition_for_date">"%s"</string>
<string name="preposition_for_time">"%s"</string>
<string name="preposition_for_year">"%s年"</string>
@@ -527,14 +530,14 @@
<string name="weeks">"週間"</string>
<string name="year">"年"</string>
<string name="years">"年"</string>
- <string name="sunday">"日曜"</string>
- <string name="monday">"月曜"</string>
- <string name="tuesday">"火曜"</string>
- <string name="wednesday">"水曜"</string>
- <string name="thursday">"木曜"</string>
- <string name="friday">"金曜"</string>
- <string name="saturday">"土曜"</string>
- <string name="every_weekday">"平日の毎日 (月~金)"</string>
+ <string name="sunday">"日曜日"</string>
+ <string name="monday">"月曜日"</string>
+ <string name="tuesday">"火曜日"</string>
+ <string name="wednesday">"水曜日"</string>
+ <string name="thursday">"木曜日"</string>
+ <string name="friday">"金曜日"</string>
+ <string name="saturday">"土曜日"</string>
+ <string name="every_weekday">"平日(月~金)"</string>
<string name="daily">"毎日"</string>
<string name="weekly">"毎週<xliff:g id="DAY">%s</xliff:g>"</string>
<string name="monthly">"毎月"</string>
@@ -545,25 +548,23 @@
<string name="am">"AM"</string>
<string name="pm">"PM"</string>
<string name="numeric_date">"<xliff:g id="YEAR">%Y</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="DAY">%d</xliff:g>"</string>
- <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g> (<xliff:g id="WEEKDAY1">%1$s</xliff:g>) <xliff:g id="TIME1">%3$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g> (<xliff:g id="WEEKDAY2">%4$s</xliff:g>) <xliff:g id="TIME2">%6$s</xliff:g>"</string>
- <string name="wday1_date1_wday2_date2">"<xliff:g id="DATE1">%2$s</xliff:g> (<xliff:g id="WEEKDAY1">%1$s</xliff:g>)~<xliff:g id="DATE2">%5$s</xliff:g> (<xliff:g id="WEEKDAY2">%4$s</xliff:g>)"</string>
+ <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%3$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g><xliff:g id="WEEKDAY2">%4$s</xliff:g><xliff:g id="TIME2">%6$s</xliff:g>"</string>
+ <string name="wday1_date1_wday2_date2">"<xliff:g id="DATE1">%2$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g><xliff:g id="WEEKDAY2">%4$s</xliff:g>"</string>
<string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g> <xliff:g id="TIME1">%3$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g> <xliff:g id="TIME2">%6$s</xliff:g>"</string>
<string name="date1_date2">"<xliff:g id="DATE1">%2$s</xliff:g>~<xliff:g id="DATE2">%5$s</xliff:g>"</string>
<string name="time1_time2">"<xliff:g id="TIME1">%1$s</xliff:g>~<xliff:g id="TIME2">%2$s</xliff:g>"</string>
- <string name="time_wday_date">"<xliff:g id="DATE">%3$s</xliff:g> (<xliff:g id="WEEKDAY">%2$s</xliff:g>) <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="wday_date">"<xliff:g id="DATE">%3$s</xliff:g> (<xliff:g id="WEEKDAY">%2$s</xliff:g>)"</string>
+ <string name="time_wday_date">"<xliff:g id="DATE">%3$s</xliff:g><xliff:g id="WEEKDAY">%2$s</xliff:g><xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
+ <string name="wday_date">"<xliff:g id="DATE">%3$s</xliff:g><xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
<string name="time_date">"<xliff:g id="DATE">%3$s</xliff:g>、<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <!-- no translation found for date_time (6104442718633642836) -->
- <skip />
- <!-- no translation found for relative_time (1818557177829411417) -->
- <skip />
+ <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>、<xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>、<xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g>、<xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="YEAR">yyyy</xliff:g>'\'\'年\'\''<xliff:g id="MONTH">MMMM</xliff:g><xliff:g id="DAY">d</xliff:g>'\'\'日\'\''"</string>
- <string name="full_date_day_first">"<xliff:g id="YEAR">yyyy</xliff:g>'\'\'年\'\''<xliff:g id="MONTH">MMMM</xliff:g><xliff:g id="DAY">d</xliff:g>'\'\'日\'\''"</string>
- <string name="medium_date_month_first">"<xliff:g id="YEAR">yyyy</xliff:g>'\'\'年\'\''<xliff:g id="MONTH">MMM</xliff:g><xliff:g id="DAY">d</xliff:g>'\'\'日\'\''"</string>
- <string name="medium_date_day_first">"<xliff:g id="YEAR">yyyy</xliff:g>'\'\'年\'\''<xliff:g id="MONTH">MMM</xliff:g><xliff:g id="DAY">d</xliff:g>'\'\'日\'\''"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>'/'<xliff:g id="MONTH">MMMM</xliff:g>'/'<xliff:g id="DAY">d</xliff:g>"</string>
+ <string name="full_date_day_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>'年'<xliff:g id="MONTH">MMMM</xliff:g>'月'<xliff:g id="DAY">d</xliff:g>'日'"</string>
+ <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>'/'<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>'年'"</string>
+ <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'/'<xliff:g id="MONTH">MMM</xliff:g>'/'<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"正午"</string>
<string name="Noon">"正午"</string>
<string name="midnight">"午前0時"</string>
@@ -576,66 +577,66 @@
<!-- no translation found for month_year (9219019380312413367) -->
<skip />
<string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="date_and_time">"<xliff:g id="YEAR">%Y</xliff:g>年<xliff:g id="MONTH">%B</xliff:g><xliff:g id="DAY">%-d</xliff:g>日<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
- <string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2">%8$s</xliff:g>日"</string>
- <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>)~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>)"</string>
- <string name="same_year_mdy1_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2">%8$s</xliff:g>日"</string>
- <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>)~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>)"</string>
- <string name="same_year_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日<xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2">%8$s</xliff:g>日<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>) <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>) <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日<xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2">%8$s</xliff:g>日<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>) <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>) <xliff:g id="TIME2">%10$s</xliff:g>"</string>
+ <string name="date_and_time">"<xliff:g id="YEAR">%Y</xliff:g>/<xliff:g id="MONTH">%B</xliff:g>/<xliff:g id="DAY">%-d</xliff:g> <xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string>
+ <string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>月<xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="MONTH2">%7$s</xliff:g>月<xliff:g id="DAY2">%8$s</xliff:g>日"</string>
+ <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
+ <string name="same_year_mdy1_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g>月<xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="MONTH2">%7$s</xliff:g>月<xliff:g id="DAY2">%8$s</xliff:g>日"</string>
+ <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR">%9$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
+ <string name="same_year_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>月<xliff:g id="DAY1">%3$s</xliff:g>日<xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>月<xliff:g id="DAY2">%8$s</xliff:g>日<xliff:g id="TIME2">%10$s</xliff:g>"</string>
+ <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
+ <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g>月<xliff:g id="DAY1">%3$s</xliff:g>日 <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH2">%7$s</xliff:g>月<xliff:g id="DAY2">%8$s</xliff:g>日 <xliff:g id="TIME2">%10$s</xliff:g>"</string>
+ <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="numeric_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g> (<xliff:g id="WEEKDAY1">%1$s</xliff:g>)~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g> (<xliff:g id="WEEKDAY2">%6$s</xliff:g>)"</string>
+ <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
<string name="numeric_mdy1_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g> (<xliff:g id="WEEKDAY1">%1$s</xliff:g>)~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g> (<xliff:g id="WEEKDAY2">%6$s</xliff:g>)"</string>
+ <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
<string name="numeric_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g> (<xliff:g id="WEEKDAY1">%1$s</xliff:g>) <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g> (<xliff:g id="WEEKDAY2">%6$s</xliff:g>) <xliff:g id="TIME2">%10$s</xliff:g>"</string>
+ <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
<string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g> (<xliff:g id="WEEKDAY1">%1$s</xliff:g>) <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g> (<xliff:g id="WEEKDAY2">%6$s</xliff:g>) <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="DAY2">%8$s</xliff:g>日"</string>
- <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>)~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>)"</string>
- <string name="same_month_mdy1_mdy2">"<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="DAY2">%8$s</xliff:g>日"</string>
- <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>)~<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>)"</string>
- <string name="same_month_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日<xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2">%8$s</xliff:g>日<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>) <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>) <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1">%3$s</xliff:g>日<xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2">%8$s</xliff:g>日<xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g><xliff:g id="DAY1_0">%3$s</xliff:g>日 (<xliff:g id="WEEKDAY1">%1$s</xliff:g>) <xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH2">%7$s</xliff:g><xliff:g id="DAY2_1">%8$s</xliff:g>日 (<xliff:g id="WEEKDAY2">%6$s</xliff:g>) <xliff:g id="TIME2">%10$s</xliff:g>"</string>
- <string name="abbrev_month_day_year">"<xliff:g id="YEAR">%Y</xliff:g>年<xliff:g id="MONTH">%b</xliff:g><xliff:g id="DAY">%-d</xliff:g>日"</string>
+ <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
+ <string name="same_month_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>月<xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="DAY2">%8$s</xliff:g>日"</string>
+ <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
+ <string name="same_month_mdy1_mdy2">"<xliff:g id="YEAR2">%9$s</xliff:g>年<xliff:g id="MONTH1">%2$s</xliff:g>月<xliff:g id="DAY1">%3$s</xliff:g>日~<xliff:g id="DAY2">%8$s</xliff:g>日"</string>
+ <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g>"</string>
+ <string name="same_month_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
+ <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
+ <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
+ <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="YEAR1">%4$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g><xliff:g id="WEEKDAY1">%1$s</xliff:g><xliff:g id="TIME1">%5$s</xliff:g>~<xliff:g id="YEAR2">%9$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g><xliff:g id="WEEKDAY2">%6$s</xliff:g><xliff:g id="TIME2">%10$s</xliff:g>"</string>
+ <string name="abbrev_month_day_year">"<xliff:g id="YEAR">%Y</xliff:g>/<xliff:g id="MONTH">%b</xliff:g>/<xliff:g id="DAY">%-d</xliff:g>"</string>
<!-- no translation found for abbrev_month_year (3856424847226891943) -->
<skip />
<!-- no translation found for abbrev_month_day (5028815883653985933) -->
<skip />
<!-- no translation found for abbrev_month (3131032032850777433) -->
<skip />
- <string name="day_of_week_long_sunday">"日曜"</string>
- <string name="day_of_week_long_monday">"月曜"</string>
- <string name="day_of_week_long_tuesday">"火曜"</string>
- <string name="day_of_week_long_wednesday">"水曜"</string>
- <string name="day_of_week_long_thursday">"木曜"</string>
- <string name="day_of_week_long_friday">"金曜"</string>
- <string name="day_of_week_long_saturday">"土曜"</string>
- <string name="day_of_week_medium_sunday">"日"</string>
- <string name="day_of_week_medium_monday">"月"</string>
- <string name="day_of_week_medium_tuesday">"火"</string>
- <string name="day_of_week_medium_wednesday">"水"</string>
- <string name="day_of_week_medium_thursday">"木"</string>
- <string name="day_of_week_medium_friday">"金"</string>
- <string name="day_of_week_medium_saturday">"土"</string>
- <string name="day_of_week_short_sunday">"日"</string>
- <string name="day_of_week_short_monday">"月"</string>
- <string name="day_of_week_short_tuesday">"火"</string>
- <string name="day_of_week_short_wednesday">"水"</string>
- <string name="day_of_week_short_thursday">"木"</string>
- <string name="day_of_week_short_friday">"金"</string>
- <string name="day_of_week_short_saturday">"土"</string>
- <string name="day_of_week_shorter_sunday">"日"</string>
+ <string name="day_of_week_long_sunday">"日曜日"</string>
+ <string name="day_of_week_long_monday">"月曜日"</string>
+ <string name="day_of_week_long_tuesday">"火曜日"</string>
+ <string name="day_of_week_long_wednesday">"水曜日"</string>
+ <string name="day_of_week_long_thursday">"木曜日"</string>
+ <string name="day_of_week_long_friday">"金曜日"</string>
+ <string name="day_of_week_long_saturday">"土曜日"</string>
+ <string name="day_of_week_medium_sunday">"(日)"</string>
+ <string name="day_of_week_medium_monday">"(月)"</string>
+ <string name="day_of_week_medium_tuesday">"(火)"</string>
+ <string name="day_of_week_medium_wednesday">"(水)"</string>
+ <string name="day_of_week_medium_thursday">"(木)"</string>
+ <string name="day_of_week_medium_friday">"(金)"</string>
+ <string name="day_of_week_medium_saturday">"(土)"</string>
+ <string name="day_of_week_short_sunday">"(日)"</string>
+ <string name="day_of_week_short_monday">"(月)"</string>
+ <string name="day_of_week_short_tuesday">"(火)"</string>
+ <string name="day_of_week_short_wednesday">"(水)"</string>
+ <string name="day_of_week_short_thursday">"(木)"</string>
+ <string name="day_of_week_short_friday">"(金)"</string>
+ <string name="day_of_week_short_saturday">"(土)"</string>
+ <string name="day_of_week_shorter_sunday">"(日)"</string>
<string name="day_of_week_shorter_monday">"月"</string>
- <string name="day_of_week_shorter_tuesday">"火"</string>
+ <string name="day_of_week_shorter_tuesday">"(火)"</string>
<string name="day_of_week_shorter_wednesday">"水"</string>
- <string name="day_of_week_shorter_thursday">"木"</string>
+ <string name="day_of_week_shorter_thursday">"(木)"</string>
<string name="day_of_week_shorter_friday">"金"</string>
- <string name="day_of_week_shorter_saturday">"土"</string>
+ <string name="day_of_week_shorter_saturday">"(土)"</string>
<string name="day_of_week_shortest_sunday">"日"</string>
<string name="day_of_week_shortest_monday">"月"</string>
<string name="day_of_week_shortest_tuesday">"火"</string>
@@ -669,7 +670,7 @@
<string name="month_medium_december">"12月"</string>
<string name="month_shortest_january">"1"</string>
<string name="month_shortest_february">"2"</string>
- <string name="month_shortest_march">"月"</string>
+ <string name="month_shortest_march">"3"</string>
<string name="month_shortest_april">"4"</string>
<string name="month_shortest_may">"5"</string>
<string name="month_shortest_june">"6"</string>
@@ -691,8 +692,7 @@
<string name="paste">"貼り付け"</string>
<string name="copyUrl">"URLをコピー"</string>
<string name="inputMethod">"入力方法"</string>
- <!-- no translation found for addToDictionary (726256909274177272) -->
- <skip />
+ <string name="addToDictionary">"辞書に「%s」を追加"</string>
<string name="editTextMenuTitle">"テキストを編集"</string>
<string name="low_internal_storage_view_title">"空き容量低下"</string>
<string name="low_internal_storage_view_text">"携帯電話の空き容量が少なくなっています。"</string>
@@ -700,44 +700,42 @@
<string name="cancel">"キャンセル"</string>
<string name="yes">"OK"</string>
<string name="no">"キャンセル"</string>
- <!-- no translation found for dialog_alert_title (2049658708609043103) -->
- <skip />
+ <string name="dialog_alert_title">"注意"</string>
<string name="capital_on">"オン"</string>
<string name="capital_off">"オフ"</string>
<string name="whichApplication">"操作の完了に使用"</string>
- <string name="alwaysUse">"この操作にデフォルトで使用します。"</string>
- <string name="clearDefaultHintMsg">"ホームの[設定]&gt;[アプリケーション]&gt;[アプリケーションを管理]で、デフォルトをクリアします。"</string>
+ <string name="alwaysUse">"常にこの操作で使用する"</string>
+ <string name="clearDefaultHintMsg">"ホームの[設定]&gt;[アプリケーション]&gt;[アプリケーションの管理]でデフォルト設定をクリアします。"</string>
<string name="chooseActivity">"操作の選択"</string>
<string name="noApplications">"この操作を実行できるアプリケーションはありません。"</string>
<string name="aerr_title">"エラー"</string>
- <string name="aerr_application">"アプリケーション<xliff:g id="APPLICATION">%1$s</xliff:g> (<xliff:g id="PROCESS">%2$s</xliff:g>プロセス) が予期せず停止しました。もう一度試してください。"</string>
- <string name="aerr_process">"<xliff:g id="PROCESS">%1$s</xliff:g>プロセスが予期せず停止しました。もう一度試してください。"</string>
+ <string name="aerr_application">"<xliff:g id="APPLICATION">%1$s</xliff:g>(<xliff:g id="PROCESS">%2$s</xliff:g>)が予期せず停止しました。やり直してください。"</string>
+ <string name="aerr_process">"<xliff:g id="PROCESS">%1$s</xliff:g>が予期せず停止しました。やり直してください。"</string>
<string name="anr_title">"エラー"</string>
- <string name="anr_activity_application">"<xliff:g id="ACTIVITY">%1$s</xliff:g>操作 (アプリケーション<xliff:g id="APPLICATION">%2$s</xliff:g>) は応答していません。"</string>
- <string name="anr_activity_process">"<xliff:g id="ACTIVITY">%1$s</xliff:g>操作 (プロセス:<xliff:g id="PROCESS">%2$s</xliff:g>) は応答していません。"</string>
- <string name="anr_application_process">"アプリケーション<xliff:g id="APPLICATION">%1$s</xliff:g> (<xliff:g id="PROCESS">%2$s</xliff:g>プロセス) は応答していません。"</string>
- <string name="anr_process">"<xliff:g id="PROCESS">%1$s</xliff:g>プロセスは応答していません。"</string>
+ <string name="anr_activity_application">"<xliff:g id="ACTIVITY">%1$s</xliff:g>(<xliff:g id="APPLICATION">%2$s</xliff:g>)は応答していません。"</string>
+ <string name="anr_activity_process">"<xliff:g id="ACTIVITY">%1$s</xliff:g>(プロセス: <xliff:g id="PROCESS">%2$s</xliff:g>)は応答していません。"</string>
+ <string name="anr_application_process">"<xliff:g id="APPLICATION">%1$s</xliff:g>(<xliff:g id="PROCESS">%2$s</xliff:g>)は応答していません。"</string>
+ <string name="anr_process">"<xliff:g id="PROCESS">%1$s</xliff:g>は応答していません。"</string>
<string name="force_close">"強制終了"</string>
<string name="wait">"待機"</string>
<string name="debug">"デバッグ"</string>
- <string name="sendText">"テキストの操作の選択"</string>
+ <string name="sendText">"テキストの操作"</string>
<string name="volume_ringtone">"着信音の音量"</string>
<string name="volume_music">"メディアの音量"</string>
<string name="volume_music_hint_playing_through_bluetooth">"Bluetooth経由で再生中です"</string>
<string name="volume_call">"着信音の音量"</string>
- <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
- <skip />
+ <string name="volume_bluetooth_call">"Bluetooth着信音の音量"</string>
<string name="volume_alarm">"アラームの音量"</string>
<string name="volume_notification">"通知音の音量"</string>
<string name="volume_unknown">"音量"</string>
<string name="ringtone_default">"デフォルトの着信音"</string>
- <string name="ringtone_default_with_actual">"デフォルトの着信音 (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+ <string name="ringtone_default_with_actual">"端末既定の着信音(<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent">"無音"</string>
<string name="ringtone_picker_title">"着信音"</string>
- <string name="ringtone_unknown">"不明時着信音"</string>
+ <string name="ringtone_unknown">"不明な着信音"</string>
<plurals name="wifi_available">
- <item quantity="one">"Wi-Fiネットワークが利用可能"</item>
- <item quantity="other">"Wi-Fiネットワークが利用可能"</item>
+ <item quantity="one">"Wi-Fiを利用できます"</item>
+ <item quantity="other">"Wi-Fiを利用できます"</item>
</plurals>
<plurals name="wifi_available_detailed">
<item quantity="one">"Wi-Fiオープンネットワークが利用できます"</item>
@@ -746,12 +744,12 @@
<string name="select_character">"文字を挿入"</string>
<string name="sms_control_default_app_name">"不明なアプリケーション"</string>
<string name="sms_control_title">"SMSメッセージの送信中"</string>
- <string name="sms_control_message">"大量のSMSメッセージが送信されます。送信するには[OK]、中止するには[キャンセル]を選択します。"</string>
+ <string name="sms_control_message">"大量のSMSメッセージを送信しようとしています。[OK]で送信、[キャンセル]で中止します。"</string>
<string name="sms_control_yes">"OK"</string>
<string name="sms_control_no">"キャンセル"</string>
<string name="date_time_set">"設定"</string>
- <string name="default_permission_group">"デフォルト"</string>
- <string name="no_permissions">"許可は必要ありません"</string>
+ <string name="default_permission_group">"端末既定"</string>
+ <string name="no_permissions">"権限付与の必要はありません"</string>
<string name="perms_hide"><b>"隠す"</b></string>
<string name="perms_show_all"><b>"すべて表示"</b></string>
<string name="googlewebcontenthelper_loading">"読み込み中..."</string>
@@ -762,60 +760,35 @@
<string name="usb_storage_error_message">"USBメモリにSDカードを使用する際に問題が発生しました。"</string>
<string name="usb_storage_notification_title">"USB接続"</string>
<string name="usb_storage_notification_message">"パソコンとの間でファイルをコピーします。"</string>
- <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
- <skip />
- <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
- <skip />
- <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
- <skip />
- <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
- <skip />
- <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
- <skip />
- <!-- no translation found for extmedia_format_title (8663247929551095854) -->
- <skip />
- <!-- no translation found for extmedia_format_message (3621369962433523619) -->
- <skip />
- <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
- <skip />
+ <string name="usb_storage_stop_notification_title">"USBストレージをOFFにする"</string>
+ <string name="usb_storage_stop_notification_message">"USBストレージをOFFにする場合に選択します。"</string>
+ <string name="usb_storage_stop_title">"USBストレージをOFFにする"</string>
+ <string name="usb_storage_stop_message">"USBストレージをOFFにする前にUSBホストのマウントを解除したことを確認してください。USBストレージをOFFにするには[OFF]を選択します。"</string>
+ <string name="usb_storage_stop_button_mount">"OFF"</string>
+ <string name="usb_storage_stop_button_unmount">"キャンセル"</string>
+ <string name="usb_storage_stop_error_message">"USBストレージをOFFにする際に問題が発生しました。USBホストのマウントが解除されていることを確認してからもう一度お試しください。"</string>
+ <string name="extmedia_format_title">"SDカードをフォーマット"</string>
+ <string name="extmedia_format_message">"SDカードをフォーマットしてもよろしいですか?カード内のすべてのデータが失われます。"</string>
+ <string name="extmedia_format_button_format">"フォーマット"</string>
<string name="select_input_method">"入力方法の選択"</string>
<string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
- <!-- no translation found for candidates_style (4333913089637062257) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
- <skip />
- <!-- no translation found for activity_list_empty (4168820609403385789) -->
- <skip />
- <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
- <skip />
- <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
- <skip />
+ <string name="candidates_style"><u>"候補"</u></string>
+ <string name="ext_media_checking_notification_title">"SDカードの準備中"</string>
+ <string name="ext_media_checking_notification_message">"エラーを確認中"</string>
+ <string name="ext_media_nofs_notification_title">"空のSDカード"</string>
+ <string name="ext_media_nofs_notification_message">"SDカードが空か、サポート対象外のファイルシステムを使用しています。"</string>
+ <string name="ext_media_unmountable_notification_title">"破損したSDカード"</string>
+ <string name="ext_media_unmountable_notification_message">"SDカードが破損しています。カードのフォーマットが必要な可能性があります。"</string>
+ <string name="ext_media_badremoval_notification_title">"SDカードが予期せず取り外されました"</string>
+ <string name="ext_media_badremoval_notification_message">"データの喪失を防ぐためSDカードを取り外す前にマウントを解除してください。"</string>
+ <string name="ext_media_safe_unmount_notification_title">"SDカードを安全に取り外しました"</string>
+ <string name="ext_media_safe_unmount_notification_message">"SDカードを安全に取り外せます。"</string>
+ <string name="ext_media_nomedia_notification_title">"SDカードが取り外されています"</string>
+ <string name="ext_media_nomedia_notification_message">"SDカードが取り外されました。新しいSDカードを挿入して端末のメモリを増やしてください。"</string>
+ <string name="activity_list_empty">"一致するアクティビティが見つかりません"</string>
+ <string name="permlab_pkgUsageStats">"コンポーネント使用状況に関する統計情報の更新"</string>
+ <string name="permdesc_pkgUsageStats">"収集されたコンポーネント使用状況に関する統計情報の変更を許可します。通常のアプリケーションでは使用しません。"</string>
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) -->
<skip />
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 140f32f..311f501 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_reboot">"응용프로그램이 전화기를 강제로 다시 부팅할 수 있습니다."</string>
<string name="permlab_mount_unmount_filesystems">"파일시스템 마운트 및 마운트 해제"</string>
<string name="permdesc_mount_unmount_filesystems">"응용프로그램이 이동식 저장소의 파일시스템을 마운트하고 마운트 해제할 수 있습니다."</string>
- <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
- <skip />
- <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
- <skip />
+ <string name="permlab_mount_format_filesystems">"외부 저장소 포맷"</string>
+ <string name="permdesc_mount_format_filesystems">"응용프로그램이 제거 가능한 저장소를 포맷하도록 합니다."</string>
<string name="permlab_vibrate">"진동 제어"</string>
<string name="permdesc_vibrate">"응용프로그램이 진동을 제어할 수 있습니다."</string>
<string name="permlab_flashlight">"손전등 제어"</string>
@@ -280,10 +278,8 @@
<string name="permdesc_locationUpdates">"무선의 위치 업데이트 알림을 활성화하거나 비활성화할 수 있습니다. 일반 응용프로그램에서는 사용하지 않습니다."</string>
<string name="permlab_checkinProperties">"체크인 속성 액세스"</string>
<string name="permdesc_checkinProperties">"체크인 서비스에서 업로드한 속성에 대한 읽기/쓰기 액세스를 허용합니다. 일반 응용프로그램에서는 사용하지 않습니다."</string>
- <!-- no translation found for permlab_bindGadget (2519859363977647275) -->
- <skip />
- <!-- no translation found for permdesc_bindGadget (7865866514555126333) -->
- <skip />
+ <string name="permlab_bindGadget">"가젯 선택"</string>
+ <string name="permdesc_bindGadget">"어느 응용프로그램이 어느 가젯을 사용할 수 있는지 시스템에 알려 주는 권한을 본 응용프로그램에 부여합니다. 이 권한을 사용하면 응용프로그램이 개인 데이터에 대한 액세스 권한을 다른 응용프로그램에 제공할 수 있습니다. 일반 응용프로그램은 이 권한을 사용할 수 없습니다."</string>
<string name="permlab_modifyPhoneState">"전화기 상태 수정"</string>
<string name="permdesc_modifyPhoneState">"응용프로그램이 장치의 전화 기능을 제어할 수 있습니다. 이 권한을 갖는 응용프로그램은 사용자에게 알리지 않고 네트워크를 전환하거나, 전화 무선 기능을 켜고 끌 수 있습니다."</string>
<string name="permlab_readPhoneState">"전화기 상태 읽기"</string>
@@ -312,10 +308,8 @@
<string name="permdesc_writeApnSettings">"응용프로그램이 APN의 프록시 및 포트 같은 APN 설정을 수정할 수 있습니다."</string>
<string name="permlab_changeNetworkState">"네트워크 연결 변경"</string>
<string name="permdesc_changeNetworkState">"응용프로그램이 네트워크 연결 상태를 변경할 수 있습니다."</string>
- <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
- <skip />
- <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
- <skip />
+ <string name="permlab_changeBackgroundDataSetting">"백그라운드 데이터 사용 설정 변경"</string>
+ <string name="permdesc_changeBackgroundDataSetting">"백그라운드 데이터 사용 설정을 변경할 수 있는 권한을 응용프로그램에 부여합니다."</string>
<string name="permlab_accessWifiState">"Wi-Fi 상태 보기"</string>
<string name="permdesc_accessWifiState">"응용프로그램이 Wi-Fi의 상태에 대한 정보를 볼 수 있습니다."</string>
<string name="permlab_changeWifiState">"Wi-Fi 상태 변경"</string>
@@ -336,14 +330,10 @@
<string name="permdesc_subscribedFeedsRead">"응용프로그램이 현재 동기화된 피드에 대한 상세정보를 가져올 수 있습니다."</string>
<string name="permlab_subscribedFeedsWrite">"가입 피드 작성"</string>
<string name="permdesc_subscribedFeedsWrite">"응용프로그램이 현재 동기화된 피드를 수정할 수 있습니다. 악성 응용프로그램은 이 기능을 이용하여 동기화된 피드를 변경할 수 있습니다."</string>
- <!-- no translation found for permlab_readDictionary (432535716804748781) -->
- <skip />
- <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
- <skip />
- <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
- <skip />
- <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
- <skip />
+ <string name="permlab_readDictionary">"상용자 정의 사전 읽기"</string>
+ <string name="permdesc_readDictionary">"응용프로그램이 사용자 사전에 보관되어 있을 수 있는 비공개 단어, 이름 및 구문을 읽도록 합니다."</string>
+ <string name="permlab_writeDictionary">"상용자 정의 사전에 작성"</string>
+ <string name="permdesc_writeDictionary">"응용프로그램이 사용자 사전에 새 단어를 입력할 수 있습니다."</string>
<string-array name="phoneTypes">
<item>"집"</item>
<item>"휴대전화"</item>
@@ -440,12 +430,9 @@
<string name="factorytest_not_system">"FACTORY_TEST 작업은 /system/app 디렉토리에 설치된 패키지에 대해서만 지원됩니다."</string>
<string name="factorytest_no_action">"FACTORY_TEST 작업을 제공하는 패키지가 없습니다."</string>
<string name="factorytest_reboot">"다시 부팅"</string>
- <!-- no translation found for js_dialog_title (8143918455087008109) -->
- <skip />
- <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
- <skip />
- <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
- <skip />
+ <string name="js_dialog_title">"\'<xliff:g id="TITLE">%s</xliff:g>\' 페이지 내용:"</string>
+ <string name="js_dialog_title_default">"자바스크립트"</string>
+ <string name="js_dialog_before_unload">"다른 페이지를 탐색하시겠습니까?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"계속하려면 \'확인\'을 선택하고 현재 페이지에 그대로 있으려면 \'취소\'를 선택하세요."</string>
<string name="save_password_label">"확인"</string>
<string name="save_password_message">"브라우저에 이 비밀번호를 저장하시겠습니까?"</string>
<string name="save_password_notnow">"나중에"</string>
@@ -496,22 +483,38 @@
<item quantity="one">"내일"</item>
<item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>일 후"</item>
</plurals>
- <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) -->
- <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) -->
- <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) -->
- <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) -->
- <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) -->
- <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) -->
- <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) -->
- <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) -->
- <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) -->
- <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) -->
- <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) -->
- <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) -->
- <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) -->
- <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) -->
- <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) -->
- <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) -->
+ <plurals name="abbrev_num_seconds_ago">
+ <item quantity="one">"1초 전"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 초 전"</item>
+ </plurals>
+ <plurals name="abbrev_num_minutes_ago">
+ <item quantity="one">"1분 전"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>분 전"</item>
+ </plurals>
+ <plurals name="abbrev_num_hours_ago">
+ <item quantity="one">"1시간 전"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>시간 전"</item>
+ </plurals>
+ <plurals name="abbrev_num_days_ago">
+ <item quantity="one">"어제"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>일 전"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_seconds">
+ <item quantity="one">"1초 후"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 초 후"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_minutes">
+ <item quantity="one">"1분 후"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>분 후"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_hours">
+ <item quantity="one">"1시간 후"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>시간 후"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_days">
+ <item quantity="one">"내일"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g>일 후"</item>
+ </plurals>
<string name="preposition_for_date">"%s"</string>
<string name="preposition_for_time">"%s"</string>
<string name="preposition_for_year">"%s년"</string>
@@ -553,17 +556,15 @@
<string name="time_wday_date">"<xliff:g id="DATE">%3$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="time_date">"<xliff:g id="DATE">%3$s</xliff:g>, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <!-- no translation found for date_time (6104442718633642836) -->
- <skip />
- <!-- no translation found for relative_time (1818557177829411417) -->
- <skip />
+ <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="YEAR">yyyy</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="DAY">d</xliff:g>"</string>
- <string name="full_date_day_first">"<xliff:g id="YEAR">yyyy</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="DAY">d</xliff:g>"</string>
- <string name="medium_date_month_first">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="DAY">d</xliff:g>"</string>
+ <string name="full_date_day_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="DAY">d</xliff:g>"</string>
+ <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"정오"</string>
<string name="Noon">"정오"</string>
<string name="midnight">"자정"</string>
@@ -691,8 +692,7 @@
<string name="paste">"붙여넣기"</string>
<string name="copyUrl">"URL 복사"</string>
<string name="inputMethod">"입력 방법"</string>
- <!-- no translation found for addToDictionary (726256909274177272) -->
- <skip />
+ <string name="addToDictionary">"사전에 \'%s\' 추가"</string>
<string name="editTextMenuTitle">"텍스트 수정"</string>
<string name="low_internal_storage_view_title">"저장공간 부족"</string>
<string name="low_internal_storage_view_text">"전화기 저장공간이 부족합니다."</string>
@@ -700,8 +700,7 @@
<string name="cancel">"취소"</string>
<string name="yes">"확인"</string>
<string name="no">"취소"</string>
- <!-- no translation found for dialog_alert_title (2049658708609043103) -->
- <skip />
+ <string name="dialog_alert_title">"주의"</string>
<string name="capital_on">"켜짐"</string>
<string name="capital_off">"끄기"</string>
<string name="whichApplication">"작업을 수행할 때 사용하는 권한"</string>
@@ -725,8 +724,7 @@
<string name="volume_music">"미디어 볼륨"</string>
<string name="volume_music_hint_playing_through_bluetooth">"Bluetooth를 통해 재생"</string>
<string name="volume_call">"통화볼륨"</string>
- <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
- <skip />
+ <string name="volume_bluetooth_call">"Bluetooth 통화 볼륨"</string>
<string name="volume_alarm">"알람 볼륨"</string>
<string name="volume_notification">"알림 볼륨"</string>
<string name="volume_unknown">"볼륨"</string>
@@ -762,60 +760,35 @@
<string name="usb_storage_error_message">"USB 저장소에 SD 카드를 사용하는 동안 문제가 발생했습니다."</string>
<string name="usb_storage_notification_title">"USB 연결됨"</string>
<string name="usb_storage_notification_message">"컴퓨터에 파일을 복사하거나 컴퓨터의 파일을 복사하려면 선택합니다."</string>
- <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
- <skip />
- <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
- <skip />
- <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
- <skip />
- <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
- <skip />
- <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
- <skip />
- <!-- no translation found for extmedia_format_title (8663247929551095854) -->
- <skip />
- <!-- no translation found for extmedia_format_message (3621369962433523619) -->
- <skip />
- <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
- <skip />
+ <string name="usb_storage_stop_notification_title">"USB 저장소 끄기"</string>
+ <string name="usb_storage_stop_notification_message">"USB 저장소 끄기를 선택하세요."</string>
+ <string name="usb_storage_stop_title">"USB 저장소 끄기"</string>
+ <string name="usb_storage_stop_message">"USB 저장소를 끄기 전에 반드시 USB 호스를 마운트 해제하세요. USB 저장소를 끄려면 \'끄기\'를 선택하세요."</string>
+ <string name="usb_storage_stop_button_mount">"USB 저장소 끄기"</string>
+ <string name="usb_storage_stop_button_unmount">"취소"</string>
+ <string name="usb_storage_stop_error_message">"USB 저장소를 끄는 동안 Weve에 문제가 발행했습니다. USB 호스트를 마운트 해제했는지 확인한 후 다시 시도하세요."</string>
+ <string name="extmedia_format_title">"SD 카드 포맷"</string>
+ <string name="extmedia_format_message">"SD 카드를 포맷하시겠습니까? 포맷하면 카드의 모든 데이터를 잃게 됩니다."</string>
+ <string name="extmedia_format_button_format">"포맷"</string>
<string name="select_input_method">"입력 방법 선택"</string>
<string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
- <!-- no translation found for candidates_style (4333913089637062257) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
- <skip />
- <!-- no translation found for activity_list_empty (4168820609403385789) -->
- <skip />
- <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
- <skip />
- <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
- <skip />
+ <string name="candidates_style"><u>"가능한 원인"</u></string>
+ <string name="ext_media_checking_notification_title">"SD 카드 준비 중"</string>
+ <string name="ext_media_checking_notification_message">"오류 확인 중"</string>
+ <string name="ext_media_nofs_notification_title">"빈 SD 카드"</string>
+ <string name="ext_media_nofs_notification_message">"SD 카드가 비어 있거나 지원되지 않는 파일시스템입니다."</string>
+ <string name="ext_media_unmountable_notification_title">"손상된 SD 카드"</string>
+ <string name="ext_media_unmountable_notification_message">"SD 카드가 손상되었습니다. 카드를 다시 포맷하시기 바랍니다."</string>
+ <string name="ext_media_badremoval_notification_title">"SD 카드가 예상치 않게 제거되었습니다."</string>
+ <string name="ext_media_badremoval_notification_message">"데이터 손실을 피하려면 SD 카드를 제거하기 전에 마운트 해제합니다."</string>
+ <string name="ext_media_safe_unmount_notification_title">"SD 카드를 안전하게 제거할 수 있습니다."</string>
+ <string name="ext_media_safe_unmount_notification_message">"이제 SD 카드를 안전하게 제거할 수 있습니다."</string>
+ <string name="ext_media_nomedia_notification_title">"SD 카드를 제거했습니다."</string>
+ <string name="ext_media_nomedia_notification_message">"SD가 제거되었습니다. 기기의 저장 용량을 늘리려면 새 SD 카드를 삽입하세요."</string>
+ <string name="activity_list_empty">"일치하는 활동이 없습니다."</string>
+ <string name="permlab_pkgUsageStats">"구성요소 사용 통계 업데이트"</string>
+ <string name="permdesc_pkgUsageStats">"수집된 구성요소 사용 통계를 수정할 수 있는 권한을 부여합니다. 일반 응용프로그램은 이 권한을 사용할 수 없습니다."</string>
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) -->
<skip />
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 466f2b1..9ee553f 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -559,12 +559,12 @@
<string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="MONTH">MMMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'., \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'. \\\'\'\\\'\''<xliff:g id="MONTH">MMMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first">"<xliff:g id="MONTH">MMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\', \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'. \\\'\'\\\'\''<xliff:g id="MONTH">MMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>'\\\'\'\\\'\':\\\'\'\\\'\''<xliff:g id="MINUTE">mm</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>'\\\'\'\\\'\':\\\'\'\\\'\''<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'., \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'. \\\'\'\\\'\''<xliff:g id="MONTH">MMMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\', \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>'\\\'\'\\\'\'. \\\'\'\\\'\''<xliff:g id="MONTH">MMM</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>'\\\'\'\\\'\':\\\'\'\\\'\''<xliff:g id="MINUTE">mm</xliff:g>'\\\'\'\\\'\' \\\'\'\\\'\''<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>'\\\'\'\\\'\':\\\'\'\\\'\''<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"middag"</string>
<string name="Noon">"Middag"</string>
<string name="midnight">"midnatt"</string>
@@ -789,4 +789,6 @@
<string name="activity_list_empty">"Fant ingen tilsvarende aktiviteter"</string>
<string name="permlab_pkgUsageStats">"oppdater statistikk over komponentbruk"</string>
<string name="permdesc_pkgUsageStats">"Tillater endring av innsamlet data om bruk av komponenter. Ikke ment for vanlige applikasjoner."</string>
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index a2810a1..a1446f5 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_reboot">"Hiermee kan de toepassing de telefoon gedwongen opnieuw opstarten."</string>
<string name="permlab_mount_unmount_filesystems">"bestandssystemen koppelen en ontkoppelen"</string>
<string name="permdesc_mount_unmount_filesystems">"Hiermee kan de toepassing bestandssystemen koppelen en ontkoppelen voor verwisselbare opslagruimte."</string>
- <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
- <skip />
- <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
- <skip />
+ <string name="permlab_mount_format_filesystems">"externe opslag formatteren"</string>
+ <string name="permdesc_mount_format_filesystems">"Hiermee kan de toepassing de externe opslag formatteren."</string>
<string name="permlab_vibrate">"trilstand beheren"</string>
<string name="permdesc_vibrate">"Hiermee kan de toepassing de trilstand beheren."</string>
<string name="permlab_flashlight">"zaklamp bedienen"</string>
@@ -280,10 +278,8 @@
<string name="permdesc_locationUpdates">"Hiermee kunnen updatemeldingen voor locaties van de radio worden ingeschakeld/uitgeschakeld. Niet voor gebruik door normale toepassingen."</string>
<string name="permlab_checkinProperties">"toegang tot checkin-eigenschappen"</string>
<string name="permdesc_checkinProperties">"Hiermee wordt lees-/schrijftoegang gegeven tot eigenschappen die door de checkin-service zijn geüpload. Niet voor gebruik door normale toepassingen."</string>
- <!-- no translation found for permlab_bindGadget (2519859363977647275) -->
- <skip />
- <!-- no translation found for permdesc_bindGadget (7865866514555126333) -->
- <skip />
+ <string name="permlab_bindGadget">"gadgets kiezen"</string>
+ <string name="permdesc_bindGadget">"Hiermee kan een toepassing het systeem melden welke gadgets door welke toepassing kunnen worden gebruikt. Met deze toestemming kunnen toepassingen andere toepassingen toegang geven tot persoonlijke gegevens. Niet voor gebruik door normale toepassingen."</string>
<string name="permlab_modifyPhoneState">"telefoonstatus wijzigen"</string>
<string name="permdesc_modifyPhoneState">"Hiermee kan de toepassing de telefoonfuncties van het apparaat beheren. Een toepassing met deze machtiging kan schakelen tussen netwerken, de radio van de telefoon in- of uitschakelen en dergelijke zonder dat u hiervan op de hoogte wordt gesteld."</string>
<string name="permlab_readPhoneState">"telefoonstatus lezen"</string>
@@ -312,10 +308,8 @@
<string name="permdesc_writeApnSettings">"Hiermee kan een toepassing de APN-instellingen, zoals proxy en poort, van elke APN wijzigen."</string>
<string name="permlab_changeNetworkState">"netwerkverbinding wijzigen"</string>
<string name="permdesc_changeNetworkState">"Hiermee kan een toepassing de verbindingsstatus van het netwerk wijzigen."</string>
- <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
- <skip />
- <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
- <skip />
+ <string name="permlab_changeBackgroundDataSetting">"instelling voor gebruik van achtergrondgegevens van gegevens wijzigen"</string>
+ <string name="permdesc_changeBackgroundDataSetting">"Hiermee kan een toepassing de instelling voor gebruik van achtergrondgegevens wijzigen."</string>
<string name="permlab_accessWifiState">"Wi-Fi-status bekijken"</string>
<string name="permdesc_accessWifiState">"Hiermee kan een toepassing informatie over de Wi-Fi-status bekijken."</string>
<string name="permlab_changeWifiState">"Wi-Fi-status wijzigen"</string>
@@ -336,14 +330,10 @@
<string name="permdesc_subscribedFeedsRead">"Hiermee kan een toepassing details over de huidige gesynchroniseerde feeds achterhalen."</string>
<string name="permlab_subscribedFeedsWrite">"geabonneerde feeds schrijven"</string>
<string name="permdesc_subscribedFeedsWrite">"Hiermee kan een toepassing uw huidige gesynchroniseerde feeds wijzigen. Een schadelijke toepassing kan op deze manier uw gesynchroniseerde feeds wijzigen."</string>
- <!-- no translation found for permlab_readDictionary (432535716804748781) -->
- <skip />
- <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
- <skip />
- <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
- <skip />
- <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
- <skip />
+ <string name="permlab_readDictionary">"door gebruiker gedefinieerd woordenboek lezen"</string>
+ <string name="permdesc_readDictionary">"Hiermee kan een toepassing privéwoorden, namen en woordcombinaties lezen die de gebruiker heeft opgeslagen in het gebruikerswoordenboek."</string>
+ <string name="permlab_writeDictionary">"schrijven naar door gebruiker gedefinieerd woordenboek"</string>
+ <string name="permdesc_writeDictionary">"Hiermee kan een toepassing nieuwe woorden schrijven naar het gebruikerswoordenboek."</string>
<string-array name="phoneTypes">
<item>"Thuis"</item>
<item>"Mobiel"</item>
@@ -440,12 +430,9 @@
<string name="factorytest_not_system">"De actie FACTORY_TEST wordt alleen ondersteund voor pakketten die zijn geïnstalleerd in /system/app."</string>
<string name="factorytest_no_action">"Er is geen pakket gevonden dat de actie FACTORY_TEST levert."</string>
<string name="factorytest_reboot">"Opnieuw opstarten"</string>
- <!-- no translation found for js_dialog_title (8143918455087008109) -->
- <skip />
- <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
- <skip />
- <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
- <skip />
+ <string name="js_dialog_title">"De pagina op \'<xliff:g id="TITLE">%s</xliff:g>\' zegt:"</string>
+ <string name="js_dialog_title_default">"JavaScript"</string>
+ <string name="js_dialog_before_unload">"Wilt u deze pagina verlaten?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Kies OK om door te gaan of Annuleren om op de huidige pagina te blijven."</string>
<string name="save_password_label">"Bevestigen"</string>
<string name="save_password_message">"Wilt u dat de browser dit wachtwoord onthoudt?"</string>
<string name="save_password_notnow">"Niet nu"</string>
@@ -496,22 +483,38 @@
<item quantity="one">"morgen"</item>
<item quantity="other">"over <xliff:g id="COUNT">%d</xliff:g> dagen"</item>
</plurals>
- <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) -->
- <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) -->
- <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) -->
- <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) -->
- <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) -->
- <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) -->
- <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) -->
- <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) -->
- <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) -->
- <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) -->
- <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) -->
- <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) -->
- <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) -->
- <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) -->
- <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) -->
- <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) -->
+ <plurals name="abbrev_num_seconds_ago">
+ <item quantity="one">"1 seconde geleden"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> seconden geleden"</item>
+ </plurals>
+ <plurals name="abbrev_num_minutes_ago">
+ <item quantity="one">"1 minuut geleden"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> minuten geleden"</item>
+ </plurals>
+ <plurals name="abbrev_num_hours_ago">
+ <item quantity="one">"1 uur geleden"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> uur geleden"</item>
+ </plurals>
+ <plurals name="abbrev_num_days_ago">
+ <item quantity="one">"gisteren"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> dagen geleden"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_seconds">
+ <item quantity="one">"over 1 seconde"</item>
+ <item quantity="other">"over <xliff:g id="COUNT">%d</xliff:g> seconden"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_minutes">
+ <item quantity="one">"over 1 minuut"</item>
+ <item quantity="other">"over <xliff:g id="COUNT">%d</xliff:g> minuten"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_hours">
+ <item quantity="one">"over 1 uur"</item>
+ <item quantity="other">"over <xliff:g id="COUNT">%d</xliff:g> uur"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_days">
+ <item quantity="one">"morgen"</item>
+ <item quantity="other">"over <xliff:g id="COUNT">%d</xliff:g> dagen"</item>
+ </plurals>
<string name="preposition_for_date">"op %s"</string>
<string name="preposition_for_time">"om %s"</string>
<string name="preposition_for_year">"in %s"</string>
@@ -553,17 +556,15 @@
<string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <!-- no translation found for date_time (6104442718633642836) -->
- <skip />
- <!-- no translation found for relative_time (1818557177829411417) -->
- <skip />
+ <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"twaalf uur \'s middags"</string>
<string name="Noon">"Twaalf uur \'s middags"</string>
<string name="midnight">"middernacht"</string>
@@ -691,8 +692,7 @@
<string name="paste">"Plakken"</string>
<string name="copyUrl">"URL kopiëren"</string>
<string name="inputMethod">"Invoermethode"</string>
- <!-- no translation found for addToDictionary (726256909274177272) -->
- <skip />
+ <string name="addToDictionary">"\'%s\' toevoegen aan woordenboek"</string>
<string name="editTextMenuTitle">"Tekst bewerken"</string>
<string name="low_internal_storage_view_title">"Weinig ruimte"</string>
<string name="low_internal_storage_view_text">"Opslagruimte van telefoon raakt op."</string>
@@ -700,8 +700,7 @@
<string name="cancel">"Annuleren"</string>
<string name="yes">"OK"</string>
<string name="no">"Annuleren"</string>
- <!-- no translation found for dialog_alert_title (2049658708609043103) -->
- <skip />
+ <string name="dialog_alert_title">"Let op"</string>
<string name="capital_on">"AAN"</string>
<string name="capital_off">"UIT"</string>
<string name="whichApplication">"Actie voltooien met"</string>
@@ -725,8 +724,7 @@
<string name="volume_music">"Mediavolume"</string>
<string name="volume_music_hint_playing_through_bluetooth">"Afspelen via Bluetooth"</string>
<string name="volume_call">"Volume inkomende oproep"</string>
- <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
- <skip />
+ <string name="volume_bluetooth_call">"Volume tijdens gesprek in Bluetooth-modus"</string>
<string name="volume_alarm">"Alarmvolume"</string>
<string name="volume_notification">"Meldingsvolume"</string>
<string name="volume_unknown">"Volume"</string>
@@ -762,60 +760,35 @@
<string name="usb_storage_error_message">"Er is een probleem bij het gebruik van uw SD-kaart voor USB-opslag."</string>
<string name="usb_storage_notification_title">"USB-verbinding"</string>
<string name="usb_storage_notification_message">"Selecteer dit om bestanden naar/van uw computer te kopiëren."</string>
- <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
- <skip />
- <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
- <skip />
- <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
- <skip />
- <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
- <skip />
- <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
- <skip />
- <!-- no translation found for extmedia_format_title (8663247929551095854) -->
- <skip />
- <!-- no translation found for extmedia_format_message (3621369962433523619) -->
- <skip />
- <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
- <skip />
+ <string name="usb_storage_stop_notification_title">"USB-opslag uitschakelen"</string>
+ <string name="usb_storage_stop_notification_message">"Selecteer dit om USB-opslag uit te schakelen."</string>
+ <string name="usb_storage_stop_title">"USB-opslag uitschakelen"</string>
+ <string name="usb_storage_stop_message">"Voordat u de USB-opslag uitschakelt, moet u de koppeling met de USB-host verbreken. Selecteer \'Uitschakelen\' om USB-opslag uit te schakelen."</string>
+ <string name="usb_storage_stop_button_mount">"Uitschakelen"</string>
+ <string name="usb_storage_stop_button_unmount">"Annuleren"</string>
+ <string name="usb_storage_stop_error_message">"Er is een probleem opgetreden tijdens het uitschakelen van USB-opslag. Controleer of u de USB-host heeft losgekoppeld en probeer het opnieuw."</string>
+ <string name="extmedia_format_title">"SD-kaart formatteren"</string>
+ <string name="extmedia_format_message">"Weet u zeker dat u de SD-kaart wilt formatteren? Alle gegevens op uw kaart gaan dan verloren."</string>
+ <string name="extmedia_format_button_format">"Formatteren"</string>
<string name="select_input_method">"Invoermethode selecteren"</string>
<string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
- <!-- no translation found for candidates_style (4333913089637062257) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
- <skip />
- <!-- no translation found for activity_list_empty (4168820609403385789) -->
- <skip />
- <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
- <skip />
- <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
- <skip />
+ <string name="candidates_style"><u>"kandidaten"</u></string>
+ <string name="ext_media_checking_notification_title">"SD-kaart voorbereiden"</string>
+ <string name="ext_media_checking_notification_message">"Controleren op fouten"</string>
+ <string name="ext_media_nofs_notification_title">"Lege SD-kaart"</string>
+ <string name="ext_media_nofs_notification_message">"De SD-kaart is leeg of gebruikt een niet-ondersteund bestandssysteem."</string>
+ <string name="ext_media_unmountable_notification_title">"Beschadigde SD-kaart"</string>
+ <string name="ext_media_unmountable_notification_message">"De SD-kaart is beschadigd. U moet de kaart mogelijk opnieuw formatteren."</string>
+ <string name="ext_media_badremoval_notification_title">"SD-kaart onverwachts verwijderd"</string>
+ <string name="ext_media_badremoval_notification_message">"Ontkoppel de SD-kaart voordat u deze verwijdert om gegevensverlies te voorkomen."</string>
+ <string name="ext_media_safe_unmount_notification_title">"De SD-kaart kan veilig worden verwijderd"</string>
+ <string name="ext_media_safe_unmount_notification_message">"De SD-kaart kan nu veilig worden verwijderd."</string>
+ <string name="ext_media_nomedia_notification_title">"SD-kaart is verwijderd"</string>
+ <string name="ext_media_nomedia_notification_message">"De SD-kaart is verwijderd. Plaats een nieuwe SD-kaart om de opslagcapaciteit van uw apparaat te vergroten."</string>
+ <string name="activity_list_empty">"Geen overeenkomende activiteiten gevonden"</string>
+ <string name="permlab_pkgUsageStats">"gebruiksstatistieken van component bijwerken"</string>
+ <string name="permdesc_pkgUsageStats">"Hiermee kunnen verzamelde gebruiksstatistieken van een component worden gewijzigd. Niet voor gebruik door normale toepassingen."</string>
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) -->
<skip />
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 12f1616..a49b824 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_reboot">"Pozwala aplikacji na wymuszenie ponownego uruchomienia telefonu."</string>
<string name="permlab_mount_unmount_filesystems">"montowanie i odmontowanie systemów plików"</string>
<string name="permdesc_mount_unmount_filesystems">"Pozwala aplikacjom na podłączanie i odłączanie systemów plików w pamięciach przenośnych."</string>
- <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
- <skip />
- <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
- <skip />
+ <string name="permlab_mount_format_filesystems">"formatowanie pamięci zewnętrznej"</string>
+ <string name="permdesc_mount_format_filesystems">"Zezwala aplikacji na formatowanie wymiennych nośników."</string>
<string name="permlab_vibrate">"kontrolowanie wibracji"</string>
<string name="permdesc_vibrate">"Pozwala aplikacjom na kontrolowanie wibracji."</string>
<string name="permlab_flashlight">"kontrolowanie latarki"</string>
@@ -280,10 +278,8 @@
<string name="permdesc_locationUpdates">"Pozwala włączyć/wyłączyć powiadomienia o aktualizacji położenia przez radio. Nie wykorzystywane przez normalne aplikacje."</string>
<string name="permlab_checkinProperties">"dostęp do właściwości usługi rezerwacji"</string>
<string name="permdesc_checkinProperties">"Pozwala na dostęp z uprawnieniami do odczytu/zapisu do właściwości przesłanych przez usługę rezerwacji. Nie wykorzystywane przez normalne aplikacje."</string>
- <!-- no translation found for permlab_bindGadget (2519859363977647275) -->
- <skip />
- <!-- no translation found for permdesc_bindGadget (7865866514555126333) -->
- <skip />
+ <string name="permlab_bindGadget">"wybieranie gadżetów"</string>
+ <string name="permdesc_bindGadget">"Zezwala aplikacjom na wskazywanie systemowi, które gadżety mogą być używane przez inne aplikacje. Z użyciem tego pozwolenia aplikacje mogą udzielać dostępu do danych osobistych innym aplikacjom. Nie jest ono przeznaczone dla zwykłych aplikacji."</string>
<string name="permlab_modifyPhoneState">"zmiana stanu telefonu"</string>
<string name="permdesc_modifyPhoneState">"Pozwala aplikacji na kontrolowanie funkcji telefonu w urządzeniu. Aplikacja z tymi uprawnieniami może przełączać sieci, włączać i wyłączać radio itp. bez informowania użytkownika."</string>
<string name="permlab_readPhoneState">"czytanie stanu telefonu"</string>
@@ -312,10 +308,8 @@
<string name="permdesc_writeApnSettings">"Pozwala aplikacji na zmianę ustawień APN, takich jak serwer proxy oraz port dowolnego APN."</string>
<string name="permlab_changeNetworkState">"zmienianie połączeń sieci"</string>
<string name="permdesc_changeNetworkState">"Pozwala aplikacji na zmianę stanu połączeń sieciowych."</string>
- <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
- <skip />
- <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
- <skip />
+ <string name="permlab_changeBackgroundDataSetting">"zmienianie ustawienia używania danych w tle"</string>
+ <string name="permdesc_changeBackgroundDataSetting">"Zezwala aplikacji na zmianę ustawień użycia danych w tle."</string>
<string name="permlab_accessWifiState">"wyświetlanie stanu Wi-Fi"</string>
<string name="permdesc_accessWifiState">"Pozwala aplikacji na wyświetlanie informacji o stanie Wi-Fi."</string>
<string name="permlab_changeWifiState">"zmiana stanu Wi-Fi"</string>
@@ -336,14 +330,10 @@
<string name="permdesc_subscribedFeedsRead">"Pozwala aplikacjom na pobieranie informacji szczegółowych na temat obecnie zsynchronizowanych źródeł."</string>
<string name="permlab_subscribedFeedsWrite">"zapisywanie subskrybowanych źródeł"</string>
<string name="permdesc_subscribedFeedsWrite">"Umożliwia aplikacji zmianę obecnie zsynchronizowanych źródeł. Może to pozwolić szkodliwej aplikacji na zmianę zsynchronizowanych źródeł."</string>
- <!-- no translation found for permlab_readDictionary (432535716804748781) -->
- <skip />
- <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
- <skip />
- <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
- <skip />
- <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
- <skip />
+ <string name="permlab_readDictionary">"odczytywanie słownika zdefiniowanego przez użytkownika"</string>
+ <string name="permdesc_readDictionary">"Zezwala aplikacji na odczytywanie wszelkich prywatnych słów, nazw i wyrażeń zapisanych przez użytkownika w swoim słowniku."</string>
+ <string name="permlab_writeDictionary">"zapisywanie w słowniku zdefiniowanym przez użytkownika"</string>
+ <string name="permdesc_writeDictionary">"Zezwala aplikacjom na zapisywanie nowych słów w słowniku użytkownika."</string>
<string-array name="phoneTypes">
<item>"Dom"</item>
<item>"Komórka"</item>
@@ -440,12 +430,9 @@
<string name="factorytest_not_system">"Czynność FACTORY_TEST jest obsługiwana tylko dla pakietów zainstalowanych w katalogu /system/app."</string>
<string name="factorytest_no_action">"Nie znaleziono żadnego pakietu, który zapewnia działanie FACTORY_TEST."</string>
<string name="factorytest_reboot">"Uruchom ponownie"</string>
- <!-- no translation found for js_dialog_title (8143918455087008109) -->
- <skip />
- <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
- <skip />
- <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
- <skip />
+ <string name="js_dialog_title">"Komunikat ze strony pod adresem „<xliff:g id="TITLE">%s</xliff:g>”:"</string>
+ <string name="js_dialog_title_default">"JavaScript"</string>
+ <string name="js_dialog_before_unload">"Czy opuścić tę stronę?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Wybierz opcję OK, aby kontynuować, lub opcję Anuluj, aby pozostać na tej stronie."</string>
<string name="save_password_label">"Potwierdź"</string>
<string name="save_password_message">"Czy chcesz, aby zapamiętać to hasło w przeglądarce?"</string>
<string name="save_password_notnow">"Nie teraz"</string>
@@ -496,22 +483,38 @@
<item quantity="one">"jutro"</item>
<item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> dni"</item>
</plurals>
- <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) -->
- <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) -->
- <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) -->
- <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) -->
- <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) -->
- <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) -->
- <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) -->
- <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) -->
- <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) -->
- <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) -->
- <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) -->
- <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) -->
- <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) -->
- <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) -->
- <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) -->
- <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) -->
+ <plurals name="abbrev_num_seconds_ago">
+ <item quantity="one">"sekundę temu"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> sek. temu"</item>
+ </plurals>
+ <plurals name="abbrev_num_minutes_ago">
+ <item quantity="one">"minutę temu"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> min temu"</item>
+ </plurals>
+ <plurals name="abbrev_num_hours_ago">
+ <item quantity="one">"godzinę temu"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> godz. temu"</item>
+ </plurals>
+ <plurals name="abbrev_num_days_ago">
+ <item quantity="one">"wczoraj"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> dni temu"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_seconds">
+ <item quantity="one">"za sekundę"</item>
+ <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> sek."</item>
+ </plurals>
+ <plurals name="abbrev_in_num_minutes">
+ <item quantity="one">"za minutę"</item>
+ <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> min"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_hours">
+ <item quantity="one">"za godzinę"</item>
+ <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> godz."</item>
+ </plurals>
+ <plurals name="abbrev_in_num_days">
+ <item quantity="one">"jutro"</item>
+ <item quantity="other">"za <xliff:g id="COUNT">%d</xliff:g> dni"</item>
+ </plurals>
<string name="preposition_for_date">"dnia %s"</string>
<string name="preposition_for_time">"o %s"</string>
<string name="preposition_for_year">"w %s"</string>
@@ -553,17 +556,15 @@
<string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <!-- no translation found for date_time (6104442718633642836) -->
- <skip />
- <!-- no translation found for relative_time (1818557177829411417) -->
- <skip />
+ <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>', '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"południe"</string>
<string name="Noon">"Południe"</string>
<string name="midnight">"północ"</string>
@@ -691,8 +692,7 @@
<string name="paste">"Wklej"</string>
<string name="copyUrl">"Kopiuj adres URL"</string>
<string name="inputMethod">"Metoda wejściowa"</string>
- <!-- no translation found for addToDictionary (726256909274177272) -->
- <skip />
+ <string name="addToDictionary">"Dodaj „%s” do słownika"</string>
<string name="editTextMenuTitle">"Edytuj tekst"</string>
<string name="low_internal_storage_view_title">"Mało miejsca"</string>
<string name="low_internal_storage_view_text">"Maleje ilość dostępnej pamięci telefonu."</string>
@@ -700,8 +700,7 @@
<string name="cancel">"Anuluj"</string>
<string name="yes">"OK"</string>
<string name="no">"Anuluj"</string>
- <!-- no translation found for dialog_alert_title (2049658708609043103) -->
- <skip />
+ <string name="dialog_alert_title">"Uwaga"</string>
<string name="capital_on">"Włącz"</string>
<string name="capital_off">"Wyłącz"</string>
<string name="whichApplication">"Zakończ działanie, korzystając z"</string>
@@ -725,8 +724,7 @@
<string name="volume_music">"Głośność multimediów"</string>
<string name="volume_music_hint_playing_through_bluetooth">"Odtwarzanie przez Bluetooth"</string>
<string name="volume_call">"Głośność podczas połączenia"</string>
- <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
- <skip />
+ <string name="volume_bluetooth_call">"Głośność Bluetooth w czasie połączenia"</string>
<string name="volume_alarm">"Głośność alarmu"</string>
<string name="volume_notification">"Głośność powiadomienia"</string>
<string name="volume_unknown">"Głośność"</string>
@@ -762,60 +760,35 @@
<string name="usb_storage_error_message">"Wystąpił problem z wykorzystaniem karty SD dla pamięci USB."</string>
<string name="usb_storage_notification_title">"Połączenie przez USB"</string>
<string name="usb_storage_notification_message">"Wybierz, aby skopiować pliki do/z komputera"</string>
- <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
- <skip />
- <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
- <skip />
- <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
- <skip />
- <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
- <skip />
- <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
- <skip />
- <!-- no translation found for extmedia_format_title (8663247929551095854) -->
- <skip />
- <!-- no translation found for extmedia_format_message (3621369962433523619) -->
- <skip />
- <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
- <skip />
+ <string name="usb_storage_stop_notification_title">"Wyłącz nośnik USB"</string>
+ <string name="usb_storage_stop_notification_message">"Wybierz, aby wyłączyć nośnik USB."</string>
+ <string name="usb_storage_stop_title">"Wyłącz nośnik USB"</string>
+ <string name="usb_storage_stop_message">"Przed wyłączeniem nośnika USB upewnij się, że odłączono go od hosta USB. Wybierz „Wyłącz”, aby wyłączyć nośnik USB."</string>
+ <string name="usb_storage_stop_button_mount">"Wyłącz"</string>
+ <string name="usb_storage_stop_button_unmount">"Anuluj"</string>
+ <string name="usb_storage_stop_error_message">"Napotkano problem przy wyłączaniu nośnika USB. Sprawdź, czy host USB został odłączony i spróbuj ponownie."</string>
+ <string name="extmedia_format_title">"Formatuj kartę SD"</string>
+ <string name="extmedia_format_message">"Czy na pewno sformatować kartę SD? Wszystkie dane na karcie zostaną utracone."</string>
+ <string name="extmedia_format_button_format">"Formatuj"</string>
<string name="select_input_method">"Wybierz metodę wejściową"</string>
<string name="fast_scroll_alphabet">"AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string>
<string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
- <!-- no translation found for candidates_style (4333913089637062257) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
- <skip />
- <!-- no translation found for activity_list_empty (4168820609403385789) -->
- <skip />
- <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
- <skip />
- <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
- <skip />
+ <string name="candidates_style"><u>"kandydaci"</u></string>
+ <string name="ext_media_checking_notification_title">"Przygotowywanie karty SD"</string>
+ <string name="ext_media_checking_notification_message">"Sprawdzanie w poszukiwaniu błędów"</string>
+ <string name="ext_media_nofs_notification_title">"Pusta karta SD"</string>
+ <string name="ext_media_nofs_notification_message">"Karta SD jest pusta lub używa nieobsługiwanego systemu plików."</string>
+ <string name="ext_media_unmountable_notification_title">"Uszkodzona karta SD"</string>
+ <string name="ext_media_unmountable_notification_message">"Karta SD jest uszkodzona. Konieczne może być przeformatowanie karty."</string>
+ <string name="ext_media_badremoval_notification_title">"Karta SD została nieoczekiwanie wyjęta"</string>
+ <string name="ext_media_badremoval_notification_message">"Odłącz kartę SD przed jej wyjęciem, aby uniknąć utraty danych."</string>
+ <string name="ext_media_safe_unmount_notification_title">"Można bezpiecznie usunąć kartę SD"</string>
+ <string name="ext_media_safe_unmount_notification_message">"Można teraz bezpiecznie usunąć kartę SD."</string>
+ <string name="ext_media_nomedia_notification_title">"Usunięta karta SD"</string>
+ <string name="ext_media_nomedia_notification_message">"Karta SD została usunięta. Włóż nową kartę SD, aby zwiększyć pamięć urządzenia."</string>
+ <string name="activity_list_empty">"Nie znaleziono pasujących działań"</string>
+ <string name="permlab_pkgUsageStats">"aktualizowanie statystyk użycia komponentu"</string>
+ <string name="permdesc_pkgUsageStats">"Zezwala na modyfikacje zebranych statystyk użycia komponentu. Nieprzeznaczone dla zwykłych aplikacji."</string>
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) -->
<skip />
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 76a358d..612a185 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_reboot">"Разрешает приложению принудительно перезагружать телефон."</string>
<string name="permlab_mount_unmount_filesystems">"подключаться и отключаться от файловых систем"</string>
<string name="permdesc_mount_unmount_filesystems">"Разрешает приложению подключаться и отключаться от файловых систем съемных устройств хранения."</string>
- <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
- <skip />
- <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
- <skip />
+ <string name="permlab_mount_format_filesystems">"форматировать внешний накопитель"</string>
+ <string name="permdesc_mount_format_filesystems">"Позволяет приложению форматировать съемный накопитель."</string>
<string name="permlab_vibrate">"управлять вибрацией"</string>
<string name="permdesc_vibrate">"Разрешает приложению управлять вибровызовом."</string>
<string name="permlab_flashlight">"управлять фонарем"</string>
@@ -280,10 +278,8 @@
<string name="permdesc_locationUpdates">"Разрешает включение/отключение уведомлений о местоположении по радиосвязи. Не используется обычными приложениями."</string>
<string name="permlab_checkinProperties">"открывать свойства проверки"</string>
<string name="permdesc_checkinProperties">"Разрешает доступ на чтение и запись к свойствам, загруженным службой проверки. Не используется обычными приложениями."</string>
- <!-- no translation found for permlab_bindGadget (2519859363977647275) -->
- <skip />
- <!-- no translation found for permdesc_bindGadget (7865866514555126333) -->
- <skip />
+ <string name="permlab_bindGadget">"выбирать гаджеты"</string>
+ <string name="permdesc_bindGadget">"Позволяет приложению сообщить системе, какие приложения могут использовать какие гаджеты. Это разрешение позволяет приложениям предоставлять другим приложениям доступ к личной информации. Не предназначено для использования обычными приложениями."</string>
<string name="permlab_modifyPhoneState">"изменять состояние телефона"</string>
<string name="permdesc_modifyPhoneState">"Позволяет приложению управлять телефонными функциями устройства. Приложение с такими полномочиями может переключать сети, включать и выключать радиосвязь и т.д., не сообщая вам об этом."</string>
<string name="permlab_readPhoneState">"считывать состояние телефона"</string>
@@ -312,10 +308,8 @@
<string name="permdesc_writeApnSettings">"Разрешает приложению изменять настройки APN, например прокси и порт любого APN."</string>
<string name="permlab_changeNetworkState">"изменять подключение к сети"</string>
<string name="permdesc_changeNetworkState">"Позволяет приложению изменять подключение к сети."</string>
- <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
- <skip />
- <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
- <skip />
+ <string name="permlab_changeBackgroundDataSetting">"изменить настройку использования фоновых данных"</string>
+ <string name="permdesc_changeBackgroundDataSetting">"Позволяет приложению изменять настройку использования фоновых данных."</string>
<string name="permlab_accessWifiState">"просматривать состояние Wi-Fi"</string>
<string name="permdesc_accessWifiState">"Разрешает приложению просматривать сведения о состоянии Wi-Fi."</string>
<string name="permlab_changeWifiState">"изменять состояние Wi-Fi"</string>
@@ -336,14 +330,10 @@
<string name="permdesc_subscribedFeedsRead">"Позволяет приложению получать сведения о синхронизированных фидах."</string>
<string name="permlab_subscribedFeedsWrite">"записывать фиды с подпиской"</string>
<string name="permdesc_subscribedFeedsWrite">"Разрешает приложению изменять ваши синхронизированные фиды. Это может позволить вредоносному ПО изменять ваши синхронизированные фиды."</string>
- <!-- no translation found for permlab_readDictionary (432535716804748781) -->
- <skip />
- <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
- <skip />
- <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
- <skip />
- <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
- <skip />
+ <string name="permlab_readDictionary">"выполнять чтение из пользовательского словаря"</string>
+ <string name="permdesc_readDictionary">"Позволяет приложению считывать любые слова, имена и фразы личного пользования, которые могут храниться в пользовательском словаре."</string>
+ <string name="permlab_writeDictionary">"записывать в пользовательский словарь"</string>
+ <string name="permdesc_writeDictionary">"Позволяет приложению записывать новые слова в пользовательский словарь."</string>
<string-array name="phoneTypes">
<item>"Домашний"</item>
<item>"Мобильный"</item>
@@ -440,12 +430,9 @@
<string name="factorytest_not_system">"Действие FACTORY_TEST поддерживается только для пакетов, установленных в папке /system/app."</string>
<string name="factorytest_no_action">"Пакет, предоставляющий действие FACTORY_TEST, не найден."</string>
<string name="factorytest_reboot">"Перезагрузить"</string>
- <!-- no translation found for js_dialog_title (8143918455087008109) -->
- <skip />
- <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
- <skip />
- <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
- <skip />
+ <string name="js_dialog_title">"На странице по адресу \"<xliff:g id="TITLE">%s</xliff:g>\" сказано:"</string>
+ <string name="js_dialog_title_default">"JavaScript"</string>
+ <string name="js_dialog_before_unload">"Перейти с этой страницы?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Нажмите \"ОК\", чтобы продолжить, или \"Отмена\", чтобы остаться на текущей странице."</string>
<string name="save_password_label">"Подтверждение"</string>
<string name="save_password_message">"Сохранить этот пароль в браузере?"</string>
<string name="save_password_notnow">"Не сейчас"</string>
@@ -496,22 +483,38 @@
<item quantity="one">"завтра"</item>
<item quantity="other">"через <xliff:g id="COUNT">%d</xliff:g> дн."</item>
</plurals>
- <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) -->
- <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) -->
- <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) -->
- <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) -->
- <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) -->
- <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) -->
- <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) -->
- <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) -->
- <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) -->
- <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) -->
- <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) -->
- <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) -->
- <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) -->
- <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) -->
- <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) -->
- <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) -->
+ <plurals name="abbrev_num_seconds_ago">
+ <item quantity="one">"1 сек. назад"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> сек. назад"</item>
+ </plurals>
+ <plurals name="abbrev_num_minutes_ago">
+ <item quantity="one">"1 мин. назад"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> мин. назад"</item>
+ </plurals>
+ <plurals name="abbrev_num_hours_ago">
+ <item quantity="one">"1 час назад"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> ч. назад"</item>
+ </plurals>
+ <plurals name="abbrev_num_days_ago">
+ <item quantity="one">"вчера"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> дн. назад"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_seconds">
+ <item quantity="one">"через 1 сек."</item>
+ <item quantity="other">"через <xliff:g id="COUNT">%d</xliff:g> сек."</item>
+ </plurals>
+ <plurals name="abbrev_in_num_minutes">
+ <item quantity="one">"через 1 мин."</item>
+ <item quantity="other">"через <xliff:g id="COUNT">%d</xliff:g> мин."</item>
+ </plurals>
+ <plurals name="abbrev_in_num_hours">
+ <item quantity="one">"через 1 час"</item>
+ <item quantity="other">"через <xliff:g id="COUNT">%d</xliff:g> час."</item>
+ </plurals>
+ <plurals name="abbrev_in_num_days">
+ <item quantity="one">"завтра"</item>
+ <item quantity="other">"через <xliff:g id="COUNT">%d</xliff:g> дн."</item>
+ </plurals>
<string name="preposition_for_date">"%s"</string>
<string name="preposition_for_time">"в %s"</string>
<string name="preposition_for_year">"в %s"</string>
@@ -553,17 +556,15 @@
<string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="DATE">%3$s</xliff:g>"</string>
- <!-- no translation found for date_time (6104442718633642836) -->
- <skip />
- <!-- no translation found for relative_time (1818557177829411417) -->
- <skip />
+ <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>, <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>, <xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_month_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"полдень"</string>
<string name="Noon">"Полдень"</string>
<string name="midnight">"полночь"</string>
@@ -691,8 +692,7 @@
<string name="paste">"Вставить"</string>
<string name="copyUrl">"Копировать URL"</string>
<string name="inputMethod">"Способ ввода"</string>
- <!-- no translation found for addToDictionary (726256909274177272) -->
- <skip />
+ <string name="addToDictionary">"Добавить \"%s\" в словарь"</string>
<string name="editTextMenuTitle">"Правка текста"</string>
<string name="low_internal_storage_view_title">"Недостаточно места"</string>
<string name="low_internal_storage_view_text">"В памяти телефона осталось мало места."</string>
@@ -700,8 +700,7 @@
<string name="cancel">"Отмена"</string>
<string name="yes">"ОК"</string>
<string name="no">"Отмена"</string>
- <!-- no translation found for dialog_alert_title (2049658708609043103) -->
- <skip />
+ <string name="dialog_alert_title">"Внимание"</string>
<string name="capital_on">"ВКЛ"</string>
<string name="capital_off">"ВЫКЛ"</string>
<string name="whichApplication">"Выполнить действие с помощью"</string>
@@ -725,8 +724,7 @@
<string name="volume_music">"Громкость звука мультимедиа"</string>
<string name="volume_music_hint_playing_through_bluetooth">"Воспроизводится через Bluetooth"</string>
<string name="volume_call">"Громкость звонка"</string>
- <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
- <skip />
+ <string name="volume_bluetooth_call">"Громкость входящего вызова Bluetooth"</string>
<string name="volume_alarm">"Громкость будильника"</string>
<string name="volume_notification">"Громкость уведомления"</string>
<string name="volume_unknown">"Громкость"</string>
@@ -762,60 +760,35 @@
<string name="usb_storage_error_message">"Не удается использовать карту SD в качестве USB-хранилища."</string>
<string name="usb_storage_notification_title">"Подключение через USB"</string>
<string name="usb_storage_notification_message">"Выберите для копирования файлов на/с компьютера."</string>
- <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
- <skip />
- <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
- <skip />
- <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
- <skip />
- <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
- <skip />
- <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
- <skip />
- <!-- no translation found for extmedia_format_title (8663247929551095854) -->
- <skip />
- <!-- no translation found for extmedia_format_message (3621369962433523619) -->
- <skip />
- <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
- <skip />
+ <string name="usb_storage_stop_notification_title">"Выключить USB-накопитель"</string>
+ <string name="usb_storage_stop_notification_message">"Выберите, чтобы выключить USB-накопитель."</string>
+ <string name="usb_storage_stop_title">"Выключить USB-накопитель"</string>
+ <string name="usb_storage_stop_message">"Перед выключением USB-накопителя обязательно отключите USB-хост. Выберите \"Выключить\", чтобы выключить USB-накопитель."</string>
+ <string name="usb_storage_stop_button_mount">"Выключить"</string>
+ <string name="usb_storage_stop_button_unmount">"Отмена"</string>
+ <string name="usb_storage_stop_error_message">"При выключении USB-накопителя произошла проблема. Убедитесь, что USB-хост отключен, и повторите попытку."</string>
+ <string name="extmedia_format_title">"Форматировать карту SD"</string>
+ <string name="extmedia_format_message">"Отформатировать карту SD? Все данные, находящиеся на карте, будут уничтожены."</string>
+ <string name="extmedia_format_button_format">"Формат"</string>
<string name="select_input_method">"Выбор способа ввода"</string>
<string name="fast_scroll_alphabet">"АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ"</string>
<string name="fast_scroll_numeric_alphabet">"0123456789АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЫЭЮЯ"</string>
- <!-- no translation found for candidates_style (4333913089637062257) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
- <skip />
- <!-- no translation found for activity_list_empty (4168820609403385789) -->
- <skip />
- <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
- <skip />
- <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
- <skip />
+ <string name="candidates_style"><u>"кандидаты"</u></string>
+ <string name="ext_media_checking_notification_title">"Подготовка карты SD"</string>
+ <string name="ext_media_checking_notification_message">"Поиск ошибок"</string>
+ <string name="ext_media_nofs_notification_title">"Пустая карта SD"</string>
+ <string name="ext_media_nofs_notification_message">"Карта SD пуста или использует неподдерживаемую файловую систему."</string>
+ <string name="ext_media_unmountable_notification_title">"Поврежденная карта SD"</string>
+ <string name="ext_media_unmountable_notification_message">"Карта SD повреждена. Может потребоваться переформатировать ее."</string>
+ <string name="ext_media_badremoval_notification_title">"Карта SD неожиданно извлечена"</string>
+ <string name="ext_media_badremoval_notification_message">"Перед извлечением карты SD отключите ее во избежание потери данных."</string>
+ <string name="ext_media_safe_unmount_notification_title">"Безопасное удаление карты SD"</string>
+ <string name="ext_media_safe_unmount_notification_message">"Теперь карту SD можно безопасно удалить."</string>
+ <string name="ext_media_nomedia_notification_title">"Карта SD удалена"</string>
+ <string name="ext_media_nomedia_notification_message">"Карта SD была удалена. Для увеличения емкости устройства вставьте новую карту SD."</string>
+ <string name="activity_list_empty">"Подходящих действий не найдено"</string>
+ <string name="permlab_pkgUsageStats">"обновлять статистику использования компонентов"</string>
+ <string name="permdesc_pkgUsageStats">"Позволяет изменять собранную статистику использования компонентов. Не предназначено для использования обычными приложениями."</string>
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) -->
<skip />
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 13d4e9c..fbd58e8 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_reboot">"允许应用程序强制手机重新引导。"</string>
<string name="permlab_mount_unmount_filesystems">"装载和卸载文件系统"</string>
<string name="permdesc_mount_unmount_filesystems">"允许应用程序装载和卸载文件系统以进行可移动存储。"</string>
- <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
- <skip />
- <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
- <skip />
+ <string name="permlab_mount_format_filesystems">"格式化外部存储设备"</string>
+ <string name="permdesc_mount_format_filesystems">"允许应用程序格式化可移除的存储设备。"</string>
<string name="permlab_vibrate">"控制振动器"</string>
<string name="permdesc_vibrate">"允许应用程序控制振动器。"</string>
<string name="permlab_flashlight">"控制闪光灯"</string>
@@ -280,10 +278,8 @@
<string name="permdesc_locationUpdates">"允许启用/禁用来自收音机的位置更新通知。普通应用程序不能使用此权限。"</string>
<string name="permlab_checkinProperties">"访问检入属性"</string>
<string name="permdesc_checkinProperties">"允许对检入服务上传的属性进行读/写访问。普通应用程序不能使用此权限。"</string>
- <!-- no translation found for permlab_bindGadget (2519859363977647275) -->
- <skip />
- <!-- no translation found for permdesc_bindGadget (7865866514555126333) -->
- <skip />
+ <string name="permlab_bindGadget">"选择小工具"</string>
+ <string name="permdesc_bindGadget">"允许应用程序告诉系统哪些应用程序可以使用哪些小工具。应用程序可以借此授予其他应用程序访问个人数据的权限。普通应用程序不能使用此权限。"</string>
<string name="permlab_modifyPhoneState">"修改手机状态"</string>
<string name="permdesc_modifyPhoneState">"允许应用程序控制设备的手机功能。具有此权限的应用程序可能会切换网络,打开和关闭手机收音机以及类似操作,而不会通知您。"</string>
<string name="permlab_readPhoneState">"读取手机状态"</string>
@@ -312,10 +308,8 @@
<string name="permdesc_writeApnSettings">"允许应用程序修改 APN 设置,例如任何 APN 的代理和端口。"</string>
<string name="permlab_changeNetworkState">"更改网络连接性"</string>
<string name="permdesc_changeNetworkState">"允许应用程序更改状态网络连接性。"</string>
- <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
- <skip />
- <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
- <skip />
+ <string name="permlab_changeBackgroundDataSetting">"更改背景数据使用设置"</string>
+ <string name="permdesc_changeBackgroundDataSetting">"允许应用程序更改背景数据使用设置。"</string>
<string name="permlab_accessWifiState">"查看 Wi-Fi 状态"</string>
<string name="permdesc_accessWifiState">"允许应用程序查看有关 Wi-Fi 状态的信息。"</string>
<string name="permlab_changeWifiState">"更改 Wi-Fi 状态"</string>
@@ -336,14 +330,10 @@
<string name="permdesc_subscribedFeedsRead">"允许应用程序获取有关当前同步的供稿的详情。"</string>
<string name="permlab_subscribedFeedsWrite">"写入订阅的供稿"</string>
<string name="permdesc_subscribedFeedsWrite">"允许应用程序修改您当前同步的供稿。这样恶意程序可以更改您同步的供稿。"</string>
- <!-- no translation found for permlab_readDictionary (432535716804748781) -->
- <skip />
- <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
- <skip />
- <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
- <skip />
- <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
- <skip />
+ <string name="permlab_readDictionary">"读取用户定义的词典"</string>
+ <string name="permdesc_readDictionary">"允许应用程序读取用户在用户词典中存储的任意私有字词、名称和短语。"</string>
+ <string name="permlab_writeDictionary">"写入用户定义的词典"</string>
+ <string name="permdesc_writeDictionary">"允许应用程序向用户词典中写入新词。"</string>
<string-array name="phoneTypes">
<item>"家庭"</item>
<item>"手机"</item>
@@ -440,12 +430,9 @@
<string name="factorytest_not_system">"只有在 /system/app 中安装的包支持 FACTORY_TEST 操作。"</string>
<string name="factorytest_no_action">"未发现支持 FACTORY_TEST 操作的包。"</string>
<string name="factorytest_reboot">"重新引导"</string>
- <!-- no translation found for js_dialog_title (8143918455087008109) -->
- <skip />
- <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
- <skip />
- <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
- <skip />
+ <string name="js_dialog_title">"“<xliff:g id="TITLE">%s</xliff:g>”处的页面表明:"</string>
+ <string name="js_dialog_title_default">"JavaScript"</string>
+ <string name="js_dialog_before_unload">"是否从该页面导航至它处?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"选择“确定”继续,或选择“取消”留在当前页面。"</string>
<string name="save_password_label">"确认"</string>
<string name="save_password_message">"是否希望浏览器记住此密码?"</string>
<string name="save_password_notnow">"暂不保存"</string>
@@ -496,22 +483,38 @@
<item quantity="one">"明天"</item>
<item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 天后"</item>
</plurals>
- <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) -->
- <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) -->
- <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) -->
- <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) -->
- <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) -->
- <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) -->
- <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) -->
- <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) -->
- <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) -->
- <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) -->
- <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) -->
- <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) -->
- <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) -->
- <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) -->
- <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) -->
- <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) -->
+ <plurals name="abbrev_num_seconds_ago">
+ <item quantity="one">"1 秒前"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 秒前"</item>
+ </plurals>
+ <plurals name="abbrev_num_minutes_ago">
+ <item quantity="one">"1 分钟前"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 分钟前"</item>
+ </plurals>
+ <plurals name="abbrev_num_hours_ago">
+ <item quantity="one">"1 小时前"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 小时前"</item>
+ </plurals>
+ <plurals name="abbrev_num_days_ago">
+ <item quantity="one">"昨天"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 天前"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_seconds">
+ <item quantity="one">"1 秒后"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 秒后"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_minutes">
+ <item quantity="one">"1 分钟后"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 分钟后"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_hours">
+ <item quantity="one">"1 小时后"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 小时后"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_days">
+ <item quantity="one">"明天"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 天后"</item>
+ </plurals>
<string name="preposition_for_date">"在 %s"</string>
<string name="preposition_for_time">"在 %s"</string>
<string name="preposition_for_year">"%s 年内"</string>
@@ -553,17 +556,15 @@
<string name="time_wday_date">"<xliff:g id="DATE">%3$s</xliff:g><xliff:g id="WEEKDAY">%2$s</xliff:g> <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
<string name="wday_date">"<xliff:g id="DATE">%3$s</xliff:g><xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
<string name="time_date">"<xliff:g id="DATE">%3$s</xliff:g> <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <!-- no translation found for date_time (6104442718633642836) -->
- <skip />
- <!-- no translation found for relative_time (1818557177829411417) -->
- <skip />
+ <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g><xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g><xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="WEEKDAY">%2$s</xliff:g> <xliff:g id="TIME_RANGE">%1$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string>
- <string name="full_date_day_first">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string>
- <string name="medium_date_month_first">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string>
- <string name="medium_date_day_first">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="DAY">d</xliff:g>' 月 '<xliff:g id="MONTH">MMM</xliff:g>' 日'"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string>
+ <string name="full_date_day_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string>
+ <string name="medium_date_month_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="MONTH">MMM</xliff:g>' 月 '<xliff:g id="DAY">d</xliff:g>' 日'"</string>
+ <string name="medium_date_day_first" format="date">"<xliff:g id="YEAR">yyyy</xliff:g>' 年 '<xliff:g id="DAY">d</xliff:g>' 月 '<xliff:g id="MONTH">MMM</xliff:g>' 日'"</string>
+ <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"中午"</string>
<string name="Noon">"中午"</string>
<string name="midnight">"午夜"</string>
@@ -691,8 +692,7 @@
<string name="paste">"粘贴"</string>
<string name="copyUrl">"复制网址"</string>
<string name="inputMethod">"输入方法"</string>
- <!-- no translation found for addToDictionary (726256909274177272) -->
- <skip />
+ <string name="addToDictionary">"将“%s”添加到词典"</string>
<string name="editTextMenuTitle">"编辑文本"</string>
<string name="low_internal_storage_view_title">"存储空间不足"</string>
<string name="low_internal_storage_view_text">"手机存储空间在减少。"</string>
@@ -700,8 +700,7 @@
<string name="cancel">"取消"</string>
<string name="yes">"正常"</string>
<string name="no">"取消"</string>
- <!-- no translation found for dialog_alert_title (2049658708609043103) -->
- <skip />
+ <string name="dialog_alert_title">"注意事项"</string>
<string name="capital_on">"开启"</string>
<string name="capital_off">"关闭"</string>
<string name="whichApplication">"使用以下内容完成操作"</string>
@@ -725,8 +724,7 @@
<string name="volume_music">"媒体音量"</string>
<string name="volume_music_hint_playing_through_bluetooth">"正通过蓝牙播放"</string>
<string name="volume_call">"来电音量"</string>
- <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
- <skip />
+ <string name="volume_bluetooth_call">"使用蓝牙时的通话音量"</string>
<string name="volume_alarm">"警告音量"</string>
<string name="volume_notification">"通知音量"</string>
<string name="volume_unknown">"音量"</string>
@@ -762,60 +760,35 @@
<string name="usb_storage_error_message">"使用 SD 卡进行 USB 存储时出现问题。"</string>
<string name="usb_storage_notification_title">"USB 已连接"</string>
<string name="usb_storage_notification_message">"选择以将文件复制到计算机或从计算机复制文件。"</string>
- <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
- <skip />
- <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
- <skip />
- <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
- <skip />
- <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
- <skip />
- <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
- <skip />
- <!-- no translation found for extmedia_format_title (8663247929551095854) -->
- <skip />
- <!-- no translation found for extmedia_format_message (3621369962433523619) -->
- <skip />
- <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
- <skip />
+ <string name="usb_storage_stop_notification_title">"关闭 USB 存储设备"</string>
+ <string name="usb_storage_stop_notification_message">"选中以关闭 USB 存储设备。"</string>
+ <string name="usb_storage_stop_title">"关闭 USB 存储设备"</string>
+ <string name="usb_storage_stop_message">"在关闭 USB 存储设备前,请确保您已卸载了 USB 主设备。选择“关闭”关闭 USB 存储设备。"</string>
+ <string name="usb_storage_stop_button_mount">"关闭"</string>
+ <string name="usb_storage_stop_button_unmount">"取消"</string>
+ <string name="usb_storage_stop_error_message">"关闭 USB 存储设备时遇到问题。请检查是否卸载了 USB 主设备,然后重试。"</string>
+ <string name="extmedia_format_title">"格式化 SD 卡"</string>
+ <string name="extmedia_format_message">"您确定要格式化 SD 卡?卡上的所有数据都会丢失。"</string>
+ <string name="extmedia_format_button_format">"格式化"</string>
<string name="select_input_method">"选择输入方法"</string>
<string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
- <!-- no translation found for candidates_style (4333913089637062257) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
- <skip />
- <!-- no translation found for activity_list_empty (4168820609403385789) -->
- <skip />
- <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
- <skip />
- <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
- <skip />
+ <string name="candidates_style"><u>"候选"</u></string>
+ <string name="ext_media_checking_notification_title">"正在准备 SD 卡"</string>
+ <string name="ext_media_checking_notification_message">"检查是否有错误"</string>
+ <string name="ext_media_nofs_notification_title">"空 SD 卡"</string>
+ <string name="ext_media_nofs_notification_message">"SD 卡为空或使用不支持的文件系统。"</string>
+ <string name="ext_media_unmountable_notification_title">"SD 卡受损"</string>
+ <string name="ext_media_unmountable_notification_message">"SD 卡受损。您可能需要重新格式化您的卡。"</string>
+ <string name="ext_media_badremoval_notification_title">"SD 卡被意外拔除"</string>
+ <string name="ext_media_badremoval_notification_message">"先卸载 SD 卡再拔除,以避免数据丢失。"</string>
+ <string name="ext_media_safe_unmount_notification_title">"SD 卡已安全移除"</string>
+ <string name="ext_media_safe_unmount_notification_message">"现在可以安全移除 SD 卡。"</string>
+ <string name="ext_media_nomedia_notification_title">"已移除 SD 卡"</string>
+ <string name="ext_media_nomedia_notification_message">"SD 卡已移除。请插入新 SD 卡来增加您的设备存储空间。"</string>
+ <string name="activity_list_empty">"找不到匹配的活动"</string>
+ <string name="permlab_pkgUsageStats">"更新组件使用情况统计"</string>
+ <string name="permdesc_pkgUsageStats">"允许修改收集的组件使用情况统计。普通应用程序不能使用此权限。"</string>
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) -->
<skip />
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 419e8c2..18d6711 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -262,10 +262,8 @@
<string name="permdesc_reboot">"允許應用程式強制重開機。"</string>
<string name="permlab_mount_unmount_filesystems">"掛載/卸載檔案系統"</string>
<string name="permdesc_mount_unmount_filesystems">"允許應用程式掛載/卸載抽取式儲存設備的檔案系統。"</string>
- <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
- <skip />
- <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
- <skip />
+ <string name="permlab_mount_format_filesystems">"將外接式儲存裝置格式化"</string>
+ <string name="permdesc_mount_format_filesystems">"允許應用程式將可移除式儲存裝置格式化。"</string>
<string name="permlab_vibrate">"控制震動器"</string>
<string name="permdesc_vibrate">"允許應用程式控制震動器。"</string>
<string name="permlab_flashlight">"控制閃光燈"</string>
@@ -280,10 +278,8 @@
<string name="permdesc_locationUpdates">"允許啟用/停用無線通訊位置更新通知。一般應用程式不會使用此功能。"</string>
<string name="permlab_checkinProperties">"存取登機選項"</string>
<string name="permdesc_checkinProperties">"允許讀寫登機服務上傳的資料。一般應用程式不會使用此功能。"</string>
- <!-- no translation found for permlab_bindGadget (2519859363977647275) -->
- <skip />
- <!-- no translation found for permdesc_bindGadget (7865866514555126333) -->
- <skip />
+ <string name="permlab_bindGadget">"選擇小工具"</string>
+ <string name="permdesc_bindGadget">"允許應用程式告知系統哪些應用程式可以使用哪些小工具。擁有此權限的應用程式可以讓其他應用程式使用個人資料。一般應用程式不會使用此功能。"</string>
<string name="permlab_modifyPhoneState">"修改手機狀態"</string>
<string name="permdesc_modifyPhoneState">"允許應用程式控制電話功能。擁有此權限的程式可自行切換網路、開關無線通訊功能。"</string>
<string name="permlab_readPhoneState">"讀取手機狀態"</string>
@@ -312,10 +308,8 @@
<string name="permdesc_writeApnSettings">"允許應用程式修改 APN 設定,例如:Proxy 及 APN 的連接埠。"</string>
<string name="permlab_changeNetworkState">"變更網路連線"</string>
<string name="permdesc_changeNetworkState">"允許應用程式變更網路連線狀態。"</string>
- <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
- <skip />
- <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
- <skip />
+ <string name="permlab_changeBackgroundDataSetting">"變更背景資料使用設定"</string>
+ <string name="permdesc_changeBackgroundDataSetting">"允許應用程式變更背景資料使用設定。"</string>
<string name="permlab_accessWifiState">"檢視 Wi-Fi 狀態"</string>
<string name="permdesc_accessWifiState">"允許應用程式檢視 Wi-Fi 狀態資訊。"</string>
<string name="permlab_changeWifiState">"變更 Wi-Fi 狀態"</string>
@@ -336,14 +330,10 @@
<string name="permdesc_subscribedFeedsRead">"允許應用程式取得目前已同步處理的資訊提供。"</string>
<string name="permlab_subscribedFeedsWrite">"寫入訂閱資訊提供"</string>
<string name="permdesc_subscribedFeedsWrite">"允許應用程式修改已同步處理的資訊提供。惡意程式可使用此功能變更已同步處理的資訊提供。"</string>
- <!-- no translation found for permlab_readDictionary (432535716804748781) -->
- <skip />
- <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
- <skip />
- <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
- <skip />
- <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
- <skip />
+ <string name="permlab_readDictionary">"讀取使用者定義的字典"</string>
+ <string name="permdesc_readDictionary">"允許應用程式讀取使用者儲存在使用者字典內的任何私人字詞、名稱和詞組。"</string>
+ <string name="permlab_writeDictionary">"寫入使用者定義的字典"</string>
+ <string name="permdesc_writeDictionary">"允許應用程式將新字詞寫入使用者的字典。"</string>
<string-array name="phoneTypes">
<item>"首頁"</item>
<item>"行動"</item>
@@ -440,12 +430,9 @@
<string name="factorytest_not_system">"FACTORY_TEST 動作只支援安裝在 /system/app 裡的程式。"</string>
<string name="factorytest_no_action">"找不到提供 FACTORY_TEST 的程式。"</string>
<string name="factorytest_reboot">"重新開機"</string>
- <!-- no translation found for js_dialog_title (8143918455087008109) -->
- <skip />
- <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
- <skip />
- <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
- <skip />
+ <string name="js_dialog_title">"「<xliff:g id="TITLE">%s</xliff:g>」的網頁指出:"</string>
+ <string name="js_dialog_title_default">"JavaScript"</string>
+ <string name="js_dialog_before_unload">"離開此頁?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n" 選取 [確定] 離開此頁;或 [取消] 留在此頁。"</string>
<string name="save_password_label">"確認"</string>
<string name="save_password_message">"是否記憶此密碼?"</string>
<string name="save_password_notnow">"現在不要"</string>
@@ -496,22 +483,38 @@
<item quantity="one">"明天"</item>
<item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 天內"</item>
</plurals>
- <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) -->
- <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) -->
- <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) -->
- <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) -->
- <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) -->
- <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) -->
- <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) -->
- <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) -->
- <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) -->
- <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) -->
- <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) -->
- <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) -->
- <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) -->
- <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) -->
- <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) -->
- <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) -->
+ <plurals name="abbrev_num_seconds_ago">
+ <item quantity="one">"1 秒以前"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 秒以前"</item>
+ </plurals>
+ <plurals name="abbrev_num_minutes_ago">
+ <item quantity="one">"1 分鐘以前"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 分鐘以前"</item>
+ </plurals>
+ <plurals name="abbrev_num_hours_ago">
+ <item quantity="one">"1 小時以前"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 小時以前"</item>
+ </plurals>
+ <plurals name="abbrev_num_days_ago">
+ <item quantity="one">"昨天"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 天以前"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_seconds">
+ <item quantity="one">"1 秒內"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 秒內"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_minutes">
+ <item quantity="one">"1 分鐘內"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 分鐘內"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_hours">
+ <item quantity="one">"1 小時內"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 小時內"</item>
+ </plurals>
+ <plurals name="abbrev_in_num_days">
+ <item quantity="one">"明天"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> 天內"</item>
+ </plurals>
<string name="preposition_for_date">"%s"</string>
<string name="preposition_for_time">"%s"</string>
<string name="preposition_for_year">"%s"</string>
@@ -553,17 +556,15 @@
<string name="time_wday_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>,<xliff:g id="WEEKDAY">%2$s</xliff:g>,<xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="wday_date">"<xliff:g id="WEEKDAY">%2$s</xliff:g>,<xliff:g id="DATE">%3$s</xliff:g>"</string>
<string name="time_date">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>,<xliff:g id="DATE">%3$s</xliff:g>"</string>
- <!-- no translation found for date_time (6104442718633642836) -->
- <skip />
- <!-- no translation found for relative_time (1818557177829411417) -->
- <skip />
+ <string name="date_time">"<xliff:g id="DATE">%1$s</xliff:g>,<xliff:g id="TIME">%2$s</xliff:g>"</string>
+ <string name="relative_time">"<xliff:g id="DATE">%1$s</xliff:g>,<xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="time_wday">"<xliff:g id="TIME_RANGE">%1$s</xliff:g>,<xliff:g id="WEEKDAY">%2$s</xliff:g>"</string>
- <string name="full_date_month_first">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="full_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_month_first">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="medium_date_day_first">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string>
- <string name="twelve_hour_time_format">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
- <string name="twenty_four_hour_time_format">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
+ <string name="full_date_month_first" format="date">"<xliff:g id="MONTH">MMMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="full_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMMM</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_month_first" format="date">"<xliff:g id="MONTH">MMM</xliff:g>' '<xliff:g id="DAY">d</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="medium_date_day_first" format="date">"<xliff:g id="DAY">d</xliff:g>' '<xliff:g id="MONTH">MMM</xliff:g>','<xliff:g id="YEAR">yyyy</xliff:g>"</string>
+ <string name="twelve_hour_time_format" format="date">"<xliff:g id="HOUR">h</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>' '<xliff:g id="AMPM">a</xliff:g>"</string>
+ <string name="twenty_four_hour_time_format" format="date">"<xliff:g id="HOUR">H</xliff:g>':'<xliff:g id="MINUTE">mm</xliff:g>"</string>
<string name="noon">"中午"</string>
<string name="Noon">"中午"</string>
<string name="midnight">"午夜"</string>
@@ -691,8 +692,7 @@
<string name="paste">"貼上"</string>
<string name="copyUrl">"複製網址"</string>
<string name="inputMethod">"輸入法"</string>
- <!-- no translation found for addToDictionary (726256909274177272) -->
- <skip />
+ <string name="addToDictionary">"將「%s」新增到字典"</string>
<string name="editTextMenuTitle">"編輯文字"</string>
<string name="low_internal_storage_view_title">"儲存空間太少"</string>
<string name="low_internal_storage_view_text">"手機儲存空間即將不足。"</string>
@@ -700,8 +700,7 @@
<string name="cancel">"取消"</string>
<string name="yes">"確定"</string>
<string name="no">"取消"</string>
- <!-- no translation found for dialog_alert_title (2049658708609043103) -->
- <skip />
+ <string name="dialog_alert_title">"注意"</string>
<string name="capital_on">"開啟"</string>
<string name="capital_off">"關閉"</string>
<string name="whichApplication">"選取...完成動作"</string>
@@ -725,8 +724,7 @@
<string name="volume_music">"媒體音量"</string>
<string name="volume_music_hint_playing_through_bluetooth">"透過藍牙播放"</string>
<string name="volume_call">"來電音量"</string>
- <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
- <skip />
+ <string name="volume_bluetooth_call">"藍牙通話音量"</string>
<string name="volume_alarm">"鬧鐘音量"</string>
<string name="volume_notification">"通知音量"</string>
<string name="volume_unknown">"音量"</string>
@@ -762,60 +760,35 @@
<string name="usb_storage_error_message">"把 SD 卡當成 USB 儲存裝置時發生問題。"</string>
<string name="usb_storage_notification_title">"USB 已連接"</string>
<string name="usb_storage_notification_message">"選取此項將檔案複製到電腦,或從電腦複製。"</string>
- <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
- <skip />
- <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
- <skip />
- <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
- <skip />
- <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
- <skip />
- <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
- <skip />
- <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
- <skip />
- <!-- no translation found for extmedia_format_title (8663247929551095854) -->
- <skip />
- <!-- no translation found for extmedia_format_message (3621369962433523619) -->
- <skip />
- <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
- <skip />
+ <string name="usb_storage_stop_notification_title">"關閉 USB 儲存裝置"</string>
+ <string name="usb_storage_stop_notification_message">"選取此處關閉 USB 儲存裝置。"</string>
+ <string name="usb_storage_stop_title">"關閉 USB 儲存裝置"</string>
+ <string name="usb_storage_stop_message">"關閉 USB 儲存裝置之前,請確定先從 USB Host 卸載。選取 [關閉] 即可關閉 USB 儲存裝置。"</string>
+ <string name="usb_storage_stop_button_mount">"關閉"</string>
+ <string name="usb_storage_stop_button_unmount">"取消"</string>
+ <string name="usb_storage_stop_error_message">"關閉 USB 儲存裝置時發生問題。請檢查確認您是否已卸載 USB Host,然後再試一次。"</string>
+ <string name="extmedia_format_title">"將 SD 卡格式化"</string>
+ <string name="extmedia_format_message">"確定要將 SD 卡格式化嗎?該 SD 卡中的所有資料將會遺失。"</string>
+ <string name="extmedia_format_button_format">"格式化"</string>
<string name="select_input_method">"選取輸入法"</string>
<string name="fast_scroll_alphabet">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
- <!-- no translation found for candidates_style (4333913089637062257) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
- <skip />
- <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
- <skip />
- <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
- <skip />
- <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
- <skip />
- <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
- <skip />
- <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
- <skip />
- <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
- <skip />
- <!-- no translation found for activity_list_empty (4168820609403385789) -->
- <skip />
- <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
- <skip />
- <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
- <skip />
+ <string name="candidates_style"><u>"待選項目"</u></string>
+ <string name="ext_media_checking_notification_title">"正在準備 SD 卡"</string>
+ <string name="ext_media_checking_notification_message">"正在檢查錯誤"</string>
+ <string name="ext_media_nofs_notification_title">"SD 卡為空白"</string>
+ <string name="ext_media_nofs_notification_message">"SD 卡為空白或使用不支援的檔案系統。"</string>
+ <string name="ext_media_unmountable_notification_title">"SD 卡已損壞"</string>
+ <string name="ext_media_unmountable_notification_message">"SD 卡已損壞。您可能需要將 SD 卡重新格式化。"</string>
+ <string name="ext_media_badremoval_notification_title">"SD 卡未預期移除"</string>
+ <string name="ext_media_badremoval_notification_message">"請先卸載 SD 卡,再將其移除,以免資料遺失。"</string>
+ <string name="ext_media_safe_unmount_notification_title">"可安全移除 SD 卡"</string>
+ <string name="ext_media_safe_unmount_notification_message">"現在可以安全移除 SD 卡。"</string>
+ <string name="ext_media_nomedia_notification_title">"已移除 SD 卡"</string>
+ <string name="ext_media_nomedia_notification_message">"已移除 SD 卡。請插入新的 SD 卡來增加裝置的儲存容量。"</string>
+ <string name="activity_list_empty">"找不到符合的活動"</string>
+ <string name="permlab_pkgUsageStats">"更新元件使用統計資料"</string>
+ <string name="permdesc_pkgUsageStats">"允許修改收集到的元件使用統計資料。一般應用程式不會使用此功能。"</string>
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4742624865416767717) -->
<skip />
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 593d1ff..6e6e074 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -224,15 +224,18 @@
<!-- Leave the soft input window as-is, in whatever state it
last was. -->
<flag name="stateUnchanged" value="1" />
- <!-- Don't display the soft input area, there is no reason to
- do so on this window. -->
+ <!-- Make the soft input area hidden when normally appropriate
+ (when the user is navigating forward to your window). -->
<flag name="stateHidden" value="2" />
+ <!-- Always make the soft input area hidden when this window
+ has input focus. -->
+ <flag name="stateAlwaysHidden" value="3" />
<!-- Make the soft input area visible when normally appropriate
(when the user is navigating forward to your window). -->
- <flag name="stateVisible" value="3" />
+ <flag name="stateVisible" value="4" />
<!-- Always make the soft input area visible when this window
has input focus. -->
- <flag name="stateAlwaysVisible" value="4" />
+ <flag name="stateAlwaysVisible" value="5" />
<!-- The window resize/pan adjustment has not been specified,
the system will automatically select between resize and pan
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index f717196..2ff0962 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -170,6 +170,12 @@
user ID, they must also be signed with the same signature. -->
<attr name="sharedUserId" format="string" />
+ <!-- Specify a label for the shared user UID of this package. This is
+ only used if you have also used android:sharedUserId. This must
+ be a reference to a string resource; it can not be an explicit
+ string. -->
+ <attr name="sharedUserLabel" format="reference" />
+
<!-- Internal version code. This is the number used to determine whether
one version is more recent than another: it has no other meaning than
that higher numbers are more recent. You could use this number to
@@ -579,6 +585,7 @@
<attr name="versionCode" />
<attr name="versionName" />
<attr name="sharedUserId" />
+ <attr name="sharedUserLabel" />
</declare-styleable>
<!-- The <code>application</code> tag describes application-level components
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 9175f31..e6b0ff7 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1004,6 +1004,7 @@
<public type="attr" name="hapticFeedbackEnabled" id="0x0101025e" />
<public type="attr" name="innerRadius" id="0x0101025f" />
<public type="attr" name="thickness" id="0x01010260" />
+ <public type="attr" name="sharedUserLabel" id="0x01010261" />
<!-- The part of the UI shown by an
{@link android.inputmethodservice.InputMethodService} that contains the
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 1174996..7adf542 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -243,6 +243,9 @@
<!-- Displayed to the user to tell them that they have started up the phone in "safe mode" -->
<string name="safeMode">Safe mode</string>
+ <!-- Label for the Android system components when they are shown to the user. -->
+ <string name="android_system_label">Android System</string>
+
<!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgrouplab_costMoney">Services that cost you money</string>
<!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
@@ -2265,6 +2268,3 @@
<!-- Shown in the tutorial for double tap to zoom. -->
<string name="tutorial_double_tap_to_zoom_message_short">Double tap to zoom</string>
</resources>
-
-
-
diff --git a/data/sounds/Android.mk b/data/sounds/Android.mk
index dd0dcaa..9e3697f 100644
--- a/data/sounds/Android.mk
+++ b/data/sounds/Android.mk
@@ -64,9 +64,6 @@ ALL_PREBUILT += $(TARGET_OUT)/media/audio/ringtones/Ring_Synth_02.ogg
$(TARGET_OUT)/media/audio/ringtones/Ring_Synth_02.ogg : $(LOCAL_PATH)/Ring_Synth_02.ogg | $(ACP)
$(transform-prebuilt-to-target)
-ALL_PREBUILT += $(TARGET_OUT)/sounds/test.mid
-$(TARGET_OUT)/sounds/test.mid : $(LOCAL_PATH)/test.mid | $(ACP)
- $(transform-prebuilt-to-target)
#
# --- New Wave Labs ringtones
#
@@ -204,10 +201,6 @@ ALL_PREBUILT += $(TARGET_OUT)/media/audio/notifications/Voila.ogg
$(TARGET_OUT)/media/audio/notifications/Voila.ogg : $(LOCAL_PATH)/newwavelabs/Voila.ogg | $(ACP)
$(transform-prebuilt-to-target)
-ALL_PREBUILT += $(TARGET_OUT)/media/audio/ui/Effect_Tick.ogg
-$(TARGET_OUT)/media/audio/ui/Effect_Tick.ogg : $(LOCAL_PATH)/Effect_Tick.ogg | $(ACP)
- $(transform-prebuilt-to-target)
-
ALL_PREBUILT += $(TARGET_OUT)/media/audio/notifications/Beat_Box_Android.ogg
$(TARGET_OUT)/media/audio/notifications/Beat_Box_Android.ogg : $(LOCAL_PATH)/notifications/Beat_Box_Android.ogg | $(ACP)
$(transform-prebuilt-to-target)
@@ -223,3 +216,25 @@ $(TARGET_OUT)/media/audio/notifications/TaDa.ogg : $(LOCAL_PATH)/notifications/T
ALL_PREBUILT += $(TARGET_OUT)/media/audio/notifications/Tinkerbell.ogg
$(TARGET_OUT)/media/audio/notifications/Tinkerbell.ogg : $(LOCAL_PATH)/notifications/Tinkerbell.ogg | $(ACP)
$(transform-prebuilt-to-target)
+
+# UI effects
+ALL_PREBUILT += $(TARGET_OUT)/media/audio/ui/Effect_Tick.ogg
+$(TARGET_OUT)/media/audio/ui/Effect_Tick.ogg : $(LOCAL_PATH)/effects/Effect_Tick.ogg | $(ACP)
+ $(transform-prebuilt-to-target)
+
+ALL_PREBUILT += $(TARGET_OUT)/media/audio/ui/KeypressStandard.ogg
+$(TARGET_OUT)/media/audio/ui/KeypressStandard.ogg : $(LOCAL_PATH)/effects/KeypressStandard.ogg | $(ACP)
+ $(transform-prebuilt-to-target)
+
+ALL_PREBUILT += $(TARGET_OUT)/media/audio/ui/KeypressSpacebar.ogg
+$(TARGET_OUT)/media/audio/ui/KeypressSpacebar.ogg : $(LOCAL_PATH)/effects/KeypressSpacebar.ogg | $(ACP)
+ $(transform-prebuilt-to-target)
+
+ALL_PREBUILT += $(TARGET_OUT)/media/audio/ui/KeypressDelete.ogg
+$(TARGET_OUT)/media/audio/ui/KeypressDelete.ogg : $(LOCAL_PATH)/effects/KeypressDelete.ogg | $(ACP)
+ $(transform-prebuilt-to-target)
+
+ALL_PREBUILT += $(TARGET_OUT)/media/audio/ui/KeypressReturn.ogg
+$(TARGET_OUT)/media/audio/ui/KeypressReturn.ogg : $(LOCAL_PATH)/effects/KeypressReturn.ogg | $(ACP)
+ $(transform-prebuilt-to-target)
+
diff --git a/data/sounds/Effect_Tick.ogg b/data/sounds/effects/Effect_Tick.ogg
index c899a7d..c899a7d 100644
--- a/data/sounds/Effect_Tick.ogg
+++ b/data/sounds/effects/Effect_Tick.ogg
Binary files differ
diff --git a/data/sounds/effects/KeypressDelete.ogg b/data/sounds/effects/KeypressDelete.ogg
new file mode 100644
index 0000000..b35ea65
--- /dev/null
+++ b/data/sounds/effects/KeypressDelete.ogg
Binary files differ
diff --git a/data/sounds/effects/KeypressDelete.wav b/data/sounds/effects/KeypressDelete.wav
new file mode 100644
index 0000000..5903f7f
--- /dev/null
+++ b/data/sounds/effects/KeypressDelete.wav
Binary files differ
diff --git a/data/sounds/effects/KeypressReturn.ogg b/data/sounds/effects/KeypressReturn.ogg
new file mode 100644
index 0000000..1b0fd56
--- /dev/null
+++ b/data/sounds/effects/KeypressReturn.ogg
Binary files differ
diff --git a/data/sounds/effects/KeypressReturn.wav b/data/sounds/effects/KeypressReturn.wav
new file mode 100644
index 0000000..9558fcf
--- /dev/null
+++ b/data/sounds/effects/KeypressReturn.wav
Binary files differ
diff --git a/data/sounds/effects/KeypressSpacebar.ogg b/data/sounds/effects/KeypressSpacebar.ogg
new file mode 100644
index 0000000..5299337
--- /dev/null
+++ b/data/sounds/effects/KeypressSpacebar.ogg
Binary files differ
diff --git a/data/sounds/effects/KeypressSpacebar.wav b/data/sounds/effects/KeypressSpacebar.wav
new file mode 100644
index 0000000..1226a21
--- /dev/null
+++ b/data/sounds/effects/KeypressSpacebar.wav
Binary files differ
diff --git a/data/sounds/effects/KeypressStandard.ogg b/data/sounds/effects/KeypressStandard.ogg
new file mode 100644
index 0000000..8a152d1
--- /dev/null
+++ b/data/sounds/effects/KeypressStandard.ogg
Binary files differ
diff --git a/data/sounds/effects/KeypressStandard.wav b/data/sounds/effects/KeypressStandard.wav
new file mode 100644
index 0000000..0c9aa2a
--- /dev/null
+++ b/data/sounds/effects/KeypressStandard.wav
Binary files differ
diff --git a/data/sounds/test.mid b/data/sounds/testfiles/test.mid
index d4ead53..d4ead53 100755
--- a/data/sounds/test.mid
+++ b/data/sounds/testfiles/test.mid
Binary files differ
diff --git a/docs/html/_build_id.cs b/docs/html/_build_id.cs
deleted file mode 100644
index 139c216..0000000
--- a/docs/html/_build_id.cs
+++ /dev/null
@@ -1,2 +0,0 @@
-<?cs # appears on the right side of the blue bar at the bottom of every page
-?><div id="jd-build-id"> Build <?cs var:page.build ?> - <?cs var:page.now ?> </div>
diff --git a/docs/html/about.jd b/docs/html/about.jd
deleted file mode 100755
index a129916..0000000
--- a/docs/html/about.jd
+++ /dev/null
@@ -1,13 +0,0 @@
-about=true
-page.title=About
-@jd:body
-
- <div id="mainBodyFixed">
- <h2 id="searchTitle">About</h2>
- <img src="{@docRoot}assets/images/hr_gray_main.jpg" />
- <div><br /></div>
- <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
- <br /><br /><br /><br /><br /><br /><br /><br />
- <br /><br /><br /><br /><br /><br /><br /><br />
- <br /><br /><br /><br /><br /><br /><br /><br />
- </div> \ No newline at end of file
diff --git a/docs/html/goodies/index.jd b/docs/html/goodies/index.jd
deleted file mode 100644
index c126098..0000000
--- a/docs/html/goodies/index.jd
+++ /dev/null
@@ -1,85 +0,0 @@
-page.title=Goodies
-@jd:body
-
-<h1>Goodies</h1>
-
-<h2>Wallpaper</h2>
-
-<table class="columns">
- <tr>
- <td>
- <ul style="font-size: 85%; list-style: none; margin: 0 0 1em 0;">
- <li><img src="{@docRoot}goodies/wallpaper/android-wallpaper1_thumbnail.png" height="125" width="200" alt="Android Wallpaper #1"></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper1_1024x768.png">1024 x 768</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper1_1280x800.png">1280 x 800</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper1_1440x900.png">1440 x 900</a></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper1_1600x1200.png">1600 x 1200</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper1_1680x1050.png">1680 x 1050</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper1_1920x1200.png">1920 x 1200</a></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper1_2560x1600.png">2560 x 1600</a></li>
- </ul>
- </td>
- <td>
- <ul style="font-size: 85%; list-style: none; margin: 0 0 1em 0;">
- <li><img src="{@docRoot}goodies/wallpaper/android-wallpaper2_thumbnail.png" height="125" width="200" alt="Android Wallpaper #2"></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper2_1024x768.png">1024 x 768</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper2_1280x800.png">1280 x 800</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper2_1440x900.png">1440 x 900</a></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper2_1600x1200.png">1600 x 1200</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper2_1680x1050.png">1680 x 1050</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper2_1920x1200.png">1920 x 1200</a></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper2_2560x1600.png">2560 x 1600</a></li>
- </ul>
- </td>
- <td>
- <ul style="font-size: 85%; list-style: none; margin: 0 0 1em 0;">
- <li><img src="{@docRoot}goodies/wallpaper/android-wallpaper3_thumbnail.png" height="125" width="200" alt="Android Wallpaper #3"></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper3_1024x768.png">1024 x 768</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper3_1280x800.png">1280 x 800</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper3_1440x900.png">1440 x 900</a></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper3_1600x1200.png">1600 x 1200</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper3_1680x1050.png">1680 x 1050</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper3_1920x1200.png">1920 x 1200</a></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper3_2560x1600.png">2560 x 1600</a></li>
- </ul>
- </td>
- <tr>
- </tr>
- <td>
- <ul style="font-size: 85%; list-style: none; margin: 0 0 1em 0;">
- <li><img src="{@docRoot}goodies/wallpaper/android-wallpaper4_thumbnail.png" height="125" width="200" alt="Android Wallpaper #4"></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper4_1024x768.png">1024 x 768</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper4_1280x800.png">1280 x 800</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper4_1440x900.png">1440 x 900</a></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper4_1600x1200.png">1600 x 1200</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper4_1680x1050.png">1680 x 1050</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper4_1920x1200.png">1920 x 1200</a></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper4_2560x1600.png">2560 x 1600</a></li>
- </ul>
- </td>
- <td>
- <ul style="font-size: 85%; list-style: none; margin: 0 0 1em 0;">
- <li><img src="{@docRoot}goodies/wallpaper/android-wallpaper5_thumbnail.jpg" height="125" width="200" alt="Android Wallpaper #5"></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper5_1024x768.jpg">1024 x 768</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper5_1280x800.jpg">1280 x 800</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper5_1440x900.jpg">1440 x 900</a></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper5_1600x1200.jpg">1600 x 1200</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper5_1680x1050.jpg">1680 x 1050</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper5_1920x1200.jpg">1920 x 1200</a></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper5_2560x1600.jpg">2560 x 1600</a></li>
- </ul>
- </td>
- <td>
- <ul style="font-size: 85%; list-style: none; margin: 0 0 1em 0;">
- <li><img src="{@docRoot}goodies/wallpaper/android-wallpaper6_thumbnail.jpg" height="125" width="200" alt="Android Wallpaper #6"></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper6_1024x768.jpg">1024 x 768</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper6_1280x800.jpg">1280 x 800</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper6_1440x900.jpg">1440 x 900</a></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper6_1600x1200.jpg">1600 x 1200</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper6_1680x1050.jpg">1680 x 1050</a> / <a href="{@docRoot}goodies/wallpaper/android-wallpaper6_1920x1200.jpg">1920 x 1200</a></li>
- <li><a href="{@docRoot}goodies/wallpaper/android-wallpaper6_2560x1600.jpg">2560 x 1600</a></li>
- </ul>
- </td>
- </tr>
-</table>
-
-<br>
-
-<div class="notice"><div id="notice" style="text-align: center; border: 1em 0em 1em 0em">
- Except as otherwise <a
- href="http://code.google.com/policies.html#restrictions">noted</a>,
- the content of this page is licensed under the <a rel="license"
- href="http://creativecommons.org/licenses/by/3.0/">Creative Commons
- Attribution 3.0 License</a>.
-<!-- <rdf:RDF xmlns="http://web.resource.org/cc/"
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <Work rdf:about="">
- <license rdf:resource="http://creativecommons.org/licenses/by/3.0/" />
- </Work>
- <License rdf:about="http://creativecommons.org/licenses/by/3.0/">
- <permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
- <permits rdf:resource="http://web.resource.org/cc/Distribution"/>
- <requires rdf:resource="http://web.resource.org/cc/Notice"/>
- <requires rdf:resource="http://web.resource.org/cc/Attribution"/>
- <permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
- </License>
-</rdf:RDF> -->
-</div>
diff --git a/docs/html/goodies/wallpaper/android-wallpaper1_1024x768.png b/docs/html/goodies/wallpaper/android-wallpaper1_1024x768.png
deleted file mode 100644
index f33b16c..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper1_1024x768.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper1_1280x800.png b/docs/html/goodies/wallpaper/android-wallpaper1_1280x800.png
deleted file mode 100644
index 391eb1a..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper1_1280x800.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper1_1440x900.png b/docs/html/goodies/wallpaper/android-wallpaper1_1440x900.png
deleted file mode 100644
index dcc49b5..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper1_1440x900.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper1_1600x1200.png b/docs/html/goodies/wallpaper/android-wallpaper1_1600x1200.png
deleted file mode 100644
index 3799bd7..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper1_1600x1200.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper1_1680x1050.png b/docs/html/goodies/wallpaper/android-wallpaper1_1680x1050.png
deleted file mode 100644
index 7ed9dca..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper1_1680x1050.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper1_1920x1200.png b/docs/html/goodies/wallpaper/android-wallpaper1_1920x1200.png
deleted file mode 100644
index 74b937c..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper1_1920x1200.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper1_2560x1600.png b/docs/html/goodies/wallpaper/android-wallpaper1_2560x1600.png
deleted file mode 100644
index 1fa8446..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper1_2560x1600.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper1_thumbnail.png b/docs/html/goodies/wallpaper/android-wallpaper1_thumbnail.png
deleted file mode 100644
index 7c9b435..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper1_thumbnail.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper2_1024x768.png b/docs/html/goodies/wallpaper/android-wallpaper2_1024x768.png
deleted file mode 100644
index d3613e9..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper2_1024x768.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper2_1280x800.png b/docs/html/goodies/wallpaper/android-wallpaper2_1280x800.png
deleted file mode 100644
index f0ef459..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper2_1280x800.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper2_1440x900.png b/docs/html/goodies/wallpaper/android-wallpaper2_1440x900.png
deleted file mode 100644
index 99b71f9..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper2_1440x900.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper2_1600x1200.png b/docs/html/goodies/wallpaper/android-wallpaper2_1600x1200.png
deleted file mode 100644
index 4e145e7..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper2_1600x1200.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper2_1680x1050.png b/docs/html/goodies/wallpaper/android-wallpaper2_1680x1050.png
deleted file mode 100644
index eeb7508..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper2_1680x1050.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper2_1920x1200.png b/docs/html/goodies/wallpaper/android-wallpaper2_1920x1200.png
deleted file mode 100644
index ecabf82..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper2_1920x1200.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper2_2560x1600.png b/docs/html/goodies/wallpaper/android-wallpaper2_2560x1600.png
deleted file mode 100644
index cae1607..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper2_2560x1600.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper2_thumbnail.png b/docs/html/goodies/wallpaper/android-wallpaper2_thumbnail.png
deleted file mode 100644
index cac05de..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper2_thumbnail.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper3_1024x768.png b/docs/html/goodies/wallpaper/android-wallpaper3_1024x768.png
deleted file mode 100644
index 18ccd88..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper3_1024x768.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper3_1280x800.png b/docs/html/goodies/wallpaper/android-wallpaper3_1280x800.png
deleted file mode 100644
index dffd997..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper3_1280x800.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper3_1440x900.png b/docs/html/goodies/wallpaper/android-wallpaper3_1440x900.png
deleted file mode 100644
index b62cae9..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper3_1440x900.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper3_1600x1200.png b/docs/html/goodies/wallpaper/android-wallpaper3_1600x1200.png
deleted file mode 100644
index 7f4409b..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper3_1600x1200.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper3_1680x1050.png b/docs/html/goodies/wallpaper/android-wallpaper3_1680x1050.png
deleted file mode 100644
index 5828234c..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper3_1680x1050.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper3_1920x1200.png b/docs/html/goodies/wallpaper/android-wallpaper3_1920x1200.png
deleted file mode 100644
index 7e33515..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper3_1920x1200.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper3_2560x1600.png b/docs/html/goodies/wallpaper/android-wallpaper3_2560x1600.png
deleted file mode 100644
index d948b4e..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper3_2560x1600.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper3_thumbnail.png b/docs/html/goodies/wallpaper/android-wallpaper3_thumbnail.png
deleted file mode 100644
index abd2c92..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper3_thumbnail.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper4_1024x768.png b/docs/html/goodies/wallpaper/android-wallpaper4_1024x768.png
deleted file mode 100644
index 536056d..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper4_1024x768.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper4_1280x800.png b/docs/html/goodies/wallpaper/android-wallpaper4_1280x800.png
deleted file mode 100644
index ba87529..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper4_1280x800.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper4_1440x900.png b/docs/html/goodies/wallpaper/android-wallpaper4_1440x900.png
deleted file mode 100644
index aa88c61..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper4_1440x900.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper4_1600x1200.png b/docs/html/goodies/wallpaper/android-wallpaper4_1600x1200.png
deleted file mode 100644
index cf10a81..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper4_1600x1200.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper4_1680x1050.png b/docs/html/goodies/wallpaper/android-wallpaper4_1680x1050.png
deleted file mode 100644
index 00d19fc..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper4_1680x1050.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper4_1920x1200.png b/docs/html/goodies/wallpaper/android-wallpaper4_1920x1200.png
deleted file mode 100644
index 3df19a9..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper4_1920x1200.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper4_2560x1600.png b/docs/html/goodies/wallpaper/android-wallpaper4_2560x1600.png
deleted file mode 100644
index 4d693ef..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper4_2560x1600.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper4_thumbnail.png b/docs/html/goodies/wallpaper/android-wallpaper4_thumbnail.png
deleted file mode 100644
index f1a1841..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper4_thumbnail.png
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper5_1024x768.jpg b/docs/html/goodies/wallpaper/android-wallpaper5_1024x768.jpg
deleted file mode 100644
index 68bdee83..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper5_1024x768.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper5_1280x800.jpg b/docs/html/goodies/wallpaper/android-wallpaper5_1280x800.jpg
deleted file mode 100644
index fc441b8..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper5_1280x800.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper5_1440x900.jpg b/docs/html/goodies/wallpaper/android-wallpaper5_1440x900.jpg
deleted file mode 100644
index 7f6bde8..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper5_1440x900.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper5_1600x1200.jpg b/docs/html/goodies/wallpaper/android-wallpaper5_1600x1200.jpg
deleted file mode 100644
index bb577bb..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper5_1600x1200.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper5_1680x1050.jpg b/docs/html/goodies/wallpaper/android-wallpaper5_1680x1050.jpg
deleted file mode 100644
index d28b06b..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper5_1680x1050.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper5_1920x1080.jpg b/docs/html/goodies/wallpaper/android-wallpaper5_1920x1080.jpg
deleted file mode 100644
index 7239e51..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper5_1920x1080.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper5_1920x1200.jpg b/docs/html/goodies/wallpaper/android-wallpaper5_1920x1200.jpg
deleted file mode 100644
index 862b5b6..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper5_1920x1200.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper5_2560x1600.jpg b/docs/html/goodies/wallpaper/android-wallpaper5_2560x1600.jpg
deleted file mode 100644
index 7fc9a08..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper5_2560x1600.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper5_thumbnail.jpg b/docs/html/goodies/wallpaper/android-wallpaper5_thumbnail.jpg
deleted file mode 100644
index 99f22f7..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper5_thumbnail.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper6_1024x768.jpg b/docs/html/goodies/wallpaper/android-wallpaper6_1024x768.jpg
deleted file mode 100644
index 2074065..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper6_1024x768.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper6_1280x800.jpg b/docs/html/goodies/wallpaper/android-wallpaper6_1280x800.jpg
deleted file mode 100644
index d0fe49c..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper6_1280x800.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper6_1440x900.jpg b/docs/html/goodies/wallpaper/android-wallpaper6_1440x900.jpg
deleted file mode 100644
index 52d3b4f..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper6_1440x900.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper6_1600x1200.jpg b/docs/html/goodies/wallpaper/android-wallpaper6_1600x1200.jpg
deleted file mode 100644
index b1b151e..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper6_1600x1200.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper6_1680x1050.jpg b/docs/html/goodies/wallpaper/android-wallpaper6_1680x1050.jpg
deleted file mode 100644
index d0f9c63..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper6_1680x1050.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper6_1920x1200.jpg b/docs/html/goodies/wallpaper/android-wallpaper6_1920x1200.jpg
deleted file mode 100644
index 730ef98..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper6_1920x1200.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper6_2560x1600.jpg b/docs/html/goodies/wallpaper/android-wallpaper6_2560x1600.jpg
deleted file mode 100644
index eb80b5c..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper6_2560x1600.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/goodies/wallpaper/android-wallpaper6_thumbnail.jpg b/docs/html/goodies/wallpaper/android-wallpaper6_thumbnail.jpg
deleted file mode 100644
index eabfe71..0000000
--- a/docs/html/goodies/wallpaper/android-wallpaper6_thumbnail.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/googleb38c1d60b7ba5d19.html b/docs/html/googleb38c1d60b7ba5d19.html
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/docs/html/googleb38c1d60b7ba5d19.html
diff --git a/docs/html/guide/developing/device.jd b/docs/html/guide/developing/device.jd
index 034f707..35c0a1a 100644
--- a/docs/html/guide/developing/device.jd
+++ b/docs/html/guide/developing/device.jd
@@ -42,7 +42,7 @@ href="http://www.t-mobileg1.com">T-Mobile G1 site</a>. </p>
<h3 id="dev-phone-1">Android Dev Phone 1</h3>
<div class="sidebox-wrapper">
-<div class="sidebox">
+<div class="sidebox-inner">
<p>Selected specs for Android Dev Phone 1:</p>
<ul>
<li>Touch screen</li>
diff --git a/docs/html/guide/developing/instrumentation/inst-testing.jd b/docs/html/guide/developing/instrumentation/inst-testing.jd
deleted file mode 100644
index 2dc4daa..0000000
--- a/docs/html/guide/developing/instrumentation/inst-testing.jd
+++ /dev/null
@@ -1,205 +0,0 @@
-
-page.title=Instrumentation Testing
-@jd:body
-
-<p>Sometimes you may want to manually interact with your applications to verify that a particular feature or behavior is working properly; why not automate this verification with a JUnit TestCase that can instrument applications?</p>
-<p>Instrumentation testing allows you to verify a particular feature or behavior with an automated JUnit TestCase. You can launch activities and providers within an application, send key events, and make assertions about various UI elements.</p>
-
-This document provides an overview of how to use instrumentation on Android and covers these topics:
-
-<ul>
-<li><a href="#androidInstrumentationTestingClasses">Classes</a></li>
-<li><a href="#androidInstrumentationTestingRunning">Running Tests</a></li>
-<li><a href="#androidInstrumentationTestingCreating">Creating Tests</a></li>
-<li><a href="#androidInstrumentationAliases">Aliases for Running Framework Instrumentation Tests</a></li>
-</ul>
-
-
-
-
-<a name="androidInstrumentationTestingClasses"></a><h2>Classes</h2>
-
-<p> The following classes help glue together <code>Instrumentation</code> with JUnit testing. </p>
-<table>
- <tr>
- <th scope="col">Class</th>
- <th scope="col">Description</th></tr>
- <tr>
- <td valign="top"><code>InstrumentationTestCase</code></td>
- <td valign="top">
- <p>This extends the standard JUnit <code>TestCase</code> and offers access to an <code>Instrumentation</code> class. Write tests inside your instrumentation class any way you see fit. For example, your test might launch activities and send key events. For this to work properly, the instrumentation needs to be injected into the test case.</p>
- </td>
- </tr>
- <tr>
- <td valign="top"><code>InstrumentationTestRunner</code></td>
- <td valign="top">The instrumentation test runner is an instrumentation that runs instrumentation test cases and injects itself into each test case. Instrumentation test cases need to be grouped together with an instrumentation test runner with the appropriate target package.</td>
- </tr>
- <tr>
- <td valign="top"><code>InstrumentationTestSuite</code></td>
- <td valign="top">The instrumentation test suite is a simple extension of the standard JUnit <code>TestSuite</code> that keeps a member <code>Instrumentation</code> variable on hand to inject into each <code>TestCase</code> before running them. It is used by <code>InstrumentationTestRunner</code>.</td>
- </tr>
-</table>
-<p> Three additional base classes extend <code>InstrumentationTestCase</code> to allow you to test <code>Activity</code> and <code>Provider</code> classes:</p>
-<table>
- <tr>
- <th scope="col">Class</th>
- <th scope="col">Description</th>
- </tr>
- <tr>
- <td valign="top"><code>ActivityTestCase</code></td>
- <td valign="top"><p>This class can be used to write tests for a specific activity. An activity is launched in its <code>setUp()</code> method and finished with <code>tearDown</code>. If you write a test case that extends <code>ActivityTestCase</code>, you can write tests that access the activity using <code>getActivity()</code> and assume it has been set up properly.</p></td>
- </tr>
- <tr>
- <td valign="top"><code>SingleLaunchActivityTestCase</code></td>
- <td valign="top">This class is similar to <code>ActivityTestCase</code> except that the activity is launched once per class instead of every time the test case calls setup. </td>
- </tr>
- <tr>
- <td valign="top"><code>ProviderTestCase</code></td>
- <td valign="top">This class is similar to <code>ActivityTestCase</code> except that it will setup, tear down, and provide access to the <code>Provider</code> of your choice.</td>
- </tr>
-</table>
-
-
-<a name="androidInstrumentationTestingRunning"></a><h2>Running Tests</h2>
-
-<p> To run your tests, use the <code>am instrument</code> command with your <code>InstrumentationTestRunner</code> as its argument. Results are printed as a result of the instrumentation. For example, the following snippet displays the output after running the framework tests with one test failing (note the unusual syntax caused by how instrumentations are run via <code>am</code>):</p>
-<pre class="prettify">
-$ adb shell am instrument -w com.google.android.frameworktest/.tests.FrameworkInstrumentationTestRunner
-INSTRUMENTATION_RESULT: test results:=.......F.......
-Time: 6.837
-There was 1 failure:
-1) testSetUpConditions(com.google.android.frameworktest.tests.focus.RequestFocusTest)junit.framework.AssertionFailedError: requestFocus() should work from onCreate.
- at com.google.android.frameworktest.tests.focus.RequestFocusTest.testSetUpConditions(RequestFocusTest.java:66)
- at java.lang.reflect.Method.invokeNative(Native Method)
- at android.test.InstrumentationTestSuite.runTest(InstrumentationTestSuite.java:73)
- at android.test.InstrumentationTestSuite.runTest(InstrumentationTestSuite.java:73)
- at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:151)
- at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1088)
-
-FAILURES!!!
-Tests run: 14, Failures: 1, Errors: 0
-
-&lt;RETURN&gt; to continue
-
-INSTRUMENTATION_CODE: -1
-$
-</pre>
-
-
-<a name="androidInstrumentationTestingRunningAll"></a><h3>All Tests</h3>
-
-<pre class="prettify">
-$ adb shell am instrument -w MyInstrumentationTestRunner
-</pre>
-
-
-<a name="androidInstrumentationTestingRunningSingleTestCase"></a><h3>A Single Test Case</h3>
-
-<pre class="prettify">
-$ adb shell am instrument \
- -e class MyInstrumentationTestCase \
- -w MyInstrumentationTestRunner
-</pre>
-
-
-<a name="androidInstrumentationTestingRunningSingleTest"></a><h3>A Single Test</h3>
-
-<pre class="prettify">
-$ adb shell am instrument \
- -e class MyInstrumentationTestCase#myTestMethod \
- -w MyInstrumentationTestRunner
-</pre>
-
-
-<a name="androidInstrumentationTestingCreating"></a><h2>Creating Tests</h2>
-
-
-
-<a name="androidInstrumentationTestingCreatingTestRunner"></a>
-
-<h3>New Instrumentation TestRunner</h3>
-
-<pre>
-public class FrameworkInstrumentationTestRunner extends InstrumentationTestRunner {
-
- &#64;Override
- public TestSuite getAllTests() {
- InstrumentationTestSuite suite = new InstrumentationTestSuite(this);
-
- suite.addTestSuite(FocusAfterRemovalTest.class);
- suite.addTestSuite(RequestFocusTest.class);
- suite.addTestSuite(RequestRectangleVisibleTest.class);
- return suite;
- }
-
- &#64;Override
- public ClassLoader getLoader() {
- return FrameworkInstrumentationTestRunner.class.getClassLoader();
- }
-}
-</pre>
-
-<p> Next, in an appropriate <code>AndroidManifest.xml</code>, define the instrumentation for the derived class with the appropriate <code>android:targetPackage</code> set. For example, the snippet below defines the instrumentation runner for the framework tests.</p>
-
-<pre>
-&lt;instrumentation android:name="android.tests.FrameworkInstrumentationTestRunner"
- android:targetPackage="com.google.android.frameworktest"
- android:label="framework instrumentation test runner" /&gt;
-</pre>
-
-
-<a name="androidInstrumentationTestingCreatingTestCase"></a>
-
-<h3>New InstrumentationTestCase</h3>
-
-<p> To create a new test case, write a class that extends <code>InstrumentationTestCase</code> in the same application archive as your test runner. The following snippet illustrates an example <code>ActivityTestCase</code> that tests an activity named <code>MyActivity</code>.</p>
-<pre>
-public class ButtonPressTest extends ActivityTestCase&lt;MyActivity&gt; {
-
- Button mLeftButton;
-
- public ButtonPressTest() {
- super("com.example", MyActivity.class);
- }
-
- &#64;Override
- public void setUp() throws Exception {
- super.setUp();
- mLeftButton = (Button) getActivity().findViewById(R.id.leftButton);
- }
-
- public void testFocusMovesToRight() throws Exception {
- assertTrue(mLeftButton.hasFocus());
- getInstrumentation().sendCharacterSync(KeyEvent.KEYCODE_DPAD_RIGHT);
-
- Button rightButton = (Button) getActivity().findViewById(R.id.rightButton);
- assertTrue(rightButton.hasFocus());
- }
-
- // could have several more tests...
-}
-</pre>
-
-
-<a name="androidInstrumentationAliases"></a><h2>Aliases for Running Framework Instrumentation Tests</h2>
-
-<pre class="prettify">
-# compiles and installs FrameworkTests
-alias deploytests="(cd tests/FrameworkTests/ && mm) && adb install out/target/product/dream/system/app/FrameworkTest.apk"
-
-# runs all of FrameworkTests unit tests
-alias runtests="adb shell am instrument -w com.google.android.frameworktest/.tests.FrameworkInstrumentationTestRunner"
-
-# runtest TEST: runs a single unit test, for instance runtest view.VisibilityTest
-# -- for convenience, you don't have to type the com.google.android.frameworktest.tests.
-function runtest {
- adb shell am instrument -e class com.google.android.frameworktest.tests.$1 -w com.google.android.frameworktest/.tests.FrameworkInstrumentationTestRunner
-}
-
-# debugtest TEST: runs a single unit test in debug mode, for instance runtest view.VisibilityTest
-function debugtest {
- adb shell am instrument -e debug true -e class com.google.android.frameworktest.tests.$1 -w com.google.android.frameworktest/.tests.FrameworkInstrumentationTestRunner
-}
-</pre>
-
-
diff --git a/docs/html/guide/developing/tools/emulator.jd b/docs/html/guide/developing/tools/emulator.jd
index dd367b7..769491b 100644
--- a/docs/html/guide/developing/tools/emulator.jd
+++ b/docs/html/guide/developing/tools/emulator.jd
@@ -812,7 +812,7 @@ in the default directory, or in a custom location (if you specified a path with
<tr>
<td><code>userdata-qemu.img</code></td>
<td>An image to which the emulator writes runtime user-data for a unique user.</td>
- <td>Override using <code>-data &lt;;filepath&gt;</code>, where <code>&lt;filepath&gt;</code> is the
+ <td>Override using <code>-data &lt;filepath&gt;</code>, where <code>&lt;filepath&gt;</code> is the
path the image, relative to the current working directory. If you supply a filename only,
the emulator looks for the file in the current working directory. If the file at <code>&lt;filepath&gt;</code> does
not exist, the emulator creates an image from the default userdata.img, stores it under the name you
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index ee56ebb..77d3522 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -34,7 +34,7 @@
<li><a href="<?cs var:toroot ?>guide/topics/resources/available-resources.html">Available Resource Types</a></li>
</ul>
</li>
- <li><a href="<?cs var:toroot ?>guide/topics/intents/intents-filters.html">Intents and Intent Filtering</a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/intents/intents-filters.html">Intents and Intent Filters</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/data/data-storage.html">Data Storage</a></li>
<li><a href="<?cs var:toroot ?>guide/topics/providers/content-providers.html">Content Providers</a></li>
<!-- <li><a style="color:gray;">Notifications</a></li> -->
@@ -147,15 +147,30 @@
</ul>
</li>
-<li><h2>Tutorials</h2>
+<li><h2>Tutorials and Sample Code</h2>
<ul>
<li><a href="<?cs var:toroot ?>guide/tutorials/hello-world.html">Hello World</a></li>
<li><a href="<?cs var:toroot ?>guide/tutorials/views/index.html">Hello Views</a></li>
- <li><a href="<?cs var:toroot ?>guide/tutorials/notepad/index.html">Notepad</a></li>
- <li><a href="<?cs var:toroot ?>guide/samples/index.html">Sample Code</a></li>
+ <li><a href="<?cs var:toroot ?>guide/tutorials/notepad/index.html">Notepad Tutorial</a></li>
+ </ul>
+ <ul>
+ <?cs if:android.whichdoc != "online" ?>
+ <li><a href="<?cs var:toroot ?>../samples">Sample Code &raquo;</a></li>
+ <?cs else ?>
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>guide/samples/index.html">Sample Code</a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>guide/samples/ApiDemos/index.html">API Demos</a></li>
+ <li><a href="<?cs var:toroot ?>guide/samples/LunarLander/index.html">Lunar Lander</a></li>
+ <li><a href="<?cs var:toroot ?>guide/samples/NotePad/index.html">NotePad</a></li>
+ </ul>
+ </li>
+ <?cs /if ?>
</ul>
</li>
+
+
<li><h2>Appendix</h2>
<ul>
<li><a href="<?cs var:toroot ?>guide/appendix/media-formats.html">Supported Media Formats</a></li>
diff --git a/docs/html/guide/publishing/preparing.jd b/docs/html/guide/publishing/preparing.jd
index 267cba2..4db546d 100644
--- a/docs/html/guide/publishing/preparing.jd
+++ b/docs/html/guide/publishing/preparing.jd
@@ -94,12 +94,12 @@ orientation changes. </li>
</ul>
<h3 id="eula">2. Consider adding an End User License Agreement in your
-application</h4>
+application</h3>
<p>To protect your person, organization, and intellectual property, you may want
to provide an End User License Agreement (EULA) with your application.
-<h3 id="iconlabel">3. Specify an icon and label in the application's manifest</h4>
+<h3 id="iconlabel">3. Specify an icon and label in the application's manifest</h3>
<p>The icon and label that you specify in an application's manifest are
important because they are displayed to users as your application's icon and
@@ -114,7 +114,7 @@ display the icon and label to users. </p>
<p>As regards the design of your icon, you should try to make it match as much
as possible the style used by the built-in Android applications.</p>
-<h3 id="logging">4. Turn off logging and debugging and clean up data/files</h4>
+<h3 id="logging">4. Turn off logging and debugging and clean up data/files</h3>
<p>For release, you should make sure that debug facilities are turned off and
that debug and other unnecessary data/files are removed from your application
@@ -129,9 +129,9 @@ application project.</li>
code.</li>
</ul>
-<h2 id="finalcompile">Before you do the final compile of your application</h3>
+<h2 id="finalcompile">Before you do the final compile of your application</h2>
-<h3 id="versionapp">5. Version Your Application</h4>
+<h3 id="versionapp">5. Version Your Application</h3>
<p>Before you compile your application, you must make sure that you have defined
a version number for your application, specifying an appropriate value for both
@@ -149,7 +149,7 @@ element in the application's manifest file, using appropriate values. </p>
<p>For detailed information about how to define version information for your
application, see <a href="{@docRoot}guide/publishing/versioning.html">Versioning Your Applications</a>.</p>
-<h3 id="cryptokey">6. Obtain a suitable cryptographic key</h4>
+<h3 id="cryptokey">6. Obtain a suitable cryptographic key</h3>
<p>If you have read and followed all of the preparation steps up to this point,
your application is compiled and ready for signing. Inside the .apk, the
@@ -222,20 +222,20 @@ to download Maps data. </li>
href="#signing">Signing Your Applications</a>.</p>
-<h2 id="compile">Compile Your Application</h3>
+<h2 id="compile">Compile Your Application</h2>
<p>When you've prepared your application as described in the previous sections,
you can compile your application for release. </p>
-<h2 id="post-compile">After Compiling Your Application</h3>
+<h2 id="post-compile">After Compiling Your Application</h2>
-<h3 id="signapp">8. Sign Your Application</h4>
+<h3 id="signapp">8. Sign Your Application</h3>
<p>Sign your application using your private key. Signing your application
correctly is critically important. Please see <a href="#signing">Signing Your
Applications</a> for complete information. </p>
-<h3 id="testapp">9. Test Your Compiled and Signed Application</h4>
+<h3 id="testapp">9. Test Your Compiled and Signed Application</h3>
<p>Before you release your compiled application, you should thoroughly test it
on the target mobile device (and target network, if possible). In particular,
diff --git a/docs/html/guide/publishing/versioning.jd b/docs/html/guide/publishing/versioning.jd
index d106266..d0eafcd 100644
--- a/docs/html/guide/publishing/versioning.jd
+++ b/docs/html/guide/publishing/versioning.jd
@@ -125,7 +125,7 @@ applications use the
{@link android.content.pm.PackageManager#getPackageInfo(java.lang.String, int)}
method of {@link android.content.pm.PackageManager PackageManager}. </p>
-<h2 id="#minsdkversion">Specifying Minimum System API Version</h2>.
+<h2 id="minsdkversion">Specifying Minimum System API Version</h2>
<p>If your application requires a specific minimum version of the Android
platform, you can specify that version as an API Level identifier
@@ -152,4 +152,4 @@ that your application is compatible with all platform versions.</p></li>
<code>&lt;manifest&gt;</code>, then define the
<code>android:minSdkVersion</code> as an attribute. </p>
-<p>For more information, also see the <a href="{@docRoot}sdk/android-1.1.html">Android System Image 1.1 Version Notes</a>.</p> \ No newline at end of file
+<p>For more information, also see the <a href="{@docRoot}sdk/android-1.1.html">Android System Image 1.1 Version Notes</a>.</p>
diff --git a/docs/html/guide/samples/index.jd b/docs/html/guide/samples/index.jd
index c2dbb48..4e665fa 100644
--- a/docs/html/guide/samples/index.jd
+++ b/docs/html/guide/samples/index.jd
@@ -1,11 +1,17 @@
guide=true
-page.title=Android Samples
+page.title=Sample Code
@jd:body
-<p>Sometimes, the best way to learn how things are done is to just look at some code.
-So here we've provided the source code for some simple Android applications.</p>
+<p>Sometimes, the best way to learn how things are done is to just look at some code. So here
+ we've provided links to let you browse the source of some some simple Android applications. </p>
+<p>The source code for these applications is included in the Android SDK, in this location:</p>
+
+<p style="margin-left:2em"><code>&lt;sdk&gt;/samples/</code></p>
+
+<p>You can easily add these applications as projects in your development environment, so that you
+can modify them and watch them execute. </p>
<dl>
<dt><a href="ApiDemos/index.html">API Demos</a></dt>
<dd>A variety of small applications that demonstrate simple views and widgets.</dd>
@@ -14,4 +20,4 @@ So here we've provided the source code for some simple Android applications.</p>
<dt><a href="NotePad/index.html">Note Pad</a></dt>
<dd>An application for saving notes. Similar (but not identical) to the
<a href="{@docRoot}guide/tutorials/notepad/index.html">Notepad tutorial</a>.</dd>
-</dl> \ No newline at end of file
+</dl>
diff --git a/docs/html/guide/topics/fundamentals.jd b/docs/html/guide/topics/fundamentals.jd
index 3e1501c..3c7f419 100644
--- a/docs/html/guide/topics/fundamentals.jd
+++ b/docs/html/guide/topics/fundamentals.jd
@@ -42,6 +42,7 @@ page.title=Application Fundamentals
<li><a href="#broadlife">Broadcast receiver lifecycle</a></li>
<li><a href="#proclife">Processes and lifecycles</a></li>
</ol></li>
+</ol>
</div>
</div>
@@ -401,7 +402,7 @@ components. For example, an activity might be declared as follows:
&lt;/activity&gt;
. . .
&lt;/application&gt;
-&lt/manifest&gt;</pre>
+&lt;/manifest&gt;</pre>
<p>
The {@code name} attribute of the
@@ -469,7 +470,7 @@ two intent filters to the activity:
&lt;/activity&gt;
. . .
&lt;/application&gt;
-&lt/manifest&gt;</pre>
+&lt;/manifest&gt;</pre>
<p>
The first filter in the example &mdash; the combination of the action
@@ -769,9 +770,9 @@ return to what that instance was doing before the new intent arrived.
</p>
<p>
-For more on launch modes, see
-<a href="{@docRoot}guide/topics/manifest/manifest-intro.html">The
-AndroidManifest.xml File</a>
+For more on launch modes, see the description of the
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+element.
</p>
@@ -792,19 +793,25 @@ control this behavior and modify it:
</p>
<dl>
-<dt>The {@code alwaysRetainTaskState} attribute</dt>
+<dt>The <code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html#always">alwaysRetainTaskState</a></code>
+attribute</dt>
<dd>If this attribute is set to "{@code true}" in the root activity of a task,
the default behavior just described does not happen.
The task retains all activities in its stack even after a long period.</dd>
-<dt>The {@code clearTaskOnLaunch} attribute</dt>
+<dt>The <code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code>
+attribute</dt>
<dd>If this attribute is set to "{@code true}" in the root activity of a task,
the stack is cleared down to the root activity whenever the user leaves the task
and returns to it. In other words, it's the polar opposite of
{@code alwaysRetainTaskState}. The user always returns to the task in its
initial state, even after a momentary absence.</dd>
-<dt>The {@code finishOnTaskLaunch} attribute</dt>
+<dt>The <code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html#finish">finishOnTaskLaunch</a></code>
+attribute</dt>
<dd>This attribute is like {@code clearTaskOnLaunch}, but it operates on a
single activity, not an entire task. And it can cause any activity to go
away, including the root activity. When it's set to "{@code true}", the
@@ -999,7 +1006,7 @@ in the following diagram:
</p>
<p style="margin-left: 2em">
-<img src="{@docRoot}images/binder_rpc.png" alt="RPC mechanism." border="0" />
+<img src="{@docRoot}images/binder_rpc.png" alt="RPC mechanism." />
</p>
<p>
@@ -1173,7 +1180,7 @@ to commit data changes and otherwise prepare to stop interacting with the user.
</p>
<div class="sidebox-wrapper">
-<div class="sidebox">
+<div class="sidebox-inner">
<h2>Calling into the superclass</h2>
<p>
An implementation of any activity lifecycle method should always first
@@ -1235,18 +1242,18 @@ to perform operations when the activity transitions between states.
<p>
<p style="margin-left: 2em"><img src="{@docRoot}images/activity_lifecycle.png"
-alt="State diagram for an Android activity lifecycle." border="0" /></p>
+alt="State diagram for an Android activity lifecycle." /></p>
<p>
The following table describes each of these methods in more detail and
locates it within the activity's overall lifecycle:
</p>
-<table border="2" width="85%" align="center" frame="hsides" rules="rows">
-<colgroup align="left" span="3" />
-<colgroup align="left" />
-<colgroup align="center" />
-<colgroup align="center" />
+<table border="2" width="85%" frame="hsides" rules="rows">
+<colgroup align="left" span="3"></colgroup>
+<colgroup align="left"></colgroup>
+<colgroup align="center"></colgroup>
+<colgroup align="center"></colgroup>
<thead>
<tr><th colspan="3">Method</th> <th>Description</th> <th>Killable?</th> <th>Next</th></tr>
@@ -1254,7 +1261,7 @@ locates it within the activity's overall lifecycle:
<tbody>
<tr>
- <td colspan="3" align="left" border="0"><code>{@link android.app.Activity#onCreate onCreate()}</code></td>
+ <td colspan="3" align="left"><code>{@link android.app.Activity#onCreate onCreate()}</code></td>
<td>Called when the activity is first created.
This is where you should do all of your normal static set up &mdash;
create views, bind data to lists, and so on. This method is passed
@@ -1268,7 +1275,7 @@ locates it within the activity's overall lifecycle:
<tr>
<td rowspan="5" style="border-left: none; border-right: none;">&nbsp;&nbsp;&nbsp;&nbsp;</td>
- <td colspan="2" align="left" border="0"><code>{@link android.app.Activity#onRestart
+ <td colspan="2" align="left"><code>{@link android.app.Activity#onRestart
onRestart()}</code></td>
<td>Called after the activity has been stopped, just prior to it being
started again.
@@ -1278,7 +1285,7 @@ onRestart()}</code></td>
</tr>
<tr>
- <td colspan="2" align="left" border="0"><code>{@link android.app.Activity#onStart onStart()}</code></td>
+ <td colspan="2" align="left"><code>{@link android.app.Activity#onStart onStart()}</code></td>
<td>Called just before the activity becomes visible to the user.
<p>Followed by {@code onResume()} if the activity comes
to the foreground, or {@code onStop()} if it becomes hidden.</p></td>
@@ -1288,7 +1295,7 @@ onRestart()}</code></td>
<tr>
<td rowspan="2" style="border-left: none;">&nbsp;&nbsp;&nbsp;&nbsp;</td>
- <td align="left" border="0"><code>{@link android.app.Activity#onResume onResume()}</code></td>
+ <td align="left"><code>{@link android.app.Activity#onResume onResume()}</code></td>
<td>Called just before the activity starts
interacting with the user. At this point the activity is at
the top of the activity stack, with user input going to it.
@@ -1298,7 +1305,7 @@ onRestart()}</code></td>
</tr>
<tr>
- <td align="left" border="0"><code>{@link android.app.Activity#onPause onPause()}</code></td>
+ <td align="left"><code>{@link android.app.Activity#onPause onPause()}</code></td>
<td>Called when the system is about to start resuming another
activity. This method is typically used to commit unsaved changes to
persistent data, stop animations and other things that may be consuming
@@ -1307,24 +1314,24 @@ onRestart()}</code></td>
<p>Followed either by {@code onResume()} if the activity
returns back to the front, or by {@code onStop()} if it becomes
invisible to the user.</td>
- <td align="center"><font color="#800000"><strong>Yes</strong></font></td>
+ <td align="center"><strong style="color:#800000">Yes</strong></td>
<td align="center">{@code onResume()} <br/>or<br/> {@code onStop()}</td>
</tr>
<tr>
- <td colspan="2" align="left" border="0"><code>{@link android.app.Activity#onStop onStop()}</code></td>
+ <td colspan="2" align="left"><code>{@link android.app.Activity#onStop onStop()}</code></td>
<td>Called when the activity is no longer visible to the user. This
may happen because it is being destroyed, or because another activity
(either an existing one or a new one) has been resumed and is covering it.
<p>Followed either by {@code onRestart()} if
the activity is coming back to interact with the user, or by
{@code onDestroy()} if this activity is going away.</p></td>
- <td align="center"><font color="#800000"><strong>Yes</strong></font></td>
+ <td align="center"><strong style="color:#800000">Yes</strong></td>
<td align="center">{@code onRestart()} <br/>or<br/> {@code onDestroy()}</td>
</tr>
<tr>
- <td colspan="3" align="left" border="0"><code>{@link android.app.Activity#onDestroy
+ <td colspan="3" align="left"><code>{@link android.app.Activity#onDestroy
onDestroy()}</code></td>
<td>Called before the activity is destroyed. This is the final call
that the activity will receive. It could be called either because the
@@ -1333,7 +1340,7 @@ onDestroy()}</code></td>
instance of the activity to save space. You can distinguish
between these two scenarios with the <code>{@link
android.app.Activity#isFinishing isFinishing()}</code> method.</td>
- <td align="center"><font color="#800000"><strong>Yes</strong></font></td>
+ <td align="center"><strong style="color:#800000">Yes</strong></td>
<td align="center"><em>nothing</em></td>
</tr>
</tbody>
@@ -1346,7 +1353,7 @@ whether or not the system can kill the process hosting the activity
line of the activity's code</em>. Three methods ({@code onPause()},
{@code onStop()}, and {@code onDestroy()}) are marked "Yes." Because
{@code onPause()} is the first of the three, it's the only one that's
-guaranteed to be called before the process is killed &mdash
+guaranteed to be called before the process is killed &mdash;
{@code onStop()} and {@code onDestroy()} may not be. Therefore, you
should use {@code onPause()} to write any persistent data (such as user
edits) to storage.
@@ -1380,7 +1387,7 @@ previous state.
To capture that state before the activity is killed, you can implement
an <code>{@link android.app.Activity#onSaveInstanceState
onSaveInstanceState()}</code> method for the activity. Android calls this
-method before making the activity vulnerable to being destroyed &mdash
+method before making the activity vulnerable to being destroyed &mdash;
that is, before {@code onPause()} is called. It
passes the method a {@link android.os.Bundle} object where you can record
the dynamic state of the activity as name-value pairs. When the activity is
@@ -1552,7 +1559,7 @@ so any service may receive {@code onBind()} and {@code onUnbind()} calls.
</p>
<p style="margin-left: 2em"><img src="{@docRoot}images/service_lifecycle.png"
-alt="State diagram for Service callbacks." border="0" /></p>
+alt="State diagram for Service callbacks." /></p>
<h3 id="broadlife">Broadcast receiver lifecycle</h3>
@@ -1615,7 +1622,7 @@ in the foreground if any of the following conditions hold:
<ul>
<li>It is running an activity that the user is interacting with
(the Activity object's <code>{@link android.app.Activity#onResume
-onResume()}</code> method has been called).</p></li>
+onResume()}</code> method has been called).</li>
<li><p>It hosts a service that's bound
to the activity that the user is interacting with.</p></li>
diff --git a/docs/html/guide/topics/intents/intents-filters.jd b/docs/html/guide/topics/intents/intents-filters.jd
index d49d27e..fd20ca1 100644
--- a/docs/html/guide/topics/intents/intents-filters.jd
+++ b/docs/html/guide/topics/intents/intents-filters.jd
@@ -399,7 +399,7 @@ IntentFilter objects.)
</p>
<div class="sidebox-wrapper">
-<div class="sidebox">
+<div class="sidebox-inner">
<h2>Filters and security</h2>
<p>An intent filter cannot be relied on for security. While it opens a
component to receiving only certain kinds of implicit intents, it does
diff --git a/docs/html/guide/topics/manifest/action-element.jd b/docs/html/guide/topics/manifest/action-element.jd
new file mode 100644
index 0000000..bc2e1d3
--- /dev/null
+++ b/docs/html/guide/topics/manifest/action-element.jd
@@ -0,0 +1,46 @@
+page.title=&lt;action&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;action android:<a href="#nm">name</a>="<i>string</i>" /&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code></dd>
+
+<p>
+<dt>description:</dt>
+<dd>Adds an action to an intent filter.
+An <code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code> element must contain
+one or more {@code &lt;action&gt;} elements. If it doesn't contain any, no
+Intent objects will get through the filter. See
+<a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and
+Intent Filters</a> for details on intent filters and the role of action
+specifications within a filter.
+</dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="nm"></a>{@code android:name}</dt>
+<dd>The name of the action. Some standard actions are defined in the
+{@link android.content.Intent#ACTION_CHOOSER Intent} class as
+{@code ACTION_<i>string</i>} constants. To assign one of these actions to
+this attribute, prepend "{@code android.intent.action.}" to the
+{@code <i>string</i>} that follows {@code ACTION_}.
+For example, for {@code ACTION_MAIN}, use "{@code android.intent.action.MAIN}"
+and for {@code ACTION_WEB_SEARCH}, use "{@code android.intent.action.WEB_SEARCH}".
+
+<p>
+For actions you define, it's best to use the package name as a prefix to
+ensure uniqueness. For example, a {@code TRANSMOGRIFY} action might be specified
+as follows:
+</p>
+
+<pre>&lt;action android:name="com.example.project.TRANSMOGRIFY" /&gt;</pre>
+</dd>
+</dl></dd>
+
+<dt>see also:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code></dd>
+
+</dl> \ No newline at end of file
diff --git a/docs/html/guide/topics/manifest/activity-alias-element.jd b/docs/html/guide/topics/manifest/activity-alias-element.jd
new file mode 100644
index 0000000..9d81d50
--- /dev/null
+++ b/docs/html/guide/topics/manifest/activity-alias-element.jd
@@ -0,0 +1,129 @@
+page.title=&lt;activity-alias&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;activity-alias android:<a href="#enabled">enabled</a>=["true" | "false"]
+ android:<a href="#exported">exported</a>=["true" | "false"]
+ android:<a href="#icon">icon</a>="<i>drawable resource</i>"
+ android:<a href="#label">label</a>="<i>string resource</i>"
+ android:<a href="#nm">name</a>="<i>string</i>"
+ android:<a href="#prmsn">permission</a>="<i>string</i>"
+ android:<a href="#trgt">targetActivity</a>="<i>string</i>" &gt;
+ . . .
+&lt;/activity-alias&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code></dd>
+
+<dt>can contain:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>An alias for an activity, named by the {@code targetActivity}
+attribute. The target must be in the same application as the
+alias and it must be declared before the alias in the manifest.
+
+<p>
+The alias presents the target activity as a independent entity.
+It can have its own set of intent filters, and they, rather than the
+intent filters on the target activity itself, determine which intents
+can activate the target through the alias and how the system
+treats the alias. For example, the intent filters on the alias may
+specify the "<code>{@link android.content.Intent#ACTION_MAIN
+android.intent.action.MAIN}</code>"
+and "<code>{@link android.content.Intent#CATEGORY_LAUNCHER
+android.intent.category.LAUNCHER}</code>" flags, causing it to be
+represented in the application launcher, even though none of the
+filters on the target activity itself set these flags.
+</p>
+
+<p>
+With the exception of {@code targetActivity}, {@code &lt;activity-alias&gt;}
+attributes are a subset of <code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code> attributes.
+For attributes in the subset, none of the values set for the target carry over
+to the alias. However, for attributes not in the subset, the values set for
+the target activity also apply to the alias.
+</p></dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="enabled"></a>{@code android:enabled}</dt>
+<dd>Whether or not the target activity can be instantiated by the system through
+this alias &mdash; "{@code true}" if it can be, and "{@code false}" if not.
+The default value is "{@code true}".
+
+<p>
+The <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element has its own
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#enabled">enabled</a></code> attribute that applies to all
+application components, including activity aliases. The
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> and {@code &lt;activity-alias&gt;}
+attributes must both be "{@code true}" for the system to be able to instantiate
+the target activity through the alias. If either is "{@code false}", the alias
+does not work.
+</p></dd>
+
+<dt><a name="exported"></a>{@code android:exported}</dt>
+<dd>Whether or not components of other applications can launch the target activity
+through this alias &mdash; "{@code true}" if they can, and "{@code false}" if not.
+If "{@code false}", the target activity can be launched through the alias only by
+components of the same application as the alias or applications with the same user ID.
+
+<p>
+The default value depends on whether the alias contains intent filters. The
+absence of any filters means that the activity can be invoked through the alias
+only by specifying the exact name of the alias. This implies that the alias
+is intended only for application-internal use (since others would not know its name)
+&mdash; so the default value is "{@code false}".
+On the other hand, the presence of at least one filter implies that the alias
+is intended for external use &mdash; so the default value is "{@code true}".
+</p></dd>
+
+<dt><a name="icon"></a>{@code android:icon}</dt>
+<dd>An icon for the target activity when presented to users through the alias.
+See the <code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#icon">icon</a></code> attribute for more information.
+
+<dt><a name="label"></a>{@code android:label}</dt>
+<dd>A user-readable label for the alias when presented to users through the alias.
+See the the <code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#label">label</a></code> attribute for more information.
+</p></dd>
+
+<dt><a name="nm">{@code android:name}</dt>
+<dd>A unique name for the alias. The name should resemble a fully
+qualified class name. But, unlike the name of the target activity,
+the alias name is arbitrary; it does not refer to an actual class.
+</p></dd>
+
+<dt><a name="prmsn"></a>{@code android:permission}</dt>
+<dd>The name of a permission that clients must have to launch the target activity
+or get it to do something via the alias. If a caller of
+<code>{@link android.content.Context#startActivity startActivity()}</code> or
+<code>{@link android.app.Activity#startActivityForResult startActivityForResult()}</code>
+has not been granted the specified permission, the target activity will not be
+activated.
+
+<p>This attribute supplants any permission set for the target activity itself. If
+it is not set, a permission is not needed to activate the target through the alias.
+</p>
+
+<p>
+For more information on permissions, see the
+<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#perms">Permissions</a>
+section in the introduction.
+</p></dd>
+
+<dt><a name="trgt"></a>{@code android:targetActivity}</dt>
+<dd>The name of the activity that can be activated through the alias.
+This name must match the {@code name} attribute of an
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code> element that precedes
+the alias in the manifest.
+</p></dd>
+</dl></dd>
+
+<dt>see also:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code></dd>
+
+</dl> \ No newline at end of file
diff --git a/docs/html/guide/topics/manifest/activity-element.jd b/docs/html/guide/topics/manifest/activity-element.jd
new file mode 100644
index 0000000..aba89d7
--- /dev/null
+++ b/docs/html/guide/topics/manifest/activity-element.jd
@@ -0,0 +1,565 @@
+page.title=&lt;activity&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;activity android:<a href="#reparent">allowTaskReparenting</a>=["true" | "false"]
+ android:<a href="#always">alwaysRetainTaskState</a>=["true" | "false"]
+ android:<a href="#clear">clearTaskOnLaunch</a>=["true"" | "false"]
+ android:<a href="#config">configChanges</a>=[<i>one or more of</i>: "mcc" "mnc" "locale"
+ "touchscreen" "keyboard" "keyboardHidden"
+ "navigation" "orientation" "fontScale"]
+ android:<a href="#enabled">enabled</a>=["true" | "false"]
+ android:<a href="#exclude">excludeFromRecents</a>=["true" | "false"]
+ android:<a href="#exported">exported</a>=["true" | "false"]
+ android:<a href="#finish">finishOnTaskLaunch</a>=["true" | "false"]
+ android:<a href="#icon">icon</a>="<i>drawable resource</i>"
+ android:<a href="#label">label</a>="<i>string resource</i>"
+ android:<a href="#lmode">launchMode</a>=["multiple" | "singleTop" |
+ "singleTask" | "singleInstance"]
+ android:<a href="#multi">multiprocess</a>=["true" | "false"]
+ android:<a href="#nm">name</a>="<i>string</i>"
+ android:<a href="#prmsn">permission</a>="<i>string</i>"
+ android:<a href="#proc">process</a>="<i>string</i>"
+ android:<a href="#screen">screenOrientation</a>=["unspecified" | "user" | "behind" |
+ "landscape" | "portrait" |
+ "sensor" | "nonsensor"]
+ android:<a href="#state">stateNotNeeded</a>=["true" | "false"]
+ android:<a href="#aff">taskAffinity</a>="<i>string</i>"
+ android:<a href="#theme">theme</a>="<i>resource or theme</i>" &gt;
+ . . .
+&lt;/activity&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code></dd>
+
+<dt>can contain:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Declares an activity (an {@link android.app.Activity} subclass) that
+implements part of the application's visual user interface. All activities
+must be represented by {@code &lt;activity&gt;}
+elements in the manifest file. Any that are not declared there will not be seen
+by the system and will never be run.
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a href name="reparent"></a>{@code android:allowTaskReparenting}</dt>
+<dd>Whether or not the activity can move from the task that started it to
+the task it has an affinity for when that task is next brought to the
+front &mdash; "{@code true}" if it can move, and "{@code false}" if it
+must remain with the task where it started.
+
+<p>
+If this attribute is not set, the value set by the corresponding
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#reparent">allowTaskReparenting</a></code>
+attribute of the <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element
+applies to the activity. The default value is "{@code false}".
+</p>
+
+<p>
+Normally when an activity is started, it's associated with the task of
+the activity that started it and it stays there for its entire lifetime.
+You can use this attribute to force it to be re-parented to the task it
+has an affinity for when its current task is no longer displayed.
+Typically, it's used to cause the activities of an application to move
+to the main task associated with that application.
+</p>
+
+<p>
+For example, if an e-mail message contains a link to a web page, clicking
+the link brings up an activity that can display the page. That activity
+is defined by the browser application, but is launched as part of the e-mail
+task. If it's reparented to the browser task, it will be shown when the
+browser next comes to the front, and will be absent when the e-mail task
+again comes forward.
+</p>
+
+<p>
+The affinity of an activity is defined by the
+<code><a href="#aff">taskAffinity</a></code> attribute. The affinity
+of a task is determined by reading the affinity of its root activity.
+Therefore, by definition, a root activity is always in a task with the
+same affinity. Since activities with "{@code singleTask}" or
+"{@code singleInstance}" launch modes can only be at the root of a task,
+re-parenting is limited to the "{@code standard}" and "{@code singleTop}"
+modes. (See also the <code><a href="#lmode">launchMode</a></code>
+attribute.)
+</p></dd>
+
+<dt><a name="always"></a>{@code android:alwaysRetainTaskState}</dt>
+<dd>Whether or not the state of the task that the activity is in will always
+be maintained by the system &mdash; "{@code true}" if it will be, and
+"{@code false}" if the system is allowed to reset the task to its initial
+state in certain situations. The default value is "{@code false}". This
+attribute is meaningful only for the root activity of a task; it's ignored
+for all other activities.
+
+<p>
+Normally, the system clears a task (removes all activities from the stack
+above the root activity) in certain situations when the user re-selects that
+task from the home screen. Typically, this is done if the user hasn't visited
+the task for a certain amount of time, such as 30 minutes.
+</p>
+
+<p>
+However, when this attribute is "{@code true}", users will always return
+to the task in its last state, regardless of how they get there. This is
+useful, for example, in an application like the web browser where there is
+a lot of state (such as multiple open tabs) that users would not like to lose.
+</p></dd>
+
+<dt><a name="clear"></a>{@code android:clearTaskOnLaunch}</dt>
+<dd>Whether or not all activities will be removed from the task, except for
+the root activity, whenever it is re-launched from the home screen &mdash;
+"{@code true}" if the task is always stripped down to its root activity, and
+"{@code false}" if not. The default value is "{@code false}". This attribute
+is meaningful only for activities that start a new task (the root activity);
+it's ignored for all other activities in the task.
+
+<p>
+When the value is "{@code true}", every time users start the task again, they
+are brought to its root activity, regardless of what they were last doing in
+the task and regardless of whether they used BACK or HOME to last leave it.
+When the value is "{@code false}", the task may be cleared of activities in
+some situations (see the
+<code><a href="#always">alwaysRetainTaskState</a></code> attribute), but not always.
+</p>
+
+<p>
+Suppose, for example, that someone launches activity P from the home screen,
+and from there goes to activity Q. The user next presses HOME, and then returns
+to activity P. Normally, the user would see activity Q, since that is what they
+were last doing in P's task. However, if P set this flag to "{@code true}", all
+of the activities on top of it (Q in this case) were removed when the user pressed
+HOME and the task went to the background. So the user sees only P when returning
+to the task.
+</p>
+
+<p>
+If this attribute and <code><a href="#reparent">allowTaskReparenting</a></code>
+are both "{@code true}", any activities that can be re-parented are moved to
+the task they share an affinity with; the remaining activities are then dropped,
+as described above.
+</p></dd>
+
+<dt><a name="config"></a>{@code android:configChanges}</dt>
+<dd>Lists configuration changes that the activity will handle itself. When
+changes that are not listed occur, the activity is shut down and restarted.
+When a listed change occurs, the activity remains running and its <code>{@link android.app.Activity#onConfigurationChanged onConfigurationChanged()}</code>
+method is called.
+
+<p>
+Any or all of the following strings can be used to set this attribute. Values are
+separated by '{@code |}' &mdash; for example, "{@code locale|navigation|orientation}".
+</p>
+
+<table>
+<tr>
+ <td><b>Value</b></td>
+ <td><b>Description</b></td>
+</tr><tr>
+ <td>"{@code mcc}"</td>
+ <td>The IMSI mobile country code (MCC) has changed &mdash;
+ that is, a SIM has been detected and updated the MCC.</td>
+</tr><tr>
+ <td>"{@code mnc}"</td>
+ <td>The IMSI mobile network code (MNC) has changed &mdash;
+ that is, a SIM has been detected and updated the MNC.</td>
+</tr><tr>
+ <td>"{@code locale}"</td>
+ <td>The locale has changed &mdash; for example, the user has selected a new
+ language that text should be displayed in.</td>
+</tr><tr>
+ <td>"{@code touchscreen}"</td>
+ <td>The touchscreen has changed. (This should never normally happen.)</td>
+</tr><tr>
+ <td>"{@code keyboard}"</td>
+ <td>The keyboard type has changed &mdash; for example, the user has
+ plugged in an external keyboard.</td>
+</tr><tr>
+ <td>"{@code keyboardHidden}"</td>
+ <td>The keyboard accessibility has changed &mdash; for example, the
+ user has slid the keyboard out to expose it.</td>
+</tr><tr>
+ <td>"{@code navigation}"</td>
+ <td>The navigation type has changed. (This should never normally happen.)</td>
+</tr><tr>
+ <td>"{@code orientation}"</td>
+ <td>The screen orientation has changed &mdash; that is, the user has rotated
+ the device.</td>
+ </tr><tr>
+ <td>"{@code fontScale}"</td>
+ <td>The font scaling factor has changed &mdash; that is, the user has selected
+ a new global font size.</td>
+</tr>
+</table>
+
+<p>
+All of these configuration changes can impact the resource values seen by the
+application. Therefore, when <code>{@link android.app.Activity#onConfigurationChanged
+onConfigurationChanged()}</code> is called, it will generally be necessary to again
+retrieve all resources (including view layouts, drawables, and so on) to correctly
+handle the change.
+</p></dd>
+
+<dt><a name="enabled"></a>{@code android:enabled}</dt>
+<dd>Whether or not the activity can be instantiated by the system &mdash;
+"{@code true}" if it can be, and "{@code false}" if not. The default value
+is "{@code true}".
+
+<p>
+The <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element has its own
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#enabled">enabled</a></code> attribute that applies to all
+application components, including activities. The
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> and {@code &lt;activity&gt;}
+attributes must both be "{@code true}" (as they both are by default) for
+the system to be able to instantiate the activity. If either is
+"{@code false}", it cannot be instantiated.
+</p></dd>
+
+<dt><a name="exclude"></a>{@code android:excludeFromRecents}</dt>
+<dd>Whether or not the activity should be excluded from the list of recently
+launched activities that can be displayed to users &mdash; "{@code true}" if
+it should be excluded, and "{@code false}" if it should be included.
+The default value is "{@code false}".
+</p></dd>
+
+<dt><a name="exported"></a>{@code android:exported}</dt>
+<dd>Whether or not the activity can be launched by components of other
+applications &mdash; "{@code true}" if it can be, and "{@code false}" if not.
+If "{@code false}", the activity can be launched only by components of the
+same application or applications with the same user ID.
+
+<p>
+The default value depends on whether the activity contains intent filters. The
+absence of any filters means that the activity can be invoked only by specifying
+its exact class name. This implies that the activity is intended only for
+application-internal use (since others would not know the class name). So in
+this case, the default value is "{@code false}".
+On the other hand, the presence of at least one filter implies that the activity
+is intended for external use, so the default value is "{@code true}".
+</p>
+
+<p>
+This attribute is not the only way to limit an activity's exposure to other
+applications. You can also use a permission to limit the external entities that
+can invoke the activity (see the <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#prmsn">permission</a></code>
+attribute).
+</p></dd>
+
+<dt><a name="finish"></a>{@code android:finishOnTaskLaunch}</dt>
+<dd>Whether or not an existing instance of the activity should be shut down
+(finished) whenever the user again launches its task (chooses the task on the
+home screen) &mdash; "{@code true}" if it should be shut down, and "{@code false}"
+if not. The default value is "{@code false}".
+
+<p>
+If this attribute and <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">allowTaskReparenting</a></code>
+are both "{@code true}", this attribute trumps the other. The affinity of the
+activity is ignored. The activity is not re-parented, but destroyed.
+</p>
+
+<dt><a name="icon"></a>{@code android:icon}</dt>
+<dd>An icon representing the activity. The icon is displayed to users when
+a representation of the activity is required on-screen. For example, icons
+for activities that initiate tasks are displayed in the launcher window.
+The icon is often accompanied by a label (see the {@code label} attribute).
+</p>
+
+<p>
+This attribute must be set as a reference to a drawable resource containing
+the image definition. If it is not set, the icon specified for the application
+as a whole is used instead (see the <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+element's <code><a href="{@docRoot}guide/topics/manifest/application-element.html#icon">icon</a></code> attribute).
+</p>
+
+<p>
+The activity's icon &mdash; whether set here or by the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element &mdash; is also the
+default icon for all the activity's intent filters (see the
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html#icon">icon</a></code> attribute).
+</p></dd>
+
+<dt><a name="label"></a>{@code android:label}</dt>
+<dd>A user-readable label for the activity. The label is displayed on-screen
+when the activity must be represented to the user. It's often displayed along
+with the activity icon.
+
+<p>
+If this attribute is not set, the label set for the application as a whole is
+used instead (see the <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#label">label</a></code> attribute).
+</p>
+
+<p>
+The activity's label &mdash; whether set here or by the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element &mdash; is also the
+default label for all the activity's intent filters (see the
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html#label">label</a></code> attribute).
+</p>
+
+<p>
+The label should be set as a reference to a string resource, so that
+it can be localized like other strings in the user interface.
+However, as a convenience while you're developing the application,
+it can also be set as a raw string.
+</p></dd>
+
+<dt><a name="lmode"></a>{@code android:launchMode}</dt>
+<dd>An instruction on how the activity should be launched. There are four modes
+that work in conjunction with activity flags ({@code FLAG_ACTIVITY_*} constants)
+in {@link android.content.Intent} objects to determine what should happen when
+the activity is called upon to handle an intent. They are:
+
+<p style="margin-left: 2em">"{@code standard}"
+<br>"{@code singleTop}"
+<br>"{@code singleTask}"
+<br>"{@code singleInstance}"</p>
+
+<p>
+The default mode is "{@code standard}".
+</p>
+
+<p>
+The modes fall into two main groups, with "{@code standard}" and
+"{@code singleTop}" activities on one side, and "{@code singleTask}" and
+"{@code singleInstance}" activities on the other. An activity with the
+"{@code standard}" or "{@code singleTop}" launch mode can be instantiated
+multiple times. The instances can belong to any task and can be located
+anywhere in the activity stack. Typically, they're launched into the task
+that called
+<code>{@link android.content.Context#startActivity startActivity()}</code>
+(unless the Intent object contains a
+<code>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</code>
+instruction, in which case a different task is chosen &mdash; see the
+<a href="#aff">taskAffinity</a> attribute).
+</p>
+
+<p>
+In contrast, "{@code singleTask}" and "{@code singleInstance}" activities
+can only begin a task. They are always at the root of the activity stack.
+Moreover, the device can hold only one instance of the activity at a time
+&mdash; only one such task.
+</p>
+
+<p>
+The "{@code standard}" and "{@code singleTop}" modes differ from each other
+in just one respect: Every time there's new intent for a "{@code standard}"
+activity, a new instance of the class is created to respond to that intent.
+Each instance handles a single intent.
+Similarly, a new instance of a "{@code singleTop}" activity may also be
+created to handle a new intent. However, if the target task already has an
+existing instance of the activity at the top of its stack, that instance
+will receive the new intent (in an
+<code>{@link android.app.Activity#onNewIntent onNewIntent()}</code> call);
+a new instance is not created.
+In other circumstances &mdash; for example, if an existing instance of the
+"{@code singleTop}" activity is in the target task, but not at the top of
+the stack, or if it's at the top of a stack, but not in the target task
+&mdash; a new instance would be created and pushed on the stack.
+</p>
+
+<p>
+The "{@code singleTask}" and "{@code singleInstance}" modes also differ from
+each other in only one respect: A "{@code singleTask}" activity allows other
+activities to be part of its task. It's at the root of the activity stack,
+but other activities (necessarily "{@code standard}" and "{@code singleTop}"
+activities) can be launched into the same task. A "{@code singleInstance}"
+activity, on the other hand, permits no other activities to be part of its
+task. It's the only activity in the task. If it starts another activity,
+that activity is assigned to a different task &mdash; as if {@code
+FLAG_ACTIVITY_NEW_TASK} was in the intent.
+</p>
+
+<p>For more information on launch modes and their interaction with Intent
+flags, see the
+<a href="{@docRoot}guide/topics/fundamentals.html#acttask">Activities and
+Tasks</a> section of the
+<a href="{@docRoot}guide/topics/fundamentals.html">Application Fundamentals</a>
+document.
+</p>
+</dd>
+
+<dt><a name="multi"></a>{@code android:multiprocess}</dt>
+<dd>Whether an instance of the activity can be launched into the process of the component
+that started it &mdash; "{@code true}" if it can be, and "{@code false}" if not.
+The default value is "{@code false}".
+
+<p>
+Normally, a new instance of an activity is launched into the process of the
+application that defined it, so all instances of the activity run in the same
+process. However, if this flag is set to "{@code true}", instances of the
+activity can run in multiple processes, allowing the system to create instances
+wherever they are used (provided permissions allow it), something that is almost
+never necessary or desirable.
+</p></dd>
+
+<dt><a name="nm"></a>{@code android:name}</dt>
+<dd>The name of the class that implements the activity, a subclass of
+{@link android.app.Activity}. The attribute value should be a fully qualified
+class name (such as, "{@code com.example.project.ExtracurricularActivity}").
+However, as a shorthand, if the first character of the name is a period
+(for example, "{@code .ExtracurricularActivity}"), it is appended to the
+package name specified in the
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
+element.
+
+<p>
+There is no default. The name must be specified.
+</p></dd>
+
+<dt><a name="prmsn"></a>{@code android:permission}</dt>
+<dd>The name of a permission that clients must have to launch the activity
+or otherwise get it to respond to an intent. If a caller of
+<code>{@link android.content.Context#startActivity startActivity()}</code> or
+<code>{@link android.app.Activity#startActivityForResult startActivityForResult()}</code>
+has not been granted the specified permission, its intent will not be
+delivered to the activity.
+
+<p>
+If this attribute is not set, the permission set by the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#prmsn">permission</a></code> attribute applies
+to the activity. If neither attribute is set, the activity is
+not protected by a permission.
+</p>
+
+<p>
+For more information on permissions, see the
+<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#sectperm">Permissions</a>
+section in the introduction and another document,
+<a href="{@docRoot}guide/topics/security/security.html">Security and
+Permissions</a>.
+</p></dd>
+
+<dt><a name="proc"></a>{@code android:process}</dt>
+<dd>The name of the process in which the activity should run. Normally,
+all components of an application run in the default process created for the
+application. It has the same name as the application package. The <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#proc">process</a></code> attribute can set a different
+default for all components. But each component can override the default,
+allowing you to spread your application across multiple processes.
+
+<p>
+If the name assigned to this attribute begins with a colon (':'), a new
+process, private to the application, is created when it's needed and
+the activity runs in that process.
+If the process name begins with a lowercase character, the activity will run
+in a global process of that name, provided that it has permission to do so.
+This allows components in different applications to share a process, reducing
+resource usage.
+</p></dd>
+
+<dt><a name="screen"></a>{@code android:screenOrientation}</dt>
+<dd>The orientation of the activity's display on the device.
+The value can be any one of the following strings:
+
+<table>
+<tr>
+ <td>"{@code unspecified}"</td>
+ <td>The default value. The system chooses the orientation. The policy it
+ uses, and therefore the choices made in specific contexts, may differ
+ from device to device.</td>
+</tr><tr>
+ <td>"{@code landscape}"</td>
+ <td>Landscape orientation (the display is wider than it is tall).</td>
+</tr><tr>
+ <td>"{@code portrait}"</td>
+ <td>Portrait orientation (the display is taller than it is wide).</td>
+</tr><tr>
+ <td>"{@code user}"</td>
+ <td>The user's current preferred orientation.</td>
+</tr><tr>
+ <td>"{@code behind}"</td>
+ <td>The same orientation as the activity that's immediately beneath it in
+ the activity stack.</td>
+</tr><tr>
+ <td>"{@code sensor}"</td>
+ <td>The orientation determined by a physical orientation sensor. The
+ orientation of the display depends on how the user is holding the device;
+ it changes when the user rotates the device.</td>
+</tr><tr>
+ <td>"{@code nosensor}"</td>
+ <td>An orientation determined without reference to a physical orientation sensor.
+ The sensor is ignored, so the display will not rotate based on how the user
+ moves the device. Except for this distinction, the system chooses the
+ orientation using the same policy as for the "{@code unspecified}" setting.</td>
+</tr>
+</table></dd>
+
+<dt><a name="state"></a>{@code android:stateNotNeeded}</dt>
+<dd>Whether or not the activity can be killed and successfully restarted
+without having saved its state &mdash; "{@code true}" if it can be restarted
+without reference to its previous state, and "{@code false}" if its previous
+state is required. The default value is "{@code false}".
+
+<p>
+Normally, before an activity is temporarily shut down to save resources, its
+<code>{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}</code>
+method is called. This method stores the current state of the activity in a
+{@link android.os.Bundle} object, which is then passed to
+<code>{@link android.app.Activity#onCreate onCreate()}</code> when the activity
+is restarted. If this attribute is set to "{@code true}",
+{@code onSaveInstanceState()} may not be called and {@code onCreate()} will
+be passed {@code null} instead of the Bundle &mdash; just as it was when the
+activity started for the first time.
+</p>
+
+<p>
+A "{@code true}" setting ensures that the activity can be restarted in the
+absence of retained state. For example, the activity that displays the
+home screen uses this setting to make sure that it does not get removed if it
+crashes for some reason.
+</p></dd>
+
+<dt><a name="aff"></a>{@code android:taskAffinity}</dt>
+<dd>The task that the activity has an affinity for. Activities with
+the same affinity conceptually belong to the same task (to the same
+"application" from the user's perspective). The affinity of a task
+is determined by the affinity of its root activity.
+
+<p>
+The affinity determines two things &mdash; the task that the activity is re-parented
+to (see the <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">allowTaskReparenting</a></code>
+attribute) and the task that will house the activity when it is launched
+with the <code>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</code>
+flag.
+</p>
+
+<p>
+By default, all activities in an application have the same affinity. You
+can set this attribute to group them differently, and even place
+activities defined in different applications within the same task. To
+specify that the activity does not have an affinity for any task, set
+it to an empty string.
+
+<p>
+If this attribute is not set, the activity inherits the affinity set
+for the application (see the <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+element's <code><a href="{@docRoot}guide/topics/manifest/application-element.html#aff">taskAffinity</a></code> attribute).
+The name of the default affinity for an application is the package name set
+by the <code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code> element.
+</p>
+
+<dt><a name="theme"></a>{@code android:theme}</dt>
+<dd>A reference to a style resource defining an overall theme for the activity.
+This automatically sets the activity's context to use this theme (see
+<code>{@link android.content.Context#setTheme setTheme()}</code>, and may also
+cause "starting" animations prior to the activity being launched (to better
+match what the activity actually looks like).
+
+<p>
+If this attribute is not set, the activity inherits the theme set for the
+application as a whole &mdash; see the <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+element's <code><a href="{@docRoot}guide/topics/manifest/application-element.html#theme">theme</a></code> attribute. If that attribute is
+also not set, the default system theme is used.
+</p>
+<dd>
+</dl></dd>
+
+</dl> \ No newline at end of file
diff --git a/docs/html/guide/topics/manifest/application-element.jd b/docs/html/guide/topics/manifest/application-element.jd
new file mode 100644
index 0000000..362c205
--- /dev/null
+++ b/docs/html/guide/topics/manifest/application-element.jd
@@ -0,0 +1,226 @@
+page.title=&lt;application&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;application android:<a href="#clear">allowClearUserData</a>=["true" | "false"]
+ android:<a href="#reparent">allowTaskReparenting</a>=["true" | "false"]
+ android:<a href="#debug">debuggable</a>=["true" | "false"]
+ android:<a href="#desc">description</a>="<i>string resource</i>"
+ android:<a href="#enabled">enabled</a>=["true" | "false"]
+ android:<a href="#code">hasCode</a>=["true" | "false"]
+ android:<a href="#icon">icon</a>="<i>drawable resource</i>"
+ android:<a href="#label">label</a>="<i>string resource</i>"
+ android:<a href="#space">manageSpaceActivity</a>="<i>string</i>"
+ android:<a href="#nm">name</a>="<i>string</i>"
+ android:<a href="#prmsn">permission</a>="<i>string</i>"
+ android:<a href="#persistent">persistent</a>=["true" | "false"]
+ android:<a href="#proc">process</a>="<i>string</i>"
+ android:<a href="#aff">taskAffinity</a>="<i>string</i>"
+ android:<a href="#theme">theme</a>="<i>resource or theme</i>" &gt;
+ . . .
+&lt;/application&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
+
+<dt>can contain:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;activity-alias&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>The declaration of the application. This element contains subelements
+that declare each of the application's components and has attributes
+that can affect all the components. Many of these attributes (such as
+{@code icon}, {@code label}, {@code permission}, {@code process},
+{@code taskAffinity}, and {@code allowTaskReparenting}) set default values
+for corresponding attributes of the component elements. Others (such as
+{@code debuggable}, {@code enabled}, {@code description}, and
+{@code allowClearUserData}) set values for the application as a whole and
+cannot be overridden by the components.</dd>
+
+<dt>attributes</dt>
+<dd><dl class="attr">
+<dt><a name="clear"></a>{@code android:allowClearUserData}</dt>
+<dd>Whether or not users are given the option to remove user data &mdash;
+"{@code true}" if they are, and "{@code false}" if not. If the value is
+"{@code true}", as it is by default, the application manager includes an
+option that allows users to clear the data.</dd>
+
+<dt><a name="reparent"></a>{@code android:allowTaskReparenting}</dt>
+<dd>Whether or not activities that the application defines can move from
+the task that started them to the task they have an affinity for when that task
+is next brought to the front &mdash; "{@code true}" if they can move, and
+"{@code false}" if they must remain with the task where they started.
+The default value is "{@code false}".
+
+<p>
+The
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+element has its own
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">allowTaskReparenting</a></code>
+attribute that can override the value set here. See that attribute for more
+information.
+</p></dd>
+
+<dt><a name="debug"></a>{@code android:debuggable}</dt>
+<dd>Whether or not the application can be debugged, even when running
+on a device in user mode &mdash; "{@code true}" if it can be, and "{@code false}"
+if not. The default value is "{@code false}".</dd>
+
+<dt><a name="desc"></a>{@code android:description}</dt>
+<dd>User-readable text about the application, longer and more descriptive than the application label. The value must be set as a reference to a string resource. Unlike the label, it cannot be a raw string. There is no default value.</dd>
+
+<dt><a name="enabled"></a>{@code android:enabled}</dt>
+<dd>Whether or not the Android system can instantiate components of
+the application &mdash; "{@code true}" if it can, and "{@code false}"
+if not. If the value is "{@code true}", each component's
+{@code enabled} attribute determines whether that component is enabled
+or not. If the value is "{@code false}", it overrides the
+component-specific values; all components are disabled.
+
+<p>
+The default value is "{@code true}".
+</p></dd>
+
+<dt><a name="code"></a>{@code android:hasCode}</dt>
+<dd>Whether or not the application contains any code &mdash; "{@code true}"
+if it does, and "{@code false}" if not. When the value is "{@code false}",
+the system does not try to load any application code when launching components.
+The default value is "{@code true}".
+
+<p>
+An application would not have any code of its own only if it's using nothing
+but built-in component classes, such as an activity that uses the {@link
+android.app.AliasActivity} class, a rare occurrence.
+
+<dt><a name="icon"></a>{@code android:icon}</dt>
+<dd>An icon for the application as whole, and the default icon for
+each of the application's components. See the individual
+{@code icon} attributes for
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>,
+<code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;activity-alias&gt;</a></code>,
+<code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>,
+<code><a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code>, and
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code> elements.
+
+<p>
+This attribute must be set as a reference to a drawable resource containing
+the image definition. There is no default icon.
+</p></dd>
+
+<dt><a name="label"></a>{@code android:label}</dt>
+<dd>A user-readable label for the application as a whole, and a default
+label for each of the application's components. See the individual
+{@code label} attributes for
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>,
+<code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;activity-alias&gt;</a></code>,
+<code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>,
+<code><a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code>, and
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code> elements.
+
+<p>
+The label should be set as a reference to a string resource, so that
+it can be localized like other strings in the user interface.
+However, as a convenience while you're developing the application,
+it can also be set as a raw string.
+</p></dd>
+
+<dt><a name="space"></a>{@code android:manageSpaceActivity}</dt>
+<dd>The fully qualified name of an Activity subclass that the system
+can launch to let users manage the memory occupied by the application
+on the device. The activity should also be declared with an
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code> element.
+</dd>
+
+<dt><a name="nm"></a>{@code android:name}</dt>
+<dd>The fully qualified name of an {@link android.app.Application}
+subclass implemented for the application. When the application process
+is started, this class is instantiated before any of the application's
+components.
+
+<p>
+The subclass is optional; most applications won't need one.
+In the absence of a subclass, Android uses an instance of the base
+Application class.
+</p></dd>
+
+<dt><a name="prmsn"></a>{@code android:permission}</dt>
+<dd>The name of a permission that clients must have in order to interact
+with the application. This attribute is a convenient way to set a
+permission that applies to all of the application's components. It can
+be overwritten by setting the {@code permission} attributes of individual
+components.
+
+<p>
+For more information on permissions, see the
+<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#sectperm">Permissions</a>
+section in the introduction and another document,
+<a href="{@docRoot}guide/topics/security/security.html">Security and
+Permissions</a>.
+</p></dd>
+
+<dt><a name="persistent"></a>{@code android:persistent}</dt>
+<dd>Whether or not the application should remain running at all times &mdash;
+"{@code true}" if it should, and "{@code false}" if not. The default value
+is "{@code false}". Applications should not normally set this flag;
+persistence mode is intended only for certain system applications.</dd>
+
+<dt><a name="proc"></a>{@code android:process}</dt>
+<dd>The name of a process where all components of the application should run.
+Each component can override this default by setting its own {@code process}
+attribute.
+
+<p>
+By default, Android creates a process for an application when the first
+of its components needs to run. All components then run in that process.
+The name of the default process matches the package name set by the
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code> element.
+</p>
+
+<p>By setting this attribute to a process name that's shared with another
+application, you can arrange for components of both applications to run in
+the same process &mdash; but only if the two applications also share a
+user ID and be signed with the same certificate.
+</p>
+
+<p>
+If the name assigned to this attribute begins with a colon (':'), a new
+process, private to the application, is created when it's needed.
+If the process name begins with a lowercase character, a global process
+of that name is created. A global process can be shared with other
+applications, reducing resource usage.
+</p></dd>
+
+<dt><a href name="aff"></a>{@code android:taskAffinity}</dt>
+<dd>An affinity name that applies to all activities within the application,
+except for those that set a different affinity with their own
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">taskAffinity</a></code>
+attributes. See that attribute for more information.
+
+<p>
+By default, all activities within an application share the same
+affinity. The name of that affinity is the same as the package name
+set by the
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code> element.
+</p></dd>
+
+<dt><a name="theme"></a>{@code android:theme}</dt>
+<dd>A reference to a style resource defining a default theme for all
+activities in the application. Individual activities can override
+the default by setting their own <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#theme">theme</a></code>
+attributes; see that attribute for more information.</dd>
+
+</dl></dd>
+
+<dt>see also:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/category-element.jd b/docs/html/guide/topics/manifest/category-element.jd
new file mode 100644
index 0000000..50ea576
--- /dev/null
+++ b/docs/html/guide/topics/manifest/category-element.jd
@@ -0,0 +1,38 @@
+page.title=&lt;category&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;category android:<a href="#nm">name</a>="<i>string</i>" /&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Adds a category name to an intent filter. See
+<a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and
+Intent Filters</a> for details on intent filters and the role of category
+specifications within a filter.</dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="nm"></a>{@code android:name}</dt>
+<dd>The name of the category. Standard categories are defined in the
+{@link android.content.Intent} class as {@code CATEGORY_<i>name</i>}
+constants. The name assigned here can be derived from those constants
+by prefixing "{@code android.intent.category.}" to the
+{@code <i>name</i>} that follows {@code CATEGORY_}. For example,
+the string value for {@code CATEGORY_LAUNCHER} is
+"{@code android.intent.category.LAUNCHER}".
+
+<p>
+Custom categories should use the package name as a prefix, to ensure
+that they are unique.
+</p></dd>
+</dl></dd>
+
+<dt>see also:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/action-element.html">&lt;action&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/data-element.html">&lt;data&gt;</a></code></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/data-element.jd b/docs/html/guide/topics/manifest/data-element.jd
new file mode 100644
index 0000000..5d8fde2
--- /dev/null
+++ b/docs/html/guide/topics/manifest/data-element.jd
@@ -0,0 +1,148 @@
+page.title=&lt;data&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;data android:<a href="#host">host</a>="<i>string</i>"
+ android:<a href="#mime">mimeType</a>="<i>string</i>"
+ android:<a href="#path">path</a>="<i>string</i>"
+ android:<a href="#path">pathPattern</a>="<i>string</i>"
+ android:<a href="#path">pathPrefix</a>="<i>string</i>"
+ android:<a href="#port">port</a>="<i>string</i>"
+ android:<a href="#scheme">scheme</a>="<i>string</i>" /&gt;</pre></dd>
+
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Adds a data specification to an intent filter. The specification can
+be just a data type (the <code><a href="{@docRoot}guide/topics/manifest/data-element.html#mime">mimeType</a></code> attribute),
+just a URI, or both a data type and a URI. A URI is specified by separate
+attributes for each of its parts:
+
+<p style="margin-left: 2em">{@code scheme://host:port/path} <i>or</i>
+{@code pathPrefix} <i>or</i> {@code pathPattern}</p>
+
+<p>
+These attributes are optional, but also mutually dependent:
+If a <code><a href="{@docRoot}guide/topics/manifest/data-element.html#scheme">scheme</a></code> is not specified for the
+intent filter, all the other URI attributes are ignored. If a
+<code><a href="{@docRoot}guide/topics/manifest/data-element.html#host">host</a></code> is not specified for the filer,
+the {@code port} attribute and all the path attributes are ignored.
+</p>
+
+<p>
+All the {@code &lt;data&gt;} elements contained within the same
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code> element contribute to
+the same filter. So, for example, the following filter specification,
+</p>
+
+<pre>&lt;intent-filter . . . &gt;
+ &lt;data android:scheme="something" android:host="project.example.com" /&gt;
+ . . .
+&lt;/intent-filter&gt;</pre>
+
+<p>is equivalent to this one:</p>
+
+<pre>&lt;intent-filter . . . &gt;
+ &lt;data android:scheme="something" /&gt
+ &lt;data android:host="project.example.com" /&gt;
+ . . .
+&lt;/intent-filter&gt;</pre>
+
+<p>
+You can place any number of &lt;data&gt; elements inside an
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code> to give it multiple data
+options. None of its attributes have default values.
+</p>
+
+<p>
+Information on how intent filters work, including the rules for how Intent objects
+are matched against filters, can be found in another document,
+<a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and
+Intent Filters</a>. See also the
+<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#ifs">Intent Filters</a>
+section in the introduction.
+</p></dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="host"></a>{@code android:host}</dt>
+<dd>The host part of a URI authority. This attribute is meaningless
+unless a <code><a href="{@docRoot}guide/topics/manifest/data-element.html#scheme">scheme</a></code> attribute is also
+specified for the filter.
+</dd>
+
+<dt><a name="mime"></a>{@code android:mimeType}</dt>
+<dd>A MIME media type, such as {@code image/jpeg} or {@code audio/mpeg4-generic}.
+The subtype can be the asterisk wildcard ({@code *}) to indicate that any
+subtype matches.</dd>
+
+<dt><a name="path"></a>{@code android:path}
+<br/>{@code android:pathPrefix}
+<br/>{@code android:pathPattern}</dt>
+<dd>The path part of a URI. The {@code path} attribute specifies a complete
+path that is matched against the complete path in an Intent object. The
+{@code pathPrefix} attribute specifies a partial path that is matched against
+only the initial part of the path in the Intent object. The {@code pathPattern}
+attribute specifies a complete path that is matched against the complete path
+in the Intent object, but it can contain the following wildcards:
+
+<ul>
+<li>An asterisk ('{@code *}') matches a sequence of 0 to many occurrences of
+the immediately preceding character.</li>
+
+<li>A period followed by an asterisk ("{@code .*}") matches any sequence of
+0 to many characters.</li>
+</ul>
+
+<p>
+Because '{@code \}' is used as an escape character when the string is read
+from XML (before it is parsed as a pattern), you will need to double-escape:
+For example, a literal '{@code *}' would be written as "{@code \\*}" and a
+literal '{@code \}' would be written as "{@code \\\\}". This is basically
+the same as what you would need to write if constructing the string in Java code.
+</p>
+
+<p>
+For more information on these three types of patterns, see the descriptions of
+{@link android.os.PatternMatcher#PATTERN_LITERAL},
+{@link android.os.PatternMatcher#PATTERN_PREFIX}, and
+{@link android.os.PatternMatcher#PATTERN_SIMPLE_GLOB} in the
+{@link android.os.PatternMatcher} class.
+</p>
+
+<p>These attributes are meaningful only if the
+<code><a href="#scheme">scheme</a></code> and <code><a href="#host">host</a></code>
+attributes are also specified for the filter.
+</p></dd>
+
+<dt><a name="port"></a>{@code android:port}</dt>
+<dd>The port part of a URI authority. This attribute is meaningful only
+if the <code><a href="#scheme">scheme</a></code> and
+<code><a href="#host">host</a></code> attributes are also specified for
+the filter.</dd>
+
+<dt><a name="scheme"></a>{@code android:scheme}</dt>
+<dd>The scheme part of a URI. This is the minimal essential attribute for
+specifying a URI; at least one {@code scheme} attribute must be set
+for the filter, or none of the other URI attributes are meaningful.
+
+<p>
+A scheme is specified without the trailing colon (for example,
+{@code http}, rather than {@code http:}).
+</p>
+
+<p>
+If the filter has a data type set (the <code><a href="{@docRoot}guide/topics/manifest/data-element.html#mime">mimeType</a></code>
+attribute) but no scheme, the {@code content:} and {@code file:} schemes are
+assumed.
+</p></dd>
+</dl></dd>
+
+<dt>see also:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/action-element.html">&lt;action&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/category-element.html">&lt;category&gt;</a></code></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/grant-uri-permission-element.jd b/docs/html/guide/topics/manifest/grant-uri-permission-element.jd
new file mode 100644
index 0000000..f5b37b5
--- /dev/null
+++ b/docs/html/guide/topics/manifest/grant-uri-permission-element.jd
@@ -0,0 +1,85 @@
+page.title=&lt;grant-uri-permission&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;grant-uri-permission android:<a href="#path">path</a>="<i>string</i>"
+ android:<a href="#path">pathPattern</a>="<i>string</i>"
+ android:<a href="#path">pathPrefix</a>="<i>string</i>" /&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Specifies which data subsets of the parent content provider permission
+can be granted for. Data subsets are indicated by the path part of a
+{@code content:} URI. (The authority part of the URI identifies the
+content provider.)
+Granting permission is a way of enabling clients of the provider that don't
+normally have permission to access its data to overcome that restriction on
+a one-time basis.
+
+<p>
+If a content provider's <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmns">grantUriPermissions</a></code>
+attribute is "{@code true}", permission can be granted for any the data under
+the provider's purview. However, if that attribute is "{@code false}", permission
+can be granted only to data subsets that are specified by this element.
+A provider can contain any number of {@code &lt;grant-uri-permission&gt;} elements.
+Each one can specify only one path (only one of the three possible attributes).
+</p>
+
+<p>
+For information on how permission is granted, see the
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">grantUriPermissions</a></code> attribute.
+</p></dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="path"></a>{@code android:path}
+<br/>{@code android:pathPrefix}
+<br/>{@code android:pathPattern}</dt>
+<dd>A path identifying the data subset or subsets that permission can be
+granted for. The {@code path} attribute specifies a complete path;
+permission can be granted only to the particular data subset identified
+by that path.
+The {@code pathPrefix} attribute specifies the initial part of a path;
+permission can be granted to all data subsets with paths that share that
+initial part.
+The {@code pathPattern} attribute specifies a complete path, but one
+that can contain the following wildcards:
+
+<ul>
+<li>An asterisk ('{@code *}') matches a sequence of 0 to many occurrences of
+the immediately preceding character.</li>
+
+<li><p>A period followed by an asterisk ("{@code .*}") matches any sequence of
+0 to many characters.</p></li>
+</ul>
+
+<p>
+Because '{@code \}' is used as an escape character when the string is read
+from XML (before it is parsed as a pattern), you will need to double-escape:
+For example, a literal '{@code *}' would be written as "{@code \\*}" and a
+literal '{@code \}' would be written as "{@code \\\\}". This is basically
+the same as what you would need to write if constructing the string in Java code.
+</p>
+
+<p>
+For more information on these types of patterns, see the descriptions of
+{@link android.os.PatternMatcher#PATTERN_LITERAL},
+{@link android.os.PatternMatcher#PATTERN_PREFIX}, and
+{@link android.os.PatternMatcher#PATTERN_SIMPLE_GLOB} in the
+{@link android.os.PatternMatcher} class.
+</p></dd>
+</dl></dd>
+
+<dt>see also:</dt>
+<dd>the
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmns">grantUriPermissions</a></code>
+attribute of the
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>
+element</dd>
+
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/instrumentation-element.jd b/docs/html/guide/topics/manifest/instrumentation-element.jd
new file mode 100644
index 0000000..fdec949
--- /dev/null
+++ b/docs/html/guide/topics/manifest/instrumentation-element.jd
@@ -0,0 +1,61 @@
+page.title=&lt;instrumentation&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;instrumentation android:<a href="#ftest">functionalTest</a>=["true" | "false"]
+ android:<a href="#hprof">handleProfiling</a>=["true" | "false"]
+ android:<a href="#icon">icon</a>="<i>drawable resource</i>"
+ android:<a href="#label">label</a>="<i>string resource</i>"
+ android:<a href="#nm">name</a>="<i>string</i>"
+ android:<a href="#trgt">targetPackage</a>="<i>string</i>" /&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Declares an {@link android.app.Instrumentation} class that enables you
+to monitor an application's interaction with the system. The Instrumentation
+object is instantiated before any of the application's components.</dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="ftest"></a>{@code android:functionalTest}</dt>
+<dd>Whether or not the Instrumentation class should run as a functional test
+&mdash; "{@code true}" if it should, and "{@code false}" if not. The
+default value is "{@code false}".</dd>
+
+<dt><a name="hprof"></a>{@code android:handleProfiling}</dt>
+<dd>Whether or not the Instrumentation object will turn profiling on and
+off &mdash; "{@code true}" if it determines when profiling starts and
+stops, and "{@code false}" if profiling continues the entire time it is
+running. A value of "{@code true}" enables the object to target profiling
+at a specific set of operations. The default value is "{@code false}".</dd>
+
+<dt><a name="icon"></a>{@code android:icon}</dt>
+<dd>An icon that represents the Instrumentation class. This attribute must
+be set as a reference to a drawable resource.</dd>
+
+<dt><a name="label"></a>{@code android:label}</dt>
+<dd>A user-readable label for the Instrumentation class. The label can
+be set as a raw string or a reference to a string resource.</dd>
+
+<dt><a name="nm"></a>{@code android:name}</dt>
+<dd>The name of the {@link android.app.Instrumentation} subclass.
+This should be a fully qualified class name (such as,
+"{@code com.example.project.StringInstrumentation}"). However, as a shorthand,
+if the first character of the name is a period, it is appended to the package
+name specified in the <code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code> element.
+
+<p>
+There is no default. The name must be specified.
+</p></dd>
+
+<dt><a name="trgt"></a>{@code android:targetPackage}</dt>
+<dd>The application that the Instrumentation object will run against.
+An application is identified by the package name assigned in its manifest
+file by the <code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code> element.</dd>
+
+</dl></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/intent-filter-element.jd b/docs/html/guide/topics/manifest/intent-filter-element.jd
new file mode 100644
index 0000000..58d1f91
--- /dev/null
+++ b/docs/html/guide/topics/manifest/intent-filter-element.jd
@@ -0,0 +1,130 @@
+page.title=&lt;intent-filter&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;intent-filter android:<a href="#icon">icon</a>="<i>drawable resource</i>"
+ android:<a href="#label">label</a>="<i>string resource</i>"
+ android:<a href="#priority">priority</a>="<i>integer</i>" &gt;
+ . . .
+&lt;/intent-filter&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;activity-alias&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code></dd>
+
+<dt>must contain:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/action-element.html">&lt;action&gt;</a></code></dd>
+
+<dt>can contain:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/category-element.html">&lt;category&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/data-element.html">&lt;data&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Specifies the types of intents that an activity, service, or broadcast
+receiver can respond to. An intent filter declares the capabilities of its
+parent component &mdash; what an activity or service can do and what types
+of broadcasts a receiver can handle. It opens the component to receiving
+intents of the advertised type, while filtering out those that are not
+meaningful for the component.
+
+<p>
+Most of the contents of the filter are described by its
+<code><a href="{@docRoot}guide/topics/manifest/action-element.html">&lt;action&gt;</a></code>,
+<code><a href="{@docRoot}guide/topics/manifest/category-element.html">&lt;category&gt;</a></code>, and
+<code><a href="{@docRoot}guide/topics/manifest/data-element.html">&lt;data&gt;</a></code> subelements.
+</p>
+
+<p>
+For a more detailed discussion of filters, see the separate
+<a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents
+and Intent Filters</a> document, as well as the
+<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#ifs">Intents Filters</a>
+section in the introduction.
+</p></dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="icon"></a>{@code android:icon}</dt>
+<dd>An icon that represents the parent activity, service, or broadcast
+receiver when that component is presented to the user as having the
+capability described by the filter.
+
+<p>
+This attribute must be set as a reference to a drawable resource
+containing the image definition. The default value is the icon set
+by the parent component's {@code icon} attribute. If the parent
+does not specify an icon, the default is the icon set by the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element.
+</p>
+
+<p>
+For more on intent filter icons, see
+<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#iconlabel">Icons and Labels</a>
+in the introduction.
+</p></dd>
+
+<dt><a name="label"></a>{@code android:label}</dt>
+<dd>A user-readable label for the parent component. This label, rather than
+the one set by the parent component, is used when the component is presented
+to the user as having the capability described by the filter.
+
+<p>
+The label should be set as a reference to a string resource, so that
+it can be localized like other strings in the user interface.
+However, as a convenience while you're developing the application,
+it can also be set as a raw string.
+</p>
+
+<p>
+The default value is the label set by the parent component. If the
+parent does not specify a label, the default is the label set by the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#label"> label</a></code> attribute.
+</p>
+
+<p>
+For more on intent filter labels, see
+<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#iconlabel">Icons and Labels</a>
+in the introduction.
+</p></dd>
+
+<dt><a name="priority"></a>{@code android:priority}</dt>
+<dd>The priority that should be given to the parent component with regard
+to handling intents of the type described by the filter. This attribute has
+meaning for both activities and broadcast receivers:
+
+<ul>
+<li>It provides information about how able an activity is to respond to
+an intent that matches the filter, relative to other activities that could
+also respond to the intent. When an intent could be handled by multiple
+activities with different priorities, Android will consider only those with
+higher priority values as potential targets for the intent.</li>
+
+<li><p>It controls the order in which broadcast receivers are executed to
+receive broadcast messages. Those with higher priority
+values are called before those with lower values. (The order applies only
+to synchronous messages; it's ignored for asynchronous messages.)</p></li>
+</ul>
+
+<p>
+Use this attribute only if you really need to impose a specific order in
+which the broadcasts are received, or want to force Android to prefer
+one activity over others.
+</p>
+
+<p>
+The value must be an integer, such as "{@code 100}". Higher numbers have a
+higher priority.
+</p></dd>
+
+</dl></dd>
+
+<dt>see also:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/action-element.html">&lt;action&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/category-element.html">&lt;category&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/data-element.html">&lt;data&gt;</a></code></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/manifest-element.jd b/docs/html/guide/topics/manifest/manifest-element.jd
new file mode 100644
index 0000000..2669487
--- /dev/null
+++ b/docs/html/guide/topics/manifest/manifest-element.jd
@@ -0,0 +1,94 @@
+page.title=&lt;manifest&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;manifest xmlns:<a href="#nspace">android</a>="http://schemas.android.com/apk/res/android"
+ <a href="#package">package</a>="<i>string</i>"
+ android:<a href="#uid">sharedUserId</a>="<i>string</i>"
+ android:<a href="#vcode">versionCode</a>="<i>integer</i>"
+ android:<a href="#vname">versionName</a>="<i>string</i>" &gt;
+ . . .
+&lt;/manifest&gt;</pre></dd>
+
+<p>
+<dt>contained in:</dt>
+<dd><i>none</i></dd>
+
+<p>
+<p>
+<dt>must contain:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code></dd>
+
+<dt>can contain:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/instrumentation-element.html">&lt;instrumentation&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-tree-element.html">&lt;permission-tree&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code></dd>
+
+<p>
+<dt>description:</dt>
+<dd>The root element of the AndroidManifest.xml file. It must
+contain an <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element
+and specify {@code xlmns:android} and {@code package} attributes.</dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="nspace"></a>{@code xmlns:android}</dt>
+<dd>Defines the Android namespace. This attribute should always be set
+to "{@code http://schemas.android.com/apk/res/android}".</dd>
+
+<dt><a name="package"></a>{@code package}</dt>
+<dd>A full Java package name for the application. The name should
+be unique. For example, applications published by Google could have
+names in the form <code>com.google.app.<i>application_name</i></code>.
+
+<p>
+The package name serves as a unique identifier for the application.
+It's also the default name for the application process (see the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+element's
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#aff">process</a></code>
+process</a></code> attribute) and the default task affinity of an activity
+(see the
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+element's
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">taskAffinity</a></code> attribute).
+</p></dd>
+
+<dt><a name="uid"></a>{@code android:sharedUserId}</dt>
+<dd>The name of a Linux user ID that will be shared with other applications.
+By default, Android assigns each application its own unique user ID.
+However, if this attribute is set to the same value for two or more applications,
+they will all share the same ID &mdash; provided that they are also signed
+by the same certificate. Application with the same user ID can access each
+other's data and, if desired, run in the same process.</dd>
+
+<dt><a name="vcode"></a>{@code android:versionCode}</dt>
+<dd>An internal version number. This number is used only to determine whether
+one version is more recent than another, with higher numbers indicating more
+recent versions. This is not the version number shown to users; that number
+is set by the {@code versionName} attribute.
+
+<p>
+The value must be set as an integer, such as "100". You can define it however
+you want, as long as each successive version has a higher number. For example,
+it could be a build number. Or you could translate a version number in "x.y"
+format to an integer by encoding the "x" and "y" separately in the lower and
+upper 16 bits. Or you could simply increase the number by one each time a new
+version is released.
+</p></dd>
+
+<dt><a name="vname"></a>{@code android:versionName}</dt>
+<dd>The version number shown to users. This attribute can be set as a raw
+string or as a reference to a string resource. The string has no other purpose
+than to be displayed to users. The {@code versionCode} attribute holds
+the significant version number used internally.
+</dl></dd>
+
+<p>
+<dt>see also:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/manifest-intro.jd b/docs/html/guide/topics/manifest/manifest-intro.jd
new file mode 100644
index 0000000..3c8a34a
--- /dev/null
+++ b/docs/html/guide/topics/manifest/manifest-intro.jd
@@ -0,0 +1,511 @@
+page.title=The AndroidManifest.xml File
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+<ol>
+<li><a href="#filestruct">Structure of the Manifest File</a></li>
+<li><a href="#filec">File Conventions</a>
+<li><a href="#filef">File Features</a>
+ <ol>
+ <li><a href="#ifs">Intent Filters</a></li>
+ <li><a href="#iconlabel">Icons and Labels</a></li>
+ <li><a href="#perms">Permissions</a></li>
+ <li><a href="#libs">Libraries</a></li>
+ </ol></li>
+</ol>
+</div>
+</div>
+
+<p>
+Every application must have an AndroidManifest.xml file (with precisely that
+name) in its root directory. The manifest presents essential information about
+the application to the Android system, information the system must have before
+it can run any of the application's code. Among other things, the manifest
+does the following:
+</p>
+
+<ul>
+<li>It names the Java package for the application.
+The package name serves as a unique identifier for the application.</li>
+
+<li>It describes the components of the application &mdash; the activities,
+services, broadcast receivers, and content providers that the application is
+composed of. It names the classes that implement each of the components and
+publishes their capabilities (for example, which {@link android.content.Intent
+Intent} messages they can handle). These declarations let the Android system
+know what the components are and under what conditions they can be launched.</li>
+
+<li>It determines which processes will host application components.</li>
+
+<li>It declares which permissions the application must have in order to
+access protected parts of the API and interact with other applications.</li>
+
+<li>It also declares the permissions that others are required to have in
+order to interact with the application's components.</li>
+
+<li>It lists the {@link android.app.Instrumentation} classes that provide
+profiling and other information as the application is running. These declarations
+are present in the manifest only while the application is being developed and
+tested; they're removed before the application is published.</li>
+
+<li>It declares the minimum version of the Android API that the application
+requires.</li>
+
+<li>It lists the libraries that the application must be linked against.</li>
+</ul>
+
+
+<h2 id="filestruct">Structure of the Manifest File</h2>
+
+<p>
+The diagram below shows the general structure of the manifest file and
+every element that it can contain. Each element, along with all of its
+attributes, is documented in full in a separate file. To view detailed
+information about any element, click on the element name in the diagram,
+in the alphabetical list of elements that follows the diagram, or on any
+other mention of the element name.
+</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+
+<a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/permission-tree-element.html">&lt;permission-tree /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group /&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/instrumentation-element.html">&lt;instrumentation /&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk /&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/action-element.html">&lt;action /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/category-element.html">&lt;category /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/data-element.html">&lt;data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;/intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;/activity&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;activity-alias&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a> . . . <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;/intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;/activity-alias&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a> . . . <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;/intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data/&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;/service&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a> . . . <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;/intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;/receiver&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;/provider&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library /&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;/application&gt;</a>
+
+<a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;/manifest&gt;</a>
+</pre>
+
+<p>
+All the elements that can appear in the manifest file are listed below
+in alphabetical order. These are the only legal elements; you cannot
+add your own elements or attributes.
+</p>
+
+<p style="margin-left: 2em">
+<code><a href="{@docRoot}guide/topics/manifest/action-element.html">&lt;action&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;activity-alias&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/category-element.html">&lt;category&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/data-element.html">&lt;data&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/instrumentation-element.html">&lt;instrumentation&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-tree-element.html">&lt;permission-tree&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk&gt;</a></code>
+</p>
+
+
+
+<h2 id="filec">File Conventions</h2>
+
+<p>
+Some conventions and rules apply generally to all elements and attributes
+in the manifest:
+</p>
+
+<dl>
+<dt><b>Elements</b></dt>
+<dd>Only the
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code> and
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+elements are required, they each must be present and can occur only once.
+Most of the others can occur many times or not at all &mdash; although at
+least some of them must be present for the manifest to accomplish anything
+meaningful.
+
+<p>
+If an element contains anything at all, it contains other elements.
+All values are set through attributes, not as character data within an element.
+</p>
+
+<p>
+Elements at the same level are generally not ordered. For example,
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>,
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>, and
+<code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
+elements can be intermixed in any sequence. (An
+<code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;activity-alias&gt;</a></code>
+element is the exception to this rule: It must follow the
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+it is an alias for.)
+</p></dd>
+
+<dt><b>Attributes</b></dt>
+<dd>In a formal sense, all attributes are optional. However, there are some
+that must be specified for an element to accomplish its purpose. Use the
+documentation as a guide. For truly optional attributes, it mentions a default
+value or states what happens in the absence of a specification.
+
+<p>Except for some attributes of the root
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
+element, all attribute names begin with an {@code android:} prefix &mdash;
+for example, {@code android:alwaysRetainTaskState}. Because the prefix is
+universal, the documentation generally omits it when referring to attributes
+by name.</p></dd>
+
+<dt><b>Declaring class names</b></dt>
+<dd>Many elements correspond to Java objects, including elements for the
+application itself (the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+element) and its principal components &mdash; activities
+(<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>),
+services
+(<code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>),
+broadcast receivers
+(<code><a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code>),
+and content providers
+(<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>).
+
+<p>
+If you define a subclass, as you almost always would for the component classes
+({@link android.app.Activity}, {@link android.app.Service},
+{@link android.content.BroadcastReceiver}, and {@link android.content.ContentProvider}),
+the subclass is declared through a {@code name} attribute. The name must include
+the full package designation.
+For example, an {@link android.app.Service} subclass might be declared as follows:
+</p>
+
+<pre>&lt;manifest . . . &gt;
+ &lt;application . . . &gt;
+ &lt;service android:name="com.example.project.SecretService" . . . &gt;
+ . . .
+ &lt;/service&gt;
+ . . .
+ &lt;/application&gt;
+&lt;/manifest&gt;</pre>
+
+<p>
+However, as a shorthand, if the first character of the string is a period, the
+string is appended to the application's package name (as specified by the
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
+element's
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html#package">package</a></code>
+attribute). The following assignment is the same as the one above:
+</p>
+
+<pre>&lt;manifest package="com.example.project" . . . &gt;
+ &lt;application . . . &gt;
+ &lt;service android:name=".SecretService" . . . &gt;
+ . . .
+ &lt;/service&gt;
+ . . .
+ &lt;/application&gt;
+&lt;/manifest&gt;</pre>
+
+<p>
+When starting a component, Android creates an instance of the named subclass.
+If a subclass isn't specified, it creates an instance of the base class.
+</p></dd>
+
+<dt><b>Multiple values</b></dt>
+<dd>If more than one value can be specified, the element is almost always
+repeated, rather than listing multiple values within a single element.
+For example, an intent filter can list several actions:
+
+<pre>&lt;intent-filter . . . &gt;
+ &lt;action android:name="android.intent.action.EDIT" /&gt;
+ &lt;action android:name="android.intent.action.INSERT" /&gt;
+ &lt;action android:name="android.intent.action.DELETE" /&gt;
+ . . .
+&lt;/intent-filter&gt;</pre></dd>
+
+<dt><b>Resource values</b></dt>
+<dd>Some attributes have values that can be displayed to users &mdash; for
+example, a label and an icon for an activity. The values of these attributes
+should be localized and therefore set from a resource or theme. Resource
+values are expressed in the following format,</p>
+
+<p style="margin-left: 2em">{@code @[<i>package</i>:]<i>type</i>:<i>name</i>}</p>
+
+<p>
+where the <i>package</i> name can be omitted if the resource is in the same package
+as the application, <i>type</i> is a type of resource &mdash; such as "string" or
+"drawable" &mdash; and <i>name</i> is the name that identifies the specific resource.
+For example:
+</p>
+
+<pre>&lt;activity android:icon="@drawable/smallPic" . . . &gt</pre>
+
+<p>
+Values from a theme are expressed in a similar manner, but with an initial '{@code ?}'
+rather than '{@code @}':
+</p>
+
+<p style="margin-left: 2em">{@code ?[<i>package</i>:]<i>type</i>:<i>name</i>}
+</p></dd>
+
+<dt><b>String values</b></dt>
+<dd>Where an attribute value is a string, double backslashes ('{@code \\}')
+must be used to escape characters &mdash; for example, '{@code \\n}' for
+a newline or '{@code \\uxxxx}' for a Unicode character.</dd>
+</dl>
+
+
+<h2 id="filef">File Features</h2>
+
+<p>
+The following sections describe how some Android features are reflected
+in the manifest file.
+</p>
+
+
+<h3 id="ifs">Intent Filters</h3>
+
+<p>
+The core components of an application (its activities, services, and broadcast
+receivers) are activated by <i>intents</i>. An intent is a
+bundle of information (an {@link android.content.Intent} object) describing a
+desired action &mdash; including the data to be acted upon, the category of
+component that should perform the action, and other pertinent instructions.
+Android locates an appropriate component to respond to the intent, launches
+a new instance of the component if one is needed, and passes it the
+Intent object.
+</p>
+
+<p>
+Components advertise their capabilities &mdash; the kinds of intents they can
+respond to &mdash; through <i>intent filters</i>. Since the Android system
+must learn which intents a component can handle before it launches the component,
+intent filters are specified in the manifest as
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code>
+elements. A component may have any number of filters, each one describing
+a different capability.
+</p>
+
+<p>
+An intent that explicitly names a target component will activate that component;
+the filter doesn't play a role. But an intent that doesn't specify a target by
+name can activate a component only if it can pass through one of the component's
+filters.
+</p>
+
+<p>
+For information on how Intent objects are tested against intent filters,
+see a separate document,
+<a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents
+and Intent Filters</a>.
+</p>
+
+
+<h3 id="iconlabel">Icons and Labels</h3>
+
+<p>
+A number of elements have {@code icon} and {@code label} attributes for a
+small icon and a text label that can be displayed to users. Some also have a
+{@code description} attribute for longer explanatory text that can also be
+shown on-screen. For example, the
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+element has all three of these attributes, so that when the user is asked whether
+to grant the permission to an application that has requested it, an icon representing
+the permission, the name of the permission, and a description of what it
+entails can all be presented to the user.
+</p>
+
+<p>
+In every case, the icon and label set in a containing element become the default
+{@code icon} and {@code label} settings for all of the container's subelements.
+Thus, the icon and label set in the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+element are the default icon and label for each of the application's components.
+Similarly, the icon and label set for a component &mdash; for example, an
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+element &mdash; are the default settings for each of the component's
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code>
+elements. If an
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+element sets a label, but an activity and its intent filter do not,
+the application label is treated as the label for both the activity and
+the intent filter.
+</p>
+
+<p>
+The icon and label set for an intent filter are used to represent a component
+whenever the component is presented to the user as fulfilling the function
+advertised by the filter. For example, a filter with
+"{@code android.intent.action.MAIN}" and
+"{@code android.intent.category.LAUNCHER}" settings advertises an activity
+as one that initiates an application &mdash; that is, as
+one that should be displayed in the application launcher. The icon and label
+set in the filter are therefore the ones displayed in the launcher.
+</p>
+
+
+<h3 id="perms">Permissions</h3>
+
+<p>
+A <i>permission</i> is a restriction limiting access to a part of the code
+or to data on the device. The limitation is imposed to protect critical
+data and code that could be misused to distort or damage the user experience.
+</p>
+
+<p>
+Each permission is identified by a unique label. Often the label indicates
+the action that's restricted. For example, here are some permissions defined
+by Android:
+</p>
+
+<p style="margin-left: 2em">{@code android.permission.CALL_EMERGENCY_NUMBERS}
+<br/>{@code android.permission.READ_OWNER_DATA}
+<br/>{@code android.permission.SET_WALLPAPER}
+<br/>{@code android.permission.DEVICE_POWER}</p>
+
+<p>
+A feature can be protected by at most one permission.
+</p>
+
+<p>
+If an application needs access to a feature protected by a permission,
+it must declare that it requires that permission with a
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+element in the manifest. Then, when the application is installed on
+the device, the installer determines whether or not to grant the requested
+permission by checking the authorities that signed the application's
+certificates and, in some cases, asking the user.
+If the permission is granted, the application is able to use the protected
+features. If not, its attempts to access those features will simply fail
+without any notification to the user.
+</p>
+
+<p>
+An application can also protect its own components (activities, services,
+broadcast receivers, and content providers) with permissions. It can employ
+any of the permissions defined by Android (listed in
+{@link android.Manifest.permission android.Manifest.permission}) or declared
+by other applications. Or it can define its own. A new permission is declared
+with the
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+element. For example, an activity could be protected as follows:
+</p>
+
+<pre>
+&lt;manifest . . . &gt;
+ &lt;permission android:name="com.example.project.DEBIT_ACCT" . . . /&gt;
+ . . .
+ &lt;application . . .&gt;
+ &lt;activity android:name="com.example.project.FreneticActivity" . . . &gt;
+ android:permission="com.example.project.DEBIT_ACCT"
+ . . . &gt;
+ . . .
+ &lt;/activity&gt;
+ &lt;/application&gt;
+ . . .
+ &lt;uses-permission android:name="com.example.project.DEBIT_ACCT" /&gt;
+ . . .
+&lt;/manifest&gt;
+</pre>
+
+<p>
+Note that, in this example, the {@code DEBIT_ACCT} permission is not only
+declared with the
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+element, its use is also requested with the
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+element. Its use must be requested in order for other components of the
+application to launch the protected activity, even though the protection
+is imposed by the application itself.
+</p>
+
+<p>
+If, in the same example, the {@code permission} attribute was set to a
+permission declared elsewhere
+(such as {@code android.permission.CALL_EMERGENCY_NUMBERS}, it would not
+have been necessary to declare it again with a
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+element. However, it would still have been necessary to request its use with
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>.
+</p>
+
+<p>
+The
+<code><a href="{@docRoot}guide/topics/manifest/permission-tree-element.html">&lt;permission-tree&gt;</a></code>
+element declares a namespace for a group of permissions that will be defined in
+code. And
+<code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></code>
+defines a label for a set of permissions (both those declared in the manifest with
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+elements and those declared elsewhere). It affects only how the permissions are
+grouped when presented to the user. The
+<code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></code>
+element does not specify which permissions belong to the group;
+it just gives the group a name. A permission is placed in the group
+by assigning the group name to the
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+element's
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html#pgroup">permissionGroup</a></code>
+attribute.
+</p>
+
+
+<h3 id="libs">Libraries</h3>
+
+<p>
+Every application is linked against the default Android library, which
+includes the basic packages for building applications (with common classes
+such as Activity, Service, Intent, View, Button, Application, ContentProvider,
+and so on).
+</p>
+
+<p>
+However, some packages reside in their own libraries. If your application
+uses code from any of these packages, it must explicitly asked to be linked
+against them. The manifest must contain a separate
+<code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library&gt;</a></code>
+element to name each of the libraries. (The library name can be found in the
+documentation for the package.)
+</p>
diff --git a/docs/html/guide/topics/manifest/manifest.jd b/docs/html/guide/topics/manifest/manifest.jd
deleted file mode 100644
index bf9194c..0000000
--- a/docs/html/guide/topics/manifest/manifest.jd
+++ /dev/null
@@ -1,3063 +0,0 @@
-page.title=The AndroidManifest.xml File
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2>In this document</h2>
-<ol>
-<li><a href="#filestruct">Structure of the Manifest File</a></li>
-<li><a href="#filef">File Features</a>
- <ol>
- <li><a href="#ifs">Intent Filter</a></li>
- <li><a href="#iconlabel">Icons and Labels</a></li>
- <li><a href="#perms">Using Permissions</a></li>
- <li><a href="#libs">Libraries</a></li>
- </ol></li>
-<li><a href="#elems">Elements of the Manifest File</a></li>
-</ol>
-</div>
-</div>
-
-<p>
-Every application must have an AndroidManifest.xml file (with precisely that
-name) in its root directory. The manifest presents essential information about
-the application to the Android system, information the system must have before
-it can run any of the application's code. Among other things, the manifest
-does the following:
-</p>
-
-<ul>
-<li>It names the Java package for the application.
-The package name serves as a unique identifier for the application.</li>
-
-<li>It describes the components of the application &mdash; the activities,
-services, broadcast receivers, and content providers that the application is
-composed of. It names the classes that implement each of the components and
-publishes their capabilities (for example, which {@link android.content.Intent
-Intent} messages they can handle). These declarations let the Android system
-know what the components are and under what conditions they can be launched.</li>
-
-<li>It determines which processes will host application components.</li>
-
-<li>It declares which permissions the application must have in order to
-access protected parts of the API and interact with other applications.</li>
-
-<li>It also declares the permissions that others are required to have in
-order to interact with the application's components.</li>
-
-<li>It lists the {@link android.app.Instrumentation} classes that provide
-profiling and other information as the application is running. These declarations
-are present in the manifest only while the application is being developed and
-tested; they're removed before the application is published.</li>
-
-<li>It declares the minimum version of the Android API that the application
-requires.</li>
-
-<li>It lists the libraries that the application must be linked against.</li>
-</ul>
-
-
-<h2 id="filestruct">Structure of the Manifest File</h2>
-
-<p>
-A later section of this document, <a href="#elems">"Elements of the Manifest
-File"</a>, describes all of the elements that can appear in the manifest file
-and each of their attributes. The diagram below shows the general structure of
-the file and every element it can contain.
-</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-
-<a href="#manf">&lt;manifest&gt;</a>
-
- <a href="#usesp">&lt;uses-permission /&gt;</a>
- <a href="#prmsn">&lt;permission /&gt;</a>
- <a href="#ptree">&lt;permission-tree /&gt;</a>
- <a href="#pgroup">&lt;permission-group /&gt;</a>
-
- <a href="#instru">&lt;instrumentation /&gt;</a>
-
- <a href="#usess">&lt;uses-sdk /&gt;</a>
-
- <a href="#app">&lt;application&gt;</a>
-
- <a href="#actv">&lt;activity&gt;</a>
- <a href="#ifilt">&lt;intent-filter&gt;</a>
- <a href="#actn">&lt;action /&gt;</a>
- <a href="#catg">&lt;category /&gt;</a>
- <a href="#data">&lt;data /&gt;</a>
- <a href="#ifilt">&lt;/intent-filter&gt;</a>
- <a href="#meta">&lt;meta-data /&gt;</a>
- <a href="#actv">&lt;/activity&gt;</a>
-
- <a href="#alias">&lt;activity-alias&gt;</a>
- <a href="#ifilt">&lt;intent-filter&gt;</a> . . . <a href="#ifilt">&lt;/intent-filter&gt;</a>
- <a href="#meta">&lt;meta-data /&gt;</a>
- <a href="#alias">&lt;/activity-alias&gt;</a>
-
- <a href="#srvc">&lt;service&gt;</a>
- <a href="#ifilt">&lt;intent-filter&gt;</a> . . . <a href="#ifilt">&lt;/intent-filter&gt;</a>
- <a href="#meta">&lt;meta-data/&gt;</a>
- <a href="#srvc">&lt;/service&gt;</a>
-
- <a href="#rcvr">&lt;receiver&gt;</a>
- <a href="#ifilt">&lt;intent-filter&gt;</a> . . . <a href="#ifilt">&lt;/intent-filter&gt;</a>
- <a href="#meta">&lt;meta-data /&gt;</a>
- <a href="#rcvr">&lt;/receiver&gt;</a>
-
- <a href="#pvdr">&lt;provider&gt;</a>
- <a href="#grantp">&lt;grant-uri-permission /&gt;</a>
- <a href="#meta">&lt;meta-data /&gt;</a>
- <a href="#pvdr">&lt;/provider&gt;</a>
-
- <a href="#usesl">&lt;uses-library /&gt;</a>
-
- <a href="#app">&lt;/application&gt;</a>
-
-<a href="#manf">&lt;/manifest&gt;</a>
-</pre>
-
-<p>
-Some conventions and rules apply generally to all elements and attributes
-in the manifest:
-</p>
-
-<dl>
-<dt><b>Elements</b></dt>
-<dd>Only the {@code <a href="#manf">&lt;manifest&gt;</a>} and
-{@code <a href="#app">&lt;application&gt;</a>} elements are required, they each
-must be present and can occur only once. Most of the others can occur many times
-or not at all &mdash; although at least some of them must be present for the
-manifest to accomplish anything meaningful.
-
-<p>
-If an element contains anything at all, it contains other elements.
-All values are set through attributes, not as character data within an element.
-</p>
-
-<p>
-Elements at the same level are generally not ordered. For example,
-{@code <a href="#actv">&lt;activity&gt;</a>},
-{@code <a href{@code <a href="#pvdr">&lt;provider&gt;</a>}, and
-{@code <a href="#srvc">&lt;service&gt;</a>} elements can be intermixed in
-any sequence. (An {@code <a href="#alias">&lt;activity-alias&gt;</a>} is the
-exception to this rule: It must follow the {@code <a href="#actv">&lt;activity&gt;</a>}
-it is an alias for.)</p></dd>
-
-<dt><b>Attributes</b></dt>
-<dd>In a formal sense, all attributes are optional. However, there are some
-that must be specified for an element to accomplish its purpose. Use the
-documentation as a guide. For truly optional attributes, it mentions a default
-value or states what happens in the absence of a specification.
-
-<p>Except for some attributes of
-the root {@code <a href="#manf">&lt;manifest&gt;</a>} element,
-all attribute names begin with an {@code android:} prefix &mdash;
-for example, {@code android:alwaysRetainTaskState}. Because the prefix is
-universal, this documentation generally omits it when referring to attributes
-by name.</p></dd>
-
-<dt><b>Declaring class names</b></dt>
-<dd>Many elements correspond to Java objects, including elements for the
-application itself (the {@code <a href="#app">&lt;application&gt;</a>} element)
-and its principal components &mdash;
-activities ({@code <a href="#actv">&lt;activity&gt;</a>}),
-services ({@code <a href="#srvc">&lt;service&gt;</a>}),
-broadcast receivers ({@code <a href="#rcvr">&lt;receiver&gt;</a>}),
-and content providers ({@code <a href="#pvdr">&lt;provider&gt;</a>}).
-
-<p>
-If you define a subclass, as you almost always would for the component classes
-({@link android.app.Activity}, {@link android.app.Service},
-{@link android.content.BroadcastReceiver},
-and {@link android.content.ContentProvider}), the subclass is declared through
-a {@code name} attribute. The name must include the full package designation.
-For example, an {@link android.app.Service} subclass might be declared as follows:
-</p>
-
-<pre>&lt;manifest . . . &gt;
- &lt;application . . . &gt;
- &lt;service android:name="com.example.project.SecretService" . . . &gt;
- . . .
- &lt;/service&gt;
- . . .
- &lt;/application&gt;
-&lt;/manifest&gt;</pre>
-
-<p>
-However, as a shorthand, if the first character of the string is a period, the
-string is appended to the application's package name (as specified by the
-{@code <a href="#manf">&lt;manifest&gt;</a>} element's
-{@code <a href="#manf_package">package</a>} attribute). The following assignment
-is the same as the one above:
-</p>
-
-<pre>&lt;manifest package="com.example.project" . . . &gt;
- &lt;application . . . &gt;
- &lt;service android:name=".SecretService" . . . &gt;
- . . .
- &lt;/service&gt;
- . . .
- &lt;/application&gt;
-&lt;/manifest&gt;</pre>
-
-<p>
-When starting a component, Android creates an instance of the named subclass.
-If a subclass isn't specified, it creates an instance of the base class.
-</p></dd>
-
-<dt><b>Multiple values</b></dt>
-<dd>If more than one value can be specified, the element is almost always repeated,
-rather than listing multiple values within a single element.
-For example, an intent filter can list several actions:
-
-<pre>&lt;intent-filter . . . &gt;
- &lt;action android:name="android.intent.action.EDIT" /&gt;
- &lt;action android:name="android.intent.action.INSERT" /&gt;
- &lt;action android:name="android.intent.action.DELETE" /&gt;
- . . .
-&lt;/intent-filter&gt;</pre></dd>
-
-<dt><b>Resource values</b></dt>
-<dd>Some attributes have values that can be displayed to users &mdash; for
-example, a label and an icon for an activity. The values of these attributes
-should be localized and therefore set from a resource or theme. Resource values
-are expressed in the following format,</p>
-
-<p style="margin-left: 2em">{@code @[<i>package</i>:]<i>type</i>:<i>name</i>}</p>
-
-<p>
-where the <i>package</i> name can be omitted if the resource is in the same package
-as the application, <i>type</i> is a type of resource &mdash; such as "string" or
-"drawable" &mdash; and <i>name</i> is the name that identifies the specific resource.
-For example:
-</p>
-
-<pre>&lt;activity android:icon="@drawable/smallPic" . . . &gt</pre>
-
-<p>
-Values from a theme are expressed in a similar manner, but with an initial '?'
-rather than '@':
-</p>
-
-<p style="margin-left: 2em">{@code ?[<i>package</i>:]<i>type</i>:<i>name</i>}
-</p></dd>
-
-<dt><b>String values</b></dt>
-<dd>Where an attribute value is a string, double backslashes ('{@code \\}')
-must be used to escape characters &mdash; for example, '{@code \\n}' for
-a newline or '{@code \\uxxxx}' for a Unicode character.</dd>
-</dl>
-
-
-<h2 id="filef">File Features</h2>
-
-<p>
-The following sections describe how some Android features are reflected
-in the manifest file.
-</p>
-
-
-<h3 id="ifs">Intent Filters</h3>
-
-<p>
-The core components of an application (its activities, services, and broadcast
-receivers) are activated by <i>intents</i>. An intent is a
-bundle of information (an {@link android.content.Intent} object) describing a
-desired action &mdash; including the data to be acted upon, the category of
-component that should perform the action, and other pertinent instructions.
-Android locates an appropriate component to respond to the intent, launches
-a new instance of the component if one is needed, and passes it the
-Intent object.
-</p>
-
-<p>
-Components advertise their capabilities &mdash; the kinds of intents they can
-respond to &mdash; through <i>intent filters</i>. Since the Android system
-must learn which intents a component can handle before it launches the component,
-intent filters are specified in the manifest as
-{@code <a href="#ifilt">&lt;intent-filter&gt;</a>} elements. A component may
-have any number of filters, each one describing a different capability.
-</p>
-
-<p>
-An intent that explicitly names a target component will activate that component;
-the filter doesn't play a role. But an intent that doesn't specify a target by
-name can activate a component only if it can pass through one of the component's
-filters.
-</p>
-
-<p>
-For information on how Intent objects are tested against intent filters,
-a separate document,
-<a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents
-and Intent Filters</a>.
-</p>
-
-
-<h3 id="iconlabel">Icons and Labels</h3>
-
-<p>
-A number of elements have {@code icon} and {@code label} attributes for an
-icon and a text label that can displayed to users. Some also have a
-{@code description} attribute for longer explanatory text that can also be
-shown on-screen. For example, the {@code <a href="#prmsn">&lt;permission&gt;</a>}
-element has all three of these attributes, so that when the user is asked whether
-to grant the permission to an application that has requested it, an icon representing
-the permission, the name of the permission, and a description of what it
-entails can all be presented to the user.
-</p>
-
-<p>
-In every case, the icon and label set in a containing element become the default
-{@code icon} and {@code label} settings for all of the container's subelements.
-Thus, the icon and label set in the {@code <a href="#app">&lt;application&gt;</a>}
-element are the default icon and label for each of the application's components.
-Similarly, the icon and label set for a component &mdash; for example, an
-{@code <a href="#actv">&lt;activity&gt;</a>} element &mdash; are the default
-settings for each of the component's
-{@code <a href="#ifilt">&lt;intent-filter&gt;</a>} elements. If an
-{@code <a href="#app">&lt;application&gt;</a>} element sets a label, but
-an activity and its intent filter do not, the application label is treated
-as the label for both the activity and the intent filter.
-</p>
-
-<p>
-The icon and label set for an intent filter are used to represent a component
-whenever the component is presented to the user as fulfilling the function
-advertised by the filter. For example, a filter with
-"{@code android.intent.action.MAIN}" and
-"{@code android.intent.category.LAUNCHER}" settings advertises an activity
-as one that initiates an application &mdash; that is, as
-one that should be displayed in the application launcher. The icon and label
-set in the filter are therefore the ones displayed in the launcher.
-</p>
-
-
-<h3 id="perms">Permissions</h3>
-
-<p>
-A <i>permission</i> is a restriction limiting access to a part of the code
-or to data on the device. The limitation is imposed to protect critical
-data and code that could be misused to distort or damage the user experience.
-</p>
-
-<p>
-Each permission is identified
-by a unique label. Often the label indicates the action that's restricted.
-For example, here are some permissions defined by Android:
-</p>
-
-<p style="margin-left: 2em">{@code android.permission.CALL_EMERGENCY_NUMBERS}
-<br/>{@code android.permission.READ_OWNER_DATA}
-<br/>{@code android.permission.SET_WALLPAPER}
-<br/>{@code android.permission.DEVICE_POWER}</p>
-
-<p>
-A feature can be protected by at most one permission.
-</p>
-
-<p>
-If an application needs access to a feature protected by a permission, it must
-declare that it requires that permission with a
-{@code <a href="#usesp">&lt;uses-permission&gt;</a>} element in the manifest.
-Then, when the application is installed on the device, the installer determines
-whether or not to grant the requested permission by checking the authorities that
-signed the application's certificates and, in some cases, asking the user.
-If the permission is granted, the application is able to use the protected
-features. If not, its attempts to access those features will simply fail
-without any notification to the user.
-</p>
-
-<p>
-An application can also protect its own components (activities, services,
-broadcast receivers, and content providers) with permissions. It can employ
-any of the permissions defined by Android (listed in
-{@link android.Manifest.permission android.Manifest.permission}) or declared
-by other applications. Or it can define its own. A new permission is declared
-with the {@code <a href="#prmsn">&lt;permission&gt;</a>} element.
-For example, an activity could be protected as follows:
-</p>
-
-<pre>
-&lt;manifest . . . &gt;
- &lt;permission android:name="com.example.project.DEBIT_ACCT" . . . /&gt;
- . . .
- &lt;application . . .&gt;
- &lt;activity android:name="com.example.project.FreneticActivity" . . . &gt;
- android:permission="com.example.project.DEBIT_ACCT"
- . . . &gt;
- . . .
- &lt;/activity&gt;
- &lt;/application&gt;
- . . .
- &lt;uses-permission android:name="com.example.project.DEBIT_ACCT" /&gt;
- . . .
-&lt;/manifest&gt;
-</pre>
-
-<p>
-Note that, in this example, the {@code DEBIT_ACCT} permission is not only
-declared with the {@code <a href="#prmsn">&lt;permission&gt;</a>}
-element, its use is also requested with
-the {@code <a href="#usesp">&lt;uses-permission&gt;</a>} element. Its use
-must be requested in order for other components of the application to launch
-the protected activity, even though the protection is imposed by the
-application itself.
-</p>
-
-<p>
-If, in the same example, the {@code permission} attribute was set to a
-permission declared elsewhere
-(such as {@code android.permission.CALL_EMERGENCY_NUMBERS}, it would not
-have been necessary to declare it again with the
-{@code <a href="#prmsn">&lt;permission&gt;</a>} element.
-However, it would still have been necessary to request its use with
-{@code <a href="#usesp">&lt;uses-permission&gt;</a>}.
-</p>
-
-<p>
-The {@code <a href="#ptree">&lt;permission-tree&gt;</a>} element declares
-a namespace for a group of permissions that will be defined in code.
-And {@code <a href="#pgroup">&lt;permission-group&gt;</a>}
-defines a label for a set of permissions (both those declared in the
-manifest with {@code <a href="#prmsn">&lt;permission&gt;</a>} elements and
-those declared elsewhere). It affects only how the permissions are grouped
-when presented to the user.
-</p>
-
-
-<h3 id="libs">Libraries</h3>
-
-<p>
-Every application is linked against the default Android library, which
-includes the basic packages for building applications (with common classes
-such as Activity, Service, Intent, View, Button, Application, ContentProvider,
-and so on).
-</p>
-
-<p>
-However, some packages reside in their own libraries. If your application
-uses code from any of these packages, it must explicitly asked to be linked
-against them. The manifest must contain a separate
-{@code <a href="#usesl">&lt;uses-library&gt;</a>} element to name each
-of the libraries. (The library name can be found in the documentation
-for the package.)
-</p>
-
-
-<h2 id="elems">Elements of the Manifest File</h2>
-
-<p>
-This section describes all the elements that can appear in the manifest and each
-of their attributes in more detail. Only the elements listed here are legal.
-The list is alphabetical.
-</p>
-
-
-<h3 id="actn">&lt;action&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;action android:name="<i>string</i>" /&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#ifilt">&lt;intent-filter&gt;</a>}</dd>
-
-<p>
-<dt>description:</dt>
-<dd>Adds an action to an intent filter.
-An {@code <a href="#ifilt">&lt;intent-filter&gt;</a>} element must contain
-one or more {@code &lt;action&gt;} elements. If it doesn't contain any, no
-Intent objects will get through the filter. See
-<a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and
-Intent Filters</a> for details on intent filters and the role of action
-specifications within a filter.
-</dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:name}</dt>
-<dd>The name of the action. Some standard actions are defined in the
-{@link android.content.Intent#ACTION_CHOOSER Intent} class as
-{@code ACTION_<i>string</i>} constants. To assign one of these actions to
-this attribute, prepend "{@code android.intent.action.}" to the
-{@code <i>string</i>} that follows {@code ACTION_}.
-For example, for {@code ACTION_MAIN}, use "{@code android.intent.action.MAIN}"
-and for {@code ACTION_WEB_SEARCH}, use "{@code android.intent.action.WEB_SEARCH}".
-
-<p>
-For actions you define, it's best to use the package name as a prefix to
-ensure uniqueness. For example, a {@code TRANSMOGRIFY} action might be specified
-as follows:
-</p>
-
-<pre>&lt;action android:name="com.example.project.TRANSMOGRIFY" /&gt;</pre>
-</dd>
-</dl></dd>
-
-<dt>see also:</dt>
-<dd>{@code <a href="#ifilt">&lt;intent-filter&gt;</a>}</dd>
-
-</dl>
-<hr>
-
-<h3 id="actv">&lt;activity&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;activity android:allowTaskReparenting=["true" | "false"]
- android:alwaysRetainTaskState=["true" | "false"]
- android:clearTaskOnLaunch=["true"" | "false"]
- android:configChanges=["mcc" | "mnc" | "locale" |
- "touchscreen" | "keyboard" |
- "keyboardHidden" | "navigation" |
- "orientation" | "fontScale"]
- android:enabled=["true" | "false"]
- android:excludeFromRecents=["true" | "false"]
- android:exported=["true" | "false"]
- android:finishOnTaskLaunch=["true" | "false"]
- android:icon="<i>drawable resource</i>"
- android:label="<i>string resource</i>"
- android:launchMode=["multiple" | "singleTop" |
- "singleTask" | "singleInstance"]
- android:multiprocess=["true" | "false"]
- android:name="<i>string</i>"
- android:permission="<i>string</i>"
- android:process="<i>string</i>"
- android:screenOrientation=["unspecified" | "user" | "behind" |
- "landscape" | "portrait" |
- "sensor" | "nonsensor"]
- android:stateNotNeeded=["true" | "false"]
- android:taskAffinity="<i>string</i>"
- android:theme="<i>resource or theme</i>" &gt;
- . . .
-&lt;/activity&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#app">&lt;application&gt;</a>}</dd>
-
-<dt>can contain:</dt>
-<dd>{@code <a href="#ifilt">&lt;intent-filter&gt;</a>}
-<br/>{@code <a href="#meta">&lt;meta-data&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Declares an activity (an {@link android.app.Activity} subclass) that
-implements part of the application's visual user interface. All activities
-must be represented by {@code &lt;activity&gt;}
-elements in the manifest file. Any that are not declared there will not be seen
-by the system and will never be run.
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt><a href name="actv_reparent"></a>{@code android:allowTaskReparenting}</dt>
-<dd>Whether or not the activity can move from the task that started it to
-the task it has an affinity for when that task is next brought to the
-front &mdash; "{@code true}" if it can move, and "{@code false}" if it
-must remain with the task where it started.
-
-<p>
-If this attribute is not set, the value set by the corresponding
-{@code <a href="#app_reparent">allowTaskReparenting</a>}
-attribute of the {@code <a href="#app">&lt;application&gt;</a>} element
-applies to the activity. The default value is "{@code false}".
-</p>
-
-<p>
-Normally when an activity is started, it's associated with the task of
-the activity that started it and it stays there for its entire lifetime.
-You can use this attribute to force it to be re-parented to the task it
-has an affinity for when its current task is no longer displayed.
-Typically, it's used to cause the activities of an application to move
-to the main task associated with that application.
-</p>
-
-<p>
-For example, if an e-mail message contains a link to a web page, clicking
-the link brings up an activity that can display the page. That activity
-is defined by the browser application, but is launched as part of the e-mail
-task. If it's reparented to the browser task, it will be shown when the
-browser next comes to the front, and will be absent when the e-mail task
-again comes forward.
-</p>
-
-<p>
-The affinity of an activity is defined by the
-{@code <a href="#actv_aff">taskAffinity</a>} attribute. The affinity
-of a task is determined by reading the affinity of its root activity.
-Therefore, by definition, a root activity is always in a task with the
-same affinity. Since activities with "{@code singleTask}" or
-"{@code singleInstance}" launch modes can only be at the root of a task,
-re-parenting is limited to the "{@code standard}" and "{@code singleTop}"
-modes. (See also the {@code <a href="#actv_lmode">launchMode</a>}
-attribute.)
-</p></dd>
-
-<dt>{@code android:alwaysRetainTaskState}</dt>
-<dd>Whether or not the state of the task that the activity is in will always
-be maintained by the system &mdash; "{@code true}" if it will be, and
-"{@code false}" if the system is allowed to reset the task to its initial
-state in certain situations. The default value is "{@code false}". This
-attribute is meaningful only for the root activity of a task; it's ignored
-for all other activities.
-
-<p>
-Normally, the system clears a task (removes all activities from the stack
-above the root activity) in certain situations when the user re-selects that
-task from the home screen. Typically, this is done if the user hasn't visited
-the task for a certain amount of time, such as 30 minutes.
-</p>
-
-<p>
-However, when this attribute is "{@code true}", users will always return
-to the task in its last state, regardless of how they get there. This is
-useful, for example, in an application like the web browser where there is
-a lot of state (such as multiple open tabs) that users would not like to lose.
-</p></dd>
-
-<dt>{@code android:clearTaskOnLaunch}</dt>
-<dd>Whether or not all activities will be removed from the task, except for
-the root activity, whenever it is re-launched from the home screen &mdash;
-"{@code true}" if the task is always stripped down to its root activity, and
-"{@code false}" if not. The default value is "{@code false}". This attribute
-is meaningful only for activities that start a new task (the root activity);
-it's ignored for all other activities in the task.
-
-<p>
-When the value is "{@code true}", every time users start the task again, they
-are brought to its root activity, regardless of what they were last doing in
-the task and regardless of whether they used BACK or HOME to last leave it.
-When the value is "{@code false}", the task may be cleared of activities in
-some situations (see the {@code alwaysRetainTaskState} attribute), but not always.
-</p>
-
-<p>
-Suppose, for example, that someone launches activity P from the home screen,
-and from there goes to activity Q. The user next presses HOME, and then returns
-to activity P. Normally, the user would see activity Q, since that is what they
-were last doing in P's task. However, if P set this flag to "{@code true}", all
-of the activities on top of it (Q in this case) were removed when the user pressed
-HOME and the task went to the background. So the user sees only P when returning
-to the task.
-</p>
-
-<p>
-If this attribute and {@code allowTaskReparenting} are both "{@code true}",
-any activities that can be re-parented are moved to the task they share an
-affinity with; the remaining activities are then dropped, as described above.
-</p></dd>
-
-<dt>{@code android:configChanges}</dt>
-<dd>Lists configuration changes that the activity will handle itself. When
-changes that are not listed occur, the activity is shut down and restarted.
-When a listed change occurs, the activity remains running and its <code>{@link android.app.Activity#onConfigurationChanged onConfigurationChanged()}</code>
-method is called.
-
-<p>
-Any or all of the following strings can be used to set this attribute. Values are
-separated by '{@code |}' &mdash; for example, "{@code locale|navigation|orientation}".
-</p>
-
-<table>
-<tr>
- <td><b>Value</b></td>
- <td><b>Description</b></td>
-</tr><tr>
- <td>"{@code mcc}"</td>
- <td>The IMSI mobile country code (MCC) has changed &mdash;
- that is, a SIM has been detected and updated the MCC.</td>
-</tr><tr>
- <td>"{@code mnc}"</td>
- <td>The IMSI mobile network code (MNC) has changed &mdash;
- that is, a SIM has been detected and updated the MNC.</td>
-</tr><tr>
- <td>"{@code locale}"</td>
- <td>The locale has changed &mdash; for example, the user has selected a new
- language that text should be displayed in.</td>
-</tr><tr>
- <td>"{@code touchscreen}"</td>
- <td>The touchscreen has changed. (This should never normally happen.)</td>
-</tr><tr>
- <td>"{@code keyboard}"</td>
- <td>The keyboard type has changed &mdash; for example, the user has
- plugged in an external keyboard.</td>
-</tr><tr>
- <td>"{@code keyboardHidden}"</td>
- <td>The keyboard accessibility has changed &mdash; for example, the
- user has slid the keyboard out to expose it.</td>
-</tr><tr>
- <td>"{@code navigation}"</td>
- <td>The navigation type has changed. (This should never normally happen.)</td>
-</tr><tr>
- <td>"{@code orientation}"</td>
- <td>The screen orientation has changed &mdash; that is, the user has rotated
- the device.</td>
- </tr><tr>
- <td>"{@code fontScale}"</td>
- <td>The font scaling factor has changed &mdash; that is, the user has selected
- a new global font size.</td>
-</tr>
-</table>
-
-<p>
-All of these configuration changes can impact the resource values seen by the
-application. Therefore, when <code>{@link android.app.Activity#onConfigurationChanged
-onConfigurationChanged()}</code> is called, it will generally be necessary to again
-retrieve all resources (including view layouts, drawables, and so on) to correctly
-handle the change.
-</p></dd>
-
-<dt>{@code android:enabled}</dt>
-<dd>Whether or not the activity can be instantiated by the system &mdash;
-"{@code true}" if it can be, and "{@code false}" if not. The default value
-is "{@code true}".
-
-<p>
-The {@code <a href="#app">&lt;application&gt;</a>} element has its own
-{@code <a href="#app_enabled">enabled</a>} attribute that applies to all
-application components, including activities. The
-{@code <a href="#app">&lt;application&gt;</a>} and {@code &lt;activity&gt;}
-attributes must both be "{@code true}" (as they both are by default) for
-the system to be able to instantiate the activity. If either is
-"{@code false}", it cannot be instantiated.
-</p></dd>
-
-<dt>{@code android:excludeFromRecents}</dt>
-<dd>Whether or not the activity should be excluded from the list of recently
-launched activities that can be displayed to users &mdash; "{@code true}" if
-it should be excluded, and "{@code false}" if it should be included.
-The default value is "{@code false}".
-</p></dd>
-
-<dt>{@code android:exported}</dt>
-<dd>Whether or not the activity can be launched by components of other
-applications &mdash; "{@code true}" if it can be, and "{@code false}" if not.
-If "{@code false}", the activity can be launched only by components of the
-same application or applications with the same user ID.
-
-<p>
-The default value depends on whether the activity contains intent filters. The
-absence of any filters means that the activity can be invoked only by specifying
-its exact class name. This implies that the activity is intended only for
-application-internal use (since others would not know the class name). So in
-this case, the default value is "{@code false}".
-On the other hand, the presence of at least one filter implies that the activity
-is intended for external use, so the default value is "{@code true}".
-</p>
-
-<p>
-This attribute is not the only way to limit an activity's exposure to other
-applications. You can also use a permission to limit the external entities that
-can invoke the activity (see the {@code <a href="#actv_prmsn">permission</a>}
-attribute).
-</p></dd>
-
-<dt>{@code android:finishOnTaskLaunch}</dt>
-<dd>Whether or not an existing instance of the activity should be shut down
-(finished) whenever the user again launches its task (chooses the task on the
-home screen) &mdash; "{@code true}" if it should be shut down, and "{@code false}"
-if not. The default value is "{@code false}".
-
-<p>
-If this attribute and {@code <a href="#actv_reparent">allowTaskReparenting</a>}
-are both "{@code true}", this attribute trumps the other. The affinity of the
-activity is ignored. The activity is not re-parented, but destroyed.
-</p>
-
-<dt><a name="actv_icon"></a>{@code android:icon}</dt>
-<dd>An icon representing the activity. The icon is displayed to users when
-a representation of the activity is required on-screen. For example, icons
-for activities that initiate tasks are displayed in the launcher window.
-The icon is often accompanied by a label (see the {@code label} attribute).
-</p>
-
-<p>
-This attribute must be set as a reference to a drawable resource containing
-the image definition. If it is not set, the icon specified for the application
-as a whole is used instead (see the {@code <a href="#app">&lt;application&gt;</a>}
-element's {@code <a href="#app_icon">icon</a>} attribute).
-</p>
-
-<p>
-The activity's icon &mdash; whether set here or by the
-{@code <a href="#app">&lt;application&gt;</a>} element &mdash; is also the
-default icon for all the activity's intent filters (see the
-{@code <a href="#ifilt">&lt;intent-filter&gt;</a>} element's
-{@code <a href="#ifilt_icon">icon</a>} attribute).
-</p></dd>
-
-<dt>{@code android:label}</dt>
-<dd>A user-readable label for the activity. The label is displayed on-screen
-when the activity must be represented to the user. It's often displayed along
-with the activity icon.
-
-<p>
-If this attribute is not set, the label set for the application as a whole is
-used instead (see the {@code <a href="#app">&lt;application&gt;</a>} element's
-{@code <a href="#app_label">label</a>} attribute).
-</p>
-
-<p>
-The activity's label &mdash; whether set here or by the
-{@code <a href="#app">&lt;application&gt;</a>} element &mdash; is also the
-default label for all the activity's intent filters (see the
-{@code <a href="#ifilt">&lt;intent-filter&gt;</a>} element's
-{@code <a href="#ifilt_label">label</a>} attribute).
-</p>
-
-<p>
-The label should be set as a reference to a string resource, so that
-it can be localized like other strings in the user interface.
-However, as a convenience while you're developing the application,
-it can also be set as a raw string.
-</p></dd>
-
-<dt><a name="actv_lmode"></a>{@code android:launchMode}</dt>
-<dd>An instruction on how the activity should be launched. There are four modes
-that work in conjunction with activity flags ({@code FLAG_ACTIVITY_*} constants)
-in {@link android.content.Intent} objects to determine what should happen when
-the activity is called upon to handle an intent:
-
-<p style="margin-left: 2em">"{@code standard}"
-<br>"{@code singleTop}"
-<br>"{@code singleTask}"
-<br>"{@code singleInstance}"</p>
-
-<p>
-The default mode is "{@code standard}".
-The modes differ from each other on three points:
-</p>
-
-<ol>
-
-<li><p><b>Whether or not a new instance of the class will be launched</b>. For
-the default "{@code standard}" mode, every time a new intent is received, a new
-instance of the class is created to handle that intent. For all the other modes,
-an existing instance is re-used if it resides at the top of the activity stack.
-As we'll see below, if there's an existing instance of a "{@code singleTask}" or
-"{@code singleInstance}" activity, it will always be (or come to be) at the top
-of the stack, so this condition will always be met for those two modes. However,
-an existing "{@code singleTop}" instance may or may not be at the top of the stack.
-If it is, it will be re-used. If not, a new instance is created.</p>
-
-<p>
-For example, suppose a task's activity stack consists of root activity A with
-activities B, C, and D on top in that order, so the stack is A-B-C-D. An intent
-arrives for an activity of type D. If D has the default "{@code standard}" launch
-mode, a new instance of the class is launched and the stack becomes A-B-C-D-D.
-However, if D's launch mode is "{@code singleTop}", the existing instance is
-expected to handle the new intent (since it's at the top of the stack) and the
-stack remains A-B-C-D.
-</p>
-
-<p>
-If, on the other hand, the arriving intent is for an activity of type B, a new
-instance of B would be launched no matter whether B's mode is "{@code standard}"
-or "{@code singleTop}" (since B is not at the top of the stack), so the resulting
-stack would be A-B-C-D-B.
-</p>
-
-<p>
-Now, suppose again that the stack is A-B-C-D and that the intent that arrives for
-B has the <code>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</code> flag set. Since
-the intent is destined for an activity of type B and the stack already has an object
-of that type, the flag causes activities C and D to be shut down and removed from
-the stack. If B's launch mode is "{@code standard}", it too will be removed, and
-a new instance of B launched to handle the incoming intent. That's because a new
-instance is always created for a new intent when the launch mode is "{@code standard}".
-However, if B's launch mode is "{@code singleTop}", the current instance would remain
-in the stack and receive the intent.
-</p>
-
-<p>
-Whenever an existing "{@code singleTop}", "{@code singleTask}", or
-"{@code singleInstance}" object is expected to handle an incoming intent, its
-<code>{@link android.app.Activity#onNewIntent onNewIntent()}</code> method is called with the
-{@link android.content.Intent} object passed as an argument.
-</p>
-</li>
-
-<li><p><b>Which task will hold the activity that responds to the intent</b>.
-For the "{@code standard}" and "{@code singleTop}" modes, it's the task that
-originated the intent (and called <code>{@link android.content.Context#startActivity
-startActivity()}</code>) &mdash; unless the Intent object contains the
-<code>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</code> flag. In that case,
-a different task is chosen as follows:</p>
-
-<ul>
-<li>If there's an existing task with the same affinity as the target activity,
-that task will hold the instance that responds to the intent. (As noted above,
-it could be an existing instance for a "{@code singleTop}" activity, but will
-always be a new instance for a "{@code standard}" activity.)</li>
-
-<li>Otherwise, the activity is launched as the root of a new task.</li>
-</ul>
-
-<p>
-In contrast, the "{@code singleTask}" and "{@code singleInstance}" modes mark
-activities that will always be at the root of a task; they can never be launched
-as part of another task. Moreover, once a "{@code singleTask}" or
-"{@code singleInstance}" activity has been launched, that instance is re-used
-to handle all new intents, so there is never more than one instance of the
-activity on the device.
-</p>
-
-<p>
-When a new intent arrives for an existing "{@code singleTask}" activity, all
-other activities are removed from its stack, so that only the root activity
-remains; it's as if the Intent object included the
-<code>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</code> flag. The activity
-is then at the top of its stack, and in a position to receive the new intent
-in an <code>{@link android.app.Activity#onNewIntent onNewIntent()}</code> call.
-</p></li>
-
-<li><p><b>Whether the instance can have other activities in its task</b>.
-A "{@code singleInstance}" activity stands alone as the only activity in its
-task. If it starts another activity, that activity will be launched in a
-different task regardless of its launch mode. In all other respects, the
-"{@code singleInstance}" mode is identical to "{@code singleTask}".</p>
-
-<p>
-All modes other than "{@code singleInstance}" permit multiple activities
-to belong to the task.
-</p></li>
-</ol>
-</dd>
-
-<dt>{@code android:multiprocess}</dt>
-<dd>Whether an instance of the activity can be launched into the process of the component
-that started it &mdash; "{@code true}" if it can be, and "{@code false}" if not.
-The default value is "{@code false}".
-
-<p>
-Normally, a new instance of an activity is launched into the process of the
-application that defined it, so all instances of the activity run in the same
-process. However, if this flag is set to "{@code true}", instances of the
-activity can run in multiple processes, allowing the system to create instances
-wherever they are used (provided permissions allow it), something that is almost
-never necessary or desirable.
-</p></dd>
-
-<dt>{@code android:name}</dt>
-<dd>The name of the class that implements the activity, a subclass of
-{@link android.app.Activity}. The attribute value should be a fully qualified
-class name (such as, "{@code com.example.project. ExtracurricularActivity}").
-However, as a shorthand, if the first character of the name is a period
-(for example, "{@code . ExtracurricularActivity}"), it is appended to the
-package name specified in the {@code <a href="#manf">&lt;manifest&gt;</a>}
-element.
-
-<p>
-There is no default. The name must be specified.
-</p></dd>
-
-<dt><a name="actv_prmsn"></a>{@code android:permission}</dt>
-<dd>The name of a permission that clients must have to launch the activity
-or otherwise get it to respond to an intent. If a caller of
-<code>{@link android.content.Context#startActivity startActivity()}</code> or
-<code>{@link android.app.Activity#startActivityForResult startActivityForResult()}</code>
-has not been granted the specified permission, its intent will not be
-delivered to the activity.
-
-<p>
-If this attribute is not set, the permission set by the
-{@code <a href="#app">&lt;application&gt;</a>} element's
-{@code <a href="#app_prmsn">permission</a>} attribute applies
-to the activity. If neither attribute is set, the activity is
-not protected by a permission.
-</p>
-
-<p>
-For more information on permissions, see the <a href="#sectperm">Permissions</a>
-section earlier in this document and a separate document,
-<a href="{@docRoot}guide/topics/security/security.html">Security and
-Permissions</a>.
-</p></dd>
-
-<dt>{@code android:process}</dt>
-<dd>The name of the process in which the activity should run. Normally,
-all components of an application run in the default process created for the
-application. It has the same name as the application package. The {@code <a href="#app">&lt;application&gt;</a>} element's
-{@code <a href="#app_proc">process</a>} attribute can set a different
-default for all components. But each component can override the default,
-allowing you to spread your application across multiple processes.
-
-<p>
-If the name assigned to this attribute begins with a colon (':'), a new
-process, private to the application, is created when it's needed and
-the activity runs in that process.
-If the process name begins with a lowercase character, the activity will run
-in a global process of that name, provided that it has permission to do so.
-This allows components in different applications to share a process, reducing
-resource usage.
-</p></dd>
-
-<dt>{@code android:screenOrientation}</dt>
-<dd>The orientation of the activity's display on the device.
-The value can be any one of the following strings:
-
-<table>
-<tr>
- <td>"{@code unspecified}"</td>
- <td>The default value. The system chooses the orientation. The policy it
- uses, and therefore the choices made in specific contexts, may differ
- from device to device.</td>
-</tr><tr>
- <td>"{@code landscape}"</td>
- <td>Landscape orientation (the display is wider than it is tall).</td>
-</tr><tr>
- <td>"{@code portrait}"</td>
- <td>Portrait orientation (the display is taller than it is wide).</td>
-</tr><tr>
- <td>"{@code user}"</td>
- <td>The user's current preferred orientation.</td>
-</tr><tr>
- <td>"{@code behind}"</td>
- <td>The same orientation as the activity that's immediately beneath it in
- the activity stack.</td>
-</tr><tr>
- <td>"{@code sensor}"</td>
- <td>The orientation determined by a physical orientation sensor. The
- orientation of the display depends on how the user is holding the device;
- it changes when the user rotates the device.</td>
-</tr><tr>
- <td>"{@code nosensor}"</td>
- <td>An orientation determined without reference to a physical orientation sensor.
- The sensor is ignored, so the display will not rotate based on how the user
- moves the device. Except for this distinction, the system chooses the
- orientation using the same policy as for the "{@code unspecified}" setting.</td>
-</tr>
-</table></dd>
-
-<dt>{@code android:stateNotNeeded}</dt>
-<dd>Whether or not the activity can be killed and successfully restarted
-without having saved its state &mdash; "{@code true}" if it can be restarted
-without reference to its previous state, and "{@code false}" if its previous
-state is required. The default value is "{@code false}".
-
-<p>
-Normally, before an activity is temporarily shut down to save resources, its
-<code>{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}</code>
-method is called. This method stores the current state of the activity in a
-{@link android.os.Bundle} object, which is then passed to
-<code>{@link android.app.Activity#onCreate onCreate()}</code> when the activity
-is restarted. If this attribute is set to "{@code true}",
-{@code onSaveInstanceState()} may not be called and {@code onCreate()} will
-be passed {@code null} instead of the Bundle &mdash; just as it was when the
-activity started for the first time.
-</p>
-
-<p>
-A "{@code true}" setting ensures that the activity can be restarted in the
-absence of retained state. For example, the activity that displays the
-home screen uses this setting to make sure that it does not get removed if it
-crashes for some reason.
-</p></dd>
-
-<dt><a name="actv_aff"></a>{@code android:taskAffinity}</dt>
-<dd>The task that the activity has an affinity for. Activities with
-the same affinity conceptually belong to the same task (to the same
-"application" from the user's perspective). The affinity of a task
-is determined by the affinity of its root activity.
-
-<p>
-The affinity determines two things &mdash; the task that the activity is re-parented
-to (see the {@code <a href="#actv_reparent">allowTaskReparenting</a>}
-attribute) and the task that will house the activity when it is launched
-with the <code>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</code>
-flag.
-</p>
-
-<p>
-By default, all activities in an application have the same affinity. You
-can set this attribute to group them differently, and even place
-activities defined in different applications within the same task. To
-specify that the activity does not have an affinity for any task, set
-it to an empty string.
-
-<p>
-If this attribute is not set, the activity inherits the affinity set
-for the application (see the {@code <a href="#app">&lt;application&gt;</a>}
-element's {@code <a href="#app_aff">taskAffinity</a>} attribute).
-The name of the default affinity for an application is the package name set
-by the {@code <a href="#manf">&lt;manifest&gt;</a>} element.
-</p>
-
-<dt><a name="actv_theme"></a>{@code android:theme}</dt>
-<dd>A reference to a style resource defining an overall theme for the activity.
-This automatically sets the activity's context to use this theme (see
-<code>{@link android.content.Context#setTheme setTheme()}</code>, and may also
-cause "starting" animations prior to the activity being launched (to better
-match what the activity actually looks like).
-
-<p>
-If this attribute is not set, the activity inherits the theme set for the
-application as a whole &mdash; see the {@code <a href="#app">&lt;application&gt;</a>}
-element's {@code <a href="#app_theme">theme</a>} attribute. If that attribute is
-also not set, the default system theme is used.
-</p>
-<dd>
-</dl></dd>
-
-</dl>
-<hr>
-
-
-<h3 id="alias">&lt;activity-alias&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;activity-alias android:enabled=["true" | "false"]
- android:exported=["true" | "false"]
- android:icon="<i>drawable resource</i>"
- android:label="<i>string resource</i>"
- android:name="<i>string</i>"
- android:permission="<i>string</i>"
- android:targetActivity="<i>string</i>" &gt;
- . . .
-&lt;/activity-alias&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#app">&lt;application&gt;</a>}</dd>
-
-<dt>can contain:</dt>
-<dd>{@code <a href="#ifilt">&lt;intent-filter&gt;</a>}
-<br/>{@code <a href="#meta">&lt;meta-data&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>An alias for an activity, named by the {@code targetActivity}
-attribute. The target must be in the same application as the
-alias and it must be declared before the alias in the manifest.
-
-<p>
-The alias presents the target activity as a independent entity.
-It can have its own set of intent filters, and they, rather than the
-intent filters on the target activity itself, determine which intents
-can activate the target through the alias and how the system
-treats the alias. For example, the intent filters on the alias may
-specify the "<code>{@link android.content.Intent#ACTION_MAIN
-android.intent.action.MAIN}</code>"
-and "<code>{@link android.content.Intent#CATEGORY_LAUNCHER
-android.intent.category.LAUNCHER}</code>" flags, causing it to be
-represented in the application launcher, even though none of the
-filters on the target activity itself set these flags.
-</p>
-
-<p>
-With the exception of {@code targetActivity}, {@code &lt;activity-alias&gt;}
-attributes are a subset of {@code <a href="#actv">&lt;activity&gt;</a>} attributes.
-For attributes in the subset, none of the values set for the target carry over
-to the alias. However, for attributes not in the subset, the values set for
-the target activity also apply to the alias.
-</p></dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:enabled}</dt>
-<dd>Whether or not the target activity can be instantiated by the system through
-this alias &mdash; "{@code true}" if it can be, and "{@code false}" if not.
-The default value is "{@code true}".
-
-<p>
-The {@code <a href="#app">&lt;application&gt;</a>} element has its own
-{@code <a href="#app_enabled">enabled</a>} attribute that applies to all
-application components, including activity aliases. The
-{@code <a href="#app">&lt;application&gt;</a>} and {@code &lt;activity-alias&gt;}
-attributes must both be "{@code true}" for the system to be able to instantiate
-the target activity through the alias. If either is "{@code false}", the alias
-does not work.
-</p></dd>
-
-<dt>{@code android:exported}</dt>
-<dd>Whether or not components of other applications can launch the target activity
-through this alias &mdash; "{@code true}" if they can, and "{@code false}" if not.
-If "{@code false}", the target activity can be launched through the alias only by
-components of the same application as the alias or applications with the same user ID.
-
-<p>
-The default value depends on whether the alias contains intent filters. The
-absence of any filters means that the activity can be invoked through the alias
-only by specifying the exact name of the alias. This implies that the alias
-is intended only for application-internal use (since others would not know its name)
-&mdash; so the default value is "{@code false}".
-On the other hand, the presence of at least one filter implies that the alias
-is intended for external use &mdash; so the default value is "{@code true}".
-</p></dd>
-
-<dt>{@code android:icon}</dt>
-<dd>An icon for the target activity when presented to users through the alias.
-See the {@code <a href="#actv">&lt;activity&gt;</a>} element's
-{@code <a href="#actv_icon">icon</a>} attribute for more information.
-
-<dt>{@code android:label}</dt>
-<dd>A user-readable label for the alias when presented to users through the alias.
-See the the {@code <a href="#actv">&lt;activity&gt;</a>} element's
-{@code <a href="#actv_label">label</a>} attribute for more information.
-</p></dd>
-
-<dt>{@code android:name}</dt>
-<dd>A unique name for the alias. The name should resemble a fully
-qualified class name. But, unlike the name of the target activity,
-the alias name is arbitrary; it does not refer to an actual class.
-</p></dd>
-
-<dt>{@code android:permission}</dt>
-<dd>The name of a permission that clients must have to launch the target activity
-or get it to do something via the alias. If a caller of
-<code>{@link android.content.Context#startActivity startActivity()}</code> or
-<code>{@link android.app.Activity#startActivityForResult startActivityForResult()}</code>
-has not been granted the specified permission, the target activity will not be
-activated.
-
-<p>This attribute supplants any permission set for the target activity itself. If
-it is not set, a permission is not needed to activate the target through the alias.
-</p>
-
-<p>
-For more information on permissions, see the {@code <a href="#perms">Permissions</a>
-section earlier in this document.
-</p></dd>
-
-<dt>{@code android:targetActivity}</dt>
-<dd>The name of the activity that can be activated through the alias.
-This name must match the {@code name} attribute of an
-{@code <a href="#actv">&lt;activity&gt;</a>} element that precedes
-the alias in the manifest.
-</p></dd>
-</dl></dd>
-
-<dt>see also:</dt>
-<dd>{@code <a href="#actv">&lt;activity&gt;</a>}</dd>
-
-</dl>
-<hr>
-
-<h3 id="app">&lt;application&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;application android:allowClearUserData=["true" | "false"]
- android:allowTaskReparenting=["true" | "false"]
- android:debuggable=["true" | "false"]
- android:description="<i>string resource</i>"
- android:enabled=["true" | "false"]
- android:hasCode=["true" | "false"]
- android:icon="<i>drawable resource</i>"
- android:label="<i>string resource</i>"
- android:manageSpaceActivity="<i>string</i>"
- android:name="<i>string</i>"
- android:permission="<i>string</i>"
- android:persistent=["true" | "false"]
- android:process="<i>string</i>"
- android:taskAffinity="<i>string</i>"
- android:theme="<i>resource or theme</i>" &gt;
- . . .
-&lt;/application&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#manf">&lt;manifest&gt;</a>}</dd>
-
-<dt>can contain:</dt>
-<dd>{@code <a href="#actv">&lt;activity&gt;</a>}
-<br/>{@code <a href="#alias">&lt;activity-alias&gt;</a>}
-<br/>{@code <a href="#srvc">&lt;service&gt;</a>}
-<br/>{@code <a href="#rcvr">&lt;receiver&gt;</a>}
-<br/>{@code <a href="#pvdr">&lt;provider&gt;</a>}
-<br/>{@code <a href="#usesl">&lt;uses-library&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>The declaration of the application. This element contains subelements
-that declare each of the application's components and has attributes
-that can affect all the components. Many of these attributes (such as
-{@code icon}, {@code label}, {@code permission}, {@code process},
-{@code taskAffinity}, and {@code allowTaskReparenting}) set default values
-for corresponding attributes of the component elements. Others (such as
-{@code debuggable}, {@code enabled}, {@code description}, and
-{@code allowClearUserData}) set values for the application as a whole and
-cannot be overridden by the components.</dd>
-
-<dt>attributes</dt>
-<dd><dl class="attr">
-<dt>{@code android:allowClearUserData}</dt>
-<dd>Whether or not users are given the option to remove user data &mdash;
-"{@code true}" if they are, and "{@code false}" if not. If the value is
-"{@code true}", as it is by default, the application manager includes an
-option that allows users to clear the data.</dd>
-
-<dt><a name="app_reparent"></a>{@code android:allowTaskReparenting}</dt>
-<dd>Whether or not activities that the application defines can move from
-the task that started them to the task they have an affinity for when that task
-is next brought to the front &mdash; "{@code true}" if they can move, and
-"{@code false}" if they must remain with the task where they started.
-The default value is "{@code false}".
-
-<p>
-The {@code <a href="#actv">&lt;activity&gt;</a>} element has its own
-{@code <a href="#act_reparent">allowTaskReparenting</a>} attribute
-that can override the value set here. See that attribute for more
-information.
-</p></dd>
-
-<dt>{@code android:debuggable}</dt>
-<dd>Whether or not the application can be debugged, even when running
-on a device in user mode &mdash; "{@code true}" if it can be, and "{@code false}"
-if not. The default value is "{@code false}".</dd>
-
-<dt>{@code android:description}</dt>
-<dd>User-readable text about the application, longer and more descriptive than the application label. The value must be set as a reference to a string resource. Unlike the label, it cannot be a raw string. There is no default value.</dd>
-
-<dt><a name="app_enabled"></a>{@code android:enabled}</dt>
-<dd>Whether or not the Android system can instantiate components of
-the application &mdash; "{@code true}" if it can, and "{@code false}"
-if not. If the value is "{@code true}", each component's
-{@code enabled} attribute determines whether that component is enabled
-or not. If the value is "{@code false}", it overrides the
-component-specific values; all components are disabled.
-
-<p>
-The default value is "{@code true}".
-</p></dd>
-
-<dt>{@code android:hasCode}</dt>
-<dd>Whether or not the application contains any code &mdash; "{@code true}"
-if it does, and "{@code false}" if not. When the value is "{@code false}",
-the system does not try to load any application code when launching components.
-The default value is "{@code true}".
-
-<p>
-An application would not have any code of its own only if it's using nothing
-but built-in component classes, such as an activity that uses the {@link
-android.app.AliasActivity} class, a rare occurrence.
-
-<dt><a name="app_icon"></a>{@code android:icon}</dt>
-<dd>An icon for the application as whole, and the default icon for
-each of the application's components. See the individual
-{@code icon} attributes for
-{@code <a href="#actv">&lt;activity&gt;</a>},
-{@code <a href="#alias">&lt;activity-alias&gt;</a>},
-{@code <a href="#srvc">&lt;service&gt;</a>},
-{@code <a href="#rcvr">&lt;receiver&gt;</a>}, and
-{@code <a href="#pvdr">&lt;provider&gt;</a>} elements.
-
-<p>
-This attribute must be set as a reference to a drawable resource containing
-the image definition. There is no default icon.
-</p></dd>
-
-<dt><a name="app_label"></a>{@code android:label}</dt>
-<dd>A user-readable label for the application as a whole, and a default
-label for each of the application's components. See the individual
-{@code label} attributes for
-{@code <a href="#actv">&lt;activity&gt;</a>},
-{@code <a href="#alias">&lt;activity-alias&gt;</a>},
-{@code <a href="#srvc">&lt;service&gt;</a>},
-{@code <a href="#rcvr">&lt;receiver&gt;</a>}, and
-{@code <a href="#pvdr">&lt;provider&gt;</a>} elements.
-
-<p>
-The label should be set as a reference to a string resource, so that
-it can be localized like other strings in the user interface.
-However, as a convenience while you're developing the application,
-it can also be set as a raw string.
-</p></dd>
-
-<dt>{@code android:manageSpaceActivity}</dt>
-<dd>The fully qualified name of an Activity subclass that the system
-can launch to let users manage the memory occupied by the application
-on the device. The activity should also be declared with an
-{@code <a href="#actv">&lt;activity&gt;</a>} element.
-</dd>
-
-<dt>{@code android:name}</dt>
-<dd>The fully qualified name of an {@link android.app.Application}
-subclass implemented for the application. When the application process
-is started, this class is instantiated before any of the application's
-components.
-
-<p>
-The subclass is optional; most applications won't need one.
-In the absence of a subclass, Android uses an instance of the base
-Application class.
-</p></dd>
-
-<dt><a name="app_prmsn"></a>{@code android:permission}</dt>
-<dd>The name of a permission that clients must have in order to interact
-with the application. This attribute is a convenient way to set a
-permission that applies to all of the application's components. It can
-be overwritten by setting the {@code permission} attributes of individual
-components.
-
-<p>
-For more information on permissions, see the <a href="#sectperm">Permissions</a>
-section earlier in this document and a separate document,
-<a href="{@docRoot}guide/topics/security/security.html">Security and
-Permissions</a>.
-</p></dd>
-
-<dt>{@code android:persistent}</dt>
-<dd>Whether or not the application should remain running at all times &mdash;
-"{@code true}" if it should, and "{@code false}" if not. The default value
-is "{@code false}". Applications should not normally set this flag;
-persistence mode is intended only for certain system applications.</dd>
-
-<dt><a name="app_proc"></a>{@code android:process}</dt>
-<dd>The name of a process where all components of the application should run.
-Each component can override this default by setting its own {@code process}
-attribute.
-
-<p>
-By default, Android creates a process for an application when the first
-of its components needs to run. All components then run in that process.
-The name of the default process matches the package name set by the
-{@code <a href="#manf">&lt;manifest&gt;</a>} element.
-</p>
-
-<p>By setting this attribute to a process name that's shared with another
-application, you can arrange for components of both applications to run in
-the same process &mdash; but only if the two applications also share a
-user ID and be signed with the same certificate.
-</p>
-
-<p>
-If the name assigned to this attribute begins with a colon (':'), a new
-process, private to the application, is created when it's needed.
-If the process name begins with a lowercase character, a global process
-of that name is created. A global process can be shared with other
-applications, reducing resource usage.
-</p></dd>
-
-<dt><a href name="app_aff"></a>{@code android:taskAffinity}</dt>
-<dd>An affinity name that applies to all activities within the application,
-except for those that set a different affinity with their own {@code
-<a href="#actv_aff">taskAffinity</a>} attributes. See that attribute
-for more information.
-
-<p>
-By default, all activities within an application share the same
-affinity. The name of that affinity is the same as the package name
-set by the {@code <a href="#manf">&lt;manifest&gt;</a>} element.
-</p></dd>
-
-<dt><a name="app_theme"></a>{@code android:theme}</dt>
-<dd>A reference to a style resource defining a default theme for all
-activities in the application. Individual activities can override
-the default by setting their own {@code <a href="#actv_theme">theme</a>}
-attributes; see that attribute for more information.</dd>
-
-</dl></dd>
-
-<dt>see also:</dt>
-<dd>{@code <a href="#actv">&lt;activity&gt;</a>}
-<br/>{@code <a href="#srvc">&lt;service&gt;</a>}
-<br/>{@code <a href="#rcvr">&lt;receiver&gt;</a>}
-<br/>{@code <a href="#pvdr">&lt;provider&gt;</a>}</dd>
-
-</dl>
-<hr>
-
-<h3 id="catg">&lt;category&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;category android:name="<i>string</i>" /&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#ifilt">&lt;intent-filter&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Adds a category name to an intent filter. See
-<a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and
-Intent Filters</a> for details on intent filters and the role of category
-specifications within a filter.</dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:name}</dt>
-<dd>The name of the category. Standard categories are defined in the
-{@link android.content.Intent} class as {@code CATEGORY_<i>name</i>}
-constants. The name assigned here can be derived from those constants
-by prefixing "{@code android.intent.category.}" to the
-{@code <i>name</i>} that follows {@code CATEGORY_}. For example,
-the string value for {@code CATEGORY_LAUNCHER} is
-"{@code android.intent.category.LAUNCHER}".
-
-<p>
-Custom categories should use the package name as a prefix, to ensure
-that they are unique.
-</p></dd>
-</dl></dd>
-
-<dt>see also:</dt>
-<dd>{@code <a href="#actn">&lt;action&gt;</a>}
-<br/>{@code <a href="#data">&lt;data&gt;</a>}</dd>
-
-</dl>
-<hr>
-
-<h3 id="data">&lt;data&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;data android:host="<i>string</i>"
- android:mimeType="<i>string</i>"
- android:path="<i>string</i>"
- android:pathPattern="<i>string</i>"
- android:pathPrefix="<i>string</i>"
- android:port="<i>string</i>"
- android:scheme="<i>string</i>" /&gt;</pre></dd>
-
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#ifilt">&lt;intent-filter&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Adds a data specification to an intent filter. The specification can
-be just a data type (the {@code <a href="#data_mime">mimeType</a>} attribute),
-just a URI, or both a data type and a URI. A URI is specified by separate
-attributes for each of its parts:
-
-<p style="margin-left: 2em">{@code scheme://host:port/path} <i>or</i>
-{@code pathPrefix} <i>or</i> {@code pathPattern}</p>
-
-<p>
-These attributes are optional, but also mutually dependent:
-If a {@code <a href="#data_scheme">scheme</a>} is not specified for the
-intent filter, all the other URI attributes are ignored. If a
-{@code <a href="#data_host">host</a>} is not specified for the filer,
-the {@code port} attribute and all the path attributes are ignored.
-</p>
-
-<p>
-All the {@code &lt;data&gt;} elements contained within the same
-{@code <a href="#ifilt">&lt;intent-filter&gt;</a>} element contribute to
-the same filter. So, for example, the following filter specification,
-</p>
-
-<pre>&lt;intent-filter . . . &gt;
- &lt;data android:scheme="something" android:host="project.example.com" /&gt;
- . . .
-&lt;/intent-filter&gt;</pre>
-
-<p>is equivalent to this one:</p>
-
-<pre>&lt;intent-filter . . . &gt;
- &lt;data android:scheme="something" /&gt
- &lt;data android:host="project.example.com" /&gt;
- . . .
-&lt;/intent-filter&gt;</pre>
-
-<p>
-You can place any number of &lt;data&gt; elements inside an
-{@code <a href="#ifilt">&lt;intent-filter&gt;</a>} to give it multiple data
-options. None of its attributes have default values.
-</p>
-
-<p>
-Information on how intent filters work, including the rules for how Intent objects
-are matched against filters, can be found in another document,
-<a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and
-Intent Filters</a>. See also the <a href="#ifs">Intent Filters</a> section
-earlier in this document.
-</p></dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt><a name="data_host"></a>{@code android:host}</dt>
-<dd>The host part of a URI authority. This attribute is meaningless
-unless a {@code <a href="#data_scheme">scheme</a>} attribute is also
-specified for the filter.
-</dd>
-
-<dt><a name="data_mime"></a>{@code android:mimeType}</dt>
-<dd>A MIME media type, such as {@code image/jpeg} or {@code audio/mpeg4-generic}.
-The subtype can be the asterisk wildcard ({@code *}) to indicate that any
-subtype matches.</dd>
-
-<dt>{@code android:path}
-<br/>{@code android:pathPrefix}
-<br/>{@code android:pathPattern}</dt>
-<dd>The path part of a URI. The {@code path} attribute specifies a complete
-path that is matched against the complete path in an Intent object. The
-{@code pathPrefix} attribute specifies a partial path that is matched against
-only the initial part of the path in the Intent object. The {@code pathPattern}
-attribute specifies a complete path that is matched against the complete path
-in the Intent object, but it can contain the following wildcards:
-
-<ul>
-<li>An asterisk ('{@code *}') matches a sequence of 0 to many occurrences of
-the immediately preceding character.</li>
-
-<li><p>A period followed by an asterisk ("{@code .*}") matches any sequence of
-0 to many characters.</p></li>
-</ul>
-
-<p>
-Because '{@code \}' is used as an escape character when the string is read
-from XML (before it is parsed as a pattern), you will need to double-escape:
-For example, a literal '{@code *}' would be written as "{@code \\*}" and a
-literal '{@code \}' would be written as "{@code \\\\}". This is basically
-the same as what you would need to write if constructing the string in Java code.
-</p>
-
-<p>
-For more information on these three types of patterns, see the descriptions of
-{@link android.os.PatternMatcher#PATTERN_LITERAL},
-{@link android.os.PatternMatcher#PATTERN_PREFIX}, and
-{@link android.os.PatternMatcher#PATTERN_SIMPLE_GLOB} in the
-{@link android.os.PatternMatcher} class.
-</p>
-
-<p>These attributes are meaningful only if the
-{@code <a href="#data_scheme">scheme</a>} and
-{@code <a href="#data_host">host</a>}
-attributes are also specified for the filter.
-</p></dd>
-
-<dt>{@code android:port}</dt>
-<dd>The port part of a URI authority. This attribute is meaningful only
-if the {@code <a href="#data_scheme">scheme</a>} and
-{@code <a href="#data_host">host</a>} attributes are also specified for
-the filter.</dd>
-
-<dt><a name="data_scheme"></a>{@code android:scheme}</dt>
-<dd>The scheme part of a URI. This is the minimal essential attribute for
-specifying a URI; at least one {@code scheme} attribute must be set
-for the filter, or none of the other URI attributes are meaningful.
-
-<p>
-A scheme is specified without the trailing colon (for example,
-{@code http}, rather than {@code http:}).
-</p>
-
-<p>
-If the filter has a data type set (the {@code <a href="#data_mime">mimeType</a>}
-attribute) but no scheme, the {@code content:} and {@code file:} schemes are
-assumed.
-</p></dd>
-</dl></dd>
-
-<dt>see also:</dt>
-<dd>{@code <a href="#actn">&lt;action&gt;</a>}
-<br/>{@code <a href="#catg">&lt;category&gt;</a>}</dd>
-
-</dl>
-<hr>
-
-<h3 id="grantp">&lt;grant-uri-permission&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;grant-uri-permission android:path="<i>string</i>"
- android:pathPattern="<i>string</i>"
- android:pathPrefix="<i>string</i>" /&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#pvdr">&lt;provider&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Specifies which data subsets of the parent content provider permission
-can be granted for. Data subsets are indicated by the path part of a
-{@code content:} URI. (The authority part of the URI identifies the
-content provider.)
-Granting permission is a way of enabling clients of the provider that don't
-normally have permission to access its data to overcome that restriction on
-a one-time basis.
-
-<p>
-If a content provider's {@code <a href="#pvdr_gprmsn">grantUriPermissions</a>}
-attribute is "{@code true}", permission can be granted for any the data under
-the provider's purview. However, if that attribute is "{@code false}", permission
-can be granted only to data subsets that are specified by this element.
-A provider can contain any number of {@code &lt;grant-uri-permission&gt;} elements.
-Each one can specify only one path (only one of the three possible attributes).
-</p>
-
-<p>
-For information on how permission is granted, see the
-{@code <a href="#ifilt">&lt;intent-filter&gt;</a>} element's
-{@code <a href="#pvdr_gprmsn">grantUriPermissions</a>} attribute.
-</p></dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:path}
-<br/>{@code android:pathPrefix}
-<br/>{@code android:pathPattern}</dt>
-<dd>A path identifying the data subset or subsets that permission can be
-granted for. The {@code path} attribute specifies a complete path;
-permission can be granted only to the particular data subset identified
-by that path.
-The {@code pathPrefix} attribute specifies the initial part of a path;
-permission can be granted to all data subsets with paths that share that
-initial part.
-The {@code pathPattern} attribute specifies a complete path, but one
-that can contain the following wildcards:
-
-<ul>
-<li>An asterisk ('{@code *}') matches a sequence of 0 to many occurrences of
-the immediately preceding character.</li>
-
-<li><p>A period followed by an asterisk ("{@code .*}") matches any sequence of
-0 to many characters.</p></li>
-</ul>
-
-<p>
-Because '{@code \}' is used as an escape character when the string is read
-from XML (before it is parsed as a pattern), you will need to double-escape:
-For example, a literal '{@code *}' would be written as "{@code \\*}" and a
-literal '{@code \}' would be written as "{@code \\\\}". This is basically
-the same as what you would need to write if constructing the string in Java code.
-</p>
-
-<p>
-For more information on these types of patterns, see the descriptions of
-{@link android.os.PatternMatcher#PATTERN_LITERAL},
-{@link android.os.PatternMatcher#PATTERN_PREFIX}, and
-{@link android.os.PatternMatcher#PATTERN_SIMPLE_GLOB} in the
-{@link android.os.PatternMatcher} class.
-</p></dd>
-</dl></dd>
-
-<dt>see also:</dt>
-<dd>the {@code <a href="#pvdr_gprmsn">grantUriPermissions</a>} attribute
-of the {@code <a href="#pvdr">&lt;provider&gt;</a>} element</dd>
-
-
-</dl>
-<hr>
-
-<h3 id="instru">&lt;instrumentation&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;instrumentation android:functionalTest=["true" | "false"]
- android:handleProfiling=["true" | "false"]
- android:icon="<i>drawable resource</i>"
- android:label="<i>string resource</i>"
- android:name="<i>string</i>"
- android:targetPackage="<i>string</i>" /&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#manf">&lt;manifest&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Declares an {@link android.app.Instrumentation} class that enables you
-to monitor an application's interaction with the system. The Instrumentation
-object is instantiated before any of the application's components.</dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:functionalTest}</dt>
-<dd>Whether or not the Instrumentation class should run as a functional test
-&mdash; "{@code true}" if it should, and "{@code false}" if not. The
-default value is "{@code false}".</dd>
-
-<dt>{@code android:handleProfiling}</dt>
-<dd>Whether or not the Instrumentation object will turn profiling on and
-off &mdash; "{@code true}" if it determines when profiling starts and
-stops, and "{@code false}" if profiling continues the entire time it is
-running. A value of "{@code true}" enables the object to target profiling
-at a specific set of operations. The default value is "{@code false}".</dd>
-
-<dt>{@code android:icon}</dt>
-<dd>An icon that represents the Instrumentation class. This attribute must
-be set as a reference to a drawable resource.</dd>
-
-<dt>{@code android:label}</dt>
-<dd>A user-readable label for the Instrumentation class. The label can
-be set as a raw string or a reference to a string resource.</dd>
-
-<dt>{@code android:name}</dt>
-<dd>The name of the {@link android.app.Instrumentation} subclass.
-This should be a fully qualified class name (such as,
-"{@code com.example.project.StringInstrumentation}"). However, as a shorthand,
-if the first character of the name is a period, it is appended to the package
-name specified in the {@code <a href="#manf">&lt;manifest&gt;</a>} element.
-
-<p>
-There is no default. The name must be specified.
-</p></dd>
-
-<dt>{@code android:targetPackage}</dt>
-<dd>The application that the Instrumentation object will run against.
-An application is identified by the package name assigned in its manifest
-file by the {@code <a href="#manf">&lt;manifest&gt;</a>} element.</dd>
-
-</dl></dd>
-
-</dl>
-<hr>
-
-<h3 id="ifilt">&lt;intent-filter&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;intent-filter android:icon="<i>drawable resource</i>"
- android:label="<i>string resource</i>"
- android:priority="<i>integer</i>" &gt;
- . . .
-&lt;/intent-filter&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#actv">&lt;activity&gt;</a>}
-<br/>{@code <a href="#alias">&lt;activity-alias&gt;</a>}
-<br/>{@code <a href="#srvc">&lt;service&gt;</a>}
-<br/>{@code <a href="#rcvr">&lt;receiver&gt;</a>}</dd>
-
-<dt>must contain:</dt>
-<dd>{@code <a href="#actn">&lt;action&gt;</a>}</dd>
-
-<dt>can contain:</dt>
-<dd>{@code <a href="#catg">&lt;category&gt;</a>}
-<br/>{@code <a href="#data">&lt;data&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Specifies the types of intents that an activity, service, or broadcast
-receiver can respond to. An intent filter declares the capabilities of its
-parent component &mdash; what an activity or service can do and what types
-of broadcasts a receiver can handle. It opens the component to receiving
-intents of the advertised type, while filtering out those that are not
-meaningful for the component.
-
-<p>
-Most of the contents of the filter are described by its
-{@code <a href="#actn">&lt;action&gt;</a>},
-{@code <a href="#catg">&lt;category&gt;</a>}, and
-{@code <a href="#data">&lt;data&gt;</a>} subelements.
-</p>
-
-<p>
-For a more detailed discussion of filters, see the separate
-<a href="{@docRoot}guide/topics/intents/intents-filters.html">Intents
-and Intent Filters</a> document, as well as the
-<a href="#ifs">Intents Filters</a> section earlier in this document.
-</p></dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt><a name="ifilt_icon"></a>{@code android:icon}</dt>
-<dd>An icon that represents the parent activity, service, or broadcast
-receiver when that component is presented to the user as having the
-capability described by the filter.
-
-<p>
-This attribute must be set as a reference to a drawable resource
-containing the image definition. The default value is the icon set
-by the parent component's {@code icon} attribute. If the parent
-does not specify an icon, the default is the icon set by the
-{@code <a href="#app">&lt;application&gt;</a>} element.
-</p>
-
-<p>
-For more on intent filter icons, see <a href="#iconlabel">Icons and Labels</a>,
-earlier.
-</p></dd>
-
-<dt>{@code android:label}</dt>
-<dd>A user-readable label for the parent component. This label, rather than
-the one set by the parent component, is used when the component is presented
-to the user as having the capability described by the filter.
-
-<p>
-The label should be set as a reference to a string resource, so that
-it can be localized like other strings in the user interface.
-However, as a convenience while you're developing the application,
-it can also be set as a raw string.
-</p>
-
-<p>
-The default value is the label set by the parent component. If the
-parent does not specify a label, the default is the label set by the
-{@code <a href="#app">&lt;application&gt;</a>} element's
-{@code <a href="#app_label"> label</a>} attribute.
-</p>
-
-<p>
-For more on intent filter labels, see <a href="#iconlabel">Icons and Labels</a>,
-earlier.
-</p></dd>
-
-<dt>{@code android:priority}</dt>
-<dd>The priority that should be given to the parent component with regard
-to handling intents of the type described by the filter. This attribute has
-meaning for both activities and broadcast receivers:
-
-<ul>
-<li>It provides information about how able an activity is to respond to
-an intent that matches the filter, relative to other activities that could
-also respond to the intent. When an intent could be handled by multiple
-activities with different priorities, Android will consider only those with
-higher priority values as potential targets for the intent.</li>
-
-<li><p>It controls the order in which broadcast receivers are executed to
-receive broadcast messages. Those with higher priority
-values are called before those with lower values. (The order applies only
-to synchronous messages; it's ignored for asynchronous messages.)</p></li>
-</ul>
-
-<p>
-Use this attribute only if you really need to impose a specific order in
-which the broadcasts are received, or want to force Android to prefer
-one activity over others.
-</p>
-
-<p>
-The value must be an integer, such as "{@code 100}". Higher numbers have a
-higher priority.
-</p></dd>
-
-</dl></dd>
-
-<dt>see also:</dt>
-<dd>{@code <a href="#actn">&lt;action&gt;</a>}
-<br/>{@code <a href="#catg">&lt;category&gt;</a>}
-<br/>{@code <a href="#data">&lt;data&gt;</a>}</dd>
-
-</dl>
-<hr>
-
-
-<h3 id="manf">&lt;manifest&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="<i>string</i>"
- android:sharedUserId="<i>string</i>"
- android:versionCode="<i>integer</i>"
- android:versionName="<i>string</i>" &gt;
- . . .
-&lt;/manifest&gt;</pre></dd>
-
-<p>
-<dt>contained in:</dt>
-<dd><i>none</i></dd>
-
-<p>
-<p>
-<dt>must contain:</dt>
-<dd>{@code <a href="#app">&lt;application&gt;</a>}</dd>
-
-<dt>can contain:</dt>
-<dd>{@code <a href="#instru">&lt;instrumentation&gt;</a>}
-<br/>{@code <a href="#prmsn">&lt;permission&gt;</a>}
-<br/>{@code <a href="#pgroup">&lt;permission-group&gt;</a>}
-<br/>{@code <a href="#ptree">&lt;permission-tree&gt;</a>}
-<br/>{@code <a href="#usesp">&lt;uses-permission&gt;</a>}</dd>
-
-<p>
-<dt>description:</dt>
-<dd>The root element of the AndroidManifest.xml file. It must
-contain an {@code <a href="#app">&lt;application&gt;</a>} element
-and specify {@code xlmns:android} and {@code package} attributes.</dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code xmlns:android}</dt>
-<dd>Defines the Android namespace. This attribute should always be set
-to "{@code http://schemas.android.com/apk/res/android}".</dd>
-
-<dt><a name="manf_package"></a>{@code package}</dt>
-<dd>A full Java package name for the application. The name should
-be unique. For example, applications published by Google could have
-names in the form <code>com.google.app.<i>application_name</i></code>.
-
-<p>
-The package name serves as a unique identifier for the application.
-It's also the default name for the task affinity of components
-(see the {@code <a href="#app_aff">taskAffinity</a>} attribute).
-</p></dd>
-
-<dt>{@code android:sharedUserId}</dt>
-<dd>The name of a Linux user ID that will be shared with other applications.
-By default, Android assigns each application its own unique user ID.
-However, if this attribute is set to the same value for two or more applications,
-they will all share the same ID &mdash; provided that they are also signed
-by the same certificate. Application with the same user ID can access each
-other's data and, if desired, run in the same process.</dd>
-
-<dt>{@code android:versionCode}</dt>
-<dd>An internal version number. This number is used only to determine whether
-one version is more recent than another, with higher numbers indicating more
-recent versions. This is not the version number shown to users; that number
-is set by the {@code versionName} attribute.
-
-<p>
-The value must be set as an integer, such as "100". You can define it however
-you want, as long as each successive version has a higher number. For example,
-it could be a build number. Or you could translate a version number in "x.y"
-format to an integer by encoding the "x" and "y" separately in the lower and
-upper 16 bits. Or you could simply increase the number by one each time a new
-version is released.
-</p></dd>
-
-<dt>{@code android:versionName}</dt>
-<dd>The version number shown to users. This attribute can be set as a raw
-string or as a reference to a string resource. The string has no other purpose
-than to be displayed to users. The {@code versionCode} attribute holds
-the significant version number used internally.
-</dl></dd>
-
-<p>
-<dt>see also:</dt>
-<dd>{@code <a href="#app">&lt;application&gt;</a>}</dd>
-
-</dl>
-<hr>
-
-<h3 id="meta">&lt;meta-data&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;meta-data android:name="<i>string</i>"
- android:resource="<i>resource specification</i>"
- android:value="<i>string</i>" /&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#actv">&lt;activity&gt;</a>}
-<br/>{@code <a href="#alias">&lt;activity-alias&gt;</a>}
-<br/>{@code <a href="#srvc">&lt;service&gt;</a>}
-<br/>{@code <a href="#rcvr">&lt;receiver&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>A name-value pair for an item of additional, arbitrary data that can
-be supplied to the parent component. A component element can contain any
-number of {@code &lt;meta-data&gt;} subelements. The values from all of
-them are collected in a single {@link android.os.Bundle} object and made
-available to the component as the
-{@link android.content.pm.PackageItemInfo#metaData
-PackageItemInfo.metaData} field.
-
-<p>
-Ordinary values are specified through the {@code <a href="#meta_value">value</a>}
-attribute. However, to assign a resource ID as the value, use the
-{@code <a href="#meta_resource">resource</a>} attribute instead. For example,
-the following code assigns whatever value is stored in the {@code @string/kangaroo}
-resource to the "{@code zoo}" name:
-</p>
-
-<pre>&lt;meta-data android:name="zoo" android:value="@string/kangaroo" /&gt;</pre>
-
-<p>
-On the other hand, using the {@code resource} attribute would assign "{@code zoo}"
-the numeric ID of the resource, not the value stored in the resource:
-</p>
-
-<pre>&lt;meta-data android:name="zoo" android:resource="@string/kangaroo" /&gt;</pre>
-
-<p>
-It is highly recommended that you avoid supplying related data as
-multiple separate {@code &lt;meta-data&gt;} entries. Instead, if you
-have complex data to associate with a component, store it as a resource and
-use the {@code resource} attribute to inform the component of its ID.
-</p></dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:name}</dt>
-<dd>A unique name for the item. To ensure that the name is unique, use a
-Java-style naming convention &mdash; for example,
-"{@code com.example.project.activity.fred}".</dd>
-
-<dt>{@code android:resource}</dt>
-<dd>A reference to a resource. The ID of the resource is the value assigned
-to the item. The ID can be retrieved from the meta-data Bundle by the
-{@link android.os.Bundle#getInt Bundle.getInt()} method.</dd>
-
-<dt>{@code android:value}</dt>
-<dd>The value assigned to the item. The data types that can be assigned as values and the Bundle methods that components use to retrieve those values are listed in the following table:
-
-<table>
-<tr>
- <th>Type</th>
- <th>Bundle method</th>
-</tr><tr>
- <td>String value, using double backslashes ({@code \\}) to escape characters
- &mdash; such as "{@code \\n}" and "{@code \\uxxxxx}" for a Unicode character.</td>
- <td>{@link android.os.Bundle#getString(String) getString()}</td>
-</tr><tr>
- <td>Integer value, such as "{@code 100}"</td>
- <td>{@link android.os.Bundle#getInt(String) getInt()}</td>
-</tr><tr>
- <td>Boolean value, either "{@code true}" or "{@code false}"</td>
- <td>{@link android.os.Bundle#getBoolean(String) getBoolean()}</td>
-</tr><tr>
- <td>Color value, in the form "{@code #rgb}", "{@code #argb}",
- "{@code #rrggbb}", or "{@code #aarrggbb}"</td>
- <td>{@link android.os.Bundle#getString(String) getString()}</td>
-</tr><tr>
- <td>Float value, such as "{@code 1.23}"</td>
- <td>{@link android.os.Bundle#getFloat(String) getFloat()}</td>
-</tr>
-</table>
-</dd>
-</dl></dd>
-
-</dl>
-<hr>
-
-<h3 id="prmsn">&lt;permission&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt></dt>
-<dd><pre class="stx">&lt;permission android:description="<i>string resource</i>"
- android:icon="<i>drawable resource</i>"
- android:label="<i>string resource</i>"
- android:name="<i>string</i>"
- android:permissionGroup="<i>string</i>"
- android:protectionLevel=["normal" | "dangerous" |
- "signature" | "signatureOrSystem"] /&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#manf">&lt;manifest&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Declares a security permission that can be used to limit access
-to specific components or features of this or other applications.
-See the <a href="#perms">Permissions</a>, earlier in this document,
-and the <a href="{@docRoot}guide/topics/security/security.html">Security Model</a>
-document for more information on how permissions work.</dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:description}</dt>
-<dd>A user-readable description of the permission, longer and more
-informative than the label. It may be displayed to explain the
-permission to the user &mdash; for example, when the user is asked
-whether to grant the permission to another application.
-
-<p>
-This attribute must be set as a reference to a string resource;
-unlike the {@code label} attribute, it cannot be a raw string.
-</p></dd>
-
-<dt>{@code android:icon}</dt>
-<dd>A reference to a drawable resource for an icon that represents the
-permission.</dd>
-
-<dt>{@code android:label}</dt>
-<dd>A name for the permission, one that can be displayed to users.
-
-<p>
-As a convenience, the label can be directly set
-as a raw string while you're developing the application. However,
-when the application is ready to be published, it should be set as a
-reference to a string resource, so that it can be localized like other
-strings in the user interface.
-</p></dd>
-
-<dt>{@code android:name}</dt>
-<dd>The name of the permission. This is the name that will be used in
-code to refer to the permission &mdash; for example, in a
-{@code <a href="#usesp">&lt;uses-permission&gt;</a>} element and the
-{@code permission} attributes of application components.</dd>
-
-<p>
-The name must be unique, so it should use Java-style scoping &mdash;
-for example, "{@code com.example.project.PERMITTED_ACTION}".
-</p></dd>
-
-<dt>{@code android:permissionGroup}</dt>
-<dd>Assigns this permission to a group. The value of this attribute is
-the name of the group, which must be declared with the
-{@code <a href="#pgroup">&lt;permission-group&gt;</a>} element in this
-or another application. If this attribute is not set, the permission
-does not belong to a group.</dd>
-
-<dt>{@code android:protectionLevel}</dt>
-<dd>Characterizes the potential risk implied in the permission and
-indicates the procedure the system should follow when determining
-whether or not to grant the permission to an application requesting it.
-The value can be set to one of the following strings:
-
-<table>
-<tr>
- <th>Value</th>
- <th>Meaning</th>
-</tr><tr>
- <td>"{@code normal}"</td>
- <td>The default value. A lower-risk permission that gives requesting
- applications access to isolated application-level features, with
- minimal risk to other applications, the system, or the user.
- The system automatically grants this type
- of permission to a requesting application at installation, without
- asking for the user's explicit approval (though the user always
- has the option to review these permissions before installing).
-</tr><tr>
- <td>"{@code dangerous}"</td>
- <td>A higher-risk permission that would give a requesting application
- access to private user data or control over the device that can
- negatively impact the user. Because this type of permission
- introduces potential risk, the system may not automatically
- grant it to the requesting application. For example, any dangerous
- permissions requested by an application may be displayed to the
- user and require confirmation before proceeding, or some other
- approach may be taken to avoid the user automatically allowing
- the use of such facilities.
-</tr><tr>
- <td>"{@code signature}"</td>
- <td>A permission that the system grants only if the requesting
- application is signed with the same certificate as the application
- that declared the permission. If the certificates match, the system
- automatically grants the permission without notifying the user or
- asking for the user's explicit approval.
-</tr><tr>
- <td>"{@code signatureOrSystem}"</td>
- <td>A permission that the system grants only to applications that are
- in the Android system image <em>or</em> that are signed with the same
- certificates as those in the system image. Please avoid using this
- option, as the {@code signature} protection level should be sufficient
- for most needs and works regardless of exactly where applications are
- installed. The "{@code signatureOrSystem}"
- permission is used for certain special situations where multiple
- vendors have applications built into a system image and need
- to share specific features explicitly because they are being built
- together.
-</tr>
-</table>
-</dd>
-</dl></dd>
-
-<dt>see also:</dt>
-<dd>{@code <a href="#usesp">&lt;uses-permission&gt;</a>}
-<br/>{@code <a href="#ptree">&lt;permission-tree&gt;</a>}
-<br/>{@code <a href="#pgroup">&lt;permission-group&gt;</a>}</dd>
-</dd>
-
-</dl>
-<hr>
-
-<h3 id="pgroup">&lt;permission-group&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;permission-group android:description="<i>string resource</i>"
- android:icon="<i>drawable resource</i>"
- android:label="<i>string resource</i>"
- android:name="<i>string</i>" /&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#manf">&lt;manifest&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Declares a name for a logical grouping of related permissions. Individual
-permission join the group through the {@code permissionGroup} attribute of the
-{@code <a href="#prmsn">&lt;permission&gt;</a>} element. Members of a group are
-presented together in the user interface.
-
-<p>
-Note that this element does not declare a permission itself, only a category in
-which permissions can be placed. See the
-{@code <a href="#prmsn">&lt;permission&gt;</a>} element for element for information
-on declaring permissions and assigning them to groups.
-</p></dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:description}</dt>
-<dd>User-readable text that describes the group. The text should be
-longer and more explanatory than the label. This attribute must be
-set as a reference to a string resource. Unlike the {@code label}
-attribute, it cannot be a raw string.</dd>
-
-<dt>{@code android:icon}</dt>
-<dd>An icon representing the permission. This attribute must be set
-as a reference to a drawable resource containing the image definition.</dd>
-
-<dt>{@code android:label}</dt>
-<dd>A user-readable name for the group. As a convenience, the label can
-be directly set as a raw string while you're developing the application.
-However, when the application is ready to be published, it should be set
-as a reference to a string resource, so that it can be localized like other
-strings in the user interface.</dd>
-
-<dt>{@code android:name}</dt>
-<dd>The name of the group. This is the name that can be assigned to a
-{@code <a href="#prmsn">&lt;permission&gt;</a>} element's
-{@code permissionGroup} attribute.</dd>
-</dl></dd>
-
-<dt>see also:</dt>
-<dd>{@code <a href="#prmsn">&lt;permission&gt;</a>}
-<br/>{@code <a href="#ptree">&lt;permission-tree&gt;</a>}
-<br/>{@code <a href="#usesp">&lt;uses-permission&gt;</a>}</dd>
-
-</dl>
-<hr>
-
-<h3 id="ptree">&lt;permission-tree&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;permission-tree android:icon="<i>drawable resource</i>"
- android:label="<i>string resource</i>" ]
- android:name="<i>string</i>" /&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#manf">&lt;manifest&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Declares the base name for a tree of permissions. The application takes
-ownership of all names within the tree. It can dynamically add new permissions
-to the tree by calling <code>{@link android.content.pm.PackageManager#addPermission PackageManager.addPermission()}</code>. Names within the tree are separated by
-periods ('{@code .}'). For example, if the base name is
-{@code com.example.project.taxes}, permissions like the following might be
-added:
-
-<p style="margin-left: 2em">{@code com.example.project.taxes.CALCULATE}
-<br/>{@code com.example.project.taxes.deductions.MAKE_SOME_UP}
-<br/>{@code com.example.project.taxes.deductions.EXAGGERATE}</p>
-
-<p>
-Note that this element does not declare a permission itself, only a
-namespace in which further permissions can be placed.
-See the {@code <a href="#prmsn">&lt;permission&gt;</a>} element for
-information on declaring permissions.
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:icon}</dt>
-<dd>An icon representing all the permissions in the tree. This attribute
-must be set as a reference to a drawable resource containing the image
-definition.</dd>
-
-<dt>{@code android:label}</dt>
-<dd>A user-readable name for the group. As a convenience, the label can
-be directly set as a raw string for quick and dirty programming. However,
-when the application is ready to be published, it should be set as a
-reference to a string resource, so that it can be localized like other
-strings in the user interface.</dd>
-
-<dt>{@code android:name}</dt>
-<dd>The name that's at the base of the permission tree. It serves as
-a prefix to all permission names in the tree. Java-style scoping should
-be used to ensure that the name is unique. The name must have more than
-two period-separated seqments in its path &mdash; for example,
-{@code com.example.base} is OK, but {@code com.example} is not.</dd>
-
-</dl></dd>
-
-<p>
-<dt>see also:</dt>
-<dd>{@code <a href="#prmsn">&lt;permission&gt;</a>}
-<br/>{@code <a href="#pgroup">&lt;permission-group&gt;</a>}
-<br/>{@code <a href="#usesp">&lt;uses-permission&gt;</a>}
-</dd>
-
-</dl>
-<hr>
-
-<h3 id="pvdr">&lt;provider&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;provider android:authorities="<i>list</i>"
- android:enabled=["true" | "false"]
- android:exported=["true" | "false"]
- android:grantUriPermissions=["true" | "false"]
- android:icon="<i>drawable resource</i>"
- android:initOrder="<i>integer</i>"
- android:label="<i>string resource</i>"
- android:multiprocess=["true" | "false"]
- android:name="<i>string</i>"
- android:permission="<i>string</i>"
- android:process="<i>string</i>"
- android:readPermission="<i>string</i>"
- android:syncable=["true" | "false"]
- android:writePermission="<i>string</i>" &gt;
- . . .
-&lt;/provider&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#app">&lt;application&gt;</a>}</dd>
-
-<dt>can contain:</dt>
-<dd>{@code <a href="#meta">&lt;meta-data&gt;</a>}
-<br/>{@code <a href="#grantp">&lt;grant-uri-permission&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Declares a content provider &mdash; a subclass of
-{@link android.content.ContentProvider} &mdash; that supplies structured
-access to data managed by the application. All content providers that
-are part of the application must be represented by {@code &lt;provider&gt;}
-elements in the manifest file. The system cannot see, and therefore will
-not run, any that are not declared. (You need to declare only
-those content providers that you develop as part of your application,
-not those developed by others that your application uses.)
-
-<p>
-The Android system identifies content providers by the authority part
- of a {@code content:} URI. For example, suppose that the following URI
-is passed to <code>{@link android.content.ContentResolver#query
-ContentResolver.query()}</code>:
-
-<p style="margin-left: 2em">{@code content://com.example.project.healthcareprovider/nurses/rn}</p>
-
-<p>
-The {@code content:} scheme identifies the data as belonging to a content
-provider and the authority ({@code com.example.project.healthcareprovider})
-identifies the particular provider. The authority therefore must be unique.
-Typically, as in this example, it's the fully qualified name of a
-ContentProvider subclass. The path part of a URI may be used by a content
-provider to identify particular data subsets, but those paths are not
-declared in the manifest.
-</p>
-
-<p>
-For information on using and developing content providers, see a separate document,
-<a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>.
-</p></dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:authorities}</dt>
-<dd>A list of one or more URI authorities that identify data under the purview
-of the content provider.
-Multiple authorities are listed by separating their names with a semicolon.
-To avoid conflicts, authority names should use a Java-style naming convention
-(such as {@code com.example.provider.cartoonprovider}). Typically, it's the name
-of the ContentProvider subclass.
-
-<p>
-There is no default. At least one authority must be specified.
-</p></dd>
-
-<dt>{@code android:enabled}</dt>
-<dd>Whether or not the content provider can be instantiated by the system &mdash;
-"{@code true}" if it can be, and "{@code false}" if not. The default value
-is "{@code true}".
-
-<p>
-The {@code <a href="#app">&lt;application&gt;</a>} element has its own
-{@code <a href="#app_enabled">enabled</a>} attribute that applies to all
-application components, including content providers. The
-{@code <a href="#app">&lt;application&gt;</a>} and {@code &lt;provider&gt;}
-attributes must both be "{@code true}" (as they both
-are by default) for the content provider to be enabled. If either is
-"{@code false}", the provider is disabled; it cannot be instantiated.
-</p></dd>
-
-<dt>{@code android:exported}</dt>
-<dd>Whether or not the content provider can be used by components of other
-applications &mdash; "{@code true}" if it can be, and "{@code false}" if not.
-If "{@code false}", the provider is available only to components of the
-same application or applications with the same user ID. The default value
-is "{@code true}".
-
-<p>
-You can export a content provider but still limit access to it with the
-{@code <a href="#pvdr_prmsn">permission</a>} attribute.
-</p></dd>
-
-<dt><a name="grantp_gprmns"></a>{@code android:grantUriPermissions}</dt>
-<dd>Whether or not those who ordinarily would not have permission to
-access the content provider's data can be granted permission to do so,
-temporarily overcoming the restriction imposed by the
-{@code <a href="#pvdr_rprmsn">readPermission</a>},
-{@code <a href="#pvdr_wprmsn">writePermission</a>}, and
-{@code <a href="#pvdr_prmsn">permission</a>} attributes
-&mdash;
-"{@code true}" if permission can be granted, and "{@ code false}" if not.
-If "{@code true}", permission can be granted to any of the content
-provider's data. If "{@code false}", permission can be granted only
-to the data subsets listed in
-{@code <a href="#grantp">&lt;grant-uri-permission&gt;</a>} subelements,
-if any. The default value is "{@code false}".
-
-<p>
-Granting permission is a way of giving an application component one-time
-access to data protected by a permission. For example, when an e-mail
-message contains an attachment, the mail application may call upon the
-appropriate viewer to open it, even though the viewer doesn't have general
-permission to look at all the content provider's data.
-</p>
-
-<p>
-In such cases, permission is granted by
-<code>{@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}</code>
-and <code>{@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION}</code>
-flags in the Intent object that activates the component. For example, the
-mail application might put {@code FLAG_GRANT_READ_URI_PERMISSION} in the
-Intent passed to {@code Context.startActivity()}. The permission is specific
-to the URI in the Intent.
-</p>
-
-<p>
-If you enable this feature, either by setting this attribute to "{@code true}"
-or by defining {@code <a href="#grantp">&lt;grant-uri-permission&gt;</a>}
-subelements, you must call
-<code>{@link android.content.Context#revokeUriPermission
-Context.revokeUriPermission()}</code> when a covered URI is deleted from
-the provider.
-</p>
-
-<p>
-See also the {@code <a href="#grantp">&lt;grant-uri-permission&gt;</a>}
-element.
-</p></dd>
-
-<dt><a name="pvdr_icon"></a>{@code android:icon}</dt>
-<dd>An icon representing the content provider.
-This attribute must be set as a reference to a drawable resource containing
-the image definition. If it is not set, the icon specified for the application
-as a whole is used instead (see the {@code <a href="#app">&lt;application&gt;</a>}
-element's {@code <a href="#app_icon">icon</a>} attribute).</dd>
-
-<dt>{@code android:initOrder}</dt>
-<dd>The order in which the content provider should be instantiated,
-relative to other content providers hosted by the same process.
-When there are dependencies among content providers, setting this
-attribute for each of them ensures that they are created in the order
-required by those dependencies. The value is a simple integer,
-with higher numbers being initialized first.</dd>
-
-<dt>{@code android:label}</dt>
-<dd>A user-readable label for the content provided.
-If this attribute is not set, the label set for the application as a whole is
-used instead (see the {@code <a href="#app">&lt;application&gt;</a>} element's
-{@code <a href="#app_label">label</a>} attribute).
-
-<p>
-The label should be set as a reference to a string resource, so that
-it can be localized like other strings in the user interface.
-However, as a convenience while you're developing the application,
-it can also be set as a raw string.
-</p></dd>
-
-<dt>{@code android:multiprocess}</dt>
-<dd>Whether or not an instance of the content provider can be created in
-every client process &mdash; "{@code true}" if instances can run in multiple
-processes, and "{@code false}" if not. The default value is "{@code false}".
-
-<p>
-Normally, a content provider is instantiated in the process of the
-application that defined it. However, if this flag is set to "{@code true}",
-the system can create an instance in every process where there's a client
-that wants to interact withit, thus avoiding the overhead of interprocess
-communication.
-</p></dd>
-
-<dt>{@code android:name}</dt>
-<dd>The name of the class that implements the content provider, a subclass of
-{@link android.content.ContentProvider}. This should be a fully qualified
-class name (such as, "{@code com.example.project.TransportationProvider}").
-However, as a shorthand, if the first character of the name is a period,
-it is appended to the package name specified in the
-{@code <a href="#manf">&lt;manifest&gt;</a>} element.
-
-<p>
-There is no default. The name must be specified.
-</p></dd>
-
-
-<dt>{@code android:permission}</dt>
-<dd>The name of a permission that clients must have to read or write the
-content provider's data. This attribute is a convenient way of setting a
-single permission for both reading and writing. However, the
-{@code <a href="#pvdr_rprmsn">readPermission</a>} and
-{@code <a href="#pvdr_wprmsn">writePermission</a>} attributes take precedence
-over this one. If the {@code <a href="#pvdr_rprmsn">readPermission</a>}
-attribute is also set, it controls access for querying the content provider.
-And if the {@code <a href="#pvdr_wprmsn">writePermission</a>} attribute is set,
-it controls access for modifying the provider's data.
-
-<p>
-For more information on permissions, see the <a href="#sectperm">Permissions</a>
-section earlier in this document and a separate document,
-<a href="{@docRoot}guide/topics/security/security.html">Security and
-Permissions</a>.
-</p></dd>
-
-<dt>{@code android:process}</dt>
-<dd>The name of the process in which the content provider should run. Normally,
-all components of an application run in the default process created for the
-application. It has the same name as the application package. The {@code <a href="#app">&lt;application&gt;</a>} element's
-{@code <a href="#app_proc">process</a>} attribute can set a different
-default for all components. But each component can override the default
-with its own {@code process} attribute, allowing you to spread your
-application across multiple processes.
-
-<p>
-If the name assigned to this attribute begins with a colon (':'), a new
-process, private to the application, is created when it's needed and
-the activity runs in that process.
-If the process name begins with a lowercase character, the activity will run
-in a global process of that name, provided that it has permission to do so.
-This allows components in different applications to share a process, reducing
-resource usage.
-</p></dd>
-
-<dt>{@code android:readPermission}</dt>
-<dd>A permission that clients must have to query the content provider.
-See also the {@code <a href="#pvdr_prmsn">permission</a>} and
-{@code <a href="#pvdr_wprmsn">writePermission</a>} attributes.</dd>
-
-<dt>{@code android:syncable}</dt>
-<dd>Whether or not the data under the content provider's control
-is to be synchronized with data on a server &mdash; "{@code true}"
-if it is to be synchronized, and "{@ code false}" if not.</dd>
-
-<dt>{@code android:writePermission}</dt>
-<dd>A permission that clients must have to make changes to the data
-controlled by the content provider.
-See also the {@code <a href="#pvdr_prmsn">permission</a>} and
-{@code <a href="#pvdr_rprmsn">readPermission</a>} attributes.</dd>
-
-</dl></dd>
-
-<p>
-<dt>see also:</dt>
-<dd><a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a></dd>
-
-</dl>
-<hr>
-
-<h3 id="rcvr">&lt;receiver&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;receiver android:enabled=["true" | "false"]
- android:exported=["true" | "false"]
- android:icon="<i>drawable resource</i>"
- android:label="<i>string resource</i>"
- android:name="<i>string</i>"
- android:permission="<i>string</i>"
- android:process="<i>string</i>" &gt;
- . . .
-&lt;/receiver&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#app">&lt;application&gt;</a>}</dd>
-
-<dt>can contain:</dt>
-<dd>{@code <a href="#ifilt">&lt;intent-filer&gt;</a>}
-<br/>{@code <a href="#meta">&lt;meta-data&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Declares a broadcast receiver (a {@link android.content.BroadcastReceiver}
-subclass) as one of the application's components. Broadcast receivers enable
-applications to receive intents that are broadcast by the system or by other
-applications, even when other components of the application are not running.
-
-<p>
-There are two ways to make a broadcast receiver known to the system: One is
-declare it in the manifest file with this element. The other is to create
-the receiver dynamically in code and register it with the <code>{@link
-android.content.Context#registerReceiver Context.registerReceiver()}</code>
-method. See the {@link android.content.BroadcastReceiver} class description
-for more on dynamically created receivers.
-</p></dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:enabled}</dt>
-<dd>Whether or not the broadcast receiver can be instantiated by the system &mdash;
-"{@code true}" if it can be, and "{@code false}" if not. The default value
-is "{@code true}".
-
-<p>
-The {@code <a href="#app">&lt;application&gt;</a>} element has its own
-{@code <a href="#app_enabled">enabled</a>} attribute that applies to all
-application components, including broadcast receivers. The
-{@code <a href="#app">&lt;application&gt;</a>} and
-{@code &lt;receiver&gt;} attributes must both be "{@code true}" for
-the broadcast receiver to be enabled. If either is "{@code false}", it is
-disabled; it cannot be instantiated.
-</p></dd>
-
-<dt>{@code android:exported}</dt>
-<dd>Whether or not the broadcast receiver can receive messages from sources
-outside its application &mdash; "{@code true}" if it can, and "{@code false}"
-if not. If "{@code false}", the only messages the broadcast receiver can
-receive are those sent by components of the same application or applications
-with the same user ID.
-
-<p>
-The default value depends on whether the broadcast receiver contains intent filters.
-The absence of any filters means that it can be invoked only by Intent objects that
-specify its exact class name. This implies that the receiver is intended only for
-application-internal use (since others would not normally know the class name).
-So in this case, the default value is "{@code false}".
-On the other hand, the presence of at least one filter implies that the broadcast
-receiver is intended to receive intents broadcast by the system or other applications,
-so the default value is "{@code true}".
-</p>
-
-<p>
-This attribute is not the only way to limit a broadcast receiver's external exposure.
-You can also use a permission to limit the external entities that can send it messages
-(see the {@code <a href="#rcvr_prmsn">permission</a>} attribute).
-</p></dd>
-
-<dt><a name="rcvr_icon"></a>{@code android:icon}</dt>
-<dd>An icon representing the broadcast receiver. This attribute must be set
-as a reference to a drawable resource containing the image definition.
-If it is not set, the icon specified for the application as a whole is used
-instead (see the {@code <a href="#app">&lt;application&gt;</a>}
-element's {@code <a href="#app_icon">icon</a>} attribute).
-
-<p>
-The broadcast receiver's icon &mdash; whether set here or by the
-{@code <a href="#app">&lt;application&gt;</a>} element &mdash; is also the
-default icon for all the receiver's intent filters (see the
-{@code <a href="#ifilt">&lt;intent-filter&gt;</a>} element's
-{@code <a href="#ifilt_icon">icon</a>} attribute).
-</p></dd>
-
-<dt>{@code android:label}</dt>
-<dd>A user-readable label for the broadcast receiver. If this attribute is not
-set, the label set for the application as a whole is
-used instead (see the {@code <a href="#app">&lt;application&gt;</a>} element's
-{@code <a href="#app_label">label</a>} attribute).
-
-<p>
-The broadcast receiver's label &mdash; whether set here or by the
-{@code <a href="#app">&lt;application&gt;</a>} element &mdash; is also the
-default label for all the receiver's intent filters (see the
-{@code <a href="#ifilt">&lt;intent-filter&gt;</a>} element's
-{@code <a href="#ifilt_label">label</a>} attribute).
-</p>
-
-<p>
-The label should be set as a reference to a string resource, so that
-it can be localized like other strings in the user interface.
-However, as a convenience while you're developing the application,
-it can also be set as a raw string.
-</p></dd>
-
-<dt>{@code android:name}</dt>
-<dd>The name of the class that implements the broadcast receiver, a subclass of
-{@link android.content.BroadcastReceiver}. This should be a fully qualified
-class name (such as, "{@code com.example.project.ReportReceiver}"). However,
-as a shorthand, if the first character of the name is a period (for example,
-"{@code . ReportReceiver}"), it is appended to the package name specified in
-the {@code <a href="#manf">&lt;manifest&gt;</a>} element.
-
-<p>
-There is no default. The name must be specified.
-</p></dd>
-
-<dt><a name="rcvr_prmsn"></a>{@code android:permission}</dt>
-<dd>The name of a permission that broadcasters must have to send a
-message to the broadcast receiver.
-If this attribute is not set, the permission set by the
-{@code <a href="#app">&lt;application&gt;</a>} element's
-{@code <a href="#app_prmsn">permission</a>} attribute applies
-to the broadcast receiver. If neither attribute is set, the receiver
-is not protected by a permission.
-
-<p>
-For more information on permissions, see the <a href="#sectperm">Permissions</a>
-section earlier in this document and a separate document,
-<a href="{@docRoot}guide/topics/security/security.html">Security and
-Permissions</a>.
-</p></dd>
-
-<dt>{@code android:process}</dt>
-<dd>The name of the process in which the broadcast receiver should run.
-Normally, all components of an application run in the default process created
-for the application. It has the same name as the application package. The
-{@code <a href="#app">&lt;application&gt;</a>} element's
-{@code <a href="#app_proc">process</a>} attribute can set a different
-default for all components. But each component can override the default
-with its own {@code process} attribute, allowing you to spread your
-application across multiple processes.
-
-<p>
-If the name assigned to this attribute begins with a colon (':'), a new
-process, private to the application, is created when it's needed and
-the broadcast receiver runs in that process.
-If the process name begins with a lowercase character, the receiver will run
-in a global process of that name, provided that it has permission to do so.
-This allows components in different applications to share a process, reducing
-resource usage.
-</p></dd>
-</dl></dd>
-
-</dl>
-<hr>
-
-<h3 id="srvc">&lt;service&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;service android:enabled=["true" | "false"]
- android:exported[="true" | "false"]
- android:icon="<i>drawable resource</i>"
- android:label="<i>string resource</i>"
- android:name="<i>string</i>"
- android:permission="<i>string</i>"
- android:process="<i>string</i>" &gt;
- . . .
-&lt;/service&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#app">&lt;application&gt;</a>}</dd>
-
-<dt>can contain:</dt>
-<dd>{@code <a href="#ifilt">&lt;intent-filer&gt;</a>}
-<br/>{@code <a href="#meta">&lt;meta-data&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Declares a service (a {@link android.app.Service} subclass) as one
-of the application's components. Unlike activities, services lack a
-visual user interface. They're used to implement long-running background
-operations or a rich communications API that can be called by other
-applications.
-
-<p>
-All services must be represented by {@code &lt;service&gt;} elements in
-the manifest file. Any that are not declared there will not be seen
-by the system and will never be run.
-</p></dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:enabled}</dt>
-<dd>Whether or not the service can be instantiated by the system &mdash;
-"{@code true}" if it can be, and "{@code false}" if not. The default value
-is "{@code true}".
-
-<p>
-The {@code <a href="#app">&lt;application&gt;</a>} element has its own
-{@code <a href="#app_enabled">enabled</a>} attribute that applies to all
-application components, including services. The
-{@code <a href="#app">&lt;application&gt;</a>} and {@code &lt;service&gt;}
-attributes must both be "{@code true}" (as they both
-are by default) for the service to be enabled. If either is
-"{@code false}", the service is disabled; it cannot be instantiated.
-</p></dd>
-
-<dt>{@code android:exported}</dt>
-<dd>Whether or not components of other applications can invoke
-the service or interact with it &mdash; "{@code true}" if they can, and
-"{@code false}" if not. When the value is "{@code false}", only
-components of the same application or applications
-with the same user ID can start the service or bind to it.
-
-<p>
-The default value depends on whether the service contains intent filters. The
-absence of any filters means that it can be invoked only by specifying
-its exact class name. This implies that the service is intended only for
-application-internal use (since others would not know the class name). So in
-this case, the default value is "{@code false}".
-On the other hand, the presence of at least one filter implies that the service
-is intended for external use, so the default value is "{@code true}".
-</p>
-
-<p>
-This attribute is not the only way to limit the exposure of a service to other
-applications. You can also use a permission to limit the external entities that
-can interact with the service (see the {@code <a href="#srvc_prmsn">permission</a>}
-attribute).
-</p></dd>
-
-<dt><a name="srvc_icon"></a>{@code android:icon}</dt>
-<dd>An icon representing the service. This attribute must be set as a
-reference to a drawable resource containing the image definition.
-If it is not set, the icon specified for the application
-as a whole is used instead (see the {@code <a href="#app">&lt;application&gt;</a>}
-element's {@code <a href="#app_icon">icon</a>} attribute).
-</p>
-
-<p>
-The service's icon &mdash; whether set here or by the
-{@code <a href="#app">&lt;application&gt;</a>} element &mdash; is also the
-default icon for all the service's intent filters (see the
-{@code <a href="#ifilt">&lt;intent-filter&gt;</a>} element's
-{@code <a href="#ifilt_icon">icon</a>} attribute).
-</p></dd>
-
-<dt>{@code android:label}</dt>
-<dd>A name for the service that can be displayed to users.
-If this attribute is not set, the label set for the application as a whole is
-used instead (see the {@code <a href="#app">&lt;application&gt;</a>} element's
-{@code <a href="#app_label">label</a>} attribute).
-
-<p>
-The service's label &mdash; whether set here or by the
-{@code <a href="#app">&lt;application&gt;</a>} element &mdash; is also the
-default label for all the service's intent filters (see the
-{@code <a href="#ifilt">&lt;intent-filter&gt;</a>} element's
-{@code <a href="#ifilt_label">label</a>} attribute).
-</p>
-
-<p>
-The label should be set as a reference to a string resource, so that
-it can be localized like other strings in the user interface.
-However, as a convenience while you're developing the application,
-it can also be set as a raw string.
-</p></dd>
-
-<dt>{@code android:name}</dt>
-<dd>The name of the {@link android.app.Service} subclass that implements
-the service. This should be a fully qualified class name (such as,
-"{@code com.example.project.RoomService}"). However, as a shorthand, if
-the first character of the name is a period (for example, "{@code .RoomService}"),
-it is appended to the package name specified in the
-{@code <a href="#manf">&lt;manifest&gt;</a>} element.
-
-<p>
-There is no default. The name must be specified.
-</p></dd>
-
-<dt><a name="srvc_prmsn"></a>{@code android:permission}</dt>
-<dd>The name of a permission that that an entity must have in order to
-launch the service or bind to it. If a caller of
-<code>{@link android.content.Context#startService startService()}</code>,
-<code>{@link android.content.Context#bindService bindService()}</code>, or
-<code>{@link android.content.Context#stopService stopService()}</code>,
-has not been granted this permission, the method will not work and the
-Intent object will not be delivered to the service.
-
-<p>
-If this attribute is not set, the permission set by the
-{@code <a href="#app">&lt;application&gt;</a>} element's
-{@code <a href="#app_prmsn">permission</a>} attribute applies
-to the service. If neither attribute is set, the service is
-not protected by a permission.
-</p>
-
-<p>
-For more information on permissions, see the <a href="#sectperm">Permissions</a>
-section earlier in this document and a separate document,
-<a href="{@docRoot}guide/topics/security/security.html">Security and
-Permissions</a>.
-</p></dd>
-
-<dt>{@code android:process}</dt>
-<dd>The name of the process where the service is to run. Normally,
-all components of an application run in the default process created for the
-application. It has the same name as the application package. The
-{@code <a href="#app">&lt;application&gt;</a>} element's
-{@code <a href="#app_proc">process</a>} attribute can set a different
-default for all components. But component can override the default
-with its own {@code process} attribute, allowing you to spread your
-application across multiple processes.
-
-<p>
-If the name assigned to this attribute begins with a colon (':'), a new
-process, private to the application, is created when it's needed and
-the service runs in that process.
-If the process name begins with a lowercase character, the service will run
-in a global process of that name, provided that it has permission to do so.
-This allows components in different applications to share a process, reducing
-resource usage.
-</p></dd>
-</dl></dd>
-
-<dt>see also:</dt>
-<dd>{@code <a href="#app">&lt;application&gt;</a>}
-<br>{@code <a href="#actv">&lt;activity&gt;</a>}</dd>
-
-</dl>
-<hr>
-
-<h3 id="usesl">&lt;uses-library&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre>&lt;uses-library android:name="<i>string</i>" /&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#app">&lt;application&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Specifies a shared library that the application must be linked against.
-This element tells the system to include the library's code in the class
-loader for the package.
-
-<p>
-All of the {@code android} packages (such as {@link android.app},
-{@link android.content}, {@link android.view}, and {@link android.widget})
-are in the default library that all applications are automatically linked
-against. However, some packages (such as {@code maps} and {@code awt} are
-in separate libraries that are not automatically linked. Consult the
-documentation for the packages you're using to determine which library
-contains the package code.
-</p></dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:name}</dt>
-<dd>The name of the library.</dd>
-</dl></dd>
-
-</dl>
-<hr>
-
-
-<h3 id="usesp">&lt;uses-permission&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;uses-permission android:name="<i>string</i>" /&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#manf">&lt;manifest&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Requests a permission that the application must be granted in
-order for it to operate correctly. Permissions are granted when the
-application is installed, not while it's running.
-
-<p>
-For more information on permissions, see the
-{@code <a href="#perms">Permissions</a>} section earlier in this document
-and the separate <a href="{@docRoot}guide/topics/security/security.html">Security Model</a>
-document.
-A list of permissions defined by the base platform can be found at
-{@link android.Manifest.permission android.Manifest.permission}.
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:name}</dt>
-<dd>The name of the permission. It can be a permission defined by the
-application with the {@code <a href="#prmsn">&lt;permission&gt;</a>}
-element, a permission defined by another application, or one of the
-standard system permissions, such as "{@code android.permission.CAMERA}"
-or "{@code android.permission.READ_CONTACTS}". As these examples show,
-a permission name typically includes the package name as a prefix.</dd>
-
-</dl></dd>
-
-<dt>see also:</dt>
-<dd>{@code <a href="#prmsn">&lt;permission&gt;</a>}</dd>
-
-</dl>
-<hr>
-
-
-<h3 id="usess">&lt;uses-sdk&gt;</h3>
-
-<dl class="xml">
-<dt>syntax:</dt>
-<dd><pre class="stx">&lt;uses-sdk android:minSdkVersion="<i>integer</i>" /&gt;</pre></dd>
-
-<dt>contained in:</dt>
-<dd>{@code <a href="#manf">&lt;manifest&gt;</a>}</dd>
-
-<dt>description:</dt>
-<dd>Declares which versions of the Android SDK (software development kit)
-the application can run against. The version number is incremented when
-there are additions to the API and resource tree, so an application developed
-using version 3 of the SDK may not run against versions 1 or 2, but should
-run against version 3, 4, 5, and above.
-
-<p>
-The default is version 1. The current version is also 1.
-</p></dd>
-
-<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt>{@code android:minSdkVersion}</dt>
-<dd>An integer designating the minimum version of the SDK that's required
-for the application to run.</dd>
-
-</dl></dd>
-
-</dl>
-
-
diff --git a/docs/html/guide/topics/manifest/meta-data-element.jd b/docs/html/guide/topics/manifest/meta-data-element.jd
new file mode 100644
index 0000000..1c91407
--- /dev/null
+++ b/docs/html/guide/topics/manifest/meta-data-element.jd
@@ -0,0 +1,90 @@
+page.title=&lt;meta-data&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;meta-data android:<a href="#nm">name</a>="<i>string</i>"
+ android:<a href="#rsrc">resource</a>="<i>resource specification</i>"
+ android:<a href="#val">value</a>="<i>string</i>" /&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;activity-alias&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>A name-value pair for an item of additional, arbitrary data that can
+be supplied to the parent component. A component element can contain any
+number of {@code &lt;meta-data&gt;} subelements. The values from all of
+them are collected in a single {@link android.os.Bundle} object and made
+available to the component as the
+{@link android.content.pm.PackageItemInfo#metaData
+PackageItemInfo.metaData} field.
+
+<p>
+Ordinary values are specified through the <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#value">value</a></code>
+attribute. However, to assign a resource ID as the value, use the
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#resource">resource</a></code> attribute instead. For example,
+the following code assigns whatever value is stored in the {@code @string/kangaroo}
+resource to the "{@code zoo}" name:
+</p>
+
+<pre>&lt;meta-data android:name="zoo" android:value="@string/kangaroo" /&gt;</pre>
+
+<p>
+On the other hand, using the {@code resource} attribute would assign "{@code zoo}"
+the numeric ID of the resource, not the value stored in the resource:
+</p>
+
+<pre>&lt;meta-data android:name="zoo" android:resource="@string/kangaroo" /&gt;</pre>
+
+<p>
+It is highly recommended that you avoid supplying related data as
+multiple separate {@code &lt;meta-data&gt;} entries. Instead, if you
+have complex data to associate with a component, store it as a resource and
+use the {@code resource} attribute to inform the component of its ID.
+</p></dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="nm"></a>{@code android:name}</dt>
+<dd>A unique name for the item. To ensure that the name is unique, use a
+Java-style naming convention &mdash; for example,
+"{@code com.example.project.activity.fred}".</dd>
+
+<dt><a name="rsrc"></a>{@code android:resource}</dt>
+<dd>A reference to a resource. The ID of the resource is the value assigned
+to the item. The ID can be retrieved from the meta-data Bundle by the
+{@link android.os.Bundle#getInt Bundle.getInt()} method.</dd>
+
+<dt><a name="val"></a>{@code android:value}</dt>
+<dd>The value assigned to the item. The data types that can be assigned as values and the Bundle methods that components use to retrieve those values are listed in the following table:
+
+<table>
+<tr>
+ <th>Type</th>
+ <th>Bundle method</th>
+</tr><tr>
+ <td>String value, using double backslashes ({@code \\}) to escape characters
+ &mdash; such as "{@code \\n}" and "{@code \\uxxxxx}" for a Unicode character.</td>
+ <td>{@link android.os.Bundle#getString(String) getString()}</td>
+</tr><tr>
+ <td>Integer value, such as "{@code 100}"</td>
+ <td>{@link android.os.Bundle#getInt(String) getInt()}</td>
+</tr><tr>
+ <td>Boolean value, either "{@code true}" or "{@code false}"</td>
+ <td>{@link android.os.Bundle#getBoolean(String) getBoolean()}</td>
+</tr><tr>
+ <td>Color value, in the form "{@code #rgb}", "{@code #argb}",
+ "{@code #rrggbb}", or "{@code #aarrggbb}"</td>
+ <td>{@link android.os.Bundle#getString(String) getString()}</td>
+</tr><tr>
+ <td>Float value, such as "{@code 1.23}"</td>
+ <td>{@link android.os.Bundle#getFloat(String) getFloat()}</td>
+</tr>
+</table>
+</dd>
+</dl></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/permission-element.jd b/docs/html/guide/topics/manifest/permission-element.jd
new file mode 100644
index 0000000..6eef081
--- /dev/null
+++ b/docs/html/guide/topics/manifest/permission-element.jd
@@ -0,0 +1,131 @@
+page.title=&lt;permission&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt></dt>
+<dd><pre class="stx">&lt;permission android:<a href="#desc">description</a>="<i>string resource</i>"
+ android:<a href="#icon">icon</a>="<i>drawable resource</i>"
+ android:<a href="#label">label</a>="<i>string resource</i>"
+ android:<a href="#nm">name</a>="<i>string</i>"
+ android:<a href="#pgroup">permissionGroup</a>="<i>string</i>"
+ android:<a href="#plevel">protectionLevel</a>=["normal" | "dangerous" |
+ "signature" | "signatureOrSystem"] /&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Declares a security permission that can be used to limit access
+to specific components or features of this or other applications.
+See the <a href="{@docRoot}guide/topics/manifest/manifest-intro.html#perms">Permissions</a>
+section in the introduction,
+and the <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a>
+document for more information on how permissions work.</dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="desc"></a>{@code android:description}</dt>
+<dd>A user-readable description of the permission, longer and more
+informative than the label. It may be displayed to explain the
+permission to the user &mdash; for example, when the user is asked
+whether to grant the permission to another application.
+
+<p>
+This attribute must be set as a reference to a string resource;
+unlike the {@code label} attribute, it cannot be a raw string.
+</p></dd>
+
+<dt><a name="icon"></a>{@code android:icon}</dt>
+<dd>A reference to a drawable resource for an icon that represents the
+permission.</dd>
+
+<dt><a name="label"></a>{@code android:label}</dt>
+<dd>A name for the permission, one that can be displayed to users.
+
+<p>
+As a convenience, the label can be directly set
+as a raw string while you're developing the application. However,
+when the application is ready to be published, it should be set as a
+reference to a string resource, so that it can be localized like other
+strings in the user interface.
+</p></dd>
+
+<dt><a name="nm"></a>{@code android:name}</dt>
+<dd>The name of the permission. This is the name that will be used in
+code to refer to the permission &mdash; for example, in a
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code> element and the
+{@code permission} attributes of application components.
+
+<p>
+The name must be unique, so it should use Java-style scoping &mdash;
+for example, "{@code com.example.project.PERMITTED_ACTION}".
+</p></dd>
+
+<dt><a name="pgroup"></a>{@code android:permissionGroup}</dt>
+<dd>Assigns this permission to a group. The value of this attribute is
+the name of the group, which must be declared with the
+<code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></code> element in this
+or another application. If this attribute is not set, the permission
+does not belong to a group.</dd>
+
+<dt><a name="plevel"></a>{@code android:protectionLevel}</dt>
+<dd>Characterizes the potential risk implied in the permission and
+indicates the procedure the system should follow when determining
+whether or not to grant the permission to an application requesting it.
+The value can be set to one of the following strings:
+
+<table>
+<tr>
+ <th>Value</th>
+ <th>Meaning</th>
+</tr><tr>
+ <td>"{@code normal}"</td>
+ <td>The default value. A lower-risk permission that gives requesting
+ applications access to isolated application-level features, with
+ minimal risk to other applications, the system, or the user.
+ The system automatically grants this type
+ of permission to a requesting application at installation, without
+ asking for the user's explicit approval (though the user always
+ has the option to review these permissions before installing).
+</tr><tr>
+ <td>"{@code dangerous}"</td>
+ <td>A higher-risk permission that would give a requesting application
+ access to private user data or control over the device that can
+ negatively impact the user. Because this type of permission
+ introduces potential risk, the system may not automatically
+ grant it to the requesting application. For example, any dangerous
+ permissions requested by an application may be displayed to the
+ user and require confirmation before proceeding, or some other
+ approach may be taken to avoid the user automatically allowing
+ the use of such facilities.
+</tr><tr>
+ <td>"{@code signature}"</td>
+ <td>A permission that the system grants only if the requesting
+ application is signed with the same certificate as the application
+ that declared the permission. If the certificates match, the system
+ automatically grants the permission without notifying the user or
+ asking for the user's explicit approval.
+</tr><tr>
+ <td>"{@code signatureOrSystem}"</td>
+ <td>A permission that the system grants only to applications that are
+ in the Android system image <em>or</em> that are signed with the same
+ certificates as those in the system image. Please avoid using this
+ option, as the {@code signature} protection level should be sufficient
+ for most needs and works regardless of exactly where applications are
+ installed. The "{@code signatureOrSystem}"
+ permission is used for certain special situations where multiple
+ vendors have applications built into a system image and need
+ to share specific features explicitly because they are being built
+ together.
+</tr>
+</table>
+</dd>
+</dl></dd>
+
+<dt>see also:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-tree-element.html">&lt;permission-tree&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></code></dd>
+</dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/permission-group-element.jd b/docs/html/guide/topics/manifest/permission-group-element.jd
new file mode 100644
index 0000000..9cfca6e
--- /dev/null
+++ b/docs/html/guide/topics/manifest/permission-group-element.jd
@@ -0,0 +1,59 @@
+page.title=&lt;permission-group&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;permission-group android:<a href="#desc">description</a>="<i>string resource</i>"
+ android:<a href="#icon">icon</a>="<i>drawable resource</i>"
+ android:<a href="#label">label</a>="<i>string resource</i>"
+ android:<a href="#nm">name</a>="<i>string</i>" /&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Declares a name for a logical grouping of related permissions. Individual
+permission join the group through the {@code permissionGroup} attribute of the
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code> element. Members of a group are
+presented together in the user interface.
+
+<p>
+Note that this element does not declare a permission itself, only a category in
+which permissions can be placed. See the
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code> element for element for information
+on declaring permissions and assigning them to groups.
+</p></dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="desc"></a>{@code android:description}</dt>
+<dd>User-readable text that describes the group. The text should be
+longer and more explanatory than the label. This attribute must be
+set as a reference to a string resource. Unlike the {@code label}
+attribute, it cannot be a raw string.</dd>
+
+<dt><a name="icon"></a>{@code android:icon}</dt>
+<dd>An icon representing the permission. This attribute must be set
+as a reference to a drawable resource containing the image definition.</dd>
+
+<dt><a name="label"></a>{@code android:label}</dt>
+<dd>A user-readable name for the group. As a convenience, the label can
+be directly set as a raw string while you're developing the application.
+However, when the application is ready to be published, it should be set
+as a reference to a string resource, so that it can be localized like other
+strings in the user interface.</dd>
+
+<dt><a name="nm"></a>{@code android:name}</dt>
+<dd>The name of the group. This is the name that can be assigned to a
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+element's
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html#pgroup">&lt;permissionGroup&gt;</a></code>
+attribute.</dd>
+</dl></dd>
+
+<dt>see also:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-tree-element.html">&lt;permission-tree&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/permission-tree-element.jd b/docs/html/guide/topics/manifest/permission-tree-element.jd
new file mode 100644
index 0000000..e2f7474
--- /dev/null
+++ b/docs/html/guide/topics/manifest/permission-tree-element.jd
@@ -0,0 +1,61 @@
+page.title=&lt;permission-tree&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;permission-tree android:<a href="#icon">icon</a>="<i>drawable resource</i>"
+ android:<a href="#label">label</a>="<i>string resource</i>" ]
+ android:<a href="#nm">name</a>="<i>string</i>" /&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Declares the base name for a tree of permissions. The application takes
+ownership of all names within the tree. It can dynamically add new permissions
+to the tree by calling <code>{@link android.content.pm.PackageManager#addPermission PackageManager.addPermission()}</code>. Names within the tree are separated by
+periods ('{@code .}'). For example, if the base name is
+{@code com.example.project.taxes}, permissions like the following might be
+added:
+
+<p style="margin-left: 2em">{@code com.example.project.taxes.CALCULATE}
+<br/>{@code com.example.project.taxes.deductions.MAKE_SOME_UP}
+<br/>{@code com.example.project.taxes.deductions.EXAGGERATE}</p>
+
+<p>
+Note that this element does not declare a permission itself, only a
+namespace in which further permissions can be placed. See the
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+element for information on declaring permissions.
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="icon"></a>{@code android:icon}</dt>
+<dd>An icon representing all the permissions in the tree. This attribute
+must be set as a reference to a drawable resource containing the image
+definition.</dd>
+
+<dt><a name="label"></a>{@code android:label}</dt>
+<dd>A user-readable name for the group. As a convenience, the label can
+be directly set as a raw string for quick and dirty programming. However,
+when the application is ready to be published, it should be set as a
+reference to a string resource, so that it can be localized like other
+strings in the user interface.</dd>
+
+<dt><a name="nm"</a>{@code android:name}</dt>
+<dd>The name that's at the base of the permission tree. It serves as
+a prefix to all permission names in the tree. Java-style scoping should
+be used to ensure that the name is unique. The name must have more than
+two period-separated seqments in its path &mdash; for example,
+{@code com.example.base} is OK, but {@code com.example} is not.</dd>
+
+</dl></dd>
+
+<p>
+<dt>see also:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+</dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/provider-element.jd b/docs/html/guide/topics/manifest/provider-element.jd
new file mode 100644
index 0000000..7359e50
--- /dev/null
+++ b/docs/html/guide/topics/manifest/provider-element.jd
@@ -0,0 +1,267 @@
+page.title=&lt;provider&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;provider android:<a href="#auth">authorities</a>="<i>list</i>"
+ android:<a href="#enabled">enabled</a>=["true" | "false"]
+ android:<a href="#exported">exported</a>=["true" | "false"]
+ android:<a href="#gprmsn">grantUriPermissions</a>=["true" | "false"]
+ android:<a href="#icon">icon</a>="<i>drawable resource</i>"
+ android:<a href="#init">initOrder</a>="<i>integer</i>"
+ android:<a href="#label">label</a>="<i>string resource</i>"
+ android:<a href="#multi">multiprocess</a>=["true" | "false"]
+ android:<a href="#nm">name</a>="<i>string</i>"
+ android:<a href="#prmsn">permission</a>="<i>string</i>"
+ android:<a href="#proc">process</a>="<i>string</i>"
+ android:<a href="#rprmsn">readPermission</a>="<i>string</i>"
+ android:<a href="#sync">syncable</a>=["true" | "false"]
+ android:<a href="#wprmsn">writePermission</a>="<i>string</i>" &gt;
+ . . .
+&lt;/provider&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code></dd>
+
+<dt>can contain:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Declares a content provider &mdash; a subclass of
+{@link android.content.ContentProvider} &mdash; that supplies structured
+access to data managed by the application. All content providers that
+are part of the application must be represented by {@code &lt;provider&gt;}
+elements in the manifest file. The system cannot see, and therefore will
+not run, any that are not declared. (You need to declare only
+those content providers that you develop as part of your application,
+not those developed by others that your application uses.)
+
+<p>
+The Android system identifies content providers by the authority part
+ of a {@code content:} URI. For example, suppose that the following URI
+is passed to <code>{@link android.content.ContentResolver#query
+ContentResolver.query()}</code>:
+
+<p style="margin-left: 2em">{@code content://com.example.project.healthcareprovider/nurses/rn}</p>
+
+<p>
+The {@code content:} scheme identifies the data as belonging to a content
+provider and the authority ({@code com.example.project.healthcareprovider})
+identifies the particular provider. The authority therefore must be unique.
+Typically, as in this example, it's the fully qualified name of a
+ContentProvider subclass. The path part of a URI may be used by a content
+provider to identify particular data subsets, but those paths are not
+declared in the manifest.
+</p>
+
+<p>
+For information on using and developing content providers, see a separate document,
+<a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>.
+</p></dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="auth"></a>{@code android:authorities}</dt>
+<dd>A list of one or more URI authorities that identify data under the purview
+of the content provider.
+Multiple authorities are listed by separating their names with a semicolon.
+To avoid conflicts, authority names should use a Java-style naming convention
+(such as {@code com.example.provider.cartoonprovider}). Typically, it's the name
+of the ContentProvider subclass.
+
+<p>
+There is no default. At least one authority must be specified.
+</p></dd>
+
+<dt><a name="enabled"></a>{@code android:enabled}</dt>
+<dd>Whether or not the content provider can be instantiated by the system &mdash;
+"{@code true}" if it can be, and "{@code false}" if not. The default value
+is "{@code true}".
+
+<p>
+The <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element has its own
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#enabled">enabled</a></code> attribute that applies to all
+application components, including content providers. The
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> and {@code &lt;provider&gt;}
+attributes must both be "{@code true}" (as they both
+are by default) for the content provider to be enabled. If either is
+"{@code false}", the provider is disabled; it cannot be instantiated.
+</p></dd>
+
+<dt><a name="exported"></a>{@code android:exported}</dt>
+<dd>Whether or not the content provider can be used by components of other
+applications &mdash; "{@code true}" if it can be, and "{@code false}" if not.
+If "{@code false}", the provider is available only to components of the
+same application or applications with the same user ID. The default value
+is "{@code true}".
+
+<p>
+You can export a content provider but still limit access to it with the
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">permission</a></code> attribute.
+</p></dd>
+
+<dt><a name="gprmsn"></a>{@code android:grantUriPermissions}</dt>
+<dd>Whether or not those who ordinarily would not have permission to
+access the content provider's data can be granted permission to do so,
+temporarily overcoming the restriction imposed by the
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#rprmsn">readPermission</a></code>,
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#wprmsn">writePermission</a></code>, and
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">permission</a></code> attributes
+&mdash;
+"{@code true}" if permission can be granted, and "{@ code false}" if not.
+If "{@code true}", permission can be granted to any of the content
+provider's data. If "{@code false}", permission can be granted only
+to the data subsets listed in
+<code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission&gt;</a></code> subelements,
+if any. The default value is "{@code false}".
+
+<p>
+Granting permission is a way of giving an application component one-time
+access to data protected by a permission. For example, when an e-mail
+message contains an attachment, the mail application may call upon the
+appropriate viewer to open it, even though the viewer doesn't have general
+permission to look at all the content provider's data.
+</p>
+
+<p>
+In such cases, permission is granted by
+<code>{@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}</code>
+and <code>{@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION}</code>
+flags in the Intent object that activates the component. For example, the
+mail application might put {@code FLAG_GRANT_READ_URI_PERMISSION} in the
+Intent passed to {@code Context.startActivity()}. The permission is specific
+to the URI in the Intent.
+</p>
+
+<p>
+If you enable this feature, either by setting this attribute to "{@code true}"
+or by defining <code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission&gt;</a></code>
+subelements, you must call
+<code>{@link android.content.Context#revokeUriPermission
+Context.revokeUriPermission()}</code> when a covered URI is deleted from
+the provider.
+</p>
+
+<p>
+See also the <code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission&gt;</a></code>
+element.
+</p></dd>
+
+<dt><a name="icon"></a>{@code android:icon}</dt>
+<dd>An icon representing the content provider.
+This attribute must be set as a reference to a drawable resource containing
+the image definition. If it is not set, the icon specified for the application
+as a whole is used instead (see the <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+element's <code><a href="{@docRoot}guide/topics/manifest/application-element.html#icon">icon</a></code> attribute).</dd>
+
+<dt><a name="init"></a>{@code android:initOrder}</dt>
+<dd>The order in which the content provider should be instantiated,
+relative to other content providers hosted by the same process.
+When there are dependencies among content providers, setting this
+attribute for each of them ensures that they are created in the order
+required by those dependencies. The value is a simple integer,
+with higher numbers being initialized first.</dd>
+
+<dt><a name="label"></a>{@code android:label}</dt>
+<dd>A user-readable label for the content provided.
+If this attribute is not set, the label set for the application as a whole is
+used instead (see the <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#label">label</a></code> attribute).
+
+<p>
+The label should be set as a reference to a string resource, so that
+it can be localized like other strings in the user interface.
+However, as a convenience while you're developing the application,
+it can also be set as a raw string.
+</p></dd>
+
+<dt><a name="multi"></a>{@code android:multiprocess}</dt>
+<dd>Whether or not an instance of the content provider can be created in
+every client process &mdash; "{@code true}" if instances can run in multiple
+processes, and "{@code false}" if not. The default value is "{@code false}".
+
+<p>
+Normally, a content provider is instantiated in the process of the
+application that defined it. However, if this flag is set to "{@code true}",
+the system can create an instance in every process where there's a client
+that wants to interact withit, thus avoiding the overhead of interprocess
+communication.
+</p></dd>
+
+<dt><a name="nm"></a>{@code android:name}</dt>
+<dd>The name of the class that implements the content provider, a subclass of
+{@link android.content.ContentProvider}. This should be a fully qualified
+class name (such as, "{@code com.example.project.TransportationProvider}").
+However, as a shorthand, if the first character of the name is a period,
+it is appended to the package name specified in the
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code> element.
+
+<p>
+There is no default. The name must be specified.
+</p></dd>
+
+
+<dt><a name="prmsn"></a>{@code android:permission}</dt>
+<dd>The name of a permission that clients must have to read or write the
+content provider's data. This attribute is a convenient way of setting a
+single permission for both reading and writing. However, the
+<code><a href="#rprmsn">readPermission</a></code> and
+<code><a href="#wprmsn">writePermission</a></code> attributes take precedence
+over this one. If the <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#rprmsn">readPermission</a></code>
+attribute is also set, it controls access for querying the content provider.
+And if the <code><a href="#wprmsn">writePermission</a></code> attribute is set,
+it controls access for modifying the provider's data.
+
+<p>
+For more information on permissions, see the
+<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#sectperm">Permissions</a>
+section in the introduction and a separate document,
+<a href="{@docRoot}guide/topics/security/security.html">Security and
+Permissions</a>.
+</p></dd>
+
+<dt><a name="proc"></a>{@code android:process}</dt>
+<dd>The name of the process in which the content provider should run. Normally,
+all components of an application run in the default process created for the
+application. It has the same name as the application package. The
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#proc">process</a></code>
+attribute can set a different
+default for all components. But each component can override the default
+with its own {@code process} attribute, allowing you to spread your
+application across multiple processes.
+
+<p>
+If the name assigned to this attribute begins with a colon (':'), a new
+process, private to the application, is created when it's needed and
+the activity runs in that process.
+If the process name begins with a lowercase character, the activity will run
+in a global process of that name, provided that it has permission to do so.
+This allows components in different applications to share a process, reducing
+resource usage.
+</p></dd>
+
+<dt><a name="rprmsn"></a>{@code android:readPermission}</dt>
+<dd>A permission that clients must have to query the content provider.
+See also the <code><a href="#prmsn">permission</a></code> and
+<code><a href="#wprmsn">writePermission</a></code> attributes.</dd>
+
+<dt><a name="sync"></a>{@code android:syncable}</dt>
+<dd>Whether or not the data under the content provider's control
+is to be synchronized with data on a server &mdash; "{@code true}"
+if it is to be synchronized, and "{@ code false}" if not.</dd>
+
+<dt><a name="wprmsn"></a>{@code android:writePermission}</dt>
+<dd>A permission that clients must have to make changes to the data
+controlled by the content provider.
+See also the <code><a href="#prmsn">permission</a></code> and
+<code><a href="#rprmsn">readPermission</a></code> attributes.</dd>
+
+</dl></dd>
+
+<p>
+<dt>see also:</dt>
+<dd><a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/receiver-element.jd b/docs/html/guide/topics/manifest/receiver-element.jd
new file mode 100644
index 0000000..777d016
--- /dev/null
+++ b/docs/html/guide/topics/manifest/receiver-element.jd
@@ -0,0 +1,164 @@
+page.title=&lt;receiver&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;receiver android:<a href="#enabled">enabled</a>=["true" | "false"]
+ android:<a href="#exported">exported</a>=["true" | "false"]
+ android:<a href="#icon">icon</a>="<i>drawable resource</i>"
+ android:<a href="#label">label</a>="<i>string resource</i>"
+ android:<a href="#nm">name</a>="<i>string</i>"
+ android:<a href="#prmsn">permission</a>="<i>string</i>"
+ android:<a href="#proc">process</a>="<i>string</i>" &gt;
+ . . .
+&lt;/receiver&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code></dd>
+
+<dt>can contain:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filer&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Declares a broadcast receiver (a {@link android.content.BroadcastReceiver}
+subclass) as one of the application's components. Broadcast receivers enable
+applications to receive intents that are broadcast by the system or by other
+applications, even when other components of the application are not running.
+
+<p>
+There are two ways to make a broadcast receiver known to the system: One is
+declare it in the manifest file with this element. The other is to create
+the receiver dynamically in code and register it with the <code>{@link
+android.content.Context#registerReceiver Context.registerReceiver()}</code>
+method. See the {@link android.content.BroadcastReceiver} class description
+for more on dynamically created receivers.
+</p></dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="enabled"></a>{@code android:enabled}</dt>
+<dd>Whether or not the broadcast receiver can be instantiated by the system &mdash;
+"{@code true}" if it can be, and "{@code false}" if not. The default value
+is "{@code true}".
+
+<p>
+The <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element has its own
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#enabled">enabled</a></code> attribute that applies to all
+application components, including broadcast receivers. The
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> and
+{@code &lt;receiver&gt;} attributes must both be "{@code true}" for
+the broadcast receiver to be enabled. If either is "{@code false}", it is
+disabled; it cannot be instantiated.
+</p></dd>
+
+<dt><a name="exported"></a>{@code android:exported}</dt>
+<dd>Whether or not the broadcast receiver can receive messages from sources
+outside its application &mdash; "{@code true}" if it can, and "{@code false}"
+if not. If "{@code false}", the only messages the broadcast receiver can
+receive are those sent by components of the same application or applications
+with the same user ID.
+
+<p>
+The default value depends on whether the broadcast receiver contains intent filters.
+The absence of any filters means that it can be invoked only by Intent objects that
+specify its exact class name. This implies that the receiver is intended only for
+application-internal use (since others would not normally know the class name).
+So in this case, the default value is "{@code false}".
+On the other hand, the presence of at least one filter implies that the broadcast
+receiver is intended to receive intents broadcast by the system or other applications,
+so the default value is "{@code true}".
+</p>
+
+<p>
+This attribute is not the only way to limit a broadcast receiver's external exposure.
+You can also use a permission to limit the external entities that can send it messages
+(see the <code><a href="{@docRoot}guide/topics/manifest/receiver-element.html#prmsn">permission</a></code> attribute).
+</p></dd>
+
+<dt><a name="icon"></a>{@code android:icon}</dt>
+<dd>An icon representing the broadcast receiver. This attribute must be set
+as a reference to a drawable resource containing the image definition.
+If it is not set, the icon specified for the application as a whole is used
+instead (see the <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+element's <code><a href="{@docRoot}guide/topics/manifest/application-element.html#icon">icon</a></code> attribute).
+
+<p>
+The broadcast receiver's icon &mdash; whether set here or by the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element &mdash; is also the
+default icon for all the receiver's intent filters (see the
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html#icon">icon</a></code> attribute).
+</p></dd>
+
+<dt><a name="label"></a>{@code android:label}</dt>
+<dd>A user-readable label for the broadcast receiver. If this attribute is not
+set, the label set for the application as a whole is
+used instead (see the <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#label">label</a></code> attribute).
+
+<p>
+The broadcast receiver's label &mdash; whether set here or by the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element &mdash; is also the
+default label for all the receiver's intent filters (see the
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html#label">label</a></code> attribute).
+</p>
+
+<p>
+The label should be set as a reference to a string resource, so that
+it can be localized like other strings in the user interface.
+However, as a convenience while you're developing the application,
+it can also be set as a raw string.
+</p></dd>
+
+<dt><a name="nm"></a>{@code android:name}</dt>
+<dd>The name of the class that implements the broadcast receiver, a subclass of
+{@link android.content.BroadcastReceiver}. This should be a fully qualified
+class name (such as, "{@code com.example.project.ReportReceiver}"). However,
+as a shorthand, if the first character of the name is a period (for example,
+"{@code . ReportReceiver}"), it is appended to the package name specified in
+the <code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code> element.
+
+<p>
+There is no default. The name must be specified.
+</p></dd>
+
+<dt><a name="prmsn"></a>{@code android:permission}</dt>
+<dd>The name of a permission that broadcasters must have to send a
+message to the broadcast receiver.
+If this attribute is not set, the permission set by the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#prmsn">permission</a></code> attribute applies
+to the broadcast receiver. If neither attribute is set, the receiver
+is not protected by a permission.
+
+<p>
+For more information on permissions, see the
+<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#sectperm">Permissions</a>
+section in the introduction and a separate document,
+<a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a>.
+</p></dd>
+
+<dt><a name="proc"></a>{@code android:process}</dt>
+<dd>The name of the process in which the broadcast receiver should run.
+Normally, all components of an application run in the default process created
+for the application. It has the same name as the application package. The
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#proc">process</a></code> attribute can set a different
+default for all components. But each component can override the default
+with its own {@code process} attribute, allowing you to spread your
+application across multiple processes.
+
+<p>
+If the name assigned to this attribute begins with a colon (':'), a new
+process, private to the application, is created when it's needed and
+the broadcast receiver runs in that process.
+If the process name begins with a lowercase character, the receiver will run
+in a global process of that name, provided that it has permission to do so.
+This allows components in different applications to share a process, reducing
+resource usage.
+</p></dd>
+</dl></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/service-element.jd b/docs/html/guide/topics/manifest/service-element.jd
new file mode 100644
index 0000000..ad65abe
--- /dev/null
+++ b/docs/html/guide/topics/manifest/service-element.jd
@@ -0,0 +1,176 @@
+page.title=&lt;service&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;service android:<a href="#enabled">enabled</a>=["true" | "false"]
+ android:<a href="#exported">exported[</a>="true" | "false"]
+ android:<a href="#icon">icon</a>="<i>drawable resource</i>"
+ android:<a href="#label">label</a>="<i>string resource</i>"
+ android:<a href="#nm">name</a>="<i>string</i>"
+ android:<a href="#prmsn">permission</a>="<i>string</i>"
+ android:<a href="#proc">process</a>="<i>string</i>" &gt;
+ . . .
+&lt;/service&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code></dd>
+
+<dt>can contain:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filer&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Declares a service (a {@link android.app.Service} subclass) as one
+of the application's components. Unlike activities, services lack a
+visual user interface. They're used to implement long-running background
+operations or a rich communications API that can be called by other
+applications.
+
+<p>
+All services must be represented by {@code &lt;service&gt;} elements in
+the manifest file. Any that are not declared there will not be seen
+by the system and will never be run.
+</p></dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="enabled"></a>{@code android:enabled}</dt>
+<dd>Whether or not the service can be instantiated by the system &mdash;
+"{@code true}" if it can be, and "{@code false}" if not. The default value
+is "{@code true}".
+
+<p>
+The <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element has its own
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#enabled">enabled</a></code> attribute that applies to all
+application components, including services. The
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> and {@code &lt;service&gt;}
+attributes must both be "{@code true}" (as they both
+are by default) for the service to be enabled. If either is
+"{@code false}", the service is disabled; it cannot be instantiated.
+</p></dd>
+
+<dt><a name="exported"></a>{@code android:exported}</dt>
+<dd>Whether or not components of other applications can invoke
+the service or interact with it &mdash; "{@code true}" if they can, and
+"{@code false}" if not. When the value is "{@code false}", only
+components of the same application or applications
+with the same user ID can start the service or bind to it.
+
+<p>
+The default value depends on whether the service contains intent filters. The
+absence of any filters means that it can be invoked only by specifying
+its exact class name. This implies that the service is intended only for
+application-internal use (since others would not know the class name). So in
+this case, the default value is "{@code false}".
+On the other hand, the presence of at least one filter implies that the service
+is intended for external use, so the default value is "{@code true}".
+</p>
+
+<p>
+This attribute is not the only way to limit the exposure of a service to other
+applications. You can also use a permission to limit the external entities that
+can interact with the service (see the <code><a href="{@docRoot}guide/topics/manifest/service-element.html#prmsn">permission</a></code>
+attribute).
+</p></dd>
+
+<dt><a name="icon"></a>{@code android:icon}</dt>
+<dd>An icon representing the service. This attribute must be set as a
+reference to a drawable resource containing the image definition.
+If it is not set, the icon specified for the application
+as a whole is used instead (see the <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+element's <code><a href="{@docRoot}guide/topics/manifest/application-element.html#icon">icon</a></code> attribute).
+</p>
+
+<p>
+The service's icon &mdash; whether set here or by the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element &mdash; is also the
+default icon for all the service's intent filters (see the
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html#icon">icon</a></code> attribute).
+</p></dd>
+
+<dt><a name="label"></a>{@code android:label}</dt>
+<dd>A name for the service that can be displayed to users.
+If this attribute is not set, the label set for the application as a whole is
+used instead (see the <code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#label">label</a></code> attribute).
+
+<p>
+The service's label &mdash; whether set here or by the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element &mdash; is also the
+default label for all the service's intent filters (see the
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html#label">label</a></code> attribute).
+</p>
+
+<p>
+The label should be set as a reference to a string resource, so that
+it can be localized like other strings in the user interface.
+However, as a convenience while you're developing the application,
+it can also be set as a raw string.
+</p></dd>
+
+<dt><a name="nm"></a>{@code android:name}</dt>
+<dd>The name of the {@link android.app.Service} subclass that implements
+the service. This should be a fully qualified class name (such as,
+"{@code com.example.project.RoomService}"). However, as a shorthand, if
+the first character of the name is a period (for example, "{@code .RoomService}"),
+it is appended to the package name specified in the
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code> element.
+
+<p>
+There is no default. The name must be specified.
+</p></dd>
+
+<dt><a name="prmsn"></a>{@code android:permission}</dt>
+<dd>The name of a permission that that an entity must have in order to
+launch the service or bind to it. If a caller of
+<code>{@link android.content.Context#startService startService()}</code>,
+<code>{@link android.content.Context#bindService bindService()}</code>, or
+<code>{@link android.content.Context#stopService stopService()}</code>,
+has not been granted this permission, the method will not work and the
+Intent object will not be delivered to the service.
+
+<p>
+If this attribute is not set, the permission set by the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#prmsn">permission</a></code>
+attribute applies to the service. If neither attribute is set, the service is
+not protected by a permission.
+</p>
+
+<p>
+For more information on permissions, see the
+<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#sectperm">Permissions</a>
+section in the introduction and a separate document,
+<a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a>.
+</p></dd>
+
+<dt><a name="proc"></a>{@code android:process}</dt>
+<dd>The name of the process where the service is to run. Normally,
+all components of an application run in the default process created for the
+application. It has the same name as the application package. The
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code> element's
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html#proc">process</a></code>
+attribute can set a different
+default for all components. But component can override the default
+with its own {@code process} attribute, allowing you to spread your
+application across multiple processes.
+
+<p>
+If the name assigned to this attribute begins with a colon (':'), a new
+process, private to the application, is created when it's needed and
+the service runs in that process.
+If the process name begins with a lowercase character, the service will run
+in a global process of that name, provided that it has permission to do so.
+This allows components in different applications to share a process, reducing
+resource usage.
+</p></dd>
+</dl></dd>
+
+<dt>see also:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+<br><code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/uses-library-element.jd b/docs/html/guide/topics/manifest/uses-library-element.jd
new file mode 100644
index 0000000..d66da2c
--- /dev/null
+++ b/docs/html/guide/topics/manifest/uses-library-element.jd
@@ -0,0 +1,32 @@
+page.title=&lt;uses-library&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre>&lt;uses-library android:<a href="#nm">name</a>="<i>string</i>" /&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Specifies a shared library that the application must be linked against.
+This element tells the system to include the library's code in the class
+loader for the package.
+
+<p>
+All of the {@code android} packages (such as {@link android.app},
+{@link android.content}, {@link android.view}, and {@link android.widget})
+are in the default library that all applications are automatically linked
+against. However, some packages (such as {@code maps} and {@code awt} are
+in separate libraries that are not automatically linked. Consult the
+documentation for the packages you're using to determine which library
+contains the package code.
+</p></dd>
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="nm"></a>{@code android:name}</dt>
+<dd>The name of the library.</dd>
+</dl></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/uses-permission-element.jd b/docs/html/guide/topics/manifest/uses-permission-element.jd
new file mode 100644
index 0000000..07741b1
--- /dev/null
+++ b/docs/html/guide/topics/manifest/uses-permission-element.jd
@@ -0,0 +1,39 @@
+page.title=&lt;uses-permission&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;uses-permission android:<a href="#nm">name</a>="<i>string</i>" /&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Requests a permission that the application must be granted in
+order for it to operate correctly. Permissions are granted when the
+application is installed, not while it's running.
+
+<p>
+For more information on permissions, see the
+<a href="{@docRoot}guide/topics/manifest/manifest-intro.html#perms">Permissions</a></code>
+section in the introduction and the separate
+<a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> document.
+A list of permissions defined by the base platform can be found at
+{@link android.Manifest.permission android.Manifest.permission}.
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="nm"></a>{@code android:name}</dt>
+<dd>The name of the permission. It can be a permission defined by the
+application with the <code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+element, a permission defined by another application, or one of the
+standard system permissions, such as "{@code android.permission.CAMERA}"
+or "{@code android.permission.READ_CONTACTS}". As these examples show,
+a permission name typically includes the package name as a prefix.</dd>
+
+</dl></dd>
+
+<dt>see also:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/manifest/uses-sdk-element.jd b/docs/html/guide/topics/manifest/uses-sdk-element.jd
new file mode 100644
index 0000000..a88635a
--- /dev/null
+++ b/docs/html/guide/topics/manifest/uses-sdk-element.jd
@@ -0,0 +1,49 @@
+page.title=&lt;uses-sdk&gt;
+@jd:body
+
+<dl class="xml">
+<dt>syntax:</dt>
+<dd><pre class="stx">&lt;uses-sdk android:<a href="#min">minSdkVersion</a>="<i>integer</i>" /&gt;</pre></dd>
+
+<dt>contained in:</dt>
+<dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
+
+<dt>description:</dt>
+<dd>Declares which levels of the Android API the application can run against.
+The level is incremented when there are additions to the API and resource tree,
+so an application developed using level 3 of the API may not run against level
+1 or 2, but should run against level 3, 4, 5, and above.
+</p>
+
+<p>
+The default level is 1.
+</p>
+
+<p>
+For more information on the API level, see the
+<a href="{@docRoot}guide/publishing/versioning.html#minsdkversion">Specifying
+Minimum System API Version</a> section of
+<a href="{@docRoot}guide/publishing/versioning.html">Versioning Your
+Applications</a>.
+</p></dd>
+
+
+<dt>attributes:</dt>
+<dd><dl class="attr">
+<dt><a name="min"></a>{@code android:minSdkVersion}</dt>
+<dd>An integer designating the minimum level of the Android API that's required
+for the application to run.
+
+<p>
+Despite its name, this attribute is set to the API level, <em>not</em> to the
+version number of the SDK (software development kit). The API level is always
+a single integer; the SDK version may be split into major and minor components
+(such as 1.2). You cannot derive the API level from the SDK version number
+(for example, it is not the same as the major version or the sum of the major
+and minor versions). To learn what the API level is, check the notes that
+came with the SDK you're using.
+</p></dd>
+
+</dl></dd>
+
+</dl>
diff --git a/docs/html/guide/topics/ui/binding.jd b/docs/html/guide/topics/ui/binding.jd
index f9afbc5..85aed18 100644
--- a/docs/html/guide/topics/ui/binding.jd
+++ b/docs/html/guide/topics/ui/binding.jd
@@ -81,6 +81,9 @@ s2.setAdapter(adapter2);
<p>Note that it is necessary to have the People._ID column in projection used with CursorAdapter
or else you will get an exception.</p>
+<p>If, during the course of your application's life, you change the underlying data that is read by your Adapter,
+you should call {@link android.widget.ArrayAdapter#notifyDataSetChanged()}. This will notify the attached View
+that the data has been changed and it should refresh itself.</p>
<h2 id="HandlingUserSelections">Handling User Selections</h2>
<p>You handle the user's selecction by setting the class's {@link
diff --git a/docs/html/guide/topics/ui/declaring-layout.jd b/docs/html/guide/topics/ui/declaring-layout.jd
index dd0b7de..7ef22a6 100644
--- a/docs/html/guide/topics/ui/declaring-layout.jd
+++ b/docs/html/guide/topics/ui/declaring-layout.jd
@@ -5,6 +5,12 @@ parent.link=index.html
<div id="qv-wrapper">
<div id="qv">
+ <h2>Key classes</h2>
+ <ol>
+ <li>{@link android.view.View}</li>
+ <li>{@link android.view.ViewGroup}</li>
+ <li>{@link android.view.ViewGroup.LayoutParams}</li>
+ </ol>
<h2>In this document</h2>
<ol>
<li><a href="#write">Write the XML</a></li>
diff --git a/docs/html/guide/topics/ui/index.jd b/docs/html/guide/topics/ui/index.jd
index ccc8ff6..6bd1d15 100644
--- a/docs/html/guide/topics/ui/index.jd
+++ b/docs/html/guide/topics/ui/index.jd
@@ -4,11 +4,11 @@ page.title=User Interface
<div id="qv-wrapper">
<div id="qv">
- <h2>Key classes and packages</h2>
+ <h2>Key classes</h2>
<ol>
<li>{@link android.view.View}</li>
<li>{@link android.view.ViewGroup}</li>
- <li>{@link android.widget}</li>
+ <li>{@link android.widget Widget classes}</li>
</ol>
<h2>In this document</h2>
@@ -107,7 +107,7 @@ complex layout.</p>
<p>For more on building a UI layout, read <a href="declaring-layout.html">Declaring Layout</a>.
<div class="sidebox-wrapper">
-<div class="sidebox">
+<div class="sidebox-inner">
<p><b>Tip:</b> You can also draw View and ViewGroups objects in Java code,
using the <code>{@link android.view.ViewGroup#addView(View)}</code> methods
to dynamically insert new View and ViewGroup objects.</p>
diff --git a/docs/html/guide/topics/ui/menus.jd b/docs/html/guide/topics/ui/menus.jd
index ed796ee..bae94ca 100644
--- a/docs/html/guide/topics/ui/menus.jd
+++ b/docs/html/guide/topics/ui/menus.jd
@@ -5,6 +5,12 @@ parent.link=index.html
<div id="qv-wrapper">
<div id="qv">
+ <h2>Key classes</h2>
+ <ol>
+ <li>{@link android.view.Menu}</li>
+ <li>{@link android.view.ContextMenu}</li>
+ <li>{@link android.view.SubMenu}</li>
+ </ol>
<h2>In this document</h2>
<ol>
<li><a href="#options-menu">Options Menu</a></li>
@@ -20,12 +26,6 @@ parent.link=index.html
</ol>
</li>
</ol>
- <h2>Key classes</h2>
- <ol>
- <li>{@link android.view.Menu}</li>
- <li>{@link android.view.ContextMenu}</li>
- <li>{@link android.view.SubMenu}</li>
- </ol>
</div>
</div>
diff --git a/docs/html/guide/topics/ui/themes.jd b/docs/html/guide/topics/ui/themes.jd
index d684512..956ffe1 100644
--- a/docs/html/guide/topics/ui/themes.jd
+++ b/docs/html/guide/topics/ui/themes.jd
@@ -5,7 +5,16 @@ parent.link=index.html
<div id="qv-wrapper">
<div id="qv">
-
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#styles">Styles</a></li>
+ <li><a href="#themes">Themes</a>
+ <ol>
+ <li><a href="#inTheManifest">Set the theme in the manifest</a></li>
+ <li><a href="#fromTheApp">Set the theme from the application</a></li>
+ </ol>
+ </li>
+ </ol>
<h2>See also</h2>
<ol>
<li><a href="{@docRoot}guide/topics/resources/available-resources.html#stylesandthemes">Style and Theme Resources</a></li>
@@ -33,7 +42,7 @@ parent.link=index.html
</ol>
-<h2>Styles</h2>
+<h2 id="styles">Styles</h2>
<p>Here's an example declaration of a style: </p>
@@ -66,7 +75,7 @@ or a reference to any other resource type.</p>
<p>Now this EditText widget will be styled as defined by the <code>style</code> example above.</p>
-<h2>Themes</h2>
+<h2 id="themes">Themes</h2>
<p>Just like styles, themes are also declared in XML <code>&lt;style&gt;</code> elements, and are referenced in the same manner.
The difference is that you can add a theme style only to <code>&lt;application&gt;</code> and <code>&lt;activity&gt;</code> elements &mdash;
@@ -100,8 +109,8 @@ is done by referring to a specific <code>&lt;item></code> by its <code>name</cod
This technique can be used only in XML resources.
</p>
-<h3>Set the theme in the Manifest</h3>
-<p>To set this theme for all the activites of your application, open the Manifest file and
+<h3 id="inTheManifest">Set the theme in the manifest</h3>
+<p>To set this theme for all the activites of your application, open the AndroidManifest.xml file and
edit the <code>&lt;application></code> tag to include the <code>android:theme</code> attribute with the
theme name:</p>
@@ -136,7 +145,7 @@ For example, we'll modify the <code>Theme.Dialog</code> theme. First, we need to
So, for each item in the Dialog theme that we want to override, we re-define the value under this style and
then use <var>CustomDialogTheme</var> instead of the <var>Theme.Dialog</var>.</p>
-<h3>Set the theme from the application</h3>
+<h3 id="fromTheApp">Set the theme from the application</h3>
<p>You can also load a theme for an Activity programmatically, if needed.
To do so, use the {@link android.app.Activity#setTheme(int) setTheme()}
method. Note that, when doing so, you must be sure to set the theme <em>before</em>
diff --git a/docs/html/guide/tutorials/hello-world.jd b/docs/html/guide/tutorials/hello-world.jd
index bbc4f77..7b9287f 100644
--- a/docs/html/guide/tutorials/hello-world.jd
+++ b/docs/html/guide/tutorials/hello-world.jd
@@ -2,37 +2,40 @@ page.title=Hello, World
@jd:body
<p>As a developer, you know that the first impression
-you get of a development framework is how easy it is to write "Hello,
-World." Well, on Android, it's pretty easy. </p>
-
-<p>It's particularly easy if you're using Eclipse as your IDE, because we've provided a
+of a development framework is how easy it is to write "Hello,
+World." Well, on Android, it's pretty easy.
+It's particularly easy if you're using Eclipse as your IDE, because we've provided a
great plugin that handles your project creation and management to greatly speed up your
-development cycles. Get <a href="http://www.eclipse.org/downloads/">Eclipse</a> and visit the
-<a href="{@docRoot}guide/developing/tools/adt.html">ADT Plugin</a> page to install it.</p>
+development cycles.</p>
<p>If you're not using Eclipse, that's okay. Familiarize yourself with
<a href="{@docRoot}guide/developing/other-ide.html">Developing in Other IDEs</a>.
You can then come back here and ignore anything about Eclipse.</p>
+<p>Before you start, you should already have the latest SDK installed, and if you're using
+Eclipse, you should have installed the ADT plugin as well. See
+<a href="{@docRoot}sdk/1.1_r1/installing.html">Installing the Android SDK</a> to get these
+installed.</p>
+
<p class="note"><strong>Note:</strong>
In some cases, you might want to click the screenshots below to get a bigger view.
</p>
<h2 id="create">Create the Project</h2>
-<ol class="listhead">
- <li>Create a new Android Project.
+<ol>
+ <li><strong>Open a new Android Project.</strong>
<p>From Eclipse, select the <strong>File &gt; New &gt; Project</strong> menu item. If the Android
Plugin for Eclipse has been successfully installed, the resulting dialog
should have a folder labeled "Android" which should contain a single entry:
"Android Project".</p>
+ <p>Selected "Android Project" and click <strong>Next</strong>.</p>
<a href="images/hello_world_0.png"><img src="images/hello_world_0.png" style="height:230px" alt="" /></a>
- <p>Once you've selected "Android Project", click <strong>Next</strong>.</p>
</li>
- <li>Fill out the project details.
+ <li><strong>Fill out the project details.</strong>
<p>The next screen allows you to enter the relevant details for your project:</p>
<ul>
<li><em>Project name:</em> HelloAndroid</li>
@@ -40,7 +43,7 @@ In some cases, you might want to click the screenshots below to get a bigger vie
<li><em>Activity name:</em> HelloAndroid</li>
<li><em>Application name:</em> Hello, Android</li>
</ul>
-
+ <p>Click <strong>Finish</strong>.</p>
<a href="images/hello_world_1.png"><img src="images/hello_world_1.png" style="height:230px" alt="" /></a>
<p>Here's what each field on this screen means:</p>
@@ -74,12 +77,18 @@ In some cases, you might want to click the screenshots below to get a bigger vie
</li>
-<li>Edit the auto-generated source code.
-<p>After the plugin runs, you'll have a class named <code>HelloAndroid</code>
-(found in your package, <em>HelloAndroid > src > com.android.hello</em>). It should look like
+<li><strong>View the auto-generated source code.</strong>
+<p>After the plugin completes your project creations, you'll have a class named <code>HelloAndroid</code>
+(found in your project package, <em>HelloAndroid > src > com.android.hello</em>). It should look like
this:</p>
-<pre>public class HelloAndroid extends Activity {
+<pre>
+package com.example.hello;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
&#64;Override
public void onCreate(Bundle savedInstanceState) {
@@ -88,9 +97,7 @@ this:</p>
}
}</pre>
-<p>Now, you <em>could</em> run this right away, but let's go a little further,
-so we understand more about what's happening.
-So, the next step is to modify some code! </p>
+<p>Now let's modify some code! </p>
</li>
</ol>
@@ -105,16 +112,16 @@ package com.android.hello;
import android.app.Activity;
import android.os.Bundle;
-import android.widget.TextView;
+<strong>import android.widget.TextView;</strong>
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
&#64;Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- TextView tv = new TextView(this);
+ <strong>TextView tv = new TextView(this);
tv.setText(&quot;Hello, Android&quot;);
- setContentView(tv);
+ setContentView(tv);</strong>
}
}</pre>
@@ -122,16 +129,21 @@ public class HelloAndroid extends Activity {
press <strong>Ctrl-Shift-O</strong> (<strong>Cmd-Shift-O</strong>, on Mac). This is an Eclipse
shortcut to organize imports&mdash;it identifies missing packages and adds them for you.</p>
-<p>In Android, user interfaces are composed of hierarchies of classes called
-Views. A View is simply a drawable object, such as a radio button, an
+<p>Notice that our class is based on the {@link android.app.Activity} class. An Activity is a
+single application entity that is used to perform actions. An application may have many, but the user
+interacts with them only one at a time. An Activity is not required to actually have a user interface,
+but usually will.</p>
+
+<p>An Android user interface is composed of hierarchies of objects called
+Views. A {@link android.view.View} is simply a drawable object, such as a radio button, an
animation, or (in our case) a text label. The specific name for the View
-subclass that handles text is simply TextView.</p>
+subclass that handles text, which we use here, is {@link android.widget.TextView}.</p>
<p>Here's how you construct a TextView:</p>
<pre>TextView tv = new TextView(this);</pre>
-<p>The argument to TextView's constructor is an Android Context instance. The
+<p>The argument to TextView's constructor is an Android {@link android.content.Context} instance. The
Context is simply a handle to the system; it provides services like
resolving resources, obtaining access to databases and preferences, and so
on. The Activity class inherits from Context. Since our
@@ -189,18 +201,21 @@ simply continue.</p>
<a href="images/hello_world_4.png"><img src="images/hello_world_4.png" style="height:230px" alt="" /></a>
-<p>That's it &mdash; you're done! Click the Run button, and the Android Emulator
-should start. Once it's booted up your application will appear. When all is said and done, you should
+<p>Now click <strong>Run</strong>, and the Android Emulator should start and open the application.
+Once it's booted up your application will appear. (Once booted, you may need to unlock the emulator's phone screen
+by pressing the device MENU key.) When all is said and done, you should
see something like this:</p>
<a href="images/hello_world_5.png"><img src="images/hello_world_5.png" style="height:230px" alt="" /></a>
+
<p>That's "Hello, World" in Android. Pretty straightforward, eh?
The next sections of the tutorial offer more detailed information that you may find valuable as you
learn more about Android.</p>
+
<h2 id="upgrading">Upgrading the UI to an XML Layout</h2>
<p>The "Hello, World" example you just completed uses what we call "programmatic"
@@ -220,12 +235,12 @@ programmatically-constructed example you just completed:</p>
&lt;TextView xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
android:layout_width=&quot;fill_parent&quot;
android:layout_height=&quot;fill_parent&quot;
- android:text=&quot;Hello, Android&quot;/&gt;</pre>
+ android:text=&quot;@string/hello&quot;/&gt;</pre>
<p>The general structure of an Android XML layout file is simple: it's a tree
of XML elements, where each element is the name of a View class
(this example, however, is just one element). You can use the
-name of any class that extends View as an element in your XML layouts,
+name of any class that extends {@link android.view.View} as an element in your XML layouts,
including custom View classes you define in your own code. This
structure makes it very easy to quickly build up UIs, using a more simple
structure and syntax than you would in source code. This model is inspired
@@ -274,14 +289,20 @@ which has four XML attributes. Here's a summary of what they mean:</p>
<code>android:text</code>
</td>
<td>
- This sets the text that the TextView should contain. In this example, it's our usual "Hello, Android" message.
+ This sets the text that the TextView should display. In this example, we use a string
+ resource instead of a hard-coded string value.
+ The <em>hello</em> string is defined in the <em>res/values/strings.xml</em> file. This is the
+ recommended practice for inserting strings to your application, because it makes the localization
+ of your application to other languages graceful, without need to hard-code changes to the layout file.
+ For more information, see <a href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources
+ and Internationalization</a>.
</td>
</tr>
</tbody>
</table>
-<p>This layout file belongs in the <code>res/layout/</code> directory in your project. The "res" is
+<p>These layout files belong in the <em>res/layout/</em> directory in your project. The "res" is
short for "resources" and that directory contains all the non-code assets that
your application requires. Resources also include things like images, localized
strings, and XML layout files.</p>
@@ -293,17 +314,43 @@ strings, and XML layout files.</p>
Without it the layout will just be stretched.</p>
</div>
-<p>The Eclipse plugin creates one of these XML files for you (<code>main.xml</code>). In our example
-above, we just ignored it and created our layout programmatically. In the Eclipse Package Explorer, expand the
-folder res/layout/, and open the file <code>main.xml</code> (once opened, you might need to click
+<p>The Eclipse plugin automatically creates one of these layout files for you (<code>main.xml</code>). In our example
+above, we just ignored it and created our layout programmatically. We did so just to teach you a little more
+about the framework, but you should almost always define your layout in an XML file instead of in your code.</p>
+
+<p>So, let's put it to use and change the "Hello, Android" sample to use the XML layout.</p>
+
+<ol>
+ <li>In the Eclipse Package Explorer, expand the
+folder <em>res/layout/</em>, and open the file <code>main.xml</code> (once opened, you might need to click
the "main.xml" tab at the bottom to see the XML source). Replace its contents with
-the sample XML above and save your changes.</p>
+the following XML:
+<pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
+&lt;TextView xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
+ android:layout_width=&quot;fill_parent&quot;
+ android:layout_height=&quot;fill_parent&quot;
+ android:text=&quot;@string/hello&quot;/&gt;</pre>
+<p>Save the file.</p>
+</li>
-<p>Now open and modify your <code>HelloAndroid</code> class source code to read the
-XML layout, instead of the hard-coded version. Edit the file to look like this:</p>
+<li>Inside the project folder <em>res/values/</em>, open the file <code>strings.xml</code>.
+This is where you should save all default text strings for your user interface. If you're using Eclipse, then
+ADT will have started you with two strings, <em>hello</em> and <em>app_name</em>.
+Revise <em>hello</em> to something else. Perhaps "Hello, Android! I am a string resource!"
+The entire file should now look like this:
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+ &lt;string name="hello">Hello, Android! I am a string resource!&lt;/string>
+ &lt;string name="app_name">Hello, Android&lt;/string>
+&lt;/resources>
+</pre>
+</li>
+<li>Now open and modify your <code>HelloAndroid</code> class source code to read the
+XML layout, instead of the hard-coded version. Edit the file to look like this:
<pre>
-package com.android.hello;
+package com.example.hello;
import android.app.Activity;
import android.os.Bundle;
@@ -319,39 +366,50 @@ public class HelloAndroid extends Activity {
<p>When you make this change, type it by hand to try the code-completion feature on that R class. You'll probably find that it helps a lot.</p>
-<p>The <code>setContentView()</code> method we're now using expects a reference to a layout resource.
-We pass it <code>R.layout.main</code>, which is the reference to the <code>layout/main.xml</code> once it's
-compiled into our R class by the Eclipse plugin. (More about the R class in a moment.)</p>
+<p>Now, instead of passing <code>setContentView()</code> a View object, we give it a reference to our layout resource.
+The resource is identified as <code>R.layout.main</code>, which is actually a compiled object representation of
+the layout defined in <em>layout/main.xml</em>. The Eclipse plugin automatically creates this reference for
+us inside the project's R.java class. If you're not using Eclipse, then the R.java class will be generated for you
+when you run Ant to build the application. (More about the R class in a moment.)</p>
+</li>
+</ol>
<p>Now that you've made this change, go ahead and re-run your application &mdash; all
you need to do is click the green Run arrow icon, or select
-<strong>Run &gt; Run History &gt; Hello, Android</strong> from the menu. You should see.... well, exactly the same thing
+<strong>Run &gt; Run History &gt; Hello, Android</strong> from the menu. You should see pretty much the same thing
you saw before! After all, the point was to show that the two different
layout approaches produce identical results.</p>
-<p>There's a lot more to creating these XML layouts, but that's as far as we'll go
-here. Read the <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> documentation for more
-information on creating layouts.</p>
+<p class="note"><strong>Tip:</strong> Use the shortcut <strong>Ctrl-Shift-F11</strong>
+(<strong>Cmd-Shift-F11</strong>, on Mac) to run your currently visible application.</p>
+
+<p>You've just completed your first Android application! Continue reading for an introduction
+to debugging and a little more information on using other IDEs. Once you're ready to move on,
+please begin by reading <a href="{@docRoot}guide/topics/fundamentals.html">Application
+Fundamentals</a>. Also refer to the <a href="{@docRoot}guide/index.html">Developer's Guide</a>
+introduction page for an overview of the <em>Dev Guide</em> documentation.</p>
+
<div class="special">
<h3>R class</h3>
-<p>Open the file named R.java in your source code folder in the Package
+<p>In Eclipse, open the file named R.java in your source code folder in the Package
Explorer. It should look something like this:</p>
<pre>
public final class R {
public static final class attr {
- };
+ }
public static final class drawable {
public static final int icon=0x7f020000;
- };
+ }
public static final class layout {
public static final int main=0x7f030000;
- };
+ }
public static final class string {
- public static final int app_name=0x7f040000;
- };
-};
+ public static final int app_name=0x7f040001;
+ public static final int hello=0x7f040000;
+ }
+}
</pre>
<p>A project's R.java file is an index into all the resources defined in the
@@ -361,10 +419,13 @@ particularly powerful with the code-completion features of IDEs like Eclipse
because it lets you quickly and interactively locate the specific reference
you're looking for.</p>
-<p>For now, notice the inner class named "layout", and its
+<p>It's possible yours looks slighly different than this (perhaps the hexadecimal values are different).
+For now, notice the inner class named "layout", and its
member field "main". The Eclipse plugin noticed the XML
layout file named main.xml and generated a class for it here. As you add other
-resources to your project (in the <code>res/</code> directory), you'll see R.java change to keep up.</p>
+resources to your project (such as strings in the <em>res/values/string.xml</em> file or drawables inside
+the <em>res/drawable/</em> direcory) you'll see R.java change to keep up.</p>
+<p>When not using Eclipse, this class file will be generated for you at build time (with the Ant tool).</p>
<p><em>You should never edit this file by hand.</em></p>
</div>
@@ -436,4 +497,4 @@ just as you would for any other application.</p>
installed and run in your emulator using the 'adb' tool.</p>
<p>For more information on how to use these tools, please read the documentation
- cited above.</p> \ No newline at end of file
+ cited above.</p>
diff --git a/docs/html/images/judgebio_charles.jpg b/docs/html/images/judgebio_charles.jpg
deleted file mode 100644
index 2449cfe..0000000
--- a/docs/html/images/judgebio_charles.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/judgebio_dibona.jpg b/docs/html/images/judgebio_dibona.jpg
deleted file mode 100644
index 91869fb..0000000
--- a/docs/html/images/judgebio_dibona.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/judgebio_gadi.jpg b/docs/html/images/judgebio_gadi.jpg
deleted file mode 100644
index d1e40c3..0000000
--- a/docs/html/images/judgebio_gadi.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/judgebio_jens.jpg b/docs/html/images/judgebio_jens.jpg
deleted file mode 100644
index 6f07254..0000000
--- a/docs/html/images/judgebio_jens.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/judgebio_jeremiah.jpg b/docs/html/images/judgebio_jeremiah.jpg
deleted file mode 100644
index c91b43f..0000000
--- a/docs/html/images/judgebio_jeremiah.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/judgebio_kristian.jpg b/docs/html/images/judgebio_kristian.jpg
deleted file mode 100644
index 19e93dd..0000000
--- a/docs/html/images/judgebio_kristian.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/images/judgebio_leon.jpg b/docs/html/images/judgebio_leon.jpg
deleted file mode 100644
index c648bd3..0000000
--- a/docs/html/images/judgebio_leon.jpg
+++ /dev/null
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 8db339d..bd681e2 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -1,5 +1,4 @@
home=true
-page.title=Home
@jd:body
diff --git a/docs/html/license.jd b/docs/html/license.jd
index 39fb3a0..88932b6 100644
--- a/docs/html/license.jd
+++ b/docs/html/license.jd
@@ -1,4 +1,5 @@
-page.title=Content License
+page.title=Content License
+hide_license_footer=true
@jd:body
<div id="mainBodyFluid">
@@ -30,8 +31,8 @@ is licensed under GPLv2 or other license. In those cases, the license
covering the source code module will apply to the documentation
extracted from it. </p>
-<p>All other content on this site, except as otherwise noted,
-is licensed under the <a
+<p>All other content on this site, except the license documents themselves
+and as otherwise noted, is licensed under the <a
href="http://creativecommons.org/licenses/by/2.5/">Creative Commons
Attribution 2.5</a> license. </p>
diff --git a/docs/html/offline.jd b/docs/html/offline.jd
index 07c20d6..d41459b 100644
--- a/docs/html/offline.jd
+++ b/docs/html/offline.jd
@@ -8,21 +8,29 @@ page.title=Welcome
<img src="{@docRoot}images/android_icon_125.png" style="float:right; margin:1em 6em 6em;" />
-<p>If you've just downloaded the SDK, then continue with the
-<a href="{@docRoot}sdk/1.1_r1/installing.html">Installing</a> guide.</p>
+<p>If you've just downloaded the SDK, then continue with
+<a href="{@docRoot}sdk/1.1_r1/installing.html">Installing the Android SDK</a>.</p>
<p>If you're upgrading from a previously installed version, then refer to the
<a href="{@docRoot}sdk/1.1_r1/upgrading.html">Upgrading</a> guide.</p>
-<p>Once you've completed the SDK installation, you can start learning about development on the Android framework
-by reading the <em><a href="{@docRoot}guide/index.html">Dev Guide</a></em>. And don't forget that the SDK comes packaged with
-a wide variety of very helpful code <a href="{@docRoot}samples/index.html">samples</a>.</p>
+<p>Once you've completed the SDK installation, you can start learning about
+development on the Android framework by reading the <a
+href="{@docRoot}guide/index.html">Developer's Guide</a>. The SDK package
+also includes a wide variety of very helpful <a
+href="{@docRoot}samples/index.html">code samples</a>.</p>
-<p>Please note that you are currently viewing a local, offline version of the Android developer documentation.
-The offline documentation will behave just like the online documentation, except searches in the above
-search bar will not work. However, the search bar is still able to provide auto-completion for package and class names,
-which can help you quickly find reference documentation for specific classes that you remember.
-If you'd like fully searchable documentation, please visit
-<a href="http://developer.android.com/index.html">http://developer.android.com</a>.</p>
+<p>Please note that you are currently viewing a local, offline version of the
+Android developer documentation. The offline documentation offers the same
+content and features as the online documentation, but since the search
+capability is network-based, it will not work while you are offline.
+Autocompletion for API packages and classes, also offered from the search box,
+is available both online and offline and loads the reference documentation for
+the item you select.</p>
-</div> \ No newline at end of file
+<p>For the most current, fully searchable documentation, please visit</p>
+
+<p style="margin-left:2em;"><a href="http://developer.android.com/index.html">
+http://developer.android.com</a>.</p>
+
+</div>
diff --git a/docs/html/roadmap.jd b/docs/html/roadmap.jd
deleted file mode 100644
index 1198638..0000000
--- a/docs/html/roadmap.jd
+++ /dev/null
@@ -1,120 +0,0 @@
-page.title=Developer Roadmap
-@jd:body
-<h1>Android Developer Roadmap</h1>
-<h2>Introduction</h2>
-<p>
-On 12 November, 2007, we made available the first early look at the Android
-SDK to give developers an opportunity to explore Android and build
-applications for the Android Developer Challenge. That was followed by the
-"M5" early look build.
-</p><p>
-Since then, we've been hard at work with our <a
-href="http://www.openhandsetalliance.com/">partners</a> preparing the first
-device for launch and finalizing the APIs and platform. The developer
-feedback we received via the "early look" SDKs has been extremely valuable in
-that process. This Roadmap outlines our plans for
-the coming months, and lets you know what to expect as we near device
-availability.
-</p><p>
-This is the top-level Roadmap. Individual components of Android (such as
-the Dalvik virtual machine, the Android Developer Tools, and so on) will have
-their own roadmaps, once we complete the source code release. Those roadmaps
-will be linked to this page, as they become available.
-</p>
-<h2>Timeline</h2>
-<p>
-To orient yourself, consult this brief timeline. Read on for details on these
-milestones.
-</p><ul>
-<li>12 November, 2007 - "Early Look" SDK released</li>
-<li>January to August, 2008 - Android Developer Challenge I</li>
-<li>18 August, 2008 - Android 0.9 SDK beta released</li>
-<li>28 August, 2008 - Android Market introduced</li>
-<li>23 September, 2008 - Android 1.0 SDK Release 1 available (first actual
-1.0-compatible SDK)</li>
-<li>22 October, 2008 - Android 1.0 devices available at retail</li>
-<li>Q4 2008 - Source code released</li>
-<li>Q4 2008 - Key Announcement on Android Developer Challenge II</li>
-</ul>
-<h2>SDK Naming and Compatibility</h2>
-<p>
-Before we dive into details, here is a quick note on how we name SDKs.
-</p><p>
-We've adopted the following naming convention for Android SDKs:
- "Android &lt;Platform&gt; SDK, release &lt;Release&gt;"
-</p><p>
-The downloadable file names for the SDKs will have this naming convention:
- "android-sdk-&lt;Host-OS&gt;-&lt;Platform&gt;_r&lt;Release&gt;.zip"
-</p><p>
-The "&lt;Platform&gt;" refers to the version of the Android platform with which the
-SDK is compatible. For instance, an SDK that can be used to build
-applications that will run on Android 1.0 is considered to be an "Android 1.0
-SDK". However, since we do expect to release bug fixes and enhancements for
-the various tools included in the SDK (such as the emulator, Eclipse plugin,
-DDMS, and so on) we need to distinguish between releases of the SDK that can
-be used to build for the same Android platform. That's what we will use the
-"&lt;Release&gt;" for.
-</p><p>
-For example, the first SDK that is compatible with Android 1.0 is named
-"Android 1.0 SDK, release 1", and will have file names such as
-"android-sdk-windows-1.0_r1.zip". In the future, after we release a
-hypothetical Android 2.0 platform version, you might see an SDK named "Android
-2.0 SDK, release 3", which would refer to the third released SDK compatible
-with Android 2.0.
-</p>
-<h2>Details of Key Events</h2>
-<h3>Ongoing SDK Releases</h3>
-<p>
-The SDK consists of two general pieces: a version of the Android platform
-itself (that runs in the emulator), and the accompanying developer tools that
-surround it. This means that when we ship SDK releases, all releases within a
-given series (such as all the SDKs for Android 1.0) will consist of
-essentially the same platform image, but with different, updated tools.
-</p><p>
-In August, we released Android 0.9 SDK, beta. The Android
-platform image was not quite 1.0-final (which is why we identified it as 0.9),
-and the tools were not yet final (which is why we referred to it as
-beta.) </p>
-
-<p>For the SDK that includes the Android 1.0 platform and updated tools,
-we've dropped the beta labeling and released "Android 1.0 SDK, release
-1". Applications developed on this SDK version will be compatible with
-devices that run the Android 1.0 platform.</p>
-
-<h3>Device Availability</h3>
-<p>The first Android-powered device, the T-Mobile G1, was announced on 23 September,
-2008. To learn more about the T-Mobile G1, see the <a href="http://www.t-mobileg1.com">T-Mobile G1 site</a>.
-
-<p>Other partners will be releasing Android-powered devices in the future.
-We will update this space with more specific information about each device
-release, as it becomes
-available.</p>
-
-<h3>Source Code Release</h3>
-<p>
-We are currently in the process of preparing for the release of the source
-code. This includes a few key tasks:
-</p><ul>
-<li>Selection of hosting infrastructure</li>
-<li>Updating the build infrastructure for general use</li>
-<li>Creation of a project governance framework</li>
-<li>Final examination of source code for release approval</li>
-<li>Physical upload and release packaging of the source code</li>
-</ul><p>
-This work is already under way, but since Android contains some 8 million
-lines of code, it's a lengthy process. We expect this process to conclude
-(and source code to be released) in Q4 of 2008.
-</p>
-<h3>Android Developer Challenge II</h3>
-<p>
-When Android was announced on 5 November, 2007, Google also announced a $10
-million <a href="{@docRoot}adc.html">Android Developer Challenge</a>, split into two separate $5 million
-events. The first Android Developer Challenge ran from January 2008 through
-August 2008, and was intended to give developers an opportunity to explore
-their ideas using the early look SDK and build prototype applications -- to
-"get in on the ground floor." The second Challenge will give developers a
-chance to build polished applications once hardware is available.
-</p><p>
-We'll be making some interesting announcements regarding ADC II soon, in Q3 or
-Q4.
-</p>
diff --git a/docs/html/robots.txt b/docs/html/robots.txt
new file mode 100644
index 0000000..a872944
--- /dev/null
+++ b/docs/html/robots.txt
@@ -0,0 +1,6 @@
+User-Agent: *
+Allow: /
+Disallow: /gae_shell/
+Disallow: /assets/
+Disallow: /images/
+Sitemap: http://developer.android.com/sitemap.txt
diff --git a/docs/html/sdk/1.1_r1/index.jd b/docs/html/sdk/1.1_r1/index.jd
index b516acb..7e70b6b 100644
--- a/docs/html/sdk/1.1_r1/index.jd
+++ b/docs/html/sdk/1.1_r1/index.jd
@@ -1,19 +1,19 @@
-page.title=Download Android 1.1 SDK, Release 1
+page.title=Android 1.1 SDK, Release 1
sdk.version=1.1_r1
sdk.date=February 2009
sdk.win_download=android-sdk-windows-1.1_r1.zip
-sdk.win_bytes=unknown
-sdk.win_checksum=unknown
+sdk.win_bytes=84533935
+sdk.win_checksum=4cec82e3d2c1658d73182e543d130a06
sdk.mac_download=android-sdk-mac_x86-1.1_r1.zip
-sdk.mac_bytes=unknown
-sdk.mac_checksum=unknown
+sdk.mac_bytes=78918508
+sdk.mac_checksum=d67fb5f0eaf4f5a83dc985f5790940c6
sdk.linux_download=android-sdk-linux_x86-1.1_r1.zip
-sdk.linux_bytes=unknown
-sdk.linux_checksum=unknown
+sdk.linux_bytes=79219171
+sdk.linux_checksum=df88091c9f0ef6cc56cd92afcdad8d56
@jd:body
@@ -57,6 +57,6 @@ in the <code>&lt;sdk&gt;/samples/</code> directory of the SDK package.</p>
<p>The most current documentation is always available on the Android Developers site:</p>
-<p style="margin-left:2em;"><a href="ttp://developer.android.com/index.html">http://developer.android.com/</a></p>
+<p style="margin-left:2em;"><a href="http://developer.android.com/index.html">http://developer.android.com/</a></p>
diff --git a/docs/html/sdk/1.1_r1/installing.jd b/docs/html/sdk/1.1_r1/installing.jd
index 1319237..b198800 100644
--- a/docs/html/sdk/1.1_r1/installing.jd
+++ b/docs/html/sdk/1.1_r1/installing.jd
@@ -5,10 +5,11 @@ sdk.version=1.1_r1
<p>This page describes how to install the Android 1.1 SDK, Release 1, and set up your development environment.
-If you haven't downloaded the SDK yet, you can so so from the <a href="{@docRoot}sdk/1.1_r1/index.html">Download</a> page.</p>
+If you haven't downloaded the SDK yet, you can so from the <a href="{@docRoot}sdk/1.1_r1/index.html">Download</a> page.</p>
<p>Before you begin, be sure that your development environment meets the SDK
-<a href="{@docRoot}sdk/1.1_r1/requirements.html">System Requirements</a>.</p>
+<a href="{@docRoot}sdk/1.1_r1/requirements.html">System Requirements</a>. If you encounter any problems during installation,
+see the <a href="#installnotes">Installation Notes</a> at the bottom of this page.</p>
<h4 style="margin-top">Upgrading?</h4>
<p>If you have already developed applications using an earlier version of the
@@ -20,7 +21,7 @@ SDK, please skip this page and read the
<a name="setup"></a>
<h2>Installing the SDK</h2>
- <p>After downloading the SDK, unpack the .zip archive to a suitable location on your machine. By default, the SDK files are unpacked into a directory named <code>android_sdk_<em>&lt;platform</em>&gt;_<em>&lt;release&gt;</em>_<em>&lt;build&gt;</em></code>. The directory contains the subdirectories <code>tools/</code>, <code>samples/</code>, and others. </p>
+ <p>After downloading the SDK, unpack the .zip archive to a suitable location on your machine. By default, the SDK files are unpacked into a directory named <code>android_sdk_<em>&lt;platform</em>&gt;_<em>&lt;release&gt;</em>_<em>&lt;build&gt;</em></code>. The directory contains a link to a local copy of the documentation and the subdirectories <code>tools/</code>, <code>samples/</code>, and others. </p>
<p>Make a note of the name and location of the unpacked SDK directory on your system &mdash; you will need to refer to the SDK directory later, when setting up the Android plugin or using SDK tools. </p>
@@ -44,25 +45,16 @@ SDK, please skip this page and read the
<p>Adding <code>tools</code> to your path lets you run Android Debug Bridge (adb) and the other command line <a href="{@docRoot}guide/developing/tools/index.html">tools</a> without needing to supply the full path to the tools directory. Note that, if you update your SDK, you should remember to update your PATH settings to point to the new location, if different.</p>
-<h2>Setting up Eclipse</h2>
-<p>If you'll be developing with the Eclipse IDE, follow the following procedure to setup the IDE
-to use the Android SDK.</p>
-<p>Basically, you just need to update your Eclipse preferences to point to the Android SDK directory:</p>
-<ol>
- <li>Select <strong>Window</strong> &gt; <strong>Preferences...</strong> to open the Preferences
- panel. (Mac OS X: <strong>Eclipse</strong> &gt; <strong>Preferences</strong>) </li>
- <li>Select <strong>Android</strong> from the left panel. </li>
- <li>For the SDK Location in the main panel, click <strong>Browse...</strong> and locate the SDK directory. </li>
- <li>Click <strong>Apply</strong>, then <strong>OK</strong>.</li>
-</ol>
-<p>Done! We now recommend that you install the ADT Eclipse plugin, which will provide some much-appreciated assistance in developing Android apps with Eclipse...</p>
+<p>If you will be using the Eclipse IDE as your environment for developing Android applications, continue reading the next
+section in order to install the Android Development Tools plugin and setup Eclipse. If you choose not to use Eclipse, you can
+develop Android applications using other tools &mdash; read the guide to developing
+<a href="{@docRoot}guide/developing/other-ide.html">In other IDEs</a>.</p>
-<h2 id="installingplugin">Installing the Eclipse Plugin (ADT)</h2>
-<p>If you will be using the Eclipse IDE as your environment for developing Android applications, you can install a custom plugin called Android Development Tools (ADT), which adds integrated support for Android projects and tools. The ADT plugin includes a variety of powerful extensions that make creating, running, and debugging Android applications faster and easier. Developing in ADT/Eclipse is highly recommended for Eclipse users and those new to Android.</p>
+<h2>Setting up Eclipse</h2>
-<p>If you <em>will not</em> be using the Eclipse IDE, you do not need to download or install the ADT plugin. You can still develop Android applications using other tools. </p>
+<p>First, you should install a custom plugin called Android Development Tools (ADT), which adds integrated support for Android projects and tools. The ADT plugin includes a variety of powerful extensions that make creating, running, and debugging Android applications faster and easier. Developing in ADT/Eclipse is highly recommended for Eclipse users and those new to Android.</p>
<p>To download and install the ADT plugin, follow the steps below for your respective Eclipse version. </p>
@@ -131,6 +123,21 @@ to use the Android SDK.</p>
</tr>
</table>
+
+<p>Now, you just need to modify your Eclipse preferences to point to the Android SDK directory:</p>
+<ol>
+ <li>Select <strong>Window</strong> &gt; <strong>Preferences...</strong> to open the Preferences
+ panel. (Mac OS X: <strong>Eclipse</strong> &gt; <strong>Preferences</strong>) </li>
+ <li>Select <strong>Android</strong> from the left panel. </li>
+ <li>For the SDK Location in the main panel, click <strong>Browse...</strong> and locate the SDK directory. </li>
+ <li>Click <strong>Apply</strong>, then <strong>OK</strong>.</li>
+</ol>
+
+<p>Done! If you haven't encountered any problems, then you're ready to begin developing Android applications.
+We recommend you begin with the <a href="{@docRoot}guide/tutorials/hello-world.html">Hello World</a> tutorial,
+which will teach you some basics about Android applications and how to create projects using Eclipse.</p>
+
+
<h3 id="troubleshooting">Troubleshooting ADT Installation</h3>
<p>
If you are having trouble downloading the ADT plugin after following the steps above, here are some suggestions: </p>
diff --git a/docs/html/sdk/1.1_r1/upgrading.jd b/docs/html/sdk/1.1_r1/upgrading.jd
index aa7c3a5..2ad6757 100644
--- a/docs/html/sdk/1.1_r1/upgrading.jd
+++ b/docs/html/sdk/1.1_r1/upgrading.jd
@@ -30,7 +30,7 @@ sdk.version=1.1_r1
</div>
-->
-<p>This document describes how to move your devlopment environment and existing
+<p>This document describes how to move your development environment and existing
Android applications from an Android 1.0 SDK to the Android 1.1, Release 1 SDK.
If you are migrating applications from an earlier SDK, please read the upgrading
document available in the Android 1.0 SDK package.
@@ -38,18 +38,18 @@ document available in the Android 1.0 SDK package.
<p>To ensure that your applications are compliant with the Android 1.1 system available
on mobile devices, you need to install the Android 1.1 SDK and port your existing Android
-applications to it. The sections below guide you through the process.</p>
+applications to it. The sections below will guide you through the process.</p>
<h2 id="install-new">Installing the Latest SDK</h2>
<p><a href="{@docRoot}sdk/1.1_r1/index.html">Download the SDK</a> and unpack it into a safe location.</p>
-<p>After unpacking the new SDK, you should:</p>
+<p>After unpacking the new SDK and saving it an appropriate location, you should:</p>
<ul>
<li>Wipe your emulator data. <p>Some data formats have changed since the last
SDK release, so any previously saved data in your emulator must be removed. Open a console/terminal
- and navigate to the <code>/tools</code> directory of your SDK. Launch the
+ and navigate to the <code>/tools</code> directory of your new SDK. Launch the
emulator with the <code>-wipe-data</code> option.
<p>Windows: <code>emulator -wipe-data</code><br/>
Mac/Linux: <code>./emulator -wipe-data</code></p>
@@ -71,7 +71,7 @@ applications to it. The sections below guide you through the process.</p>
<h2 id="update-plugin">Update your ADT Eclipse Plugin</h2>
<p>If you develop on Eclipse and are migrating from an Android 1.0
-SDK, no update of the ADT plugin is needed. </p>
+SDK, no update of the ADT plugin is needed &mdash; skip to <a href="#updateEclipsePrefs">Update your Eclipse SDK Preferences</a>. </p>
<p>If you are migrating from an earlier version of the SDK, you will
need to update the ADT plugin. <p>You may also want to upgrade your
@@ -111,7 +111,9 @@ version available. </p>
</tr>
</table>
-<p>After restart, update your Eclipse preferences to point to the SDK directory:</p>
+<h2 id="updateEclipsePrefs">Update your Eclipse SDK Preferences</h2>
+
+<p>The last step is to update your Eclipse preferences to point to the new SDK directory:</p>
<ol>
<li>Select <strong>Window</strong> > <strong>Preferences...</strong> to open the Preferences panel. (Mac OSX: <strong>Eclipse</strong> > <strong>Preferences</strong>)</li>
<li>Select <strong>Android</strong> from the left panel.</li>
@@ -119,43 +121,6 @@ version available. </p>
<li>Click <strong>Apply</strong>, then <strong>OK</strong>.</li>
</ol>
-
-<!--
-<h2 id="sign">Set Up Application Signing</h2>
-
-<p>All applications must now be signed before you can install them on the emulator. Both
-the ADT plugin and the Ant-based build tools support this requirement by signing compiled
-.apk files with a debug key. To do so, the build tools use the Keytool utility included
-in the JDK to to create a keystore and a key with a known alias and password. For more
-information, see <a href="{@docRoot}guide/publishing/app-signing.html">Signing Your Applications</a>.
-
-<p>To support signing, you should first make sure that Keytool is available to the SDK build
-tools. In most cases, you can tell the SDK build tools how to find Keytool by making sure that
-your JAVA_HOME environment variable is set and that it references a suitable JDK. Alternatively,
-you can add the JDK version of Keytool to your PATH variable.</p>
-
-<p>If you are developing on a version of Linux that originally came with Gnu Compiler for Java,
-make sure that the system is using the JDK version of Keytool, rather than the gcj version.
-If keytool is already in your PATH, it might be pointing to a symlink at /usr/bin/keytool.
-In this case, check the symlink target to make sure that it points to the keytool in the JDK.</p>
-
-<p>If (and only if) you use Ant to build your .apk files (rather than ADT for Eclipse), you must regenerate
-your build.xml file. To do that, follow these steps:</p>
-<ol>
- <li>In your Android application project directory, locate and delete the current build.xml file.</li>
- <li>Run activitycreator, directing output to the folder containing your application project.
-
-<pre>- exec activitycreator --out &lt;project folder&gt; your.activity.YourActivity</pre>
-
- </li>
-</ol>
-
-<p>Run in this way, activitycreator will not erase or create new Java files (or manifest files),
-provided the activity and package already exists. It is important that the package and the activity
-are real. The tool creates a new build.xml file, as well as a new directory called "libs" in which
-to place 3rd jar files, which are now automatically handled by the Ant script.</p>
--->
-
<h2 id="migrate">Migrate Your Applications, if Necessary</h2>
<p>If (and only if) you have written apps in an SDK released previous to
diff --git a/docs/html/sdk/RELEASENOTES.jd b/docs/html/sdk/RELEASENOTES.jd
index 6e0716c..bad71a2 100644
--- a/docs/html/sdk/RELEASENOTES.jd
+++ b/docs/html/sdk/RELEASENOTES.jd
@@ -1,10 +1,9 @@
page.title=SDK Release Notes
-sdk.version=1.1_r1
@jd:body
<p>This document provides version-specific information about Android SDK releases. For the latest known issues, please ensure that you're viewing this page at: <a href="http://developer.android.com/sdk/RELEASENOTES.html">http://developer.android.com/sdk/RELEASENOTES.html</a>.</p>
-<h2>Android 1.1 SDK, Release 1</h2>
+<h2 id="1.1_r1">Android 1.1 SDK, Release 1</h2>
<p>This SDK provides the development tools and Android system image you need to create applications for Android-powered devices. Applications developed on this SDK will be compatible with mobile devices running the Android 1.1 platform. </p>
@@ -20,14 +19,14 @@ sdk.version=1.1_r1
<pre><code>&lt;manifest&gt;
...
- &lt;uses-sdk minSdkVersion="2"&gt;
+ &lt;uses-sdk minSdkVersion="2" /&gt;
...
&lt;/manifest&gt;</code>
</pre>
<p>By setting <code>android:minSdkVersion</code> in this way, you ensure that users will only be able to install your application if their devices are running the Android 1.1 platform. In turn, this ensures that your application will function properly on their devices, especially if it uses APIs introduced in Android 1.1. </p>
-<p>If your application uses APIs introduced in Android 1.1 but does not declare <code>&lt;uses-sdk minSdkVersion="2"&gt;</code>, then it will run properly on Android 1.1 devices but <em>not</em> on Android 1.0 devices. </p>
+<p>If your application uses APIs introduced in Android 1.1 but does not declare <code>&lt;uses-sdk minSdkVersion="2" /&gt;</code>, then it will run properly on Android 1.1 devices but <em>not</em> on Android 1.0 devices. </p>
<p>If your application does not use any new APIs introduced in Android 1.1, you can indicate Android 1.0 compatibility by removing <code>minSdkVersion</code> or setting the attribute to "1". However, before publishing your application, you must make sure to compile your application against the Android 1.0 system image (available in the Android 1.0 SDK), to ensure that it builds and functions properly for Android 1.0 devices. You should test the application against system images corresponding to the API Levels that the application is designed to be compatible with.</p>
@@ -115,7 +114,196 @@ in Eclipse</a>.</li>
<li>It is not possible to send MMS messages between emulator instances. </li>
<li>In some cases, you may encounter problems when using the browser on an
emulator started with the command-line option <code>-http-proxy</code>. </li>
-<li>We regret to inform developers that Android 1.1 will not include support for
+<li>On the OSX platform, if you manually remove the ~/.android directory
+using <code>rm -rf ~/.android</code>, then try to run
+the emulator, it crashes. This happens because the emulator fails to create
+a new .android directory before attempting to create the child SDK1.0 directory.
+To work around this issue, manually create a new .android directory using
+<code>mkdir ~/.android</code>, then run the emulator. The emulator
+creates the SDK1.0 directory and starts normally. </li>
+<li>We regret to inform developers that Android 1.1 will not include support
+for ARCNet network interfaces.</li>
+<li>The final set of Intent patterns honored by Android 1.0 has not yet been
+fully documented. Documentation will be provided in future releases.</li>
+<li>In ADT Editor, you can add at most ten new resource values at a time,
+in a given res/values/*.xml, using the form in the Android Resources pane.
+If you add more than ten, the Android Resources pane will not display the
+attributes fields for the additional resource entries. To work around this
+problem, you can close the file in the editor and open it again, or you
+can edit the resource entries in the XML text mode. </li>
+<li>The emulator's battery-control commands (<code>power &lt;option&gt</code>)
+are not working in this release.</li>
+</ul>
+
+
+
+
+
+<h2 id="1.0_r2">Android 1.0 SDK, Release 2</h2>
+
+<p>This SDK release includes the Android 1.0 platform and application API.
+Applications developed on this SDK will be compatible with mobile devices
+running the Android 1.0 platform.</p>
+
+<p>This release includes mainly bug fixes, although some smaller features were
+added.</p>
+
+<h3>ADT Plugin Compatibility</h3>
+
+<p>For this release of the SDK, the compatible version of the Android
+Development Tools (ADT) Plugin for Eclipse is <strong>0.8.0</strong>. If you are
+using a previous version of ADT, you should update to the latest version for use
+with this SDK. For information about how to update your ADT plugin, see <a
+href="/android/intro/upgrading.html">Upgrading the SDK</a>.</p>
+
+<h3>Installation and Upgrade Notes</h3>
+
+<p>If you're installing the Android SDK for the first time, please see the
+instructions in <a href="/android/intro/installing.html">Installing the
+SDK</a>.
+
+<h3>Other Notes</h3>
+
+<p><strong>T-Mobile G1 Compatability</strong></p>
+
+<p>This version of the SDK has been tested for compatability with the first
+Android-powered mobile device, the <a href="http://www.t-mobileg1.com">T-Mobile
+G1</a>. </p>
+
+<p><strong>MapView API Key</strong></p>
+
+<p>MapView is a class that lets you easily integrate Google Maps into your
+application. Before you can access the maps data, you will need to register with
+the Google Maps service and receive a Maps API Key, which you then add to your
+MapView for authentication to the server.</p>
+
+<p>Developers should note that the registration service for MapView is now
+active and Google Maps is actively enforcing the Maps API Key requirement. For
+information about how to register for a Maps API Key, see <a
+href="http://code.google.com/android/toolbox/apis/mapkey.html">http://code.
+google.com/android/toolbox/apis/mapkey.html</a>.</p>
+
+<p><strong>USB Driver for Windows</strong></p>
+<p>If you using Windows and want to develop or test your application on an
+Android-powered device (such as the T-Mobile G1), you need an appropriate USB
+driver. For your convenience, the Windows version of the Android SDK includes a
+USB driver that you can install, to let you develop on the device. The USB
+driver files are located in the <code>&lt;SDK&gt;/usb_driver</code> directory.
+
+</p>
+
+<h3>Resolved Issues, Changes</h3>
+<ul>
+<li>The android.jar in this SDK release now includes several classes that were
+missing from the previous SDK. </li>
+<li>The android.R.styleable class and its fields were removed from the public
+API, to better ensure forward-compatibility for applications. The constants
+declared in android.R.styleable were platform-specific and subject to arbitrary
+change across versions, so were not suitable for use by applications. You can
+still access the platform's styleable attributes from your resources or code. To
+do so, declare a custom resource element using a
+<code>&lt;declare-styleable&gt;</code> in your project's res/values/R.attrs
+file, then declare the attribute inside. For examples, see
+&lt;sdk&gt;/samples/ApiDemos/res/values/attrs.xml. For more information about
+custom resources, see <a
+href="/android/reference/available-resources.html#customresources">Custom
+Layout Resources</a>. Note that the android.R.styleable documentation is still
+provided in the SDK, but only as a reference of the platform's styleable
+attributes for the various elements.</li>
+<li>The VM now properly ensures that private classes are not
+available to applications through reflection. If you were using reflection
+to access private classes in a previous release, you will now get a run-time
+error. </li>
+
+<li>The Settings and Email applications are now included in the SDK and
+available in the emulator.</li>
+<li>We regret to inform developers that SDK 1.0_r2 does not support MFM, RLL,
+or Winchester hard disk drives.</li>
+<li>In the emulator, the control key for enabling/disabling trackball mode
+is changed from Control-T to F6. You can also enter trackball mode temporarily
+using the Delete key. While the key is pressed, you can send trackball events.</li>
+</ul>
+
+<p>Unless otherwise noted, Known Issues from the previous SDK release also apply
+to this release.</p>
+
+
+
+
+
+
+<h2 id="1.0_r1">Android 1.0 SDK, Release 1</h2>
+
+<p>This SDK release is the first to include the Android 1.0 platform and application API. Applications developed on this SDK will be compatible with mobile devices running the Android 1.0 platform, when such devices are available.</p>
+
+<p>This release includes mainly bug fixes, although some smaller features were added. The Android 1.0 also includes several API changes from the 0.9 version. For more information on API changes, see the <a href="/android/migrating/0.9-1.0/changes-overview.html">Overview of Changes</a> and the <a href="/android/migrating/0.9-1.0/changes.html">API Differences Report</a>. For those porting from the M5 release, the SDK also includes the legacy changes overview and API Differences Reports. See the current Overview of Changes for more information. </p>
+
+<h3>ADT Plugin Compatibility</h3>
+
+<p>For this version of the SDK &mdash; Android 1.0 SDK, Release 1 &mdash; the compatible version of the Android Development Tools (ADT) Plugin for Eclipse is <strong>0.8.0</strong>. If you are using a previous version of ADT, you should update to the latest version for use with this SDK. For information about how to update your ADT plugin, see <a href="/android/intro/upgrading.html">Upgrading the SDK</a>.</p>
+
+<h3>Installation and Upgrade Notes</h3>
+
+<p>If you've been developing an application using a previous SDK version and you want the application to run on Android-powered mobile devices, you must port the application to the Android 1.0 SDK. Please see <a href="/android/intro/upgrading.html">Upgrading the SDK</a> for detailed instructions on how to make the transition to this release. Be sure to wipe application user data (emulator option <code>-wipe-data</code>) when running your application on the Android 1.0 SDK emulator.</p>
+
+<p>If you're installing the Android SDK for the first time, please see the instructions in <a href="/android/intro/installing.html">Installing the SDK</a>.
+
+<h3>Other Notes</h3>
+
+<p><strong>MapView API Key</strong></p>
+
+<p><a href="/android/reference/com/google/android/maps/MapView.html">MapView</a> is a class that lets you easily integrate Google Maps into your application. Before you can access the maps data, you will need to register with the Google Maps service and receive a Maps API Key, which you then add to your MapView for authentication to the server.</p>
+
+<p>Currently, the registration service for MapView is not yet active and Google Maps is not yet enforcing the Maps API Key requirement. However, note that the registration service will be activated soon, so that MapViews in any application deployed to a mobile device will require registration and a valid Maps API Key. </p>
+
+<p>As soon as the registration service becomes available, we will update the page at <a href="http://code.google.com/android/toolbox/apis/mapkey.html">http://code.google.com/android/toolbox/apis/mapkey.html</a> with details about how and where to register. Please check that page periodically for registration information, if you are using a MapView.</p>
+
+
+<h3>Resolved Issues, Changes</h3>
+
+<p><strong>Emulator</strong></p>
+<ul>
+<li>Emulator now saves the user image in &lt;android&gt;/SDK1.0/</code></li>
+<li>Fixed EsounD-related freezes on Linux.</li>
+<li>Fixed the documentation in -help-audio. '-audio list' doesn't work, one
+ needs to call -help-audio-out and -help-audio-in to get the list of valid
+ audio backends.</li>
+<li>Fixed scrollwheel Dpad emulation in rotated mode. before that, using the
+ scroll-wheel would always generated Dpad Up/Down events, even when in
+ landscape mode.</li>
+
+<li>Several Obsolete command options were removed.</li>
+<li>Setting the network speed through the console or the -netspeed option will
+ properly modify the connectivity icon on the device.</li>
+<li>Setting the GSM voice registration state to 'roaming' in the console will
+ properly modify the voice icon on the device</li>
+</ul>
+
+<p><strong>SQLite</strong></p>
+<ul>
+<li>SQLite is now included in the SDK package on all platforms. </li>
+</ul>
+
+<h3>Known Issues</h3>
+
+<p><strong>JUnit and Eclipse/ADT</strong></p>
+<ul>
+<li>If you are developing in Eclipse/ADT and want to add JUnit test
+classes, you can do so. However, you need to set up a custom JUnit configuration
+before your tests will run properly. For detailed information about how to set
+up the JUnit configuration, see the troubleshooting topic <a
+href="/android/kb/troubleshooting.html#addjunit">Running a Junit test class
+in Eclipse</a>.</li>
+</ul>
+
+<p><strong>Other</strong></p>
+
+<ul>
+<li>It is not possible to send MMS messages between emulator instances. </li>
+<li>In some cases, you may encounter problems when using the browser on an
+emulator started with the command-line option <code>-http-proxy</code>. </li>
+
+<li>We regret to inform developers that Android 1.0 will not include support for
dot-matrix printers.</li>
<li>On the OSX platform, if you manually remove the ~/.android directory
using <code>rm -rf ~/.android</code>, then try to run
@@ -134,5 +322,6 @@ problem, you can close the file in the editor and open it again, or you
can edit the resource entries in the XML text mode. </li>
<li>The emulator's battery-control commands (<code>power &lt;option&gt</code>)
are not working in this release.</li>
+
</ul>
diff --git a/docs/html/sdk/android-1.1.jd b/docs/html/sdk/android-1.1.jd
index 8e63ba3..f70ad26 100644
--- a/docs/html/sdk/android-1.1.jd
+++ b/docs/html/sdk/android-1.1.jd
@@ -59,7 +59,7 @@ attribute looks like this: </p>
<pre><code>&lt;manifest&gt;
...
- &lt;uses-sdk minSdkVersion="2"&gt;
+ &lt;uses-sdk minSdkVersion="2" /&gt;
...
&lt;/manifest&gt;</code>
</pre>
@@ -71,7 +71,7 @@ your application will function properly on their devices, especially if
it uses <a href="#apichange">APIs introduced in Android 1.1</a>. </p>
<p>If your application uses APIs introduced in Android 1.1 but does not
-declare <code>&lt;uses-sdk minSdkVersion="2"&gt;</code>, then it will
+declare <code>&lt;uses-sdk minSdkVersion="2" /&gt;</code>, then it will
run properly on Android 1.1 devices but <em>not</em> on Android 1.0
devices. In the latter case, the application will crash at runtime when
it tries to use the Android 1.1 APIs.</p>
@@ -175,14 +175,13 @@ AM/PM).</li>
<li>Improves recovery from POP3 connection failures.</li>
<li>POP3 parser rules loosened, so the application can work with
non-compliant email servers.</li>
-<li>Removes green CALL button as a shortcut for "add a new call".</li>
</ul>
<h2 id="features">New Features</h2>
<ul>
<li>Maps: Adds details and reviews when a user does a search on Maps and
-clicks on a business to view it's details.</li>
+clicks on a business to view its details.</li>
<li>Dialer: In-call screen timeout default is now longer when using the
speakerphone.</li>
<li>Dialer: Adds a "Show dialpad" / "Hide dialpad" item to the in-call
@@ -216,9 +215,9 @@ SDK-bound system images. </li>
<th>Module or Feature</th><th>Change Description</th>
</tr>
<tr><td rowspan="4">Annotations for test systems</td></tr>
- <tr><td>Added class {@link android.test.suitebuilder.annotation.LargeTest LargeTest} to package {@link android.test.suitebuilder.annotation}</td></tr>
- <tr><td>Added class {@link android.test.suitebuilder.annotation.MediumTest MediumTest} to package {@link android.test.suitebuilder.annotation}</td></tr>
- <tr><td>Added class {@link android.test.suitebuilder.annotation.SmallTest SmallTest} to package {@link android.test.suitebuilder.annotation}</td></tr>
+ <tr><td>Added {@link android.test.suitebuilder.annotation.LargeTest LargeTest} annotation.</td></tr>
+ <tr><td>Added {@link android.test.suitebuilder.annotation.MediumTest MediumTest} annotation.</td></tr>
+ <tr><td>Added {@link android.test.suitebuilder.annotation.SmallTest SmallTest} annotation.</td></tr>
<tr><td rowspan="2">Allow a process to easily know its UID.</td></tr>
<tr><td>Added public method {@link android.os.Process#myUid} to class {@link android.os.Process android.os.Process}</td></tr>
diff --git a/docs/html/sdk/download.jd b/docs/html/sdk/download.jd
index d64b781..3c4f06b 100644
--- a/docs/html/sdk/download.jd
+++ b/docs/html/sdk/download.jd
@@ -1,15 +1,11 @@
page.title=Download the Android SDK
-@jd:body
-
-<p>Please carefully review the Android SDK License Agreement before downloading the SDK.
-The License Agreement constitutes a contract between you and Google with respect to your use of the SDK.</p>
+hide_license_footer=true
-<iframe style="border:1px solid #888;margin:0 0 1em;height:400px;width:95%;" src="terms_body.html">
-</iframe>
+@jd:body
<script language="javascript">
function verify() {
- document.getElementById('download_button').disabled = !document.getElementById('checkbox').checked;
+ document.getElementById('download-button').disabled = !document.getElementById('checkbox').checked;
}
function submit() {
var location = window.location.href;
@@ -18,20 +14,30 @@ The License Agreement constitutes a contract between you and Google with respect
if (document.getElementById('checkbox').checked) {
document.location = "http://dl.google.com/android/" + filename;
}
- document.getElementById('click_download').setAttribute("href", "http://dl.google.com/android/" + filename);
- document.getElementById('next_steps').style.display = "block";
+ document.getElementById('click-download').setAttribute("href", "http://dl.google.com/android/" + filename);
+ $("#terms-form").hide(500);
+ $("#next-steps").show(500);
+ document.getElementById('checkbox').disabled=true;
+ document.getElementById('download-button').disabled=true;
} else {
alert("You have not selected an SDK version. Please return to the Download page");
}
}
</script>
+<div id="terms-form">
+ <p>Please carefully review the Android SDK License Agreement before downloading the SDK.
+The License Agreement constitutes a contract between you and Google with respect to your use of the SDK.</p>
+
+ <iframe id="terms" style="border:1px solid #888;margin:0 0 1em;height:400px;width:95%;" src="terms_body.html">
+ </iframe>
+
<p>
<input type="checkbox" id="checkbox" onclick="verify()" />
<label for="checkbox">I agree to the terms of the Android SDK License Agreement.</label>
</p>
<p>
- <input type="submit" value="Download" id="download_button" disabled="disabled" onclick="submit()" />
+ <input type="submit" value="Download" id="download-button" disabled="disabled" onclick="submit()" />
</p>
<p>
<script language="javascript">
@@ -42,20 +48,24 @@ The License Agreement constitutes a contract between you and Google with respect
}
</script>
</p>
+</div><!-- end terms-form -->
<noscript>
<p><strong>Please enable Javascript in your browser in order to agree to the terms and download the SDK.</strong></p>
</noscript>
-<div class="special" id="next_steps" style="display:none">
- <p>Your download should be underway. If not, <a id="click_download">click here to download</a>.</p>
- <p>Continue your setup with one the following documents:</p>
- <ul style="margin-top:.5em">
- <li><a href="installing.html" class="addVersionPath">Installing</a> - If you are
- installing the Android SDK for the first time.</li>
- <li><a href="upgrading.html" class="addVersionPath">Upgrading</a> - If you are
- upgrading from a previously installed version of the Android SDK.</li>
- </ul>
+<div class="special" id="next-steps" style="display:none">
+ <h2>Thank you for downloading the Android SDK!</h2>
+ <p>Your download should be underway. If not, <a id="click-download">click here to start the download</a>.</p>
+ <p>If you are upgrading from a previously installed version of the Android SDK, see
+ <a href="upgrading.html" class="addVersionPath">Upgrading the SDK</a>.</p>
+ <p>If you are installing for the first time, read
+ <a href="installing.html" class="addVersionPath">Installing the Android SDK</a> to get your environment set up.
+ Once you have completed your installation, visit the <em>Dev Guide</em> tab and begin with the
+ <a href="/guide/tutorials/hello-world.html">Hello World</a> tutorial to create your first
+ Android application. From there, learn more about Android with the
+ <a href="/guide/topics/fundamentals.html">Application Fundamentals</a> documentation.</p>
+ <p>If you want to re-read the license agreement, it's available to you in the <em>SDK</em> tab.</p>
</div>
<script language="javascript">
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index f617302..688929f 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -1,8 +1,12 @@
<ul>
- <li><h2>Latest SDK Release</h2>
+ <li>
+ <?cs if:android.whichdoc != "online" ?><h2>Android 1.1 SDK, r1</h2>
+ <?cs else ?><h2>Latest SDK Release</h2><?cs /if ?>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/1.1_r1/index.html">Download</a></li>
+ <?cs if:android.whichdoc == "online" ?>
+ <li><a href="<?cs var:toroot ?>sdk/1.1_r1/index.html">Download</a></li>
+ <?cs /if ?>
<li><a href="<?cs var:toroot ?>sdk/1.1_r1/installing.html">Installing</a></li>
<li><a href="<?cs var:toroot ?>sdk/1.1_r1/upgrading.html">Upgrading</a></li>
<li><a href="<?cs var:toroot ?>sdk/1.1_r1/requirements.html">System Requirements</a></li>
@@ -15,6 +19,8 @@
</ul>
<ul>
<li><a href="<?cs var:toroot ?>sdk/terms.html">SDK Terms and Conditions</a></li>
- <li><a href="http://code.google.com/android/download_list.html">Previous SDK Releases</a></li>
+ <?cs if:android.whichdoc == "online" ?>
+ <li><a href="http://code.google.com/android/download_list.html">Previous SDK Releases</a></li>
+ <?cs /if ?>
</ul>
diff --git a/docs/html/sdk/terms.jd b/docs/html/sdk/terms.jd
index 72e5bd0..4638850 100644
--- a/docs/html/sdk/terms.jd
+++ b/docs/html/sdk/terms.jd
@@ -1,5 +1,5 @@
page.title=Terms and Conditions
-sdk.version=1.1_r1
+hide_license_footer=true
@jd:body
<p>This is the Android Software Development Kit License Agreement.</p>
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 7437f65..77c90ba 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -70,7 +70,16 @@ public:
ROUTE_BLUETOOTH_SCO = (1 << 2),
ROUTE_HEADSET = (1 << 3),
ROUTE_BLUETOOTH_A2DP = (1 << 4),
- ROUTE_ALL = 0xFFFFFFFF
+ ROUTE_ALL = -1UL,
+ };
+
+ enum audio_in_acoustics {
+ AGC_ENABLE = 0x0001,
+ AGC_DISABLE = 0,
+ NS_ENABLE = 0x0002,
+ NS_DISABLE = 0,
+ TX_IIR_ENABLE = 0x0004,
+ TX_DISABLE = 0
};
/* These are static methods to control the system-wide AudioFlinger
diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
index 3c18036..d1b7af3 100644
--- a/libs/audioflinger/A2dpAudioInterface.cpp
+++ b/libs/audioflinger/A2dpAudioInterface.cpp
@@ -72,7 +72,8 @@ AudioStreamOut* A2dpAudioInterface::openOutputStream(
}
AudioStreamIn* A2dpAudioInterface::openInputStream(
- int format, int channelCount, uint32_t sampleRate, status_t *status)
+ int format, int channelCount, uint32_t sampleRate, status_t *status,
+ AudioSystem::audio_in_acoustics acoustics)
{
if (status)
*status = -1;
diff --git a/libs/audioflinger/A2dpAudioInterface.h b/libs/audioflinger/A2dpAudioInterface.h
index 38ba684..5bef5da 100644
--- a/libs/audioflinger/A2dpAudioInterface.h
+++ b/libs/audioflinger/A2dpAudioInterface.h
@@ -58,7 +58,8 @@ public:
int format,
int channelCount,
uint32_t sampleRate,
- status_t *status);
+ status_t *status,
+ AudioSystem::audio_in_acoustics acoustics);
protected:
virtual status_t doRouting();
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
index 42204d6..9a94102 100644
--- a/libs/audioflinger/AudioDumpInterface.h
+++ b/libs/audioflinger/AudioDumpInterface.h
@@ -78,8 +78,9 @@ public:
virtual status_t setParameter(const char* key, const char* value)
{return mFinalInterface->setParameter(key, value);}
- virtual AudioStreamIn* openInputStream( int format, int channelCount, uint32_t sampleRate, status_t *status)
- {return mFinalInterface->openInputStream( format, channelCount, sampleRate, status);}
+ virtual AudioStreamIn* openInputStream( int format, int channelCount, uint32_t sampleRate, status_t *status,
+ AudioSystem::audio_in_acoustics acoustics)
+ {return mFinalInterface->openInputStream( format, channelCount, sampleRate, status, acoustics);}
virtual status_t dump(int fd, const Vector<String16>& args) { return mFinalInterface->dumpState(fd, args); }
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index d347f14..557d93b 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -278,6 +278,9 @@ status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
mA2dpMixerThread->dump(fd, args);
#endif
+ // dump record client
+ if (mAudioRecordThread != 0) mAudioRecordThread->dump(fd, args);
+
if (mAudioHardware) {
mAudioHardware->dumpState(fd, args);
}
@@ -1155,7 +1158,7 @@ bool AudioFlinger::MixerThread::threadLoop()
// active tracks were late. Sleep a little bit to give
// them another chance. If we're too late, the audio
// hardware will zero-fill for us.
-// LOGV("no buffers - usleep(%lu)", sleepTime);
+ //LOGV("no buffers - usleep(%lu)", sleepTime);
usleep(sleepTime);
if (sleepTime < kMaxBufferRecoveryInUsecs) {
sleepTime += kBufferRecoveryInUsecs;
@@ -1223,6 +1226,11 @@ sp<AudioFlinger::MixerThread::Track> AudioFlinger::MixerThread::createTrack(
track = new Track(this, client, streamType, sampleRate, format,
channelCount, frameCount, sharedBuffer);
+ if (track->getCblk() == NULL) {
+ track.clear();
+ lStatus = NO_MEMORY;
+ goto Exit;
+ }
mTracks.add(track);
lStatus = NO_ERROR;
}
@@ -1506,6 +1514,7 @@ AudioFlinger::MixerThread::TrackBase::TrackBase(
int format,
int channelCount,
int frameCount,
+ uint32_t flags,
const sp<IMemory>& sharedBuffer)
: RefBase(),
mMixerThread(mixerThread),
@@ -1515,7 +1524,7 @@ AudioFlinger::MixerThread::TrackBase::TrackBase(
mState(IDLE),
mClientTid(-1),
mFormat(format),
- mFlags(0)
+ mFlags(flags & ~SYSTEM_FLAGS_MASK)
{
mName = mixerThread->getTrackName();
LOGV("TrackBase contructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
@@ -1526,7 +1535,6 @@ AudioFlinger::MixerThread::TrackBase::TrackBase(
LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
-
// LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
size_t size = sizeof(audio_track_cblk_t);
size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
@@ -1614,7 +1622,7 @@ void AudioFlinger::MixerThread::TrackBase::reset() {
cblk->server = 0;
cblk->userBase = 0;
cblk->serverBase = 0;
- mFlags = 0;
+ mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
LOGV("TrackBase::reset");
}
@@ -1659,7 +1667,7 @@ AudioFlinger::MixerThread::Track::Track(
int channelCount,
int frameCount,
const sp<IMemory>& sharedBuffer)
- : TrackBase(mixerThread, client, streamType, sampleRate, format, channelCount, frameCount, sharedBuffer)
+ : TrackBase(mixerThread, client, streamType, sampleRate, format, channelCount, frameCount, 0, sharedBuffer)
{
mVolume[0] = 1.0f;
mVolume[1] = 1.0f;
@@ -1836,10 +1844,11 @@ AudioFlinger::MixerThread::RecordTrack::RecordTrack(
uint32_t sampleRate,
int format,
int channelCount,
- int frameCount)
+ int frameCount,
+ uint32_t flags)
: TrackBase(mixerThread, client, streamType, sampleRate, format,
- channelCount, frameCount, 0),
- mOverflow(false)
+ channelCount, frameCount, flags, 0),
+ mOverflow(false)
{
}
@@ -2232,7 +2241,12 @@ sp<IAudioRecord> AudioFlinger::openRecord(
// create new record track and pass to record thread
recordTrack = new MixerThread::RecordTrack(mHardwareMixerThread, client, streamType, sampleRate,
- format, channelCount, frameCount);
+ format, channelCount, frameCount, flags);
+ if (recordTrack->getCblk() == NULL) {
+ recordTrack.clear();
+ lStatus = NO_MEMORY;
+ goto Exit;
+ }
// return to handle to client
recordHandle = new RecordHandle(recordTrack);
@@ -2323,15 +2337,17 @@ bool AudioFlinger::AudioRecordThread::threadLoop()
input = 0;
}
mRecordTrack.clear();
+ mStopped.signal();
mWaitWorkCV.wait(mLock);
LOGV("AudioRecordThread: loop starting");
if (mRecordTrack != 0) {
input = mAudioHardware->openInputStream(mRecordTrack->format(),
- mRecordTrack->channelCount(),
- mRecordTrack->sampleRate(),
- &mStartStatus);
+ mRecordTrack->channelCount(),
+ mRecordTrack->sampleRate(),
+ &mStartStatus,
+ (AudioSystem::audio_in_acoustics)(mRecordTrack->mFlags >> 16));
if (input != 0) {
inBufferSize = input->bufferSize();
inFrameCount = inBufferSize/input->frameSize();
@@ -2347,12 +2363,13 @@ bool AudioFlinger::AudioRecordThread::threadLoop()
mWaitWorkCV.signal();
}
mLock.unlock();
- } else if (mRecordTrack != 0){
+ } else if (mRecordTrack != 0) {
buffer.frameCount = inFrameCount;
if (LIKELY(mRecordTrack->getNextBuffer(&buffer) == NO_ERROR)) {
LOGV("AudioRecordThread read: %d frames", buffer.frameCount);
- if (input->read(buffer.raw, inBufferSize) < 0) {
+ ssize_t bytesRead = input->read(buffer.raw, inBufferSize);
+ if (bytesRead < 0) {
LOGE("Error reading audio input");
sleep(1);
}
@@ -2407,6 +2424,7 @@ void AudioFlinger::AudioRecordThread::stop(MixerThread::RecordTrack* recordTrack
AutoMutex lock(&mLock);
if (mActive && (recordTrack == mRecordTrack.get())) {
mActive = false;
+ mStopped.wait(mLock);
}
}
@@ -2421,6 +2439,22 @@ void AudioFlinger::AudioRecordThread::exit()
requestExitAndWait();
}
+status_t AudioFlinger::AudioRecordThread::dump(int fd, const Vector<String16>& args)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+ pid_t pid = 0;
+
+ if (mRecordTrack != 0 && mRecordTrack->mClient != 0) {
+ snprintf(buffer, SIZE, "Record client pid: %d\n", mRecordTrack->mClient->pid());
+ result.append(buffer);
+ } else {
+ result.append("No record client\n");
+ }
+ write(fd, result.string(), result.size());
+ return NO_ERROR;
+}
status_t AudioFlinger::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 3b5932d..dfbb1e9 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -221,16 +221,22 @@ private:
};
enum track_flags {
- STEPSERVER_FAILED = 0x01 // StepServer could not acquire cblk->lock mutex
+ STEPSERVER_FAILED = 0x01, // StepServer could not acquire cblk->lock mutex
+ SYSTEM_FLAGS_MASK = 0x0000ffffUL,
+
+ AUDIO_IN_AGC_ENABLE = AudioSystem::AGC_ENABLE << 16,
+ AUDIO_IN_NS_ENABLE = AudioSystem::NS_ENABLE << 16,
+ AUDIO_IN_IIR_ENABLE = AudioSystem::TX_IIR_ENABLE << 16
};
- TrackBase( const sp<MixerThread>& mixerThread,
+ TrackBase(const sp<MixerThread>& mixerThread,
const sp<Client>& client,
int streamType,
uint32_t sampleRate,
int format,
int channelCount,
int frameCount,
+ uint32_t flags,
const sp<IMemory>& sharedBuffer);
~TrackBase();
@@ -295,7 +301,7 @@ private:
int mState;
int mClientTid;
uint8_t mFormat;
- uint8_t mFlags;
+ uint32_t mFlags;
};
// playback track
@@ -362,13 +368,14 @@ private:
// record track
class RecordTrack : public TrackBase {
public:
- RecordTrack( const sp<MixerThread>& mixerThread,
+ RecordTrack(const sp<MixerThread>& mixerThread,
const sp<Client>& client,
int streamType,
uint32_t sampleRate,
int format,
int channelCount,
- int frameCount);
+ int frameCount,
+ uint32_t flags);
~RecordTrack();
virtual status_t start();
@@ -585,6 +592,7 @@ private:
status_t start(MixerThread::RecordTrack* recordTrack);
void stop(MixerThread::RecordTrack* recordTrack);
void exit();
+ status_t dump(int fd, const Vector<String16>& args);
private:
AudioRecordThread();
@@ -592,6 +600,7 @@ private:
sp<MixerThread::RecordTrack> mRecordTrack;
Mutex mLock;
Condition mWaitWorkCV;
+ Condition mStopped;
volatile bool mActive;
status_t mStartStatus;
};
diff --git a/libs/audioflinger/AudioHardwareGeneric.cpp b/libs/audioflinger/AudioHardwareGeneric.cpp
index e455186..62beada 100644
--- a/libs/audioflinger/AudioHardwareGeneric.cpp
+++ b/libs/audioflinger/AudioHardwareGeneric.cpp
@@ -93,7 +93,8 @@ void AudioHardwareGeneric::closeOutputStream(AudioStreamOutGeneric* out) {
}
AudioStreamIn* AudioHardwareGeneric::openInputStream(
- int format, int channelCount, uint32_t sampleRate, status_t *status)
+ int format, int channelCount, uint32_t sampleRate, status_t *status,
+ AudioSystem::audio_in_acoustics acoustics)
{
AutoMutex lock(mLock);
@@ -107,7 +108,7 @@ AudioStreamIn* AudioHardwareGeneric::openInputStream(
// create new output stream
AudioStreamInGeneric* in = new AudioStreamInGeneric();
- status_t lStatus = in->set(this, mFd, format, channelCount, sampleRate);
+ status_t lStatus = in->set(this, mFd, format, channelCount, sampleRate, acoustics);
if (status) {
*status = lStatus;
}
@@ -246,7 +247,8 @@ status_t AudioStreamInGeneric::set(
int fd,
int format,
int channels,
- uint32_t rate)
+ uint32_t rate,
+ AudioSystem::audio_in_acoustics acoustics)
{
// FIXME: remove logging
LOGD("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, format, channels, rate);
diff --git a/libs/audioflinger/AudioHardwareGeneric.h b/libs/audioflinger/AudioHardwareGeneric.h
index a7822e1..1d58389 100644
--- a/libs/audioflinger/AudioHardwareGeneric.h
+++ b/libs/audioflinger/AudioHardwareGeneric.h
@@ -69,7 +69,8 @@ public:
int mFd,
int format,
int channelCount,
- uint32_t sampleRate);
+ uint32_t sampleRate,
+ AudioSystem::audio_in_acoustics acoustics);
uint32_t sampleRate() const { return 8000; }
virtual size_t bufferSize() const { return 320; }
@@ -114,7 +115,8 @@ public:
int format,
int channelCount,
uint32_t sampleRate,
- status_t *status);
+ status_t *status,
+ AudioSystem::audio_in_acoustics acoustics);
void closeOutputStream(AudioStreamOutGeneric* out);
void closeInputStream(AudioStreamInGeneric* in);
diff --git a/libs/audioflinger/AudioHardwareStub.cpp b/libs/audioflinger/AudioHardwareStub.cpp
index e9f3d69..b13cb1c 100644
--- a/libs/audioflinger/AudioHardwareStub.cpp
+++ b/libs/audioflinger/AudioHardwareStub.cpp
@@ -56,10 +56,11 @@ AudioStreamOut* AudioHardwareStub::openOutputStream(
}
AudioStreamIn* AudioHardwareStub::openInputStream(
- int format, int channelCount, uint32_t sampleRate, status_t *status)
+ int format, int channelCount, uint32_t sampleRate,
+ status_t *status, AudioSystem::audio_in_acoustics acoustics)
{
AudioStreamInStub* in = new AudioStreamInStub();
- status_t lStatus = in->set(format, channelCount, sampleRate);
+ status_t lStatus = in->set(format, channelCount, sampleRate, acoustics);
if (status) {
*status = lStatus;
}
@@ -142,7 +143,8 @@ status_t AudioStreamOutStub::dump(int fd, const Vector<String16>& args)
// ----------------------------------------------------------------------------
-status_t AudioStreamInStub::set(int format, int channels, uint32_t rate)
+status_t AudioStreamInStub::set(int format, int channels, uint32_t rate,
+ AudioSystem::audio_in_acoustics acoustics)
{
if ((format == AudioSystem::PCM_16_BIT) &&
(channels == channelCount()) &&
diff --git a/libs/audioflinger/AudioHardwareStub.h b/libs/audioflinger/AudioHardwareStub.h
index 24736ed..d406424 100644
--- a/libs/audioflinger/AudioHardwareStub.h
+++ b/libs/audioflinger/AudioHardwareStub.h
@@ -43,7 +43,7 @@ public:
class AudioStreamInStub : public AudioStreamIn {
public:
- virtual status_t set(int format, int channelCount, uint32_t sampleRate);
+ virtual status_t set(int format, int channelCount, uint32_t sampleRate, AudioSystem::audio_in_acoustics acoustics);
virtual uint32_t sampleRate() const { return 8000; }
virtual size_t bufferSize() const { return 320; }
virtual int channelCount() const { return 1; }
@@ -81,7 +81,8 @@ public:
int format,
int channelCount,
uint32_t sampleRate,
- status_t *status);
+ status_t *status,
+ AudioSystem::audio_in_acoustics acoustics);
protected:
virtual status_t doRouting() { return NO_ERROR; }
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index d381f6e..aacf857 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -19,6 +19,7 @@ package android.location;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.Printer;
import java.text.DecimalFormat;
import java.util.StringTokenizer;
@@ -81,6 +82,16 @@ public class Location implements Parcelable {
// Scratchpad
private float[] mResults = new float[2];
+ public void dump(Printer pw, String prefix) {
+ pw.println(prefix + "mProvider=" + mProvider + " mTime=" + mTime);
+ pw.println(prefix + "mLatitude=" + mLatitude + " mLongitude=" + mLongitude);
+ pw.println(prefix + "mHasAltitude=" + mHasAltitude + " mAltitude=" + mAltitude);
+ pw.println(prefix + "mHasSpeed=" + mHasSpeed + " mSpeed=" + mSpeed);
+ pw.println(prefix + "mHasBearing=" + mHasBearing + " mBearing=" + mBearing);
+ pw.println(prefix + "mHasAccuracy=" + mHasAccuracy + " mAccuracy=" + mAccuracy);
+ pw.println(prefix + "mExtras=" + mExtras);
+ }
+
/**
* Constructs a new Location. By default, time, latitude,
* longitude, and numSatellites are 0; hasAltitude, hasSpeed, and
diff --git a/media/java/android/media/AsyncPlayer.java b/media/java/android/media/AsyncPlayer.java
index 0620f32..35f0409 100644
--- a/media/java/android/media/AsyncPlayer.java
+++ b/media/java/android/media/AsyncPlayer.java
@@ -22,6 +22,7 @@ import android.os.PowerManager;
import android.util.Log;
import java.io.IOException;
+import java.lang.IllegalStateException;
/**
* Plays a series of audio URIs, but does all the hard work on another thread
@@ -71,20 +72,20 @@ public class AsyncPlayer {
// is playing, let it continue until we're done, so there
// is less of a glitch.
MediaPlayer player = new MediaPlayer();
- player.setDataSource(cmd.context, cmd.uri);
player.setAudioStreamType(cmd.stream);
+ player.setDataSource(cmd.context, cmd.uri);
player.setLooping(cmd.looping);
player.prepare();
+ player.start();
if (mPlayer != null) {
- // stop the previous one.
- mPlayer.stop();
mPlayer.release();
}
- player.start();
mPlayer = player;
}
catch (IOException e) {
Log.w(mTag, "error loading sound for " + cmd.uri, e);
+ } catch (IllegalStateException e) {
+ Log.w(mTag, "IllegalStateException (content provider died?) " + cmd.uri, e);
}
break;
case STOP:
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 4d2e725..077d016 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -932,29 +932,53 @@ public class AudioManager {
*/
public static final int FX_KEY_CLICK = 0;
/**
- * Focuse has moved up
+ * Focus has moved up
* @see #playSoundEffect(int)
*/
public static final int FX_FOCUS_NAVIGATION_UP = 1;
/**
- * Focuse has moved down
+ * Focus has moved down
* @see #playSoundEffect(int)
*/
public static final int FX_FOCUS_NAVIGATION_DOWN = 2;
/**
- * Focuse has moved left
+ * Focus has moved left
* @see #playSoundEffect(int)
*/
public static final int FX_FOCUS_NAVIGATION_LEFT = 3;
/**
- * Focuse has moved right
+ * Focus has moved right
* @see #playSoundEffect(int)
*/
public static final int FX_FOCUS_NAVIGATION_RIGHT = 4;
/**
+ * IME standard keypress sound
+ * @see #playSoundEffect(int)
+ * @hide FIXME: Unhide before release
+ */
+ public static final int FX_KEYPRESS_STANDARD = 5;
+ /**
+ * IME spacebar keypress sound
+ * @see #playSoundEffect(int)
+ * @hide FIXME: Unhide before release
+ */
+ public static final int FX_KEYPRESS_SPACEBAR = 6;
+ /**
+ * IME delete keypress sound
+ * @see #playSoundEffect(int)
+ * @hide FIXME: Unhide before release
+ */
+ public static final int FX_KEYPRESS_DELETE = 7;
+ /**
+ * IME return_keypress sound
+ * @see #playSoundEffect(int)
+ * @hide FIXME: Unhide before release
+ */
+ public static final int FX_KEYPRESS_RETURN = 8;
+ /**
* @hide Number of sound effects
*/
- public static final int NUM_SOUND_EFFECTS = 5;
+ public static final int NUM_SOUND_EFFECTS = 9;
/**
* Plays a sound effect (Key clicks, lid open/close...)
@@ -964,6 +988,13 @@ public class AudioManager {
* {@link #FX_FOCUS_NAVIGATION_DOWN},
* {@link #FX_FOCUS_NAVIGATION_LEFT},
* {@link #FX_FOCUS_NAVIGATION_RIGHT},
+ * FIXME: include links before release
+ * {link #FX_KEYPRESS_STANDARD},
+ * {link #FX_KEYPRESS_SPACEBAR},
+ * {link #FX_KEYPRESS_DELETE},
+ * {link #FX_KEYPRESS_RETURN},
+ * NOTE: This version uses the UI settings to determine
+ * whether sounds are heard or not.
*/
public void playSoundEffect(int effectType) {
if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) {
@@ -983,6 +1014,37 @@ public class AudioManager {
}
/**
+ * Plays a sound effect (Key clicks, lid open/close...)
+ * @param effectType The type of sound effect. One of
+ * {@link #FX_KEY_CLICK},
+ * {@link #FX_FOCUS_NAVIGATION_UP},
+ * {@link #FX_FOCUS_NAVIGATION_DOWN},
+ * {@link #FX_FOCUS_NAVIGATION_LEFT},
+ * {@link #FX_FOCUS_NAVIGATION_RIGHT},
+ * FIXME: include links before release
+ * {link #FX_KEYPRESS_STANDARD},
+ * {link #FX_KEYPRESS_SPACEBAR},
+ * {link #FX_KEYPRESS_DELETE},
+ * {link #FX_KEYPRESS_RETURN},
+ * @param volume Sound effect volume
+ * NOTE: This version is for applications that have their own
+ * settings panel for enabling and controlling volume.
+ * @hide FIXME: Unhide before release
+ */
+ public void playSoundEffect(int effectType, float volume) {
+ if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) {
+ return;
+ }
+
+ IAudioService service = getService();
+ try {
+ service.playSoundEffectVolume(effectType, volume);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Dead object in playSoundEffect"+e);
+ }
+ }
+
+ /**
* Settings has an in memory cache, so this is fast.
*/
private boolean querySoundEffectsEnabled() {
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index bdabda7..83ede0d 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -102,12 +102,16 @@ public class AudioService extends IAudioService.Stub {
private SoundPool mSoundPool;
private Object mSoundEffectsLock = new Object();
private static final int NUM_SOUNDPOOL_CHANNELS = 4;
- private static final float SOUND_EFFECT_VOLUME = 1.0f;
+ private static final int SOUND_EFFECT_VOLUME = 1000;
/* Sound effect file names */
private static final String SOUND_EFFECTS_PATH = "/media/audio/ui/";
private static final String[] SOUND_EFFECT_FILES = new String[] {
- "Effect_Tick.ogg"
+ "Effect_Tick.ogg",
+ "KeypressStandard.ogg",
+ "KeypressSpacebar.ogg",
+ "KeypressDelete.ogg",
+ "KeypressReturn.ogg"
};
/* Sound effect file name mapping sound effect id (AudioManager.FX_xxx) to
@@ -118,7 +122,11 @@ public class AudioService extends IAudioService.Stub {
{0, -1}, // FX_FOCUS_NAVIGATION_UP
{0, -1}, // FX_FOCUS_NAVIGATION_DOWN
{0, -1}, // FX_FOCUS_NAVIGATION_LEFT
- {0, -1} // FX_FOCUS_NAVIGATION_RIGHT
+ {0, -1}, // FX_FOCUS_NAVIGATION_RIGHT
+ {1, -1}, // FX_KEYPRESS_STANDARD
+ {2, -1}, // FX_KEYPRESS_SPACEBAR
+ {3, -1}, // FX_FOCUS_DELETE
+ {4, -1} // FX_FOCUS_RETURN
};
private AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
@@ -180,9 +188,7 @@ public class AudioService extends IAudioService.Stub {
readAudioSettings();
mMediaServerOk = true;
AudioSystem.setErrorCallback(mAudioSystemCallback);
- if (Settings.System.getInt(mContentResolver, Settings.System.SOUND_EFFECTS_ENABLED, 0) == 1) {
- loadSoundEffects();
- }
+ loadSoundEffects();
}
private void createAudioSystemThread() {
@@ -648,8 +654,15 @@ public class AudioService extends IAudioService.Stub {
/** @see AudioManager#playSoundEffect(int) */
public void playSoundEffect(int effectType) {
- sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SHARED_MSG, SENDMSG_NOOP, effectType, 0,
- null, 0);
+ sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SHARED_MSG, SENDMSG_NOOP,
+ effectType, SOUND_EFFECT_VOLUME, null, 0);
+ }
+
+ /** @see AudioManager#playSoundEffect(int, float) */
+ /* @hide FIXME: unhide before release */
+ public void playSoundEffectVolume(int effectType, float volume) {
+ sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SHARED_MSG, SENDMSG_NOOP,
+ effectType, (int) (volume * 1000), null, 0);
}
/**
@@ -1113,15 +1126,15 @@ public class AudioService extends IAudioService.Stub {
System.putInt(mContentResolver, System.VIBRATE_ON, mVibrateSetting);
}
- private void playSoundEffect(int effectType) {
+ private void playSoundEffect(int effectType, int volume) {
synchronized (mSoundEffectsLock) {
if (mSoundPool == null) {
return;
}
if (SOUND_EFFECT_FILES_MAP[effectType][1] > 0) {
- mSoundPool.play(SOUND_EFFECT_FILES_MAP[effectType][1], SOUND_EFFECT_VOLUME, SOUND_EFFECT_VOLUME,
- 0, 0, 1.0f);
+ float v = (float) volume / 1000.0f;
+ mSoundPool.play(SOUND_EFFECT_FILES_MAP[effectType][1], v, v, 0, 0, 1.0f);
} else {
MediaPlayer mediaPlayer = new MediaPlayer();
if (mediaPlayer != null) {
@@ -1214,7 +1227,7 @@ public class AudioService extends IAudioService.Stub {
break;
case MSG_PLAY_SOUND_EFFECT:
- playSoundEffect(msg.arg1);
+ playSoundEffect(msg.arg1, msg.arg2);
break;
}
}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 74ffc1a..e32835c 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -538,9 +538,10 @@ public class AudioTrack
* @param audioFormat the format in which the audio data is represented.
* See {@link AudioFormat#ENCODING_PCM_16BIT} and
* {@link AudioFormat#ENCODING_PCM_8BIT}
- * @return -1 if an invalid parameter was passed or if the implementation was unable to
- * query the hardware for its output properties, or the minimum buffer size expressed
- * in number of bytes.
+ * @return {@link #ERROR_BAD_VALUE} if an invalid parameter was passed,
+ * or {@link #ERROR} if the implementation was unable to query the hardware for its output
+ * properties,
+ * or the minimum buffer size expressed in number of bytes.
*/
static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {
int channelCount = 0;
@@ -553,16 +554,28 @@ public class AudioTrack
break;
default:
loge("getMinBufferSize(): Invalid channel configuration.");
- return -1;
+ return AudioTrack.ERROR_BAD_VALUE;
}
if ((audioFormat != AudioFormat.ENCODING_PCM_16BIT)
&& (audioFormat != AudioFormat.ENCODING_PCM_8BIT)) {
loge("getMinBufferSize(): Invalid audio format.");
- return -1;
+ return AudioTrack.ERROR_BAD_VALUE;
}
- return native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);
+ if ( (sampleRateInHz < 4000) || (sampleRateInHz > 48000) ) {
+ loge("getMinBufferSize(): " + sampleRateInHz +"Hz is not a supported sample rate.");
+ return AudioTrack.ERROR_BAD_VALUE;
+ }
+
+ int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);
+ if ((size == -1) || (size == 0)) {
+ loge("getMinBufferSize(): error querying hardware");
+ return AudioTrack.ERROR;
+ }
+ else {
+ return size;
+ }
}
@@ -810,7 +823,7 @@ public class AudioTrack
return -1;
}
- return native_write_byte(audioData, offsetInBytes, sizeInBytes);
+ return native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat);
}
@@ -836,7 +849,7 @@ public class AudioTrack
return -1;
}
- return native_write_short(audioData, offsetInShorts, sizeInShorts);
+ return native_write_short(audioData, offsetInShorts, sizeInShorts, mAudioFormat);
}
@@ -969,10 +982,10 @@ public class AudioTrack
private native final void native_flush();
private native final int native_write_byte(byte[] audioData,
- int offsetInBytes, int sizeInBytes);
+ int offsetInBytes, int sizeInBytes, int format);
private native final int native_write_short(short[] audioData,
- int offsetInShorts, int sizeInShorts);
+ int offsetInShorts, int sizeInShorts, int format);
private native final int native_reload_static();
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 3e33d98..f5e242d 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -65,6 +65,8 @@ interface IAudioService {
oneway void playSoundEffect(int effectType);
+ oneway void playSoundEffectVolume(int effectType, float volume);
+
boolean loadSoundEffects();
oneway void unloadSoundEffects();
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 1ffad46..f8520a7 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -156,7 +156,7 @@ status_t AudioTrack::set(
}
// validate parameters
- if (((format != AudioSystem::PCM_8_BIT) || mSharedBuffer != 0) &&
+ if (((format != AudioSystem::PCM_8_BIT) || sharedBuffer != 0) &&
(format != AudioSystem::PCM_16_BIT)) {
LOGE("Invalid format");
return BAD_VALUE;
diff --git a/media/libmedia/JetPlayer.cpp b/media/libmedia/JetPlayer.cpp
index 9bd75c2..2c62104 100644
--- a/media/libmedia/JetPlayer.cpp
+++ b/media/libmedia/JetPlayer.cpp
@@ -86,8 +86,8 @@ int JetPlayer::init()
mState = EAS_STATE_ERROR;
return result;
}
- // init the JET library
- result = JET_Init(mEasData, NULL, 0);
+ // init the JET library with the default app event controller range
+ result = JET_Init(mEasData, NULL, sizeof(S_JET_CONFIG));
if( result != EAS_SUCCESS) {
LOGE("JetPlayer::init(): Error initializing JET library, aborting.");
mState = EAS_STATE_ERROR;
@@ -200,6 +200,11 @@ int JetPlayer::render() {
while (!mRender)
{
LOGV("JetPlayer::render(): signal wait");
+ if (audioStarted) {
+ mAudioTrack->pause();
+ // we have to restart the playback once we start rendering again
+ audioStarted = false;
+ }
mCondition.wait(mMutex);
LOGV("JetPlayer::render(): signal rx'd");
}
@@ -315,7 +320,7 @@ void JetPlayer::fireEventsFromJetQueue()
while (JET_GetEvent(mEasData, NULL, NULL)) { }
return;
}
-
+
EAS_U32 rawEvent;
while (JET_GetEvent(mEasData, &rawEvent, NULL)) {
mEventCallback(
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
index 1731940..453a165 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
@@ -47,7 +47,7 @@ public class MediaFrameworkTestRunner extends InstrumentationTestRunner {
suite.addTestSuite(MediaPlayerApiTest.class);
suite.addTestSuite(SimTonesTest.class);
suite.addTestSuite(MediaMetadataTest.class);
- suite.addTestSuite(CameraTest.class);
+ // suite.addTestSuite(CameraTest.class);
suite.addTestSuite(MediaRecorderTest.class);
suite.addTestSuite(MediaAudioTrackTest.class);
return suite;
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 3f33b67..e35773e 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -530,13 +530,7 @@ EGLDisplay eglGetDisplay(NativeDisplayType display)
property_get("debug.egl.hw", value, "1");
if (atoi(value) != 0) {
cnx->hooks = &gHooks[IMPL_HARDWARE];
- property_get("debug.egl.profiler", value, "0");
- if (atoi(value) == 0) {
- cnx->dso = load_driver("libhgl.so", cnx->hooks);
- } else {
- LOGW("Using instrumented h/w OpenGL ES library");
- cnx->dso = load_driver("libhgld.so", cnx->hooks);
- }
+ cnx->dso = load_driver("libhgl.so", cnx->hooks);
} else {
LOGD("3D hardware acceleration is disabled");
}
diff --git a/preloaded-classes b/preloaded-classes
index 61390db..a90579f 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -499,8 +499,6 @@ com.android.internal.logging.AndroidConfig
com.android.internal.logging.AndroidHandler
com.android.internal.os.AndroidPrintStream
com.android.internal.os.BinderInternal$GcWatcher
-com.android.internal.os.HandlerHelper
-com.android.internal.os.HandlerThread
com.android.internal.os.LoggingPrintStream
com.android.internal.os.LoggingPrintStream$1
com.android.internal.os.RuntimeInit
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index e4fdd0c..9c9a580 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -121,9 +121,10 @@ class BatteryService extends Binder {
}
int plugTypeBit = 0;
if (mAcOnline) {
- plugTypeBit = BatteryManager.BATTERY_PLUGGED_AC;
- } else if (mUsbOnline) {
- plugTypeBit = BatteryManager.BATTERY_PLUGGED_USB;
+ plugTypeBit |= BatteryManager.BATTERY_PLUGGED_AC;
+ }
+ if (mUsbOnline) {
+ plugTypeBit |= BatteryManager.BATTERY_PLUGGED_USB;
}
return (plugTypeSet & plugTypeBit) != 0;
}
diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/java/com/android/server/DeviceStorageMonitorService.java
index 44f70f0..85861bb 100644
--- a/services/java/com/android/server/DeviceStorageMonitorService.java
+++ b/services/java/com/android/server/DeviceStorageMonitorService.java
@@ -67,6 +67,7 @@ class DeviceStorageMonitorService extends Binder {
private static final int EVENT_LOG_LOW_STORAGE_NOTIFICATION = 2745;
private static final int EVENT_LOG_FREE_STORAGE_LEFT = 2746;
private static final long DEFAULT_DISK_FREE_CHANGE_REPORTING_THRESHOLD = 2 * 1024 * 1024; // 2MB
+ private static final long DEFAULT_CHECK_INTERVAL = MONITOR_INTERVAL*60*1000;
private long mFreeMem;
private long mLastReportedFreeMem;
private long mLastReportedFreeMemTime;
@@ -82,6 +83,9 @@ class DeviceStorageMonitorService extends Binder {
boolean mClearingCache;
private Intent mStorageLowIntent;
private Intent mStorageOkIntent;
+ private CachePackageDataObserver mClearCacheObserver;
+ private static final int _TRUE = 1;
+ private static final int _FALSE = 0;
/**
* This string is used for ServiceManager access to this class.
@@ -100,7 +104,7 @@ class DeviceStorageMonitorService extends Binder {
Log.e(TAG, "Will not process invalid message");
return;
}
- checkMemory();
+ checkMemory(msg.arg1 == _TRUE);
}
};
@@ -109,7 +113,8 @@ class DeviceStorageMonitorService extends Binder {
mClearSucceeded = succeeded;
mClearingCache = false;
if(localLOGV) Log.i(TAG, " Clear succeeded:"+mClearSucceeded
- +", mClearingCache:"+mClearingCache);
+ +", mClearingCache:"+mClearingCache+" Forcing memory check");
+ postCheckMemoryMsg(false, 0);
}
}
@@ -145,11 +150,15 @@ class DeviceStorageMonitorService extends Binder {
}
private final void clearCache() {
- CachePackageDataObserver observer = new CachePackageDataObserver();
+ if (mClearCacheObserver == null) {
+ // Lazy instantiation
+ mClearCacheObserver = new CachePackageDataObserver();
+ }
mClearingCache = true;
try {
+ if (localLOGV) Log.i(TAG, "Clearing cache");
IPackageManager.Stub.asInterface(ServiceManager.getService("package")).
- freeStorageAndNotify(getMemThreshold(), observer);
+ freeStorageAndNotify(getMemThreshold(), mClearCacheObserver);
} catch (RemoteException e) {
Log.w(TAG, "Failed to get handle for PackageManger Exception: "+e);
mClearingCache = false;
@@ -157,7 +166,7 @@ class DeviceStorageMonitorService extends Binder {
}
}
- private final void checkMemory() {
+ private final void checkMemory(boolean checkCache) {
//if the thread that was started to clear cache is still running do nothing till its
//finished clearing cache. Ideally this flag could be modified by clearCache
// and should be accessed via a lock but even if it does this test will fail now and
@@ -172,16 +181,23 @@ class DeviceStorageMonitorService extends Binder {
} else {
restatDataDir();
if (localLOGV) Log.v(TAG, "freeMemory="+mFreeMem);
+
//post intent to NotificationManager to display icon if necessary
long memThreshold = getMemThreshold();
if (mFreeMem < memThreshold) {
if (!mLowMemFlag) {
- //see if clearing cache helps
- mThreadStartTime = System.currentTimeMillis();
- clearCache();
- Log.i(TAG, "Running low on memory. Sending notification");
- sendNotification();
- mLowMemFlag = true;
+ if (checkCache) {
+ // See if clearing cache helps
+ // Note that clearing cache is asynchronous and so we do a
+ // memory check again once the cache has been cleared.
+ mThreadStartTime = System.currentTimeMillis();
+ mClearSucceeded = false;
+ clearCache();
+ } else {
+ Log.i(TAG, "Running low on memory. Sending notification");
+ sendNotification();
+ mLowMemFlag = true;
+ }
} else {
if (localLOGV) Log.v(TAG, "Running low on memory " +
"notification already sent. do nothing");
@@ -196,8 +212,15 @@ class DeviceStorageMonitorService extends Binder {
}
if(localLOGV) Log.i(TAG, "Posting Message again");
//keep posting messages to itself periodically
- mHandler.sendMessageDelayed(mHandler.obtainMessage(DEVICE_MEMORY_WHAT),
- MONITOR_INTERVAL*60*1000);
+ postCheckMemoryMsg(true, DEFAULT_CHECK_INTERVAL);
+ }
+
+ private void postCheckMemoryMsg(boolean clearCache, long delay) {
+ // Remove queued messages
+ mHandler.removeMessages(DEVICE_MEMORY_WHAT);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(DEVICE_MEMORY_WHAT,
+ clearCache ?_TRUE : _FALSE, 0),
+ delay);
}
/*
@@ -231,7 +254,7 @@ class DeviceStorageMonitorService extends Binder {
mTotalMemory = (mFileStats.getBlockCount()*mBlkSize)/100;
mStorageLowIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_LOW);
mStorageOkIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK);
- checkMemory();
+ checkMemory(true);
}
@@ -281,14 +304,11 @@ class DeviceStorageMonitorService extends Binder {
}
public void updateMemory() {
- ActivityManagerService ams = (ActivityManagerService)ServiceManager.getService("activity");
int callingUid = getCallingUid();
if(callingUid != Process.SYSTEM_UID) {
return;
}
- //remove queued messages
- mHandler.removeMessages(DEVICE_MEMORY_WHAT);
- //force an early check
- checkMemory();
+ // force an early check
+ postCheckMemoryMsg(true, 0);
}
}
diff --git a/services/java/com/android/server/GadgetService.java b/services/java/com/android/server/GadgetService.java
index ddf3afe..4a430e0 100644
--- a/services/java/com/android/server/GadgetService.java
+++ b/services/java/com/android/server/GadgetService.java
@@ -38,7 +38,6 @@ import android.os.Bundle;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.AttributeSet;
-import android.util.Config;
import android.util.Log;
import android.util.Xml;
import android.widget.RemoteViews;
@@ -66,7 +65,6 @@ import org.xmlpull.v1.XmlSerializer;
class GadgetService extends IGadgetService.Stub
{
private static final String TAG = "GadgetService";
- private static final boolean LOGD = Config.LOGD || false;
private static final String SETTINGS_FILENAME = "gadgets.xml";
private static final String SETTINGS_TMP_FILENAME = SETTINGS_FILENAME + ".tmp";
@@ -82,6 +80,7 @@ class GadgetService extends IGadgetService.Stub
GadgetProviderInfo info;
ArrayList<GadgetId> instances = new ArrayList();
PendingIntent broadcast;
+ boolean zombie; // if we're in safe mode, don't prune this just because nobody references it
int tag; // for use while saving state (the index)
}
@@ -92,6 +91,7 @@ class GadgetService extends IGadgetService.Stub
String packageName;
ArrayList<GadgetId> instances = new ArrayList();
IGadgetHost callbacks;
+ boolean zombie; // if we're in safe mode, don't prune this just because nobody references it
int tag; // for use while saving state (the index)
}
@@ -110,13 +110,18 @@ class GadgetService extends IGadgetService.Stub
int mNextGadgetId = GadgetManager.INVALID_GADGET_ID + 1;
ArrayList<GadgetId> mGadgetIds = new ArrayList();
ArrayList<Host> mHosts = new ArrayList();
+ boolean mSafeMode;
GadgetService(Context context) {
mContext = context;
mPackageManager = context.getPackageManager();
mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
-
- getGadgetList();
+ }
+
+ public void systemReady(boolean safeMode) {
+ mSafeMode = safeMode;
+
+ loadGadgetList();
loadStateLocked();
// Register for the boot completed broadcast, so we can send the
@@ -148,11 +153,12 @@ class GadgetService extends IGadgetService.Stub
int N = mInstalledProviders.size();
pw.println("Providers: (size=" + N + ")");
for (int i=0; i<N; i++) {
- GadgetProviderInfo info = mInstalledProviders.get(i).info;
+ Provider p = mInstalledProviders.get(i);
+ GadgetProviderInfo info = p.info;
pw.println(" [" + i + "] provder=" + info.provider
+ " min=(" + info.minWidth + "x" + info.minHeight + ")"
+ " updatePeriodMillis=" + info.updatePeriodMillis
- + " initialLayout=" + info.initialLayout);
+ + " initialLayout=" + info.initialLayout + " zombie=" + p.zombie);
}
N = mGadgetIds.size();
@@ -172,7 +178,7 @@ class GadgetService extends IGadgetService.Stub
Host host = mHosts.get(i);
pw.println(" [" + i + "] packageName=" + host.packageName + " uid=" + host.uid
+ " hostId=" + host.hostId + " callbacks=" + host.callbacks
- + " instances.size=" + host.instances.size());
+ + " instances.size=" + host.instances.size() + " zombie=" + host.zombie);
}
}
}
@@ -199,16 +205,10 @@ class GadgetService extends IGadgetService.Stub
public void deleteGadgetId(int gadgetId) {
synchronized (mGadgetIds) {
- int callingUid = getCallingUid();
- final int N = mGadgetIds.size();
- for (int i=0; i<N; i++) {
- GadgetId id = mGadgetIds.get(i);
- if (id.provider != null && canAccessGadgetId(id, callingUid)) {
- deleteGadgetLocked(id);
-
- saveStateLocked();
- return;
- }
+ GadgetId id = lookupGadgetIdLocked(gadgetId);
+ if (id != null) {
+ deleteGadgetLocked(id);
+ saveStateLocked();
}
}
}
@@ -264,19 +264,21 @@ class GadgetService extends IGadgetService.Stub
Provider p = id.provider;
if (p != null) {
p.instances.remove(id);
- // send the broacast saying that this gadgetId has been deleted
- Intent intent = new Intent(GadgetManager.ACTION_GADGET_DELETED);
- intent.setComponent(p.info.provider);
- intent.putExtra(GadgetManager.EXTRA_GADGET_ID, id.gadgetId);
- mContext.sendBroadcast(intent);
- if (p.instances.size() == 0) {
- // cancel the future updates
- cancelBroadcasts(p);
-
- // send the broacast saying that the provider is not in use any more
- intent = new Intent(GadgetManager.ACTION_GADGET_DISABLED);
+ if (!p.zombie) {
+ // send the broacast saying that this gadgetId has been deleted
+ Intent intent = new Intent(GadgetManager.ACTION_GADGET_DELETED);
intent.setComponent(p.info.provider);
+ intent.putExtra(GadgetManager.EXTRA_GADGET_ID, id.gadgetId);
mContext.sendBroadcast(intent);
+ if (p.instances.size() == 0) {
+ // cancel the future updates
+ cancelBroadcasts(p);
+
+ // send the broacast saying that the provider is not in use any more
+ intent = new Intent(GadgetManager.ACTION_GADGET_DISABLED);
+ intent.setComponent(p.info.provider);
+ mContext.sendBroadcast(intent);
+ }
}
}
}
@@ -310,6 +312,10 @@ class GadgetService extends IGadgetService.Stub
if (p == null) {
throw new IllegalArgumentException("not a gadget provider: " + provider);
}
+ if (p.zombie) {
+ throw new IllegalArgumentException("can't bind to a 3rd party provider in"
+ + " safe mode: " + provider);
+ }
id.provider = p;
p.instances.add(id);
@@ -334,7 +340,7 @@ class GadgetService extends IGadgetService.Stub
public GadgetProviderInfo getGadgetInfo(int gadgetId) {
synchronized (mGadgetIds) {
GadgetId id = lookupGadgetIdLocked(gadgetId);
- if (id != null) {
+ if (id != null && id.provider != null && !id.provider.zombie) {
return id.provider.info;
}
return null;
@@ -356,7 +362,10 @@ class GadgetService extends IGadgetService.Stub
final int N = mInstalledProviders.size();
ArrayList<GadgetProviderInfo> result = new ArrayList(N);
for (int i=0; i<N; i++) {
- result.add(mInstalledProviders.get(i).info);
+ Provider p = mInstalledProviders.get(i);
+ if (!p.zombie) {
+ result.add(p.info);
+ }
}
return result;
}
@@ -399,7 +408,7 @@ class GadgetService extends IGadgetService.Stub
// allow for stale gadgetIds and other badness
// lookup also checks that the calling process can access the gadget id
// drop unbound gadget ids (shouldn't be possible under normal circumstances)
- if (id != null && id.provider != null) {
+ if (id != null && id.provider != null && !id.provider.zombie && !id.host.zombie) {
id.views = views;
// is anyone listening?
@@ -460,9 +469,7 @@ class GadgetService extends IGadgetService.Stub
return true;
}
// Nobody else can access it.
- // TODO: convert callingPackage over to use UID-based checking instead
- // TODO: our temp solution is to short-circuit this security check
- return true;
+ return false;
}
GadgetId lookupGadgetIdLocked(int gadgetId) {
@@ -521,7 +528,7 @@ class GadgetService extends IGadgetService.Stub
}
}
- void getGadgetList() {
+ void loadGadgetList() {
PackageManager pm = mPackageManager;
Intent intent = new Intent(GadgetManager.ACTION_GADGET_UPDATE);
@@ -854,8 +861,16 @@ class GadgetService extends IGadgetService.Stub
String pkg = parser.getAttributeValue(null, "pkg");
String cl = parser.getAttributeValue(null, "cl");
Provider p = lookupProviderLocked(new ComponentName(pkg, cl));
- // if it wasn't uninstalled or something
+ if (p == null && mSafeMode) {
+ // if we're in safe mode, make a temporary one
+ p = new Provider();
+ p.info = new GadgetProviderInfo();
+ p.info.provider = new ComponentName(pkg, cl);
+ p.zombie = true;
+ mInstalledProviders.add(p);
+ }
if (p != null) {
+ // if it wasn't uninstalled or something
loadedProviders.put(providerIndex, p);
}
providerIndex++;
@@ -868,13 +883,15 @@ class GadgetService extends IGadgetService.Stub
host.packageName = parser.getAttributeValue(null, "pkg");
try {
host.uid = getUidForPackage(host.packageName);
+ } catch (PackageManager.NameNotFoundException ex) {
+ host.zombie = true;
+ }
+ if (!host.zombie || mSafeMode) {
+ // In safe mode, we don't discard the hosts we don't recognize
+ // so that they're not pruned from our list. Otherwise, we do.
host.hostId = Integer.parseInt(
parser.getAttributeValue(null, "id"), 16);
mHosts.add(host);
- } catch (PackageManager.NameNotFoundException ex) {
- // Just ignore drop this entry, as if it has been uninstalled.
- // We need to deal with this case because of safe mode, but there's
- // a bug filed about it.
}
}
else if ("g".equals(tag)) {
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 7588129..4b45828 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1062,6 +1062,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// Do nothing.
break;
case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
+ if ((softInputMode &
+ WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
+ if (DEBUG) Log.v(TAG, "Window asks to hide input going forward");
+ hideCurrentInputLocked(0);
+ }
+ break;
+ case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
if (DEBUG) Log.v(TAG, "Window asks to hide input");
hideCurrentInputLocked(0);
break;
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index db4daa5..bc8da93 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -18,14 +18,16 @@ package com.android.server;
import java.io.BufferedReader;
import java.io.File;
+import java.io.FileDescriptor;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Locale;
+import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
@@ -46,6 +48,7 @@ import android.location.LocationManager;
import android.location.LocationProvider;
import android.location.LocationProviderImpl;
import android.net.ConnectivityManager;
+import android.net.Uri;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Binder;
@@ -57,12 +60,13 @@ import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
import android.telephony.CellLocation;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Config;
import android.util.Log;
+import android.util.PrintWriterPrinter;
+import android.util.SparseIntArray;
import com.android.internal.app.IBatteryStats;
import com.android.internal.location.CellState;
@@ -124,6 +128,7 @@ public class LocationManagerService extends ILocationManager.Stub
private final Context mContext;
private GpsLocationProvider mGpsLocationProvider;
+ private boolean mGpsNavigating;
private LocationProviderImpl mNetworkLocationProvider;
private INetworkLocationProvider mNetworkLocationInterface;
private LocationWorkerHandler mLocationHandler;
@@ -151,35 +156,38 @@ public class LocationManagerService extends ILocationManager.Stub
private final IBatteryStats mBatteryStats;
- // The calling UID when we are in a clearCallingIdentity/restoreCallingIdentity block, or -1
- private int mCallingUid = -1;
-
/**
* Mapping from listener IBinder/PendingIntent to local Listener wrappers.
*/
- private final HashMap<Object,Receiver> mListeners =
- new HashMap<Object,Receiver>();
+ private final ArrayList<Receiver> mListeners = new ArrayList<Receiver>();
/**
+ * Used for reporting which UIDs are causing the GPS to run.
+ */
+ private final SparseIntArray mReportedGpsUids = new SparseIntArray();
+ private int mReportedGpsSeq = 0;
+
+ /**
* Mapping from listener IBinder/PendingIntent to a map from provider name to UpdateRecord.
+ * This also serves as the lock for our state.
*/
- private final HashMap<Object,HashMap<String,UpdateRecord>> mLocationListeners =
- new HashMap<Object,HashMap<String,UpdateRecord>>();
+ private final HashMap<Receiver,HashMap<String,UpdateRecord>> mLocationListeners =
+ new HashMap<Receiver,HashMap<String,UpdateRecord>>();
/**
* Mapping from listener IBinder/PendingIntent to a map from provider name to last broadcast
* location.
*/
- private final HashMap<Object,HashMap<String,Location>> mLastFixBroadcast =
- new HashMap<Object,HashMap<String,Location>>();
- private final HashMap<Object,HashMap<String,Long>> mLastStatusBroadcast =
- new HashMap<Object,HashMap<String,Long>>();
+ private final HashMap<Receiver,HashMap<String,Location>> mLastFixBroadcast =
+ new HashMap<Receiver,HashMap<String,Location>>();
+ private final HashMap<Receiver,HashMap<String,Long>> mLastStatusBroadcast =
+ new HashMap<Receiver,HashMap<String,Long>>();
/**
* Mapping from provider name to all its UpdateRecords
*/
- private final HashMap<String,HashSet<UpdateRecord>> mRecordsByProvider =
- new HashMap<String,HashSet<UpdateRecord>>();
+ private final HashMap<String,ArrayList<UpdateRecord>> mRecordsByProvider =
+ new HashMap<String,ArrayList<UpdateRecord>>();
/**
* Mappings from provider name to object to use for current location. Locations
@@ -221,22 +229,48 @@ public class LocationManagerService extends ILocationManager.Stub
private final class Receiver implements IBinder.DeathRecipient {
final ILocationListener mListener;
final PendingIntent mPendingIntent;
+ final int mUid;
+ final Object mKey;
- Receiver(ILocationListener listener) {
+ Receiver(ILocationListener listener, int uid) {
mListener = listener;
mPendingIntent = null;
+ mUid = uid;
+ mKey = listener.asBinder();
}
- Receiver(PendingIntent intent) {
+ Receiver(PendingIntent intent, int uid) {
mPendingIntent = intent;
mListener = null;
+ mUid = uid;
+ mKey = intent;
}
- public Object getKey() {
+ @Override
+ public boolean equals(Object otherObj) {
+ if (otherObj instanceof Receiver) {
+ return mKey.equals(
+ ((Receiver)otherObj).mKey);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return mKey.hashCode();
+ }
+
+
+ @Override
+ public String toString() {
if (mListener != null) {
- return mListener.asBinder();
+ return "Receiver{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " uid " + mUid + " Listener " + mKey + "}";
} else {
- return mPendingIntent;
+ return "Receiver{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " uid " + mUid + " Intent " + mKey + "}";
}
}
@@ -262,10 +296,13 @@ public class LocationManagerService extends ILocationManager.Stub
throw new IllegalStateException("Request for non-existent intent");
}
- public void onStatusChanged(String provider, int status, Bundle extras)
- throws RemoteException {
+ public boolean callStatusChangedLocked(String provider, int status, Bundle extras) {
if (mListener != null) {
- mListener.onStatusChanged(provider, status, extras);
+ try {
+ mListener.onStatusChanged(provider, status, extras);
+ } catch (RemoteException e) {
+ return false;
+ }
} else {
Intent statusChanged = new Intent();
statusChanged.putExtras(extras);
@@ -273,23 +310,29 @@ public class LocationManagerService extends ILocationManager.Stub
try {
mPendingIntent.send(mContext, 0, statusChanged, null, null);
} catch (PendingIntent.CanceledException e) {
- _removeUpdates(this);
+ return false;
}
}
+ return true;
}
- public void onLocationChanged(Location location) throws RemoteException {
+ public boolean callLocationChangedLocked(Location location) {
if (mListener != null) {
- mListener.onLocationChanged(location);
+ try {
+ mListener.onLocationChanged(location);
+ } catch (RemoteException e) {
+ return false;
+ }
} else {
Intent locationChanged = new Intent();
locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED, location);
try {
mPendingIntent.send(mContext, 0, locationChanged, null, null);
} catch (PendingIntent.CanceledException e) {
- _removeUpdates(this);
+ return false;
}
}
+ return true;
}
public void binderDied() {
@@ -297,12 +340,12 @@ public class LocationManagerService extends ILocationManager.Stub
Log.d(TAG, "Location listener died");
}
synchronized (mLocationListeners) {
- _removeUpdates(this);
+ removeUpdatesLocked(this);
}
}
}
- private Location readLastKnownLocation(String provider) {
+ private Location readLastKnownLocationLocked(String provider) {
Location location = null;
String s = null;
try {
@@ -345,7 +388,7 @@ public class LocationManagerService extends ILocationManager.Stub
return location;
}
- private void writeLastKnownLocation(String provider,
+ private void writeLastKnownLocationLocked(String provider,
Location location) {
long now = SystemClock.elapsedRealtime();
Long last = mLastWriteTime.get(provider);
@@ -403,26 +446,26 @@ public class LocationManagerService extends ILocationManager.Stub
* properties
*/
private void loadProviders() {
- synchronized (LocationManagerService.class) {
+ synchronized (mLocationListeners) {
if (sProvidersLoaded) {
return;
}
// Load providers
- loadProvidersNoSync();
+ loadProvidersLocked();
sProvidersLoaded = true;
}
}
- private void loadProvidersNoSync() {
+ private void loadProvidersLocked() {
try {
- _loadProvidersNoSync();
+ _loadProvidersLocked();
} catch (Exception e) {
Log.e(TAG, "Exception loading providers:", e);
}
}
- private void _loadProvidersNoSync() {
+ private void _loadProvidersLocked() {
// Attempt to load "real" providers first
if (GpsLocationProvider.isSupported()) {
// Create a gps location provider
@@ -495,7 +538,7 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- updateProviders();
+ updateProvidersLocked();
}
/**
@@ -546,13 +589,15 @@ public class LocationManagerService extends ILocationManager.Stub
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ intentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
context.registerReceiver(powerStateReceiver, intentFilter);
// Get the wifi manager
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// Create a wifi lock for future use
- mWifiLock = getWifiWakelock();
+ mWifiLock = getWifiWakelockLocked();
// There might be an existing wifi scan available
if (mWifiManager != null) {
@@ -566,28 +611,34 @@ public class LocationManagerService extends ILocationManager.Stub
}
public void setInstallCallback(InstallCallback callback) {
- mLocationHandler.removeMessages(MESSAGE_INSTALL_NETWORK_LOCATION_PROVIDER);
- Message m = Message.obtain(mLocationHandler,
- MESSAGE_INSTALL_NETWORK_LOCATION_PROVIDER, callback);
- mLocationHandler.sendMessageAtFrontOfQueue(m);
+ synchronized (mLocationListeners) {
+ mLocationHandler.removeMessages(MESSAGE_INSTALL_NETWORK_LOCATION_PROVIDER);
+ Message m = Message.obtain(mLocationHandler,
+ MESSAGE_INSTALL_NETWORK_LOCATION_PROVIDER, callback);
+ mLocationHandler.sendMessageAtFrontOfQueue(m);
+ }
}
public void setNetworkLocationProvider(INetworkLocationProvider provider) {
- mNetworkLocationInterface = provider;
- provider.addListener(getPackageNames());
- mNetworkLocationProvider = (LocationProviderImpl)provider;
- LocationProviderImpl.addProvider(mNetworkLocationProvider);
- updateProviders();
+ synchronized (mLocationListeners) {
+ mNetworkLocationInterface = provider;
+ provider.addListener(getPackageNames());
+ mNetworkLocationProvider = (LocationProviderImpl)provider;
+ LocationProviderImpl.addProvider(mNetworkLocationProvider);
+ updateProvidersLocked();
+ }
}
public void setLocationCollector(ILocationCollector collector) {
- mCollector = collector;
- if (mGpsLocationProvider != null) {
+ synchronized (mLocationListeners) {
+ mCollector = collector;
+ if (mGpsLocationProvider != null) {
mGpsLocationProvider.setLocationCollector(mCollector);
+ }
}
}
- private WifiManager.WifiLock getWifiWakelock() {
+ private WifiManager.WifiLock getWifiWakelockLocked() {
if (mWifiLock == null && mWifiManager != null) {
mWifiLock = mWifiManager.createWifiLock(WifiManager.WIFI_MODE_SCAN_ONLY, WIFILOCK_KEY);
mWifiLock.setReferenceCounted(false);
@@ -595,7 +646,7 @@ public class LocationManagerService extends ILocationManager.Stub
return mWifiLock;
}
- private boolean isAllowedBySettings(String provider) {
+ private boolean isAllowedBySettingsLocked(String provider) {
if (mEnabledProviders.contains(provider)) {
return true;
}
@@ -610,7 +661,7 @@ public class LocationManagerService extends ILocationManager.Stub
return ((allowedProviders != null) && (allowedProviders.contains(provider)));
}
- private void checkPermissions(String provider) {
+ private void checkPermissionsSafe(String provider) {
if (LocationManager.GPS_PROVIDER.equals(provider)
&& (mContext.checkCallingPermission(ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)) {
@@ -626,7 +677,7 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private boolean isAllowedProvider(String provider) {
+ private boolean isAllowedProviderSafe(String provider) {
if (LocationManager.GPS_PROVIDER.equals(provider)
&& (mContext.checkCallingPermission(ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)) {
@@ -651,7 +702,9 @@ public class LocationManagerService extends ILocationManager.Stub
public List<String> getAllProviders() {
try {
- return _getAllProviders();
+ synchronized (mLocationListeners) {
+ return _getAllProvidersLocked();
+ }
} catch (SecurityException se) {
throw se;
} catch (Exception e) {
@@ -660,7 +713,7 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private List<String> _getAllProviders() {
+ private List<String> _getAllProvidersLocked() {
if (Config.LOGD) {
Log.d(TAG, "getAllProviders");
}
@@ -675,7 +728,9 @@ public class LocationManagerService extends ILocationManager.Stub
public List<String> getProviders(boolean enabledOnly) {
try {
- return _getProviders(enabledOnly);
+ synchronized (mLocationListeners) {
+ return _getProvidersLocked(enabledOnly);
+ }
} catch (SecurityException se) {
throw se;
} catch (Exception e) {
@@ -684,7 +739,7 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private List<String> _getProviders(boolean enabledOnly) {
+ private List<String> _getProvidersLocked(boolean enabledOnly) {
if (Config.LOGD) {
Log.d(TAG, "getProviders");
}
@@ -693,8 +748,8 @@ public class LocationManagerService extends ILocationManager.Stub
for (LocationProviderImpl p : providers) {
String name = p.getName();
- if (isAllowedProvider(name)) {
- if (enabledOnly && !isAllowedBySettings(name)) {
+ if (isAllowedProviderSafe(name)) {
+ if (enabledOnly && !isAllowedBySettingsLocked(name)) {
continue;
}
out.add(name);
@@ -704,10 +759,16 @@ public class LocationManagerService extends ILocationManager.Stub
}
public void updateProviders() {
+ synchronized (mLocationListeners) {
+ updateProvidersLocked();
+ }
+ }
+
+ private void updateProvidersLocked() {
for (LocationProviderImpl p : LocationProviderImpl.getProviders()) {
boolean isEnabled = p.isEnabled();
String name = p.getName();
- boolean shouldBeEnabled = isAllowedBySettings(name);
+ boolean shouldBeEnabled = isAllowedBySettingsLocked(name);
// Collection is only allowed when network provider is being used
if (mCollector != null &&
@@ -716,15 +777,15 @@ public class LocationManagerService extends ILocationManager.Stub
}
if (isEnabled && !shouldBeEnabled) {
- updateProviderListeners(name, false);
+ updateProviderListenersLocked(name, false);
} else if (!isEnabled && shouldBeEnabled) {
- updateProviderListeners(name, true);
+ updateProviderListenersLocked(name, true);
}
}
}
- private void updateProviderListeners(String provider, boolean enabled) {
+ private void updateProviderListenersLocked(String provider, boolean enabled) {
int listeners = 0;
LocationProviderImpl p = LocationProviderImpl.getProvider(provider);
@@ -732,49 +793,63 @@ public class LocationManagerService extends ILocationManager.Stub
return;
}
- synchronized (mRecordsByProvider) {
- HashSet<UpdateRecord> records = mRecordsByProvider.get(provider);
- if (records != null) {
- for (UpdateRecord record : records) {
- // Sends a notification message to the receiver
- try {
- Receiver receiver = record.mReceiver;
- if (receiver.isListener()) {
- if (enabled) {
- receiver.getListener().onProviderEnabled(provider);
- } else {
- receiver.getListener().onProviderDisabled(provider);
- }
+ ArrayList<Receiver> deadReceivers = null;
+
+ ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
+ if (records != null) {
+ final int N = records.size();
+ for (int i=0; i<N; i++) {
+ UpdateRecord record = records.get(i);
+ // Sends a notification message to the receiver
+ try {
+ Receiver receiver = record.mReceiver;
+ if (receiver.isListener()) {
+ if (enabled) {
+ receiver.getListener().onProviderEnabled(provider);
} else {
- PendingIntent intent = receiver.getPendingIntent();
- Intent providerIntent = new Intent();
- providerIntent.putExtra(LocationManager.KEY_PROVIDER_ENABLED, enabled);
- try {
- receiver.getPendingIntent().send(mContext, 0,
- providerIntent, null, null);
- } catch (PendingIntent.CanceledException e) {
- _removeUpdates(receiver);
+ receiver.getListener().onProviderDisabled(provider);
+ }
+ } else {
+ Intent providerIntent = new Intent();
+ providerIntent.putExtra(LocationManager.KEY_PROVIDER_ENABLED, enabled);
+ try {
+ receiver.getPendingIntent().send(mContext, 0,
+ providerIntent, null, null);
+ } catch (PendingIntent.CanceledException e) {
+ if (deadReceivers == null) {
+ deadReceivers = new ArrayList<Receiver>();
+ deadReceivers.add(receiver);
}
}
- } catch (RemoteException e) {
- // The death link will clean this up.
}
- listeners++;
+ } catch (RemoteException e) {
+ // The death link will clean this up.
}
+ listeners++;
}
}
+ if (deadReceivers != null) {
+ for (int i=deadReceivers.size()-1; i>=0; i--) {
+ removeUpdatesLocked(deadReceivers.get(i));
+ }
+ }
+
if (enabled) {
p.enable();
if (listeners > 0) {
- p.setMinTime(getMinTime(provider));
+ p.setMinTime(getMinTimeLocked(provider));
p.enableLocationTracking(true);
- updateWakelockStatus(mScreenOn);
+ updateWakelockStatusLocked(mScreenOn);
}
} else {
p.enableLocationTracking(false);
+ if (p == mGpsLocationProvider) {
+ mGpsNavigating = false;
+ reportStopGpsLocked();
+ }
p.disable();
- updateWakelockStatus(mScreenOn);
+ updateWakelockStatusLocked(mScreenOn);
}
if (enabled && listeners > 0) {
@@ -786,40 +861,43 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private long getMinTime(String provider) {
+ private long getMinTimeLocked(String provider) {
long minTime = Long.MAX_VALUE;
- synchronized (mRecordsByProvider) {
- HashSet<UpdateRecord> records = mRecordsByProvider.get(provider);
- if (records != null) {
- for (UpdateRecord r : records) {
- minTime = Math.min(minTime, r.mMinTime);
- }
+ ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
+ if (records != null) {
+ for (int i=records.size()-1; i>=0; i--) {
+ minTime = Math.min(minTime, records.get(i).mMinTime);
}
}
return minTime;
}
private class UpdateRecord {
- String mProvider;
- Receiver mReceiver;
- long mMinTime;
- float mMinDistance;
- String[] mPackages;
+ final String mProvider;
+ final Receiver mReceiver;
+ final long mMinTime;
+ final float mMinDistance;
+ final int mUid;
+ final String[] mPackages;
+ /**
+ * Note: must be constructed with lock held.
+ */
UpdateRecord(String provider, long minTime, float minDistance,
- Receiver receiver, String[] packages) {
+ Receiver receiver, int uid, String[] packages) {
mProvider = provider;
mReceiver = receiver;
mMinTime = minTime;
mMinDistance = minDistance;
+ mUid = uid;
mPackages = packages;
- synchronized (mRecordsByProvider) {
- HashSet<UpdateRecord> records = mRecordsByProvider.get(provider);
- if (records == null) {
- records = new HashSet<UpdateRecord>();
- mRecordsByProvider.put(provider, records);
- }
+ ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
+ if (records == null) {
+ records = new ArrayList<UpdateRecord>();
+ mRecordsByProvider.put(provider, records);
+ }
+ if (!records.contains(this)) {
records.add(this);
}
}
@@ -828,18 +906,39 @@ public class LocationManagerService extends ILocationManager.Stub
* Method to be called when a record will no longer be used. Calling this multiple times
* must have the same effect as calling it once.
*/
- public void dispose() {
- synchronized (mRecordsByProvider) {
- HashSet<UpdateRecord> records = mRecordsByProvider.get(this.mProvider);
- records.remove(this);
- }
+ void disposeLocked() {
+ ArrayList<UpdateRecord> records = mRecordsByProvider.get(this.mProvider);
+ records.remove(this);
}
+ @Override
+ public String toString() {
+ return "UpdateRecord{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + mProvider + " " + mReceiver + "}";
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + this);
+ pw.println(prefix + "mProvider=" + mProvider + " mReceiver=" + mReceiver);
+ pw.println(prefix + "mMinTime=" + mMinTime + " mMinDistance=" + mMinDistance);
+ StringBuilder sb = new StringBuilder();
+ if (mPackages != null) {
+ for (int i=0; i<mPackages.length; i++) {
+ if (i > 0) sb.append(", ");
+ sb.append(mPackages[i]);
+ }
+ }
+ pw.println(prefix + "mUid=" + mUid + " mPackages=" + sb);
+ }
+
/**
* Calls dispose().
*/
@Override protected void finalize() {
- dispose();
+ synchronized (mLocationListeners) {
+ disposeLocked();
+ }
}
}
@@ -847,8 +946,10 @@ public class LocationManagerService extends ILocationManager.Stub
long minTime, float minDistance, ILocationListener listener) {
try {
- _requestLocationUpdates(provider, minTime, minDistance,
- new Receiver(listener));
+ synchronized (mLocationListeners) {
+ requestLocationUpdatesLocked(provider, minTime, minDistance,
+ new Receiver(listener, Binder.getCallingUid()));
+ }
} catch (SecurityException se) {
throw se;
} catch (Exception e) {
@@ -859,8 +960,10 @@ public class LocationManagerService extends ILocationManager.Stub
public void requestLocationUpdatesPI(String provider,
long minTime, float minDistance, PendingIntent intent) {
try {
- _requestLocationUpdates(provider, minTime, minDistance,
- new Receiver(intent));
+ synchronized (mLocationListeners) {
+ requestLocationUpdatesLocked(provider, minTime, minDistance,
+ new Receiver(intent, Binder.getCallingUid()));
+ }
} catch (SecurityException se) {
throw se;
} catch (Exception e) {
@@ -868,11 +971,10 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private synchronized void _requestLocationUpdates(String provider,
+ private void requestLocationUpdatesLocked(String provider,
long minTime, float minDistance, Receiver receiver) {
- Object key = receiver.getKey();
if (Config.LOGD) {
- Log.d(TAG, "_requestLocationUpdates: listener = " + key);
+ Log.d(TAG, "_requestLocationUpdates: listener = " + receiver);
}
LocationProviderImpl impl = LocationProviderImpl.getProvider(provider);
@@ -880,77 +982,75 @@ public class LocationManagerService extends ILocationManager.Stub
throw new IllegalArgumentException("provider=" + provider);
}
- checkPermissions(provider);
+ checkPermissionsSafe(provider);
String[] packages = getPackageNames();
// so wakelock calls will succeed
- mCallingUid = getCallingUid();
+ final int callingUid = Binder.getCallingUid();
long identity = Binder.clearCallingIdentity();
try {
- UpdateRecord r = new UpdateRecord(provider, minTime, minDistance, receiver, packages);
- synchronized (mLocationListeners) {
- if (mListeners.get(key) == null) {
- try {
- if (receiver.isListener()) {
- receiver.getListener().asBinder().linkToDeath(receiver, 0);
- }
- mListeners.put(key, receiver);
- } catch (RemoteException e) {
- return;
+ UpdateRecord r = new UpdateRecord(provider, minTime, minDistance,
+ receiver, callingUid, packages);
+ if (!mListeners.contains(receiver)) {
+ try {
+ if (receiver.isListener()) {
+ receiver.getListener().asBinder().linkToDeath(receiver, 0);
}
+ mListeners.add(receiver);
+ } catch (RemoteException e) {
+ return;
}
+ }
- HashMap<String,UpdateRecord> records = mLocationListeners.get(key);
- if (records == null) {
- records = new HashMap<String,UpdateRecord>();
- mLocationListeners.put(key, records);
- }
- UpdateRecord oldRecord = records.put(provider, r);
- if (oldRecord != null) {
- oldRecord.dispose();
- }
+ HashMap<String,UpdateRecord> records = mLocationListeners.get(receiver);
+ if (records == null) {
+ records = new HashMap<String,UpdateRecord>();
+ mLocationListeners.put(receiver, records);
+ }
+ UpdateRecord oldRecord = records.put(provider, r);
+ if (oldRecord != null) {
+ oldRecord.disposeLocked();
+ }
- boolean isProviderEnabled = isAllowedBySettings(provider);
- if (isProviderEnabled) {
- if (provider.equals(LocationManager.GPS_PROVIDER)) {
- try {
- mBatteryStats.noteRequestGpsOn(mCallingUid);
- } catch (RemoteException e) {
- Log.w(TAG, "Got RemoteException calling noteRequestGpsOff", e);
- }
+ boolean isProviderEnabled = isAllowedBySettingsLocked(provider);
+ if (isProviderEnabled) {
+ long minTimeForProvider = getMinTimeLocked(provider);
+ impl.setMinTime(minTimeForProvider);
+ impl.enableLocationTracking(true);
+ updateWakelockStatusLocked(mScreenOn);
+
+ if (provider.equals(LocationManager.GPS_PROVIDER)) {
+ if (mGpsNavigating) {
+ updateReportedGpsLocked();
}
-
- long minTimeForProvider = getMinTime(provider);
- impl.setMinTime(minTimeForProvider);
- impl.enableLocationTracking(true);
- updateWakelockStatus(mScreenOn);
-
- // Clear heartbeats if any before starting a new one
- mLocationHandler.removeMessages(MESSAGE_HEARTBEAT, provider);
- Message m = Message.obtain(mLocationHandler, MESSAGE_HEARTBEAT, provider);
- mLocationHandler.sendMessageAtTime(m, SystemClock.uptimeMillis() + 1000);
- } else {
- try {
- // Notify the listener that updates are currently disabled
- if (receiver.isListener()) {
- receiver.getListener().onProviderDisabled(provider);
- }
- } catch(RemoteException e) {
- Log.w(TAG, "RemoteException calling onProviderDisabled on " +
- receiver.getListener());
+ }
+
+ // Clear heartbeats if any before starting a new one
+ mLocationHandler.removeMessages(MESSAGE_HEARTBEAT, provider);
+ Message m = Message.obtain(mLocationHandler, MESSAGE_HEARTBEAT, provider);
+ mLocationHandler.sendMessageAtTime(m, SystemClock.uptimeMillis() + 1000);
+ } else {
+ try {
+ // Notify the listener that updates are currently disabled
+ if (receiver.isListener()) {
+ receiver.getListener().onProviderDisabled(provider);
}
+ } catch(RemoteException e) {
+ Log.w(TAG, "RemoteException calling onProviderDisabled on " +
+ receiver.getListener());
}
}
} finally {
Binder.restoreCallingIdentity(identity);
- mCallingUid = -1;
}
}
public void removeUpdates(ILocationListener listener) {
try {
- _removeUpdates(new Receiver(listener));
+ synchronized (mLocationListeners) {
+ removeUpdatesLocked(new Receiver(listener, Binder.getCallingUid()));
+ }
} catch (SecurityException se) {
throw se;
} catch (Exception e) {
@@ -960,7 +1060,9 @@ public class LocationManagerService extends ILocationManager.Stub
public void removeUpdatesPI(PendingIntent intent) {
try {
- _removeUpdates(new Receiver(intent));
+ synchronized (mLocationListeners) {
+ removeUpdatesLocked(new Receiver(intent, Binder.getCallingUid()));
+ }
} catch (SecurityException se) {
throw se;
} catch (Exception e) {
@@ -968,84 +1070,77 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private synchronized void _removeUpdates(Receiver receiver) {
- Object key = receiver.getKey();
+ private void removeUpdatesLocked(Receiver receiver) {
if (Config.LOGD) {
- Log.d(TAG, "_removeUpdates: listener = " + key);
+ Log.d(TAG, "_removeUpdates: listener = " + receiver);
}
// so wakelock calls will succeed
- mCallingUid = getCallingUid();
+ final int callingUid = Binder.getCallingUid();
long identity = Binder.clearCallingIdentity();
try {
- synchronized (mLocationListeners) {
- Receiver myReceiver = mListeners.remove(key);
- if ((myReceiver != null) && (myReceiver.isListener())) {
+ int idx = mListeners.indexOf(receiver);
+ if (idx >= 0) {
+ Receiver myReceiver = mListeners.remove(idx);
+ if (myReceiver.isListener()) {
myReceiver.getListener().asBinder().unlinkToDeath(myReceiver, 0);
}
+ }
- // Record which providers were associated with this listener
- HashSet<String> providers = new HashSet<String>();
- HashMap<String,UpdateRecord> oldRecords = mLocationListeners.get(key);
- if (oldRecords != null) {
- // Call dispose() on the obsolete update records.
- for (UpdateRecord record : oldRecords.values()) {
- if (record.mProvider.equals(LocationManager.NETWORK_PROVIDER)) {
- if (mNetworkLocationInterface != null) {
- mNetworkLocationInterface.removeListener(record.mPackages);
- }
+ // Record which providers were associated with this listener
+ HashSet<String> providers = new HashSet<String>();
+ HashMap<String,UpdateRecord> oldRecords = mLocationListeners.get(receiver);
+ if (oldRecords != null) {
+ // Call dispose() on the obsolete update records.
+ for (UpdateRecord record : oldRecords.values()) {
+ if (record.mProvider.equals(LocationManager.NETWORK_PROVIDER)) {
+ if (mNetworkLocationInterface != null) {
+ mNetworkLocationInterface.removeListener(record.mPackages);
}
- record.dispose();
}
- // Accumulate providers
- providers.addAll(oldRecords.keySet());
+ record.disposeLocked();
}
-
- if (providers.contains("gps")) {
- try {
- mBatteryStats.noteRequestGpsOff(mCallingUid);
- } catch (RemoteException e) {
- Log.w(TAG, "Got RemoteException calling noteRequestGpsOff", e);
- }
+ // Accumulate providers
+ providers.addAll(oldRecords.keySet());
+ }
+
+ mLocationListeners.remove(receiver);
+ mLastFixBroadcast.remove(receiver);
+ mLastStatusBroadcast.remove(receiver);
+
+ // See if the providers associated with this listener have any
+ // other listeners; if one does, inform it of the new smallest minTime
+ // value; if one does not, disable location tracking for it
+ for (String provider : providers) {
+ // If provider is already disabled, don't need to do anything
+ if (!isAllowedBySettingsLocked(provider)) {
+ continue;
}
- mLocationListeners.remove(key);
- mLastFixBroadcast.remove(key);
- mLastStatusBroadcast.remove(key);
-
- // See if the providers associated with this listener have any
- // other listeners; if one does, inform it of the new smallest minTime
- // value; if one does not, disable location tracking for it
- for (String provider : providers) {
- // If provider is already disabled, don't need to do anything
- if (!isAllowedBySettings(provider)) {
- continue;
- }
+ boolean hasOtherListener = false;
+ ArrayList<UpdateRecord> recordsForProvider = mRecordsByProvider.get(provider);
+ if (recordsForProvider != null && recordsForProvider.size() > 0) {
+ hasOtherListener = true;
+ }
- boolean hasOtherListener = false;
- synchronized (mRecordsByProvider) {
- HashSet<UpdateRecord> recordsForProvider = mRecordsByProvider.get(provider);
- if (recordsForProvider != null && recordsForProvider.size() > 0) {
- hasOtherListener = true;
- }
+ LocationProviderImpl p = LocationProviderImpl.getProvider(provider);
+ if (p != null) {
+ if (hasOtherListener) {
+ p.setMinTime(getMinTimeLocked(provider));
+ } else {
+ mLocationHandler.removeMessages(MESSAGE_HEARTBEAT, provider);
+ p.enableLocationTracking(false);
}
-
- LocationProviderImpl p = LocationProviderImpl.getProvider(provider);
- if (p != null) {
- if (hasOtherListener) {
- p.setMinTime(getMinTime(provider));
- } else {
- mLocationHandler.removeMessages(MESSAGE_HEARTBEAT, provider);
- p.enableLocationTracking(false);
- }
+
+ if (p == mGpsLocationProvider && mGpsNavigating) {
+ updateReportedGpsLocked();
}
}
-
- updateWakelockStatus(mScreenOn);
}
+
+ updateWakelockStatusLocked(mScreenOn);
} finally {
Binder.restoreCallingIdentity(identity);
- mCallingUid = -1;
}
}
@@ -1054,7 +1149,7 @@ public class LocationManagerService extends ILocationManager.Stub
return false;
}
if (mContext.checkCallingPermission(ACCESS_FINE_LOCATION) !=
- PackageManager.PERMISSION_GRANTED) {
+ PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires ACCESS_FINE_LOCATION permission");
}
@@ -1068,36 +1163,42 @@ public class LocationManagerService extends ILocationManager.Stub
}
public void removeGpsStatusListener(IGpsStatusListener listener) {
- mGpsLocationProvider.removeGpsStatusListener(listener);
+ synchronized (mLocationListeners) {
+ mGpsLocationProvider.removeGpsStatusListener(listener);
+ }
}
public boolean sendExtraCommand(String provider, String command, Bundle extras) {
// first check for permission to the provider
- checkPermissions(provider);
+ checkPermissionsSafe(provider);
// and check for ACCESS_LOCATION_EXTRA_COMMANDS
if ((mContext.checkCallingPermission(ACCESS_LOCATION_EXTRA_COMMANDS)
!= PackageManager.PERMISSION_GRANTED)) {
throw new SecurityException("Requires ACCESS_LOCATION_EXTRA_COMMANDS permission");
}
- LocationProviderImpl impl = LocationProviderImpl.getProvider(provider);
- if (provider == null) {
- return false;
+ synchronized (mLocationListeners) {
+ LocationProviderImpl impl = LocationProviderImpl.getProvider(provider);
+ if (provider == null) {
+ return false;
+ }
+
+ return impl.sendExtraCommand(command, extras);
}
-
- return impl.sendExtraCommand(command, extras);
}
class ProximityAlert {
- double mLatitude;
- double mLongitude;
- float mRadius;
- long mExpiration;
- PendingIntent mIntent;
- Location mLocation;
-
- public ProximityAlert(double latitude, double longitude,
+ final int mUid;
+ final double mLatitude;
+ final double mLongitude;
+ final float mRadius;
+ final long mExpiration;
+ final PendingIntent mIntent;
+ final Location mLocation;
+
+ public ProximityAlert(int uid, double latitude, double longitude,
float radius, long expiration, PendingIntent intent) {
+ mUid = uid;
mLatitude = latitude;
mLongitude = longitude;
mRadius = radius;
@@ -1109,15 +1210,15 @@ public class LocationManagerService extends ILocationManager.Stub
mLocation.setLongitude(longitude);
}
- public long getExpiration() {
+ long getExpiration() {
return mExpiration;
}
- public PendingIntent getIntent() {
+ PendingIntent getIntent() {
return mIntent;
}
- public boolean isInProximity(double latitude, double longitude) {
+ boolean isInProximity(double latitude, double longitude) {
Location loc = new Location("");
loc.setLatitude(latitude);
loc.setLongitude(longitude);
@@ -1125,6 +1226,22 @@ public class LocationManagerService extends ILocationManager.Stub
double radius = loc.distanceTo(mLocation);
return radius <= mRadius;
}
+
+ @Override
+ public String toString() {
+ return "ProximityAlert{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " uid " + mUid + mIntent + "}";
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + this);
+ pw.println(prefix + "mLatitude=" + mLatitude + " mLongitude=" + mLongitude);
+ pw.println(prefix + "mRadius=" + mRadius + " mExpiration=" + mExpiration);
+ pw.println(prefix + "mIntent=" + mIntent);
+ pw.println(prefix + "mLocation:");
+ mLocation.dump(new PrintWriterPrinter(pw), prefix + " ");
+ }
}
// Listener for receiving locations to trigger proximity alerts
@@ -1132,6 +1249,7 @@ public class LocationManagerService extends ILocationManager.Stub
boolean isGpsAvailable = false;
+ // Note: this is called with the lock held.
public void onLocationChanged(Location loc) {
// If Gps is available, then ignore updates from NetworkLocationProvider
@@ -1216,16 +1334,19 @@ public class LocationManagerService extends ILocationManager.Stub
}
+ // Note: this is called with the lock held.
public void onProviderDisabled(String provider) {
if (provider.equals(LocationManager.GPS_PROVIDER)) {
isGpsAvailable = false;
}
}
+ // Note: this is called with the lock held.
public void onProviderEnabled(String provider) {
// ignore
}
+ // Note: this is called with the lock held.
public void onStatusChanged(String provider, int status, Bundle extras) {
if ((provider.equals(LocationManager.GPS_PROVIDER)) &&
(status != LocationProvider.AVAILABLE)) {
@@ -1237,7 +1358,9 @@ public class LocationManagerService extends ILocationManager.Stub
public void addProximityAlert(double latitude, double longitude,
float radius, long expiration, PendingIntent intent) {
try {
- _addProximityAlert(latitude, longitude, radius, expiration, intent);
+ synchronized (mLocationListeners) {
+ addProximityAlertLocked(latitude, longitude, radius, expiration, intent);
+ }
} catch (SecurityException se) {
throw se;
} catch (Exception e) {
@@ -1245,7 +1368,7 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private void _addProximityAlert(double latitude, double longitude,
+ private void addProximityAlertLocked(double latitude, double longitude,
float radius, long expiration, PendingIntent intent) {
if (Config.LOGD) {
Log.d(TAG, "addProximityAlert: latitude = " + latitude +
@@ -1255,37 +1378,42 @@ public class LocationManagerService extends ILocationManager.Stub
}
// Require ability to access all providers for now
- if (!isAllowedProvider(LocationManager.GPS_PROVIDER) ||
- !isAllowedProvider(LocationManager.NETWORK_PROVIDER)) {
+ if (!isAllowedProviderSafe(LocationManager.GPS_PROVIDER) ||
+ !isAllowedProviderSafe(LocationManager.NETWORK_PROVIDER)) {
throw new SecurityException("Requires ACCESS_FINE_LOCATION permission");
}
if (expiration != -1) {
expiration += System.currentTimeMillis();
}
- ProximityAlert alert = new ProximityAlert(latitude, longitude, radius, expiration, intent);
+ ProximityAlert alert = new ProximityAlert(Binder.getCallingUid(),
+ latitude, longitude, radius, expiration, intent);
mProximityAlerts.put(intent, alert);
if (mProximityListener == null) {
- mProximityListener = new Receiver(new ProximityListener());
+ mProximityListener = new Receiver(new ProximityListener(), -1);
LocationProvider provider = LocationProviderImpl.getProvider(
LocationManager.GPS_PROVIDER);
if (provider != null) {
- _requestLocationUpdates(provider.getName(), 1000L, 1.0f, mProximityListener);
+ requestLocationUpdatesLocked(provider.getName(), 1000L, 1.0f, mProximityListener);
}
provider =
LocationProviderImpl.getProvider(LocationManager.NETWORK_PROVIDER);
if (provider != null) {
- _requestLocationUpdates(provider.getName(), 1000L, 1.0f, mProximityListener);
+ requestLocationUpdatesLocked(provider.getName(), 1000L, 1.0f, mProximityListener);
}
+ } else if (mGpsNavigating) {
+ updateReportedGpsLocked();
}
}
public void removeProximityAlert(PendingIntent intent) {
try {
- _removeProximityAlert(intent);
+ synchronized (mLocationListeners) {
+ removeProximityAlertLocked(intent);
+ }
} catch (SecurityException se) {
throw se;
} catch (Exception e) {
@@ -1293,15 +1421,17 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private void _removeProximityAlert(PendingIntent intent) {
+ private void removeProximityAlertLocked(PendingIntent intent) {
if (Config.LOGD) {
Log.d(TAG, "removeProximityAlert: intent = " + intent);
}
mProximityAlerts.remove(intent);
if (mProximityAlerts.size() == 0) {
- _removeUpdates(mProximityListener);
+ removeUpdatesLocked(mProximityListener);
mProximityListener = null;
+ } else if (mGpsNavigating) {
+ updateReportedGpsLocked();
}
}
@@ -1312,7 +1442,9 @@ public class LocationManagerService extends ILocationManager.Stub
*/
public Bundle getProviderInfo(String provider) {
try {
- return _getProviderInfo(provider);
+ synchronized (mLocationListeners) {
+ return _getProviderInfoLocked(provider);
+ }
} catch (SecurityException se) {
throw se;
} catch (Exception e) {
@@ -1321,13 +1453,13 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private Bundle _getProviderInfo(String provider) {
+ private Bundle _getProviderInfoLocked(String provider) {
LocationProviderImpl p = LocationProviderImpl.getProvider(provider);
if (p == null) {
return null;
}
- checkPermissions(provider);
+ checkPermissionsSafe(provider);
Bundle b = new Bundle();
b.putBoolean("network", p.requiresNetwork());
@@ -1345,7 +1477,9 @@ public class LocationManagerService extends ILocationManager.Stub
public boolean isProviderEnabled(String provider) {
try {
- return _isProviderEnabled(provider);
+ synchronized (mLocationListeners) {
+ return _isProviderEnabledLocked(provider);
+ }
} catch (SecurityException se) {
throw se;
} catch (Exception e) {
@@ -1354,19 +1488,21 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private boolean _isProviderEnabled(String provider) {
- checkPermissions(provider);
+ private boolean _isProviderEnabledLocked(String provider) {
+ checkPermissionsSafe(provider);
LocationProviderImpl p = LocationProviderImpl.getProvider(provider);
if (p == null) {
throw new IllegalArgumentException("provider=" + provider);
}
- return isAllowedBySettings(provider);
+ return isAllowedBySettingsLocked(provider);
}
public Location getLastKnownLocation(String provider) {
try {
- return _getLastKnownLocation(provider);
+ synchronized (mLocationListeners) {
+ return _getLastKnownLocationLocked(provider);
+ }
} catch (SecurityException se) {
throw se;
} catch (Exception e) {
@@ -1375,22 +1511,22 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private Location _getLastKnownLocation(String provider) {
- checkPermissions(provider);
+ private Location _getLastKnownLocationLocked(String provider) {
+ checkPermissionsSafe(provider);
LocationProviderImpl p = LocationProviderImpl.getProvider(provider);
if (p == null) {
throw new IllegalArgumentException("provider=" + provider);
}
- if (!isAllowedBySettings(provider)) {
+ if (!isAllowedBySettingsLocked(provider)) {
return null;
}
Location location = mLastKnownLocation.get(provider);
if (location == null) {
// Get the persistent last known location for the provider
- location = readLastKnownLocation(provider);
+ location = readLastKnownLocationLocked(provider);
if (location != null) {
mLastKnownLocation.put(provider, location);
}
@@ -1399,7 +1535,7 @@ public class LocationManagerService extends ILocationManager.Stub
return location;
}
- private boolean shouldBroadcast(Location loc, Location lastLoc, UpdateRecord record) {
+ private static boolean shouldBroadcastSafe(Location loc, Location lastLoc, UpdateRecord record) {
// Always broadcast the first update
if (lastLoc == null) {
return true;
@@ -1422,8 +1558,8 @@ public class LocationManagerService extends ILocationManager.Stub
return true;
}
- private void handleLocationChanged(String provider) {
- HashSet<UpdateRecord> records = mRecordsByProvider.get(provider);
+ private void handleLocationChangedLocked(String provider) {
+ ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
if (records == null || records.size() == 0) {
return;
}
@@ -1460,7 +1596,7 @@ public class LocationManagerService extends ILocationManager.Stub
} else {
location.set(loc);
}
- writeLastKnownLocation(provider, loc);
+ writeLastKnownLocationLocked(provider, loc);
if (p instanceof INetworkLocationProvider) {
mWakeLockNetworkReceived = true;
@@ -1495,40 +1631,44 @@ public class LocationManagerService extends ILocationManager.Stub
extras.putAll(mockExtras);
}
+ ArrayList<Receiver> deadReceivers = null;
+
// Broadcast location or status to all listeners
- for (UpdateRecord r : records) {
+ final int N = records.size();
+ for (int i=0; i<N; i++) {
+ UpdateRecord r = records.get(i);
Receiver receiver = r.mReceiver;
- Object key = receiver.getKey();
// Broadcast location only if it is valid
if (locationValid) {
- HashMap<String,Location> map = mLastFixBroadcast.get(key);
+ HashMap<String,Location> map = mLastFixBroadcast.get(receiver);
if (map == null) {
map = new HashMap<String,Location>();
- mLastFixBroadcast.put(key, map);
+ mLastFixBroadcast.put(receiver, map);
}
Location lastLoc = map.get(provider);
- if ((lastLoc == null) || shouldBroadcast(loc, lastLoc, r)) {
+ if ((lastLoc == null) || shouldBroadcastSafe(loc, lastLoc, r)) {
if (lastLoc == null) {
lastLoc = new Location(loc);
map.put(provider, lastLoc);
} else {
lastLoc.set(loc);
}
- try {
- receiver.onLocationChanged(loc);
- } catch (RemoteException doe) {
+ if (!receiver.callLocationChangedLocked(loc)) {
Log.w(TAG, "RemoteException calling onLocationChanged on " + receiver);
- _removeUpdates(receiver);
+ if (deadReceivers == null) {
+ deadReceivers = new ArrayList<Receiver>();
+ }
+ deadReceivers.add(receiver);
}
}
}
// Broadcast status message
- HashMap<String,Long> statusMap = mLastStatusBroadcast.get(key);
+ HashMap<String,Long> statusMap = mLastStatusBroadcast.get(receiver);
if (statusMap == null) {
statusMap = new HashMap<String,Long>();
- mLastStatusBroadcast.put(key, statusMap);
+ mLastStatusBroadcast.put(receiver, statusMap);
}
long prevStatusUpdateTime =
(statusMap.get(provider) != null) ? statusMap.get(provider) : 0;
@@ -1537,14 +1677,23 @@ public class LocationManagerService extends ILocationManager.Stub
(prevStatusUpdateTime != 0 || status != LocationProvider.AVAILABLE)) {
statusMap.put(provider, newStatusUpdateTime);
- try {
- receiver.onStatusChanged(provider, status, extras);
- } catch (RemoteException doe) {
+ if (!receiver.callStatusChangedLocked(provider, status, extras)) {
Log.w(TAG, "RemoteException calling onStatusChanged on " + receiver);
- _removeUpdates(receiver);
+ if (deadReceivers == null) {
+ deadReceivers = new ArrayList<Receiver>();
+ }
+ if (!deadReceivers.contains(receiver)) {
+ deadReceivers.add(receiver);
+ }
}
}
}
+
+ if (deadReceivers != null) {
+ for (int i=deadReceivers.size()-1; i>=0; i--) {
+ removeUpdatesLocked(deadReceivers.get(i));
+ }
+ }
}
private class LocationWorkerHandler extends Handler {
@@ -1555,59 +1704,63 @@ public class LocationManagerService extends ILocationManager.Stub
if (msg.what == MESSAGE_HEARTBEAT) {
// log("LocationWorkerHandler: Heartbeat!");
- synchronized (mRecordsByProvider) {
+ synchronized (mLocationListeners) {
String provider = (String) msg.obj;
- if (!isAllowedBySettings(provider)) {
+ if (!isAllowedBySettingsLocked(provider)) {
return;
}
// Process the location fix if the screen is on or we're holding a wakelock
if (mScreenOn || (mWakeLockAcquireTime != 0)) {
- handleLocationChanged(provider);
+ handleLocationChangedLocked(provider);
}
// If it continues to have listeners
- HashSet<UpdateRecord> records = mRecordsByProvider.get(provider);
+ ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
if (records != null && records.size() > 0) {
Message m = Message.obtain(this, MESSAGE_HEARTBEAT, provider);
sendMessageAtTime(m, SystemClock.uptimeMillis() + 1000);
}
- }
-
- if ((mWakeLockAcquireTime != 0) &&
- (SystemClock.elapsedRealtime() - mWakeLockAcquireTime
- > MAX_TIME_FOR_WAKE_LOCK)) {
- removeMessages(MESSAGE_ACQUIRE_WAKE_LOCK);
- removeMessages(MESSAGE_RELEASE_WAKE_LOCK);
-
- log("LocationWorkerHandler: Exceeded max time for wake lock");
- Message m = Message.obtain(this, MESSAGE_RELEASE_WAKE_LOCK);
- sendMessageAtFrontOfQueue(m);
-
- } else if (mWakeLockAcquireTime != 0 &&
- mWakeLockGpsReceived && mWakeLockNetworkReceived) {
-
- removeMessages(MESSAGE_ACQUIRE_WAKE_LOCK);
- removeMessages(MESSAGE_RELEASE_WAKE_LOCK);
-
- log("LocationWorkerHandler: Locations received.");
- mWakeLockAcquireTime = 0;
- Message m = Message.obtain(this, MESSAGE_RELEASE_WAKE_LOCK);
- sendMessageDelayed(m, TIME_AFTER_WAKE_LOCK);
+ if ((mWakeLockAcquireTime != 0) &&
+ (SystemClock.elapsedRealtime() - mWakeLockAcquireTime
+ > MAX_TIME_FOR_WAKE_LOCK)) {
+
+ removeMessages(MESSAGE_ACQUIRE_WAKE_LOCK);
+ removeMessages(MESSAGE_RELEASE_WAKE_LOCK);
+
+ log("LocationWorkerHandler: Exceeded max time for wake lock");
+ Message m = Message.obtain(this, MESSAGE_RELEASE_WAKE_LOCK);
+ sendMessageAtFrontOfQueue(m);
+
+ } else if (mWakeLockAcquireTime != 0 &&
+ mWakeLockGpsReceived && mWakeLockNetworkReceived) {
+
+ removeMessages(MESSAGE_ACQUIRE_WAKE_LOCK);
+ removeMessages(MESSAGE_RELEASE_WAKE_LOCK);
+
+ log("LocationWorkerHandler: Locations received.");
+ mWakeLockAcquireTime = 0;
+ Message m = Message.obtain(this, MESSAGE_RELEASE_WAKE_LOCK);
+ sendMessageDelayed(m, TIME_AFTER_WAKE_LOCK);
+ }
}
} else if (msg.what == MESSAGE_ACQUIRE_WAKE_LOCK) {
log("LocationWorkerHandler: Acquire");
- acquireWakeLock();
+ synchronized (mLocationListeners) {
+ acquireWakeLockLocked();
+ }
} else if (msg.what == MESSAGE_RELEASE_WAKE_LOCK) {
log("LocationWorkerHandler: Release");
// Update wakelock status so the next alarm is set before releasing wakelock
- updateWakelockStatus(mScreenOn);
- releaseWakeLock();
+ synchronized (mLocationListeners) {
+ updateWakelockStatusLocked(mScreenOn);
+ releaseWakeLockLocked();
+ }
} else if (msg.what == MESSAGE_INSTALL_NETWORK_LOCATION_PROVIDER) {
- synchronized (LocationManagerService.class) {
+ synchronized (mLocationListeners) {
Log.d(TAG, "installing network location provider");
INetworkLocationManager.InstallCallback callback =
(INetworkLocationManager.InstallCallback)msg.obj;
@@ -1627,21 +1780,23 @@ public class LocationManagerService extends ILocationManager.Stub
@Override
public void onCellLocationChanged(CellLocation cellLocation) {
try {
- int asu = mSignalStrength;
-
- // Gets cell state
- mLastCellState = new CellState(mTelephonyManager, cellLocation, asu);
-
- // Notify collector
- if (mCollector != null) {
- mCollector.updateCellState(mLastCellState);
- }
-
- // Updates providers
- List<LocationProviderImpl> providers = LocationProviderImpl.getProviders();
- for (LocationProviderImpl provider : providers) {
- if (provider.requiresCell()) {
- provider.updateCellState(mLastCellState);
+ synchronized (mLocationListeners) {
+ int asu = mSignalStrength;
+
+ // Gets cell state
+ mLastCellState = new CellState(mTelephonyManager, cellLocation, asu);
+
+ // Notify collector
+ if (mCollector != null) {
+ mCollector.updateCellState(mLastCellState);
+ }
+
+ // Updates providers
+ List<LocationProviderImpl> providers = LocationProviderImpl.getProviders();
+ for (LocationProviderImpl provider : providers) {
+ if (provider.requiresCell()) {
+ provider.updateCellState(mLastCellState);
+ }
}
}
} catch (Exception e) {
@@ -1651,17 +1806,21 @@ public class LocationManagerService extends ILocationManager.Stub
@Override
public void onSignalStrengthChanged(int asu) {
- mSignalStrength = asu;
-
- if (mLastCellState != null) {
- mLastCellState.updateSignalStrength(asu);
+ synchronized (mLocationListeners) {
+ mSignalStrength = asu;
+
+ if (mLastCellState != null) {
+ mLastCellState.updateSignalStrength(asu);
+ }
}
}
@Override
public void onDataConnectionStateChanged(int state) {
- if (mLastCellState != null) {
- mLastCellState.updateRadioType(mTelephonyManager);
+ synchronized (mLocationListeners) {
+ if (mLastCellState != null) {
+ mLastCellState.updateRadioType(mTelephonyManager);
+ }
}
}
};
@@ -1671,30 +1830,81 @@ public class LocationManagerService extends ILocationManager.Stub
String action = intent.getAction();
if (action.equals(ALARM_INTENT)) {
- mLocationHandler.removeMessages(MESSAGE_ACQUIRE_WAKE_LOCK);
- mLocationHandler.removeMessages(MESSAGE_RELEASE_WAKE_LOCK);
-
- log("PowerStateBroadcastReceiver: Alarm received");
- Message m = mLocationHandler.obtainMessage(MESSAGE_ACQUIRE_WAKE_LOCK);
- mLocationHandler.sendMessageAtFrontOfQueue(m);
+ synchronized (mLocationListeners) {
+ log("PowerStateBroadcastReceiver: Alarm received");
+ mLocationHandler.removeMessages(MESSAGE_ACQUIRE_WAKE_LOCK);
+ // Have to do this immediately, rather than posting a
+ // message, so we execute our code while the system
+ // is holding a wake lock until the alarm broadcast
+ // is finished.
+ acquireWakeLockLocked();
+ }
} else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
log("PowerStateBroadcastReceiver: Screen off");
- updateWakelockStatus(false);
+ synchronized (mLocationListeners) {
+ updateWakelockStatusLocked(false);
+ }
} else if (action.equals(Intent.ACTION_SCREEN_ON)) {
log("PowerStateBroadcastReceiver: Screen on");
- updateWakelockStatus(true);
+ synchronized (mLocationListeners) {
+ updateWakelockStatusLocked(true);
+ }
} else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
log("PowerStateBroadcastReceiver: Battery changed");
- int scale = intent.getIntExtra(BATTERY_EXTRA_SCALE, 100);
- int level = intent.getIntExtra(BATTERY_EXTRA_LEVEL, 0);
- boolean plugged = intent.getIntExtra(BATTERY_EXTRA_PLUGGED, 0) != 0;
-
- // Notify collector battery state
- if (mCollector != null) {
- mCollector.updateBatteryState(scale, level, plugged);
+ synchronized (mLocationListeners) {
+ int scale = intent.getIntExtra(BATTERY_EXTRA_SCALE, 100);
+ int level = intent.getIntExtra(BATTERY_EXTRA_LEVEL, 0);
+ boolean plugged = intent.getIntExtra(BATTERY_EXTRA_PLUGGED, 0) != 0;
+
+ // Notify collector battery state
+ if (mCollector != null) {
+ mCollector.updateBatteryState(scale, level, plugged);
+ }
+ }
+ } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
+ || action.equals(Intent.ACTION_PACKAGE_RESTARTED)) {
+ synchronized (mLocationListeners) {
+ int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+ if (uid >= 0) {
+ ArrayList<Receiver> removedRecs = null;
+ for (ArrayList<UpdateRecord> i : mRecordsByProvider.values()) {
+ for (int j=i.size()-1; j>=0; j--) {
+ UpdateRecord ur = i.get(j);
+ if (ur.mReceiver.isPendingIntent() && ur.mUid == uid) {
+ if (removedRecs == null) {
+ removedRecs = new ArrayList<Receiver>();
+ }
+ if (!removedRecs.contains(ur.mReceiver)) {
+ removedRecs.add(ur.mReceiver);
+ }
+ }
+ }
+ }
+ ArrayList<ProximityAlert> removedAlerts = null;
+ for (ProximityAlert i : mProximityAlerts.values()) {
+ if (i.mUid == uid) {
+ if (removedAlerts == null) {
+ removedAlerts = new ArrayList<ProximityAlert>();
+ }
+ if (!removedAlerts.contains(i)) {
+ removedAlerts.add(i);
+ }
+ }
+ }
+ if (removedRecs != null) {
+ for (int i=removedRecs.size()-1; i>=0; i--) {
+ removeUpdatesLocked(removedRecs.get(i));
+ }
+ }
+ if (removedAlerts != null) {
+ for (int i=removedAlerts.size()-1; i>=0; i--) {
+ removeProximityAlertLocked(removedAlerts.get(i).mIntent);
+ }
+ }
+ }
}
}
}
@@ -1713,11 +1923,13 @@ public class LocationManagerService extends ILocationManager.Stub
}
// Notify provider and collector of Wifi scan results
- if (mCollector != null) {
- mCollector.updateWifiScanResults(wifiScanResults);
- }
- if (mNetworkLocationInterface != null) {
- mNetworkLocationInterface.updateWifiScanResults(wifiScanResults);
+ synchronized (mLocationListeners) {
+ if (mCollector != null) {
+ mCollector.updateWifiScanResults(wifiScanResults);
+ }
+ if (mNetworkLocationInterface != null) {
+ mNetworkLocationInterface.updateWifiScanResults(wifiScanResults);
+ }
}
} else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
@@ -1730,10 +1942,12 @@ public class LocationManagerService extends ILocationManager.Stub
}
// Notify location providers of current network state
- List<LocationProviderImpl> providers = LocationProviderImpl.getProviders();
- for (LocationProviderImpl provider : providers) {
- if (provider.requiresNetwork()) {
- provider.updateNetworkState(networkState);
+ synchronized (mLocationListeners) {
+ List<LocationProviderImpl> providers = LocationProviderImpl.getProviders();
+ for (LocationProviderImpl provider : providers) {
+ if (provider.requiresNetwork()) {
+ provider.updateNetworkState(networkState);
+ }
}
}
@@ -1751,8 +1965,10 @@ public class LocationManagerService extends ILocationManager.Stub
}
// Notify network provider of current wifi enabled state
- if (mNetworkLocationInterface != null) {
- mNetworkLocationInterface.updateWifiEnabledState(enabled);
+ synchronized (mLocationListeners) {
+ if (mNetworkLocationInterface != null) {
+ mNetworkLocationInterface.updateWifiEnabledState(enabled);
+ }
}
} else if (action.equals(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION)) {
@@ -1760,9 +1976,16 @@ public class LocationManagerService extends ILocationManager.Stub
final boolean enabled = intent.getBooleanExtra(GpsLocationProvider.EXTRA_ENABLED,
false);
- if (!enabled) {
- // When GPS is disabled, we are OK to release wake-lock
- mWakeLockGpsReceived = true;
+ synchronized (mLocationListeners) {
+ if (enabled) {
+ updateReportedGpsLocked();
+ mGpsNavigating = true;
+ } else {
+ reportStopGpsLocked();
+ mGpsNavigating = false;
+ // When GPS is disabled, we are OK to release wake-lock
+ mWakeLockGpsReceived = true;
+ }
}
}
@@ -1771,7 +1994,7 @@ public class LocationManagerService extends ILocationManager.Stub
// Wake locks
- private void updateWakelockStatus(boolean screenOn) {
+ private void updateWakelockStatusLocked(boolean screenOn) {
log("updateWakelockStatus(): " + screenOn);
boolean needsLock = false;
@@ -1786,11 +2009,10 @@ public class LocationManagerService extends ILocationManager.Stub
needsLock = true;
minTime = Math.min(mGpsLocationProvider.getMinTime(), minTime);
if (screenOn) {
- startGps();
+ startGpsLocked();
} else if (mScreenOn && !screenOn) {
-
// We just turned the screen off so stop navigating
- stopGps();
+ stopGpsLocked();
}
}
@@ -1816,13 +2038,13 @@ public class LocationManagerService extends ILocationManager.Stub
// Clear out existing wakelocks
mLocationHandler.removeMessages(MESSAGE_ACQUIRE_WAKE_LOCK);
mLocationHandler.removeMessages(MESSAGE_RELEASE_WAKE_LOCK);
- releaseWakeLock();
+ releaseWakeLockLocked();
}
}
- private void acquireWakeLock() {
+ private void acquireWakeLockLocked() {
try {
- acquireWakeLockX();
+ acquireWakeLockXLocked();
} catch (Exception e) {
// This is to catch a runtime exception thrown when we try to release an
// already released lock.
@@ -1830,7 +2052,7 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private void acquireWakeLockX() {
+ private void acquireWakeLockXLocked() {
if (mWakeLock.isHeld()) {
log("Must release wakelock before acquiring");
mWakeLockAcquireTime = 0;
@@ -1857,7 +2079,7 @@ public class LocationManagerService extends ILocationManager.Stub
log("Acquired wakelock");
// Start the gps provider
- startGps();
+ startGpsLocked();
// Acquire cell lock
if (mCellWakeLockAcquired) {
@@ -1875,7 +2097,7 @@ public class LocationManagerService extends ILocationManager.Stub
}
// Acquire wifi lock
- WifiManager.WifiLock wifiLock = getWifiWakelock();
+ WifiManager.WifiLock wifiLock = getWifiWakelockLocked();
if (wifiLock != null) {
if (mWifiWakeLockAcquired) {
// Lock is already acquired
@@ -1889,41 +2111,104 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private void startGps() {
+ private boolean reportGpsUidLocked(int curSeq, int nextSeq, int uid) {
+ int seq = mReportedGpsUids.get(uid, -1);
+ if (seq == curSeq) {
+ // Already reported; propagate to next sequence.
+ mReportedGpsUids.put(uid, nextSeq);
+ return true;
+ } else if (seq != nextSeq) {
+ try {
+ // New UID; report it.
+ mBatteryStats.noteStartGps(uid);
+ mReportedGpsUids.put(uid, nextSeq);
+ return true;
+ } catch (RemoteException e) {
+ }
+ }
+ return false;
+ }
+
+ private void updateReportedGpsLocked() {
+ if (mGpsLocationProvider == null) {
+ return;
+ }
+
+ final String name = mGpsLocationProvider.getName();
+ final int curSeq = mReportedGpsSeq;
+ final int nextSeq = (curSeq+1) >= 0 ? (curSeq+1) : 0;
+ mReportedGpsSeq = nextSeq;
+
+ ArrayList<UpdateRecord> urs = mRecordsByProvider.get(name);
+ int num = 0;
+ final int N = urs.size();
+ for (int i=0; i<N; i++) {
+ UpdateRecord ur = urs.get(i);
+ if (ur.mReceiver == mProximityListener) {
+ // We don't want the system to take the blame for this one.
+ continue;
+ }
+ if (reportGpsUidLocked(curSeq, nextSeq, ur.mUid)) {
+ num++;
+ }
+ }
+
+ for (ProximityAlert pe : mProximityAlerts.values()) {
+ if (reportGpsUidLocked(curSeq, nextSeq, pe.mUid)) {
+ num++;
+ }
+ }
+
+ if (num != mReportedGpsUids.size()) {
+ // The number of uids is processed is different than the
+ // array; report any that are no longer active.
+ for (int i=mReportedGpsUids.size()-1; i>=0; i--) {
+ if (mReportedGpsUids.valueAt(i) != nextSeq) {
+ try {
+ mBatteryStats.noteStopGps(mReportedGpsUids.keyAt(i));
+ } catch (RemoteException e) {
+ }
+ mReportedGpsUids.removeAt(i);
+ }
+ }
+ }
+ }
+
+ private void reportStopGpsLocked() {
+ int curSeq = mReportedGpsSeq;
+ for (int i=mReportedGpsUids.size()-1; i>=0; i--) {
+ if (mReportedGpsUids.valueAt(i) == curSeq) {
+ try {
+ mBatteryStats.noteStopGps(mReportedGpsUids.keyAt(i));
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ curSeq++;
+ if (curSeq < 0) curSeq = 0;
+ mReportedGpsSeq = curSeq;
+ mReportedGpsUids.clear();
+ }
+
+ private void startGpsLocked() {
boolean gpsActive = (mGpsLocationProvider != null)
&& mGpsLocationProvider.isLocationTracking();
if (gpsActive) {
mGpsLocationProvider.startNavigating();
- long identity = Binder.clearCallingIdentity();
- try {
- mBatteryStats.noteStartGps(mCallingUid == -1 ? getCallingUid() : mCallingUid);
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException calling noteStartGps on BatteryStatsService", e);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
}
}
- private void stopGps() {
+ private void stopGpsLocked() {
boolean gpsActive = mGpsLocationProvider != null
&& mGpsLocationProvider.isLocationTracking();
if (gpsActive) {
mGpsLocationProvider.stopNavigating();
- long identity = Binder.clearCallingIdentity();
- try {
- mBatteryStats.noteStopGps(mCallingUid == -1 ? getCallingUid() : mCallingUid);
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException calling noteStopGps on BatteryStatsService", e);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
}
}
- private void releaseWakeLock() {
+ private void releaseWakeLockLocked() {
try {
- releaseWakeLockX();
+ releaseWakeLockXLocked();
} catch (Exception e) {
// This is to catch a runtime exception thrown when we try to release an
// already released lock.
@@ -1931,9 +2216,9 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private void releaseWakeLockX() {
+ private void releaseWakeLockXLocked() {
// Release wifi lock
- WifiManager.WifiLock wifiLock = getWifiWakelock();
+ WifiManager.WifiLock wifiLock = getWifiWakelockLocked();
if (wifiLock != null) {
if (mWifiWakeLockAcquired) {
wifiLock.release();
@@ -1943,7 +2228,7 @@ public class LocationManagerService extends ILocationManager.Stub
if (!mScreenOn) {
// Stop the gps
- stopGps();
+ stopGpsLocked();
}
// Release cell lock
@@ -1971,11 +2256,13 @@ public class LocationManagerService extends ILocationManager.Stub
public String getFromLocation(double latitude, double longitude, int maxResults,
String language, String country, String variant, String appName, List<Address> addrs) {
- if (mNetworkLocationInterface != null) {
- return mNetworkLocationInterface.getFromLocation(latitude, longitude, maxResults,
- language, country, variant, appName, addrs);
- } else {
- return null;
+ synchronized (mLocationListeners) {
+ if (mNetworkLocationInterface != null) {
+ return mNetworkLocationInterface.getFromLocation(latitude, longitude, maxResults,
+ language, country, variant, appName, addrs);
+ } else {
+ return null;
+ }
}
}
@@ -1983,12 +2270,14 @@ public class LocationManagerService extends ILocationManager.Stub
double lowerLeftLatitude, double lowerLeftLongitude,
double upperRightLatitude, double upperRightLongitude, int maxResults,
String language, String country, String variant, String appName, List<Address> addrs) {
- if (mNetworkLocationInterface != null) {
- return mNetworkLocationInterface.getFromLocationName(locationName, lowerLeftLatitude,
- lowerLeftLongitude, upperRightLatitude, upperRightLongitude, maxResults,
- language, country, variant, appName, addrs);
- } else {
- return null;
+ synchronized (mLocationListeners) {
+ if (mNetworkLocationInterface != null) {
+ return mNetworkLocationInterface.getFromLocationName(locationName, lowerLeftLatitude,
+ lowerLeftLongitude, upperRightLatitude, upperRightLongitude, maxResults,
+ language, country, variant, appName, addrs);
+ } else {
+ return null;
+ }
}
}
@@ -2024,43 +2313,63 @@ public class LocationManagerService extends ILocationManager.Stub
@Override
public void disable() {
String name = getName();
- mEnabledProviders.remove(name);
- mDisabledProviders.add(name);
+ // We shouldn't normally need to lock, since this should only be called
+ // by the service with the lock held, but let's be paranid.
+ synchronized (mLocationListeners) {
+ mEnabledProviders.remove(name);
+ mDisabledProviders.add(name);
+ }
}
@Override
public void enable() {
String name = getName();
- mEnabledProviders.add(name);
- mDisabledProviders.remove(name);
+ // We shouldn't normally need to lock, since this should only be called
+ // by the service with the lock held, but let's be paranid.
+ synchronized (mLocationListeners) {
+ mEnabledProviders.add(name);
+ mDisabledProviders.remove(name);
+ }
}
@Override
public boolean getLocation(Location l) {
- Location loc = mMockProviderLocation.get(getName());
- if (loc == null) {
- return false;
+ // We shouldn't normally need to lock, since this should only be called
+ // by the service with the lock held, but let's be paranid.
+ synchronized (mLocationListeners) {
+ Location loc = mMockProviderLocation.get(getName());
+ if (loc == null) {
+ return false;
+ }
+ l.set(loc);
+ return true;
}
- l.set(loc);
- return true;
}
@Override
public int getStatus(Bundle extras) {
- String name = getName();
- Integer s = mMockProviderStatus.get(name);
- int status = (s == null) ? AVAILABLE : s.intValue();
- Bundle newExtras = mMockProviderStatusExtras.get(name);
- if (newExtras != null) {
- extras.clear();
- extras.putAll(newExtras);
+ // We shouldn't normally need to lock, since this should only be called
+ // by the service with the lock held, but let's be paranid.
+ synchronized (mLocationListeners) {
+ String name = getName();
+ Integer s = mMockProviderStatus.get(name);
+ int status = (s == null) ? AVAILABLE : s.intValue();
+ Bundle newExtras = mMockProviderStatusExtras.get(name);
+ if (newExtras != null) {
+ extras.clear();
+ extras.putAll(newExtras);
+ }
+ return status;
}
- return status;
}
@Override
public boolean isEnabled() {
- return mEnabledProviders.contains(getName());
+ // We shouldn't normally need to lock, since this should only be called
+ // by the service with the lock held, but let's be paranid.
+ synchronized (mLocationListeners) {
+ return mEnabledProviders.contains(getName());
+ }
}
@Override
@@ -2109,14 +2418,9 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
- private void checkMockPermissions() {
- boolean allowMocks = false;
- try {
- allowMocks = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.ALLOW_MOCK_LOCATION) == 1;
- } catch (SettingNotFoundException e) {
- // Do nothing
- }
+ private void checkMockPermissionsSafe() {
+ boolean allowMocks = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 1;
if (!allowMocks) {
throw new SecurityException("Requires ACCESS_MOCK_LOCATION secure setting");
}
@@ -2130,87 +2434,103 @@ public class LocationManagerService extends ILocationManager.Stub
public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite,
boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
- checkMockPermissions();
-
- MockProvider provider = new MockProvider(name, requiresNetwork, requiresSatellite,
- requiresCell, hasMonetaryCost, supportsAltitude,
- supportsSpeed, supportsBearing, powerRequirement, accuracy);
- if (LocationProviderImpl.getProvider(name) != null) {
- throw new IllegalArgumentException("Provider \"" + name + "\" already exists");
+ checkMockPermissionsSafe();
+
+ synchronized (mLocationListeners) {
+ MockProvider provider = new MockProvider(name, requiresNetwork, requiresSatellite,
+ requiresCell, hasMonetaryCost, supportsAltitude,
+ supportsSpeed, supportsBearing, powerRequirement, accuracy);
+ if (LocationProviderImpl.getProvider(name) != null) {
+ throw new IllegalArgumentException("Provider \"" + name + "\" already exists");
+ }
+ LocationProviderImpl.addProvider(provider);
+ updateProvidersLocked();
}
- LocationProviderImpl.addProvider(provider);
- updateProviders();
}
public void removeTestProvider(String provider) {
- checkMockPermissions();
- LocationProviderImpl p = LocationProviderImpl.getProvider(provider);
- if (p == null) {
- throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
+ checkMockPermissionsSafe();
+ synchronized (mLocationListeners) {
+ LocationProviderImpl p = LocationProviderImpl.getProvider(provider);
+ if (p == null) {
+ throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
+ }
+ LocationProviderImpl.removeProvider(p);
+ updateProvidersLocked();
}
- LocationProviderImpl.removeProvider(p);
- updateProviders();
}
public void setTestProviderLocation(String provider, Location loc) {
- checkMockPermissions();
- if (LocationProviderImpl.getProvider(provider) == null) {
- throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
+ checkMockPermissionsSafe();
+ synchronized (mLocationListeners) {
+ if (LocationProviderImpl.getProvider(provider) == null) {
+ throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
+ }
+ mMockProviderLocation.put(provider, loc);
}
- mMockProviderLocation.put(provider, loc);
}
public void clearTestProviderLocation(String provider) {
- checkMockPermissions();
- if (LocationProviderImpl.getProvider(provider) == null) {
- throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
+ checkMockPermissionsSafe();
+ synchronized (mLocationListeners) {
+ if (LocationProviderImpl.getProvider(provider) == null) {
+ throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
+ }
+ mMockProviderLocation.remove(provider);
}
- mMockProviderLocation.remove(provider);
}
public void setTestProviderEnabled(String provider, boolean enabled) {
- checkMockPermissions();
- if (LocationProviderImpl.getProvider(provider) == null) {
- throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
- }
- if (enabled) {
- mEnabledProviders.add(provider);
- mDisabledProviders.remove(provider);
- } else {
- mEnabledProviders.remove(provider);
- mDisabledProviders.add(provider);
+ checkMockPermissionsSafe();
+ synchronized (mLocationListeners) {
+ if (LocationProviderImpl.getProvider(provider) == null) {
+ throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
+ }
+ if (enabled) {
+ mEnabledProviders.add(provider);
+ mDisabledProviders.remove(provider);
+ } else {
+ mEnabledProviders.remove(provider);
+ mDisabledProviders.add(provider);
+ }
+ updateProvidersLocked();
}
- updateProviders();
}
public void clearTestProviderEnabled(String provider) {
- checkMockPermissions();
- if (LocationProviderImpl.getProvider(provider) == null) {
- throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
+ checkMockPermissionsSafe();
+ synchronized (mLocationListeners) {
+ if (LocationProviderImpl.getProvider(provider) == null) {
+ throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
+ }
+ mEnabledProviders.remove(provider);
+ mDisabledProviders.remove(provider);
+ updateProvidersLocked();
}
- mEnabledProviders.remove(provider);
- mDisabledProviders.remove(provider);
- updateProviders();
}
public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) {
- checkMockPermissions();
- if (LocationProviderImpl.getProvider(provider) == null) {
- throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
+ checkMockPermissionsSafe();
+ synchronized (mLocationListeners) {
+ if (LocationProviderImpl.getProvider(provider) == null) {
+ throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
+ }
+ mMockProviderStatus.put(provider, new Integer(status));
+ mMockProviderStatusExtras.put(provider, extras);
+ mMockProviderStatusUpdateTime.put(provider, new Long(updateTime));
}
- mMockProviderStatus.put(provider, new Integer(status));
- mMockProviderStatusExtras.put(provider, extras);
- mMockProviderStatusUpdateTime.put(provider, new Long(updateTime));
}
public void clearTestProviderStatus(String provider) {
- checkMockPermissions();
- if (LocationProviderImpl.getProvider(provider) == null) {
- throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
+ checkMockPermissionsSafe();
+ synchronized (mLocationListeners) {
+ if (LocationProviderImpl.getProvider(provider) == null) {
+ throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
+ }
+ mMockProviderStatus.remove(provider);
+ mMockProviderStatusExtras.remove(provider);
+ mMockProviderStatusUpdateTime.remove(provider);
}
- mMockProviderStatus.remove(provider);
- mMockProviderStatusExtras.remove(provider);
- mMockProviderStatusUpdateTime.remove(provider);
}
private void log(String log) {
@@ -2218,5 +2538,154 @@ public class LocationManagerService extends ILocationManager.Stub
Log.d(TAG, log);
}
}
+
+ protected 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 AlarmManager from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+
+ synchronized (mLocationListeners) {
+ pw.println("Current Location Manager state:");
+ pw.println(" sProvidersLoaded=" + sProvidersLoaded);
+ pw.println(" mGpsLocationProvider=" + mGpsLocationProvider);
+ pw.println(" mGpsNavigating=" + mGpsNavigating);
+ pw.println(" mNetworkLocationProvider=" + mNetworkLocationProvider);
+ pw.println(" mNetworkLocationInterface=" + mNetworkLocationInterface);
+ pw.println(" mCollector=" + mCollector);
+ pw.println(" mSignalStrength=" + mSignalStrength);
+ pw.println(" mAlarmInterval=" + mAlarmInterval
+ + " mScreenOn=" + mScreenOn
+ + " mWakeLockAcquireTime=" + mWakeLockAcquireTime);
+ pw.println(" mWakeLockGpsReceived=" + mWakeLockGpsReceived
+ + " mWakeLockNetworkReceived=" + mWakeLockNetworkReceived);
+ pw.println(" mWifiWakeLockAcquired=" + mWifiWakeLockAcquired
+ + " mCellWakeLockAcquired=" + mCellWakeLockAcquired);
+ pw.println(" Listeners:");
+ int N = mListeners.size();
+ for (int i=0; i<N; i++) {
+ pw.println(" " + mListeners.get(i));
+ }
+ pw.println(" Location Listeners:");
+ for (Map.Entry<Receiver, HashMap<String,UpdateRecord>> i
+ : mLocationListeners.entrySet()) {
+ pw.println(" " + i.getKey() + ":");
+ for (Map.Entry<String,UpdateRecord> j : i.getValue().entrySet()) {
+ pw.println(" " + j.getKey() + ":");
+ j.getValue().dump(pw, " ");
+ }
+ }
+ pw.println(" Last Fix Broadcasts:");
+ for (Map.Entry<Receiver, HashMap<String,Location>> i
+ : mLastFixBroadcast.entrySet()) {
+ pw.println(" " + i.getKey() + ":");
+ for (Map.Entry<String,Location> j : i.getValue().entrySet()) {
+ pw.println(" " + j.getKey() + ":");
+ j.getValue().dump(new PrintWriterPrinter(pw), " ");
+ }
+ }
+ pw.println(" Last Status Broadcasts:");
+ for (Map.Entry<Receiver, HashMap<String,Long>> i
+ : mLastStatusBroadcast.entrySet()) {
+ pw.println(" " + i.getKey() + ":");
+ for (Map.Entry<String,Long> j : i.getValue().entrySet()) {
+ pw.println(" " + j.getKey() + " -> 0x"
+ + Long.toHexString(j.getValue()));
+ }
+ }
+ pw.println(" Records by Provider:");
+ for (Map.Entry<String, ArrayList<UpdateRecord>> i
+ : mRecordsByProvider.entrySet()) {
+ pw.println(" " + i.getKey() + ":");
+ for (UpdateRecord j : i.getValue()) {
+ pw.println(" " + j + ":");
+ j.dump(pw, " ");
+ }
+ }
+ pw.println(" Locations by Provider:");
+ for (Map.Entry<String, Location> i
+ : mLocationsByProvider.entrySet()) {
+ pw.println(" " + i.getKey() + ":");
+ i.getValue().dump(new PrintWriterPrinter(pw), " ");
+ }
+ pw.println(" Last Known Locations:");
+ for (Map.Entry<String, Location> i
+ : mLastKnownLocation.entrySet()) {
+ pw.println(" " + i.getKey() + ":");
+ i.getValue().dump(new PrintWriterPrinter(pw), " ");
+ }
+ if (mProximityAlerts.size() > 0) {
+ pw.println(" Proximity Alerts:");
+ for (Map.Entry<PendingIntent, ProximityAlert> i
+ : mProximityAlerts.entrySet()) {
+ pw.println(" " + i.getKey() + ":");
+ i.getValue().dump(pw, " ");
+ }
+ }
+ if (mProximitiesEntered.size() > 0) {
+ pw.println(" Proximities Entered:");
+ for (ProximityAlert i : mProximitiesEntered) {
+ pw.println(" " + i + ":");
+ i.dump(pw, " ");
+ }
+ }
+ pw.println(" mProximityListener=" + mProximityListener);
+ if (mEnabledProviders.size() > 0) {
+ pw.println(" Enabled Providers:");
+ for (String i : mEnabledProviders) {
+ pw.println(" " + i);
+ }
+
+ }
+ if (mDisabledProviders.size() > 0) {
+ pw.println(" Disabled Providers:");
+ for (String i : mDisabledProviders) {
+ pw.println(" " + i);
+ }
+
+ }
+ if (mMockProviders.size() > 0) {
+ pw.println(" Mock Providers:");
+ for (Map.Entry<String, MockProvider> i : mMockProviders.entrySet()) {
+ pw.println(" " + i.getKey() + " -> " + i.getValue());
+ }
+ }
+ if (mMockProviderLocation.size() > 0) {
+ pw.println(" Mock Provider Location:");
+ for (Map.Entry<String, Location> i : mMockProviderLocation.entrySet()) {
+ pw.println(" " + i.getKey() + ":");
+ i.getValue().dump(new PrintWriterPrinter(pw), " ");
+ }
+ }
+ if (mMockProviderStatus.size() > 0) {
+ pw.println(" Mock Provider Status:");
+ for (Map.Entry<String, Integer> i : mMockProviderStatus.entrySet()) {
+ pw.println(" " + i.getKey() + " -> 0x"
+ + Integer.toHexString(i.getValue()));
+ }
+ }
+ if (mMockProviderStatusExtras.size() > 0) {
+ pw.println(" Mock Provider Status Extras:");
+ for (Map.Entry<String, Bundle> i : mMockProviderStatusExtras.entrySet()) {
+ pw.println(" " + i.getKey() + " -> " + i.getValue());
+ }
+ }
+ if (mMockProviderStatusUpdateTime.size() > 0) {
+ pw.println(" Mock Provider Status Update Time:");
+ for (Map.Entry<String, Long> i : mMockProviderStatusUpdateTime.entrySet()) {
+ pw.println(" " + i.getKey() + " -> " + i.getValue());
+ }
+ }
+ pw.println(" Reported GPS UIDs @ seq " + mReportedGpsSeq + ":");
+ N = mReportedGpsUids.size();
+ for (int i=0; i<N; i++) {
+ pw.println(" UID " + mReportedGpsUids.keyAt(i)
+ + " seq=" + mReportedGpsUids.valueAt(i));
+ }
+ }
+ }
}
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 6974b5e..16b5819 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -182,6 +182,7 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
private long mScreenOnTime;
private long mScreenOnStartTime;
private boolean mPreventScreenOn;
+ private int mScreenBrightnessOverride = -1;
// Used when logging number and duration of touch-down cycles
private long mTotalTouchDownTime;
@@ -245,7 +246,8 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
public void acquire() {
if (!mRefCounted || mCount++ == 0) {
- PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken, mTag);
+ PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken,
+ MY_UID, mTag);
}
}
@@ -486,17 +488,18 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
public void acquireWakeLock(int flags, IBinder lock, String tag) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
+ int uid = Binder.getCallingUid();
long ident = Binder.clearCallingIdentity();
try {
synchronized (mLocks) {
- acquireWakeLockLocked(flags, lock, tag);
+ acquireWakeLockLocked(flags, lock, uid, tag);
}
} finally {
Binder.restoreCallingIdentity(ident);
}
}
- public void acquireWakeLockLocked(int flags, IBinder lock, String tag) {
+ public void acquireWakeLockLocked(int flags, IBinder lock, int uid, String tag) {
int acquireUid = -1;
String acquireName = null;
int acquireType = -1;
@@ -509,7 +512,7 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
WakeLock wl;
boolean newlock;
if (index < 0) {
- wl = new WakeLock(flags, lock, tag, Binder.getCallingUid());
+ wl = new WakeLock(flags, lock, tag, uid);
switch (wl.flags & LOCK_MASK)
{
case PowerManager.FULL_WAKE_LOCK:
@@ -577,13 +580,10 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
}
if (acquireType >= 0) {
- long origId = Binder.clearCallingIdentity();
try {
mBatteryStats.noteStartWakelock(acquireUid, acquireName, acquireType);
} catch (RemoteException e) {
// Ignore
- } finally {
- Binder.restoreCallingIdentity(origId);
}
}
}
@@ -797,6 +797,8 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
+ " mUserActivityAllowed=" + mUserActivityAllowed);
pw.println(" mKeylightDelay=" + mKeylightDelay + " mDimDelay=" + mDimDelay
+ " mScreenOffDelay=" + mScreenOffDelay);
+ pw.println(" mPreventScreenOn=" + mPreventScreenOn
+ + " mScreenBrightnessOverride=" + mScreenBrightnessOverride);
pw.println(" mTotalDelaySetting=" + mTotalDelaySetting);
pw.println(" mBroadcastWakeLock=" + mBroadcastWakeLock);
pw.println(" mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock);
@@ -1077,7 +1079,6 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
* lock (rather than an IPowerManager call).
*/
public void preventScreenOn(boolean prevent) {
- // TODO: use a totally new permission (separate from DEVICE_POWER) for this?
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
synchronized (mLocks) {
@@ -1126,6 +1127,17 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
}
}
+ public void setScreenBrightnessOverride(int brightness) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+
+ synchronized (mLocks) {
+ if (mScreenBrightnessOverride != brightness) {
+ mScreenBrightnessOverride = brightness;
+ updateLightsLocked(mPowerState, SCREEN_ON_BIT);
+ }
+ }
+ }
+
/**
* Sanity-check that gets called 5 seconds after any call to
* preventScreenOn(true). This ensures that the original call
@@ -1211,7 +1223,7 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
}
if (mPowerState != newState) {
- err = updateLightsLocked(newState, becauseOfUser);
+ err = updateLightsLocked(newState, 0);
if (err != 0) {
return;
}
@@ -1294,6 +1306,15 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
mScreenOnTime += SystemClock.elapsedRealtime() - mScreenOnStartTime;
mScreenOnStartTime = 0;
if (err == 0) {
+ //
+ // FIXME(joeo)
+ //
+ // The problem that causes the screen not to come on is that this isn't
+ // called until after the animation is done. It needs to be set right
+ // away, and the anmiation's state needs to be recorded separately.
+ //
+ //
+
mPowerState &= ~SCREEN_ON_BIT;
int why = becauseOfUser
? WindowManagerPolicy.OFF_BECAUSE_OF_USER
@@ -1310,9 +1331,9 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
mBatteryService.getBatteryLevel() <= Power.LOW_BATTERY_THRESHOLD);
}
- private int updateLightsLocked(int newState, boolean becauseOfUser) {
+ private int updateLightsLocked(int newState, int forceState) {
int oldState = mPowerState;
- int difference = newState ^ oldState;
+ int difference = (newState ^ oldState) | forceState;
if (difference == 0) {
return 0;
}
@@ -1544,6 +1565,9 @@ class PowerManagerService extends IPowerManager.Stub implements LocalPowerManage
private int getPreferredBrightness() {
try {
+ if (mScreenBrightnessOverride >= 0) {
+ return mScreenBrightnessOverride;
+ }
final int brightness = Settings.System.getInt(mContext.getContentResolver(),
SCREEN_BRIGHTNESS);
// Don't let applications turn the screen all the way off
diff --git a/services/java/com/android/server/SensorService.java b/services/java/com/android/server/SensorService.java
index 461b006..29b45ab 100644
--- a/services/java/com/android/server/SensorService.java
+++ b/services/java/com/android/server/SensorService.java
@@ -113,9 +113,9 @@ class SensorService extends ISensorService.Stub {
int uid = Binder.getCallingUid();
long identity = Binder.clearCallingIdentity();
if (enable == SENSOR_DISABLE) {
- mBatteryStats.noteStopSensor(uid, name, sensor);
+ mBatteryStats.noteStopSensor(uid, sensor);
} else {
- mBatteryStats.noteStartSensor(uid, name, sensor);
+ mBatteryStats.noteStartSensor(uid, sensor);
}
Binder.restoreCallingIdentity(identity);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index d624573..fc25e38 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -181,6 +181,7 @@ class ServerThread extends Thread {
StatusBarService statusBar = null;
InputMethodManagerService imm = null;
+ GadgetService gadget = null;
if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
try {
@@ -309,7 +310,8 @@ class ServerThread extends Thread {
try {
Log.i(TAG, "Starting Gadget Service");
- ServiceManager.addService(Context.GADGET_SERVICE, new GadgetService(context));
+ gadget = new GadgetService(context);
+ ServiceManager.addService(Context.GADGET_SERVICE, gadget);
} catch (Throwable e) {
Log.e(TAG, "Failure starting Gadget Service", e);
}
@@ -337,6 +339,9 @@ class ServerThread extends Thread {
pm.systemReady();
} catch (RemoteException e) {
}
+ if (gadget != null) {
+ gadget.systemReady(safeMode);
+ }
// After making the following code, third party code may be running...
try {
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index fed6d12..fc22bad 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -66,6 +66,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
+import android.os.Power;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
@@ -326,6 +327,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
long mFreezeGcPending = 0;
int mAppsFreezingScreen = 0;
+ // This is held as long as we have the screen frozen, to give us time to
+ // perform a rotation animation when turning off shows the lock screen which
+ // changes the orientation.
+ PowerManager.WakeLock mScreenFrozenLock;
+
// State management of app transitions. When we are preparing for a
// transition, mNextAppTransition will be the kind of transition to
// perform or TRANSIT_NONE if we are not waiting. If we are waiting,
@@ -351,6 +357,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// This just indicates the window the input method is on top of, not
// necessarily the window its input is going to.
WindowState mInputMethodTarget = null;
+ WindowState mUpcomingInputMethodTarget = null;
boolean mInputMethodTargetWaitingAnim;
int mInputMethodAnimLayerAdjustment;
@@ -472,6 +479,10 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mPowerManager = pm;
mPowerManager.setPolicy(mPolicy);
+ PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+ mScreenFrozenLock = pmc.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+ "SCREEN_FROZEN");
+ mScreenFrozenLock.setReferenceCounted(false);
mActivityManager = ActivityManagerNative.getDefault();
mBatteryStats = BatteryStatsService.getService();
@@ -742,6 +753,15 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
}
}
+ static boolean canBeImeTarget(WindowState w) {
+ final int fl = w.mAttrs.flags
+ & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
+ if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
+ return w.isVisibleOrAdding();
+ }
+ return false;
+ }
+
int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
final ArrayList localmWindows = mWindows;
final int N = localmWindows.size();
@@ -750,18 +770,32 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
while (i > 0) {
i--;
w = (WindowState)localmWindows.get(i);
- final int fl = w.mAttrs.flags
- & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
+
//Log.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
- // + Integer.toHexString(fl));
- if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM)) {
+ // + Integer.toHexString(w.mAttrs.flags));
+ if (canBeImeTarget(w)) {
//Log.i(TAG, "Putting input method here!");
- if (w.isVisibleOrAdding()) {
- break;
+
+ // Yet more tricksyness! If this window is a "starting"
+ // window, we do actually want to be on top of it, but
+ // it is not -really- where input will go. So if the caller
+ // is not actually looking to move the IME, look down below
+ // for a real window to target...
+ if (!willMove
+ && w.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
+ && i > 0) {
+ WindowState wb = (WindowState)localmWindows.get(i-1);
+ if (wb.mAppToken == w.mAppToken && canBeImeTarget(wb)) {
+ i--;
+ w = wb;
+ }
}
+ break;
}
}
+ mUpcomingInputMethodTarget = w;
+
if (DEBUG_INPUT_METHOD) Log.v(TAG, "Desired input method target="
+ w + " willMove=" + willMove);
@@ -1209,8 +1243,6 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
addWindowToListInOrderLocked(win, true);
}
- Binder.restoreCallingIdentity(origId);
-
win.mEnterAnimationPending = true;
mPolicy.getContentInsetHintLw(attrs, outContentInsets);
@@ -1542,6 +1574,11 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
&& !win.mCommitDrawPending && !mDisplayFrozen) {
applyEnterAnimationLocked(win);
}
+ if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
+ // To change the format, we need to re-build the surface.
+ win.destroySurfaceLocked();
+ displayed = true;
+ }
try {
Surface surface = win.createSurfaceLocked();
if (surface != null) {
@@ -7169,11 +7206,14 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// The focus for the client is the window immediately below
// where we would place the input method window.
int idx = findDesiredInputMethodWindowIndexLocked(false);
+ WindowState imFocus;
if (idx > 0) {
- WindowState imFocus = (WindowState)mWindows.get(idx-1);
- if (imFocus != null && imFocus.mSession.mClient != null &&
- imFocus.mSession.mClient.asBinder() == client.asBinder()) {
- return true;
+ imFocus = (WindowState)mWindows.get(idx-1);
+ if (imFocus != null) {
+ if (imFocus.mSession.mClient != null &&
+ imFocus.mSession.mClient.asBinder() == client.asBinder()) {
+ return true;
+ }
}
}
}
@@ -7393,6 +7433,7 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
boolean orientationChangeComplete = true;
Session holdScreen = null;
+ float screenBrightness = -1;
boolean focusDisplayed = false;
boolean animating = false;
@@ -7622,7 +7663,6 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
boolean blurring = false;
boolean dimming = false;
boolean covered = false;
- int tint = 0;
for (i=N-1; i>=0; i--) {
WindowState w = (WindowState)mWindows.get(i);
@@ -7878,9 +7918,13 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
// Update effect.
if (!obscured) {
- if (w.mSurface != null &&
- (attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
- holdScreen = w.mSession;
+ if (w.mSurface != null) {
+ if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
+ holdScreen = w.mSession;
+ }
+ if (w.mAttrs.screenBrightness >= 0 && screenBrightness < 0) {
+ screenBrightness = w.mAttrs.screenBrightness;
+ }
}
if (w.isFullscreenOpaque(dw, dh)) {
// This window completely covers everything behind it,
@@ -8122,6 +8166,12 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
requestAnimationLocked(currentTime+(1000/60)-SystemClock.uptimeMillis());
}
mQueue.setHoldScreenLocked(holdScreen != null);
+ if (screenBrightness < 0 || screenBrightness > 1.0f) {
+ mPowerManager.setScreenBrightnessOverride(-1);
+ } else {
+ mPowerManager.setScreenBrightnessOverride((int)
+ (screenBrightness * Power.BRIGHTNESS_ON));
+ }
if (holdScreen != mHoldingScreenOn) {
mHoldingScreenOn = holdScreen;
Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, holdScreen);
@@ -8354,6 +8404,8 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
return;
}
+ mScreenFrozenLock.acquire();
+
long now = SystemClock.uptimeMillis();
//Log.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
if (mFreezeGcPending != 0) {
@@ -8409,6 +8461,8 @@ public class WindowManagerService extends IWindowManager.Stub implements Watchdo
mH.removeMessages(H.FORCE_GC);
mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
2000);
+
+ mScreenFrozenLock.release();
}
@Override
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index e391da3..6443d53 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -204,6 +204,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
*/
static final int LAUNCH_TIMEOUT = 10*1000;
+ // How long we wait for a launched process to attach to the activity manager
+ // before we decide it's never going to come up for real.
+ static final int PROC_START_TIMEOUT = 10*1000;
+
// How long we wait until giving up on the last activity telling us it
// is idle.
static final int IDLE_TIMEOUT = 10*1000;
@@ -811,6 +815,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
static final int DESTROY_TIMEOUT_MSG = 17;
static final int SERVICE_ERROR_MSG = 18;
static final int RESUME_TOP_ACTIVITY_MSG = 19;
+ static final int PROC_START_TIMEOUT_MSG = 20;
AlertDialog mUidAlert;
@@ -852,12 +857,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
} break;
case SHOW_NOT_RESPONDING_MSG: {
- HashMap data = (HashMap) msg.obj;
- // This needs to be *un*synchronized to avoid deadlock.
- Checkin.logEvent(mContext.getContentResolver(),
- Checkin.Events.Tag.SYSTEM_APP_NOT_RESPONDING,
- (String)data.get("info"));
synchronized (ActivityManagerService.this) {
+ HashMap data = (HashMap) msg.obj;
ProcessRecord proc = (ProcessRecord)data.get("app");
if (proc != null && proc.anrDialog != null) {
Log.e(TAG, "App already has anr dialog: " + proc);
@@ -993,6 +994,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
resumeTopActivityLocked(null);
}
}
+ case PROC_START_TIMEOUT_MSG: {
+ ProcessRecord app = (ProcessRecord)msg.obj;
+ synchronized (ActivityManagerService.this) {
+ processStartTimedOutLocked(app);
+ }
+ }
}
}
};
@@ -1685,6 +1692,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
if (app.pid > 0 && app.pid != MY_PID) {
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.remove(app.pid);
+ mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
}
app.pid = 0;
}
@@ -1777,6 +1785,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
app.removed = false;
synchronized (mPidsSelfLocked) {
this.mPidsSelfLocked.put(pid, app);
+ Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
+ msg.obj = app;
+ mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
}
} else {
app.pid = 0;
@@ -4033,9 +4044,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
info.append("\nCPU usage:\n");
info.append(processInfo);
}
- info.append("\n/proc/meminfo:\n");
- info.append(readFile("/proc/meminfo"));
-
Log.i(TAG, info.toString());
// The application is not responding. Dump as many thread traces as we can.
@@ -4087,7 +4095,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
msg.what = SHOW_NOT_RESPONDING_MSG;
msg.obj = map;
map.put("app", app);
- map.put("info", info.toString());
if (activity != null) {
map.put("activity", activity);
}
@@ -4390,6 +4397,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
int pid = app.pid;
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.remove(pid);
+ mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
}
handleAppDiedLocked(app, true);
mLRUProcesses.remove(app);
@@ -4409,6 +4417,31 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
return needRestart;
}
+ private final void processStartTimedOutLocked(ProcessRecord app) {
+ final int pid = app.pid;
+ boolean gone = false;
+ synchronized (mPidsSelfLocked) {
+ ProcessRecord knownApp = mPidsSelfLocked.get(pid);
+ if (knownApp != null && knownApp.thread == null) {
+ mPidsSelfLocked.remove(pid);
+ gone = true;
+ }
+ }
+
+ if (gone) {
+ Log.w(TAG, "Process " + app + " failed to attach");
+ mProcessNames.remove(app.processName, app.info.uid);
+ Process.killProcess(pid);
+ if (mPendingBroadcast.curApp.pid == pid) {
+ Log.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
+ mPendingBroadcast = null;
+ scheduleBroadcastsLocked();
+ }
+ } else {
+ Log.w(TAG, "Spurious process start timeout - pid not known for " + app);
+ }
+ }
+
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
@@ -4472,6 +4505,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
app.foregroundServices = false;
app.debugging = false;
+ mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
+
List providers = generateApplicationProvidersLocked(app);
if (localLOGV) Log.v(
@@ -8630,6 +8665,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
// Goodbye!
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.remove(app.pid);
+ mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
}
app.pid = 0;
}
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index 1cd6298..9ba1198 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -22,8 +22,10 @@ import com.android.internal.os.BatteryStatsImpl;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
+import android.os.Parcel;
import android.os.Process;
import android.os.ServiceManager;
+import android.util.PrintWriterPrinter;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -58,16 +60,25 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
/**
* @return the current statistics object, which may be modified
- * to reflect events that affect battery usage.
+ * to reflect events that affect battery usage. You must lock the
+ * stats object before doing anything with it.
*/
public BatteryStatsImpl getActiveStatistics() {
return mStats;
}
- public BatteryStatsImpl getStatistics() {
+ public byte[] getStatistics() {
mContext.enforceCallingPermission(
android.Manifest.permission.BATTERY_STATS, null);
- return mStats;
+ synchronized (mStats) {
+ //Log.i("foo", "SENDING BATTERY INFO:");
+ //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo"));
+ Parcel out = Parcel.obtain();
+ mStats.writeToParcel(out, 0);
+ byte[] data = out.marshall();
+ out.recycle();
+ return data;
+ }
}
public void noteStartWakelock(int uid, String name, int type) {
@@ -84,17 +95,17 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
}
}
- public void noteStartSensor(int uid, String name, int sensor) {
+ public void noteStartSensor(int uid, int sensor) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.getUidStatsLocked(uid).noteStartSensor(name, sensor);
+ mStats.getUidStatsLocked(uid).noteStartSensor(sensor);
}
}
- public void noteStopSensor(int uid, String name, int sensor) {
+ public void noteStopSensor(int uid, int sensor) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.getUidStatsLocked(uid).noteStopSensor(name, sensor);
+ mStats.getUidStatsLocked(uid).noteStopSensor(sensor);
}
}
@@ -111,32 +122,18 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
mStats.noteStopGps(uid);
}
}
-
- public void noteRequestGpsOn(int uid) {
- enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteRequestGpsOn(uid);
- }
- }
-
- public void noteRequestGpsOff(int uid) {
- enforceCallingPermission();
- synchronized (mStats) {
- mStats.noteRequestGpsOff(uid);
- }
- }
-
+
public void noteScreenOn() {
enforceCallingPermission();
synchronized (mStats) {
- mStats.noteScreenOn();
+ mStats.noteScreenOnLocked();
}
}
public void noteScreenOff() {
enforceCallingPermission();
synchronized (mStats) {
- mStats.noteScreenOff();
+ mStats.noteScreenOffLocked();
}
}
@@ -171,8 +168,18 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- synchronized (this) {
- mStats.dumpLocked(fd, pw, args);
+ synchronized (mStats) {
+ boolean isCheckin = false;
+ if (args != null) {
+ for (String arg : args) {
+ if ("-c".equals(arg)) {
+ isCheckin = true;
+ break;
+ }
+ }
+ }
+ if (isCheckin) mStats.dumpCheckinLocked(pw, args);
+ else mStats.dumpLocked(new PrintWriterPrinter(pw));
}
}
}
diff --git a/services/java/com/android/server/status/AnimatedImageView.java b/services/java/com/android/server/status/AnimatedImageView.java
index 36492da..cd581c4 100644
--- a/services/java/com/android/server/status/AnimatedImageView.java
+++ b/services/java/com/android/server/status/AnimatedImageView.java
@@ -42,6 +42,7 @@ public class AnimatedImageView extends ImageView {
}
@Override
+ @android.view.RemotableViewMethod
public void setImageResource(int resid) {
super.setImageResource(resid);
updateAnim();
diff --git a/services/java/com/android/server/status/StatusBarService.java b/services/java/com/android/server/status/StatusBarService.java
index a4844b1..4748389 100644
--- a/services/java/com/android/server/status/StatusBarService.java
+++ b/services/java/com/android/server/status/StatusBarService.java
@@ -27,6 +27,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
@@ -1326,80 +1327,89 @@ public class StatusBarService extends IStatusBar.Stub
}
protected 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 StatusBar from from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+
synchronized (mQueue) {
- pw.println("mExpanded=" + mExpanded
+ pw.println("Current Status Bar state:");
+ pw.println(" mExpanded=" + mExpanded
+ ", mExpandedVisible=" + mExpandedVisible);
- pw.println("mTicking=" + mTicking);
- pw.println("mTracking=" + mTracking);
- pw.println("mAnimating=" + mAnimating
+ pw.println(" mTicking=" + mTicking);
+ pw.println(" mTracking=" + mTracking);
+ pw.println(" mAnimating=" + mAnimating
+ ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel
+ ", mAnimAccel=" + mAnimAccel);
- pw.println("mCurAnimationTime=" + mCurAnimationTime
+ pw.println(" mCurAnimationTime=" + mCurAnimationTime
+ " mAnimLastTime=" + mAnimLastTime);
- pw.println("mDisplayHeight=" + mDisplayHeight
+ pw.println(" mDisplayHeight=" + mDisplayHeight
+ " mAnimatingReveal=" + mAnimatingReveal
+ " mViewDelta=" + mViewDelta);
- pw.println("mDisplayHeight=" + mDisplayHeight);
+ pw.println(" mDisplayHeight=" + mDisplayHeight);
final int N = mQueue.size();
- pw.println("mQueue.size=" + N);
+ pw.println(" mQueue.size=" + N);
for (int i=0; i<N; i++) {
PendingOp op = mQueue.get(i);
- pw.println(" [" + i + "] key=" + op.key + " code=" + op.code + " visible="
+ pw.println(" [" + i + "] key=" + op.key + " code=" + op.code + " visible="
+ op.visible);
- pw.println(" iconData=" + op.iconData);
- pw.println(" notificationData=" + op.notificationData);
+ pw.println(" iconData=" + op.iconData);
+ pw.println(" notificationData=" + op.notificationData);
}
- pw.println("mExpandedParams: " + mExpandedParams);
- pw.println("mExpandedView: " + viewInfo(mExpandedView));
- pw.println("mExpandedDialog: " + mExpandedDialog);
- pw.println("mTrackingParams: " + mTrackingParams);
- pw.println("mTrackingView: " + viewInfo(mTrackingView));
- pw.println("mOngoingTitle: " + viewInfo(mOngoingTitle));
- pw.println("mOngoingItems: " + viewInfo(mOngoingItems));
- pw.println("mLatestTitle: " + viewInfo(mLatestTitle));
- pw.println("mLatestItems: " + viewInfo(mLatestItems));
- pw.println("mNoNotificationsTitle: " + viewInfo(mNoNotificationsTitle));
- pw.println("mCloseView: " + viewInfo(mCloseView));
- pw.println("mTickerView: " + viewInfo(mTickerView));
- pw.println("mScrollView: " + viewInfo(mScrollView)
+ pw.println(" mExpandedParams: " + mExpandedParams);
+ pw.println(" mExpandedView: " + viewInfo(mExpandedView));
+ pw.println(" mExpandedDialog: " + mExpandedDialog);
+ pw.println(" mTrackingParams: " + mTrackingParams);
+ pw.println(" mTrackingView: " + viewInfo(mTrackingView));
+ pw.println(" mOngoingTitle: " + viewInfo(mOngoingTitle));
+ pw.println(" mOngoingItems: " + viewInfo(mOngoingItems));
+ pw.println(" mLatestTitle: " + viewInfo(mLatestTitle));
+ pw.println(" mLatestItems: " + viewInfo(mLatestItems));
+ pw.println(" mNoNotificationsTitle: " + viewInfo(mNoNotificationsTitle));
+ pw.println(" mCloseView: " + viewInfo(mCloseView));
+ pw.println(" mTickerView: " + viewInfo(mTickerView));
+ pw.println(" mScrollView: " + viewInfo(mScrollView)
+ " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
pw.println("mNotificationLinearLayout: " + viewInfo(mNotificationLinearLayout));
}
synchronized (mIconMap) {
final int N = mIconMap.size();
- pw.println("mIconMap.size=" + N);
+ pw.println(" mIconMap.size=" + N);
Set<IBinder> keys = mIconMap.keySet();
int i=0;
for (IBinder key: keys) {
StatusBarIcon icon = mIconMap.get(key);
- pw.println(" [" + i + "] key=" + key);
- pw.println(" data=" + icon.mData);
+ pw.println(" [" + i + "] key=" + key);
+ pw.println(" data=" + icon.mData);
i++;
}
}
synchronized (mNotificationData) {
int N = mNotificationData.ongoingCount();
- pw.println("ongoingCount.size=" + N);
+ pw.println(" ongoingCount.size=" + N);
for (int i=0; i<N; i++) {
StatusBarNotification n = mNotificationData.getOngoing(i);
- pw.println(" [" + i + "] key=" + n.key + " view=" + n.view);
- pw.println(" data=" + n.data);
+ pw.println(" [" + i + "] key=" + n.key + " view=" + n.view);
+ pw.println(" data=" + n.data);
}
N = mNotificationData.latestCount();
- pw.println("ongoingCount.size=" + N);
+ pw.println(" ongoingCount.size=" + N);
for (int i=0; i<N; i++) {
StatusBarNotification n = mNotificationData.getLatest(i);
- pw.println(" [" + i + "] key=" + n.key + " view=" + n.view);
- pw.println(" data=" + n.data);
+ pw.println(" [" + i + "] key=" + n.key + " view=" + n.view);
+ pw.println(" data=" + n.data);
}
}
synchronized (mDisableRecords) {
final int N = mDisableRecords.size();
- pw.println("mDisableRecords.size=" + N
+ pw.println(" mDisableRecords.size=" + N
+ " mDisabled=0x" + Integer.toHexString(mDisabled));
for (int i=0; i<N; i++) {
DisableRecord tok = mDisableRecords.get(i);
- pw.println(" [" + i + "] what=0x" + Integer.toHexString(tok.what)
+ pw.println(" [" + i + "] what=0x" + Integer.toHexString(tok.what)
+ " pkg=" + tok.pkg + " token=" + tok.token);
}
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 4957366..2b4195b 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -38,7 +38,7 @@ interface ITelephony {
void dial(String number);
/**
- * Place a call to the numer.
+ * Place a call to the specified number.
* @param number the number to be called.
*/
void call(String number);
@@ -73,6 +73,36 @@ interface ITelephony {
boolean endCall();
/**
+ * Answer the currently-ringing call.
+ *
+ * If there's already a current active call, that call will be
+ * automatically put on hold. If both lines are currently in use, the
+ * current active call will be ended.
+ *
+ * TODO: provide a flag to let the caller specify what policy to use
+ * if both lines are in use. (The current behavior is hardwired to
+ * "answer incoming, end ongoing", which is how the CALL button
+ * is specced to behave.)
+ *
+ * TODO: this should be a oneway call (especially since it's called
+ * directly from the key queue thread).
+ */
+ void answerRingingCall();
+
+ /**
+ * Silence the ringer if an incoming call is currently ringing.
+ * (If vibrating, stop the vibrator also.)
+ *
+ * It's safe to call this if the ringer has already been silenced, or
+ * even if there's no incoming call. (If so, this method will do nothing.)
+ *
+ * TODO: this should be a oneway call too (see above).
+ * (Actually *all* the methods here that return void can
+ * probably be oneway.)
+ */
+ void silenceRinger();
+
+ /**
* Check if we are in either an active or holding call
* @return true if the phone state is OFFHOOK.
*/
diff --git a/telephony/java/com/android/internal/telephony/gsm/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/DataConnectionTracker.java
index b115713..1c64641 100644
--- a/telephony/java/com/android/internal/telephony/gsm/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/DataConnectionTracker.java
@@ -559,6 +559,14 @@ final class DataConnectionTracker extends Handler
}
/**
+ * Simply tear down data connections due to radio off
+ * and don't setup again.
+ */
+ public void cleanConnectionBeforeRadioOff() {
+ cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
+ }
+
+ /**
* Report the current state of data connectivity (enabled or disabled) for
* the default APN.
* @return {@code false} if data connectivity has been explicitly disabled,
@@ -1257,6 +1265,23 @@ final class DataConnectionTracker extends Handler
return (shouldPost && cause != PdpConnection.PdpFailCause.UNKNOWN);
}
+ /**
+ * Return true if data connection need to be setup after disconnected due to
+ * reason.
+ *
+ * @param reason the reason why data is disconnected
+ * @return true if try setup data connection is need for this reason
+ */
+ private boolean retryAfterDisconnected(String reason) {
+ boolean retry = true;
+
+ if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) ||
+ Phone.REASON_DATA_DISABLED.equals(reason) ) {
+ retry = false;
+ }
+ return retry;
+ }
+
private void reconnectAfterFail(PdpFailCause lastFailCauseCode, String reason) {
if (state == State.FAILED) {
Log.d(LOG_TAG, "PDP activate failed. Scheduling next attempt for "
@@ -1475,7 +1500,9 @@ final class DataConnectionTracker extends Handler
setState(State.IDLE);
phone.notifyDataConnection(reason);
mActiveApn = null;
- trySetupData(reason);
+ if ( retryAfterDisconnected(reason) ) {
+ trySetupData(reason);
+ }
break;
case EVENT_PDP_STATE_CHANGED:
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index bd6d41e..4ad65fc 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -91,6 +91,8 @@ public class GSMPhone extends PhoneBase {
public static final String VM_NUMBER = "vm_number_key";
// Key used to read/write the SIM IMSI used for storing the voice mail
public static final String VM_SIM_IMSI = "vm_sim_imsi_key";
+ // Key used to read/write "disable DNS server check" pref (used for testing)
+ public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key";
//***** Instance Variables
@@ -197,6 +199,9 @@ public class GSMPhone extends PhoneBase {
mCM.setOnCallRing(h, EVENT_CALL_RING, null);
mSST.registerForNetworkAttach(h, EVENT_REGISTERED_TO_NETWORK, null);
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
+ mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
+
if (false) {
try {
//debugSocket = new LocalServerSocket("com.android.internal.telephony.debug");
@@ -1160,6 +1165,10 @@ public class GSMPhone extends PhoneBase {
*/
public void disableDnsCheck(boolean b) {
mDnsCheckDisabled = b;
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
+ editor.commit();
}
/**
diff --git a/telephony/java/com/android/internal/telephony/gsm/MccTable.java b/telephony/java/com/android/internal/telephony/gsm/MccTable.java
index 57a54c4..bb17cc4 100644
--- a/telephony/java/com/android/internal/telephony/gsm/MccTable.java
+++ b/telephony/java/com/android/internal/telephony/gsm/MccTable.java
@@ -171,16 +171,16 @@ public final class MccTable
table.add(new MccEntry(202,"gr",2)); //Greece
table.add(new MccEntry(204,"nl",2,"Europe/Amsterdam")); //Netherlands (Kingdom of the)
table.add(new MccEntry(206,"be",2)); //Belgium
- table.add(new MccEntry(208,"fr",2)); //France
+ table.add(new MccEntry(208,"fr",2,"Europe/Paris","fr")); //France
table.add(new MccEntry(212,"mc",2)); //Monaco (Principality of)
table.add(new MccEntry(213,"ad",2)); //Andorra (Principality of)
- table.add(new MccEntry(214,"es",2)); //Spain
+ table.add(new MccEntry(214,"es",2,"Europe/Madrid","es")); //Spain
table.add(new MccEntry(216,"hu",2)); //Hungary (Republic of)
table.add(new MccEntry(218,"ba",2)); //Bosnia and Herzegovina
table.add(new MccEntry(219,"hr",2)); //Croatia (Republic of)
table.add(new MccEntry(220,"rs",2)); //Serbia and Montenegro
- table.add(new MccEntry(222,"it",2)); //Italy
- table.add(new MccEntry(225,"va",2)); //Vatican City State
+ table.add(new MccEntry(222,"it",2,"Europe/Rome","it")); //Italy
+ table.add(new MccEntry(225,"va",2,"Europe/Rome","it")); //Vatican City State
table.add(new MccEntry(226,"ro",2)); //Romania
table.add(new MccEntry(228,"ch",2)); //Switzerland (Confederation of)
table.add(new MccEntry(230,"cz",2,"Europe/Prague")); //Czech Republic
@@ -217,7 +217,7 @@ public final class MccTable
table.add(new MccEntry(290,"gl",2)); //Greenland (Denmark)
table.add(new MccEntry(292,"sm",2)); //San Marino (Republic of)
table.add(new MccEntry(293,"sl",2)); //Slovenia (Republic of)
- table.add(new MccEntry(294,"mk",2)); //The Former Yugoslav Republic of Macedonia
+ table.add(new MccEntry(294,"mk",2)); //The Former Yugoslav Republic of Macedonia
table.add(new MccEntry(295,"li",2)); //Liechtenstein (Principality of)
table.add(new MccEntry(302,"ca",2)); //Canada
table.add(new MccEntry(308,"pm",2)); //Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise)
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index 75f56a3..22bd6e2 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -1191,11 +1191,6 @@ public final class SIMRecords extends Handler implements SimConstants
SmsMessage message = SmsMessage.newFromCMT(
new String[] { "", pdu });
- Log.i("ENF", "message from " +
- message.getOriginatingAddress());
- Log.i("ENF", "message text " +
- message.getMessageBody());
-
phone.mSMS.dispatchMessage(message);
}
}
@@ -1226,11 +1221,6 @@ public final class SIMRecords extends Handler implements SimConstants
SmsMessage message = SmsMessage.newFromCMT(
new String[] { "", pdu });
- Log.i("ENF", "message from " +
- message.getOriginatingAddress());
- Log.i("ENF", "message text " +
- message.getMessageBody());
-
phone.mSMS.dispatchMessage(message);
// 3GPP TS 51.011 v5.0.0 (20011-12) 10.5.3
diff --git a/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java
index 0ab4a0e..4176004 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java
@@ -449,6 +449,13 @@ final class SMSDispatcher extends Handler {
* @param sms the incoming message from the phone
*/
/* package */ void dispatchMessage(SmsMessage sms) {
+
+ // If sms is null, means there was a parsing error.
+ // TODO: Should NAK this.
+ if (sms == null) {
+ return;
+ }
+
boolean handled = false;
// Special case the message waiting indicator messages
diff --git a/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java
index 10baa1b..f37d1eb 100644
--- a/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java
@@ -25,6 +25,8 @@ import static com.android.internal.telephony.TelephonyProperties.PROPERTY_SIM_OP
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_SIM_OPERATOR_NUMERIC;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.gsm.DataConnectionTracker.State;
+
import android.app.AlarmManager;
import android.content.ContentResolver;
import android.content.Context;
@@ -70,6 +72,9 @@ final class ServiceStateTracker extends Handler
static final int DATA_ACCESS_GPRS = 1;
static final int DATA_ACCESS_EDGE = 2;
static final int DATA_ACCESS_UMTS = 3;
+
+ static final int MAX_NUM_DATA_STATE_READS = 15;
+ static final int DATA_STATE_POLL_SLEEP_MS = 100;
//***** Instance Variables
@@ -595,6 +600,18 @@ final class ServiceStateTracker extends Handler
(dcTracker.getAnyDataEnabled() ? 1 : 0) );
EventLog.writeEvent(TelephonyEventLog.EVENT_DATA_STATE_RADIO_OFF, val);
}
+ dcTracker.cleanConnectionBeforeRadioOff();
+
+ // poll data state up to 15 times, with a 100ms delay
+ // totaling 1.5 sec. Normal data disable action will finish in 100ms.
+ for (int i = 0; i < MAX_NUM_DATA_STATE_READS; i++) {
+ if (dcTracker.state != State.CONNECTED
+ && dcTracker.state != State.DISCONNECTING) {
+ Log.d(LOG_TAG, "Data shutdown complete.");
+ break;
+ }
+ SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS);
+ }
// If it's on and available and we want it off..
cm.setRadioPower(false, null);
} // Otherwise, we're in the desired state
diff --git a/test-runner/android/test/ServiceTestCase.java b/test-runner/android/test/ServiceTestCase.java
index c53bf7d..fcb9d55 100644
--- a/test-runner/android/test/ServiceTestCase.java
+++ b/test-runner/android/test/ServiceTestCase.java
@@ -48,7 +48,7 @@ import java.util.Random;
* the test case will call onCreate(), and then call the corresponding entry point in your service.
* It will record any parameters or other support values necessary to support the lifecycle.</li>
* <li>After your test completes, the test case {@link #tearDown} function is
- * automatically called, and it will stop & destroy your service with the appropriate
+ * automatically called, and it will stop and destroy your service with the appropriate
* calls (depending on how your test invoked the service.)</li>
* </ul>
*
@@ -172,7 +172,7 @@ public abstract class ServiceTestCase<T extends Service> extends AndroidTestCase
* Return the communication channel to the service. May return null if
* clients can not bind to the service. The returned
* {@link android.os.IBinder} is usually for a complex interface
- * that has been <a href="{@docRoot}reference/aidl.html">described using
+ * that has been <a href="{@docRoot}guide/developing/tools/aidl.html">described using
* aidl</a>.
*
* Note: In order to test with this interface, your service must implement a getService()
diff --git a/test-runner/android/test/TestCaseUtil.java b/test-runner/android/test/TestCaseUtil.java
index 4109d9c..3ba9711 100644
--- a/test-runner/android/test/TestCaseUtil.java
+++ b/test-runner/android/test/TestCaseUtil.java
@@ -17,6 +17,7 @@
package android.test;
import com.google.android.collect.Lists;
+
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
@@ -26,7 +27,9 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Enumeration;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
/**
* @hide - This is part of a framework that is under development and should not be used for
@@ -48,10 +51,25 @@ public class TestCaseUtil {
}
public static List<? extends Test> getTests(Test test, boolean flatten) {
+ return getTests(test, flatten, new HashSet<Class<?>>());
+ }
+
+ private static List<? extends Test> getTests(Test test, boolean flatten,
+ Set<Class<?>> seen) {
List<Test> testCases = Lists.newArrayList();
if (test != null) {
- Test workingTest = invokeSuiteMethodIfPossible(test.getClass());
+ Test workingTest = null;
+ /*
+ * If we want to run a single TestCase method only, we must not
+ * invoke the suite() method, because we will run all test methods
+ * of the class then.
+ */
+ if (test instanceof TestCase &&
+ ((TestCase)test).getName() == null) {
+ workingTest = invokeSuiteMethodIfPossible(test.getClass(),
+ seen);
+ }
if (workingTest == null) {
workingTest = test;
}
@@ -62,7 +80,7 @@ public class TestCaseUtil {
while (enumeration.hasMoreElements()) {
Test childTest = (Test) enumeration.nextElement();
if (flatten) {
- testCases.addAll(getTests(childTest, flatten));
+ testCases.addAll(getTests(childTest, flatten, seen));
} else {
testCases.add(childTest);
}
@@ -74,11 +92,20 @@ public class TestCaseUtil {
return testCases;
}
- private static Test invokeSuiteMethodIfPossible(Class testClass) {
+ private static Test invokeSuiteMethodIfPossible(Class testClass,
+ Set<Class<?>> seen) {
try {
Method suiteMethod = testClass.getMethod(
BaseTestRunner.SUITE_METHODNAME, new Class[0]);
- if (Modifier.isStatic(suiteMethod.getModifiers())) {
+ /*
+ * Additional check necessary: If a TestCase contains a suite()
+ * method that returns a TestSuite including the TestCase itself,
+ * we need to stop the recursion. We use a set of classes to
+ * remember which classes' suite() methods were already invoked.
+ */
+ if (Modifier.isStatic(suiteMethod.getModifiers())
+ && !seen.contains(testClass)) {
+ seen.add(testClass);
try {
return (Test) suiteMethod.invoke(null, (Object[]) null);
} catch (InvocationTargetException e) {
@@ -128,7 +155,8 @@ public class TestCaseUtil {
public static TestSuite createTestSuite(Class<? extends Test> testClass)
throws InstantiationException, IllegalAccessException {
- Test test = invokeSuiteMethodIfPossible(testClass);
+ Test test = invokeSuiteMethodIfPossible(testClass,
+ new HashSet<Class<?>>());
if (test == null) {
return new TestSuite(testClass);
diff --git a/tests/AndroidTests/Android.mk b/tests/AndroidTests/Android.mk
index cf8ac94..f5e49d7 100644
--- a/tests/AndroidTests/Android.mk
+++ b/tests/AndroidTests/Android.mk
@@ -1,7 +1,7 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := eng tests
+LOCAL_MODULE_TAGS := tests
LOCAL_JAVA_LIBRARIES := framework-tests android.test.runner
diff --git a/tests/AndroidTests/DisabledTestApp/Android.mk b/tests/AndroidTests/DisabledTestApp/Android.mk
index 814607d..a5daedf 100644
--- a/tests/AndroidTests/DisabledTestApp/Android.mk
+++ b/tests/AndroidTests/DisabledTestApp/Android.mk
@@ -1,7 +1,7 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := eng tests
+LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := $(call all-subdir-java-files)
diff --git a/tests/AndroidTests/EnabledTestApp/Android.mk b/tests/AndroidTests/EnabledTestApp/Android.mk
index 2de5c3b..4b986d3 100644
--- a/tests/AndroidTests/EnabledTestApp/Android.mk
+++ b/tests/AndroidTests/EnabledTestApp/Android.mk
@@ -1,7 +1,7 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := eng tests
+LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := $(call all-subdir-java-files)
diff --git a/tests/CoreTests/android/Android.mk b/tests/CoreTests/android/Android.mk
index 3b80228..e6b5c45 100644
--- a/tests/CoreTests/android/Android.mk
+++ b/tests/CoreTests/android/Android.mk
@@ -1,7 +1,7 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := eng tests
+LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := \
$(call all-subdir-java-files)
diff --git a/tests/CoreTests/android/AndroidManifest.xml b/tests/CoreTests/android/AndroidManifest.xml
index 8c642f4..4809f844 100644
--- a/tests/CoreTests/android/AndroidManifest.xml
+++ b/tests/CoreTests/android/AndroidManifest.xml
@@ -23,6 +23,7 @@
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
<uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
+ <uses-permission android:name="android.permission.BROADCAST_STICKY" />
<!-- location test permissions -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
diff --git a/tests/CoreTests/android/core/TestHandler.java b/tests/CoreTests/android/core/TestHandler.java
deleted file mode 100644
index 4ff2e6e..0000000
--- a/tests/CoreTests/android/core/TestHandler.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/* //device/java/android/com/android/tests/TestHandler.java
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT 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.core;
-
-import com.android.internal.os.HandlerHelper;
-import android.os.HandlerInterface;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemClock;
-
-/**
- * Naive class that implements a getNextMessage()
- * by running a Handler in a new thread. <p>
- * <p/>
- * This class blocks the Handler thread when the getNextMessage() thread
- * is not in getNextMessage(). This allows the getNextMessage() thread to
- * inspect state that is otherwise unguarded and would otherwise be prone to
- * race conditions.<p>
- * <p/>
- * Please note that both threads are allowed to run unsynchronized until
- * the first message is posted to this handler.
- * <p/>
- * Please call hh.looper.quit() when done to clean this up
- */
-public class TestHandler implements Runnable, HandlerInterface {
- //***** Instance Variables
-
- public HandlerHelper hh;
- public Looper looper;
-
- Runnable setupRoutine;
- Message nextMessage;
- long failTimeoutMillis;
- boolean waitBeforeReturning = true;
-
- //***** Class Methods
-
- public static TestHandler create() {
- return create("TestHandler", null);
- }
-
- public static TestHandler create(String name) {
- return create(name, null);
- }
-
- public static TestHandler create(String name, Runnable doSetup) {
- TestHandler ret;
-
- ret = new TestHandler();
-
- ret.setupRoutine = doSetup;
-
- synchronized (ret) {
- new Thread(ret, name).start();
- while (ret.looper == null) {
- try {
- ret.wait();
- } catch (InterruptedException ex) {
- }
- }
- }
-
- return ret;
- }
-
- //***** Public Methods
-
- /**
- * Maximum time to wait for a message before failing
- * by throwing exception
- */
- public void setFailTimeoutMillis(long msec) {
- failTimeoutMillis = msec;
- }
-
- /**
- * Waits for the next message to be sent to this handler and returns it.
- * Blocks the Handler's looper thread until another call to getNextMessage()
- * is made
- */
-
- public Message getNextMessage() {
- Message ret;
-
- synchronized (this) {
- long time = SystemClock.uptimeMillis();
-
- waitBeforeReturning = false;
- this.notifyAll();
-
- try {
- while (nextMessage == null) {
- if (failTimeoutMillis > 0
- && ((SystemClock.uptimeMillis() - time)
- > failTimeoutMillis)) {
- throw new RuntimeException("Timeout exceeded exceeded");
- }
-
- try {
- this.wait(failTimeoutMillis);
- } catch (InterruptedException ex) {
- }
- }
- ret = nextMessage;
- nextMessage = null;
- } finally {
- waitBeforeReturning = true;
- }
- }
-
- return ret;
- }
-
- //***** Overridden from Runnable
-
- public void run() {
- Looper.prepare();
- hh = new HandlerHelper(this);
-
- if (setupRoutine != null) {
- setupRoutine.run();
- }
-
- synchronized (this) {
- looper = Looper.myLooper();
- this.notify();
- }
-
- Looper.loop();
- }
-
- //***** HandlerHelper implementation
-
- public void handleMessage(Message msg) {
- synchronized (this) {
- while (nextMessage != null) {
- try {
- this.wait();
- } catch (InterruptedException ex) {
- }
- }
-
- // msg will be recycled when this method returns.
- // so we need to make a copy of it.
- nextMessage = Message.obtain();
- nextMessage.copyFrom(msg);
- this.notifyAll();
-
- while (waitBeforeReturning) {
- try {
- this.wait();
- } catch (InterruptedException ex) {
- }
- }
- }
- }
-}
-
-
diff --git a/tests/CoreTests/com/android/internal/telephony/gsm/GSMPhoneTest.java b/tests/CoreTests/com/android/internal/telephony/gsm/GSMPhoneTest.java
index ec9b3ef..7107412 100644
--- a/tests/CoreTests/com/android/internal/telephony/gsm/GSMPhoneTest.java
+++ b/tests/CoreTests/com/android/internal/telephony/gsm/GSMPhoneTest.java
@@ -9,19 +9,23 @@
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * WITHOUT WARRANTIES OR CONDITIONS OF GSMTestHandler.ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.telephony.gsm;
-import android.core.TestHandler;
import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
import android.os.Message;
+import android.os.Process;
import android.telephony.ServiceState;
import android.test.AndroidTestCase;
import android.test.PerformanceTestCase;
+import android.util.Log;
import com.android.internal.telephony.Call;
import com.android.internal.telephony.CallStateException;
@@ -29,15 +33,22 @@ import com.android.internal.telephony.Connection;
import com.android.internal.telephony.MmiCode;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.TestPhoneNotifier;
+import com.android.internal.telephony.gsm.CallFailCause;
+import com.android.internal.telephony.gsm.GSMPhone;
+import com.android.internal.telephony.gsm.GSMTestHandler;
+import com.android.internal.telephony.gsm.GsmMmiCode;
+import com.android.internal.telephony.gsm.SuppServiceNotification;
import com.android.internal.telephony.test.SimulatedCommands;
import com.android.internal.telephony.test.SimulatedRadioControl;
import java.util.List;
+
public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase {
private SimulatedRadioControl mRadioControl;
- private TestHandler mTestHandler;
private GSMPhone mGSMPhone;
+ private GSMTestHandler mGSMTestHandler;
+ private Handler mHandler;
private static final int EVENT_PHONE_STATE_CHANGED = 1;
private static final int EVENT_DISCONNECT = 2;
@@ -51,78 +62,65 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
private static final int EVENT_IN_SERVICE = 10;
private static final int SUPP_SERVICE_FAILED = 11;
private static final int SERVICE_STATE_CHANGED = 12;
-
- private static final int FAIL_TIMEOUT_MILLIS = 5 * 1000;
+ private static final int EVENT_OEM_RIL_MESSAGE = 13;
+ public static final int ANY_MESSAGE = -1;
@Override
protected void setUp() throws Exception {
super.setUp();
+ mGSMTestHandler = new GSMTestHandler(mContext);
+
+ mGSMTestHandler.start();
+ synchronized (mGSMTestHandler) {
+ do {
+ mGSMTestHandler.wait();
+ } while (mGSMTestHandler.getGSMPhone() == null);
+ }
+
+ mGSMPhone = mGSMTestHandler.getGSMPhone();
+ mRadioControl = mGSMTestHandler.getSimulatedCommands();
+
+ mHandler = mGSMTestHandler.getHandler();
+ mGSMPhone.registerForPhoneStateChanged(mHandler, EVENT_PHONE_STATE_CHANGED, null);
+ mGSMPhone.registerForNewRingingConnection(mHandler, EVENT_RINGING, null);
+ mGSMPhone.registerForDisconnect(mHandler, EVENT_DISCONNECT, null);
+
+ mGSMPhone.setOnPostDialCharacter(mHandler, EVENT_POST_DIAL, null);
- mTestHandler = TestHandler.create("GSMPhoneTest TestHandler",
- new Runnable() {
- public void run() {
- SimulatedCommands sc = new SimulatedCommands();
- mRadioControl = sc;
- mGSMPhone = new GSMPhone(
- mContext, sc,
- new TestPhoneNotifier(),
- true);
-
- }
- }
- );
-
- mTestHandler.setFailTimeoutMillis(FAIL_TIMEOUT_MILLIS);
- mGSMPhone.registerForPhoneStateChanged(mTestHandler.hh, EVENT_PHONE_STATE_CHANGED, null);
- mGSMPhone.registerForNewRingingConnection(mTestHandler.hh, EVENT_RINGING, null);
- mGSMPhone.registerForDisconnect(mTestHandler.hh, EVENT_DISCONNECT, null);
-
- mGSMPhone.setOnPostDialCharacter(mTestHandler.hh, EVENT_POST_DIAL, null);
-
- mGSMPhone.registerForSuppServiceNotification(mTestHandler.hh, EVENT_SSN, null);
- mGSMPhone.registerForMmiInitiate(mTestHandler.hh, EVENT_MMI_INITIATE, null);
- mGSMPhone.registerForMmiComplete(mTestHandler.hh, EVENT_MMI_COMPLETE, null);
- mGSMPhone.registerForSuppServiceFailed(mTestHandler.hh, SUPP_SERVICE_FAILED, null);
-
- mGSMPhone.registerForServiceStateChanged(mTestHandler.hh, SERVICE_STATE_CHANGED, null);
+ mGSMPhone.registerForSuppServiceNotification(mHandler, EVENT_SSN, null);
+ mGSMPhone.registerForMmiInitiate(mHandler, EVENT_MMI_INITIATE, null);
+ mGSMPhone.registerForMmiComplete(mHandler, EVENT_MMI_COMPLETE, null);
+ mGSMPhone.registerForSuppServiceFailed(mHandler, SUPP_SERVICE_FAILED, null);
+
+ mGSMPhone.registerForServiceStateChanged(mHandler, SERVICE_STATE_CHANGED, null);
// wait until we get phone in both voice and data service
Message msg;
ServiceState state;
+
do {
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != SERVICE_STATE_CHANGED);
- state = (ServiceState) ((AsyncResult) msg.obj).result;
+ msg = mGSMTestHandler.waitForMessage(SERVICE_STATE_CHANGED);
+ assertNotNull("Message Time Out", msg);
+ state = (ServiceState) ((AsyncResult) msg.obj).result;
} while (state.getState() != ServiceState.STATE_IN_SERVICE);
-
}
@Override
protected void tearDown() throws Exception {
- mGSMPhone.unregisterForPhoneStateChanged(mTestHandler.hh);
- mGSMPhone.unregisterForNewRingingConnection(mTestHandler.hh);
- mGSMPhone.unregisterForDisconnect(mTestHandler.hh);
- mGSMPhone.setOnPostDialCharacter(null, 0, null);
- mGSMPhone.unregisterForSuppServiceNotification(mTestHandler.hh);
- mGSMPhone.unregisterForMmiInitiate(mTestHandler.hh);
- mGSMPhone.unregisterForMmiComplete(mTestHandler.hh);
-
mRadioControl.shutdown();
- mTestHandler.hh.sendMessage(mTestHandler.hh.obtainMessage(EVENT_DONE));
-
- Message msg;
-
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_DONE);
-
- mTestHandler.looper.quit();
+ mGSMPhone.unregisterForPhoneStateChanged(mHandler);
+ mGSMPhone.unregisterForNewRingingConnection(mHandler);
+ mGSMPhone.unregisterForDisconnect(mHandler);
+ mGSMPhone.setOnPostDialCharacter(mHandler, 0, null);
+ mGSMPhone.unregisterForSuppServiceNotification(mHandler);
+ mGSMPhone.unregisterForMmiInitiate(mHandler);
+ mGSMPhone.unregisterForMmiComplete(mHandler);
mGSMPhone = null;
mRadioControl = null;
- mTestHandler = null;
+ mHandler = null;
+ mGSMTestHandler.cleanup();
super.tearDown();
}
@@ -136,7 +134,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
return false;
}
-
+
//This test is causing the emulator screen to turn off. I don't understand
//why, but I'm removing it until we can figure it out.
public void brokenTestGeneral() throws Exception {
@@ -167,19 +165,16 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_PHONE_STATE_CHANGED);
+ msg = mGSMTestHandler.waitForMessage(EVENT_PHONE_STATE_CHANGED);
+ assertNotNull("Message Time Out", msg);
assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
assertEquals(Call.State.DIALING, mGSMPhone.getForegroundCall().getState());
assertTrue(mGSMPhone.getForegroundCall().isDialingOrAlerting());
- /*
- do {
- th.getNextMessage();
- } while (phone.getForegroundCall().getConnections().size() == 0);
- */
+ /*do {
+ mGSMTestHandler.waitForMessage(ANY_MESSAGE);
+ } while (mGSMPhone.getForegroundCall().getConnections().size() == 0);*/
assertEquals(0, mGSMPhone.getRingingCall().getConnections().size());
assertEquals(1, mGSMPhone.getForegroundCall().getConnections().size());
@@ -206,7 +201,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.progressConnectingCallState();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
}
while (mGSMPhone.getForegroundCall().getState() != Call.State.ALERTING);
@@ -234,7 +229,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.progressConnectingCallState();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
@@ -259,9 +254,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// One disconnected connection
mGSMPhone.getForegroundCall().hangup();
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_DISCONNECT);
+ msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
+ assertNotNull("Message Time Out", msg);
assertEquals(Phone.State.IDLE, mGSMPhone.getState());
assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
@@ -311,9 +305,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerRing("18005551212");
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_RINGING);
+ msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
+ assertNotNull("Message Time Out", msg);
assertEquals(Phone.State.RINGING, mGSMPhone.getState());
assertTrue(mGSMPhone.getRingingCall().isRinging());
@@ -347,7 +340,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.acceptCall();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getRingingCall().getConnections().size() == 1);
assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
@@ -382,10 +375,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
fail("unexpected ex");
}
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_DISCONNECT);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
+ assertNotNull("Message Time Out", msg);
assertEquals(Phone.State.IDLE, mGSMPhone.getState());
assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
@@ -444,7 +435,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerRing("18005551212");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getRingingCall().getConnections().isEmpty());
assertEquals(Phone.State.RINGING, mGSMPhone.getState());
@@ -471,7 +462,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.rejectCall();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.IDLE);
assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
@@ -525,7 +516,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerRing("18005551212");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getRingingCall().getConnections().isEmpty());
assertEquals(Phone.State.RINGING, mGSMPhone.getState());
@@ -539,7 +530,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerHangupForeground();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.IDLE);
assertEquals(Connection.DisconnectCause.INCOMING_MISSED, cn.getDisconnectCause());
@@ -549,7 +540,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerRing("18005551212");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.RINGING);
@@ -559,7 +550,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.acceptCall();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.OFFHOOK);
assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
@@ -569,7 +560,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.switchHoldingAndActive();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
@@ -580,7 +571,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.switchHoldingAndActive();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
}
while (mGSMPhone.getBackgroundCall().getState() == Call.State.HOLDING);
@@ -592,7 +583,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerHangupAll();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.IDLE);
assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
@@ -603,13 +594,13 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerRing("18005551212");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.RINGING);
mGSMPhone.rejectCall();
do {
- msg = mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (msg.what != EVENT_DISCONNECT);
ar = (AsyncResult) msg.obj;
@@ -624,7 +615,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerRing("18005551212");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.RINGING);
cn = mGSMPhone.getRingingCall().getEarliestConnection();
@@ -632,7 +623,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.acceptCall();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.OFFHOOK);
assertEquals(Connection.DisconnectCause.NOT_DISCONNECTED, cn.getDisconnectCause());
@@ -647,7 +638,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
}
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState()
!= Call.State.DISCONNECTED);
@@ -661,7 +652,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.dial("+13125551212");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.OFFHOOK);
assertTrue(mGSMPhone.getForegroundCall().isDialingOrAlerting());
@@ -672,7 +663,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// One ACTIVE call
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
@@ -682,7 +673,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerRing("18005551212");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.RINGING);
assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
@@ -692,7 +683,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.acceptCall();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.OFFHOOK);
assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
@@ -706,7 +697,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.conference();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
@@ -720,7 +711,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.switchHoldingAndActive();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
}
while (mGSMPhone.getBackgroundCall().getState() != Call.State.HOLDING);
@@ -734,7 +725,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerRing("18005558355");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.RINGING);
assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
@@ -750,7 +741,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.getBackgroundCall().hangup();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getBackgroundCall().getState() != Call.State.DISCONNECTED);
assertEquals(Phone.State.RINGING, mGSMPhone.getState());
@@ -763,7 +754,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.rejectCall();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.IDLE);
assertFalse(mGSMPhone.getForegroundCall().isDialingOrAlerting());
@@ -782,10 +773,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
Connection cn = mGSMPhone.dial("+13125551212");
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_DISCONNECT);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
+ assertNotNull("Message Time Out", msg);
assertEquals(Phone.State.IDLE, mGSMPhone.getState());
assertEquals(Connection.DisconnectCause.NORMAL, cn.getDisconnectCause());
@@ -812,7 +801,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.dial("+13125551212");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
}
while (mGSMPhone.getForegroundCall().getState() != Call.State.DIALING);
@@ -820,10 +809,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.getForegroundCall().hangup();
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_DISCONNECT);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
+ assertNotNull("Message Time Out", msg);
assertEquals(Phone.State.IDLE, mGSMPhone.getState());
assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
@@ -833,13 +820,13 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.dial("+13125551212");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.OFFHOOK);
mRadioControl.progressConnectingCallState();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
}
while (mGSMPhone.getForegroundCall().getState() != Call.State.ALERTING);
@@ -847,9 +834,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.getForegroundCall().hangup();
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_DISCONNECT);
+ msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
+ assertNotNull("Message Time Out", msg);
assertEquals(Phone.State.IDLE, mGSMPhone.getState());
@@ -867,10 +853,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.resumeResponses();
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_DISCONNECT);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
+ assertNotNull("Message Time Out", msg);
assertEquals(Phone.State.IDLE, mGSMPhone.getState());
assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
@@ -883,13 +867,13 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.dial("+13125551212");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getConnections().isEmpty());
mRadioControl.shutdown();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
mGSMPhone.clearDisconnected();
} while (!mGSMPhone.getForegroundCall().getConnections().isEmpty());
}
@@ -902,7 +886,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
do {
mRadioControl.progressConnectingCallState();
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
@@ -912,9 +896,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerRing("18005551212");
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_RINGING);
+ msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
+ assertNotNull("Message Time Out", msg);
assertEquals(Phone.State.RINGING, mGSMPhone.getState());
assertTrue(mGSMPhone.getRingingCall().isRinging());
@@ -927,7 +910,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.handleInCallMmiCommands("0");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING);
assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
@@ -940,7 +923,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.switchHoldingAndActive();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
@@ -952,7 +935,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.handleInCallMmiCommands("0");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getBackgroundCall().getState() == Call.State.HOLDING);
assertEquals(Phone.State.IDLE, mGSMPhone.getState());
@@ -968,7 +951,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
do {
mRadioControl.progressConnectingCallState();
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
@@ -979,7 +962,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerRing("18005551212");
do {
- msg = mTestHandler.getNextMessage();
+ msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE);
+ assertNotNull("Message Time Out", msg);
} while (msg.what != EVENT_RINGING);
assertEquals(Phone.State.RINGING, mGSMPhone.getState());
@@ -994,7 +978,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.handleInCallMmiCommands("1");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING);
assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
@@ -1008,7 +992,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.switchHoldingAndActive();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
assertEquals(Call.State.IDLE, mGSMPhone.getForegroundCall().getState());
@@ -1019,7 +1003,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.handleInCallMmiCommands("1");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
@@ -1033,9 +1017,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerRing("16505550100");
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_RINGING);
+ msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
+ assertNotNull("Message Time Out", msg);
assertEquals(Phone.State.RINGING, mGSMPhone.getState());
assertTrue(mGSMPhone.getRingingCall().isRinging());
@@ -1048,7 +1031,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.handleInCallMmiCommands("12");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
assertEquals(Phone.State.RINGING, mGSMPhone.getState());
@@ -1060,7 +1043,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.acceptCall();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getState() != Phone.State.OFFHOOK);
assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
@@ -1075,7 +1058,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
do {
mRadioControl.progressConnectingCallState();
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE ||
mGSMPhone.getBackgroundCall().getState() != Call.State.HOLDING);
@@ -1086,20 +1069,20 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// have the gsm index of 2
// Simulate entering "11" followed by SEND: release the call with
- // gsm index equals to 1. This should not be allowed, and a
+ // gsm index equals to 1. This should not be allowed, and a
// Supplementary Service notification must be received.
mGSMPhone.handleInCallMmiCommands("11");
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg != null && msg.what != SUPP_SERVICE_FAILED);
+
+ msg = mGSMTestHandler.waitForMessage(SUPP_SERVICE_FAILED);
+ assertNotNull("Message Time Out", msg);
assertFalse("IncallMmiCallWaiting: command should not work on holding call", msg == null);
-
+
// Simulate entering "12" followed by SEND: release the call with
// gsm index equals to 2.
mGSMPhone.handleInCallMmiCommands("12");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
@@ -1108,9 +1091,9 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// Simulate entering 1 followed by SEND: release all active calls
// (if any exist) and accepts the other (held or waiting) call.
mGSMPhone.handleInCallMmiCommands("1");
-
+
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
@@ -1124,7 +1107,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.handleInCallMmiCommands("11");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
@@ -1139,7 +1122,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
do {
mRadioControl.progressConnectingCallState();
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
@@ -1149,9 +1132,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerRing("18005551212");
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_RINGING);
+ msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
+ assertNotNull("Message Time Out", msg);
assertEquals(Phone.State.RINGING, mGSMPhone.getState());
assertTrue(mGSMPhone.getRingingCall().isRinging());
@@ -1166,7 +1148,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.handleInCallMmiCommands("2");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getRingingCall().getState() == Call.State.WAITING);
@@ -1184,9 +1166,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// swap the active and holding calls
mGSMPhone.handleInCallMmiCommands("2");
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_PHONE_STATE_CHANGED);
+ msg = mGSMTestHandler.waitForMessage(EVENT_PHONE_STATE_CHANGED);
+ assertNotNull("Message Time Out", msg);
assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
assertEquals("13125551212",
@@ -1199,7 +1180,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.conference();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
@@ -1212,20 +1193,19 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// Simulate entering "23" followed by SEND: places all active call
// on hold except call 3. This should fail and a supplementary service
// failed notification should be received.
-
+
mGSMPhone.handleInCallMmiCommands("23");
-
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg != null && msg.what != SUPP_SERVICE_FAILED);
+
+ msg = mGSMTestHandler.waitForMessage(SUPP_SERVICE_FAILED);
+ assertNotNull("Message Time Out", msg);
assertFalse("IncallMmiCallHold: separate should have failed!", msg == null);
-
+
// Simulate entering "21" followed by SEND: places all active call
// on hold except call 1.
mGSMPhone.handleInCallMmiCommands("21");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getBackgroundCall().getState() == Call.State.IDLE);
assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
@@ -1242,7 +1222,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
do {
mRadioControl.progressConnectingCallState();
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
@@ -1253,7 +1233,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
do {
mRadioControl.progressConnectingCallState();
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
@@ -1262,7 +1242,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.handleInCallMmiCommands("3");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
assertEquals(Phone.State.OFFHOOK, mGSMPhone.getState());
@@ -1282,7 +1262,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
do {
mRadioControl.progressConnectingCallState();
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
@@ -1297,7 +1277,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
do {
mRadioControl.progressConnectingCallState();
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
@@ -1310,7 +1290,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.conference();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getBackgroundCall().getState() != Call.State.IDLE);
assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
@@ -1326,9 +1306,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// of 7
mRadioControl.triggerRing("18005551212");
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_RINGING);
+ msg = mGSMTestHandler.waitForMessage(EVENT_RINGING);
+ assertNotNull("Message Time Out", msg);
assertEquals(Phone.State.RINGING, mGSMPhone.getState());
assertTrue(mGSMPhone.getRingingCall().isRinging());
@@ -1341,7 +1320,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.acceptCall();
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getRingingCall().getState() != Call.State.IDLE);
assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
@@ -1354,7 +1333,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.handleInCallMmiCommands("17");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
@@ -1366,7 +1345,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.handleInCallMmiCommands("1");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() != Call.State.ACTIVE);
assertEquals(Call.State.ACTIVE, mGSMPhone.getForegroundCall().getState());
@@ -1375,7 +1354,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.handleInCallMmiCommands("16");
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (mGSMPhone.getForegroundCall().getState() == Call.State.ACTIVE);
assertEquals(Call.State.DISCONNECTED, mGSMPhone.getForegroundCall().getState());
@@ -1389,53 +1368,44 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.dial("+13125551212,1234;5N8xx");
- do {
- msg = mTestHandler.getNextMessage();
- mRadioControl.progressConnectingToActive();
- } while (msg.what != EVENT_POST_DIAL);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
+ assertNotNull("Message Time Out", msg);
ar = (AsyncResult) (msg.obj);
cn = (Connection) (ar.result);
assertEquals(',', msg.arg1);
assertEquals("1234;5N8", cn.getRemainingPostDialString());
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
+ assertNotNull("Message Time Out", msg);
assertEquals('1', msg.arg1);
ar = (AsyncResult) (msg.obj);
assertEquals(Connection.PostDialState.STARTED, ar.userObj);
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
+ assertNotNull("Message Time Out", msg);
assertEquals('2', msg.arg1);
ar = (AsyncResult) (msg.obj);
assertEquals(Connection.PostDialState.STARTED, ar.userObj);
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
+ assertNotNull("Message Time Out", msg);
assertEquals('3', msg.arg1);
ar = (AsyncResult) (msg.obj);
assertEquals(Connection.PostDialState.STARTED, ar.userObj);
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
+ assertNotNull("Message Time Out", msg);
assertEquals('4', msg.arg1);
ar = (AsyncResult) (msg.obj);
assertEquals(Connection.PostDialState.STARTED, ar.userObj);
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
+ assertNotNull("Message Time Out", msg);
assertEquals(';', msg.arg1);
ar = (AsyncResult) (msg.obj);
cn = (Connection) (ar.result);
@@ -1443,18 +1413,15 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
assertEquals(Connection.PostDialState.WAIT, ar.userObj);
cn.proceedAfterWaitChar();
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
+ assertNotNull("Message Time Out", msg);
assertEquals('5', msg.arg1);
ar = (AsyncResult) (msg.obj);
assertEquals(Connection.PostDialState.STARTED, ar.userObj);
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
assertEquals('N', msg.arg1);
ar = (AsyncResult) (msg.obj);
cn = (Connection) (ar.result);
@@ -1462,27 +1429,22 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
assertEquals(Connection.PostDialState.WILD, ar.userObj);
cn.proceedAfterWildChar(",6;7");
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
+ assertNotNull("Message Time Out", msg);
ar = (AsyncResult) (msg.obj);
cn = (Connection) (ar.result);
assertEquals(',', msg.arg1);
assertEquals("6;78", cn.getRemainingPostDialString());
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
+ assertNotNull("Message Time Out", msg);
assertEquals('6', msg.arg1);
ar = (AsyncResult) (msg.obj);
assertEquals(Connection.PostDialState.STARTED, ar.userObj);
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
+ assertNotNull("Message Time Out", msg);
assertEquals(';', msg.arg1);
ar = (AsyncResult) (msg.obj);
cn = (Connection) (ar.result);
@@ -1490,28 +1452,21 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
assertEquals(Connection.PostDialState.WAIT, ar.userObj);
cn.proceedAfterWaitChar();
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
+ assertNotNull("Message Time Out", msg);
assertEquals('7', msg.arg1);
ar = (AsyncResult) (msg.obj);
assertEquals(Connection.PostDialState.STARTED, ar.userObj);
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
+ assertNotNull("Message Time Out", msg);
assertEquals('8', msg.arg1);
ar = (AsyncResult) (msg.obj);
assertEquals(Connection.PostDialState.STARTED, ar.userObj);
// Bogus chars at end should be ignored
-
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
+ assertNotNull("Message Time Out", msg);
assertEquals(0, msg.arg1);
ar = (AsyncResult) (msg.obj);
cn = (Connection) (ar.result);
@@ -1530,16 +1485,11 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.progressConnectingToActive();
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
+ assertNotNull("Message Time Out", msg);
assertEquals(',', msg.arg1);
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_POST_DIAL);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_POST_DIAL);
assertEquals('N', msg.arg1);
ar = (AsyncResult) (msg.obj);
cn = (Connection) (ar.result);
@@ -1567,16 +1517,13 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// Normally these failure conditions would happen in DIALING
// not ALERTING
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (cn.getState() == Call.State.DIALING);
mRadioControl.triggerHangupAll();
-
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_DISCONNECT);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
+ assertNotNull("Message Time Out", msg);
assertEquals(Phone.State.IDLE, mGSMPhone.getState());
assertEquals(Connection.DisconnectCause.NORMAL, cn.getDisconnectCause());
@@ -1608,16 +1555,13 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// Normally these failure conditions would happen in DIALING
// not ALERTING
do {
- mTestHandler.getNextMessage();
+ assertNotNull("Message Time Out", mGSMTestHandler.waitForMessage(ANY_MESSAGE));
} while (cn.getState() == Call.State.DIALING);
mRadioControl.triggerHangupAll();
-
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_DISCONNECT);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_DISCONNECT);
+ assertNotNull("Message Time Out", msg);
assertEquals(Phone.State.IDLE, mGSMPhone.getState());
assertEquals(Connection.DisconnectCause.BUSY, cn.getDisconnectCause());
@@ -1650,7 +1594,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// Normally these failure conditions would happen in DIALING
// not ALERTING
do {
- mTestHandler.getNextMessage();
+ msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE);
+ assertNotNull("Message Time Out", msg);
} while (cn.getState() == Call.State.DIALING);
@@ -1659,7 +1604,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// Unlike the while loops above, this one waits
// for a "phone state changed" message back to "idle"
do {
- msg = mTestHandler.getNextMessage();
+ msg = mGSMTestHandler.waitForMessage(ANY_MESSAGE);
+ assertNotNull("Message Time Out", msg);
} while (!(msg.what == EVENT_PHONE_STATE_CHANGED
&& mGSMPhone.getState() == Phone.State.IDLE));
@@ -1696,10 +1642,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mRadioControl.triggerSsn(type, code);
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_SSN);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_SSN);
+ assertNotNull("Message Time Out", msg);
AsyncResult ar = (AsyncResult) msg.obj;
assertNull(ar.exception);
@@ -1714,7 +1658,7 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
public void testUssd() throws Exception {
// Quick hack to work around a race condition in this test:
// We may initiate a USSD MMI before GSMPhone receives its initial
- // EVENT_RADIO_OFF_OR_NOT_AVAILABLE event. When the phone sees this
+ // GSMTestHandler.EVENT_RADIO_OFF_OR_NOT_AVAILABLE event. When the phone sees this
// event, it will cancel the just issued USSD MMI, which we don't
// want. So sleep a little first.
try {
@@ -1735,10 +1679,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// Receive an incoming NOTIFY
mRadioControl.triggerIncomingUssd("0", "NOTIFY message");
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_MMI_COMPLETE);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
+ assertNotNull("Message Time Out", msg);
ar = (AsyncResult) msg.obj;
mmi = (MmiCode) ar.result;
@@ -1746,29 +1688,23 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// Receive a REQUEST and send response
mRadioControl.triggerIncomingUssd("1", "REQUEST Message");
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_MMI_COMPLETE);
+ msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
+ assertNotNull("Message Time Out", msg);
ar = (AsyncResult) msg.obj;
mmi = (MmiCode) ar.result;
assertTrue(mmi.isUssdRequest());
mGSMPhone.sendUssdResponse("## TEST: TEST_GSMPhone responding...");
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_MMI_INITIATE);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
+ assertNotNull("Message Time Out", msg);
ar = (AsyncResult) msg.obj;
mmi = (MmiCode) ar.result;
GsmMmiCode gsmMmi = (GsmMmiCode) mmi;
assertTrue(gsmMmi.isPendingUSSD());
-
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_MMI_COMPLETE);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
+ assertNotNull("Message Time Out", msg);
ar = (AsyncResult) msg.obj;
mmi = (MmiCode) ar.result;
@@ -1777,19 +1713,16 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// Receive a REQUEST and cancel
mRadioControl.triggerIncomingUssd("1", "REQUEST Message");
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_MMI_COMPLETE);
+ msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
+ assertNotNull("Message Time Out", msg);
ar = (AsyncResult) msg.obj;
mmi = (MmiCode) ar.result;
assertTrue(mmi.isUssdRequest());
mmi.cancel();
-
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_MMI_COMPLETE);
+ msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
+ assertNotNull("Message Time Out", msg);
ar = (AsyncResult) msg.obj;
mmi = (MmiCode) ar.result;
@@ -1808,13 +1741,11 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
mGSMPhone.dial("#646#");
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_MMI_INITIATE);
+ msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
+ assertNotNull("Message Time Out", msg);
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_MMI_COMPLETE);
+ msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
+ assertNotNull("Message Time Out", msg);
ar = (AsyncResult) msg.obj;
mmi = (MmiCode) ar.result;
@@ -1842,13 +1773,11 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
assertTrue(mmi.isCancelable());
mmi.cancel();
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_MMI_INITIATE);
+ msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
+ assertNotNull("Message Time Out", msg);
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_MMI_COMPLETE);
+ msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
+ assertNotNull("Message Time Out", msg);
AsyncResult ar = (AsyncResult) msg.obj;
mmi = (MmiCode) ar.result;
@@ -1867,11 +1796,10 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// null byte array
- mGSMPhone.invokeOemRilRequestRaw(null, mTestHandler.hh.obtainMessage(999));
+ mGSMPhone.invokeOemRilRequestRaw(null, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
- do {
- msg = mTestHandler.getNextMessage();
- } while (!(msg.what == 999));
+ msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
+ assertNotNull("Message Time Out", msg);
ar = ((AsyncResult) msg.obj);
@@ -1880,11 +1808,10 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// empty byte array
- mGSMPhone.invokeOemRilRequestRaw(new byte[0], mTestHandler.hh.obtainMessage(999));
+ mGSMPhone.invokeOemRilRequestRaw(new byte[0], mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
- do {
- msg = mTestHandler.getNextMessage();
- } while (!(msg.what == 999));
+ msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
+ assertNotNull("Message Time Out", msg);
ar = ((AsyncResult) msg.obj);
@@ -1894,11 +1821,10 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// byte array with data
mGSMPhone.invokeOemRilRequestRaw("Hello".getBytes("utf-8"),
- mTestHandler.hh.obtainMessage(999));
+ mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
- do {
- msg = mTestHandler.getNextMessage();
- } while (!(msg.what == 999));
+ msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
+ assertNotNull("Message Time Out", msg);
ar = ((AsyncResult) msg.obj);
@@ -1907,11 +1833,10 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// null strings
- mGSMPhone.invokeOemRilRequestStrings(null, mTestHandler.hh.obtainMessage(999));
+ mGSMPhone.invokeOemRilRequestStrings(null, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
- do {
- msg = mTestHandler.getNextMessage();
- } while (!(msg.what == 999));
+ msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
+ assertNotNull("Message Time Out", msg);
ar = ((AsyncResult) msg.obj);
@@ -1921,11 +1846,10 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
// empty byte array
mGSMPhone.invokeOemRilRequestStrings(new String[0],
- mTestHandler.hh.obtainMessage(999));
+ mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
- do {
- msg = mTestHandler.getNextMessage();
- } while (!(msg.what == 999));
+ msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
+ assertNotNull("Message Time Out", msg);
ar = ((AsyncResult) msg.obj);
@@ -1938,11 +1862,10 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
s[0] = "Hello";
- mGSMPhone.invokeOemRilRequestStrings(s, mTestHandler.hh.obtainMessage(999));
+ mGSMPhone.invokeOemRilRequestStrings(s, mHandler.obtainMessage(EVENT_OEM_RIL_MESSAGE));
- do {
- msg = mTestHandler.getNextMessage();
- } while (!(msg.what == 999));
+ msg = mGSMTestHandler.waitForMessage(EVENT_OEM_RIL_MESSAGE);
+ assertNotNull("Message Time Out", msg);
ar = ((AsyncResult) msg.obj);
@@ -1976,21 +1899,15 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
private void runValidMmi(String dialString, boolean cancelable) throws CallStateException {
Connection c = mGSMPhone.dial(dialString);
assertNull(c);
-
- Message msg;
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_MMI_INITIATE);
-
+ Message msg = mGSMTestHandler.waitForMessage(EVENT_MMI_INITIATE);
+ assertNotNull("Message Time Out", msg);
// Should not be cancelable.
AsyncResult ar = (AsyncResult) msg.obj;
MmiCode mmi = (MmiCode) ar.result;
assertEquals(cancelable, mmi.isCancelable());
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_MMI_COMPLETE);
-
+ msg = mGSMTestHandler.waitForMessage(EVENT_MMI_COMPLETE);
+ assertNotNull("Message Time Out", msg);
}
private void runValidMmiWithConnect(String dialString) throws CallStateException {
@@ -2006,11 +1923,8 @@ public class GSMPhoneTest extends AndroidTestCase implements PerformanceTestCase
cn.hangup();
mRadioControl.resumeResponses();
+ assertNotNull(mGSMTestHandler.waitForMessage(EVENT_DISCONNECT));
- Message msg;
- do {
- msg = mTestHandler.getNextMessage();
- } while (msg.what != EVENT_DISCONNECT);
}
private void runNotMmi(String dialString) throws CallStateException {
diff --git a/tests/CoreTests/com/android/internal/telephony/gsm/GSMTestHandler.java b/tests/CoreTests/com/android/internal/telephony/gsm/GSMTestHandler.java
new file mode 100644
index 0000000..fb8a5d9
--- /dev/null
+++ b/tests/CoreTests/com/android/internal/telephony/gsm/GSMTestHandler.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.gsm;
+
+import android.content.Context;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+
+import com.android.internal.telephony.gsm.GSMPhone;
+import com.android.internal.telephony.test.SimulatedCommands;
+import com.android.internal.telephony.TestPhoneNotifier;
+
+/**
+ * This class creates a HandlerThread which waits for the various messages.
+ */
+public class GSMTestHandler extends HandlerThread implements Handler.Callback {
+
+ private Handler mHandler;
+ private Message mCurrentMessage;
+
+ private Boolean mMsgConsumed;
+ private SimulatedCommands sc;
+ private GSMPhone mGSMPhone;
+ private Context mContext;
+
+ private static final int FAIL_TIMEOUT_MILLIS = 5 * 1000;
+
+ public GSMTestHandler(Context context) {
+ super("GSMPhoneTest");
+ mMsgConsumed = false;
+ mContext = context;
+ }
+
+ @Override
+ protected void onLooperPrepared() {
+ sc = new SimulatedCommands();
+ mGSMPhone = new GSMPhone(mContext, sc, new TestPhoneNotifier(), true);
+ mHandler = new Handler(getLooper(), this);
+ synchronized (this) {
+ notifyAll();
+ }
+ }
+
+ public boolean handleMessage(Message msg) {
+ synchronized (this) {
+ mCurrentMessage = msg;
+ this.notifyAll();
+ while(!mMsgConsumed) {
+ try {
+ this.wait();
+ } catch (InterruptedException e) {}
+ }
+ mMsgConsumed = false;
+ }
+ return true;
+ }
+
+
+ public void cleanup() {
+ Looper looper = getLooper();
+ if (looper != null) looper.quit();
+ mHandler = null;
+ }
+
+ public Handler getHandler() {
+ return mHandler;
+ }
+
+ public SimulatedCommands getSimulatedCommands() {
+ return sc;
+ }
+
+ public GSMPhone getGSMPhone() {
+ return mGSMPhone;
+ }
+
+ public Message waitForMessage(int code) {
+ Message msg;
+ while(true) {
+ msg = null;
+ synchronized (this) {
+ try {
+ this.wait(FAIL_TIMEOUT_MILLIS);
+ } catch (InterruptedException e) {
+ }
+
+ // Check if timeout has occurred.
+ if (mCurrentMessage != null) {
+ // Consume the message
+ msg = Message.obtain();
+ msg.copyFrom(mCurrentMessage);
+ mCurrentMessage = null;
+ mMsgConsumed = true;
+ this.notifyAll();
+ }
+ }
+ if (msg == null || code == GSMPhoneTest.ANY_MESSAGE || msg.what == code) return msg;
+ }
+ }
+}
diff --git a/tests/CoreTests/com/android/internal/telephony/gsm/SMSDispatcherTest.java b/tests/CoreTests/com/android/internal/telephony/gsm/SMSDispatcherTest.java
index 84974ef..6db230f 100644
--- a/tests/CoreTests/com/android/internal/telephony/gsm/SMSDispatcherTest.java
+++ b/tests/CoreTests/com/android/internal/telephony/gsm/SMSDispatcherTest.java
@@ -16,7 +16,6 @@
package com.android.internal.telephony.gsm;
-import android.core.TestHandler;
import android.test.suitebuilder.annotation.MediumTest;
import com.android.internal.telephony.TestPhoneNotifier;
import com.android.internal.telephony.test.SimulatedCommands;
@@ -38,24 +37,24 @@ public class SMSDispatcherTest extends AndroidTestCase {
Iterator<SmsHeader.Element> elements;
String[] lines = new String[2];
-
- lines[0] = "+CMT: ,158";
+
+ lines[0] = "+CMT: ,158";
lines[1] = "07914140279510F6440A8111110301003BF56080426101748A8C0B05040B"
+ "8423F000035502010106276170706C69636174696F6E2F766E642E776170"
+ "2E6D6D732D6D65737361676500AF848D0185B4848C8298524F347839776F"
+ "7547514D4141424C3641414141536741415A4B554141414141008D908918"
+ "802B31363530323438363137392F545950453D504C4D4E008A808E028000"
+ "88058103093A8083687474703A2F2F36";
-
+
sms = SmsMessage.newFromCMT(lines);
header = sms.getUserDataHeader();
assertNotNull(header);
assertNotNull(sms.getUserData());
-
+
elements = header.getElements().iterator();
assertNotNull(elements);
}
-
+
@MediumTest
public void testCMT2() throws Exception {
SmsMessage sms;
@@ -63,7 +62,7 @@ public class SMSDispatcherTest extends AndroidTestCase {
Iterator<SmsHeader.Element> elements;
String[] lines = new String[2];
-
+
lines[0] = "+CMT: ,77";
lines[1] = "07914140279510F6440A8111110301003BF56080426101848A3B0B05040B8423F"
@@ -75,7 +74,7 @@ public class SMSDispatcherTest extends AndroidTestCase {
System.out.println("header = " + header);
assertNotNull(header);
assertNotNull(sms.getUserData());
-
+
elements = header.getElements().iterator();
assertNotNull(elements);
}
diff --git a/tests/CoreTests/com/android/internal/telephony/gsm/SimPhoneBookTest.java b/tests/CoreTests/com/android/internal/telephony/gsm/SimPhoneBookTest.java
index 53fdd51..db55bca 100644
--- a/tests/CoreTests/com/android/internal/telephony/gsm/SimPhoneBookTest.java
+++ b/tests/CoreTests/com/android/internal/telephony/gsm/SimPhoneBookTest.java
@@ -16,7 +16,6 @@
package com.android.internal.telephony.gsm;
-import android.core.TestHandler;
import android.os.ServiceManager;
import android.test.suitebuilder.annotation.Suppress;
@@ -48,21 +47,21 @@ public class SimPhoneBookTest extends TestCase {
AdnRecord originalAdn = null;
// We need to maintain the state of the SIM before and after the test.
// Since this test doesn't mock the SIM we try to get a valid ADN record,
- // for 3 tries and if this fails, we bail out.
+ // for 3 tries and if this fails, we bail out.
for (adnIndex = 3 ; adnIndex >= 1; adnIndex--) {
listIndex = adnIndex - 1; // listIndex is zero based.
originalAdn = adnRecordList.get(listIndex);
assertNotNull("Original Adn is Null.", originalAdn);
assertNotNull("Original Adn alpha tag is null.", originalAdn.getAlphaTag());
assertNotNull("Original Adn number is null.", originalAdn.getNumber());
-
- if (originalAdn.getNumber().length() > 0 &&
- originalAdn.getAlphaTag().length() > 0) {
+
+ if (originalAdn.getNumber().length() > 0 &&
+ originalAdn.getAlphaTag().length() > 0) {
break;
}
}
if (adnIndex == 0) return;
-
+
AdnRecord emptyAdn = new AdnRecord("", "");
AdnRecord firstAdn = new AdnRecord("John", "4085550101");
AdnRecord secondAdn = new AdnRecord("Andy", "6505550102");
diff --git a/tests/FrameworkTest/AndroidManifest.xml b/tests/FrameworkTest/AndroidManifest.xml
index c0824c0..c70302b 100644
--- a/tests/FrameworkTest/AndroidManifest.xml
+++ b/tests/FrameworkTest/AndroidManifest.xml
@@ -571,6 +571,14 @@
</intent-filter>
</activity>
+ <activity android:name=".listview.ListWithFirstScreenUnSelectable" android:label="ListWithFirstScreenUnSelectable">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+
<activity android:name=".listview.ListWithSeparators" android:label="ListWithSeparators">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/core/java/com/android/internal/os/HandlerHelper.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithFirstScreenUnSelectable.java
index d810e6b..4ad72fd 100644
--- a/core/java/com/android/internal/os/HandlerHelper.java
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithFirstScreenUnSelectable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,25 +14,20 @@
* limitations under the License.
*/
-package com.android.internal.os;
+package com.android.frameworktest.listview;
-import android.os.Handler;
-import android.os.HandlerInterface;
-import android.os.Message;
+import com.android.frameworktest.util.ListScenario;
-/** @hide */
-public class HandlerHelper extends Handler
-{
- public HandlerHelper(HandlerInterface target)
- {
- mTarget = target;
- }
+/**
+ * The first item is unselectable, and takes up the whole screen.
+ */
+public class ListWithFirstScreenUnSelectable extends ListScenario {
- public void handleMessage(Message msg)
- {
- mTarget.handleMessage(msg);
- }
+ @Override
+ protected void init(Params params) {
+ params.setItemScreenSizeFactor(1.2)
+ .setNumItems(2)
+ .setPositionsUnselectable(0);
- private HandlerInterface mTarget;
+ }
}
-
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/ScrollingThroughListOfFocusablesTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/ScrollingThroughListOfFocusablesTest.java
index 2134e04..07916ee 100644
--- a/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/ScrollingThroughListOfFocusablesTest.java
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/ScrollingThroughListOfFocusablesTest.java
@@ -87,9 +87,12 @@ public class ScrollingThroughListOfFocusablesTest extends InstrumentationTestCas
assertEquals(0, mListView.getSelectedItemPosition());
InternalSelectionView view = (InternalSelectionView)
mListView.getSelectedView();
- assertEquals("bottom of view should be just above fading edge",
- mListView.getBottom() - mListView.getVerticalFadingEdgeLength(),
- view.getBottom());
+
+ // 1 pixel tolerance in case height / 4 is not an even number
+ final int fadingEdge = mListView.getBottom() - mListView.getVerticalFadingEdgeLength();
+ assertTrue("bottom of view should be just above fading edge",
+ view.getBottom() >= fadingEdge - 1 &&
+ view.getBottom() <= fadingEdge);
}
@@ -138,9 +141,9 @@ public class ScrollingThroughListOfFocusablesTest extends InstrumentationTestCas
view.getRectForRow(mTempRect, mNumRowsPerItem - 1);
mListView.offsetDescendantRectToMyCoords(view, mTempRect);
- assertEquals("bottom of last row of last item should be at " +
+ assertTrue("bottom of last row of last item should be at " +
"the bottom of the list view (no fading edge)",
- mListView.getBottom(), mTempRect.bottom);
+ mListView.getBottom() - mListView.getVerticalFadingEdgeLength() < mTempRect.bottom);
}
@LargeTest
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithFirstScreenUnSelectableTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithFirstScreenUnSelectableTest.java
new file mode 100644
index 0000000..307c39d
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithFirstScreenUnSelectableTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.frameworktest.listview.arrowscroll;
+
+import com.android.frameworktest.listview.ListWithFirstScreenUnSelectable;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.KeyEvent;
+import android.widget.ListView;
+import android.widget.AdapterView;
+
+public class ListWithFirstScreenUnSelectableTest
+ extends ActivityInstrumentationTestCase2<ListWithFirstScreenUnSelectable> {
+ private ListView mListView;
+
+ public ListWithFirstScreenUnSelectableTest() {
+ super("com.android.frameworktest", ListWithFirstScreenUnSelectable.class);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ setActivityInitialTouchMode(true);
+
+ mListView = getActivity().getListView();
+ }
+
+ public void testPreconditions() {
+ assertTrue(mListView.isInTouchMode());
+ assertEquals(1, mListView.getChildCount());
+ assertFalse(mListView.getAdapter().isEnabled(0));
+ assertEquals(AdapterView.INVALID_POSITION, mListView.getSelectedItemPosition());
+ }
+
+ public void testRessurectSelection() {
+ sendKeys(KeyEvent.KEYCODE_SPACE);
+ assertEquals(AdapterView.INVALID_POSITION, mListView.getSelectedItemPosition());
+ }
+
+ public void testScrollUpDoesNothing() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals(AdapterView.INVALID_POSITION, mListView.getSelectedItemPosition());
+ assertEquals(1, mListView.getChildCount());
+ assertEquals(0, mListView.getFirstVisiblePosition());
+ }
+
+ public void testScrollDownPansNextItemOn() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals(2, mListView.getChildCount());
+ }
+}