summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk10
-rw-r--r--api/current.txt215
-rw-r--r--cmds/am/src/com/android/commands/am/Am.java12
-rw-r--r--core/java/android/app/ActivityManagerNative.java6
-rw-r--r--core/java/android/app/ActivityThread.java34
-rw-r--r--core/java/android/app/ApplicationThreadNative.java6
-rw-r--r--core/java/android/app/ContextImpl.java6
-rw-r--r--core/java/android/app/FragmentManager.java1
-rw-r--r--core/java/android/app/IActivityManager.java2
-rw-r--r--core/java/android/app/IApplicationThread.java2
-rw-r--r--core/java/android/app/StatusBarManager.java5
-rw-r--r--core/java/android/appwidget/AppWidgetManager.java8
-rw-r--r--core/java/android/appwidget/AppWidgetProviderInfo.java4
-rw-r--r--core/java/android/bluetooth/BluetoothDeviceProfileState.java46
-rw-r--r--core/java/android/bluetooth/BluetoothHeadset.java2
-rw-r--r--core/java/android/content/ComponentCallbacks.java7
-rw-r--r--core/java/android/content/Context.java9
-rw-r--r--core/java/android/inputmethodservice/ExtractEditLayout.java5
-rw-r--r--core/java/android/net/ConnectivityManager.java11
-rw-r--r--core/java/android/net/EthernetDataTracker.java4
-rw-r--r--core/java/android/net/IConnectivityManager.aidl2
-rw-r--r--core/java/android/net/INetworkManagementEventObserver.aidl10
-rw-r--r--core/java/android/net/LinkProperties.java4
-rw-r--r--core/java/android/net/VpnBuilder.java413
-rw-r--r--core/java/android/nfc/INfcAdapter.aidl5
-rw-r--r--core/java/android/nfc/INfcTag.aidl1
-rw-r--r--core/java/android/nfc/NfcAdapter.java47
-rw-r--r--core/java/android/nfc/tech/IsoDep.java18
-rw-r--r--core/java/android/nfc/tech/MifareClassic.java18
-rw-r--r--core/java/android/nfc/tech/MifareUltralight.java18
-rw-r--r--core/java/android/nfc/tech/NfcA.java18
-rw-r--r--core/java/android/nfc/tech/NfcF.java18
-rw-r--r--core/java/android/os/Handler.java9
-rw-r--r--core/java/android/os/INetworkManagementService.aidl2
-rw-r--r--core/java/android/os/Looper.java14
-rw-r--r--core/java/android/os/SystemClock.java18
-rw-r--r--core/java/android/preference/CheckBoxPreference.java4
-rw-r--r--core/java/android/preference/PreferenceActivity.java10
-rw-r--r--core/java/android/preference/SwitchPreference.java4
-rw-r--r--core/java/android/preference/TwoStatePreference.java45
-rw-r--r--core/java/android/provider/ContactsContract.java7
-rw-r--r--core/java/android/provider/Settings.java88
-rw-r--r--core/java/android/server/BluetoothBondState.java33
-rwxr-xr-xcore/java/android/server/BluetoothService.java18
-rw-r--r--core/java/android/service/textservice/SpellCheckerService.java140
-rw-r--r--core/java/android/service/textservice/SpellCheckerSession.java284
-rw-r--r--core/java/android/speech/tts/AudioPlaybackHandler.java46
-rw-r--r--core/java/android/speech/tts/SynthesisMessageParams.java2
-rw-r--r--core/java/android/util/JsonReader.java6
-rw-r--r--core/java/android/view/CollapsibleActionView.java41
-rw-r--r--core/java/android/view/DisplayList.java9
-rw-r--r--core/java/android/view/GLES20Canvas.java51
-rw-r--r--core/java/android/view/GLES20DisplayList.java86
-rw-r--r--core/java/android/view/GLES20RecordingCanvas.java96
-rw-r--r--core/java/android/view/HardwareRenderer.java6
-rw-r--r--core/java/android/view/View.java20
-rw-r--r--core/java/android/view/ViewDebug.java205
-rw-r--r--core/java/android/view/ViewGroup.java11
-rw-r--r--core/java/android/view/animation/AlphaAnimation.java8
-rw-r--r--core/java/android/view/animation/Animation.java9
-rw-r--r--core/java/android/view/animation/AnimationSet.java26
-rw-r--r--core/java/android/view/textservice/SpellCheckerInfo.aidl19
-rw-r--r--core/java/android/view/textservice/SpellCheckerInfo.java112
-rw-r--r--core/java/android/view/textservice/SuggestionsInfo.aidl19
-rw-r--r--core/java/android/view/textservice/SuggestionsInfo.java186
-rw-r--r--core/java/android/view/textservice/TextInfo.aidl19
-rw-r--r--core/java/android/view/textservice/TextInfo.java117
-rw-r--r--core/java/android/view/textservice/TextServicesManager.java100
-rw-r--r--core/java/android/webkit/WebView.java26
-rw-r--r--core/java/android/webkit/WebViewCore.java48
-rw-r--r--core/java/android/webkit/ZoomManager.java2
-rw-r--r--core/java/android/widget/AbsListView.java3
-rw-r--r--core/java/android/widget/ActivityChooserModel.java6
-rw-r--r--core/java/android/widget/ActivityChooserView.java2
-rw-r--r--core/java/android/widget/AdapterView.java19
-rw-r--r--core/java/android/widget/CheckedTextView.java32
-rw-r--r--core/java/android/widget/GridLayout.java2
-rw-r--r--core/java/android/widget/ImageView.java13
-rw-r--r--core/java/android/widget/TextView.java137
-rw-r--r--core/java/com/android/internal/app/AlertController.java2
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl2
-rw-r--r--core/java/com/android/internal/statusbar/StatusBarIcon.java25
-rw-r--r--core/java/com/android/internal/textservice/ISpellCheckerService.aidl29
-rw-r--r--core/java/com/android/internal/textservice/ISpellCheckerSession.aidl28
-rw-r--r--core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl26
-rw-r--r--core/java/com/android/internal/textservice/ITextServicesManager.aidl35
-rw-r--r--core/java/com/android/internal/textservice/ITextServicesSessionListener.aidl29
-rw-r--r--core/java/com/android/internal/view/menu/MenuBuilder.java63
-rw-r--r--core/java/com/android/internal/view/menu/MenuItemImpl.java3
-rw-r--r--core/java/com/android/internal/view/menu/SubMenuBuilder.java9
-rw-r--r--core/java/com/android/internal/widget/ActionBarView.java28
-rw-r--r--core/jni/android_media_AudioRecord.cpp31
-rw-r--r--core/jni/android_net_wifi_Wifi.cpp60
-rw-r--r--core/jni/android_os_SystemClock.cpp36
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp23
-rw-r--r--core/res/AndroidManifest.xml9
-rw-r--r--core/res/res/anim/screen_rotate_minus_90_enter.xml5
-rw-r--r--core/res/res/anim/screen_rotate_plus_90_enter.xml5
-rw-r--r--core/res/res/drawable-hdpi/text_edit_suggestions_top_window.9.pngbin943 -> 0 bytes
-rw-r--r--core/res/res/drawable-hdpi/text_edit_suggestions_window.9.png (renamed from core/res/res/drawable-hdpi/text_edit_suggestions_bottom_window.9.png)bin929 -> 929 bytes
-rw-r--r--core/res/res/drawable-mdpi/text_edit_suggestions_top_window.9.pngbin585 -> 0 bytes
-rw-r--r--core/res/res/drawable-mdpi/text_edit_suggestions_window.9.png (renamed from core/res/res/drawable-mdpi/text_edit_suggestions_bottom_window.9.png)bin605 -> 605 bytes
-rw-r--r--core/res/res/layout/text_edit_suggestion_item.xml2
-rw-r--r--core/res/res/layout/text_edit_suggestions_bottom_window.xml23
-rw-r--r--core/res/res/layout/text_edit_suggestions_window.xml (renamed from core/res/res/layout/text_edit_suggestions_top_window.xml)2
-rwxr-xr-xcore/res/res/values/attrs.xml10
-rw-r--r--core/res/res/values/public.xml3
-rwxr-xr-xcore/res/res/values/strings.xml25
-rw-r--r--core/res/res/values/styles.xml3
-rw-r--r--core/res/res/values/themes.xml3
-rw-r--r--docs/html/guide/appendix/api-levels.jd79
-rw-r--r--docs/html/guide/developing/tools/adb.jd2
-rw-r--r--docs/html/guide/topics/intents/intents-filters.jd2
-rw-r--r--docs/html/guide/topics/manifest/activity-element.jd4
-rw-r--r--docs/html/guide/topics/providers/content-providers.jd2
-rw-r--r--docs/html/sdk/android-3.1.jd6
-rw-r--r--docs/html/sdk/android-3.2.jd737
-rw-r--r--docs/html/sdk/api_diff/13/changes.html45
-rw-r--r--docs/html/sdk/api_diff/13/changes/alldiffs_index_additions.html663
-rw-r--r--docs/html/sdk/api_diff/13/changes/alldiffs_index_all.html941
-rw-r--r--docs/html/sdk/api_diff/13/changes/alldiffs_index_changes.html561
-rw-r--r--docs/html/sdk/api_diff/13/changes/alldiffs_index_removals.html61
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.Manifest.permission.html122
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.R.attr.html136
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.R.style.html395
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.app.Activity.html195
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.app.ActivityGroup.html108
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.app.Fragment.html136
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.app.FragmentManager.html122
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.app.FragmentTransaction.html136
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.app.KeyguardManager.KeyguardLock.html108
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.app.KeyguardManager.html135
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.app.LocalActivityManager.html108
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.app.TabActivity.html108
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.content.pm.ActivityInfo.html129
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.content.pm.ApplicationInfo.html136
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.content.pm.PackageManager.html143
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.content.res.Configuration.html164
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.graphics.Point.html152
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.graphics.PointF.html152
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.hardware.usb.UsbDeviceConnection.html122
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.net.ConnectivityManager.html129
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.os.Binder.html122
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.os.Build.VERSION_CODES.html122
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.os.IBinder.html137
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.os.ParcelFileDescriptor.html136
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.os.PowerManager.html124
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.telephony.TelephonyManager.html122
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.util.DisplayMetrics.html122
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.view.Display.html157
-rw-r--r--docs/html/sdk/api_diff/13/changes/android.view.KeyEvent.html122
-rw-r--r--docs/html/sdk/api_diff/13/changes/changes-summary.html205
-rw-r--r--docs/html/sdk/api_diff/13/changes/classes_index_additions.html73
-rw-r--r--docs/html/sdk/api_diff/13/changes/classes_index_all.html300
-rw-r--r--docs/html/sdk/api_diff/13/changes/classes_index_changes.html298
-rw-r--r--docs/html/sdk/api_diff/13/changes/classes_index_removals.html61
-rw-r--r--docs/html/sdk/api_diff/13/changes/constructors_index_additions.html61
-rw-r--r--docs/html/sdk/api_diff/13/changes/constructors_index_all.html61
-rw-r--r--docs/html/sdk/api_diff/13/changes/constructors_index_changes.html61
-rw-r--r--docs/html/sdk/api_diff/13/changes/constructors_index_removals.html61
-rw-r--r--docs/html/sdk/api_diff/13/changes/fields_index_additions.html363
-rw-r--r--docs/html/sdk/api_diff/13/changes/fields_index_all.html365
-rw-r--r--docs/html/sdk/api_diff/13/changes/fields_index_changes.html67
-rw-r--r--docs/html/sdk/api_diff/13/changes/fields_index_removals.html61
-rw-r--r--docs/html/sdk/api_diff/13/changes/jdiff_help.html134
-rw-r--r--docs/html/sdk/api_diff/13/changes/jdiff_statistics.html382
-rw-r--r--docs/html/sdk/api_diff/13/changes/jdiff_topleftframe.html63
-rw-r--r--docs/html/sdk/api_diff/13/changes/methods_index_additions.html225
-rw-r--r--docs/html/sdk/api_diff/13/changes/methods_index_all.html298
-rw-r--r--docs/html/sdk/api_diff/13/changes/methods_index_changes.html158
-rw-r--r--docs/html/sdk/api_diff/13/changes/methods_index_removals.html61
-rw-r--r--docs/html/sdk/api_diff/13/changes/packages_index_additions.html63
-rw-r--r--docs/html/sdk/api_diff/13/changes/packages_index_all.html75
-rw-r--r--docs/html/sdk/api_diff/13/changes/packages_index_changes.html75
-rw-r--r--docs/html/sdk/api_diff/13/changes/packages_index_removals.html63
-rw-r--r--docs/html/sdk/api_diff/13/changes/pkg_android.app.html190
-rw-r--r--docs/html/sdk/api_diff/13/changes/pkg_android.content.pm.html133
-rw-r--r--docs/html/sdk/api_diff/13/changes/pkg_android.content.res.html119
-rw-r--r--docs/html/sdk/api_diff/13/changes/pkg_android.graphics.html126
-rw-r--r--docs/html/sdk/api_diff/13/changes/pkg_android.hardware.usb.html119
-rw-r--r--docs/html/sdk/api_diff/13/changes/pkg_android.html133
-rw-r--r--docs/html/sdk/api_diff/13/changes/pkg_android.net.html119
-rw-r--r--docs/html/sdk/api_diff/13/changes/pkg_android.os.html162
-rw-r--r--docs/html/sdk/api_diff/13/changes/pkg_android.telephony.html119
-rw-r--r--docs/html/sdk/api_diff/13/changes/pkg_android.util.html119
-rw-r--r--docs/html/sdk/api_diff/13/changes/pkg_android.view.html126
-rw-r--r--docs/html/sdk/api_diff/13/stylesheet-jdiff.css44
-rw-r--r--docs/html/sdk/sdk_toc.cs8
-rw-r--r--graphics/jni/android_renderscript_RenderScript.cpp1
-rw-r--r--include/gui/ISurfaceTexture.h12
-rw-r--r--include/gui/SurfaceTexture.h23
-rw-r--r--include/gui/SurfaceTextureClient.h4
-rw-r--r--include/media/AudioEffect.h8
-rw-r--r--include/media/AudioSystem.h5
-rw-r--r--include/media/IAudioPolicyService.h5
-rw-r--r--include/media/IMediaRecorder.h2
-rw-r--r--include/media/MediaProfiles.h46
-rw-r--r--include/media/MediaRecorderBase.h2
-rw-r--r--include/media/mediarecorder.h10
-rw-r--r--include/media/mediascanner.h40
-rw-r--r--include/media/stagefright/DataSource.h5
-rw-r--r--include/media/stagefright/HardwareAPI.h7
-rw-r--r--include/media/stagefright/MediaSource.h2
-rw-r--r--include/media/stagefright/StagefrightMediaScanner.h6
-rw-r--r--include/media/stagefright/SurfaceMediaSource.h350
-rw-r--r--include/media/stagefright/openmax/OMX_IVCommon.h411
-rw-r--r--include/surfaceflinger/ISurfaceComposerClient.h3
-rw-r--r--include/surfaceflinger/Surface.h33
-rw-r--r--include/ui/PixelFormat.h10
-rw-r--r--include/utils/Pool.h71
-rw-r--r--libs/gui/ISurfaceComposerClient.cpp6
-rw-r--r--libs/gui/ISurfaceTexture.cpp28
-rw-r--r--libs/gui/Surface.cpp74
-rw-r--r--libs/gui/SurfaceComposerClient.cpp2
-rw-r--r--libs/gui/SurfaceTexture.cpp88
-rw-r--r--libs/gui/SurfaceTextureClient.cpp15
-rw-r--r--libs/gui/tests/SurfaceTextureClient_test.cpp5
-rw-r--r--libs/gui/tests/SurfaceTexture_test.cpp151
-rw-r--r--libs/hwui/DisplayListRenderer.cpp11
-rw-r--r--libs/hwui/DisplayListRenderer.h4
-rw-r--r--libs/ui/FramebufferNativeWindow.cpp28
-rw-r--r--libs/utils/Android.mk1
-rw-r--r--libs/utils/Pool.cpp37
-rw-r--r--media/java/android/media/AudioRecord.java24
-rw-r--r--media/java/android/media/MediaRecorder.java97
-rw-r--r--media/java/android/media/videoeditor/MediaArtistNativeHelper.java9
-rwxr-xr-xmedia/java/android/media/videoeditor/MediaImageItem.java117
-rwxr-xr-xmedia/java/android/media/videoeditor/MediaProperties.java35
-rwxr-xr-xmedia/java/android/media/videoeditor/MediaVideoItem.java16
-rwxr-xr-xmedia/java/android/media/videoeditor/VideoEditor.java4
-rwxr-xr-xmedia/java/android/media/videoeditor/VideoEditorImpl.java22
-rwxr-xr-xmedia/java/android/media/videoeditor/VideoEditorProfile.java82
-rw-r--r--media/jni/android_media_MediaProfiles.cpp52
-rw-r--r--media/jni/android_media_MediaRecorder.cpp17
-rw-r--r--media/jni/android_media_MediaScanner.cpp57
-rwxr-xr-xmedia/jni/mediaeditor/VideoEditorClasses.cpp7
-rwxr-xr-xmedia/jni/mediaeditor/VideoEditorPropertiesMain.cpp12
-rw-r--r--media/libeffects/data/audio_effects.conf69
-rw-r--r--media/libeffects/factory/Android.mk3
-rw-r--r--media/libeffects/factory/EffectsFactory.c1
-rw-r--r--media/libeffects/factory/EffectsFactory.h7
-rw-r--r--media/libmedia/AudioEffect.cpp14
-rw-r--r--media/libmedia/AudioRecord.cpp21
-rw-r--r--media/libmedia/AudioSystem.cpp13
-rw-r--r--media/libmedia/IAudioPolicyService.cpp16
-rw-r--r--media/libmedia/IMediaRecorder.cpp30
-rw-r--r--media/libmedia/MediaProfiles.cpp64
-rw-r--r--media/libmedia/MediaScanner.cpp148
-rw-r--r--media/libmedia/MediaScannerClient.cpp6
-rw-r--r--media/libmedia/mediaplayer.cpp2
-rw-r--r--media/libmedia/mediarecorder.cpp33
-rw-r--r--media/libmediaplayerservice/MediaRecorderClient.cpp15
-rw-r--r--media/libmediaplayerservice/MediaRecorderClient.h68
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp109
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.h18
-rw-r--r--media/libstagefright/Android.mk1
-rwxr-xr-xmedia/libstagefright/CameraSource.cpp50
-rw-r--r--media/libstagefright/NuCachedSource2.cpp61
-rw-r--r--media/libstagefright/StagefrightMediaScanner.cpp115
-rw-r--r--media/libstagefright/SurfaceMediaSource.cpp756
-rw-r--r--media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp34
-rw-r--r--media/libstagefright/include/ChromiumHTTPDataSource.h2
-rw-r--r--media/libstagefright/include/NuCachedSource2.h6
-rw-r--r--media/libstagefright/tests/Android.mk53
-rw-r--r--media/libstagefright/tests/DummyRecorder.cpp91
-rw-r--r--media/libstagefright/tests/DummyRecorder.h58
-rw-r--r--media/libstagefright/tests/SurfaceMediaSource_test.cpp349
-rw-r--r--packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml2
-rw-r--r--packages/SystemUI/res/layout-sw600dp/status_bar.xml4
-rw-r--r--packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_item.xml6
-rw-r--r--packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml6
-rw-r--r--packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml34
-rw-r--r--packages/SystemUI/res/layout/navigation_bar.xml7
-rw-r--r--packages/SystemUI/res/values/config.xml2
-rw-r--r--packages/SystemUI/res/values/strings.xml131
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java151
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityContentDescriptions.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java50
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationArea.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java83
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanelTitle.java82
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPeekPanel.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java2
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java7
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java17
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java88
-rw-r--r--services/audioflinger/AudioFlinger.cpp524
-rw-r--r--services/audioflinger/AudioFlinger.h157
-rw-r--r--services/audioflinger/AudioPolicyService.cpp396
-rw-r--r--services/audioflinger/AudioPolicyService.h62
-rw-r--r--services/input/InputDispatcher.cpp385
-rw-r--r--services/input/InputDispatcher.h164
-rw-r--r--services/java/com/android/server/AppWidgetService.java6
-rw-r--r--services/java/com/android/server/ConnectivityService.java95
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java34
-rw-r--r--services/java/com/android/server/NetworkManagementService.java90
-rwxr-xr-xservices/java/com/android/server/NotificationManagerService.java2
-rw-r--r--services/java/com/android/server/StatusBarManagerService.java10
-rw-r--r--services/java/com/android/server/SystemServer.java11
-rw-r--r--services/java/com/android/server/TextServicesManagerService.java346
-rw-r--r--services/java/com/android/server/ThrottleService.java1
-rw-r--r--services/java/com/android/server/WifiService.java8
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java52
-rw-r--r--services/java/com/android/server/am/ActivityStack.java1
-rw-r--r--services/java/com/android/server/am/ProcessRecord.java2
-rw-r--r--services/java/com/android/server/connectivity/Tethering.java177
-rw-r--r--services/java/com/android/server/connectivity/Vpn.java4
-rw-r--r--services/java/com/android/server/usb/UsbDeviceManager.java45
-rw-r--r--services/java/com/android/server/wm/BlackFrame.java4
-rw-r--r--services/jni/com_android_server_UsbDeviceManager.cpp15
-rw-r--r--services/sensorservice/SensorService.cpp6
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp3
-rw-r--r--services/surfaceflinger/SurfaceTextureLayer.cpp6
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnectionTracker.java22
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneBase.java4
-rw-r--r--telephony/java/com/android/internal/telephony/RILConstants.java2
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java50
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java8
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java35
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java2
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java3
-rw-r--r--tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java2
-rw-r--r--tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java8
-rw-r--r--tests/TileBenchmark/AndroidManifest.xml6
-rw-r--r--tests/TileBenchmark/res/layout/main.xml19
-rw-r--r--tests/TileBenchmark/res/values/colors.xml17
-rw-r--r--tests/TileBenchmark/res/values/strings.xml24
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java25
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java37
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java122
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java125
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java35
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/TileData.java18
-rw-r--r--tools/aapt/AaptAssets.cpp4
-rw-r--r--tools/aapt/AaptAssets.h5
-rw-r--r--tools/aapt/Android.mk2
-rw-r--r--tools/aapt/Bundle.h12
-rw-r--r--tools/aapt/CacheUpdater.h107
-rw-r--r--tools/aapt/Command.cpp67
-rw-r--r--tools/aapt/CrunchCache.cpp104
-rw-r--r--tools/aapt/CrunchCache.h102
-rw-r--r--tools/aapt/DirectoryWalker.h98
-rw-r--r--tools/aapt/FileFinder.cpp113
-rw-r--r--tools/aapt/FileFinder.h80
-rw-r--r--tools/aapt/Images.cpp121
-rw-r--r--tools/aapt/Images.h10
-rw-r--r--tools/aapt/Main.cpp23
-rw-r--r--tools/aapt/Main.h14
-rw-r--r--tools/aapt/Package.cpp19
-rw-r--r--tools/aapt/Resource.cpp69
-rw-r--r--tools/aapt/ZipFile.h2
-rw-r--r--tools/aapt/tests/CrunchCache_test.cpp97
-rw-r--r--tools/aapt/tests/FileFinder_test.cpp101
-rw-r--r--tools/aapt/tests/MockCacheUpdater.h40
-rw-r--r--tools/aapt/tests/MockDirectoryWalker.h85
-rw-r--r--tools/aapt/tests/MockFileFinder.h55
-rw-r--r--wifi/java/android/net/wifi/WifiNative.java22
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java168
-rw-r--r--wifi/java/android/net/wifi/WifiWatchdogStateMachine.java320
372 files changed, 23367 insertions, 2878 deletions
diff --git a/Android.mk b/Android.mk
index 335fb732b214..3b0fc599ed17 100644
--- a/Android.mk
+++ b/Android.mk
@@ -158,6 +158,11 @@ LOCAL_SRC_FILES += \
core/java/com/android/internal/os/IResultReceiver.aidl \
core/java/com/android/internal/statusbar/IStatusBar.aidl \
core/java/com/android/internal/statusbar/IStatusBarService.aidl \
+ core/java/com/android/internal/textservice/ISpellCheckerService.aidl \
+ core/java/com/android/internal/textservice/ISpellCheckerSession.aidl \
+ core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl \
+ core/java/com/android/internal/textservice/ITextServicesManager.aidl \
+ core/java/com/android/internal/textservice/ITextServicesSessionListener.aidl \
core/java/com/android/internal/view/IInputContext.aidl \
core/java/com/android/internal/view/IInputContextCallback.aidl \
core/java/com/android/internal/view/IInputMethod.aidl \
@@ -266,6 +271,11 @@ aidl_files := \
frameworks/base/core/java/android/view/Surface.aidl \
frameworks/base/core/java/android/view/WindowManager.aidl \
frameworks/base/core/java/android/widget/RemoteViews.aidl \
+ frameworks/base/core/java/com/android/internal/textservice/ISpellCheckerService.aidl \
+ frameworks/base/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl \
+ frameworks/base/core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl \
+ frameworks/base/core/java/com/android/internal/textservice/ITextServicesManager.aidl \
+ frameworks/base/core/java/com/android/internal/textservice/ITextServicesSessionListener.aidl \
frameworks/base/core/java/com/android/internal/view/IInputContext.aidl \
frameworks/base/core/java/com/android/internal/view/IInputMethod.aidl \
frameworks/base/core/java/com/android/internal/view/IInputMethodCallback.aidl \
diff --git a/api/current.txt b/api/current.txt
index 8fc3a7263a93..2514efdb4910 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -21,6 +21,7 @@ package android {
field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
+ field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
field public static final java.lang.String BIND_WALLPAPER = "android.permission.BIND_WALLPAPER";
field public static final java.lang.String BLUETOOTH = "android.permission.BLUETOOTH";
field public static final java.lang.String BLUETOOTH_ADMIN = "android.permission.BLUETOOTH_ADMIN";
@@ -184,14 +185,14 @@ package android {
public static final class R.attr {
ctor public R.attr();
field public static final int absListViewStyle = 16842858; // 0x101006a
- field public static final int accessibilityEventTypes = 16843648; // 0x1010380
- field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
- field public static final int accessibilityFlags = 16843652; // 0x1010384
+ field public static final int accessibilityEventTypes = 16843647; // 0x101037f
+ field public static final int accessibilityFeedbackType = 16843649; // 0x1010381
+ field public static final int accessibilityFlags = 16843651; // 0x1010383
field public static final int accountPreferences = 16843423; // 0x101029f
field public static final int accountType = 16843407; // 0x101028f
field public static final int action = 16842797; // 0x101002d
field public static final int actionBarSize = 16843499; // 0x10102eb
- field public static final int actionBarSplitStyle = 16843670; // 0x1010396
+ field public static final int actionBarSplitStyle = 16843669; // 0x1010395
field public static final int actionBarStyle = 16843470; // 0x10102ce
field public static final int actionBarTabBarStyle = 16843508; // 0x10102f4
field public static final int actionBarTabStyle = 16843507; // 0x10102f3
@@ -207,10 +208,10 @@ package android {
field public static final int actionModeCopyDrawable = 16843538; // 0x1010312
field public static final int actionModeCutDrawable = 16843537; // 0x1010311
field public static final int actionModePasteDrawable = 16843539; // 0x1010313
- field public static final int actionModeSelectAllDrawable = 16843646; // 0x101037e
- field public static final int actionModeStyle = 16843682; // 0x10103a2
+ field public static final int actionModeSelectAllDrawable = 16843645; // 0x101037d
+ field public static final int actionModeStyle = 16843681; // 0x10103a1
field public static final int actionOverflowButtonStyle = 16843510; // 0x10102f6
- field public static final int actionProviderClass = 16843671; // 0x1010397
+ field public static final int actionProviderClass = 16843670; // 0x1010396
field public static final int actionViewClass = 16843516; // 0x10102fc
field public static final int activatedBackgroundIndicator = 16843517; // 0x10102fd
field public static final int activityCloseEnterAnimation = 16842938; // 0x10100ba
@@ -222,7 +223,7 @@ package android {
field public static final int alertDialogIcon = 16843605; // 0x1010355
field public static final int alertDialogStyle = 16842845; // 0x101005d
field public static final int alertDialogTheme = 16843529; // 0x1010309
- field public static final int alignmentMode = 16843640; // 0x1010378
+ field public static final int alignmentMode = 16843639; // 0x1010377
field public static final int allContactsName = 16843468; // 0x10102cc
field public static final int allowBackup = 16843392; // 0x1010280
field public static final int allowClearUserData = 16842757; // 0x1010005
@@ -256,8 +257,8 @@ package android {
field public static final int background = 16842964; // 0x10100d4
field public static final int backgroundDimAmount = 16842802; // 0x1010032
field public static final int backgroundDimEnabled = 16843295; // 0x101021f
- field public static final int backgroundSplit = 16843673; // 0x1010399
- field public static final int backgroundStacked = 16843672; // 0x1010398
+ field public static final int backgroundSplit = 16843672; // 0x1010398
+ field public static final int backgroundStacked = 16843671; // 0x1010397
field public static final int backupAgent = 16843391; // 0x101027f
field public static final int baseline = 16843548; // 0x101031c
field public static final int baselineAlignBottom = 16843042; // 0x1010122
@@ -266,7 +267,7 @@ package android {
field public static final int borderlessButtonStyle = 16843563; // 0x101032b
field public static final int bottom = 16843184; // 0x10101b0
field public static final int bottomBright = 16842957; // 0x10100cd
- field public static final int bottomChevronDrawable = 16843659; // 0x101038b
+ field public static final int bottomChevronDrawable = 16843658; // 0x101038a
field public static final int bottomDark = 16842953; // 0x10100c9
field public static final int bottomLeftRadius = 16843179; // 0x10101ab
field public static final int bottomMedium = 16842958; // 0x10100ce
@@ -285,7 +286,7 @@ package android {
field public static final int cacheColorHint = 16843009; // 0x1010101
field public static final int calendarViewShown = 16843596; // 0x101034c
field public static final int calendarViewStyle = 16843613; // 0x101035d
- field public static final int canRetrieveWindowContent = 16843653; // 0x1010385
+ field public static final int canRetrieveWindowContent = 16843652; // 0x1010384
field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
field public static final deprecated int capitalize = 16843113; // 0x1010169
field public static final int centerBright = 16842956; // 0x10100cc
@@ -314,18 +315,18 @@ package android {
field public static final int codes = 16843330; // 0x1010242
field public static final int collapseColumns = 16843083; // 0x101014b
field public static final int color = 16843173; // 0x10101a5
- field public static final int colorActivatedHighlight = 16843678; // 0x101039e
+ field public static final int colorActivatedHighlight = 16843677; // 0x101039d
field public static final int colorBackground = 16842801; // 0x1010031
field public static final int colorBackgroundCacheHint = 16843435; // 0x10102ab
- field public static final int colorFocusedHighlight = 16843677; // 0x101039d
+ field public static final int colorFocusedHighlight = 16843676; // 0x101039c
field public static final int colorForeground = 16842800; // 0x1010030
field public static final int colorForegroundInverse = 16843270; // 0x1010206
- field public static final int colorLongPressedHighlight = 16843676; // 0x101039c
- field public static final int colorMultiSelectHighlight = 16843679; // 0x101039f
- field public static final int colorPressedHighlight = 16843675; // 0x101039b
- field public static final int columnCount = 16843637; // 0x1010375
+ field public static final int colorLongPressedHighlight = 16843675; // 0x101039b
+ field public static final int colorMultiSelectHighlight = 16843678; // 0x101039e
+ field public static final int colorPressedHighlight = 16843674; // 0x101039a
+ field public static final int columnCount = 16843636; // 0x1010374
field public static final int columnDelay = 16843215; // 0x10101cf
- field public static final int columnOrderPreserved = 16843638; // 0x1010376
+ field public static final int columnOrderPreserved = 16843637; // 0x1010375
field public static final int columnWidth = 16843031; // 0x1010117
field public static final int compatibleWidthLimitDp = 16843621; // 0x1010365
field public static final int completionHint = 16843122; // 0x1010172
@@ -379,11 +380,11 @@ package android {
field public static final int drawSelectorOnTop = 16843004; // 0x10100fc
field public static final int drawable = 16843161; // 0x1010199
field public static final int drawableBottom = 16843118; // 0x101016e
- field public static final int drawableEnd = 16843681; // 0x10103a1
+ field public static final int drawableEnd = 16843680; // 0x10103a0
field public static final int drawableLeft = 16843119; // 0x101016f
field public static final int drawablePadding = 16843121; // 0x1010171
field public static final int drawableRight = 16843120; // 0x1010170
- field public static final int drawableStart = 16843680; // 0x10103a0
+ field public static final int drawableStart = 16843679; // 0x101039f
field public static final int drawableTop = 16843117; // 0x101016d
field public static final int drawingCacheQuality = 16842984; // 0x10100e8
field public static final int dropDownAnchor = 16843363; // 0x1010263
@@ -440,7 +441,7 @@ package android {
field public static final int fastScrollTextColor = 16843609; // 0x1010359
field public static final int fastScrollThumbDrawable = 16843574; // 0x1010336
field public static final int fastScrollTrackDrawable = 16843577; // 0x1010339
- field public static final int feedbackCount = 16843665; // 0x1010391
+ field public static final int feedbackCount = 16843664; // 0x1010390
field public static final int fillAfter = 16843197; // 0x10101bd
field public static final int fillBefore = 16843196; // 0x10101bc
field public static final int fillEnabled = 16843343; // 0x101024f
@@ -493,7 +494,7 @@ package android {
field public static final int hand_hour = 16843011; // 0x1010103
field public static final int hand_minute = 16843012; // 0x1010104
field public static final int handle = 16843354; // 0x101025a
- field public static final int handleDrawable = 16843655; // 0x1010387
+ field public static final int handleDrawable = 16843654; // 0x1010386
field public static final int handleProfiling = 16842786; // 0x1010022
field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e
field public static final int hardwareAccelerated = 16843475; // 0x10102d3
@@ -502,12 +503,12 @@ package android {
field public static final int headerDividersEnabled = 16843310; // 0x101022e
field public static final int height = 16843093; // 0x1010155
field public static final int hint = 16843088; // 0x1010150
- field public static final int hitRadius = 16843662; // 0x101038e
+ field public static final int hitRadius = 16843661; // 0x101038d
field public static final int homeAsUpIndicator = 16843531; // 0x101030b
field public static final int homeLayout = 16843549; // 0x101031d
field public static final int horizontalDivider = 16843053; // 0x101012d
field public static final int horizontalGap = 16843327; // 0x101023f
- field public static final int horizontalOffset = 16843667; // 0x1010393
+ field public static final int horizontalOffset = 16843666; // 0x1010392
field public static final int horizontalScrollViewStyle = 16843603; // 0x1010353
field public static final int horizontalSpacing = 16843028; // 0x1010114
field public static final int host = 16842792; // 0x1010028
@@ -553,7 +554,7 @@ package android {
field public static final int installLocation = 16843447; // 0x10102b7
field public static final int interpolator = 16843073; // 0x1010141
field public static final int isAlwaysSyncable = 16843571; // 0x1010333
- field public static final int isAuxiliary = 16843647; // 0x101037f
+ field public static final int isAuxiliary = 16843646; // 0x101037e
field public static final int isDefault = 16843297; // 0x1010221
field public static final int isIndicator = 16843079; // 0x1010147
field public static final int isModifier = 16843334; // 0x1010246
@@ -606,8 +607,8 @@ package android {
field public static final int layout_centerInParent = 16843151; // 0x101018f
field public static final int layout_centerVertical = 16843153; // 0x1010191
field public static final int layout_column = 16843084; // 0x101014c
- field public static final int layout_columnFlexibility = 16843645; // 0x101037d
- field public static final int layout_columnSpan = 16843644; // 0x101037c
+ field public static final int layout_columnFlexibility = 16843644; // 0x101037c
+ field public static final int layout_columnSpan = 16843643; // 0x101037b
field public static final int layout_gravity = 16842931; // 0x10100b3
field public static final int layout_height = 16842997; // 0x10100f5
field public static final int layout_margin = 16842998; // 0x10100f6
@@ -615,9 +616,9 @@ package android {
field public static final int layout_marginLeft = 16842999; // 0x10100f7
field public static final int layout_marginRight = 16843001; // 0x10100f9
field public static final int layout_marginTop = 16843000; // 0x10100f8
- field public static final int layout_row = 16843641; // 0x1010379
- field public static final int layout_rowFlexibility = 16843643; // 0x101037b
- field public static final int layout_rowSpan = 16843642; // 0x101037a
+ field public static final int layout_row = 16843640; // 0x1010378
+ field public static final int layout_rowFlexibility = 16843642; // 0x101037a
+ field public static final int layout_rowSpan = 16843641; // 0x1010379
field public static final int layout_scale = 16843155; // 0x1010193
field public static final int layout_span = 16843085; // 0x101014d
field public static final int layout_toLeftOf = 16843138; // 0x1010182
@@ -627,7 +628,7 @@ package android {
field public static final int layout_x = 16843135; // 0x101017f
field public static final int layout_y = 16843136; // 0x1010180
field public static final int left = 16843181; // 0x10101ad
- field public static final int leftChevronDrawable = 16843656; // 0x1010388
+ field public static final int leftChevronDrawable = 16843655; // 0x1010387
field public static final int lineSpacingExtra = 16843287; // 0x1010217
field public static final int lineSpacingMultiplier = 16843288; // 0x1010218
field public static final int lines = 16843092; // 0x1010154
@@ -639,8 +640,8 @@ package android {
field public static final int listDividerAlertDialog = 16843525; // 0x1010305
field public static final int listPopupWindowStyle = 16843519; // 0x10102ff
field public static final int listPreferredItemHeight = 16842829; // 0x101004d
- field public static final int listPreferredItemHeightLarge = 16843668; // 0x1010394
- field public static final int listPreferredItemHeightSmall = 16843669; // 0x1010395
+ field public static final int listPreferredItemHeightLarge = 16843667; // 0x1010393
+ field public static final int listPreferredItemHeightSmall = 16843668; // 0x1010394
field public static final int listSelector = 16843003; // 0x10100fb
field public static final int listSeparatorTextViewStyle = 16843272; // 0x1010208
field public static final int listViewStyle = 16842868; // 0x1010074
@@ -671,8 +672,8 @@ package android {
field public static final int minHeight = 16843072; // 0x1010140
field public static final int minLevel = 16843185; // 0x10101b1
field public static final int minLines = 16843094; // 0x1010156
- field public static final int minResizeHeight = 16843684; // 0x10103a4
- field public static final int minResizeWidth = 16843683; // 0x10103a3
+ field public static final int minResizeHeight = 16843683; // 0x10103a3
+ field public static final int minResizeWidth = 16843682; // 0x10103a2
field public static final int minSdkVersion = 16843276; // 0x101020c
field public static final int minWidth = 16843071; // 0x101013f
field public static final int mode = 16843134; // 0x101017e
@@ -688,7 +689,7 @@ package android {
field public static final int nextFocusUp = 16842979; // 0x10100e3
field public static final int noHistory = 16843309; // 0x101022d
field public static final int normalScreens = 16843397; // 0x1010285
- field public static final int notificationTimeout = 16843651; // 0x1010383
+ field public static final int notificationTimeout = 16843650; // 0x1010382
field public static final int numColumns = 16843032; // 0x1010118
field public static final int numStars = 16843076; // 0x1010144
field public static final deprecated int numeric = 16843109; // 0x1010165
@@ -702,11 +703,11 @@ package android {
field public static final int orderingFromXml = 16843239; // 0x10101e7
field public static final int orientation = 16842948; // 0x10100c4
field public static final int outAnimation = 16843128; // 0x1010178
- field public static final int outerRadius = 16843661; // 0x101038d
+ field public static final int outerRadius = 16843660; // 0x101038c
field public static final int overScrollFooter = 16843459; // 0x10102c3
field public static final int overScrollHeader = 16843458; // 0x10102c2
field public static final int overScrollMode = 16843457; // 0x10102c1
- field public static final int packageNames = 16843649; // 0x1010381
+ field public static final int packageNames = 16843648; // 0x1010380
field public static final int padding = 16842965; // 0x10100d5
field public static final int paddingBottom = 16842969; // 0x10100d9
field public static final int paddingLeft = 16842966; // 0x10100d6
@@ -791,17 +792,17 @@ package android {
field public static final int restoreAnyVersion = 16843450; // 0x10102ba
field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d
field public static final int right = 16843183; // 0x10101af
- field public static final int rightChevronDrawable = 16843657; // 0x1010389
+ field public static final int rightChevronDrawable = 16843656; // 0x1010388
field public static final int ringtonePreferenceStyle = 16842899; // 0x1010093
field public static final int ringtoneType = 16843257; // 0x10101f9
field public static final int rotation = 16843558; // 0x1010326
field public static final int rotationX = 16843559; // 0x1010327
field public static final int rotationY = 16843560; // 0x1010328
- field public static final int rowCount = 16843635; // 0x1010373
+ field public static final int rowCount = 16843634; // 0x1010372
field public static final int rowDelay = 16843216; // 0x10101d0
field public static final int rowEdgeFlags = 16843329; // 0x1010241
field public static final int rowHeight = 16843058; // 0x1010132
- field public static final int rowOrderPreserved = 16843636; // 0x1010374
+ field public static final int rowOrderPreserved = 16843635; // 0x1010373
field public static final int saveEnabled = 16842983; // 0x10100e7
field public static final int scaleGravity = 16843262; // 0x10101fe
field public static final int scaleHeight = 16843261; // 0x10101fd
@@ -867,7 +868,7 @@ package android {
field public static final int smallIcon = 16843422; // 0x101029e
field public static final int smallScreens = 16843396; // 0x1010284
field public static final int smoothScrollbar = 16843313; // 0x1010231
- field public static final int snapMargin = 16843664; // 0x1010390
+ field public static final int snapMargin = 16843663; // 0x101038f
field public static final int soundEffectsEnabled = 16843285; // 0x1010215
field public static final int spacing = 16843027; // 0x1010113
field public static final int spinnerDropDownItemStyle = 16842887; // 0x1010087
@@ -915,7 +916,7 @@ package android {
field public static final int subtitleTextStyle = 16843513; // 0x10102f9
field public static final int suggestActionMsg = 16843228; // 0x10101dc
field public static final int suggestActionMsgColumn = 16843229; // 0x10101dd
- field public static final int suggestionsEnabled = 16843634; // 0x1010372
+ field public static final int suggestionsEnabled = 16843633; // 0x1010371
field public static final int summary = 16843241; // 0x10101e9
field public static final int summaryColumn = 16843426; // 0x10102a2
field public static final int summaryOff = 16843248; // 0x10101f0
@@ -932,7 +933,7 @@ package android {
field public static final int tag = 16842961; // 0x10100d1
field public static final int targetActivity = 16843266; // 0x1010202
field public static final int targetClass = 16842799; // 0x101002f
- field public static final int targetDrawables = 16843654; // 0x1010386
+ field public static final int targetDrawables = 16843653; // 0x1010385
field public static final int targetPackage = 16842785; // 0x1010021
field public static final int targetSdkVersion = 16843376; // 0x1010270
field public static final int taskAffinity = 16842770; // 0x1010012
@@ -947,7 +948,7 @@ package android {
field public static final int tension = 16843370; // 0x101026a
field public static final int testOnly = 16843378; // 0x1010272
field public static final int text = 16843087; // 0x101014f
- field public static final int textAllCaps = 16843674; // 0x101039a
+ field public static final int textAllCaps = 16843673; // 0x1010399
field public static final int textAppearance = 16842804; // 0x1010034
field public static final int textAppearanceButton = 16843271; // 0x1010207
field public static final int textAppearanceInverse = 16842805; // 0x1010035
@@ -988,9 +989,8 @@ package android {
field public static final int textEditPasteWindowLayout = 16843540; // 0x1010314
field public static final int textEditSideNoPasteWindowLayout = 16843615; // 0x101035f
field public static final int textEditSidePasteWindowLayout = 16843614; // 0x101035e
- field public static final int textEditSuggestionItemLayout = 16843633; // 0x1010371
- field public static final int textEditSuggestionsBottomWindowLayout = 16843631; // 0x101036f
- field public static final int textEditSuggestionsTopWindowLayout = 16843632; // 0x1010370
+ field public static final int textEditSuggestionItemLayout = 16843632; // 0x1010370
+ field public static final int textEditSuggestionsWindowLayout = 16843631; // 0x101036f
field public static final int textFilterEnabled = 16843007; // 0x10100ff
field public static final int textIsSelectable = 16843542; // 0x1010316
field public static final int textOff = 16843045; // 0x1010125
@@ -1023,7 +1023,7 @@ package android {
field public static final int toYScale = 16843205; // 0x10101c5
field public static final int top = 16843182; // 0x10101ae
field public static final int topBright = 16842955; // 0x10100cb
- field public static final int topChevronDrawable = 16843658; // 0x101038a
+ field public static final int topChevronDrawable = 16843657; // 0x1010389
field public static final int topDark = 16842951; // 0x10100c7
field public static final int topLeftRadius = 16843177; // 0x10101a9
field public static final int topOffset = 16843352; // 0x1010258
@@ -1039,7 +1039,7 @@ package android {
field public static final int unfocusedMonthDateColor = 16843588; // 0x1010344
field public static final int unselectedAlpha = 16843278; // 0x101020e
field public static final int updatePeriodMillis = 16843344; // 0x1010250
- field public static final int useDefaultMargins = 16843639; // 0x1010377
+ field public static final int useDefaultMargins = 16843638; // 0x1010376
field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
field public static final int useLevel = 16843167; // 0x101019f
field public static final int userVisible = 16843409; // 0x1010291
@@ -1053,10 +1053,10 @@ package android {
field public static final int verticalCorrection = 16843322; // 0x101023a
field public static final int verticalDivider = 16843054; // 0x101012e
field public static final int verticalGap = 16843328; // 0x1010240
- field public static final int verticalOffset = 16843666; // 0x1010392
+ field public static final int verticalOffset = 16843665; // 0x1010391
field public static final int verticalScrollbarPosition = 16843572; // 0x1010334
field public static final int verticalSpacing = 16843029; // 0x1010115
- field public static final int vibrationDuration = 16843663; // 0x101038f
+ field public static final int vibrationDuration = 16843662; // 0x101038e
field public static final int visibility = 16842972; // 0x10100dc
field public static final int visible = 16843156; // 0x1010194
field public static final int vmSafeMode = 16843448; // 0x10102b8
@@ -1073,7 +1073,7 @@ package android {
field public static final int wallpaperIntraOpenExitAnimation = 16843416; // 0x1010298
field public static final int wallpaperOpenEnterAnimation = 16843411; // 0x1010293
field public static final int wallpaperOpenExitAnimation = 16843412; // 0x1010294
- field public static final int waveDrawable = 16843660; // 0x101038c
+ field public static final int waveDrawable = 16843659; // 0x101038b
field public static final int webTextViewStyle = 16843449; // 0x10102b9
field public static final int webViewStyle = 16842885; // 0x1010085
field public static final int weekDayTextAppearance = 16843592; // 0x1010348
@@ -4784,6 +4784,7 @@ package android.content {
field public static final java.lang.String SENSOR_SERVICE = "sensor";
field public static final java.lang.String STORAGE_SERVICE = "storage";
field public static final java.lang.String TELEPHONY_SERVICE = "phone";
+ field public static final java.lang.String TEXT_SERVICES_MANAGER_SERVICE = "textservices";
field public static final java.lang.String UI_MODE_SERVICE = "uimode";
field public static final java.lang.String USB_SERVICE = "usb";
field public static final java.lang.String VIBRATOR_SERVICE = "vibrator";
@@ -10405,8 +10406,8 @@ package android.media {
method public void setAudioEncodingBitRate(int);
method public void setAudioSamplingRate(int);
method public void setAudioSource(int) throws java.lang.IllegalStateException;
- method public void setAuxiliaryOutputFile(java.io.FileDescriptor);
- method public void setAuxiliaryOutputFile(java.lang.String);
+ method public deprecated void setAuxiliaryOutputFile(java.io.FileDescriptor);
+ method public deprecated void setAuxiliaryOutputFile(java.lang.String);
method public void setCamera(android.hardware.Camera);
method public void setCaptureRate(double);
method public void setLocation(float, float);
@@ -16726,18 +16727,18 @@ package android.provider {
field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY = "wifi_networks_available_repeat_delay";
field public static final java.lang.String WIFI_NUM_OPEN_NETWORKS_KEPT = "wifi_num_open_networks_kept";
field public static final java.lang.String WIFI_ON = "wifi_on";
- field public static final java.lang.String WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE = "wifi_watchdog_acceptable_packet_loss_percentage";
- field public static final java.lang.String WIFI_WATCHDOG_AP_COUNT = "wifi_watchdog_ap_count";
- field public static final java.lang.String WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS = "wifi_watchdog_background_check_delay_ms";
- field public static final java.lang.String WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED = "wifi_watchdog_background_check_enabled";
- field public static final java.lang.String WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS = "wifi_watchdog_background_check_timeout_ms";
- field public static final java.lang.String WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT = "wifi_watchdog_initial_ignored_ping_count";
- field public static final java.lang.String WIFI_WATCHDOG_MAX_AP_CHECKS = "wifi_watchdog_max_ap_checks";
+ field public static final deprecated java.lang.String WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE = "wifi_watchdog_acceptable_packet_loss_percentage";
+ field public static final deprecated java.lang.String WIFI_WATCHDOG_AP_COUNT = "wifi_watchdog_ap_count";
+ field public static final deprecated java.lang.String WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS = "wifi_watchdog_background_check_delay_ms";
+ field public static final deprecated java.lang.String WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED = "wifi_watchdog_background_check_enabled";
+ field public static final deprecated java.lang.String WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS = "wifi_watchdog_background_check_timeout_ms";
+ field public static final deprecated java.lang.String WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT = "wifi_watchdog_initial_ignored_ping_count";
+ field public static final deprecated java.lang.String WIFI_WATCHDOG_MAX_AP_CHECKS = "wifi_watchdog_max_ap_checks";
field public static final java.lang.String WIFI_WATCHDOG_ON = "wifi_watchdog_on";
- field public static final java.lang.String WIFI_WATCHDOG_PING_COUNT = "wifi_watchdog_ping_count";
- field public static final java.lang.String WIFI_WATCHDOG_PING_DELAY_MS = "wifi_watchdog_ping_delay_ms";
- field public static final java.lang.String WIFI_WATCHDOG_PING_TIMEOUT_MS = "wifi_watchdog_ping_timeout_ms";
- field public static final java.lang.String WIFI_WATCHDOG_WATCH_LIST = "wifi_watchdog_watch_list";
+ field public static final deprecated java.lang.String WIFI_WATCHDOG_PING_COUNT = "wifi_watchdog_ping_count";
+ field public static final deprecated java.lang.String WIFI_WATCHDOG_PING_DELAY_MS = "wifi_watchdog_ping_delay_ms";
+ field public static final deprecated java.lang.String WIFI_WATCHDOG_PING_TIMEOUT_MS = "wifi_watchdog_ping_timeout_ms";
+ field public static final deprecated java.lang.String WIFI_WATCHDOG_WATCH_LIST = "wifi_watchdog_watch_list";
}
public static class Settings.SettingNotFoundException extends android.util.AndroidException {
@@ -17942,6 +17943,31 @@ package android.security {
}
+package android.service.textservice {
+
+ public abstract class SpellCheckerService extends android.app.Service {
+ ctor public SpellCheckerService();
+ method public void cancel();
+ method public abstract android.view.textservice.SuggestionsInfo getSuggestions(android.view.textservice.TextInfo, int, java.lang.String);
+ method public android.view.textservice.SuggestionsInfo[] getSuggestionsMultiple(android.view.textservice.TextInfo[], java.lang.String, int, boolean);
+ method public final android.os.IBinder onBind(android.content.Intent);
+ field public static final java.lang.String SERVICE_INTERFACE;
+ }
+
+ public class SpellCheckerSession {
+ method public void close();
+ method public android.view.textservice.SpellCheckerInfo getSpellChecker();
+ method public void getSuggestions(android.view.textservice.TextInfo, int);
+ method public void getSuggestions(android.view.textservice.TextInfo[], int, boolean);
+ method public boolean isSessionDisconnected();
+ }
+
+ public static abstract interface SpellCheckerSession.SpellCheckerSessionListener {
+ method public abstract void onGetSuggestions(android.view.textservice.SuggestionsInfo[]);
+ }
+
+}
+
package android.service.wallpaper {
public abstract class WallpaperService extends android.app.Service {
@@ -21005,6 +21031,11 @@ package android.view {
method public void onPrepareSubMenu(android.view.SubMenu);
}
+ public abstract interface CollapsibleActionView {
+ method public abstract void onActionViewCollapsed();
+ method public abstract void onActionViewExpanded();
+ }
+
public abstract interface ContextMenu implements android.view.Menu {
method public abstract void clearHeader();
method public abstract android.view.ContextMenu setHeaderIcon(int);
@@ -22715,10 +22746,8 @@ package android.view {
ctor public ViewDebug();
method public static void dumpCapturedView(java.lang.String, java.lang.Object);
method public static void startHierarchyTracing(java.lang.String, android.view.View);
- method public static void startLooperProfiling(java.io.File);
method public static void startRecyclerTracing(java.lang.String, android.view.View);
method public static void stopHierarchyTracing();
- method public static void stopLooperProfiling();
method public static void stopRecyclerTracing();
method public static void trace(android.view.View, android.view.ViewDebug.RecyclerTraceType, int...);
method public static void trace(android.view.View, android.view.ViewDebug.HierarchyTraceType);
@@ -24019,6 +24048,52 @@ package android.view.inputmethod {
}
+package android.view.textservice {
+
+ public final class SpellCheckerInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public android.content.ComponentName getComponent();
+ method public java.lang.String getId();
+ method public java.lang.String getPackageName();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
+ }
+
+ public final class SuggestionsInfo implements android.os.Parcelable {
+ ctor public SuggestionsInfo(int, java.lang.String[]);
+ ctor public SuggestionsInfo(int, java.lang.String[], int, int);
+ ctor public SuggestionsInfo(android.os.Parcel);
+ method public int describeContents();
+ method public int getCookie();
+ method public int getSequence();
+ method public java.lang.String getSuggestionAt(int);
+ method public int getSuggestionsAttributes();
+ method public int getSuggestionsCount();
+ method public void setCookieAndSequence(int, int);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
+ field public static final int RESULT_ATTR_IN_THE_DICTIONARY = 1; // 0x1
+ field public static final int RESULT_ATTR_LOOKS_TYPO = 2; // 0x2
+ }
+
+ public final class TextInfo implements android.os.Parcelable {
+ ctor public TextInfo(java.lang.String);
+ ctor public TextInfo(java.lang.String, int, int);
+ ctor public TextInfo(android.os.Parcel);
+ method public int describeContents();
+ method public int getCookie();
+ method public int getSequence();
+ method public java.lang.String getText();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
+ }
+
+ public final class TextServicesManager {
+ method public android.service.textservice.SpellCheckerSession newSpellCheckerSession(java.util.Locale, android.service.textservice.SpellCheckerSession.SpellCheckerSessionListener, boolean);
+ }
+
+}
+
package android.webkit {
public final deprecated class CacheManager {
@@ -29790,7 +29865,7 @@ package java.lang.ref {
ctor public ReferenceQueue();
method public synchronized java.lang.ref.Reference<? extends T> poll();
method public java.lang.ref.Reference<? extends T> remove() throws java.lang.InterruptedException;
- method public synchronized java.lang.ref.Reference<? extends T> remove(long) throws java.lang.IllegalArgumentException, java.lang.InterruptedException;
+ method public synchronized java.lang.ref.Reference<? extends T> remove(long) throws java.lang.InterruptedException;
}
public class SoftReference extends java.lang.ref.Reference {
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 3fb17362f4c1..6dfa12be9592 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -468,10 +468,16 @@ public class Am {
String profileFile = null;
boolean start = false;
boolean wall = false;
+ int profileType = 0;
String process = null;
String cmd = nextArgRequired();
+ if ("looper".equals(cmd)) {
+ cmd = nextArgRequired();
+ profileType = 1;
+ }
+
if ("start".equals(cmd)) {
start = true;
wall = "--wall".equals(nextOption());
@@ -516,7 +522,7 @@ public class Am {
} else if (start) {
//removeWallOption();
}
- if (!mAm.profileControl(process, start, profileFile, fd)) {
+ if (!mAm.profileControl(process, start, profileFile, fd, profileType)) {
wall = false;
throw new AndroidException("PROFILE FAILED on process " + process);
}
@@ -1076,8 +1082,8 @@ public class Am {
" am broadcast <INTENT>\n" +
" am instrument [-r] [-e <NAME> <VALUE>] [-p] [-w]\n" +
" [--no-window-animation] <COMPONENT>\n" +
- " am profile start <PROCESS> <FILE>\n" +
- " am profile stop <PROCESS>\n" +
+ " am profile [looper] start <PROCESS> <FILE>\n" +
+ " am profile [looper] stop <PROCESS>\n" +
" am dumpheap [flags] <PROCESS> <FILE>\n" +
" am monitor [--gdb <port>]\n" +
" am screen-compat [on|off] <PACKAGE>\n" +
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 2a731a3999fc..b7cd829563c9 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1104,10 +1104,11 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
data.enforceInterface(IActivityManager.descriptor);
String process = data.readString();
boolean start = data.readInt() != 0;
+ int profileType = data.readInt();
String path = data.readString();
ParcelFileDescriptor fd = data.readInt() != 0
? data.readFileDescriptor() : null;
- boolean res = profileControl(process, start, path, fd);
+ boolean res = profileControl(process, start, path, fd, profileType);
reply.writeNoException();
reply.writeInt(res ? 1 : 0);
return true;
@@ -2888,13 +2889,14 @@ class ActivityManagerProxy implements IActivityManager
}
public boolean profileControl(String process, boolean start,
- String path, ParcelFileDescriptor fd) throws RemoteException
+ String path, ParcelFileDescriptor fd, int profileType) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeString(process);
data.writeInt(start ? 1 : 0);
+ data.writeInt(profileType);
data.writeString(path);
if (fd != null) {
data.writeInt(1);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index f6cd866d4e34..9bbbd6c76753 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -676,11 +676,12 @@ public final class ActivityThread {
queueOrSendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
}
- public void profilerControl(boolean start, String path, ParcelFileDescriptor fd) {
+ public void profilerControl(boolean start, String path, ParcelFileDescriptor fd,
+ int profileType) {
ProfilerControlData pcd = new ProfilerControlData();
pcd.path = path;
pcd.fd = fd;
- queueOrSendMessage(H.PROFILER_CONTROL, pcd, start ? 1 : 0);
+ queueOrSendMessage(H.PROFILER_CONTROL, pcd, start ? 1 : 0, profileType);
}
public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
@@ -954,7 +955,7 @@ public final class ActivityThread {
}
public void scheduleTrimMemory(int level) {
- queueOrSendMessage(H.TRIM_MEMORY, level);
+ queueOrSendMessage(H.TRIM_MEMORY, null, level);
}
}
@@ -1148,7 +1149,7 @@ public final class ActivityThread {
handleActivityConfigurationChanged((IBinder)msg.obj);
break;
case PROFILER_CONTROL:
- handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj);
+ handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2);
break;
case CREATE_BACKUP_AGENT:
handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
@@ -1184,8 +1185,10 @@ public final class ActivityThread {
break;
case UPDATE_PACKAGE_COMPATIBILITY_INFO:
handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
+ break;
case TRIM_MEMORY:
handleTrimMemory(msg.arg1);
+ break;
}
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + msg.what);
}
@@ -3469,11 +3472,18 @@ public final class ActivityThread {
performConfigurationChanged(r.activity, mCompatConfiguration);
}
- final void handleProfilerControl(boolean start, ProfilerControlData pcd) {
+ final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) {
if (start) {
try {
- Debug.startMethodTracing(pcd.path, pcd.fd.getFileDescriptor(),
- 8 * 1024 * 1024, 0);
+ switch (profileType) {
+ case 1:
+ ViewDebug.startLooperProfiling(pcd.path, pcd.fd.getFileDescriptor());
+ break;
+ default:
+ Debug.startMethodTracing(pcd.path, pcd.fd.getFileDescriptor(),
+ 8 * 1024 * 1024, 0);
+ break;
+ }
} catch (RuntimeException e) {
Slog.w(TAG, "Profiling failed on path " + pcd.path
+ " -- can the process access this path?");
@@ -3485,7 +3495,15 @@ public final class ActivityThread {
}
}
} else {
- Debug.stopMethodTracing();
+ switch (profileType) {
+ case 1:
+ ViewDebug.stopLooperProfiling();
+ break;
+ default:
+ Debug.stopMethodTracing();
+ break;
+
+ }
}
}
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 942f245bebf8..9a5b527d7c5b 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -376,10 +376,11 @@ public abstract class ApplicationThreadNative extends Binder
{
data.enforceInterface(IApplicationThread.descriptor);
boolean start = data.readInt() != 0;
+ int profileType = data.readInt();
String path = data.readString();
ParcelFileDescriptor fd = data.readInt() != 0
? data.readFileDescriptor() : null;
- profilerControl(start, path, fd);
+ profilerControl(start, path, fd, profileType);
return true;
}
@@ -936,10 +937,11 @@ class ApplicationThreadProxy implements IApplicationThread {
}
public void profilerControl(boolean start, String path,
- ParcelFileDescriptor fd) throws RemoteException {
+ ParcelFileDescriptor fd, int profileType) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeInt(start ? 1 : 0);
+ data.writeInt(profileType);
data.writeString(path);
if (fd != null) {
data.writeInt(1);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index d2323e7defec..6289730cb56e 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -83,6 +83,7 @@ import android.view.ContextThemeWrapper;
import android.view.WindowManagerImpl;
import android.view.accessibility.AccessibilityManager;
import android.view.inputmethod.InputMethodManager;
+import android.view.textservice.TextServicesManager;
import android.accounts.AccountManager;
import android.accounts.IAccountManager;
import android.app.admin.DevicePolicyManager;
@@ -320,6 +321,11 @@ class ContextImpl extends Context {
return InputMethodManager.getInstance(ctx);
}});
+ registerService(TEXT_SERVICES_MANAGER_SERVICE, new ServiceFetcher() {
+ public Object createService(ContextImpl ctx) {
+ return TextServicesManager.getInstance();
+ }});
+
registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
public Object getService(ContextImpl ctx) {
// TODO: why isn't this caching it? It wasn't
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index c82c9ecf7a8f..789d3a692775 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1695,6 +1695,7 @@ final class FragmentManagerImpl extends FragmentManager {
public void dispatchDestroy() {
mDestroyed = true;
+ execPendingActions();
moveToState(Fragment.INITIALIZING, false);
mActivity = null;
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 93c821c04469..64d77e80750c 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -284,7 +284,7 @@ public interface IActivityManager extends IInterface {
// Turn on/off profiling in a particular process.
public boolean profileControl(String process, boolean start,
- String path, ParcelFileDescriptor fd) throws RemoteException;
+ String path, ParcelFileDescriptor fd, int profileType) throws RemoteException;
public boolean shutdown(int timeout) throws RemoteException;
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 9de0bf4ffa0e..d0607d09040d 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -105,7 +105,7 @@ public interface IApplicationThread extends IInterface {
throws RemoteException;
void scheduleLowMemory() throws RemoteException;
void scheduleActivityConfigurationChanged(IBinder token) throws RemoteException;
- void profilerControl(boolean start, String path, ParcelFileDescriptor fd)
+ void profilerControl(boolean start, String path, ParcelFileDescriptor fd, int profileType)
throws RemoteException;
void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd)
throws RemoteException;
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 1af09838c2f1..ca64c88e8fb7 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -97,9 +97,10 @@ public class StatusBarManager {
}
}
- public void setIcon(String slot, int iconId, int iconLevel) {
+ public void setIcon(String slot, int iconId, int iconLevel, String contentDescription) {
try {
- mService.setIcon(slot, mContext.getPackageName(), iconId, iconLevel);
+ mService.setIcon(slot, mContext.getPackageName(), iconId, iconLevel,
+ contentDescription);
} catch (RemoteException ex) {
// system process is dead anyway.
throw new RuntimeException(ex);
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 019652c024d9..1ef99a1e6845 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -388,6 +388,10 @@ public class AppWidgetManager {
TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics);
info.minHeight =
TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics);
+ info.minResizeWidth =
+ TypedValue.complexToDimensionPixelSize(info.minResizeWidth, mDisplayMetrics);
+ info.minResizeHeight =
+ TypedValue.complexToDimensionPixelSize(info.minResizeHeight, mDisplayMetrics);
}
return providers;
}
@@ -411,6 +415,10 @@ public class AppWidgetManager {
TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics);
info.minHeight =
TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics);
+ info.minResizeWidth =
+ TypedValue.complexToDimensionPixelSize(info.minResizeWidth, mDisplayMetrics);
+ info.minResizeHeight =
+ TypedValue.complexToDimensionPixelSize(info.minResizeHeight, mDisplayMetrics);
}
return info;
}
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index b8c5b028b165..9c352d58dfb2 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -187,6 +187,8 @@ public class AppWidgetProviderInfo implements Parcelable {
}
this.minWidth = in.readInt();
this.minHeight = in.readInt();
+ this.minResizeWidth = in.readInt();
+ this.minResizeHeight = in.readInt();
this.updatePeriodMillis = in.readInt();
this.initialLayout = in.readInt();
if (0 != in.readInt()) {
@@ -208,6 +210,8 @@ public class AppWidgetProviderInfo implements Parcelable {
}
out.writeInt(this.minWidth);
out.writeInt(this.minHeight);
+ out.writeInt(this.minResizeWidth);
+ out.writeInt(this.minResizeHeight);
out.writeInt(this.updatePeriodMillis);
out.writeInt(this.initialLayout);
if (this.configure != null) {
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index ab3a4267a7f8..095cd110eb79 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -120,6 +120,7 @@ public final class BluetoothDeviceProfileState extends StateMachine {
private Pair<Integer, String> mIncomingConnections;
private PowerManager.WakeLock mWakeLock;
private PowerManager mPowerManager;
+ private boolean mPairingRequestRcvd = false;
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
@@ -187,27 +188,38 @@ public final class BluetoothDeviceProfileState extends StateMachine {
Message msg = obtainMessage(CONNECTION_ACCESS_REQUEST_REPLY);
msg.arg1 = val;
sendMessage(msg);
+ } else if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
+ mPairingRequestRcvd = true;
+ } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
+ int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
+ BluetoothDevice.ERROR);
+ if (state == BluetoothDevice.BOND_BONDED && mPairingRequestRcvd) {
+ setTrust(BluetoothDevice.CONNECTION_ACCESS_YES);
+ mPairingRequestRcvd = false;
+ } else if (state == BluetoothDevice.BOND_NONE) {
+ mPairingRequestRcvd = false;
+ }
}
}
};
private boolean isPhoneDocked(BluetoothDevice autoConnectDevice) {
- // This works only because these broadcast intents are "sticky"
- Intent i = mContext.registerReceiver(null, new IntentFilter(Intent.ACTION_DOCK_EVENT));
- if (i != null) {
- int state = i.getIntExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
- if (state != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
- BluetoothDevice device = i.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- if (device != null && autoConnectDevice.equals(device)) {
- return true;
- }
- }
- }
- return false;
- }
+ // This works only because these broadcast intents are "sticky"
+ Intent i = mContext.registerReceiver(null, new IntentFilter(Intent.ACTION_DOCK_EVENT));
+ if (i != null) {
+ int state = i.getIntExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
+ if (state != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+ BluetoothDevice device = i.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+ if (device != null && autoConnectDevice.equals(device)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
public BluetoothDeviceProfileState(Context context, String address,
- BluetoothService service, BluetoothA2dpService a2dpService) {
+ BluetoothService service, BluetoothA2dpService a2dpService, boolean setTrust) {
super(address);
mContext = context;
mDevice = new BluetoothDevice(address);
@@ -231,6 +243,8 @@ public final class BluetoothDeviceProfileState extends StateMachine {
filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);
+ filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
+ filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
mContext.registerReceiver(mBroadcastReceiver, filter);
@@ -247,6 +261,10 @@ public final class BluetoothDeviceProfileState extends StateMachine {
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, TAG);
mWakeLock.setReferenceCounted(false);
+
+ if (setTrust) {
+ setTrust(BluetoothDevice.CONNECTION_ACCESS_YES);
+ }
}
private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 32843618dcdf..8f2b3d88c2eb 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -661,7 +661,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
*/
public boolean disconnectHeadsetInternal(BluetoothDevice device) {
if (DBG) log("disconnectHeadsetInternal");
- if (mService != null && isEnabled()) {
+ if (mService != null && !isDisabled()) {
try {
return mService.disconnectHeadsetInternal(device);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
diff --git a/core/java/android/content/ComponentCallbacks.java b/core/java/android/content/ComponentCallbacks.java
index 92b98fd81b39..37cc1416ed81 100644
--- a/core/java/android/content/ComponentCallbacks.java
+++ b/core/java/android/content/ComponentCallbacks.java
@@ -56,11 +56,8 @@ public interface ComponentCallbacks {
static final int TRIM_MEMORY_COMPLETE = 80;
/** @hide */
- static final int TRIM_MEMORY_MODERATE = 60;
+ static final int TRIM_MEMORY_MODERATE = 50;
/** @hide */
- static final int TRIM_MEMORY_BACKGROUND = 40;
-
- /** @hide */
- static final int TRIM_MEMORY_INVISIBLE = 20;
+ static final int TRIM_MEMORY_BACKGROUND = 20;
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index fed6d815c9f2..0a2253c8dc75 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1612,6 +1612,15 @@ public abstract class Context {
/**
* Use with {@link #getSystemService} to retrieve a
+ * {@link android.view.textservice.TextServicesManager} for accessing
+ * text services.
+ *
+ * @see #getSystemService
+ */
+ public static final String TEXT_SERVICES_MANAGER_SERVICE = "textservices";
+
+ /**
+ * Use with {@link #getSystemService} to retrieve a
* {@link android.appwidget.AppWidgetManager} for accessing AppWidgets.
*
* @hide
diff --git a/core/java/android/inputmethodservice/ExtractEditLayout.java b/core/java/android/inputmethodservice/ExtractEditLayout.java
index eafff49528f5..5cfa998857b7 100644
--- a/core/java/android/inputmethodservice/ExtractEditLayout.java
+++ b/core/java/android/inputmethodservice/ExtractEditLayout.java
@@ -172,7 +172,10 @@ public class ExtractEditLayout extends LinearLayout {
@Override
public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
- return mCallback.onActionItemClicked(this, item);
+ if (mCallback != null) {
+ return mCallback.onActionItemClicked(this, item);
+ }
+ return false;
}
@Override
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index ce6f697be6be..a564d9771f7b 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -653,6 +653,17 @@ public class ConnectivityManager {
}
}
+ /**
+ * {@hide}
+ */
+ public int setUsbTethering(boolean enable) {
+ try {
+ return mService.setUsbTethering(enable);
+ } catch (RemoteException e) {
+ return TETHER_ERROR_SERVICE_UNAVAIL;
+ }
+ }
+
/** {@hide} */
public static final int TETHER_ERROR_NO_ERROR = 0;
/** {@hide} */
diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java
index a866436ed77d..b035c51d3da5 100644
--- a/core/java/android/net/EthernetDataTracker.java
+++ b/core/java/android/net/EthernetDataTracker.java
@@ -103,6 +103,10 @@ public class EthernetDataTracker implements NetworkStateTracker {
public void interfaceRemoved(String iface) {
mTracker.interfaceRemoved(iface);
}
+
+ public void limitReached(String limitName, String iface) {
+ // Ignored.
+ }
}
private EthernetDataTracker() {
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index d95fc8de70c3..b1d99a4abe42 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -88,6 +88,8 @@ interface IConnectivityManager
String[] getTetherableBluetoothRegexs();
+ int setUsbTethering(boolean enable);
+
void requestNetworkTransitionWakelock(in String forWhom);
void reportInetCondition(int networkType, int percentage);
diff --git a/core/java/android/net/INetworkManagementEventObserver.aidl b/core/java/android/net/INetworkManagementEventObserver.aidl
index 4436e6e444ee..a97f2030a146 100644
--- a/core/java/android/net/INetworkManagementEventObserver.aidl
+++ b/core/java/android/net/INetworkManagementEventObserver.aidl
@@ -52,4 +52,14 @@ interface INetworkManagementEventObserver {
* @param iface The interface.
*/
void interfaceRemoved(String iface);
+
+ /**
+ * A networking quota limit has been reached. The quota might not
+ * be specific to an interface.
+ *
+ * @param limitName The name of the limit that triggered.
+ * @param iface The interface on which the limit was detected.
+ */
+ void limitReached(String limitName, String iface);
+
}
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 9826becf3180..132f3bad2d26 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -58,8 +58,8 @@ public class LinkProperties implements Parcelable {
private ProxyProperties mHttpProxy;
public static class CompareResult<T> {
- public ArrayList<T> removed = new ArrayList<T>();
- public ArrayList<T> added = new ArrayList<T>();
+ public Collection<T> removed = new ArrayList<T>();
+ public Collection<T> added = new ArrayList<T>();
@Override
public String toString() {
diff --git a/core/java/android/net/VpnBuilder.java b/core/java/android/net/VpnBuilder.java
new file mode 100644
index 000000000000..458252345152
--- /dev/null
+++ b/core/java/android/net/VpnBuilder.java
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+import com.android.internal.net.VpnConfig;
+
+import java.net.InetAddress;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.DatagramSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+
+/**
+ * VpnBuilder is a framework which enables applications to build their
+ * own VPN solutions. In general, it creates a virtual network interface,
+ * configures addresses and routing rules, and returns a file descriptor
+ * to the application. Each read from the descriptor retrieves an outgoing
+ * packet which was routed to the interface. Each write to the descriptor
+ * injects an incoming packet just like it was received from the interface.
+ * The framework is running on Internet Protocol (IP), so packets are
+ * always started with IP headers. The application then completes a VPN
+ * connection by processing and exchanging packets with a remote server
+ * over a secured tunnel.
+ *
+ * <p>Letting applications intercept packets raises huge security concerns.
+ * Besides, a VPN application can easily break the network, and two of them
+ * may conflict with each other. The framework takes several actions to
+ * address these issues. Here are some key points:
+ * <ul>
+ * <li>User action is required to create a VPN connection.</li>
+ * <li>There can be only one VPN connection running at the same time. The
+ * existing interface is deactivated when a new one is created.</li>
+ * <li>A system-managed notification is shown during the lifetime of a
+ * VPN connection.</li>
+ * <li>A system-managed dialog gives the information of the current VPN
+ * connection. It also provides a button to disconnect.</li>
+ * <li>The network is restored automatically when the file descriptor is
+ * closed. It also covers the cases when a VPN application is crashed
+ * or killed by the system.</li>
+ * </ul>
+ *
+ * <p>There are two primary methods in this class: {@link #prepare} and
+ * {@link #establish}. The former deals with the user action and stops
+ * the existing VPN connection created by another application. The latter
+ * creates a VPN interface using the parameters supplied to this builder.
+ * An application must call {@link #prepare} to grant the right to create
+ * an interface, and it can be revoked at any time by another application.
+ * The application got revoked is notified by an {@link #ACTION_VPN_REVOKED}
+ * broadcast. Here are the general steps to create a VPN connection:
+ * <ol>
+ * <li>When the user press the button to connect, call {@link #prepare}
+ * and launch the intent if necessary.</li>
+ * <li>Register a receiver for {@link #ACTION_VPN_REVOKED} broadcasts.
+ * <li>Connect to the remote server and negotiate the network parameters
+ * of the VPN connection.</li>
+ * <li>Use those parameters to configure a VpnBuilder and create a VPN
+ * interface by calling {@link #establish}.</li>
+ * <li>Start processing packets between the returned file descriptor and
+ * the VPN tunnel.</li>
+ * <li>When an {@link #ACTION_VPN_REVOKED} broadcast is received, the
+ * interface is already deactivated by the framework. Close the file
+ * descriptor and shut down the VPN tunnel gracefully.
+ * </ol>
+ * Methods in this class can be used in activities and services. However,
+ * the intent returned from {@link #prepare} must be launched from an
+ * activity. The broadcast receiver can be registered at any time, but doing
+ * it before calling {@link #establish} effectively avoids race conditions.
+ *
+ * <p class="note">Using this class requires
+ * {@link android.Manifest.permission#VPN} permission.
+ * @hide
+ */
+public class VpnBuilder {
+
+ /**
+ * Broadcast intent action indicating that the VPN application has been
+ * revoked. This can be only received by the target application on the
+ * receiver explicitly registered using {@link Context#registerReceiver}.
+ *
+ * <p>This is a protected intent that can only be sent by the system.
+ */
+ public static final String ACTION_VPN_REVOKED = VpnConfig.ACTION_VPN_REVOKED;
+
+ /**
+ * Use IConnectivityManager instead since those methods are hidden and
+ * not available in ConnectivityManager.
+ */
+ private static IConnectivityManager getService() {
+ return IConnectivityManager.Stub.asInterface(
+ ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+ }
+
+ /**
+ * Prepare to establish a VPN connection. This method returns {@code null}
+ * if the VPN application is already prepared. Otherwise, it returns an
+ * {@link Intent} to a system activity. The application should launch the
+ * activity using {@link Activity#startActivityForResult} to get itself
+ * prepared. The activity may pop up a dialog to require user action, and
+ * the result will come back to the application through its
+ * {@link Activity#onActivityResult}. The application becomes prepared if
+ * the result is {@link Activity#RESULT_OK}, and it is granted to create a
+ * VPN interface by calling {@link #establish}.
+ *
+ * <p>Only one application can be granted at the same time. The right
+ * is revoked when another application is granted. The application
+ * losing the right will be notified by an {@link #ACTION_VPN_REVOKED}
+ * broadcast, and its VPN interface will be deactivated by the system.
+ * The application should then notify the remote server and disconnect
+ * gracefully. Unless the application becomes prepared again, subsequent
+ * calls to {@link #establish} will return {@code null}.
+ *
+ * @see #establish
+ * @see #ACTION_VPN_REVOKED
+ */
+ public static Intent prepare(Context context) {
+ try {
+ if (getService().prepareVpn(context.getPackageName(), null)) {
+ return null;
+ }
+ } catch (RemoteException e) {
+ // ignore
+ }
+ return VpnConfig.getIntentForConfirmation();
+ }
+
+ private VpnConfig mConfig = new VpnConfig();
+ private StringBuilder mAddresses = new StringBuilder();
+ private StringBuilder mRoutes = new StringBuilder();
+
+ /**
+ * Set the name of this session. It will be displayed in system-managed
+ * dialogs and notifications. This is recommended not required.
+ */
+ public VpnBuilder setSession(String session) {
+ mConfig.session = session;
+ return this;
+ }
+
+ /**
+ * Set the {@link PendingIntent} to an activity for users to configure
+ * the VPN connection. If it is not set, the button to configure will
+ * not be shown in system-managed dialogs.
+ */
+ public VpnBuilder setConfigureIntent(PendingIntent intent) {
+ mConfig.configureIntent = intent;
+ return this;
+ }
+
+ /**
+ * Set the maximum transmission unit (MTU) of the VPN interface. If it
+ * is not set, the default value in the operating system will be used.
+ *
+ * @throws IllegalArgumentException if the value is not positive.
+ */
+ public VpnBuilder setMtu(int mtu) {
+ if (mtu <= 0) {
+ throw new IllegalArgumentException("Bad mtu");
+ }
+ mConfig.mtu = mtu;
+ return this;
+ }
+
+ /**
+ * Private method to validate address and prefixLength.
+ */
+ private static void check(InetAddress address, int prefixLength) {
+ if (address.isLoopbackAddress()) {
+ throw new IllegalArgumentException("Bad address");
+ }
+ if (address instanceof Inet4Address) {
+ if (prefixLength < 0 || prefixLength > 32) {
+ throw new IllegalArgumentException("Bad prefixLength");
+ }
+ } else if (address instanceof Inet6Address) {
+ if (prefixLength < 0 || prefixLength > 128) {
+ throw new IllegalArgumentException("Bad prefixLength");
+ }
+ } else {
+ throw new IllegalArgumentException("Unsupported family");
+ }
+ }
+
+ /**
+ * Convenience method to add a network address to the VPN interface
+ * using a numeric address string. See {@link InetAddress} for the
+ * definitions of numeric address formats.
+ *
+ * @throws IllegalArgumentException if the address is invalid.
+ * @see #addAddress(InetAddress, int)
+ */
+ public VpnBuilder addAddress(String address, int prefixLength) {
+ return addAddress(InetAddress.parseNumericAddress(address), prefixLength);
+ }
+
+ /**
+ * Add a network address to the VPN interface. Both IPv4 and IPv6
+ * addresses are supported. At least one address must be set before
+ * calling {@link #establish}.
+ *
+ * @throws IllegalArgumentException if the address is invalid.
+ */
+ public VpnBuilder addAddress(InetAddress address, int prefixLength) {
+ check(address, prefixLength);
+
+ if (address.isAnyLocalAddress()) {
+ throw new IllegalArgumentException("Bad address");
+ }
+
+ mAddresses.append(String.format(" %s/%d", address.getHostAddress(), prefixLength));
+ return this;
+ }
+
+ /**
+ * Convenience method to add a network route to the VPN interface
+ * using a numeric address string. See {@link InetAddress} for the
+ * definitions of numeric address formats.
+ *
+ * @see #addRoute(InetAddress, int)
+ * @throws IllegalArgumentException if the route is invalid.
+ */
+ public VpnBuilder addRoute(String address, int prefixLength) {
+ return addRoute(InetAddress.parseNumericAddress(address), prefixLength);
+ }
+
+ /**
+ * Add a network route to the VPN interface. Both IPv4 and IPv6
+ * routes are supported.
+ *
+ * @throws IllegalArgumentException if the route is invalid.
+ */
+ public VpnBuilder addRoute(InetAddress address, int prefixLength) {
+ check(address, prefixLength);
+
+ int offset = prefixLength / 8;
+ byte[] bytes = address.getAddress();
+ if (offset < bytes.length) {
+ if ((byte)(bytes[offset] << (prefixLength % 8)) != 0) {
+ throw new IllegalArgumentException("Bad address");
+ }
+ while (++offset < bytes.length) {
+ if (bytes[offset] != 0) {
+ throw new IllegalArgumentException("Bad address");
+ }
+ }
+ }
+
+ mRoutes.append(String.format(" %s/%d", address.getHostAddress(), prefixLength));
+ return this;
+ }
+
+ /**
+ * Convenience method to add a DNS server to the VPN connection
+ * using a numeric address string. See {@link InetAddress} for the
+ * definitions of numeric address formats.
+ *
+ * @throws IllegalArgumentException if the address is invalid.
+ * @see #addDnsServer(InetAddress)
+ */
+ public VpnBuilder addDnsServer(String address) {
+ return addDnsServer(InetAddress.parseNumericAddress(address));
+ }
+
+ /**
+ * Add a DNS server to the VPN connection. Both IPv4 and IPv6
+ * addresses are supported. If none is set, the DNS servers of
+ * the default network will be used.
+ *
+ * @throws IllegalArgumentException if the address is invalid.
+ */
+ public VpnBuilder addDnsServer(InetAddress address) {
+ if (address.isLoopbackAddress() || address.isAnyLocalAddress()) {
+ throw new IllegalArgumentException("Bad address");
+ }
+ if (mConfig.dnsServers == null) {
+ mConfig.dnsServers = new ArrayList<String>();
+ }
+ mConfig.dnsServers.add(address.getHostAddress());
+ return this;
+ }
+
+ /**
+ * Add a search domain to the DNS resolver.
+ */
+ public VpnBuilder addSearchDomain(String domain) {
+ if (mConfig.searchDomains == null) {
+ mConfig.searchDomains = new ArrayList<String>();
+ }
+ mConfig.searchDomains.add(domain);
+ return this;
+ }
+
+ /**
+ * Create a VPN interface using the parameters supplied to this builder.
+ * The interface works on IP packets, and a file descriptor is returned
+ * for the application to access them. Each read retrieves an outgoing
+ * packet which was routed to the interface. Each write injects an
+ * incoming packet just like it was received from the interface. The file
+ * descriptor is put into non-blocking mode by default to avoid blocking
+ * Java threads. To use the file descriptor completely in native space,
+ * see {@link ParcelFileDescriptor#detachFd()}. The application MUST
+ * close the file descriptor when the VPN connection is terminated. The
+ * VPN interface will be removed and the network will be restored by the
+ * framework automatically.
+ *
+ * <p>To avoid conflicts, there can be only one active VPN interface at
+ * the same time. Usually network parameters are never changed during the
+ * lifetime of a VPN connection. It is also common for an application to
+ * create a new file descriptor after closing the previous one. However,
+ * it is rare but not impossible to have two interfaces while performing a
+ * seamless handover. In this case, the old interface will be deactivated
+ * when the new one is configured successfully. Both file descriptors are
+ * valid but now outgoing packets will be routed to the new interface.
+ * Therefore, after draining the old file descriptor, the application MUST
+ * close it and start using the new file descriptor. If the new interface
+ * cannot be created, the existing interface and its file descriptor remain
+ * untouched.
+ *
+ * <p>An exception will be thrown if the interface cannot be created for
+ * any reason. However, this method returns {@code null} if the application
+ * is not prepared or is revoked by another application. This helps solve
+ * possible race conditions while handling {@link #ACTION_VPN_REVOKED}
+ * broadcasts.
+ *
+ * @return {@link ParcelFileDescriptor} of the VPN interface, or
+ * {@code null} if the application is not prepared.
+ * @throws IllegalArgumentException if a parameter is not accepted by the
+ * operating system.
+ * @throws IllegalStateException if a parameter cannot be applied by the
+ * operating system.
+ * @see #prepare
+ */
+ public ParcelFileDescriptor establish() {
+ mConfig.addresses = mAddresses.toString();
+ mConfig.routes = mRoutes.toString();
+
+ try {
+ return getService().establishVpn(mConfig);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
+ * Protect a socket from VPN connections. The socket will be bound to the
+ * current default network interface, so its traffic will not be forwarded
+ * through VPN. This method is useful if some connections need to be kept
+ * outside of VPN. For example, a VPN tunnel should protect itself if its
+ * destination is covered by VPN routes. Otherwise its outgoing packets
+ * will be sent back to the VPN interface and cause an infinite loop.
+ *
+ * <p>The socket is NOT closed by this method.
+ *
+ * @return {@code true} on success.
+ */
+ public static boolean protect(int socket) {
+ ParcelFileDescriptor dup = null;
+ try {
+ dup = ParcelFileDescriptor.fromFd(socket);
+ return getService().protectVpn(dup);
+ } catch (Exception e) {
+ return false;
+ } finally {
+ try {
+ dup.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Protect a {@link Socket} from VPN connections.
+ *
+ * @return {@code true} on success.
+ * @see #protect(int)
+ */
+ public static boolean protect(Socket socket) {
+ return protect(socket.getFileDescriptor$().getInt$());
+ }
+
+ /**
+ * Protect a {@link DatagramSocket} from VPN connections.
+ *
+ * @return {@code true} on success.
+ * @see #protect(int)
+ */
+ public static boolean protect(DatagramSocket socket) {
+ return protect(socket.getFileDescriptor$().getInt$());
+ }
+}
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index dcbe9dab117c..2ed66191bfec 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -46,8 +46,6 @@ interface INfcAdapter
// NfcAdapter-class related methods
boolean isEnabled();
- NdefMessage localGet();
- void localSet(in NdefMessage message);
void enableForegroundDispatch(in ComponentName activity, in PendingIntent intent,
in IntentFilter[] filters, in TechListParcel techLists);
void disableForegroundDispatch(in ComponentName activity);
@@ -62,4 +60,7 @@ interface INfcAdapter
int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength);
boolean disable();
boolean enable();
+ boolean enableZeroClick();
+ boolean disableZeroClick();
+ boolean zeroClickEnabled();
}
diff --git a/core/java/android/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl
index aa5937ee9deb..7bdefe7b0eb7 100644
--- a/core/java/android/nfc/INfcTag.aidl
+++ b/core/java/android/nfc/INfcTag.aidl
@@ -44,5 +44,6 @@ interface INfcTag
Tag rediscover(int nativehandle);
int setTimeout(int technology, int timeout);
+ int getTimeout(int technology);
void resetTimeouts();
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 738e75f7a2c0..4d04027ec57c 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -684,44 +684,45 @@ public final class NfcAdapter {
}
/**
- * Set the NDEF Message that this NFC adapter should appear as to Tag
- * readers.
- * <p>
- * Any Tag reader can read the contents of the local tag when it is in
- * proximity, without any further user confirmation.
- * <p>
- * The implementation of this method must either
- * <ul>
- * <li>act as a passive tag containing this NDEF message
- * <li>provide the NDEF message on over LLCP to peer NFC adapters
- * </ul>
- * The NDEF message is preserved across reboot.
- * <p>Requires {@link android.Manifest.permission#NFC} permission.
- *
- * @param message NDEF message to make public
+ * Enable zero-click sharing.
+ *
* @hide
*/
- public void setLocalNdefMessage(NdefMessage message) {
+ public boolean enableZeroClick() {
try {
- sService.localSet(message);
+ return sService.enableZeroClick();
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
+ return false;
}
}
/**
- * Get the NDEF Message that this adapter appears as to Tag readers.
- * <p>Requires {@link android.Manifest.permission#NFC} permission.
+ * Disable zero-click sharing.
*
- * @return NDEF Message that is publicly readable
* @hide
*/
- public NdefMessage getLocalNdefMessage() {
+ public boolean disableZeroClick() {
try {
- return sService.localGet();
+ return sService.disableZeroClick();
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
- return null;
+ return false;
+ }
+ }
+
+ /**
+ * Return true if zero-click sharing is enabled.
+ *
+ * @return true if zero-click sharing is enabled
+ * @hide
+ */
+ public boolean zeroClickEnabled() {
+ try {
+ return sService.zeroClickEnabled();
+ } catch (RemoteException e) {
+ attemptDeadServiceRecovery(e);
+ return false;
}
}
diff --git a/core/java/android/nfc/tech/IsoDep.java b/core/java/android/nfc/tech/IsoDep.java
index d02086ffcf1f..0672a4eba281 100644
--- a/core/java/android/nfc/tech/IsoDep.java
+++ b/core/java/android/nfc/tech/IsoDep.java
@@ -101,6 +101,24 @@ public final class IsoDep extends BasicTagTechnology {
}
/**
+ * Gets the currently set timeout of {@link #transceive} in milliseconds.
+ *
+ * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
+ *
+ * @return timeout value in milliseconds
+ * @hide
+ */
+ // TODO Unhide for ICS
+ public int getTimeout() {
+ try {
+ return mTag.getTagService().getTimeout(TagTechnology.ISO_DEP);
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service dead", e);
+ return 0;
+ }
+ }
+
+ /**
* Return the ISO-DEP historical bytes for {@link NfcA} tags.
* <p>Does not cause any RF activity and does not block.
* <p>The historical bytes can be used to help identify a tag. They are present
diff --git a/core/java/android/nfc/tech/MifareClassic.java b/core/java/android/nfc/tech/MifareClassic.java
index 5cafe5ba6126..93e7cbddec94 100644
--- a/core/java/android/nfc/tech/MifareClassic.java
+++ b/core/java/android/nfc/tech/MifareClassic.java
@@ -597,6 +597,24 @@ public final class MifareClassic extends BasicTagTechnology {
}
}
+ /**
+ * Gets the currently set timeout of {@link #transceive} in milliseconds.
+ *
+ * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
+ *
+ * @return timeout value in milliseconds
+ * @hide
+ */
+ // TODO Unhide for ICS
+ public int getTimeout() {
+ try {
+ return mTag.getTagService().getTimeout(TagTechnology.MIFARE_CLASSIC);
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service dead", e);
+ return 0;
+ }
+ }
+
private static void validateSector(int sector) {
// Do not be too strict on upper bounds checking, since some cards
// have more addressable memory than they report. For example,
diff --git a/core/java/android/nfc/tech/MifareUltralight.java b/core/java/android/nfc/tech/MifareUltralight.java
index 3d4cdd1a8dff..ca74ebe521c9 100644
--- a/core/java/android/nfc/tech/MifareUltralight.java
+++ b/core/java/android/nfc/tech/MifareUltralight.java
@@ -238,6 +238,24 @@ public final class MifareUltralight extends BasicTagTechnology {
}
}
+ /**
+ * Gets the currently set timeout of {@link #transceive} in milliseconds.
+ *
+ * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
+ *
+ * @return timeout value in milliseconds
+ * @hide
+ */
+ // TODO Unhide for ICS
+ public int getTimeout() {
+ try {
+ return mTag.getTagService().getTimeout(TagTechnology.MIFARE_ULTRALIGHT);
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service dead", e);
+ return 0;
+ }
+ }
+
private static void validatePageIndex(int pageIndex) {
// Do not be too strict on upper bounds checking, since some cards
// may have more addressable memory than they report.
diff --git a/core/java/android/nfc/tech/NfcA.java b/core/java/android/nfc/tech/NfcA.java
index 08095e6cb163..bd1f95af63ec 100644
--- a/core/java/android/nfc/tech/NfcA.java
+++ b/core/java/android/nfc/tech/NfcA.java
@@ -141,4 +141,22 @@ public final class NfcA extends BasicTagTechnology {
Log.e(TAG, "NFC service dead", e);
}
}
+
+ /**
+ * Gets the currently set timeout of {@link #transceive} in milliseconds.
+ *
+ * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
+ *
+ * @return timeout value in milliseconds
+ * @hide
+ */
+ // TODO Unhide for ICS
+ public int getTimeout() {
+ try {
+ return mTag.getTagService().getTimeout(TagTechnology.NFC_A);
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service dead", e);
+ return 0;
+ }
+ }
}
diff --git a/core/java/android/nfc/tech/NfcF.java b/core/java/android/nfc/tech/NfcF.java
index 85abf89e6dfd..7b25a72231b9 100644
--- a/core/java/android/nfc/tech/NfcF.java
+++ b/core/java/android/nfc/tech/NfcF.java
@@ -140,4 +140,22 @@ public final class NfcF extends BasicTagTechnology {
Log.e(TAG, "NFC service dead", e);
}
}
+
+ /**
+ * Gets the currently set timeout of {@link #transceive} in milliseconds.
+ *
+ * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
+ *
+ * @return timeout value in milliseconds
+ * @hide
+ */
+ // TODO Unhide for ICS
+ public int getTimeout() {
+ try {
+ return mTag.getTagService().getTimeout(TagTechnology.NFC_F);
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service dead", e);
+ return 0;
+ }
+ }
}
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index cd39d5cc6dee..bc372447d63e 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -361,7 +361,8 @@ public class Handler {
/**
* Remove any pending posts of Runnable <var>r</var> with Object
- * <var>token</var> that are in the message queue.
+ * <var>token</var> that are in the message queue. If <var>token</var> is null,
+ * all callbacks will be removed.
*/
public final void removeCallbacks(Runnable r, Object token)
{
@@ -517,7 +518,8 @@ public class Handler {
/**
* Remove any pending posts of messages with code 'what' and whose obj is
- * 'object' that are in the message queue.
+ * 'object' that are in the message queue. If <var>token</var> is null,
+ * all messages will be removed.
*/
public final void removeMessages(int what, Object object) {
mQueue.removeMessages(this, what, object, true);
@@ -525,7 +527,8 @@ public class Handler {
/**
* Remove any pending posts of callbacks and sent messages whose
- * <var>obj</var> is <var>token</var>.
+ * <var>obj</var> is <var>token</var>. If <var>token</var> is null,
+ * all callbacks and messages will be removed.
*/
public final void removeCallbacksAndMessages(Object token) {
mQueue.removeCallbacksAndMessages(this, token);
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index f23052604528..1174e3b696f5 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -180,7 +180,7 @@ interface INetworkManagementService
/**
* Stop Wifi Access Point
*/
- void stopAccessPoint();
+ void stopAccessPoint(String wlanIface);
/**
* Set Access Point config
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index 720e802b66ea..c61f28a41894 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -130,19 +130,20 @@ public class Looper {
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
- wallStart = System.currentTimeMillis();
- threadStart = SystemClock.currentThreadTimeMillis();
+ wallStart = SystemClock.currentTimeMicro();
+ threadStart = SystemClock.currentThreadTimeMicro();
}
msg.target.dispatchMessage(msg);
if (logging != null) {
- long wallTime = System.currentTimeMillis() - wallStart;
- long threadTime = SystemClock.currentThreadTimeMillis() - threadStart;
+ long wallTime = SystemClock.currentTimeMicro() - wallStart;
+ long threadTime = SystemClock.currentThreadTimeMicro() - threadStart;
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
if (logging instanceof Profiler) {
- ((Profiler) logging).profile(msg, wallStart, wallTime, threadTime);
+ ((Profiler) logging).profile(msg, wallStart, wallTime,
+ threadStart, threadTime);
}
}
@@ -247,6 +248,7 @@ public class Looper {
* @hide
*/
public static interface Profiler {
- void profile(Message message, long wallStart, long wallTime, long threadTime);
+ void profile(Message message, long wallStart, long wallTime,
+ long threadStart, long threadTime);
}
}
diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java
index 2dd674987fc5..72917394139d 100644
--- a/core/java/android/os/SystemClock.java
+++ b/core/java/android/os/SystemClock.java
@@ -157,4 +157,22 @@ public final class SystemClock {
* @return elapsed milliseconds in the thread
*/
public static native long currentThreadTimeMillis();
+
+ /**
+ * Returns microseconds running in the current thread.
+ *
+ * @return elapsed microseconds in the thread
+ *
+ * @hide
+ */
+ public static native long currentThreadTimeMicro();
+
+ /**
+ * Returns current wall time in microseconds.
+ *
+ * @return elapsed microseconds in wall time
+ *
+ * @hide
+ */
+ public static native long currentTimeMicro();
}
diff --git a/core/java/android/preference/CheckBoxPreference.java b/core/java/android/preference/CheckBoxPreference.java
index 437e55332a81..166b21b66160 100644
--- a/core/java/android/preference/CheckBoxPreference.java
+++ b/core/java/android/preference/CheckBoxPreference.java
@@ -61,8 +61,8 @@ public class CheckBoxPreference extends TwoStatePreference {
View checkboxView = view.findViewById(com.android.internal.R.id.checkbox);
if (checkboxView != null && checkboxView instanceof Checkable) {
((Checkable) checkboxView).setChecked(mChecked);
-
- sendAccessibilityEventForView(checkboxView);
+ // Post this so this view is bound and attached when firing the event.
+ postSendAccessibilityEventForView(checkboxView);
}
syncSummaryView(view);
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index c90de176896b..78c9010af8fd 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -563,6 +563,12 @@ public abstract class PreferenceActivity extends ListActivity implements
// Single pane, showing just a prefs fragment.
findViewById(com.android.internal.R.id.headers).setVisibility(View.GONE);
mPrefsContainer.setVisibility(View.VISIBLE);
+ if (initialTitle != 0) {
+ CharSequence initialTitleStr = getText(initialTitle);
+ CharSequence initialShortTitleStr = initialShortTitle != 0
+ ? getText(initialShortTitle) : null;
+ showBreadCrumbs(initialTitleStr, initialShortTitleStr);
+ }
} else if (mHeaders.size() > 0) {
setListAdapter(new HeaderAdapter(this, mHeaders));
if (!mSinglePane) {
@@ -1093,6 +1099,10 @@ public abstract class PreferenceActivity extends ListActivity implements
} else {
getListView().clearChoices();
}
+ showBreadCrumbs(header);
+ }
+
+ void showBreadCrumbs(Header header) {
if (header != null) {
CharSequence title = header.getBreadCrumbTitle(getResources());
if (title == null) title = header.getTitle(getResources());
diff --git a/core/java/android/preference/SwitchPreference.java b/core/java/android/preference/SwitchPreference.java
index f681526a3ce4..3dbd5229cb83 100644
--- a/core/java/android/preference/SwitchPreference.java
+++ b/core/java/android/preference/SwitchPreference.java
@@ -102,8 +102,8 @@ public class SwitchPreference extends TwoStatePreference {
View checkableView = view.findViewById(com.android.internal.R.id.switchWidget);
if (checkableView != null && checkableView instanceof Checkable) {
((Checkable) checkableView).setChecked(mChecked);
-
- sendAccessibilityEventForView(checkableView);
+ // Post this so this view is bound and attached when firing the event.
+ postSendAccessibilityEventForView(checkableView);
if (checkableView instanceof Switch) {
final Switch switchView = (Switch) checkableView;
diff --git a/core/java/android/preference/TwoStatePreference.java b/core/java/android/preference/TwoStatePreference.java
index 8e21c4c493a5..55ef108e2932 100644
--- a/core/java/android/preference/TwoStatePreference.java
+++ b/core/java/android/preference/TwoStatePreference.java
@@ -16,7 +16,6 @@
package android.preference;
-import android.app.Service;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
@@ -39,28 +38,20 @@ public abstract class TwoStatePreference extends Preference {
private CharSequence mSummaryOff;
boolean mChecked;
private boolean mSendAccessibilityEventViewClickedType;
- private AccessibilityManager mAccessibilityManager;
private boolean mDisableDependentsState;
+ private SendAccessibilityEventTypeViewClicked mSendAccessibilityEventTypeViewClicked;
+
public TwoStatePreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
-
- mAccessibilityManager =
- (AccessibilityManager) getContext().getSystemService(Service.ACCESSIBILITY_SERVICE);
}
public TwoStatePreference(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- mAccessibilityManager =
- (AccessibilityManager) getContext().getSystemService(Service.ACCESSIBILITY_SERVICE);
+ this(context, attrs, 0);
}
public TwoStatePreference(Context context) {
- super(context);
-
- mAccessibilityManager =
- (AccessibilityManager) getContext().getSystemService(Service.ACCESSIBILITY_SERVICE);
+ this(context, null);
}
@Override
@@ -198,20 +189,23 @@ public abstract class TwoStatePreference extends Preference {
}
/**
- * Send an accessibility event for the given view if appropriate
+ * Post send an accessibility event for the given view if appropriate.
+ *
* @param view View that should send the event
*/
- void sendAccessibilityEventForView(View view) {
+ void postSendAccessibilityEventForView(View view) {
// send an event to announce the value change of the state. It is done here
// because clicking a preference does not immediately change the checked state
// for example when enabling the WiFi
- if (mSendAccessibilityEventViewClickedType &&
- mAccessibilityManager.isEnabled() &&
- view.isEnabled()) {
+ if (mSendAccessibilityEventViewClickedType
+ && AccessibilityManager.getInstance(getContext()).isEnabled()
+ && view.isEnabled()) {
mSendAccessibilityEventViewClickedType = false;
-
- int eventType = AccessibilityEvent.TYPE_VIEW_CLICKED;
- view.sendAccessibilityEventUnchecked(AccessibilityEvent.obtain(eventType));
+ if (mSendAccessibilityEventTypeViewClicked == null) {
+ mSendAccessibilityEventTypeViewClicked = new SendAccessibilityEventTypeViewClicked();
+ }
+ mSendAccessibilityEventTypeViewClicked.mView = view;
+ view.post(mSendAccessibilityEventTypeViewClicked);
}
}
@@ -306,4 +300,13 @@ public abstract class TwoStatePreference extends Preference {
}
};
}
+
+ private final class SendAccessibilityEventTypeViewClicked implements Runnable {
+ private View mView;
+
+ @Override
+ public void run() {
+ mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+ }
+ }
}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index c2998916add4..4a719ec7b9a1 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1439,6 +1439,13 @@ public final class ContactsContract {
CONTENT_URI, "strequent");
/**
+ * The content:// style URI for showing frequently contacted person listing.
+ * @hide
+ */
+ public static final Uri CONTENT_FREQUENT_URI = Uri.withAppendedPath(
+ CONTENT_URI, "frequent");
+
+ /**
* The content:// style URI used for "type-to-filter" functionality on the
* {@link #CONTENT_STREQUENT_URI} URI. The filter string will be used to match
* various parts of the contact name. The filter argument should be passed
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ad3204721fbd..1cd46dedd2d2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -16,8 +16,6 @@
package android.provider;
-
-
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.SearchManager;
@@ -48,7 +46,6 @@ import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.HashSet;
-
/**
* The Settings provider contains global system-level device preferences.
*/
@@ -2877,6 +2874,7 @@ public final class Settings {
* The acceptable packet loss percentage (range 0 - 100) before trying
* another AP on the same network.
*/
+ @Deprecated
public static final String WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE =
"wifi_watchdog_acceptable_packet_loss_percentage";
@@ -2884,11 +2882,13 @@ public final class Settings {
* The number of access points required for a network in order for the
* watchdog to monitor it.
*/
+ @Deprecated
public static final String WIFI_WATCHDOG_AP_COUNT = "wifi_watchdog_ap_count";
/**
* The delay between background checks.
*/
+ @Deprecated
public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS =
"wifi_watchdog_background_check_delay_ms";
@@ -2896,12 +2896,14 @@ public final class Settings {
* Whether the Wi-Fi watchdog is enabled for background checking even
* after it thinks the user has connected to a good access point.
*/
+ @Deprecated
public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED =
"wifi_watchdog_background_check_enabled";
/**
* The timeout for a background ping
*/
+ @Deprecated
public static final String WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS =
"wifi_watchdog_background_check_timeout_ms";
@@ -2911,6 +2913,7 @@ public final class Settings {
* calculation. For example, one network always seemed to time out for
* the first couple pings, so this is set to 3 by default.
*/
+ @Deprecated
public static final String WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT =
"wifi_watchdog_initial_ignored_ping_count";
@@ -2920,6 +2923,7 @@ public final class Settings {
* initial connection state for the network. This is a safeguard for
* networks containing multiple APs whose DNS does not respond to pings.
*/
+ @Deprecated
public static final String WIFI_WATCHDOG_MAX_AP_CHECKS = "wifi_watchdog_max_ap_checks";
/**
@@ -2930,24 +2934,85 @@ public final class Settings {
/**
* A comma-separated list of SSIDs for which the Wi-Fi watchdog should be enabled.
*/
+ @Deprecated
public static final String WIFI_WATCHDOG_WATCH_LIST = "wifi_watchdog_watch_list";
/**
* The number of pings to test if an access point is a good connection.
*/
+ @Deprecated
public static final String WIFI_WATCHDOG_PING_COUNT = "wifi_watchdog_ping_count";
/**
* The delay between pings.
*/
+ @Deprecated
public static final String WIFI_WATCHDOG_PING_DELAY_MS = "wifi_watchdog_ping_delay_ms";
/**
* The timeout per ping.
*/
+ @Deprecated
public static final String WIFI_WATCHDOG_PING_TIMEOUT_MS = "wifi_watchdog_ping_timeout_ms";
/**
+ * ms delay before rechecking an 'online' wifi connection when it is thought to be unstable.
+ * @hide
+ */
+ public static final String WIFI_WATCHDOG_DNS_CHECK_SHORT_INTERVAL_MS =
+ "wifi_watchdog_dns_check_short_interval_ms";
+
+ /**
+ * ms delay before rechecking an 'online' wifi connection when it is thought to be stable.
+ * @hide
+ */
+ public static final String WIFI_WATCHDOG_DNS_CHECK_LONG_INTERVAL_MS =
+ "wifi_watchdog_dns_check_long_interval_ms";
+
+ /**
+ * ms delay before rechecking a connect SSID for walled garden with a http download.
+ * @hide
+ */
+ public static final String WIFI_WATCHDOG_WALLED_GARDEN_INTERVAL_MS =
+ "wifi_watchdog_walled_garden_interval_ms";
+
+ /**
+ * max blacklist calls on an SSID before full dns check failures disable the network.
+ * @hide
+ */
+ public static final String WIFI_WATCHDOG_MAX_SSID_BLACKLISTS =
+ "wifi_watchdog_max_ssid_blacklists";
+
+ /**
+ * Number of dns pings per check.
+ * @hide
+ */
+ public static final String WIFI_WATCHDOG_NUM_DNS_PINGS = "wifi_watchdog_num_dns_pings";
+
+ /**
+ * Minimum number of responses to the dns pings to consider the test 'successful'.
+ * @hide
+ */
+ public static final String WIFI_WATCHDOG_MIN_DNS_RESPONSES =
+ "wifi_watchdog_min_dns_responses";
+
+ /**
+ * Timeout on dns pings
+ * @hide
+ */
+ public static final String WIFI_WATCHDOG_DNS_PING_TIMEOUT_MS =
+ "wifi_watchdog_dns_ping_timeout_ms";
+
+ /**
+ * We consider action from a 'blacklist' call to have finished by the end of
+ * this interval. If we are connected to the same AP with no network connection,
+ * we are likely stuck on an SSID with no external connectivity.
+ * @hide
+ */
+ public static final String WIFI_WATCHDOG_BLACKLIST_FOLLOWUP_INTERVAL_MS =
+ "wifi_watchdog_blacklist_followup_interval_ms";
+
+ /**
* Setting to turn off walled garden test on Wi-Fi. Feature is enabled by default and
* the setting needs to be set to 0 to disable it.
* @hide
@@ -2972,6 +3037,14 @@ public final class Settings {
"wifi_watchdog_walled_garden_pattern";
/**
+ * Boolean to determine whether to notify on disabling a network. Secure setting used
+ * to notify user only once. This setting is not monitored continuously.
+ * @hide
+ */
+ public static final String WIFI_WATCHDOG_SHOW_DISABLED_NETWORK_POPUP =
+ "wifi_watchdog_show_disabled_network_popup";
+
+ /**
* The maximum number of times we will retry a connection to an access
* point for which we have failed in acquiring an IP address from DHCP.
* A value of N means that we will make N+1 connection attempts in all.
@@ -3661,6 +3734,15 @@ public final class Settings {
*/
public static final String VOICE_RECOGNITION_SERVICE = "voice_recognition_service";
+
+ /**
+ * The {@link ComponentName} string of the service to be used as the spell checker
+ * service which is one of the services managed by the text service manager.
+ *
+ * @hide
+ */
+ public static final String SPELL_CHECKER_SERVICE = "spell_checker_service";
+
/**
* What happens when the user presses the Power button while in-call
* and the screen is on.<br/>
diff --git a/core/java/android/server/BluetoothBondState.java b/core/java/android/server/BluetoothBondState.java
index 75f38f934f48..30a8b2a0dda9 100644
--- a/core/java/android/server/BluetoothBondState.java
+++ b/core/java/android/server/BluetoothBondState.java
@@ -21,8 +21,13 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothHeadset;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.provider.Settings;
import android.util.Log;
import java.io.BufferedReader;
@@ -74,11 +79,17 @@ class BluetoothBondState {
private BluetoothA2dp mA2dpProxy;
private BluetoothHeadset mHeadsetProxy;
+ private ArrayList<String> mPairingRequestRcvd = new ArrayList<String>();
+
BluetoothBondState(Context context, BluetoothService service) {
mContext = context;
mService = service;
mBluetoothInputProfileHandler =
BluetoothInputProfileHandler.getInstance(mContext, mService);
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
+ mContext.registerReceiver(mReceiver, filter);
}
synchronized void setPendingOutgoingBonding(String address) {
@@ -137,11 +148,18 @@ class BluetoothBondState {
}
if (state == BluetoothDevice.BOND_BONDED) {
- mService.addProfileState(address);
+ boolean setTrust = false;
+ if (mPairingRequestRcvd.contains(address)) setTrust = true;
+
+ mService.addProfileState(address, setTrust);
+ mPairingRequestRcvd.remove(address);
+
} else if (state == BluetoothDevice.BOND_BONDING) {
if (mA2dpProxy == null || mHeadsetProxy == null) {
getProfileProxy();
}
+ } else if (state == BluetoothDevice.BOND_NONE) {
+ mPairingRequestRcvd.remove(address);
}
setProfilePriorities(address, state);
@@ -452,4 +470,17 @@ class BluetoothBondState {
}
}
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent == null) return;
+
+ String action = intent.getAction();
+ if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
+ BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+ String address = dev.getAddress();
+ mPairingRequestRcvd.add(address);
+ }
+ }
+ };
}
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index ff16c1883984..d68d8ba1e5b9 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -527,10 +527,19 @@ public class BluetoothService extends IBluetooth.Stub {
break;
case MESSAGE_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY:
address = (String)msg.obj;
- if (address != null) {
+ if (address == null) return;
+ int attempt = mBondState.getAttempt(address);
+
+ // Try only if attemps are in progress and cap it 2 attempts
+ // The 2 attempts cap is a fail safe if the stack returns
+ // an incorrect error code for bonding failures and if the pin
+ // is entered wrongly twice we should abort.
+ if (attempt > 0 && attempt <= 2) {
+ mBondState.attempt(address);
createBond(address);
return;
}
+ if (attempt > 0) mBondState.clearPinAttempts(address);
break;
}
}
@@ -741,7 +750,6 @@ public class BluetoothService extends IBluetooth.Stub {
BluetoothDevice.BOND_NONE, result);
return;
}
- mBondState.attempt(address);
}
/*package*/ BluetoothDevice getRemoteDevice(String address) {
@@ -2277,11 +2285,11 @@ public class BluetoothService extends IBluetooth.Stub {
return false;
}
- BluetoothDeviceProfileState addProfileState(String address) {
+ BluetoothDeviceProfileState addProfileState(String address, boolean setTrust) {
BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
if (state != null) return state;
- state = new BluetoothDeviceProfileState(mContext, address, this, mA2dpService);
+ state = new BluetoothDeviceProfileState(mContext, address, this, mA2dpService, setTrust);
mDeviceProfileState.put(address, state);
state.start();
return state;
@@ -2311,7 +2319,7 @@ public class BluetoothService extends IBluetooth.Stub {
}
for (String path : bonds) {
String address = getAddressFromObjectPath(path);
- BluetoothDeviceProfileState state = addProfileState(address);
+ BluetoothDeviceProfileState state = addProfileState(address, false);
}
}
diff --git a/core/java/android/service/textservice/SpellCheckerService.java b/core/java/android/service/textservice/SpellCheckerService.java
new file mode 100644
index 000000000000..6ac99cab0ebf
--- /dev/null
+++ b/core/java/android/service/textservice/SpellCheckerService.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.service.textservice;
+
+import com.android.internal.textservice.ISpellCheckerService;
+import com.android.internal.textservice.ISpellCheckerSession;
+import com.android.internal.textservice.ISpellCheckerSessionListener;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.view.textservice.SuggestionsInfo;
+import android.view.textservice.TextInfo;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * SpellCheckerService provides an abstract base class for a spell checker.
+ * This class combines a service to the system with the spell checker service interface that
+ * spell checker must implement.
+ */
+public abstract class SpellCheckerService extends Service {
+ private static final String TAG = SpellCheckerService.class.getSimpleName();
+ public static final String SERVICE_INTERFACE = SpellCheckerService.class.getName();
+
+ private final SpellCheckerServiceBinder mBinder = new SpellCheckerServiceBinder(this);
+
+ /**
+ * Get suggestions for specified text in TextInfo.
+ * This function will run on the incoming IPC thread. So, this is not called on the main thread,
+ * but will be called in series on another thread.
+ * @param textInfo the text metadata
+ * @param suggestionsLimit the number of limit of suggestions returned
+ * @param locale the locale for getting suggestions
+ * @return SuggestionInfo which contains suggestions for textInfo
+ */
+ public abstract SuggestionsInfo getSuggestions(
+ TextInfo textInfo, int suggestionsLimit, String locale);
+
+ /**
+ * A batch process of onGetSuggestions.
+ * This function will run on the incoming IPC thread. So, this is not called on the main thread,
+ * but will be called in series on another thread.
+ * @param textInfos an array of the text metadata
+ * @param locale the locale for getting suggestions
+ * @param suggestionsLimit the number of limit of suggestions returned
+ * @param sequentialWords true if textInfos can be treated as sequential words.
+ * @return an array of SuggestionInfo of onGetSuggestions
+ */
+ public SuggestionsInfo[] getSuggestionsMultiple(
+ TextInfo[] textInfos, String locale, int suggestionsLimit, boolean sequentialWords) {
+ final int length = textInfos.length;
+ final SuggestionsInfo[] retval = new SuggestionsInfo[length];
+ for (int i = 0; i < length; ++i) {
+ retval[i] = getSuggestions(textInfos[i], suggestionsLimit, locale);
+ retval[i].setCookieAndSequence(textInfos[i].getCookie(), textInfos[i].getSequence());
+ }
+ return retval;
+ }
+
+ /**
+ * Request to abort all tasks executed in SpellChecker.
+ * This function will run on the incoming IPC thread. So, this is not called on the main thread,
+ * but will be called in series on another thread.
+ */
+ public void cancel() {}
+
+ /**
+ * Implement to return the implementation of the internal spell checker
+ * service interface. Subclasses should not override.
+ */
+ @Override
+ public final IBinder onBind(final Intent intent) {
+ return mBinder;
+ }
+
+ private static class SpellCheckerSessionImpl extends ISpellCheckerSession.Stub {
+ private final WeakReference<SpellCheckerService> mInternalServiceRef;
+ private final String mLocale;
+ private final ISpellCheckerSessionListener mListener;
+
+ public SpellCheckerSessionImpl(
+ SpellCheckerService service, String locale, ISpellCheckerSessionListener listener) {
+ mInternalServiceRef = new WeakReference<SpellCheckerService>(service);
+ mLocale = locale;
+ mListener = listener;
+ }
+
+ @Override
+ public void getSuggestionsMultiple(
+ TextInfo[] textInfos, int suggestionsLimit, boolean sequentialWords) {
+ final SpellCheckerService service = mInternalServiceRef.get();
+ if (service == null) return;
+ try {
+ mListener.onGetSuggestions(
+ service.getSuggestionsMultiple(textInfos, mLocale,
+ suggestionsLimit, sequentialWords));
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public void cancel() {
+ final SpellCheckerService service = mInternalServiceRef.get();
+ if (service == null) return;
+ service.cancel();
+ }
+ }
+
+ private static class SpellCheckerServiceBinder extends ISpellCheckerService.Stub {
+ private final WeakReference<SpellCheckerService> mInternalServiceRef;
+
+ public SpellCheckerServiceBinder(SpellCheckerService service) {
+ mInternalServiceRef = new WeakReference<SpellCheckerService>(service);
+ }
+
+ @Override
+ public ISpellCheckerSession getISpellCheckerSession(
+ String locale, ISpellCheckerSessionListener listener) {
+ final SpellCheckerService service = mInternalServiceRef.get();
+ if (service == null) return null;
+ return new SpellCheckerSessionImpl(service, locale, listener);
+ }
+ }
+}
diff --git a/core/java/android/service/textservice/SpellCheckerSession.java b/core/java/android/service/textservice/SpellCheckerSession.java
new file mode 100644
index 000000000000..400454da40f9
--- /dev/null
+++ b/core/java/android/service/textservice/SpellCheckerSession.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.textservice;
+
+import com.android.internal.textservice.ISpellCheckerSession;
+import com.android.internal.textservice.ISpellCheckerSessionListener;
+import com.android.internal.textservice.ITextServicesManager;
+import com.android.internal.textservice.ITextServicesSessionListener;
+
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.textservice.SpellCheckerInfo;
+import android.view.textservice.SuggestionsInfo;
+import android.view.textservice.TextInfo;
+
+import java.util.LinkedList;
+import java.util.Locale;
+import java.util.Queue;
+
+/**
+ * The SpellCheckerSession interface provides the per client functionality of SpellCheckerService.
+ */
+public class SpellCheckerSession {
+ private static final String TAG = SpellCheckerSession.class.getSimpleName();
+ private static final boolean DBG = false;
+
+ private static final int MSG_ON_GET_SUGGESTION_MULTIPLE = 1;
+
+ private final InternalListener mInternalListener;
+ private final ITextServicesManager mTextServicesManager;
+ private final SpellCheckerInfo mSpellCheckerInfo;
+ private final SpellCheckerSessionListenerImpl mSpellCheckerSessionListenerImpl;
+
+ private boolean mIsUsed;
+ private SpellCheckerSessionListener mSpellCheckerSessionListener;
+
+ /** Handler that will execute the main tasks */
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_ON_GET_SUGGESTION_MULTIPLE:
+ handleOnGetSuggestionsMultiple((SuggestionsInfo[]) msg.obj);
+ break;
+ }
+ }
+ };
+
+ /**
+ * Constructor
+ * @hide
+ */
+ public SpellCheckerSession(
+ SpellCheckerInfo info, ITextServicesManager tsm, SpellCheckerSessionListener listener) {
+ if (info == null || listener == null || tsm == null) {
+ throw new NullPointerException();
+ }
+ mSpellCheckerInfo = info;
+ mSpellCheckerSessionListenerImpl = new SpellCheckerSessionListenerImpl(mHandler);
+ mInternalListener = new InternalListener();
+ mTextServicesManager = tsm;
+ mIsUsed = true;
+ mSpellCheckerSessionListener = listener;
+ }
+
+ /**
+ * @return true if the connection to a text service of this session is disconnected and not
+ * alive.
+ */
+ public boolean isSessionDisconnected() {
+ return mSpellCheckerSessionListenerImpl.isDisconnected();
+ }
+
+ /**
+ * Get the spell checker service info this spell checker session has.
+ * @return SpellCheckerInfo for the specified locale.
+ */
+ public SpellCheckerInfo getSpellChecker() {
+ return mSpellCheckerInfo;
+ }
+
+ /**
+ * Finish this session and allow TextServicesManagerService to disconnect the bound spell
+ * checker.
+ */
+ public void close() {
+ mIsUsed = false;
+ try {
+ mTextServicesManager.finishSpellCheckerService(mSpellCheckerSessionListenerImpl);
+ } catch (RemoteException e) {
+ // do nothing
+ }
+ }
+
+ /**
+ * Get candidate strings for a substring of the specified text.
+ * @param textInfo text metadata for a spell checker
+ * @param suggestionsLimit the number of limit of suggestions returned
+ */
+ public void getSuggestions(TextInfo textInfo, int suggestionsLimit) {
+ getSuggestions(new TextInfo[] {textInfo}, suggestionsLimit, false);
+ }
+
+ /**
+ * A batch process of getSuggestions
+ * @param textInfos an array of text metadata for a spell checker
+ * @param suggestionsLimit the number of limit of suggestions returned
+ * @param sequentialWords true if textInfos can be treated as sequential words.
+ */
+ public void getSuggestions(
+ TextInfo[] textInfos, int suggestionsLimit, boolean sequentialWords) {
+ // TODO: Handle multiple words suggestions by using WordBreakIterator
+ mSpellCheckerSessionListenerImpl.getSuggestionsMultiple(
+ textInfos, suggestionsLimit, sequentialWords);
+ }
+
+ private void handleOnGetSuggestionsMultiple(SuggestionsInfo[] suggestionInfos) {
+ mSpellCheckerSessionListener.onGetSuggestions(suggestionInfos);
+ }
+
+ private static class SpellCheckerSessionListenerImpl extends ISpellCheckerSessionListener.Stub {
+ private static final int TASK_CANCEL = 1;
+ private static final int TASK_GET_SUGGESTIONS_MULTIPLE = 2;
+ private final Queue<SpellCheckerParams> mPendingTasks =
+ new LinkedList<SpellCheckerParams>();
+ private final Handler mHandler;
+
+ private boolean mOpened;
+ private ISpellCheckerSession mISpellCheckerSession;
+
+ public SpellCheckerSessionListenerImpl(Handler handler) {
+ mOpened = false;
+ mHandler = handler;
+ }
+
+ private static class SpellCheckerParams {
+ public final int mWhat;
+ public final TextInfo[] mTextInfos;
+ public final int mSuggestionsLimit;
+ public final boolean mSequentialWords;
+ public SpellCheckerParams(int what, TextInfo[] textInfos, int suggestionsLimit,
+ boolean sequentialWords) {
+ mWhat = what;
+ mTextInfos = textInfos;
+ mSuggestionsLimit = suggestionsLimit;
+ mSequentialWords = sequentialWords;
+ }
+ }
+
+ private void processTask(SpellCheckerParams scp) {
+ switch (scp.mWhat) {
+ case TASK_CANCEL:
+ processCancel();
+ break;
+ case TASK_GET_SUGGESTIONS_MULTIPLE:
+ processGetSuggestionsMultiple(scp);
+ break;
+ }
+ }
+
+ public synchronized void onServiceConnected(ISpellCheckerSession session) {
+ mISpellCheckerSession = session;
+ mOpened = true;
+ if (DBG)
+ Log.d(TAG, "onServiceConnected - Success");
+ while (!mPendingTasks.isEmpty()) {
+ processTask(mPendingTasks.poll());
+ }
+ }
+
+ public void getSuggestionsMultiple(
+ TextInfo[] textInfos, int suggestionsLimit, boolean sequentialWords) {
+ processOrEnqueueTask(
+ new SpellCheckerParams(TASK_GET_SUGGESTIONS_MULTIPLE, textInfos,
+ suggestionsLimit, sequentialWords));
+ }
+
+ public boolean isDisconnected() {
+ return mOpened && mISpellCheckerSession == null;
+ }
+
+ public boolean checkOpenConnection() {
+ if (mISpellCheckerSession != null) {
+ return true;
+ }
+ Log.e(TAG, "not connected to the spellchecker service.");
+ return false;
+ }
+
+ private void processOrEnqueueTask(SpellCheckerParams scp) {
+ if (mISpellCheckerSession == null) {
+ mPendingTasks.offer(scp);
+ } else {
+ processTask(scp);
+ }
+ }
+
+ private void processCancel() {
+ if (!checkOpenConnection()) {
+ return;
+ }
+ try {
+ mISpellCheckerSession.cancel();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to cancel " + e);
+ }
+ }
+
+ private void processGetSuggestionsMultiple(SpellCheckerParams scp) {
+ if (!checkOpenConnection()) {
+ return;
+ }
+ try {
+ mISpellCheckerSession.getSuggestionsMultiple(
+ scp.mTextInfos, scp.mSuggestionsLimit, scp.mSequentialWords);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to get suggestions " + e);
+ }
+ }
+
+ @Override
+ public void onGetSuggestions(SuggestionsInfo[] results) {
+ mHandler.sendMessage(Message.obtain(mHandler, MSG_ON_GET_SUGGESTION_MULTIPLE, results));
+ }
+ }
+
+ /**
+ * Callback for getting results from text services
+ */
+ public interface SpellCheckerSessionListener {
+ /**
+ * Callback for "getSuggestions"
+ * @param results an array of results of getSuggestions
+ */
+ public void onGetSuggestions(SuggestionsInfo[] results);
+ }
+
+ private class InternalListener extends ITextServicesSessionListener.Stub {
+ @Override
+ public void onServiceConnected(ISpellCheckerSession session) {
+ mSpellCheckerSessionListenerImpl.onServiceConnected(session);
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ if (mIsUsed) {
+ Log.e(TAG, "SpellCheckerSession was not finished properly." +
+ "You should call finishShession() when you finished to use a spell checker.");
+ close();
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public ITextServicesSessionListener getTextServicesSessionListener() {
+ return mInternalListener;
+ }
+
+ /**
+ * @hide
+ */
+ public ISpellCheckerSessionListener getSpellCheckerSessionListener() {
+ return mSpellCheckerSessionListenerImpl;
+ }
+}
diff --git a/core/java/android/speech/tts/AudioPlaybackHandler.java b/core/java/android/speech/tts/AudioPlaybackHandler.java
index 255b333c8429..89b6f321e756 100644
--- a/core/java/android/speech/tts/AudioPlaybackHandler.java
+++ b/core/java/android/speech/tts/AudioPlaybackHandler.java
@@ -356,9 +356,7 @@ class AudioPlaybackHandler {
mLastSynthesisRequest = param;
// Create the audio track.
- final AudioTrack audioTrack = createStreamingAudioTrack(
- param.mStreamType, param.mSampleRateInHz, param.mAudioFormat,
- param.mChannelCount, param.mVolume, param.mPan);
+ final AudioTrack audioTrack = createStreamingAudioTrack(param);
if (DBG) Log.d(TAG, "Created audio track [" + audioTrack.hashCode() + "]");
@@ -405,16 +403,10 @@ class AudioPlaybackHandler {
param.mLogger.onPlaybackStart();
}
+ // Wait for the audio track to stop playing, and then release its resources.
private void handleSynthesisDone(MessageParams msg) {
final SynthesisMessageParams params = (SynthesisMessageParams) msg;
- handleSynthesisDone(params);
- // This call is delayed more than it should be, but we are
- // certain at this point that we have all the data we want.
- params.mLogger.onWriteData();
- }
- // Wait for the audio track to stop playing, and then release it's resources.
- private void handleSynthesisDone(SynthesisMessageParams params) {
if (DBG) Log.d(TAG, "handleSynthesisDone()");
final AudioTrack audioTrack = params.getAudioTrack();
@@ -422,6 +414,10 @@ class AudioPlaybackHandler {
return;
}
+ if (params.mBytesWritten < params.mAudioBufferSize) {
+ audioTrack.stop();
+ }
+
if (DBG) Log.d(TAG, "Waiting for audio track to complete : " +
audioTrack.hashCode());
blockUntilDone(params);
@@ -442,8 +438,15 @@ class AudioPlaybackHandler {
}
params.getDispatcher().dispatchUtteranceCompleted();
mLastSynthesisRequest = null;
+ params.mLogger.onWriteData();
}
+ /**
+ * The minimum increment of time to wait for an audiotrack to finish
+ * playing.
+ */
+ private static final long MIN_SLEEP_TIME_MS = 20;
+
private static void blockUntilDone(SynthesisMessageParams params) {
if (params.mAudioTrack == null || params.mBytesWritten <= 0) {
return;
@@ -460,36 +463,41 @@ class AudioPlaybackHandler {
break;
}
- long estimatedTimeMs = ((lengthInFrames - currentPosition) * 1000) /
+ final long estimatedTimeMs = ((lengthInFrames - currentPosition) * 1000) /
audioTrack.getSampleRate();
- if (DBG) Log.d(TAG, "About to sleep for : " + estimatedTimeMs + " ms," +
- " Playback position : " + currentPosition);
+ final long sleepTimeMs = Math.max(estimatedTimeMs, MIN_SLEEP_TIME_MS);
+
+ if (DBG) Log.d(TAG, "About to sleep for : " + sleepTimeMs + " ms," +
+ " Playback position : " + currentPosition + ", Length in frames : "
+ + lengthInFrames);
try {
- Thread.sleep(estimatedTimeMs);
+ Thread.sleep(sleepTimeMs);
} catch (InterruptedException ie) {
break;
}
}
}
- private static AudioTrack createStreamingAudioTrack(int streamType, int sampleRateInHz,
- int audioFormat, int channelCount, float volume, float pan) {
- int channelConfig = getChannelConfig(channelCount);
+ private static AudioTrack createStreamingAudioTrack(SynthesisMessageParams params) {
+ final int channelConfig = getChannelConfig(params.mChannelCount);
+ final int sampleRateInHz = params.mSampleRateInHz;
+ final int audioFormat = params.mAudioFormat;
int minBufferSizeInBytes
= AudioTrack.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
int bufferSizeInBytes = Math.max(MIN_AUDIO_BUFFER_SIZE, minBufferSizeInBytes);
- AudioTrack audioTrack = new AudioTrack(streamType, sampleRateInHz, channelConfig,
+ AudioTrack audioTrack = new AudioTrack(params.mStreamType, sampleRateInHz, channelConfig,
audioFormat, bufferSizeInBytes, AudioTrack.MODE_STREAM);
if (audioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
Log.w(TAG, "Unable to create audio track.");
audioTrack.release();
return null;
}
+ params.mAudioBufferSize = bufferSizeInBytes;
- setupVolume(audioTrack, volume, pan);
+ setupVolume(audioTrack, params.mVolume, params.mPan);
return audioTrack;
}
diff --git a/core/java/android/speech/tts/SynthesisMessageParams.java b/core/java/android/speech/tts/SynthesisMessageParams.java
index ffe70e27378e..7da5daabdb6d 100644
--- a/core/java/android/speech/tts/SynthesisMessageParams.java
+++ b/core/java/android/speech/tts/SynthesisMessageParams.java
@@ -35,6 +35,7 @@ final class SynthesisMessageParams extends MessageParams {
volatile AudioTrack mAudioTrack;
// Not volatile, accessed only from the synthesis thread.
int mBytesWritten;
+ int mAudioBufferSize;
private final LinkedList<ListEntry> mDataBufferList = new LinkedList<ListEntry>();
@@ -55,6 +56,7 @@ final class SynthesisMessageParams extends MessageParams {
// initially null.
mAudioTrack = null;
mBytesWritten = 0;
+ mAudioBufferSize = 0;
}
@Override
diff --git a/core/java/android/util/JsonReader.java b/core/java/android/util/JsonReader.java
index f1393721cb41..f2a86c969368 100644
--- a/core/java/android/util/JsonReader.java
+++ b/core/java/android/util/JsonReader.java
@@ -740,8 +740,8 @@ public final class JsonReader implements Closeable {
limit += total;
// if this is the first read, consume an optional byte order mark (BOM) if it exists
- if (bufferStartLine == 1 && bufferStartColumn == 1
- && limit > 0 && buffer[0] == '\ufeff') {
+ if (bufferStartLine == 1 && bufferStartColumn == 1
+ && limit > 0 && buffer[0] == '\ufeff') {
pos++;
bufferStartColumn--;
}
@@ -852,7 +852,7 @@ public final class JsonReader implements Closeable {
private boolean skipTo(String toFind) throws IOException {
outer:
- for (; pos + toFind.length() < limit || fillBuffer(toFind.length()); pos++) {
+ for (; pos + toFind.length() <= limit || fillBuffer(toFind.length()); pos++) {
for (int c = 0; c < toFind.length(); c++) {
if (buffer[pos + c] != toFind.charAt(c)) {
continue outer;
diff --git a/core/java/android/view/CollapsibleActionView.java b/core/java/android/view/CollapsibleActionView.java
new file mode 100644
index 000000000000..ab2365eb744c
--- /dev/null
+++ b/core/java/android/view/CollapsibleActionView.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.view.MenuItem.OnActionExpandListener;
+
+/**
+ * When a {@link View} implements this interface it will receive callbacks
+ * when expanded or collapsed as an action view alongside the optional,
+ * app-specified callbacks to {@link OnActionExpandListener}.
+ *
+ * <p>See {@link MenuItem} for more information about action views.
+ * See {@link android.app.ActionBar} for more information about the action bar.
+ */
+public interface CollapsibleActionView {
+ /**
+ * Called when this view is expanded as an action view.
+ * See {@link MenuItem#expandActionView()}.
+ */
+ public void onActionViewExpanded();
+
+ /**
+ * Called when this view is collapsed as an action view.
+ * See {@link MenuItem#collapseActionView()}.
+ */
+ public void onActionViewCollapsed();
+}
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index 4484d59a3ce4..f4c0249ab5a9 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -41,15 +41,6 @@ public abstract class DisplayList {
abstract void end();
/**
- * Indicates whether this display list can be replayed or not.
- *
- * @return True if the display list can be replayed, false otherwise.
- *
- * @see android.view.HardwareCanvas#drawDisplayList(DisplayList)
- */
- abstract boolean isReady();
-
- /**
* Invalidates the display list, indicating that it should be repopulated
* with new drawing commands prior to being used again. Calling this method
* causes calls to {@link #isValid()} to return <code>false</code>.
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 80244bbe9244..d22fa6e501ec 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -51,6 +51,7 @@ class GLES20Canvas extends HardwareCanvas {
// The native renderer will be destroyed when this object dies.
// DO NOT overwrite this reference once it is set.
+ @SuppressWarnings("unused")
private CanvasFinalizer mFinalizer;
private int mWidth;
@@ -97,12 +98,8 @@ class GLES20Canvas extends HardwareCanvas {
protected GLES20Canvas(boolean record, boolean translucent) {
mOpaque = !translucent;
- setupRenderer(record);
- }
-
- protected void setupRenderer(boolean record) {
if (record) {
- mRenderer = nGetDisplayListRenderer(mRenderer);
+ mRenderer = nCreateDisplayListRenderer();
} else {
mRenderer = nCreateRenderer();
}
@@ -114,43 +111,31 @@ class GLES20Canvas extends HardwareCanvas {
if (mRenderer == 0) {
throw new IllegalStateException("Could not create GLES20Canvas renderer");
} else {
- mFinalizer = CanvasFinalizer.getFinalizer(mFinalizer, mRenderer);
+ mFinalizer = new CanvasFinalizer(mRenderer);
}
}
+ protected void resetDisplayListRenderer() {
+ nResetDisplayListRenderer(mRenderer);
+ }
+
private static native int nCreateRenderer();
private static native int nCreateLayerRenderer(int layer);
- private static native int nGetDisplayListRenderer(int renderer);
+ private static native int nCreateDisplayListRenderer();
+ private static native void nResetDisplayListRenderer(int renderer);
private static native void nDestroyRenderer(int renderer);
- private static class CanvasFinalizer {
- int mRenderer;
-
- // Factory method returns new instance if old one is null, or old instance
- // otherwise, destroying native renderer along the way as necessary
- static CanvasFinalizer getFinalizer(CanvasFinalizer oldFinalizer, int renderer) {
- if (oldFinalizer == null) {
- return new CanvasFinalizer(renderer);
- }
- oldFinalizer.replaceNativeObject(renderer);
- return oldFinalizer;
- }
+ private static final class CanvasFinalizer {
+ private final int mRenderer;
- private CanvasFinalizer(int renderer) {
+ public CanvasFinalizer(int renderer) {
mRenderer = renderer;
}
- private void replaceNativeObject(int newRenderer) {
- if (mRenderer != 0 && newRenderer != mRenderer) {
- nDestroyRenderer(mRenderer);
- }
- mRenderer = newRenderer;
- }
-
@Override
protected void finalize() throws Throwable {
try {
- replaceNativeObject(0);
+ nDestroyRenderer(mRenderer);
} finally {
super.finalize();
}
@@ -322,11 +307,11 @@ class GLES20Canvas extends HardwareCanvas {
// Display list
///////////////////////////////////////////////////////////////////////////
- int getDisplayList() {
- return nGetDisplayList(mRenderer);
+ int getDisplayList(int displayList) {
+ return nGetDisplayList(mRenderer, displayList);
}
- private static native int nGetDisplayList(int renderer);
+ private static native int nGetDisplayList(int renderer, int displayList);
static void destroyDisplayList(int displayList) {
nDestroyDisplayList(displayList);
@@ -337,7 +322,7 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public boolean drawDisplayList(DisplayList displayList, int width, int height, Rect dirty) {
return nDrawDisplayList(mRenderer,
- ((GLES20DisplayList) displayList).mNativeDisplayList, width, height, dirty);
+ ((GLES20DisplayList) displayList).getNativeDisplayList(), width, height, dirty);
}
private static native boolean nDrawDisplayList(int renderer, int displayList,
@@ -345,7 +330,7 @@ class GLES20Canvas extends HardwareCanvas {
@Override
void outputDisplayList(DisplayList displayList) {
- nOutputDisplayList(mRenderer, ((GLES20DisplayList) displayList).mNativeDisplayList);
+ nOutputDisplayList(mRenderer, ((GLES20DisplayList) displayList).getNativeDisplayList());
}
private static native void nOutputDisplayList(int renderer, int displayList);
diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java
index aeff31f8a193..9e649cea63dc 100644
--- a/core/java/android/view/GLES20DisplayList.java
+++ b/core/java/android/view/GLES20DisplayList.java
@@ -16,52 +16,50 @@
package android.view;
-import java.lang.ref.WeakReference;
+import android.graphics.Bitmap;
+
+import java.util.ArrayList;
/**
* An implementation of display list for OpenGL ES 2.0.
*/
class GLES20DisplayList extends DisplayList {
- private GLES20Canvas mCanvas;
-
- private boolean mStarted = false;
- private boolean mRecorded = false;
- private boolean mValid = false;
+ // These lists ensure that any Bitmaps recorded by a DisplayList are kept alive as long
+ // as the DisplayList is alive. The Bitmaps are populated by the GLES20RecordingCanvas.
+ final ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(5);
- int mNativeDisplayList;
- WeakReference<View> hostView;
+ private GLES20RecordingCanvas mCanvas;
+ private boolean mValid;
// The native display list will be destroyed when this object dies.
// DO NOT overwrite this reference once it is set.
- @SuppressWarnings("unused")
private DisplayListFinalizer mFinalizer;
- public GLES20DisplayList(View view) {
- hostView = new WeakReference<View>(view);
+ int getNativeDisplayList() {
+ if (!mValid || mFinalizer == null) {
+ throw new IllegalStateException("The display list is not valid.");
+ }
+ return mFinalizer.mNativeDisplayList;
}
@Override
HardwareCanvas start() {
- if (mStarted) {
- throw new IllegalStateException("Recording has already started");
- }
-
if (mCanvas != null) {
- ((GLES20RecordingCanvas) mCanvas).reset();
- } else {
- mCanvas = new GLES20RecordingCanvas(true);
+ throw new IllegalStateException("Recording has already started");
}
- mStarted = true;
- mRecorded = false;
- mValid = true;
+ mValid = false;
+ mCanvas = GLES20RecordingCanvas.obtain(this);
+ mCanvas.start();
return mCanvas;
}
@Override
void invalidate() {
- mStarted = false;
- mRecorded = false;
+ if (mCanvas != null) {
+ mCanvas.recycle();
+ mCanvas = null;
+ }
mValid = false;
}
@@ -73,48 +71,28 @@ class GLES20DisplayList extends DisplayList {
@Override
void end() {
if (mCanvas != null) {
- mStarted = false;
- mRecorded = true;
-
- mNativeDisplayList = mCanvas.getDisplayList();
- mFinalizer = DisplayListFinalizer.getFinalizer(mFinalizer, mNativeDisplayList);
+ if (mFinalizer != null) {
+ mCanvas.end(mFinalizer.mNativeDisplayList);
+ } else {
+ mFinalizer = new DisplayListFinalizer(mCanvas.end(0));
+ }
+ mCanvas.recycle();
+ mCanvas = null;
+ mValid = true;
}
}
- @Override
- boolean isReady() {
- return !mStarted && mRecorded;
- }
-
private static class DisplayListFinalizer {
- int mNativeDisplayList;
-
- // Factory method returns new instance if old one is null, or old instance
- // otherwise, destroying native display list along the way as necessary
- static DisplayListFinalizer getFinalizer(DisplayListFinalizer oldFinalizer,
- int nativeDisplayList) {
- if (oldFinalizer == null) {
- return new DisplayListFinalizer(nativeDisplayList);
- }
- oldFinalizer.replaceNativeObject(nativeDisplayList);
- return oldFinalizer;
- }
+ final int mNativeDisplayList;
- private DisplayListFinalizer(int nativeDisplayList) {
+ public DisplayListFinalizer(int nativeDisplayList) {
mNativeDisplayList = nativeDisplayList;
}
- private void replaceNativeObject(int newNativeDisplayList) {
- if (mNativeDisplayList != 0 && mNativeDisplayList != newNativeDisplayList) {
- GLES20Canvas.destroyDisplayList(mNativeDisplayList);
- }
- mNativeDisplayList = newNativeDisplayList;
- }
-
@Override
protected void finalize() throws Throwable {
try {
- replaceNativeObject(0);
+ GLES20Canvas.destroyDisplayList(mNativeDisplayList);
} finally {
super.finalize();
}
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
index ec94fe70ae91..078222be6fe9 100644
--- a/core/java/android/view/GLES20RecordingCanvas.java
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -24,8 +24,10 @@ import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
-
-import java.util.ArrayList;
+import android.util.Pool;
+import android.util.Poolable;
+import android.util.PoolableManager;
+import android.util.Pools;
/**
* An implementation of a GL canvas that records drawing operations.
@@ -33,62 +35,94 @@ import java.util.ArrayList;
* Bitmap objects that it draws, preventing the backing memory of Bitmaps from being freed while
* the DisplayList is still holding a native reference to the memory.
*/
-class GLES20RecordingCanvas extends GLES20Canvas {
- // These lists ensure that any Bitmaps recorded by a DisplayList are kept alive as long
- // as the DisplayList is alive.
- @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
- private final ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(5);
+class GLES20RecordingCanvas extends GLES20Canvas implements Poolable<GLES20RecordingCanvas> {
+ // The recording canvas pool should be large enough to handle a deeply nested
+ // view hierarchy because display lists are generated recursively.
+ private static final int POOL_LIMIT = 50;
+
+ private static final Pool<GLES20RecordingCanvas> sPool = Pools.synchronizedPool(
+ Pools.finitePool(new PoolableManager<GLES20RecordingCanvas>() {
+ public GLES20RecordingCanvas newInstance() {
+ return new GLES20RecordingCanvas();
+ }
+ @Override
+ public void onAcquired(GLES20RecordingCanvas element) {
+ }
+ @Override
+ public void onReleased(GLES20RecordingCanvas element) {
+ }
+ }, POOL_LIMIT));
+
+ private GLES20RecordingCanvas mNextPoolable;
+ private boolean mIsPooled;
+
+ private GLES20DisplayList mDisplayList;
- GLES20RecordingCanvas(boolean translucent) {
- super(true, translucent);
+ private GLES20RecordingCanvas() {
+ super(true /*record*/, true /*translucent*/);
+ }
+
+ static GLES20RecordingCanvas obtain(GLES20DisplayList displayList) {
+ GLES20RecordingCanvas canvas = sPool.acquire();
+ canvas.mDisplayList = displayList;
+ return canvas;
+ }
+
+ void recycle() {
+ mDisplayList = null;
+ resetDisplayListRenderer();
+ sPool.release(this);
+ }
+
+ void start() {
+ mDisplayList.mBitmaps.clear();
+ }
+
+ int end(int nativeDisplayList) {
+ return getDisplayList(nativeDisplayList);
}
private void recordShaderBitmap(Paint paint) {
if (paint != null) {
final Shader shader = paint.getShader();
if (shader instanceof BitmapShader) {
- mBitmaps.add(((BitmapShader) shader).mBitmap);
+ mDisplayList.mBitmaps.add(((BitmapShader) shader).mBitmap);
}
}
}
- void reset() {
- mBitmaps.clear();
- setupRenderer(true);
- }
-
@Override
public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) {
super.drawPatch(bitmap, chunks, dst, paint);
- mBitmaps.add(bitmap);
+ mDisplayList.mBitmaps.add(bitmap);
// Shaders in the Paint are ignored when drawing a Bitmap
}
@Override
public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
super.drawBitmap(bitmap, left, top, paint);
- mBitmaps.add(bitmap);
+ mDisplayList.mBitmaps.add(bitmap);
// Shaders in the Paint are ignored when drawing a Bitmap
}
@Override
public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) {
super.drawBitmap(bitmap, matrix, paint);
- mBitmaps.add(bitmap);
+ mDisplayList.mBitmaps.add(bitmap);
// Shaders in the Paint are ignored when drawing a Bitmap
}
@Override
public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
super.drawBitmap(bitmap, src, dst, paint);
- mBitmaps.add(bitmap);
+ mDisplayList.mBitmaps.add(bitmap);
// Shaders in the Paint are ignored when drawing a Bitmap
}
@Override
public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) {
super.drawBitmap(bitmap, src, dst, paint);
- mBitmaps.add(bitmap);
+ mDisplayList.mBitmaps.add(bitmap);
// Shaders in the Paint are ignored when drawing a Bitmap
}
@@ -111,7 +145,7 @@ class GLES20RecordingCanvas extends GLES20Canvas {
int vertOffset, int[] colors, int colorOffset, Paint paint) {
super.drawBitmapMesh(bitmap, meshWidth, meshHeight, verts, vertOffset, colors, colorOffset,
paint);
- mBitmaps.add(bitmap);
+ mDisplayList.mBitmaps.add(bitmap);
// Shaders in the Paint are ignored when drawing a Bitmap
}
@@ -270,4 +304,24 @@ class GLES20RecordingCanvas extends GLES20Canvas {
colorOffset, indices, indexOffset, indexCount, paint);
recordShaderBitmap(paint);
}
+
+ @Override
+ public GLES20RecordingCanvas getNextPoolable() {
+ return mNextPoolable;
+ }
+
+ @Override
+ public void setNextPoolable(GLES20RecordingCanvas element) {
+ mNextPoolable = element;
+ }
+
+ @Override
+ public boolean isPooled() {
+ return mIsPooled;
+ }
+
+ @Override
+ public void setPooled(boolean isPooled) {
+ mIsPooled = isPooled;
+ }
}
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index b865b5007200..503b54bd437d 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -189,7 +189,7 @@ public abstract class HardwareRenderer {
*
* @return A new display list.
*/
- abstract DisplayList createDisplayList(View v);
+ abstract DisplayList createDisplayList();
/**
* Creates a new hardware layer. A hardware layer built by calling this
@@ -852,8 +852,8 @@ public abstract class HardwareRenderer {
}
@Override
- DisplayList createDisplayList(View v) {
- return new GLES20DisplayList(v);
+ DisplayList createDisplayList() {
+ return new GLES20DisplayList();
}
@Override
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 0108ecf17b6d..c68b01cac538 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9099,7 +9099,10 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED;
}
- private void resolvePadding() {
+ /**
+ * @hide
+ */
+ protected void resolvePadding() {
// If the user specified the absolute padding (either with android:padding or
// android:paddingLeft/Top/Right/Bottom), use this padding, otherwise
// use the default padding or the padding from the background drawable
@@ -9830,7 +9833,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
// we copy in child display lists into ours in drawChild()
mRecreateDisplayList = true;
if (mDisplayList == null) {
- mDisplayList = mAttachInfo.mHardwareRenderer.createDisplayList(this);
+ mDisplayList = mAttachInfo.mHardwareRenderer.createDisplayList();
// If we're creating a new display list, make sure our parent gets invalidated
// since they will need to recreate their display list to account for this
// new child display list.
@@ -12025,12 +12028,13 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
mPrivateFlags |= FORCE_LAYOUT;
mPrivateFlags |= INVALIDATED;
- if (mLayoutParams != null && mParent != null) {
- mLayoutParams.resolveWithDirection(getResolvedLayoutDirection());
- }
-
- if (mParent != null && !mParent.isLayoutRequested()) {
- mParent.requestLayout();
+ if (mParent != null) {
+ if (mLayoutParams != null) {
+ mLayoutParams.resolveWithDirection(getResolvedLayoutDirection());
+ }
+ if (!mParent.isLayoutRequested()) {
+ mParent.requestLayout();
+ }
}
}
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index b85159b2eaa8..4acf48c6b316 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -25,7 +25,9 @@ import android.os.Debug;
import android.os.Environment;
import android.os.Looper;
import android.os.Message;
+import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Printer;
@@ -35,7 +37,7 @@ import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
-import java.io.FileNotFoundException;
+import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
@@ -49,10 +51,14 @@ import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -424,22 +430,22 @@ public class ViewDebug {
* and obtain the traces. Both methods must be invoked on the
* same thread.
*
- * @param traceFile The path where to write the looper traces
- *
- * @see #stopLooperProfiling()
+ * @hide
*/
- public static void startLooperProfiling(File traceFile) {
+ public static void startLooperProfiling(String path, FileDescriptor fileDescriptor) {
if (sLooperProfilerStorage.get() == null) {
- LooperProfiler profiler = new LooperProfiler(traceFile);
+ LooperProfiler profiler = new LooperProfiler(path, fileDescriptor);
sLooperProfilerStorage.set(profiler);
Looper.myLooper().setMessageLogging(profiler);
}
- }
+ }
/**
* Stops profiling the looper associated with the current thread.
*
- * @see #startLooperProfiling(java.io.File)
+ * @see #startLooperProfiling(String, java.io.FileDescriptor)
+ *
+ * @hide
*/
public static void stopLooperProfiling() {
LooperProfiler profiler = sLooperProfilerStorage.get();
@@ -451,15 +457,35 @@ public class ViewDebug {
}
private static class LooperProfiler implements Looper.Profiler, Printer {
- private static final int LOOPER_PROFILER_VERSION = 1;
-
private static final String LOG_TAG = "LooperProfiler";
+ private static final int TRACE_VERSION_NUMBER = 3;
+ private static final int ACTION_EXIT_METHOD = 0x1;
+ private static final int HEADER_SIZE = 32;
+ private static final String HEADER_MAGIC = "SLOW";
+ private static final short HEADER_RECORD_SIZE = (short) 14;
+
+ private final long mTraceWallStart;
+ private final long mTraceThreadStart;
+
private final ArrayList<Entry> mTraces = new ArrayList<Entry>(512);
- private final File mTraceFile;
- public LooperProfiler(File traceFile) {
- mTraceFile = traceFile;
+ private final HashMap<String, Integer> mTraceNames = new HashMap<String, Integer>(32);
+ private int mTraceId = 0;
+
+ private final String mPath;
+ private ParcelFileDescriptor mFileDescriptor;
+
+ LooperProfiler(String path, FileDescriptor fileDescriptor) {
+ mPath = path;
+ try {
+ mFileDescriptor = ParcelFileDescriptor.dup(fileDescriptor);
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "Could not write trace file " + mPath, e);
+ throw new RuntimeException(e);
+ }
+ mTraceWallStart = SystemClock.currentTimeMicro();
+ mTraceThreadStart = SystemClock.currentThreadTimeMicro();
}
@Override
@@ -468,17 +494,28 @@ public class ViewDebug {
}
@Override
- public void profile(Message message, long wallStart, long wallTime, long threadTime) {
+ public void profile(Message message, long wallStart, long wallTime,
+ long threadStart, long threadTime) {
Entry entry = new Entry();
- entry.messageId = message.what;
- entry.name = message.getTarget().getMessageName(message);
+ entry.traceId = getTraceId(message);
entry.wallStart = wallStart;
entry.wallTime = wallTime;
+ entry.threadStart = threadStart;
entry.threadTime = threadTime;
mTraces.add(entry);
}
+ private int getTraceId(Message message) {
+ String name = message.getTarget().getMessageName(message);
+ Integer traceId = mTraceNames.get(name);
+ if (traceId == null) {
+ traceId = mTraceId++ << 4;
+ mTraceNames.put(name, traceId);
+ }
+ return traceId;
+ }
+
void save() {
// Don't block the UI thread
new Thread(new Runnable() {
@@ -486,52 +523,138 @@ public class ViewDebug {
public void run() {
saveTraces();
}
- }, "LooperProfiler[" + mTraceFile + "]").start();
+ }, "LooperProfiler[" + mPath + "]").start();
}
private void saveTraces() {
- FileOutputStream fos;
- try {
- fos = new FileOutputStream(mTraceFile);
- } catch (FileNotFoundException e) {
- Log.e(LOG_TAG, "Could not open trace file: " + mTraceFile);
- return;
- }
-
+ FileOutputStream fos = new FileOutputStream(mFileDescriptor.getFileDescriptor());
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fos));
try {
- out.writeInt(LOOPER_PROFILER_VERSION);
- out.writeInt(mTraces.size());
- for (Entry entry : mTraces) {
- saveTrace(entry, out);
- }
+ writeHeader(out, mTraceWallStart, mTraceNames, mTraces);
+ out.flush();
- Log.d(LOG_TAG, "Looper traces ready: " + mTraceFile);
+ writeTraces(fos, out.size(), mTraceWallStart, mTraceThreadStart, mTraces);
+
+ Log.d(LOG_TAG, "Looper traces ready: " + mPath);
} catch (IOException e) {
- Log.e(LOG_TAG, "Could not write trace file: ", e);
+ Log.e(LOG_TAG, "Could not write trace file " + mPath, e);
} finally {
try {
out.close();
} catch (IOException e) {
- // Ignore
+ Log.e(LOG_TAG, "Could not write trace file " + mPath, e);
+ }
+ try {
+ mFileDescriptor.close();
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "Could not write trace file " + mPath, e);
}
}
}
+
+ private static void writeTraces(FileOutputStream out, long offset, long wallStart,
+ long threadStart, ArrayList<Entry> entries) throws IOException {
+
+ FileChannel channel = out.getChannel();
+
+ // Header
+ ByteBuffer buffer = ByteBuffer.allocateDirect(HEADER_SIZE);
+ buffer.put(HEADER_MAGIC.getBytes());
+ buffer = buffer.order(ByteOrder.LITTLE_ENDIAN);
+ buffer.putShort((short) TRACE_VERSION_NUMBER); // version
+ buffer.putShort((short) HEADER_SIZE); // offset to data
+ buffer.putLong(wallStart); // start time in usec
+ buffer.putShort(HEADER_RECORD_SIZE); // size of a record in bytes
+ // padding to 32 bytes
+ for (int i = 0; i < HEADER_SIZE - 18; i++) {
+ buffer.put((byte) 0);
+ }
+
+ buffer.flip();
+ channel.position(offset).write(buffer);
+
+ buffer = ByteBuffer.allocateDirect(14).order(ByteOrder.LITTLE_ENDIAN);
+ for (Entry entry : entries) {
+ buffer.putShort((short) 1); // we simulate only one thread
+ buffer.putInt(entry.traceId); // entering method
+ buffer.putInt((int) (entry.threadStart - threadStart));
+ buffer.putInt((int) (entry.wallStart - wallStart));
+
+ buffer.flip();
+ channel.write(buffer);
+ buffer.clear();
+
+ buffer.putShort((short) 1);
+ buffer.putInt(entry.traceId | ACTION_EXIT_METHOD); // exiting method
+ buffer.putInt((int) (entry.threadStart + entry.threadTime - threadStart));
+ buffer.putInt((int) (entry.wallStart + entry.wallTime - wallStart));
+
+ buffer.flip();
+ channel.write(buffer);
+ buffer.clear();
+ }
+
+ channel.close();
+ }
+
+ private static void writeHeader(DataOutputStream out, long start,
+ HashMap<String, Integer> names, ArrayList<Entry> entries) throws IOException {
+
+ Entry last = entries.get(entries.size() - 1);
+ long wallTotal = (last.wallStart + last.wallTime) - start;
+
+ startSection("version", out);
+ addValue(null, Integer.toString(TRACE_VERSION_NUMBER), out);
+ addValue("data-file-overflow", "false", out);
+ addValue("clock", "dual", out);
+ addValue("elapsed-time-usec", Long.toString(wallTotal), out);
+ addValue("num-method-calls", Integer.toString(entries.size()), out);
+ addValue("clock-call-overhead-nsec", "1", out);
+ addValue("vm", "dalvik", out);
+
+ startSection("threads", out);
+ addThreadId(1, "main", out);
+
+ startSection("methods", out);
+ addMethods(names, out);
+
+ startSection("end", out);
+ }
+
+ private static void addMethods(HashMap<String, Integer> names, DataOutputStream out)
+ throws IOException {
+
+ for (Map.Entry<String, Integer> name : names.entrySet()) {
+ out.writeBytes(String.format("0x%08x\tEventQueue\t%s\t()V\tLooper\t-2\n",
+ name.getValue(), name.getKey()));
+ }
+ }
+
+ private static void addThreadId(int id, String name, DataOutputStream out)
+ throws IOException {
- private void saveTrace(Entry entry, DataOutputStream out) throws IOException {
- out.writeInt(entry.messageId);
- out.writeUTF(entry.name);
- out.writeLong(entry.wallStart);
- out.writeLong(entry.wallTime);
- out.writeLong(entry.threadTime);
+ out.writeBytes(Integer.toString(id) + '\t' + name + '\n');
+ }
+
+ private static void addValue(String name, String value, DataOutputStream out)
+ throws IOException {
+
+ if (name != null) {
+ out.writeBytes(name + "=");
+ }
+ out.writeBytes(value + '\n');
+ }
+
+ private static void startSection(String name, DataOutputStream out) throws IOException {
+ out.writeBytes("*" + name + '\n');
}
static class Entry {
- int messageId;
- String name;
+ int traceId;
long wallStart;
long wallTime;
+ long threadStart;
long threadTime;
}
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 54fee3c268e9..6f909713e4c1 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2148,9 +2148,12 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
onPopulateAccessibilityEvent(event);
// Let our children have a shot in populating the event.
for (int i = 0, count = getChildCount(); i < count; i++) {
- boolean handled = getChildAt(i).dispatchPopulateAccessibilityEvent(event);
- if (handled) {
- return handled;
+ View child = getChildAt(i);
+ if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
+ boolean handled = getChildAt(i).dispatchPopulateAccessibilityEvent(event);
+ if (handled) {
+ return handled;
+ }
}
}
return false;
@@ -2851,7 +2854,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
// display lists to render, force an invalidate to allow the animation to
// continue drawing another frame
invalidate(true);
- if (a instanceof AlphaAnimation) {
+ if (a.hasAlpha()) {
// alpha animations should cause the child to recreate its display list
child.invalidate(true);
}
diff --git a/core/java/android/view/animation/AlphaAnimation.java b/core/java/android/view/animation/AlphaAnimation.java
index 651fe458ab4b..c4d9afcc15c6 100644
--- a/core/java/android/view/animation/AlphaAnimation.java
+++ b/core/java/android/view/animation/AlphaAnimation.java
@@ -78,4 +78,12 @@ public class AlphaAnimation extends Animation {
public boolean willChangeBounds() {
return false;
}
+
+ /**
+ * @hide
+ */
+ @Override
+ public boolean hasAlpha() {
+ return true;
+ }
}
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index 87c759c48853..b7dfabcbed0f 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -1001,6 +1001,15 @@ public abstract class Animation implements Cloneable {
}
/**
+ * Return true if this animation changes the view's alpha property.
+ *
+ * @hide
+ */
+ public boolean hasAlpha() {
+ return false;
+ }
+
+ /**
* Utility class to parse a string description of a size.
*/
protected static class Description {
diff --git a/core/java/android/view/animation/AnimationSet.java b/core/java/android/view/animation/AnimationSet.java
index 873ce53ff315..4f2542b730de 100644
--- a/core/java/android/view/animation/AnimationSet.java
+++ b/core/java/android/view/animation/AnimationSet.java
@@ -43,6 +43,8 @@ public class AnimationSet extends Animation {
private static final int PROPERTY_CHANGE_BOUNDS_MASK = 0x80;
private int mFlags = 0;
+ private boolean mDirty;
+ private boolean mHasAlpha;
private ArrayList<Animation> mAnimations = new ArrayList<Animation>();
@@ -138,6 +140,28 @@ public class AnimationSet extends Animation {
}
/**
+ * @hide
+ */
+ @Override
+ public boolean hasAlpha() {
+ if (mDirty) {
+ mDirty = mHasAlpha = false;
+
+ final int count = mAnimations.size();
+ final ArrayList<Animation> animations = mAnimations;
+
+ for (int i = 0; i < count; i++) {
+ if (animations.get(i).hasAlpha()) {
+ mHasAlpha = true;
+ break;
+ }
+ }
+ }
+
+ return mHasAlpha;
+ }
+
+ /**
* <p>Sets the duration of every child animation.</p>
*
* @param durationMillis the duration of the animation, in milliseconds, for
@@ -175,6 +199,8 @@ public class AnimationSet extends Animation {
mLastEnd = Math.max(mLastEnd, a.getStartOffset() + a.getDuration());
mDuration = mLastEnd - mStartOffset;
}
+
+ mDirty = true;
}
/**
diff --git a/core/java/android/view/textservice/SpellCheckerInfo.aidl b/core/java/android/view/textservice/SpellCheckerInfo.aidl
new file mode 100644
index 000000000000..eb5dfcc01c88
--- /dev/null
+++ b/core/java/android/view/textservice/SpellCheckerInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.textservice;
+
+parcelable SpellCheckerInfo;
diff --git a/core/java/android/view/textservice/SpellCheckerInfo.java b/core/java/android/view/textservice/SpellCheckerInfo.java
new file mode 100644
index 000000000000..1205adfaceb3
--- /dev/null
+++ b/core/java/android/view/textservice/SpellCheckerInfo.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.view.textservice;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * This class is used to specify meta information of an spell checker.
+ */
+public final class SpellCheckerInfo implements Parcelable {
+ private final ResolveInfo mService;
+ private final String mId;
+
+ /**
+ * Constructor.
+ * @hide
+ */
+ public SpellCheckerInfo(Context context, ResolveInfo service) {
+ mService = service;
+ ServiceInfo si = service.serviceInfo;
+ mId = new ComponentName(si.packageName, si.name).flattenToShortString();
+ }
+
+ /**
+ * Constructor.
+ * @hide
+ */
+ public SpellCheckerInfo(Parcel source) {
+ mId = source.readString();
+ mService = ResolveInfo.CREATOR.createFromParcel(source);
+ }
+
+ /**
+ * Return a unique ID for this spell checker. The ID is generated from
+ * the package and class name implementing the method.
+ */
+ public String getId() {
+ return mId;
+ }
+
+
+ /**
+ * Return the component of the service that implements.
+ */
+ public ComponentName getComponent() {
+ return new ComponentName(
+ mService.serviceInfo.packageName, mService.serviceInfo.name);
+ }
+
+ /**
+ * Return the .apk package that implements this input method.
+ */
+ public String getPackageName() {
+ return mService.serviceInfo.packageName;
+ }
+
+ /**
+ * Used to package this object into a {@link Parcel}.
+ *
+ * @param dest The {@link Parcel} to be written.
+ * @param flags The flags used for parceling.
+ */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mId);
+ mService.writeToParcel(dest, flags);
+ }
+
+
+ /**
+ * Used to make this class parcelable.
+ */
+ public static final Parcelable.Creator<SpellCheckerInfo> CREATOR
+ = new Parcelable.Creator<SpellCheckerInfo>() {
+ @Override
+ public SpellCheckerInfo createFromParcel(Parcel source) {
+ return new SpellCheckerInfo(source);
+ }
+
+ @Override
+ public SpellCheckerInfo[] newArray(int size) {
+ return new SpellCheckerInfo[size];
+ }
+ };
+
+ /**
+ * Used to make this class parcelable.
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+}
diff --git a/core/java/android/view/textservice/SuggestionsInfo.aidl b/core/java/android/view/textservice/SuggestionsInfo.aidl
new file mode 100644
index 000000000000..66e20d24ce1c
--- /dev/null
+++ b/core/java/android/view/textservice/SuggestionsInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.textservice;
+
+parcelable SuggestionsInfo;
diff --git a/core/java/android/view/textservice/SuggestionsInfo.java b/core/java/android/view/textservice/SuggestionsInfo.java
new file mode 100644
index 000000000000..3332f1e262ee
--- /dev/null
+++ b/core/java/android/view/textservice/SuggestionsInfo.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.view.textservice;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * This class contains a metadata of suggestions from the text service
+ */
+public final class SuggestionsInfo implements Parcelable {
+ private static final String[] EMPTY = new String[0];
+
+ /**
+ * Flag of the attributes of the suggestions that can be obtained by
+ * {@link #getSuggestionsAttributes}: this tells that the requested word was found
+ * in the dictionary in the text service.
+ */
+ public static final int RESULT_ATTR_IN_THE_DICTIONARY = 0x0001;
+ /**
+ * Flag of the attributes of the suggestions that can be obtained by
+ * {@link #getSuggestionsAttributes}: this tells that the text service thinks the requested
+ * word looks a typo.
+ */
+ public static final int RESULT_ATTR_LOOKS_TYPO = 0x0002;
+ private final int mSuggestionsAttributes;
+ private final String[] mSuggestions;
+ private final boolean mSuggestionsAvailable;
+ private int mCookie;
+ private int mSequence;
+
+ /**
+ * Constructor.
+ * @param suggestionsAttributes from the text service
+ * @param suggestions from the text service
+ */
+ public SuggestionsInfo(int suggestionsAttributes, String[] suggestions) {
+ mSuggestionsAttributes = suggestionsAttributes;
+ if (suggestions == null) {
+ mSuggestions = EMPTY;
+ mSuggestionsAvailable = false;
+ } else {
+ mSuggestions = suggestions;
+ mSuggestionsAvailable = true;
+ }
+ mCookie = 0;
+ mSequence = 0;
+ }
+
+ /**
+ * Constructor.
+ * @param suggestionsAttributes from the text service
+ * @param suggestions from the text service
+ * @param cookie the cookie of the input TextInfo
+ * @param sequence the cookie of the input TextInfo
+ */
+ public SuggestionsInfo(
+ int suggestionsAttributes, String[] suggestions, int cookie, int sequence) {
+ if (suggestions == null) {
+ mSuggestions = EMPTY;
+ mSuggestionsAvailable = false;
+ } else {
+ mSuggestions = suggestions;
+ mSuggestionsAvailable = true;
+ }
+ mSuggestionsAttributes = suggestionsAttributes;
+ mCookie = cookie;
+ mSequence = sequence;
+ }
+
+ public SuggestionsInfo(Parcel source) {
+ mSuggestionsAttributes = source.readInt();
+ mSuggestions = source.readStringArray();
+ mCookie = source.readInt();
+ mSequence = source.readInt();
+ mSuggestionsAvailable = source.readInt() == 1;
+ }
+
+ /**
+ * Used to package this object into a {@link Parcel}.
+ *
+ * @param dest The {@link Parcel} to be written.
+ * @param flags The flags used for parceling.
+ */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mSuggestionsAttributes);
+ dest.writeStringArray(mSuggestions);
+ dest.writeInt(mCookie);
+ dest.writeInt(mSequence);
+ dest.writeInt(mSuggestionsAvailable ? 1 : 0);
+ }
+
+ /**
+ * Set the cookie and the sequence of SuggestionsInfo which are set to TextInfo from a client
+ * application
+ * @param cookie the cookie of an input TextInfo
+ * @param sequence the cookie of an input TextInfo
+ */
+ public void setCookieAndSequence(int cookie, int sequence) {
+ mCookie = cookie;
+ mSequence = sequence;
+ }
+
+ /**
+ * @return the cookie which may be set by a client application
+ */
+ public int getCookie() {
+ return mCookie;
+ }
+
+ /**
+ * @return the sequence which may be set by a client application
+ */
+ public int getSequence() {
+ return mSequence;
+ }
+
+ /**
+ * @return the attributes of suggestions. This includes whether the spell checker has the word
+ * in its dictionary or not and whether the spell checker has confident suggestions for the
+ * word or not.
+ */
+ public int getSuggestionsAttributes() {
+ return mSuggestionsAttributes;
+ }
+
+ /**
+ * @return the count of the suggestions. If there's no suggestions at all, this method returns
+ * -1. Even if this method returns 0, it doesn't necessarily mean that there are no suggestions
+ * for the requested word. For instance, the caller could have been asked to limit the maximum
+ * number of suggestions returned.
+ */
+ public int getSuggestionsCount() {
+ if (!mSuggestionsAvailable) {
+ return -1;
+ }
+ return mSuggestions.length;
+ }
+
+ /**
+ * @param i the id of suggestions
+ * @return the suggestion at the specified id
+ */
+ public String getSuggestionAt(int i) {
+ return mSuggestions[i];
+ }
+
+ /**
+ * Used to make this class parcelable.
+ */
+ public static final Parcelable.Creator<SuggestionsInfo> CREATOR
+ = new Parcelable.Creator<SuggestionsInfo>() {
+ @Override
+ public SuggestionsInfo createFromParcel(Parcel source) {
+ return new SuggestionsInfo(source);
+ }
+
+ @Override
+ public SuggestionsInfo[] newArray(int size) {
+ return new SuggestionsInfo[size];
+ }
+ };
+
+ /**
+ * Used to make this class parcelable.
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+}
diff --git a/core/java/android/view/textservice/TextInfo.aidl b/core/java/android/view/textservice/TextInfo.aidl
new file mode 100644
index 000000000000..d231d7638a75
--- /dev/null
+++ b/core/java/android/view/textservice/TextInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.textservice;
+
+parcelable TextInfo;
diff --git a/core/java/android/view/textservice/TextInfo.java b/core/java/android/view/textservice/TextInfo.java
new file mode 100644
index 000000000000..b534eb0be607
--- /dev/null
+++ b/core/java/android/view/textservice/TextInfo.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.view.textservice;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * This class contains a metadata of the input of TextService
+ */
+public final class TextInfo implements Parcelable {
+ private final String mText;
+ private final int mCookie;
+ private final int mSequence;
+
+ /**
+ * Constructor.
+ * @param text the text which will be input to TextService
+ */
+ public TextInfo(String text) {
+ this(text, 0, 0);
+ }
+
+ /**
+ * Constructor.
+ * @param text the text which will be input to TextService
+ * @param cookie the cookie for this TextInfo
+ * @param sequence the sequence number for this TextInfo
+ */
+ public TextInfo(String text, int cookie, int sequence) {
+ if (TextUtils.isEmpty(text)) {
+ throw new IllegalArgumentException(text);
+ }
+ mText = text;
+ mCookie = cookie;
+ mSequence = sequence;
+ }
+
+ public TextInfo(Parcel source) {
+ mText = source.readString();
+ mCookie = source.readInt();
+ mSequence = source.readInt();
+ }
+
+ /**
+ * Used to package this object into a {@link Parcel}.
+ *
+ * @param dest The {@link Parcel} to be written.
+ * @param flags The flags used for parceling.
+ */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mText);
+ dest.writeInt(mCookie);
+ dest.writeInt(mSequence);
+ }
+
+ /**
+ * @return the text which is an input of a text service
+ */
+ public String getText() {
+ return mText;
+ }
+
+ /**
+ * @return the cookie of TextInfo
+ */
+ public int getCookie() {
+ return mCookie;
+ }
+
+ /**
+ * @return the sequence of TextInfo
+ */
+ public int getSequence() {
+ return mSequence;
+ }
+
+ /**
+ * Used to make this class parcelable.
+ */
+ public static final Parcelable.Creator<TextInfo> CREATOR
+ = new Parcelable.Creator<TextInfo>() {
+ @Override
+ public TextInfo createFromParcel(Parcel source) {
+ return new TextInfo(source);
+ }
+
+ @Override
+ public TextInfo[] newArray(int size) {
+ return new TextInfo[size];
+ }
+ };
+
+ /**
+ * Used to make this class parcelable.
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+}
diff --git a/core/java/android/view/textservice/TextServicesManager.java b/core/java/android/view/textservice/TextServicesManager.java
new file mode 100644
index 000000000000..97494168a281
--- /dev/null
+++ b/core/java/android/view/textservice/TextServicesManager.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.view.textservice;
+
+import com.android.internal.textservice.ITextServicesManager;
+
+import android.content.Context;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.view.textservice.SpellCheckerInfo;
+import android.service.textservice.SpellCheckerSession;
+import android.service.textservice.SpellCheckerSession.SpellCheckerSessionListener;
+
+import java.util.Locale;
+
+/**
+ * System API to the overall text services, which arbitrates interaction between applications
+ * and text services. You can retrieve an instance of this interface with
+ * {@link Context#getSystemService(String) Context.getSystemService()}.
+ *
+ * The user can change the current text services in Settings. And also applications can specify
+ * the target text services.
+ */
+public final class TextServicesManager {
+ private static final String TAG = TextServicesManager.class.getSimpleName();
+
+ private static TextServicesManager sInstance;
+ private static ITextServicesManager sService;
+
+ private TextServicesManager() {
+ if (sService == null) {
+ IBinder b = ServiceManager.getService(Context.TEXT_SERVICES_MANAGER_SERVICE);
+ sService = ITextServicesManager.Stub.asInterface(b);
+ }
+ }
+
+ /**
+ * Retrieve the global TextServicesManager instance, creating it if it doesn't already exist.
+ * @hide
+ */
+ public static TextServicesManager getInstance() {
+ synchronized (TextServicesManager.class) {
+ if (sInstance != null) {
+ return sInstance;
+ }
+ sInstance = new TextServicesManager();
+ }
+ return sInstance;
+ }
+
+ /**
+ * Get a spell checker session for the specified spell checker
+ * @param locale the locale for the spell checker
+ * @param listener a spell checker session lister for getting results from a spell checker.
+ * @param referToSpellCheckerLanguageSettings if true, the session for one of enabled
+ * languages in settings will be returned.
+ * @return the spell checker session of the spell checker
+ */
+ // TODO: Add a method to get enabled spell checkers.
+ // TODO: Handle referToSpellCheckerLanguageSettings
+ public SpellCheckerSession newSpellCheckerSession(Locale locale,
+ SpellCheckerSessionListener listener, boolean referToSpellCheckerLanguageSettings) {
+ if (locale == null || listener == null) {
+ throw new NullPointerException();
+ }
+ final SpellCheckerInfo info;
+ try {
+ info = sService.getCurrentSpellChecker(locale.toString());
+ } catch (RemoteException e) {
+ return null;
+ }
+ if (info == null) {
+ return null;
+ }
+ final SpellCheckerSession session = new SpellCheckerSession(info, sService, listener);
+ try {
+ sService.getSpellCheckerService(
+ info, locale.toString(), session.getTextServicesSessionListener(),
+ session.getSpellCheckerSessionListener());
+ } catch (RemoteException e) {
+ return null;
+ }
+ return session;
+ }
+}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index b22c57b0359e..6a3b2ffefae1 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -6330,8 +6330,8 @@ public class WebView extends AbsoluteLayout
if (action == MotionEvent.ACTION_POINTER_DOWN) {
cancelTouch();
action = MotionEvent.ACTION_DOWN;
- } else if (action == MotionEvent.ACTION_POINTER_UP && ev.getPointerCount() == 2) {
- // set mLastTouchX/Y to the remaining point
+ } else if (action == MotionEvent.ACTION_POINTER_UP && ev.getPointerCount() >= 2) {
+ // set mLastTouchX/Y to the remaining points for multi-touch.
mLastTouchX = Math.round(x);
mLastTouchY = Math.round(y);
} else if (action == MotionEvent.ACTION_MOVE) {
@@ -9119,20 +9119,12 @@ public class WebView extends AbsoluteLayout
return nativeTileProfilingNumTilesInFrame(frame);
}
/** @hide only used by profiling tests */
- public int tileProfilingGetX(int frame, int tile) {
- return nativeTileProfilingGetX(frame, tile);
+ public int tileProfilingGetInt(int frame, int tile, String key) {
+ return nativeTileProfilingGetInt(frame, tile, key);
}
/** @hide only used by profiling tests */
- public int tileProfilingGetY(int frame, int tile) {
- return nativeTileProfilingGetY(frame, tile);
- }
- /** @hide only used by profiling tests */
- public boolean tileProfilingGetReady(int frame, int tile) {
- return nativeTileProfilingGetReady(frame, tile);
- }
- /** @hide only used by profiling tests */
- public int tileProfilingGetLevel(int frame, int tile) {
- return nativeTileProfilingGetLevel(frame, tile);
+ public float tileProfilingGetFloat(int frame, int tile, String key) {
+ return nativeTileProfilingGetFloat(frame, tile, key);
}
private native int nativeCacheHitFramePointer();
@@ -9262,10 +9254,8 @@ public class WebView extends AbsoluteLayout
private native void nativeTileProfilingClear();
private native int nativeTileProfilingNumFrames();
private native int nativeTileProfilingNumTilesInFrame(int frame);
- private native int nativeTileProfilingGetX(int frame, int tile);
- private native int nativeTileProfilingGetY(int frame, int tile);
- private native boolean nativeTileProfilingGetReady(int frame, int tile);
- private native int nativeTileProfilingGetLevel(int frame, int tile);
+ private native int nativeTileProfilingGetInt(int frame, int tile, String key);
+ private native float nativeTileProfilingGetFloat(int frame, int tile, String key);
// Never call this version except by updateCachedTextfield(String) -
// we always want to pass in our generation number.
private native void nativeUpdateCachedTextfield(String updatedText,
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index d7a2526003e7..8d8023bb0dd3 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1069,6 +1069,15 @@ public final class WebViewCore {
+ " arg1=" + msg.arg1 + " arg2=" + msg.arg2
+ " obj=" + msg.obj);
}
+ if (mWebView == null
+ && msg.what != EventHub.RESUME_TIMERS
+ && msg.what != EventHub.PAUSE_TIMERS) {
+ if (DebugFlags.WEB_VIEW_CORE) {
+ Log.v(LOGTAG, "Rejecting message " + msg.what
+ + " because we are destroyed");
+ }
+ return;
+ }
switch (msg.what) {
case WEBKIT_DRAW:
webkitDraw();
@@ -1757,30 +1766,17 @@ public final class WebViewCore {
}
/**
- * Removes pending messages and trigger a DESTROY message to send to
- * WebCore.
+ * Sends a DESTROY message to WebCore.
* Called from UI thread.
*/
void destroy() {
- // We don't want anyone to post a message between removing pending
- // messages and sending the destroy message.
synchronized (mEventHub) {
- // RESUME_TIMERS and PAUSE_TIMERS are per process base. They need to
- // be preserved even the WebView is destroyed.
- // Note: we should not have more than one RESUME_TIMERS/PAUSE_TIMERS
- boolean hasResume = mEventHub.hasMessages(EventHub.RESUME_TIMERS);
- boolean hasPause = mEventHub.hasMessages(EventHub.PAUSE_TIMERS);
- mEventHub.removeMessages();
+ // Do not call removeMessages as then we risk removing PAUSE_TIMERS
+ // or RESUME_TIMERS messages, which we must still handle as they
+ // are per process. DESTROY will instead trigger a white list in
+ // mEventHub, skipping any remaining messages in the queue
mEventHub.sendMessageAtFrontOfQueue(
Message.obtain(null, EventHub.DESTROY));
- if (hasPause) {
- mEventHub.sendMessageAtFrontOfQueue(
- Message.obtain(null, EventHub.PAUSE_TIMERS));
- }
- if (hasResume) {
- mEventHub.sendMessageAtFrontOfQueue(
- Message.obtain(null, EventHub.RESUME_TIMERS));
- }
mEventHub.blockMessages();
}
}
@@ -2113,13 +2109,17 @@ public final class WebViewCore {
// called from JNI or WebView thread
/* package */ void contentDraw() {
- // don't update the Picture until we have an initial width and finish
- // the first layout
- if (mCurrentViewWidth == 0 || !mBrowserFrame.firstLayoutDone()) {
- return;
- }
- // only fire an event if this is our first request
synchronized (this) {
+ if (mWebView == null || mBrowserFrame == null) {
+ // We were destroyed
+ return;
+ }
+ // don't update the Picture until we have an initial width and finish
+ // the first layout
+ if (mCurrentViewWidth == 0 || !mBrowserFrame.firstLayoutDone()) {
+ return;
+ }
+ // only fire an event if this is our first request
if (mDrawIsScheduled) return;
mDrawIsScheduled = true;
if (mDrawIsPaused) return;
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 49ea9445e46f..70e48ad74e8d 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -794,6 +794,8 @@ class ZoomManager {
mInitialZoomOverview = false;
dismissZoomPicker();
mFocusMovementQueue.clear();
+ mFocusX = detector.getFocusX();
+ mFocusY = detector.getFocusY();
mWebView.mViewManager.startZoom();
mWebView.onPinchToZoomAnimationStart();
mAccumulatedSpan = 0;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 8f8c1d069b9d..b7c1687debef 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -4638,9 +4638,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
childrenTop += getVerticalFadingEdgeLength();
}
}
- // Don't ever focus a disabled item.
- if (!mAdapter.isEnabled(i)) continue;
-
if (top >= childrenTop) {
// Found a view whose top is fully visisble
selectedPos = firstPosition + i;
diff --git a/core/java/android/widget/ActivityChooserModel.java b/core/java/android/widget/ActivityChooserModel.java
index d7429b38d2ad..4b0a6da774e9 100644
--- a/core/java/android/widget/ActivityChooserModel.java
+++ b/core/java/android/widget/ActivityChooserModel.java
@@ -317,6 +317,7 @@ public class ActivityChooserModel extends DataSetObservable {
dataModel = new ActivityChooserModel(context, historyFileName);
sDataModelRegistry.put(historyFileName, dataModel);
}
+ dataModel.readHistoricalData();
return dataModel;
}
}
@@ -505,7 +506,7 @@ public class ActivityChooserModel extends DataSetObservable {
* data is read until this method is invoked.
* <p>
*/
- public void readHistoricalData() {
+ private void readHistoricalData() {
synchronized (mInstanceLock) {
if (!mCanReadHistoricalData || !mHistoricalRecordsChanged) {
return;
@@ -527,7 +528,7 @@ public class ActivityChooserModel extends DataSetObservable {
* @throws IllegalStateException If this method is called before a call to
* {@link #readHistoricalData()}.
*/
- public void persistHistoricalData() {
+ private void persistHistoricalData() {
synchronized (mInstanceLock) {
if (!mReadShareHistoryCalled) {
throw new IllegalStateException("No preceding call to #readHistoricalData");
@@ -629,6 +630,7 @@ public class ActivityChooserModel extends DataSetObservable {
if (added) {
mHistoricalRecordsChanged = true;
pruneExcessiveHistoricalRecordsLocked();
+ persistHistoricalData();
sortActivities();
}
return added;
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 5b69aa8fb1e9..d85f8a49bdc3 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -307,7 +307,6 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
ActivityChooserModel dataModel = mAdapter.getDataModel();
if (dataModel != null) {
dataModel.registerObserver(mModelDataSetOberver);
- dataModel.readHistoricalData();
}
mIsAttachedToWindow = true;
}
@@ -318,7 +317,6 @@ public class ActivityChooserView extends ViewGroup implements ActivityChooserMod
ActivityChooserModel dataModel = mAdapter.getDataModel();
if (dataModel != null) {
dataModel.unregisterObserver(mModelDataSetOberver);
- dataModel.persistHistoricalData();
}
mIsAttachedToWindow = false;
}
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 755d4e09c039..00c75a947a2a 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -902,15 +902,16 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {
@Override
public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
- // Add a record for ourselves as well.
- AccessibilityEvent record = AccessibilityEvent.obtain();
- record.setSource(this);
- // Set the class since it is not populated in #dispatchPopulateAccessibilityEvent
- record.setClassName(getClass().getName());
- child.onInitializeAccessibilityEvent(record);
- child.dispatchPopulateAccessibilityEvent(record);
- event.appendRecord(record);
- return true;
+ if (super.onRequestSendAccessibilityEvent(child, event)) {
+ // Add a record for ourselves as well.
+ AccessibilityEvent record = AccessibilityEvent.obtain();
+ onInitializeAccessibilityEvent(record);
+ // Populate with the text of the requesting child.
+ child.dispatchPopulateAccessibilityEvent(record);
+ event.appendRecord(record);
+ return true;
+ }
+ return false;
}
@Override
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index 49616cc1ef18..f3a6da7780bb 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -39,8 +39,9 @@ public class CheckedTextView extends TextView implements Checkable {
private boolean mChecked;
private int mCheckMarkResource;
private Drawable mCheckMarkDrawable;
- private int mBasePaddingRight;
+ private int mBasePadding;
private int mCheckMarkWidth;
+ private boolean mNeedRequestlayout;
private static final int[] CHECKED_STATE_SET = {
R.attr.state_checked
@@ -123,6 +124,7 @@ public class CheckedTextView extends TextView implements Checkable {
mCheckMarkDrawable.setCallback(null);
unscheduleDrawable(mCheckMarkDrawable);
}
+ mNeedRequestlayout = (d != mCheckMarkDrawable);
if (d != null) {
d.setCallback(this);
d.setVisible(getVisibility() == VISIBLE, false);
@@ -130,19 +132,35 @@ public class CheckedTextView extends TextView implements Checkable {
setMinHeight(d.getIntrinsicHeight());
mCheckMarkWidth = d.getIntrinsicWidth();
- mUserPaddingRight = mCheckMarkWidth + mBasePaddingRight;
d.setState(getDrawableState());
} else {
- mUserPaddingRight = mBasePaddingRight;
+ mCheckMarkWidth = 0;
}
mCheckMarkDrawable = d;
- requestLayout();
+ // Do padding resolution. This will call setPadding() and do a requestLayout() if needed.
+ resolvePadding();
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ protected void resolvePadding() {
+ super.resolvePadding();
+ int newPadding = (mCheckMarkDrawable != null) ?
+ mCheckMarkWidth + mBasePadding : mBasePadding;
+ mNeedRequestlayout |= (mPaddingRight != newPadding);
+ mPaddingRight = newPadding;
+ if (mNeedRequestlayout) {
+ requestLayout();
+ mNeedRequestlayout = false;
+ }
}
@Override
public void setPadding(int left, int top, int right, int bottom) {
super.setPadding(left, top, right, bottom);
- mBasePaddingRight = mUserPaddingRight;
+ mBasePadding = mPaddingRight;
}
@Override
@@ -167,9 +185,9 @@ public class CheckedTextView extends TextView implements Checkable {
int right = getWidth();
checkMarkDrawable.setBounds(
- right - mUserPaddingRight,
+ right - mPaddingRight,
y,
- right - mUserPaddingRight + mCheckMarkWidth,
+ right - mPaddingRight + mCheckMarkWidth,
y + height);
checkMarkDrawable.draw(canvas);
}
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index 5747fd334494..3bd7fabe9ec7 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -596,7 +596,6 @@ public class GridLayout extends ViewGroup {
int col = 0;
for (int i = 0, N = getChildCount(); i < N; i++) {
View c = getChildAt(i);
- if (isGone(c)) continue;
LayoutParams lp = getLayoutParams1(c);
final Spec colSpec = lp.columnSpec;
@@ -1002,7 +1001,6 @@ public class GridLayout extends ViewGroup {
int count = -1;
for (int i = 0, N = getChildCount(); i < N; i++) {
View c = getChildAt(i);
- if (isGone(c)) continue;
LayoutParams params = getLayoutParams(c);
Spec spec = horizontal ? params.columnSpec : params.rowSpec;
count = max(count, spec.span.min);
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 161b40401327..299e1ffd2a6c 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -30,14 +30,15 @@ import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.RemotableViewMethod;
import android.view.View;
import android.view.ViewDebug;
+import android.view.accessibility.AccessibilityEvent;
import android.widget.RemoteViews.RemoteView;
-
/**
* Displays an arbitrary image, such as an icon. The ImageView class
* can load images from various sources (such as resources or content
@@ -208,7 +209,15 @@ public class ImageView extends View {
}
return false;
}
-
+
+ @Override
+ public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+ CharSequence contentDescription = getContentDescription();
+ if (!TextUtils.isEmpty(contentDescription)) {
+ event.getText().add(contentDescription);
+ }
+ }
+
/**
* Set this to true if you want the ImageView to adjust its bounds
* to preserve the aspect ratio of its drawable.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index b116f0f58b44..a7324b085f9b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -16,11 +16,6 @@
package android.widget;
-import com.android.internal.util.FastMath;
-import com.android.internal.widget.EditableInputConnection;
-
-import org.xmlpull.v1.XmlPullParserException;
-
import android.R;
import android.content.ClipData;
import android.content.ClipData.Item;
@@ -139,6 +134,11 @@ import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.RemoteViews.RemoteView;
+import com.android.internal.util.FastMath;
+import com.android.internal.widget.EditableInputConnection;
+
+import org.xmlpull.v1.XmlPullParserException;
+
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.text.BreakIterator;
@@ -329,7 +329,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private int mTextEditPasteWindowLayout, mTextEditSidePasteWindowLayout;
private int mTextEditNoPasteWindowLayout, mTextEditSideNoPasteWindowLayout;
- private int mTextEditSuggestionsBottomWindowLayout, mTextEditSuggestionsTopWindowLayout;
+ private int mTextEditSuggestionsWindowLayout;
private int mTextEditSuggestionItemLayout;
private SuggestionsPopupWindow mSuggestionsPopupWindow;
private SuggestionRangeSpan mSuggestionRangeSpan;
@@ -830,12 +830,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mTextEditSideNoPasteWindowLayout = a.getResourceId(attr, 0);
break;
- case com.android.internal.R.styleable.TextView_textEditSuggestionsBottomWindowLayout:
- mTextEditSuggestionsBottomWindowLayout = a.getResourceId(attr, 0);
- break;
-
- case com.android.internal.R.styleable.TextView_textEditSuggestionsTopWindowLayout:
- mTextEditSuggestionsTopWindowLayout = a.getResourceId(attr, 0);
+ case com.android.internal.R.styleable.TextView_textEditSuggestionsWindowLayout:
+ mTextEditSuggestionsWindowLayout = a.getResourceId(attr, 0);
break;
case com.android.internal.R.styleable.TextView_textEditSuggestionItemLayout:
@@ -5090,6 +5086,40 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
@Override
+ public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ boolean areSuggestionsShown = areSuggestionsShown();
+ boolean isInSelectionMode = mSelectionActionMode != null;
+
+ if (areSuggestionsShown || isInSelectionMode) {
+ if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
+ KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null) {
+ state.startTracking(event, this);
+ }
+ return true;
+ } else if (event.getAction() == KeyEvent.ACTION_UP) {
+ KeyEvent.DispatcherState state = getKeyDispatcherState();
+ if (state != null) {
+ state.handleUpEvent(event);
+ }
+ if (event.isTracking() && !event.isCanceled()) {
+ if (areSuggestionsShown) {
+ hideSuggestions();
+ return true;
+ }
+ if (isInSelectionMode) {
+ stopSelectionActionMode();
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return super.onKeyPreIme(keyCode, event);
+ }
+
+ @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
int which = doKeyDown(keyCode, event, null);
if (which == 0) {
@@ -5241,6 +5271,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Has to be done on key down (and not on key up) to correctly be intercepted.
case KeyEvent.KEYCODE_BACK:
+ if (areSuggestionsShown()) {
+ hideSuggestions();
+ return -1;
+ }
if (mSelectionActionMode != null) {
stopSelectionActionMode();
return -1;
@@ -7617,7 +7651,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Because of View recycling in ListView, there is no easy way to know when a TextView with
// selection becomes visible again. Until a better solution is found, stop text selection
// mode (if any) as soon as this TextView is recycled.
- stopSelectionActionMode();
+ hideControllers();
}
@Override
@@ -7889,8 +7923,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (!selectAllGotFocus && hasSelection()) {
startSelectionActionMode();
} else {
- stopSelectionActionMode();
- hideSuggestions();
+ hideControllers();
if (hasInsertionController() && !selectAllGotFocus && mText.length() > 0) {
getInsertionController().show();
}
@@ -8748,9 +8781,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private static final int MAX_NUMBER_SUGGESTIONS = 5;
private static final int NO_SUGGESTIONS = -1;
private final PopupWindow mContainer;
- private final ViewGroup[] mSuggestionViews = new ViewGroup[2];
- private final int[] mSuggestionViewLayouts = new int[] {
- mTextEditSuggestionsBottomWindowLayout, mTextEditSuggestionsTopWindowLayout};
+ private ViewGroup mSuggestionViewGroup;
private WordIterator mSuggestionWordIterator;
private TextAppearanceSpan[] mHighlightSpans = new TextAppearanceSpan[0];
@@ -8772,12 +8803,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
int suggestionIndex; // the index of the suggestion inside suggestionSpan
}
- private ViewGroup getViewGroup(boolean under) {
- final int viewIndex = under ? 0 : 1;
- ViewGroup viewGroup = mSuggestionViews[viewIndex];
-
- if (viewGroup == null) {
- final int layout = mSuggestionViewLayouts[viewIndex];
+ private void initSuggestionViewGroup() {
+ if (mSuggestionViewGroup == null) {
LayoutInflater inflater = (LayoutInflater) TextView.this.mContext.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -8786,19 +8813,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
"Unable to create TextEdit suggestion window inflater");
}
- View view = inflater.inflate(layout, null);
+ View view = inflater.inflate(mTextEditSuggestionsWindowLayout, null);
if (! (view instanceof ViewGroup)) {
throw new IllegalArgumentException(
"Inflated TextEdit suggestion window is not a ViewGroup: " + view);
}
- viewGroup = (ViewGroup) view;
+ mSuggestionViewGroup = (ViewGroup) view;
// Inflate the suggestion items once and for all.
for (int i = 0; i < MAX_NUMBER_SUGGESTIONS; i++) {
- View childView = inflater.inflate(mTextEditSuggestionItemLayout, viewGroup,
- false);
+ View childView = inflater.inflate(mTextEditSuggestionItemLayout,
+ mSuggestionViewGroup, false);
if (! (childView instanceof TextView)) {
throw new IllegalArgumentException(
@@ -8806,14 +8833,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
childView.setTag(new SuggestionInfo());
- viewGroup.addView(childView);
+ mSuggestionViewGroup.addView(childView);
childView.setOnClickListener(this);
}
- mSuggestionViews[viewIndex] = viewGroup;
+ mContainer.setContentView(mSuggestionViewGroup);
}
-
- return viewGroup;
}
public void show() {
@@ -8824,8 +8849,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
SuggestionSpan[] suggestionSpans = spannable.getSpans(pos, pos, SuggestionSpan.class);
final int nbSpans = suggestionSpans.length;
- ViewGroup viewGroup = getViewGroup(true);
- mContainer.setContentView(viewGroup);
+ initSuggestionViewGroup();
int totalNbSuggestions = 0;
int spanUnionStart = mText.length();
@@ -8841,7 +8865,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
String[] suggestions = suggestionSpan.getSuggestions();
int nbSuggestions = suggestions.length;
for (int suggestionIndex = 0; suggestionIndex < nbSuggestions; suggestionIndex++) {
- TextView textView = (TextView) viewGroup.getChildAt(totalNbSuggestions);
+ TextView textView = (TextView) mSuggestionViewGroup.getChildAt(
+ totalNbSuggestions);
textView.setText(suggestions[suggestionIndex]);
SuggestionInfo suggestionInfo = (SuggestionInfo) textView.getTag();
suggestionInfo.spanStart = spanStart;
@@ -8860,7 +8885,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (totalNbSuggestions == 0) {
// TODO Replace by final text, use a dedicated layout, add a fade out timer...
- TextView textView = (TextView) viewGroup.getChildAt(0);
+ TextView textView = (TextView) mSuggestionViewGroup.getChildAt(0);
textView.setText("No suggestions available");
SuggestionInfo suggestionInfo = (SuggestionInfo) textView.getTag();
suggestionInfo.spanStart = NO_SUGGESTIONS;
@@ -8871,17 +8896,24 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
for (int i = 0; i < totalNbSuggestions; i++) {
- final TextView textView = (TextView) viewGroup.getChildAt(i);
+ final TextView textView = (TextView) mSuggestionViewGroup.getChildAt(i);
highlightTextDifferences(textView, spanUnionStart, spanUnionEnd);
}
}
- for (int i = 0; i < MAX_NUMBER_SUGGESTIONS; i++) {
- viewGroup.getChildAt(i).setVisibility(i < totalNbSuggestions ? VISIBLE : GONE);
+ for (int i = 0; i < totalNbSuggestions; i++) {
+ mSuggestionViewGroup.getChildAt(i).setVisibility(VISIBLE);
+ }
+ for (int i = totalNbSuggestions; i < MAX_NUMBER_SUGGESTIONS; i++) {
+ mSuggestionViewGroup.getChildAt(i).setVisibility(GONE);
}
- final int size = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
- viewGroup.measure(size, size);
+ final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+ final int screenWidth = displayMetrics.widthPixels;
+ final int screenHeight = displayMetrics.heightPixels;
+ mSuggestionViewGroup.measure(
+ View.MeasureSpec.makeMeasureSpec(screenWidth, View.MeasureSpec.AT_MOST),
+ View.MeasureSpec.makeMeasureSpec(screenHeight, View.MeasureSpec.AT_MOST));
positionAtCursor();
}
@@ -9042,6 +9074,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mContainer.dismiss();
}
+ public boolean isShowing() {
+ return mContainer.isShowing();
+ }
+
@Override
public void onClick(View view) {
if (view instanceof TextView) {
@@ -9130,23 +9166,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Vertical clipping
if (coords[1] + height > screenHeight) {
- // Try to position above current line instead
- // TODO use top layout instead, reverse suggestion order,
- // try full screen vertical down if it still does not fit. TBD with designers.
-
- // Update dimensions from new view
- contentView = mContainer.getContentView();
- width = contentView.getMeasuredWidth();
- height = contentView.getMeasuredHeight();
-
- final int lineTop = mLayout.getLineTop(line);
- final int lineHeight = lineBottom - lineTop;
- coords[1] -= height + lineHeight;
+ coords[1] = screenHeight - height;
}
// Horizontal clipping
- coords[0] = Math.max(0, coords[0]);
coords[0] = Math.min(displayMetrics.widthPixels - width, coords[0]);
+ coords[0] = Math.max(0, coords[0]);
mContainer.showAtLocation(TextView.this, Gravity.NO_GRAVITY, coords[0], coords[1]);
}
@@ -9168,6 +9193,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
+ boolean areSuggestionsShown() {
+ return mSuggestionsPopupWindow != null && mSuggestionsPopupWindow.isShowing();
+ }
+
/**
* Some parts of the text can have alternate suggestion text attached. This is typically done by
* the IME by adding {@link SuggestionSpan}s to the text.
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 8d6caa17d752..2061c905ebb0 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -438,7 +438,7 @@ public class AlertController {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
- topPanel.addView(mCustomTitleView, lp);
+ topPanel.addView(mCustomTitleView, 0, lp);
// Hide the title template
View titleTemplate = mWindow.findViewById(R.id.title_template);
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index a9e505784930..07430e79d9a1 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -27,7 +27,7 @@ interface IStatusBarService
void expand();
void collapse();
void disable(int what, IBinder token, String pkg);
- void setIcon(String slot, String iconPackage, int iconId, int iconLevel);
+ void setIcon(String slot, String iconPackage, int iconId, int iconLevel, String contentDescription);
void setIconVisibility(String slot, boolean visible);
void removeIcon(String slot);
void topAppWindowChanged(boolean menuVisible);
diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java
index ae2cac2a68f7..3333c822edaa 100644
--- a/core/java/com/android/internal/statusbar/StatusBarIcon.java
+++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java
@@ -19,42 +19,35 @@ package com.android.internal.statusbar;
import android.os.Parcel;
import android.os.Parcelable;
-/**
- * @hide
- */
public class StatusBarIcon implements Parcelable {
public String iconPackage;
public int iconId;
public int iconLevel;
public boolean visible = true;
public int number;
+ public CharSequence contentDescription;
- private StatusBarIcon() {
- }
-
- public StatusBarIcon(String iconPackage, int iconId, int iconLevel) {
- this.iconPackage = iconPackage;
- this.iconId = iconId;
- this.iconLevel = iconLevel;
- }
-
- public StatusBarIcon(String iconPackage, int iconId, int iconLevel, int number) {
+ public StatusBarIcon(String iconPackage, int iconId, int iconLevel, int number,
+ CharSequence contentDescription) {
this.iconPackage = iconPackage;
this.iconId = iconId;
this.iconLevel = iconLevel;
this.number = number;
+ this.contentDescription = contentDescription;
}
+ @Override
public String toString() {
return "StatusBarIcon(pkg=" + this.iconPackage + " id=0x" + Integer.toHexString(this.iconId)
+ " level=" + this.iconLevel + " visible=" + visible
+ " num=" + this.number + " )";
}
+ @Override
public StatusBarIcon clone() {
- StatusBarIcon that = new StatusBarIcon(this.iconPackage, this.iconId, this.iconLevel);
+ StatusBarIcon that = new StatusBarIcon(this.iconPackage, this.iconId, this.iconLevel,
+ this.number, this.contentDescription);
that.visible = this.visible;
- that.number = this.number;
return that;
}
@@ -71,6 +64,7 @@ public class StatusBarIcon implements Parcelable {
this.iconLevel = in.readInt();
this.visible = in.readInt() != 0;
this.number = in.readInt();
+ this.contentDescription = in.readCharSequence();
}
public void writeToParcel(Parcel out, int flags) {
@@ -79,6 +73,7 @@ public class StatusBarIcon implements Parcelable {
out.writeInt(this.iconLevel);
out.writeInt(this.visible ? 1 : 0);
out.writeInt(this.number);
+ out.writeCharSequence(this.contentDescription);
}
public int describeContents() {
diff --git a/core/java/com/android/internal/textservice/ISpellCheckerService.aidl b/core/java/com/android/internal/textservice/ISpellCheckerService.aidl
new file mode 100644
index 000000000000..ff0049276bce
--- /dev/null
+++ b/core/java/com/android/internal/textservice/ISpellCheckerService.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.textservice;
+
+import com.android.internal.textservice.ISpellCheckerSession;
+import com.android.internal.textservice.ISpellCheckerSessionListener;
+
+/**
+ * Public interface to the global spell checker.
+ * @hide
+ */
+interface ISpellCheckerService {
+ ISpellCheckerSession getISpellCheckerSession(
+ String locale, ISpellCheckerSessionListener listener);
+}
diff --git a/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl b/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl
new file mode 100644
index 000000000000..79e43510c00a
--- /dev/null
+++ b/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.textservice;
+
+import android.view.textservice.TextInfo;
+
+/**
+ * @hide
+ */
+oneway interface ISpellCheckerSession {
+ void getSuggestionsMultiple(
+ in TextInfo[] textInfos, int suggestionsLimit, boolean multipleWords);
+ void cancel();
+}
diff --git a/core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl b/core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl
new file mode 100644
index 000000000000..796b06eb06d6
--- /dev/null
+++ b/core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.textservice;
+
+import android.view.textservice.SuggestionsInfo;
+
+/**
+ * @hide
+ */
+oneway interface ISpellCheckerSessionListener {
+ void onGetSuggestions(in SuggestionsInfo[] results);
+}
diff --git a/core/java/com/android/internal/textservice/ITextServicesManager.aidl b/core/java/com/android/internal/textservice/ITextServicesManager.aidl
new file mode 100644
index 000000000000..ad0c1ff3f816
--- /dev/null
+++ b/core/java/com/android/internal/textservice/ITextServicesManager.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.textservice;
+
+import com.android.internal.textservice.ISpellCheckerSessionListener;
+import com.android.internal.textservice.ITextServicesSessionListener;
+
+import android.content.ComponentName;
+import android.view.textservice.SpellCheckerInfo;
+
+/**
+ * Interface to the text service manager.
+ * @hide
+ */
+interface ITextServicesManager {
+ SpellCheckerInfo getCurrentSpellChecker(String locale);
+ oneway void getSpellCheckerService(in SpellCheckerInfo info, in String locale,
+ in ITextServicesSessionListener tsListener,
+ in ISpellCheckerSessionListener scListener);
+ oneway void finishSpellCheckerService(in ISpellCheckerSessionListener listener);
+}
diff --git a/core/java/com/android/internal/textservice/ITextServicesSessionListener.aidl b/core/java/com/android/internal/textservice/ITextServicesSessionListener.aidl
new file mode 100644
index 000000000000..ecb6cd0f85d1
--- /dev/null
+++ b/core/java/com/android/internal/textservice/ITextServicesSessionListener.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.textservice;
+
+import com.android.internal.textservice.ISpellCheckerSession;
+
+import android.view.textservice.SpellCheckerInfo;
+
+/**
+ * Interface to the text service session.
+ * @hide
+ */
+interface ITextServicesSessionListener {
+ oneway void onServiceConnected(in ISpellCheckerSession spellCheckerSession);
+}
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index 164d5811c31e..159b3da440bd 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -50,6 +50,8 @@ public class MenuBuilder implements Menu {
private static final String LOGTAG = "MenuBuilder";
private static final String PRESENTER_KEY = "android:menu:presenters";
+ private static final String ACTION_VIEW_STATES_KEY = "android:menu:actionviewstates";
+ private static final String EXPANDED_ACTION_VIEW_ID = "android:menu:expandedactionview";
private static final int[] sCategoryToOrder = new int[] {
1, /* No category */
@@ -308,6 +310,67 @@ public class MenuBuilder implements Menu {
dispatchRestoreInstanceState(state);
}
+ public void saveActionViewStates(Bundle outStates) {
+ SparseArray<Parcelable> viewStates = null;
+
+ final int itemCount = size();
+ for (int i = 0; i < itemCount; i++) {
+ final MenuItem item = getItem(i);
+ final View v = item.getActionView();
+ if (v != null && v.getId() != View.NO_ID) {
+ if (viewStates == null) {
+ viewStates = new SparseArray<Parcelable>();
+ }
+ v.saveHierarchyState(viewStates);
+ if (item.isActionViewExpanded()) {
+ outStates.putInt(EXPANDED_ACTION_VIEW_ID, item.getItemId());
+ }
+ }
+ if (item.hasSubMenu()) {
+ final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu();
+ subMenu.saveActionViewStates(outStates);
+ }
+ }
+
+ if (viewStates != null) {
+ outStates.putSparseParcelableArray(getActionViewStatesKey(), viewStates);
+ }
+ }
+
+ public void restoreActionViewStates(Bundle states) {
+ if (states == null) {
+ return;
+ }
+
+ SparseArray<Parcelable> viewStates = states.getSparseParcelableArray(
+ getActionViewStatesKey());
+
+ final int itemCount = size();
+ for (int i = 0; i < itemCount; i++) {
+ final MenuItem item = getItem(i);
+ final View v = item.getActionView();
+ if (v != null && v.getId() != View.NO_ID) {
+ v.restoreHierarchyState(viewStates);
+ }
+ if (item.hasSubMenu()) {
+ final SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu();
+ subMenu.restoreActionViewStates(states);
+ }
+ }
+
+ final int expandedId = states.getInt(EXPANDED_ACTION_VIEW_ID);
+ if (expandedId > 0) {
+ MenuItem itemToExpand = findItem(expandedId);
+ if (itemToExpand != null) {
+ itemToExpand.expandActionView();
+ }
+ }
+ }
+
+ protected String getActionViewStatesKey() {
+ return ACTION_VIEW_STATES_KEY;
+ }
+
public void setCallback(Callback cb) {
mCallback = cb;
}
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index 541d10120dd6..b0a002d2ce8d 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -553,6 +553,9 @@ public final class MenuItemImpl implements MenuItem {
public MenuItem setActionView(View view) {
mActionView = view;
mActionProvider = null;
+ if (view != null && view.getId() == View.NO_ID && mId > 0) {
+ view.setId(mId);
+ }
mMenu.onItemActionRequestChanged(this);
return this;
}
diff --git a/core/java/com/android/internal/view/menu/SubMenuBuilder.java b/core/java/com/android/internal/view/menu/SubMenuBuilder.java
index fb1cd5e81ef7..92acf8cda8f5 100644
--- a/core/java/com/android/internal/view/menu/SubMenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/SubMenuBuilder.java
@@ -121,4 +121,13 @@ public class SubMenuBuilder extends MenuBuilder implements SubMenu {
public boolean collapseItemActionView(MenuItemImpl item) {
return mParentMenu.collapseItemActionView(item);
}
+
+ @Override
+ public String getActionViewStatesKey() {
+ final int itemId = mItem != null ? mItem.getItemId() : 0;
+ if (itemId == 0) {
+ return null;
+ }
+ return super.getActionViewStatesKey() + ":" + itemId;
+ }
}
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index e03858b4af13..09262e01284a 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -42,6 +42,7 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.view.CollapsibleActionView;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -285,8 +286,11 @@ public class ActionBarView extends AbsActionBarView {
public void setSplitActionBar(boolean splitActionBar) {
if (mSplitActionBar != splitActionBar) {
if (mMenuView != null) {
+ final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
+ if (oldParent != null) {
+ oldParent.removeView(mMenuView);
+ }
if (splitActionBar) {
- removeView(mMenuView);
if (mSplitView != null) {
mSplitView.addView(mMenuView);
}
@@ -332,7 +336,10 @@ public class ActionBarView extends AbsActionBarView {
MenuBuilder builder = (MenuBuilder) menu;
mOptionsMenu = builder;
if (mMenuView != null) {
- removeView(mMenuView);
+ final ViewGroup oldParent = (ViewGroup) mMenuView.getParent();
+ if (oldParent != null) {
+ oldParent.removeView(mMenuView);
+ }
}
if (mActionMenuPresenter == null) {
mActionMenuPresenter = new ActionMenuPresenter();
@@ -351,6 +358,10 @@ public class ActionBarView extends AbsActionBarView {
builder.addMenuPresenter(mActionMenuPresenter);
builder.addMenuPresenter(mExpandedMenuPresenter);
menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
+ final ViewGroup oldParent = (ViewGroup) menuView.getParent();
+ if (oldParent != null && oldParent != this) {
+ oldParent.removeView(menuView);
+ }
addView(menuView, layoutParams);
} else {
mActionMenuPresenter.setExpandedActionViewsExclusive(false);
@@ -365,6 +376,10 @@ public class ActionBarView extends AbsActionBarView {
builder.addMenuPresenter(mExpandedMenuPresenter);
menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
if (mSplitView != null) {
+ final ViewGroup oldParent = (ViewGroup) menuView.getParent();
+ if (oldParent != null && oldParent != mSplitView) {
+ oldParent.removeView(menuView);
+ }
mSplitView.addView(menuView, layoutParams);
} else {
// We'll add this later if we missed it this time.
@@ -1304,6 +1319,10 @@ public class ActionBarView extends AbsActionBarView {
if (mCustomNavView != null) mCustomNavView.setVisibility(GONE);
requestLayout();
item.setActionViewExpanded(true);
+
+ if (mExpandedActionView instanceof CollapsibleActionView) {
+ ((CollapsibleActionView) mExpandedActionView).onActionViewExpanded();
+ }
return true;
}
@@ -1330,11 +1349,16 @@ public class ActionBarView extends AbsActionBarView {
if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
mCustomNavView.setVisibility(VISIBLE);
}
+ View collapsedView = mExpandedActionView;
mExpandedActionView = null;
mExpandedHomeLayout.setIcon(null);
mCurrentExpandedItem = null;
requestLayout();
item.setActionViewExpanded(false);
+
+ if (collapsedView instanceof CollapsibleActionView) {
+ ((CollapsibleActionView) collapsedView).onActionViewCollapsed();
+ }
return true;
}
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 50d9ca1d9e5d..9be3779f0d8f 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -127,7 +127,7 @@ static void recorderCallback(int event, void* user, void *info) {
static int
android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
jint source, jint sampleRateInHertz, jint channels,
- jint audioFormat, jint buffSizeInBytes)
+ jint audioFormat, jint buffSizeInBytes, jintArray jSession)
{
//LOGV(">> Entering android_media_AudioRecord_setup");
//LOGV("sampleRate=%d, audioFormat=%d, channels=%x, buffSizeInBytes=%d",
@@ -162,6 +162,20 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
return AUDIORECORD_ERROR_SETUP_INVALIDSOURCE;
}
+ if (jSession == NULL) {
+ LOGE("Error creating AudioRecord: invalid session ID pointer");
+ return AUDIORECORD_ERROR;
+ }
+
+ jint* nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL);
+ if (nSession == NULL) {
+ LOGE("Error creating AudioRecord: Error retrieving session id pointer");
+ return AUDIORECORD_ERROR;
+ }
+ int sessionId = nSession[0];
+ env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
+ nSession = NULL;
+
audiorecord_callback_cookie *lpCallbackData = NULL;
AudioRecord* lpRecorder = NULL;
@@ -193,13 +207,24 @@ android_media_AudioRecord_setup(JNIEnv *env, jobject thiz, jobject weak_this,
recorderCallback,// callback_t
lpCallbackData,// void* user
0, // notificationFrames,
- true); // threadCanCallJava)
+ true, // threadCanCallJava)
+ sessionId);
if(lpRecorder->initCheck() != NO_ERROR) {
LOGE("Error creating AudioRecord instance: initialization check failed.");
goto native_init_failure;
}
+ nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL);
+ if (nSession == NULL) {
+ LOGE("Error creating AudioRecord: Error retrieving session id pointer");
+ goto native_init_failure;
+ }
+ // read the audio session ID back from AudioTrack in case a new session was created during set()
+ nSession[0] = lpRecorder->getSessionId();
+ env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
+ nSession = NULL;
+
// save our newly created C++ AudioRecord in the "nativeRecorderInJavaObj" field
// of the Java object
env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, (int)lpRecorder);
@@ -485,7 +510,7 @@ static JNINativeMethod gMethods[] = {
// name, signature, funcPtr
{"native_start", "()I", (void *)android_media_AudioRecord_start},
{"native_stop", "()V", (void *)android_media_AudioRecord_stop},
- {"native_setup", "(Ljava/lang/Object;IIIII)I",
+ {"native_setup", "(Ljava/lang/Object;IIIII[I)I",
(void *)android_media_AudioRecord_setup},
{"native_finalize", "()V", (void *)android_media_AudioRecord_finalize},
{"native_release", "()V", (void *)android_media_AudioRecord_release},
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index e930c5c37638..0c81634a4a08 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -315,26 +315,56 @@ static jboolean android_net_wifi_stopDriverCommand(JNIEnv* env, jobject)
return doBooleanCommand("OK", "DRIVER STOP");
}
-static jboolean android_net_wifi_startPacketFiltering(JNIEnv* env, jobject)
+/*
+ Multicast filtering rules work as follows:
+
+ The driver can filter multicast (v4 and/or v6) and broadcast packets when in
+ a power optimized mode (typically when screen goes off).
+
+ In order to prevent the driver from filtering the multicast/broadcast packets, we have to
+ add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
+
+ DRIVER RXFILTER-ADD Num
+ where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
+
+ and DRIVER RXFILTER-START
+
+ In order to stop the usage of these rules, we do
+
+ DRIVER RXFILTER-STOP
+ DRIVER RXFILTER-REMOVE Num
+ where Num is as described for RXFILTER-ADD
+
+ The SETSUSPENDOPT driver command overrides the filtering rules
+*/
+
+static jboolean android_net_wifi_startMultiV4Filtering(JNIEnv* env, jobject)
{
- return doBooleanCommand("OK", "DRIVER RXFILTER-ADD 0")
- && doBooleanCommand("OK", "DRIVER RXFILTER-ADD 1")
- && doBooleanCommand("OK", "DRIVER RXFILTER-ADD 3")
+ return doBooleanCommand("OK", "DRIVER RXFILTER-STOP")
+ && doBooleanCommand("OK", "DRIVER RXFILTER-REMOVE 2")
&& doBooleanCommand("OK", "DRIVER RXFILTER-START");
}
-static jboolean android_net_wifi_stopPacketFiltering(JNIEnv* env, jobject)
+static jboolean android_net_wifi_stopMultiV4Filtering(JNIEnv* env, jobject)
{
- jboolean result = doBooleanCommand("OK", "DRIVER RXFILTER-STOP");
- if (result) {
- (void)doBooleanCommand("OK", "DRIVER RXFILTER-REMOVE 3");
- (void)doBooleanCommand("OK", "DRIVER RXFILTER-REMOVE 1");
- (void)doBooleanCommand("OK", "DRIVER RXFILTER-REMOVE 0");
- }
+ return doBooleanCommand("OK", "DRIVER RXFILTER-ADD 2")
+ && doBooleanCommand("OK", "DRIVER RXFILTER-START");
+}
- return result;
+static jboolean android_net_wifi_startMultiV6Filtering(JNIEnv* env, jobject)
+{
+ return doBooleanCommand("OK", "DRIVER RXFILTER-STOP")
+ && doBooleanCommand("OK", "DRIVER RXFILTER-REMOVE 3")
+ && doBooleanCommand("OK", "DRIVER RXFILTER-START");
}
+static jboolean android_net_wifi_stopMultiV6Filtering(JNIEnv* env, jobject)
+{
+ return doBooleanCommand("OK", "DRIVER RXFILTER-ADD 3")
+ && doBooleanCommand("OK", "DRIVER RXFILTER-START");
+}
+
+
static jint android_net_wifi_getRssiHelper(const char *cmd)
{
char reply[BUF_SIZE];
@@ -545,8 +575,10 @@ static JNINativeMethod gWifiMethods[] = {
{ "setScanModeCommand", "(Z)Z", (void*) android_net_wifi_setScanModeCommand },
{ "startDriverCommand", "()Z", (void*) android_net_wifi_startDriverCommand },
{ "stopDriverCommand", "()Z", (void*) android_net_wifi_stopDriverCommand },
- { "startPacketFiltering", "()Z", (void*) android_net_wifi_startPacketFiltering },
- { "stopPacketFiltering", "()Z", (void*) android_net_wifi_stopPacketFiltering },
+ { "startFilteringMulticastV4Packets", "()Z", (void*) android_net_wifi_startMultiV4Filtering},
+ { "stopFilteringMulticastV4Packets", "()Z", (void*) android_net_wifi_stopMultiV4Filtering},
+ { "startFilteringMulticastV6Packets", "()Z", (void*) android_net_wifi_startMultiV6Filtering},
+ { "stopFilteringMulticastV6Packets", "()Z", (void*) android_net_wifi_stopMultiV6Filtering},
{ "setPowerModeCommand", "(I)Z", (void*) android_net_wifi_setPowerModeCommand },
{ "getPowerModeCommand", "()I", (void*) android_net_wifi_getPowerModeCommand },
{ "setBandCommand", "(I)Z", (void*) android_net_wifi_setBandCommand},
diff --git a/core/jni/android_os_SystemClock.cpp b/core/jni/android_os_SystemClock.cpp
index ffd0c1e6645c..66d58cd4a470 100644
--- a/core/jni/android_os_SystemClock.cpp
+++ b/core/jni/android_os_SystemClock.cpp
@@ -80,6 +80,38 @@ static jlong android_os_SystemClock_currentThreadTimeMillis(JNIEnv* env,
}
/*
+ * native public static long currentThreadTimeMicro();
+ */
+static jlong android_os_SystemClock_currentThreadTimeMicro(JNIEnv* env,
+ jobject clazz)
+{
+#if defined(HAVE_POSIX_CLOCKS)
+ struct timespec tm;
+
+ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tm);
+
+ return tm.tv_sec * 1000000LL + tm.tv_nsec / 1000;
+#else
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ return tv.tv_sec * 1000000LL + tv.tv_nsec / 1000;
+#endif
+}
+
+/*
+ * native public static long currentTimeMicro();
+ */
+static jlong android_os_SystemClock_currentTimeMicro(JNIEnv* env,
+ jobject clazz)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ return tv.tv_sec * 1000000LL + tv.tv_usec;
+}
+
+/*
* JNI registration.
*/
static JNINativeMethod gMethods[] = {
@@ -92,6 +124,10 @@ static JNINativeMethod gMethods[] = {
(void*) android_os_SystemClock_elapsedRealtime },
{ "currentThreadTimeMillis", "()J",
(void*) android_os_SystemClock_currentThreadTimeMillis },
+ { "currentThreadTimeMicro", "()J",
+ (void*) android_os_SystemClock_currentThreadTimeMicro },
+ { "currentTimeMicro", "()J",
+ (void*) android_os_SystemClock_currentTimeMicro },
};
int register_android_os_SystemClock(JNIEnv* env)
{
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index b0c2f2c2da07..b06de9d1b91e 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -576,18 +576,18 @@ static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz,
// ----------------------------------------------------------------------------
static DisplayList* android_view_GLES20Canvas_getDisplayList(JNIEnv* env,
- jobject clazz, DisplayListRenderer* renderer) {
- return renderer->getDisplayList();
+ jobject clazz, DisplayListRenderer* renderer, DisplayList* displayList) {
+ return renderer->getDisplayList(displayList);
+}
+
+static OpenGLRenderer* android_view_GLES20Canvas_createDisplayListRenderer(JNIEnv* env,
+ jobject clazz) {
+ return new DisplayListRenderer;
}
-static OpenGLRenderer* android_view_GLES20Canvas_getDisplayListRenderer(JNIEnv* env,
+static void android_view_GLES20Canvas_resetDisplayListRenderer(JNIEnv* env,
jobject clazz, DisplayListRenderer* renderer) {
- if (renderer == NULL) {
- renderer = new DisplayListRenderer;
- } else {
- renderer->reset();
- }
- return renderer;
+ renderer->reset();
}
static void android_view_GLES20Canvas_destroyDisplayList(JNIEnv* env,
@@ -812,9 +812,10 @@ static JNINativeMethod gMethods[] = {
{ "nGetClipBounds", "(ILandroid/graphics/Rect;)Z",
(void*) android_view_GLES20Canvas_getClipBounds },
- { "nGetDisplayList", "(I)I", (void*) android_view_GLES20Canvas_getDisplayList },
+ { "nGetDisplayList", "(II)I", (void*) android_view_GLES20Canvas_getDisplayList },
{ "nDestroyDisplayList", "(I)V", (void*) android_view_GLES20Canvas_destroyDisplayList },
- { "nGetDisplayListRenderer", "(I)I", (void*) android_view_GLES20Canvas_getDisplayListRenderer },
+ { "nCreateDisplayListRenderer", "()I", (void*) android_view_GLES20Canvas_createDisplayListRenderer },
+ { "nResetDisplayListRenderer", "(I)V", (void*) android_view_GLES20Canvas_resetDisplayListRenderer },
{ "nDrawDisplayList", "(IIIILandroid/graphics/Rect;)Z",
(void*) android_view_GLES20Canvas_drawDisplayList },
{ "nOutputDisplayList", "(II)V", (void*) android_view_GLES20Canvas_outputDisplayList },
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 103a32691735..91003d181b9c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1120,6 +1120,13 @@
android:description="@string/permdesc_bindInputMethod"
android:protectionLevel="signature" />
+ <!-- Must be required by a TextService (e.g. SpellCheckerService)
+ to ensure that only the system can bind to it. -->
+ <permission android:name="android.permission.BIND_TEXT_SERVICE"
+ android:label="@string/permlab_bindTextService"
+ android:description="@string/permdesc_bindTextService"
+ android:protectionLevel="signature" />
+
<!-- Must be required by a {@link android.service.wallpaper.WallpaperService},
to ensure that only the system can bind to it. -->
<permission android:name="android.permission.BIND_WALLPAPER"
@@ -1197,7 +1204,7 @@
<permission android:name="android.permission.READ_FRAME_BUFFER"
android:label="@string/permlab_readFrameBuffer"
android:description="@string/permdesc_readFrameBuffer"
- android:protectionLevel="signature" />
+ android:protectionLevel="signatureOrSystem" />
<!-- Required to be able to disable the device (very dangerous!). -->
<permission android:name="android.permission.BRICK"
diff --git a/core/res/res/anim/screen_rotate_minus_90_enter.xml b/core/res/res/anim/screen_rotate_minus_90_enter.xml
index 30518e02784b..61aa72a3b307 100644
--- a/core/res/res/anim/screen_rotate_minus_90_enter.xml
+++ b/core/res/res/anim/screen_rotate_minus_90_enter.xml
@@ -19,11 +19,6 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
- <scale android:fromXScale="100%p" android:toXScale="100%"
- android:fromYScale="100%p" android:toYScale="100%"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:duration="@android:integer/config_mediumAnimTime" />
<rotate android:fromDegrees="-90" android:toDegrees="0"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@interpolator/decelerate_quint"
diff --git a/core/res/res/anim/screen_rotate_plus_90_enter.xml b/core/res/res/anim/screen_rotate_plus_90_enter.xml
index 20943c853578..53b0ccd43f05 100644
--- a/core/res/res/anim/screen_rotate_plus_90_enter.xml
+++ b/core/res/res/anim/screen_rotate_plus_90_enter.xml
@@ -19,11 +19,6 @@
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
- <scale android:fromXScale="100%p" android:toXScale="100%"
- android:fromYScale="100%p" android:toYScale="100%"
- android:pivotX="50%" android:pivotY="50%"
- android:interpolator="@interpolator/decelerate_quint"
- android:duration="@android:integer/config_mediumAnimTime" />
<rotate android:fromDegrees="90" android:toDegrees="0"
android:pivotX="50%" android:pivotY="50%"
android:interpolator="@interpolator/decelerate_quint"
diff --git a/core/res/res/drawable-hdpi/text_edit_suggestions_top_window.9.png b/core/res/res/drawable-hdpi/text_edit_suggestions_top_window.9.png
deleted file mode 100644
index ff6b34a7ace4..000000000000
--- a/core/res/res/drawable-hdpi/text_edit_suggestions_top_window.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_edit_suggestions_bottom_window.9.png b/core/res/res/drawable-hdpi/text_edit_suggestions_window.9.png
index c97514f3ca99..c97514f3ca99 100644
--- a/core/res/res/drawable-hdpi/text_edit_suggestions_bottom_window.9.png
+++ b/core/res/res/drawable-hdpi/text_edit_suggestions_window.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_edit_suggestions_top_window.9.png b/core/res/res/drawable-mdpi/text_edit_suggestions_top_window.9.png
deleted file mode 100644
index 41886eb378a5..000000000000
--- a/core/res/res/drawable-mdpi/text_edit_suggestions_top_window.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_edit_suggestions_bottom_window.9.png b/core/res/res/drawable-mdpi/text_edit_suggestions_window.9.png
index 88be6e1f96f4..88be6e1f96f4 100644
--- a/core/res/res/drawable-mdpi/text_edit_suggestions_bottom_window.9.png
+++ b/core/res/res/drawable-mdpi/text_edit_suggestions_window.9.png
Binary files differ
diff --git a/core/res/res/layout/text_edit_suggestion_item.xml b/core/res/res/layout/text_edit_suggestion_item.xml
index ef537d9efa93..082c5ec031c0 100644
--- a/core/res/res/layout/text_edit_suggestion_item.xml
+++ b/core/res/res/layout/text_edit_suggestion_item.xml
@@ -22,6 +22,8 @@
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:layout_gravity="left|center_vertical"
+ android:singleLine="true"
+ android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@android:color/dim_foreground_light" />
diff --git a/core/res/res/layout/text_edit_suggestions_bottom_window.xml b/core/res/res/layout/text_edit_suggestions_bottom_window.xml
deleted file mode 100644
index 588bfbd9a321..000000000000
--- a/core/res/res/layout/text_edit_suggestions_bottom_window.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:background="@android:drawable/text_edit_suggestions_bottom_window">
-
-</LinearLayout>
diff --git a/core/res/res/layout/text_edit_suggestions_top_window.xml b/core/res/res/layout/text_edit_suggestions_window.xml
index 67faa37c32d5..824025e606f4 100644
--- a/core/res/res/layout/text_edit_suggestions_top_window.xml
+++ b/core/res/res/layout/text_edit_suggestions_window.xml
@@ -18,6 +18,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:background="@android:drawable/text_edit_suggestions_top_window">
+ android:background="@android:drawable/text_edit_suggestions_window">
</LinearLayout>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 082284a5f337..7d7aea920012 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -713,10 +713,7 @@
<!-- Layout of a the view that is used to create the text suggestions popup window in an
EditText. This window will be displayed below the text line. -->
- <attr name="textEditSuggestionsBottomWindowLayout" format="reference" />
- <!-- Same as textEditSuggestionsBottomWindowLayout, but used when the popup is displayed
- above the current line of text instead of below. -->
- <attr name="textEditSuggestionsTopWindowLayout" format="reference" />
+ <attr name="textEditSuggestionsWindowLayout" format="reference" />
<!-- Layout of the TextView item that will populate the suggestion popup window. -->
<attr name="textEditSuggestionItemLayout" format="reference" />
@@ -3082,10 +3079,7 @@
<!-- Layout of a the view that is used to create the text suggestions popup window in an
EditText. This window will be displayed below the text line. -->
- <attr name="textEditSuggestionsBottomWindowLayout" />
- <!-- Same as textEditSuggestionsBottomWindowLayout, but used when the popup is displayed
- above the current line of text instead of below. -->
- <attr name="textEditSuggestionsTopWindowLayout" />
+ <attr name="textEditSuggestionsWindowLayout" />
<!-- Layout of the TextView item that will populate the suggestion popup window. -->
<attr name="textEditSuggestionItemLayout" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 75f0c4e78f1d..b2b7025b398d 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1715,8 +1715,7 @@
<public type="attr" name="switchPreferenceStyle" />
<public type="attr" name="textSuggestionsWindowStyle" />
- <public type="attr" name="textEditSuggestionsBottomWindowLayout" />
- <public type="attr" name="textEditSuggestionsTopWindowLayout" />
+ <public type="attr" name="textEditSuggestionsWindowLayout" />
<public type="attr" name="textEditSuggestionItemLayout" />
<public type="attr" name="suggestionsEnabled" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 419734aebcc1..feac38d6d695 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -705,6 +705,12 @@
interface of an input method. Should never be needed for normal applications.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_bindTextService">bind to a text service</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_bindTextService">Allows the holder to bind to the top-level
+ interface of a text service(e.g. SpellCheckerService). Should never be needed for normal applications.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_bindWallpaper">bind to a wallpaper</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_bindWallpaper">Allows the holder to bind to the top-level
@@ -2568,6 +2574,12 @@
<item quantity="one">Open Wi-Fi network available</item>
<item quantity="other">Open Wi-Fi networks available</item>
</plurals>
+
+ <!-- A notification is shown the first time a wireless network is disabled due to bad connectivity. This is the notification's title / ticker. -->
+ <string name="wifi_watchdog_network_disabled">A Wi-Fi network was disabled</string>
+ <!-- A notification is shown the first time a wireless network is disabled due to bad connectivity. This is the notification's message which leads to the settings pane -->
+ <string name="wifi_watchdog_network_disabled_detailed">A Wi-Fi network was temporarily disabled due to bad connectivity.</string>
+
<!-- Do not translate. Default access point SSID used for tethering -->
<string name="wifi_tether_configure_ssid_default" translatable="false">AndroidAP</string>
@@ -2669,12 +2681,14 @@
<!-- USB_STORAGE_ERROR dialog ok button-->
<string name="dlg_ok">OK</string>
- <!-- USB_PREFERENCES: Notification for wehen the user connects the phone to a computer via USB in MTP mode. This is the title -->
+ <!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in MTP mode. This is the title -->
<string name="usb_mtp_notification_title">Connected as a media device</string>
- <!-- USB_PREFERENCES: Notification for wehen the user connects the phone to a computer via USB in PTP mode. This is the title -->
+ <!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in PTP mode. This is the title -->
<string name="usb_ptp_notification_title">Connected as a camera</string>
- <!-- USB_PREFERENCES: Notification for wehen the user connects the phone to a computer via USB in mass storage mode (for installer CD image). This is the title -->
+ <!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in mass storage mode (for installer CD image). This is the title -->
<string name="usb_cd_installer_notification_title">Connected as an installer</string>
+ <!-- USB_PREFERENCES: Notification for when a USB accessory is attached. This is the title -->
+ <string name="usb_accessory_notification_title">Connected to a USB accessory</string>
<!-- See USB_PREFERENCES. This is the message. -->
<string name="usb_notification_message">Touch for other USB options</string>
@@ -3050,4 +3064,9 @@
<!-- Title for a dialog showing possible activities for sharing in ShareActionProvider [CHAR LIMIT=25] -->
<string name="share_action_provider_share_with">Share with...</string>
+ <!-- Status Bar icon descriptions -->
+
+ <!-- Description of for the status bar's icon that the device is locked for accessibility. [CHAR LIMIT=NONE] -->
+ <string name="status_bar_device_locked">Device locked.</string>
+
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index d647467a59fc..9b6c4424e7f0 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -423,8 +423,7 @@
<item name="android:textEditNoPasteWindowLayout">?android:attr/textEditNoPasteWindowLayout</item>
<item name="android:textEditSidePasteWindowLayout">?android:attr/textEditSidePasteWindowLayout</item>
<item name="android:textEditSideNoPasteWindowLayout">?android:attr/textEditSideNoPasteWindowLayout</item>
- <item name="android:textEditSuggestionsBottomWindowLayout">?android:attr/textEditSuggestionsBottomWindowLayout</item>
- <item name="android:textEditSuggestionsTopWindowLayout">?android:attr/textEditSuggestionsTopWindowLayout</item>
+ <item name="android:textEditSuggestionsWindowLayout">?android:attr/textEditSuggestionsWindowLayout</item>
<item name="android:textEditSuggestionItemLayout">?android:attr/textEditSuggestionItemLayout</item>
<item name="android:textCursorDrawable">?android:attr/textCursorDrawable</item>
</style>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 90f3602073c0..93ccfe30412a 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -190,8 +190,7 @@
<item name="textEditSidePasteWindowLayout">@android:layout/text_edit_side_paste_window</item>
<item name="textEditSideNoPasteWindowLayout">@android:layout/text_edit_side_no_paste_window</item>
<item name="textSuggestionsWindowStyle">@android:style/Widget.TextSuggestions</item>
- <item name="textEditSuggestionsBottomWindowLayout">@android:layout/text_edit_suggestions_bottom_window</item>
- <item name="textEditSuggestionsTopWindowLayout">@android:layout/text_edit_suggestions_top_window</item>
+ <item name="textEditSuggestionsWindowLayout">@android:layout/text_edit_suggestions_window</item>
<item name="textEditSuggestionItemLayout">@android:layout/text_edit_suggestion_item</item>
<item name="textCursorDrawable">@null</item>
diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd
index 5c18a83d1df6..7a0e17fff7d1 100644
--- a/docs/html/guide/appendix/api-levels.jd
+++ b/docs/html/guide/appendix/api-levels.jd
@@ -82,20 +82,71 @@ API Level 1 and subsequent releases have incremented the API Level.</p>
Android platform.</p>
<table>
- <tr><th>Platform Version</th><th>API Level</th></tr>
- <tr><td>Android 3.1</td><td>12</td></tr>
- <tr><td>Android 3.0</td><td>11</td></tr>
- <tr><td>Android 2.3.4</td><td rowspan="2">10</td></tr>
- <tr><td>Android 2.3.3</td></tr>
- <tr><td>Android 2.3</td><td>9</td></tr>
- <tr><td>Android 2.2</td><td>8</td></tr>
- <tr><td>Android 2.1</td><td>7</td></tr>
- <tr><td>Android 2.0.1</td><td>6</td></tr>
- <tr><td>Android 2.0</td><td>5</td></tr>
- <tr><td>Android 1.6</td><td>4</td></tr>
- <tr><td>Android 1.5</td><td>3</td></tr>
- <tr><td>Android 1.1</td><td>2</td></tr>
- <tr><td>Android 1.0</td><td>1</td></tr>
+ <tr><th>Platform Version</th><th>API Level</th><th>VERSION_CODE</th><th>Notes</th></tr>
+
+ <tr><td><a href="{@docRoot}sdk/android-3.2.html">Android 3.2</a></td>
+ <td><a href="{@docRoot}sdk/api_diff/13/changes.html" title="Diff Report">13</a></td>
+ <td>{@link android.os.Build.VERSION_CODES#HONEYCOMB_MR2}</td>
+ <td><!-- <a href="{@docRoot}sdk/android-3.2-highlights.html">Platform Highlights</a>--></td></tr>
+
+ <tr><td><a href="{@docRoot}sdk/android-3.1.html">Android 3.1.x</a></td>
+ <td><a href="{@docRoot}sdk/api_diff/12/changes.html" title="Diff Report">12</a></td>
+ <td>{@link android.os.Build.VERSION_CODES#HONEYCOMB_MR1}</td>
+ <td><a href="{@docRoot}sdk/android-3.1-highlights.html">Platform Highlights</a></td></tr>
+
+ <tr><td><a href="{@docRoot}sdk/android-3.0.html">Android 3.0.x</td>
+ <td><a href="{@docRoot}sdk/api_diff/11/changes.html" title="Diff Report">11</a></td>
+ <td>{@link android.os.Build.VERSION_CODES#HONEYCOMB}</td>
+ <td><a href="{@docRoot}sdk/android-3.0-highlights.html">Platform Highlights</a></td></tr>
+
+ <tr><td><a href="{@docRoot}sdk/android-2.3.3.html">Android 2.3.4<br>Android 2.3.3</td>
+ <td><a href="{@docRoot}sdk/api_diff/10/changes.html" title="Diff Report">10</a></td>
+ <td>{@link android.os.Build.VERSION_CODES#GINGERBREAD_MR1}</td>
+ <td rowspan="2"><a href="{@docRoot}sdk/android-2.3-highlights.html">Platform Highlights</a></td></tr>
+
+ <tr><td><a href="{@docRoot}sdk/android-2.3.html">Android 2.3.2<br>Android 2.3.1<br>Android 2.3</td>
+ <td><a href="{@docRoot}sdk/api_diff/9/changes.html" title="Diff Report">9</a></td>
+ <td>{@link android.os.Build.VERSION_CODES#GINGERBREAD}</td>
+ </tr>
+
+ <tr><td><a href="{@docRoot}sdk/android-2.2.html">Android 2.2.x</td>
+ <td ><a href="{@docRoot}sdk/api_diff/8/changes.html" title="Diff Report">8</a></td>
+ <td>{@link android.os.Build.VERSION_CODES#FROYO}</td>
+ <td><a href="{@docRoot}sdk/android-2.2-highlights.html">Platform Highlights</a></td></tr>
+
+ <tr><td><a href="{@docRoot}sdk/android-2.1.html">Android 2.1.x</td>
+ <td><a href="{@docRoot}sdk/api_diff/7/changes.html" title="Diff Report">7</a></td>
+ <td>{@link android.os.Build.VERSION_CODES#ECLAIR_MR1}</td>
+ <td rowspan="3" ><a href="{@docRoot}sdk/android-2.0-highlights.html">Platform Highlights</a></td></tr>
+
+ <tr><td><a href="{@docRoot}sdk/android-2.0.1.html">Android 2.0.1</td>
+ <td><a href="{@docRoot}sdk/api_diff/6/changes.html" title="Diff Report">6</a></td>
+ <td>{@link android.os.Build.VERSION_CODES#ECLAIR_0_1}</td>
+ </tr>
+
+ <tr><td><a href="{@docRoot}sdk/android-2.0.html">Android 2.0</td>
+ <td><a href="{@docRoot}sdk/api_diff/5/changes.html" title="Diff Report">5</a></td>
+ <td>{@link android.os.Build.VERSION_CODES#ECLAIR}</td>
+ </tr>
+
+ <tr><td><a href="{@docRoot}sdk/android-1.6.html">Android 1.6</td>
+ <td><a href="{@docRoot}sdk/api_diff/4/changes.html" title="Diff Report">4</a></td>
+ <td>{@link android.os.Build.VERSION_CODES#DONUT}</td>
+ <td><a href="{@docRoot}sdk/android-1.6-highlights.html">Platform Highlights</a></td></tr>
+
+ <tr><td><a href="{@docRoot}sdk/android-1.5.html">Android 1.5</td>
+ <td><a href="{@docRoot}sdk/api_diff/3/changes.html" title="Diff Report">3</a></td>
+ <td>{@link android.os.Build.VERSION_CODES#CUPCAKE}</td>
+ <td><a href="{@docRoot}sdk/android-1.5-highlights.html">Platform Highlights</a></td></tr>
+
+ <tr><td><a href="{@docRoot}sdk/android-1.1.html">Android 1.1</td>
+ <td>2</td>
+ <td>{@link android.os.Build.VERSION_CODES#BASE_1_1}</td><td></td></tr>
+
+ <tr><td><a href="{@docRoot}sdk/android-1.0.html">Android 1.0</td>
+ <td>1</td>
+ <td>{@link android.os.Build.VERSION_CODES#BASE}</td>
+ <td></td></tr>
</table>
diff --git a/docs/html/guide/developing/tools/adb.jd b/docs/html/guide/developing/tools/adb.jd
index 78d12effd8b7..d32cf6684eda 100644
--- a/docs/html/guide/developing/tools/adb.jd
+++ b/docs/html/guide/developing/tools/adb.jd
@@ -280,7 +280,7 @@ instance, see <a href="{@docRoot}guide/developing/building/index.html">Building
<td>Run PPP over USB.
<ul>
<li><code>&lt;tty&gt;</code> &mdash; the tty for PPP stream. For example <code>dev:/dev/omap_csmi_ttyl</code>. </li>
-<li><code>[parm]... </code> &mdash zero or more PPP/PPPD options, such as <code>defaultroute</code>, <code>local</code>, <code>notty</code>, etc.</li></ul>
+<li><code>[parm]... </code> &mdash; zero or more PPP/PPPD options, such as <code>defaultroute</code>, <code>local</code>, <code>notty</code>, etc.</li></ul>
<p>Note that you should not automatically start a PPP connection. </p></td>
<td></td>
diff --git a/docs/html/guide/topics/intents/intents-filters.jd b/docs/html/guide/topics/intents/intents-filters.jd
index 59052143523e..3f9455391a86 100644
--- a/docs/html/guide/topics/intents/intents-filters.jd
+++ b/docs/html/guide/topics/intents/intents-filters.jd
@@ -927,7 +927,7 @@ as described by its two intent filters:
<p>
The first, primary, purpose of this activity is to enable the user to
-interact with a single note &mdash to either {@code VIEW} the note or
+interact with a single note &mdash; to either {@code VIEW} the note or
{@code EDIT} it. (The {@code EDIT_NOTE} category is a synonym for
{@code EDIT}.) The intent would contain the URI for data matching the
MIME type <code>vnd.android.cursor.item/vnd.google.note</code> &mdash;
diff --git a/docs/html/guide/topics/manifest/activity-element.jd b/docs/html/guide/topics/manifest/activity-element.jd
index 34862121ae82..743832c6e763 100644
--- a/docs/html/guide/topics/manifest/activity-element.jd
+++ b/docs/html/guide/topics/manifest/activity-element.jd
@@ -710,7 +710,7 @@ the soft keyboard.</li>
The setting must be one of the values listed in the following table, or a
combination of one "{@code state...}" value plus one "{@code adjust...}"
value. Setting multiple values in either group &mdash; multiple
-"{@code state...}" values, for example &mdash has undefined results.
+"{@code state...}" values, for example &mdash; has undefined results.
Individual values are separated by a vertical bar ({@code |}). For example:
</p>
@@ -801,4 +801,4 @@ Level 3.</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-alias-element.html">&lt;activity-alias&gt;</a></code></dd>
-</dl> \ No newline at end of file
+</dl>
diff --git a/docs/html/guide/topics/providers/content-providers.jd b/docs/html/guide/topics/providers/content-providers.jd
index 2a84c263f652..513886afbe23 100644
--- a/docs/html/guide/topics/providers/content-providers.jd
+++ b/docs/html/guide/topics/providers/content-providers.jd
@@ -277,7 +277,7 @@ are returned. All the content providers that come with the platform define
constants for their columns. For example, the
{@link android.provider.Contacts.Phones android.provider.Contacts.Phones} class
defines constants for the names of the columns in the phone table illustrated
-earlier &mdash {@code _ID}, {@code NUMBER}, {@code NUMBER_KEY}, {@code NAME},
+earlier &mdash; {@code _ID}, {@code NUMBER}, {@code NUMBER_KEY}, {@code NAME},
and so on.</li>
<li><p>A filter detailing which rows to return, formatted as an SQL {@code WHERE}
diff --git a/docs/html/sdk/android-3.1.jd b/docs/html/sdk/android-3.1.jd
index 992b7d16e1c8..161472285cb0 100644
--- a/docs/html/sdk/android-3.1.jd
+++ b/docs/html/sdk/android-3.1.jd
@@ -19,14 +19,14 @@ sdk.platform.apiLevel=12
<h2>Reference</h2>
<ol>
<li><a
-href="{@docRoot}sdk/api_diff/11/changes.html">API
+href="{@docRoot}sdk/api_diff/12/changes.html">API
Differences Report &raquo;</a> </li>
</ol>
<h2>See Also</h2>
<ol>
<li><a href="{@docRoot}guide/practices/optimizing-for-3.0.html">Optimizing
-Apps for Android 3.0</a></li>
+Apps for Android 3.x</a></li>
</ol>
</div>
@@ -765,7 +765,7 @@ was upgraded while it was in started state (not in a stopped state).</p></li>
</ul>
-<h3 if="other">Core utilities</h3>
+<h3 id="other">Core utilities</h3>
<ul>
<li>LRU cache
diff --git a/docs/html/sdk/android-3.2.jd b/docs/html/sdk/android-3.2.jd
new file mode 100644
index 000000000000..5618eaeb0aff
--- /dev/null
+++ b/docs/html/sdk/android-3.2.jd
@@ -0,0 +1,737 @@
+page.title=Android 3.2 Platform
+sdk.platform.version=3.2
+sdk.platform.apiLevel=13
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+<ol>
+ <li><a href="#relnotes">Revisions</a></li>
+ <li><a href="#highlights">Highlights</a></li>
+ <li><a href="#api">API Overview</a></li>
+ <li><a href="#api-level">API Level</a></li>
+ <li><a href="#apps">Built-in Applications</a></li>
+ <li><a href="#locs">Locales</a></li>
+ <li><a href="#skins">Emulator Skins</a></li>
+</ol>
+
+<h2>Reference</h2>
+<ol>
+<li><a
+href="{@docRoot}sdk/api_diff/13/changes.html">API
+Differences Report &raquo;</a> </li>
+</ol>
+
+<h2>See Also</h2>
+<ol>
+ <li><a href="{@docRoot}guide/practices/screens_support.html">Supporting
+ Multiple Screens</a></li>
+ <li><a href="{@docRoot}guide/practices/optimizing-for-3.0.html">Optimizing
+Apps for Android 3.x</a></li>
+</ol>
+
+</div>
+</div>
+
+
+<p><em>API Level:</em>&nbsp;<strong>{@sdkPlatformApiLevel}</strong></p>
+
+<p>Welcome to Android 3.2!</p>
+
+<p>Android 3.2 is an incremental platform release that adds new
+capabilities for users and developers. The sections below provide an overview
+of the new features and developer APIs.</p>
+
+<p>For developers, the Android {@sdkPlatformVersion} platform is available as a
+downloadable component for the Android SDK. The downloadable platform includes
+an Android library and system image, as well as a set of emulator skins and
+more. The downloadable platform includes no external libraries.</p>
+
+<p>To get started developing or testing against Android {@sdkPlatformVersion},
+use the Android SDK Manager to download the platform into your SDK. For more
+information, see <a href="{@docRoot}sdk/adding-components.html">Adding SDK
+Components</a>. If you are new to Android, <a
+href="{@docRoot}sdk/index.html">download the SDK Starter Package</a> first.</p>
+
+<p class="note"><strong>Reminder:</strong> If you've already published an
+Android application, please test and optimize your application on Android 3.2 as
+soon as possible. You should do so to be sure your application provides the best
+experience possible on the latest Android-powered devices. For information about
+what you can do, read <a
+href="{@docRoot}guide/practices/optimizing-for-3.0.html">Optimizing Apps for
+Android 3.x</a>.</p>
+
+
+<h2 id="relnotes">Revisions</h2>
+
+<p>To determine what revision of the Android {@sdkPlatformVersion} platform you
+have installed, refer to the "Installed Packages" listing in the Android SDK and
+AVD Manager.</p>
+
+
+<div class="toggle-content opened" style="padding-left:1em;">
+
+ <p><a href="#" onclick="return toggleContent(this)">
+ <img src="{@docRoot}assets/images/triangle-opened.png"
+class="toggle-content-img" alt="" />
+ Android {@sdkPlatformVersion}, Revision 1</a> <em>(July 2011)</em>
+ </a></p>
+
+ <div class="toggle-content-toggleme" style="padding-left:2em;">
+
+<dl>
+<dt>Initial release. SDK Tools r12 or higher is recommended.</dt>
+</dl>
+
+ </div>
+</div>
+
+<h2 id="highlights" style="margin-top:1.5em;">Platform Highlights</h2>
+
+<h3>New user features</h3>
+
+<ul>
+<li><strong>Optimizations for a wider range of tablets</strong>
+
+<p>Android 3.2 includes a variety of optimizations across the system
+to ensure a great user experience on a wider range of tablet devices.</p></li>
+
+<li><strong>Compatibility zoom for fixed-sized apps</strong>
+
+<p>Android 3.2 introduces a new <em>compatibility zoom</em> mode that gives
+users a new way to view fixed-sized apps on larger devices. The new mode provides a
+pixel-scaled alternative to the standard UI stretching for apps that are not
+designed to run on larger screen sizes, such as on tablets. The new mode is
+accessible to users from a menu icon in the system bar, for apps that need
+compatibility support.</p></li>
+
+<li><strong>Media sync from SD card</strong>
+<p>On devices that support an SD card, users can now load media files directly
+from the SD card to apps that use them. A system facility makes the files
+accessible to apps from the system media store.</p></li>
+</ul>
+
+
+<h3>New developer features</h3>
+
+<ul>
+<li><strong>Extended API for managing screens support</strong>
+
+<p>Android 3.2 introduces extensions to the platform's screen support API to
+give developers additional ways to manage application UI across the range of
+Android-powered devices. The API includes new resource qualifiers and new
+manifest attributes that give you more precise control over how your
+apps are displayed on different sizes, rather than relying on generalized
+size categories.</p>
+
+<p>To ensure the best possible display for fixed-sized apps and apps with limited
+support for various screen sizes, the platform also provides a new zoom
+compatibility mode that renders the UI on a smaller screen area, then scales it
+up to fill the space available on the display. For more information about the
+screen support API and the controls it provides, see the sections below. </p></li>
+</ul>
+
+
+<h2 id="api">API Overview</h2>
+
+<h3 id="usb">Screens Support APIs</h3>
+
+<p>Android 3.2 introduces new screens support APIs that give you more
+control over how their applications are displayed across different screen sizes.
+The API builds on the existing screens-support API, including the platform's
+generalized screen density model, but extends it with the ability to precisely
+target specific screen ranges by their dimensions, measured in
+density-independent pixel units (such as 600dp or 720dp wide), rather than
+by their generalized screen sizes (such as large or xlarge)</p>
+
+<p>When designing an application's UI, you can still rely on the platform to
+provide density abstraction, which means that applications do not need to
+compensate for the differences in actual pixel density across devices. You
+can design the application UI according to the amount of horizontal or vertical
+space available. The platform expresses the amount of space available using three new
+characteristics: <em>smallestWidth</em>, <em>width</em>, and
+<em>height</em>.</p>
+
+<ul>
+<li>A screen's <em>smallestWidth</em> is its fundamental minimum size,
+measured in density-independent pixel ("dp") units. Of the screen's height or
+width, it is the shorter of the two. For a screen in portrait orientation, the
+smallestWidth is normally based on its width, while in landscape orientation it is based
+on its height. In all cases, the smallestWidth is derived from a fixed characteristic of the
+screen and the value does not change, regardless of orientation. The smallestWidth
+is important for applications because it represents the shortest possible width
+in which the application UI will need to be drawn, not including screen areas
+reserved by the system.
+</li>
+
+<li>In constrast, a screen's <em>width</em> and <em>height</em> represent the
+current horizontal or vertical space available for application layout, measured
+in "dp" units, not including screen areas reserved by the system. The width and
+height of a screen change when the user switches orientation between landscape
+and portrait. </li>
+
+</ul>
+
+<p>The new screens support API is designed to let you manage application UI
+according to the smallestWidth of the current screen. You can also manage the
+UI according to current width or height, as needed. For those purposes, the API
+provides these tools:</p>
+
+<ul>
+<li>New resource qualifiers for targeting layouts and other resources to a
+minimum smallestWidth, width, or height, and</li>
+<li>New manifest attributes, for specifying the app's maximum
+screen compatibility range</li>
+</ul>
+
+<p>Additionally, applications can still query the system and manage UI and
+resource loading at runtime, as in the previous versions of the platform.</p>
+
+<p>Since the new API lets you target screens more directly through smallestWidth,
+width, and height, it's helpful to understand the typical
+characteristics of the different screen types. The table below provides some
+examples, measured in "dp" units. </p>
+
+<p class="caption"><strong>Table 1.</strong> Typical devices, with density
+and size in dp.</p>
+
+<table>
+<tr>
+<th>Type</th>
+<th>Density (generalized)</th>
+<th>Dimensions (dp)</th>
+<th>smallestWidth (dp)</th>
+</tr>
+<tr>
+<td>Baseline phone</td>
+<td>mdpi</td>
+<td>320x480</td>
+<td>320</td>
+</td>
+<tr>
+<td>Small tablet/large phone</td>
+<td>mdpi</td>
+<td>480x800</td>
+<td>480</td>
+</tr>
+<tr>
+<td>7-inch tablet</td>
+<td>mdpi</td>
+<td>600x1024</td>
+<td>600</td>
+</tr>
+<tr>
+<td>10-inch tablet</td>
+<td>mdpi</td>
+<td>800x1280</td>
+<td>800</td>
+</tr>
+</table>
+
+<p>The sections below provide more information about the new screen qualifiers
+and manifest attributes. For complete information about how to use the screen
+support API, see <a
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a>.</p>
+
+<h4>New resource qualifiers for screens support</h4>
+
+<p>The new resource qualifiers in Android 3.2 let you better target your layouts
+for ranges of screen sizes. Using the qualifiers, you can create resource
+configurations designed for a specific minimum smallestWidth, current width, or
+current height, measured in density-independent pixels.</p>
+
+<p>The new qualifiers are:</p>
+<ul>
+<li><code>swNNNdp</code> &mdash; Specifies the minimum smallestWidth on which
+the resource should be used, measured in "dp" units. As mentioned above, a
+screen's smallestWidth is constant, regardless of orientation. Examples:
+<code>sw320dp</code>, <code>sw720dp</code>, <code>sw720dp</code>.</li>
+
+<li><code>wNNNdp</code> and <code>hNNNdp</code> &mdash; Specifies the minimum
+width or height on which the resource should be used, measured in "dp" units. As
+mentioned above, a screen's width and height are relative to the orientation of
+the screen and change whenever the orientation changes. Examples:
+<code>w320dp</code>, <code>w720dp</code>, <code>h1024dp</code>.</p></li>
+</ul>
+
+<p>You can also create multiple overlapping resource configurations if needed.
+For example, you could tag some resources for use on any screen wider than 480
+dp, others for wider than 600 dp, and others for wider than 720 dp. When
+multiple resource configurations are qualified for a given screen, the system
+selects the configuration that is the closest match. For precise control over
+which resources are loaded on a given screen, you can tag resources with one
+qualifier or combine several new or existing qualifiers.
+
+<p>Based on the typical dimensions listed earlier, here are some examples of how
+you could use the new qualifiers:</p>
+
+<pre class="classic prettyprint">res/layout/main_activity.xml # For phones
+res/layout-sw600dp/main_activity.xml # For 7” tablets
+res/layout-sw720dp/main_activity.xml # For 10” tablets
+res/layout-w600dp/main_activity.xml # Multi-pane when enough width
+res/layout-sw600dp-w720dp/main_activity.xml # For large width</pre>
+
+<p>Older versions of the platform will ignore the new qualifiers, so you can
+mix them as needed to ensure that your app looks great on any device. Here
+are some examples:</p>
+
+<pre class="classic prettyprint">res/layout/main_activity.xml # For phones
+res/layout-xlarge/main_activity.xml # For pre-3.2 tablets
+res/layout-sw600dp/main_activity.xml # For 3.2 and up tablets</pre>
+
+<p>For complete information about how to use the new qualifiers, see <a href="{@docRoot}guide/practices/screens_support.html#NewQualifiers">Using new
+size qualifiers</a>.</p>
+
+<h4>New manifest attributes for screen-size compatibility</h4>
+
+<p>The framework offers a new set of <a
+href="{@docRoot}"><code>&lt;supports-screens&gt;</code></a> manifest attributes that let
+you manage your app's support for different screen sizess.
+Specifically, you can specify the largest and smallest screens on which your app
+is designed to run, as well as the largest screen on which it is designed run
+without needing the system's new <a href="{@docRoot}guide/practices/screen-compat-mode.html">screen
+compatibility mode</a>. Like the resource qualifiers described above, the new
+manifest attributes specify the range of screens that the application supports,
+as specified by the smallestWidth. </p>
+
+<p>The new manifest attributes for screen support are: </p>
+
+<ul>
+<li><code>android:compatibleWidthLimitDp="<em>numDp"</em></code> &mdash; This
+attribute lets you specify the maximum smallestWidth on which the application
+can run without needing compatibility mode. If the current screen is larger than
+the value specified, the system displays the application in normal mode but
+allows the user to optionally switch to compatibility mode through a setting in
+the system bar.</li>
+
+<li><code>android:largestWidthLimitDp="<em>numDp</em>"</code> &mdash; This
+attribute lets you specify the maximum smallestWidth on which the application
+is designed to run. If the current screen is larger than the value specified,
+the system forces the application into screen compatibility mode, to ensure best
+display on the current screen.</li>
+
+<li><code>android:smallestWidthLimitDp="<em>numDp"</em></code> &mdash; This
+attribute lets you specify the minimum smallestWidth on which the application
+can run. If the current screen is smaller than the value specified, the system
+considers the application incompatible with the device, but does not prevent it
+from being installed and run.</li>
+</ul>
+
+<p class="note"><strong>Note:</strong> Android Market does not currently filter
+apps based on any of the attributes above. Support for filtering will be
+added in a later platform release. Applications that require
+filtering based on screen size can use the existing <code>&lt;supports-screens&gt;</code>
+attributes.</p>
+
+<p>For complete information about how to use the new attributes, see <a href="{@docRoot}guide/practices/screens_support.html#DeclaringScreenSizeSupport">Declaring
+screen size support</a>.</p>
+
+<h4>Screen compatibility mode</h4>
+
+<p>Android 3.2 provides a new screen compatibility mode for applications
+explicitly declaring that they do not support screens as large as the one on
+which they are running. This new "zoom" mode is a pixel-scaled &mdash; it
+renders the application in a smaller screen area and then scales the pixels to
+fill the current screen.</p>
+
+<p>By default, the system offers screen compatibility mode as an user option, for apps
+that require it. Users can turn the zoom mode on and off using a control available
+in the system bar. </p>
+
+<p>Because the new screen compatibility mode may not be appropriate for all
+applications, the platform allows the application to disable it using manifest
+attributes. When disabled by the app, the system does not offer "zoom" compatibility
+mode as an option for users when the app is running.</p>
+
+<p class="note"><strong>Note:</strong> For important information about how
+to control compatibility mode in your applications, please review the <a
+href="http://android-developers.blogspot.com/2011/07/new-mode-for-apps-on-large-
+screens.html">New Mode for Apps on Large Screens</a> article on the Android
+Developers Blog. </p>
+
+<h4>New screen density for 720p televisions and similar devices</h4>
+
+<p>To meet the needs of applications running on 720p televisions or similar with
+moderate density screens, Android 3.2 introduces a new generalized density,
+<code>tvdpi</code>, with an approximate dpi of 213. Applications can query for
+the new density in {@link android.util.DisplayMetrics#densityDpi} and can use
+the new <code>tvdpi</code> qualifier to tag resources for televisions and
+similar devices. For example:</p>
+
+<pre class="classic prettyprint">res/drawable-tvdpi/my_icon.png # Bitmap for tv density</pre>
+
+<p>In general, applications should not need to work with this density. For situations
+where output is needed for a 720p screen, the UI elements can be scaled
+automatically by the platform.</p>
+
+
+<h3 id="ui" style="margin-top:1.25em;">UI framework</h3>
+<ul>
+<li>Fragments
+ <ul>
+ <li>New {@link android.app.Fragment.SavedState} class holds the state
+ information retrieved from a fragment instance through
+ {@link android.app.FragmentManager#saveFragmentInstanceState(android.app.Fragment) saveFragmentInstanceState()}.</li>
+ <li>New method {@link android.app.FragmentManager#saveFragmentInstanceState(android.app.Fragment) saveFragmentInstanceState()}
+ saves the current instance state of
+ the given Fragment. The state can be used later when creating a new instance
+ of the Fragment that matches the current state.</li>
+ <li>New method {@link android.app.Fragment#setInitialSavedState(SavedState) setInitialSavedState()}
+ sets the initial saved state for a Fragment when first constructed.</li>
+ <li>New {@link android.app.Fragment#onViewCreated(android.view.View, android.os.Bundle)
+ onViewCreated()} callback method notifies the Fragment that
+ {@link android.app.Fragment#onCreateView(LayoutInflater, ViewGroup, Bundle) onCreateView()}
+ has returned, but before any saved state has been restored in to the View.</li>
+ <li>{@link android.app.Fragment#isDetached()} method determines whether
+ the Fragment has been explicitly detached from the UI.</li>
+ <li>New {@link android.app.FragmentTransaction#attach(android.app.Fragment) attach()}
+ and {@link android.app.FragmentTransaction#detach(android.app.Fragment) detach()}
+ methods let an application re-attach or detach fragments in the UI.</li>
+ <li>A new {@link android.app.FragmentTransaction#setCustomAnimations(int, int, int, int)
+ setCustomAnimations()} overload method lets you set specific animation
+ resources to run for enter/exit operations and specifically when
+ popping the back stack. The existing implementation does not account
+ for the different behavior of fragments when popping the back stack.</li>
+ </ul>
+</li>
+<li>Screen size information in ActivityInfo and ApplicationInfo
+ <ul>
+ <li>{@link android.content.pm.ActivityInfo} adds {@link android.content.pm.ActivityInfo#CONFIG_SCREEN_SIZE}
+ and {@link android.content.pm.ActivityInfo#CONFIG_SMALLEST_SCREEN_SIZE} as bit masks
+ in {@link android.R.attr#configChanges}. The bits indicate whether an Activity can
+ itself handle the screen size and smallest screen size.</li>
+ <li>{@link android.content.pm.ApplicationInfo} adds
+ {@link android.content.pm.ApplicationInfo#largestWidthLimitDp}, {@link android.content.pm.ApplicationInfo#compatibleWidthLimitDp},
+ and {@link android.content.pm.ApplicationInfo#requiresSmallestWidthDp} fields,
+ derived from the corresponding <code>&lt;supports-screens&gt;</code> attributes
+ in the application manifest file.</li>
+ </ul>
+</li>
+<li>Helpers for getting display size from WindowManager
+ <ul>
+ <li>New methods {@link android.view.Display#getSize(android.graphics.Point)
+ getSize()} and {@link android.view.Display#getRectSize(android.graphics.Rect)
+ getRectSize()} let applications get the raw size of the display.</li>
+ </ul>
+</li>
+<li>New public "holographic" styles
+ <ul>
+ <li>The platform now exposes a variety of public "holographic" styles
+ for text, actionbar widgets and tabs, and more. See
+ {@link android.R.style} for a full list.</li>
+ </ul>
+</li>
+<li>{@link android.app.LocalActivityManager}, {@link android.app.ActivityGroup}, and
+ {@link android.app.LocalActivityManager} are now deprecated
+ <ul>
+ <li>New applications should use Fragments instead of these classes. To
+ continue to run on older versions of the platform, you can use the v4 Support
+ Library (compatibility library), available in the Android SDK. The v4 Support
+ Library provides a version of the Fragment API that is compatible down to
+ Android 1.6 (API level 4).
+ <li>For apps developing against Android 3.0 (API level
+ 11) or higher, tabs are typically presented in the UI using the new
+ {@link android.app.ActionBar#newTab() ActionBar.newTab()} and related APIs
+ for placing tabs within their action bar area.</p></li>
+ </ul>
+</li>
+</ul>
+
+<h3 id="media" style="margin-top:1em;">Media framework</h3>
+<ul>
+ <li>Applications that use the platform's media provider ({@link
+ android.provider.MediaStore}) can now read media data directly from the
+ removeable SD card, where supported by the device. Applications can also
+ interact with the SD card files directly, using the MTP API. </li>
+
+</ul>
+<h3 id="graphics" style="margin-top:1.25em;">Graphics</h3>
+<ul>
+<li>Parcelable utilities in Point and PointF
+ <ul>
+ <li>{@link android.graphics.Point} and {@link android.graphics.PointF}
+ classes now include the {@link android.os.Parcelable} interface and utility methods {@link
+ android.graphics.Point#describeContents()}, {@link
+ android.graphics.Point#readFromParcel(android.os.Parcel) readFromParcel()}, and {@link
+ android.graphics.Point#writeToParcel(android.os.Parcel, int) writeToParcel()}.</li>
+ </ul>
+</li>
+</ul>
+
+
+<h3 id="ime" style="margin-top:1.25em;">IME framework</h3>
+<ul>
+ <li>New {@link android.view.KeyEvent#getModifiers()} method for
+ retrieving the current state of the modifier keys.</li>
+</ul>
+
+
+<h3 id="usb" style="margin-top:1.25em;">USB framework</h3>
+<ul>
+ <li>New {@link
+ android.hardware.usb.UsbDeviceConnection#getRawDescriptors()} method for
+ retrieving the raw USB descriptors for the device. You can use the
+ method to access descriptors not supported directly via the higher
+ level APIs.</li>
+</ul>
+
+
+<h3 id="network" style="margin-top:1.25em;">Network</h3>
+<ul>
+<li>Network type constants
+ <ul>
+ <li>{@link android.net.ConnectivityManager} adds the constants {@link
+ android.net.ConnectivityManager#TYPE_ETHERNET} and {@link
+ android.net.ConnectivityManager#TYPE_BLUETOOTH}.</li>
+ </ul>
+</li>
+</ul>
+
+
+<h3 id="telephony" style="margin-top:1.25em;">Telephony</h3>
+<ul>
+ <li>New {@link android.telephony.TelephonyManager#NETWORK_TYPE_HSPAP} network type constant.</li>
+</ul>
+
+<h3 id="other" style="margin-top:1.25em;">Core utilities</h3>
+<ul>
+<li>Parcelable utilities
+ <ul>
+ <li>New interface {@link android.os.Parcelable.ClassLoaderCreator} allows
+ the application to receive the ClassLoader in which the object is being created.</li>
+ <li>New {@link android.os.ParcelFileDescriptor#adoptFd(int) adoptFd}, {@link
+ android.os.ParcelFileDescriptor#dup(java.io.FileDescriptor) dup()}, and {@link
+ android.os.ParcelFileDescriptor#fromFd(int) fromFd()} for managing
+ {@link android.os.ParcelFileDescriptor} objects.</li>
+ </ul>
+</li>
+<li>Binder and IBinder
+ <ul>
+ <li>New method {@link android.os.Binder#dumpAsync(java.io.FileDescriptor, java.lang.String[]) dumpAsync()}
+ in {@link android.os.Binder} and {@link android.os.IBinder} let applications
+ dump to a specified file, ensuring that the target executes asynchronously.</li>
+ <li>New {@link android.os.IBinder} protocol transaction code {@link
+ android.os.IBinder#TWEET_TRANSACTION} lets applications send a tweet
+ to the target object.</li>
+ </ul>
+</li>
+</ul>
+
+
+
+
+<h3 id="features">New feature constants</h3>
+
+<p>The platform adds new hardware feature constants that you can declare
+in their application manifests, to inform external entities such as Android
+Market of required hardware and software capabilities. You declare these
+and other feature constants in <a
+href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code
+&lt;uses-feature&gt;}</a> manifest elements.
+
+<p>Android Market filters applications based on their <code>&lt;uses-feature&gt;</code> attributes, to ensure that they are available only to devices on which their requirements are met. </p>
+
+<ul>
+<li>Feature constants for landscape or portrait requirements
+
+<p>Android 3.2 introduces new feature constants that let applications specify whether they require display in landscape orientation, portrait orientation, or both. Declaring these constants indicates that the application must not be installed on a device that doesn't offer the associated orientation. Conversely, if one or both of the constants are not declared, it indicates that the application does not have a preference for the undeclared orientations and may be installed on a device that doesn't offer them. </p>
+
+<ul>
+ <li>{@link android.content.pm.PackageManager#FEATURE_SCREEN_LANDSCAPE
+android.hardware.screen.landscape} &mdash; The application requires display in
+landscape orientation.</li>
+ <li>{@link android.content.pm.PackageManager#FEATURE_SCREEN_PORTRAIT
+android.hardware.screen.portrait} &mdash; The application requires display in
+portrait orientation.</li>
+</ul>
+
+<p>A typical application that functions properly in both landscape and portrait orientations would not normally need to declare an orientation requirement. Rather, an application designed primarily for one orientation, such as an app designed for a television, could declare one of the constants to ensure that it isn't available to devices that don't provide that orientation.</p>
+
+<p>If the application is targeting API level 12 or lower, the platform assumes that if app has not specified whether it requires portrait or landscape, both orientations are required.</p>
+</li>
+<li>Other feature constants
+
+<ul>
+ <li>{@link android.content.pm.PackageManager#FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT
+android.hardware.faketouch.multitouch.distinct} &mdash; The application requires support for emulated mulitouch input with distinct tracking of two or more points.</li>
+
+ <li>{@link android.content.pm.PackageManager#FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND
+android.hardware.faketouch.multitouch.jazzhand} &mdash; The application requires support for emulated mulitouch input with distinct tracking of five or more points.</li>
+</ul>
+
+</li>
+</ul>
+
+
+<h3 id="api-diff">API Differences Report</h3>
+
+<p>For a detailed view of all API changes in Android {@sdkPlatformVersion} (API
+Level
+{@sdkPlatformApiLevel}), see the <a
+href="{@docRoot}sdk/api_diff/{@sdkPlatformApiLevel}/changes.html">API
+Differences Report</a>.</p>
+
+
+
+
+
+<h2 id="api-level">API Level</h2>
+
+<p>The Android {@sdkPlatformVersion} platform delivers an updated version of
+the framework API. The Android {@sdkPlatformVersion} API
+is assigned an integer identifier &mdash;
+<strong>{@sdkPlatformApiLevel}</strong> &mdash; that is
+stored in the system itself. This identifier, called the "API Level", allows the
+system to correctly determine whether an application is compatible with
+the system, prior to installing the application. </p>
+
+<p>To use APIs introduced in Android {@sdkPlatformVersion} in your application,
+you need compile the application against the Android library that is provided in
+the Android {@sdkPlatformVersion} SDK platform. Depending on your needs, you
+might
+also need to add an <code>android:minSdkVersion="{@sdkPlatformApiLevel}"</code>
+attribute to the <code>&lt;uses-sdk&gt;</code> element in the application's
+manifest.</p>
+
+<p>For more information about how to use API Level, see the <a
+href="{@docRoot}guide/appendix/api-levels.html">API Levels</a> document. </p>
+
+
+<h2 id="apps">Built-in Applications</h2>
+
+<p>The system image included in the downloadable platform provides these
+built-in applications:</p>
+
+<table style="border:0;padding-bottom:0;margin-bottom:0;">
+<tr>
+<td style="border:0;padding-bottom:0;margin-bottom:0;">
+<ul>
+<li>API Demos</li>
+<li>Browser</li>
+<li>Calculator</li>
+<li>Camera</li>
+<li>Clock</li>
+<li>Contacts</li>
+<li>Custom Locale</li>
+<li>Dev Tools</li>
+<li>Downloads</li>
+<li>Email</li>
+</ul>
+</td>
+<td style="border:0;padding-bottom:0;margin-bottom:0;padding-left:5em;">
+<ul>
+<li>Gallery</li>
+<li>Gestures Builder</li>
+<li>Messaging</li>
+<li>Music</li>
+<li>Search</li>
+<li>Settings</li>
+<li>Spare Parts</li>
+<li>Speech Recorder</li>
+<li>Widget Preview</li>
+</ul>
+</td>
+</tr>
+</table>
+
+
+<h2 id="locs" style="margin-top:.75em;">Locales</h2>
+
+<p>The system image included in the downloadable SDK platform provides a variety
+of
+built-in locales. In some cases, region-specific strings are available for the
+locales. In other cases, a default version of the language is used. The
+languages that are available in the Android 3.0 system
+image are listed below (with <em>language</em>_<em>country/region</em> locale
+descriptor).</p>
+
+<table style="border:0;padding-bottom:0;margin-bottom:0;">
+<tr>
+<td style="border:0;padding-bottom:0;margin-bottom:0;">
+<ul>
+<li>Arabic, Egypt (ar_EG)</li>
+<li>Arabic, Israel (ar_IL)</li>
+<li>Bulgarian, Bulgaria (bg_BG)</li>
+<li>Catalan, Spain (ca_ES)</li>
+<li>Czech, Czech Republic (cs_CZ)</li>
+<li>Danish, Denmark(da_DK)</li>
+<li>German, Austria (de_AT)</li>
+<li>German, Switzerland (de_CH)</li>
+<li>German, Germany (de_DE)</li>
+<li>German, Liechtenstein (de_LI)</li>
+<li>Greek, Greece (el_GR)</li>
+<li>English, Australia (en_AU)</li>
+<li>English, Canada (en_CA)</li>
+<li>English, Britain (en_GB)</li>
+<li>English, Ireland (en_IE)</li>
+<li>English, India (en_IN)</li>
+<li>English, New Zealand (en_NZ)</li>
+<li>English, Singapore(en_SG)</li>
+<li>English, US (en_US)</li>
+<li>English, Zimbabwe (en_ZA)</li>
+<li>Spanish (es_ES)</li>
+<li>Spanish, US (es_US)</li>
+<li>Finnish, Finland (fi_FI)</li>
+<li>French, Belgium (fr_BE)</li>
+<li>French, Canada (fr_CA)</li>
+<li>French, Switzerland (fr_CH)</li>
+<li>French, France (fr_FR)</li>
+<li>Hebrew, Israel (he_IL)</li>
+<li>Hindi, India (hi_IN)</li>
+</ul>
+</td>
+<td style="border:0;padding-bottom:0;margin-bottom:0;padding-left:5em;">
+<li>Croatian, Croatia (hr_HR)</li>
+<li>Hungarian, Hungary (hu_HU)</li>
+<li>Indonesian, Indonesia (id_ID)</li>
+<li>Italian, Switzerland (it_CH)</li>
+<li>Italian, Italy (it_IT)</li>
+<li>Japanese (ja_JP)</li>
+<li>Korean (ko_KR)</li>
+<li>Lithuanian, Lithuania (lt_LT)</li>
+<li>Latvian, Latvia (lv_LV)</li>
+<li>Norwegian bokmål, Norway (nb_NO)</li>
+<li>Dutch, Belgium (nl_BE)</li>
+<li>Dutch, Netherlands (nl_NL)</li>
+<li>Polish (pl_PL)</li>
+<li>Portuguese, Brazil (pt_BR)</li>
+<li>Portuguese, Portugal (pt_PT)</li>
+<li>Romanian, Romania (ro_RO)</li>
+<li>Russian (ru_RU)</li></li>
+<li>Slovak, Slovakia (sk_SK)</li>
+<li>Slovenian, Slovenia (sl_SI)</li>
+<li>Serbian (sr_RS)</li>
+<li>Swedish, Sweden (sv_SE)</li>
+<li>Thai, Thailand (th_TH)</li>
+<li>Tagalog, Philippines (tl_PH)</li>
+<li>Turkish, Turkey (tr_TR)</li>
+<li>Ukrainian, Ukraine (uk_UA)</li>
+<li>Vietnamese, Vietnam (vi_VN)</li>
+<li>Chinese, PRC (zh_CN)</li>
+<li>Chinese, Taiwan (zh_TW)</li>
+</td>
+</tr>
+</table>
+
+<p class="note"><strong>Note:</strong> The Android platform may support more
+locales than are included in the SDK system image. All of the supported locales
+are available in the <a href="http://source.android.com/">Android Open Source
+Project</a>.</p>
+
+<h2 id="skins">Emulator Skins</h2>
+
+<p>The downloadable platform includes the following emulator skin:</p>
+
+<ul>
+ <li>
+ WXGA (1280x800, medium density, xlarge screen)
+ </li>
+</ul>
+
+<p>For more information about how to develop an application that displays
+and functions properly on all Android-powered devices, see <a
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a>.</p>
diff --git a/docs/html/sdk/api_diff/13/changes.html b/docs/html/sdk/api_diff/13/changes.html
new file mode 100644
index 000000000000..0a25fca33a35
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<!-- on Wed Jun 29 10:50:35 PDT 2011 -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+API Differences between 12 and 13
+</TITLE>
+<link href="../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</head>
+<frameset cols="242,**" framespacing="1" frameborder="yes" border="1" bordercolor="#e9e9e9">
+<frameset rows="174,**" framespacing="1" frameborder="yes" border="1" bordercolor="#e9e9e9">
+ <frame src="changes/jdiff_topleftframe.html" scrolling="no" name="topleftframe" frameborder="1">
+ <frame src="changes/alldiffs_index_all.html" scrolling="auto" name="bottomleftframe" frameborder="1">
+ </frameset>
+ <frame src="changes/changes-summary.html" scrolling="auto" name="rightframe" frameborder="1">
+</frameset>
+<noframes>
+<h2>
+Frame Alert
+</h2>
+
+<p>
+This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+<br>
+Link to <a href="changes/changes-summary.html" target="_top">Non-frame version.</A>
+</noframes>
+</html>
diff --git a/docs/html/sdk/api_diff/13/changes/alldiffs_index_additions.html b/docs/html/sdk/api_diff/13/changes/alldiffs_index_additions.html
new file mode 100644
index 000000000000..1d534293dd36
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/alldiffs_index_additions.html
@@ -0,0 +1,663 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+All Additions Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for All Differences" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="alldiffs_index_all.html" xclass="hiddenlink">All Differences</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<b>Additions</b>
+ <br>
+<A HREF="alldiffs_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<!-- Method adoptFd -->
+<A NAME="A"></A>
+<br><font size="+2">A</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.os.ParcelFileDescriptor.html#android.os.ParcelFileDescriptor.adoptFd_added(int)" class="hiddenlink" target="rightframe"><b>adoptFd</b>
+(<code>int</code>)</A></nobr><br>
+<!-- Method attach -->
+<nobr><A HREF="android.app.FragmentTransaction.html#android.app.FragmentTransaction.attach_added(android.app.Fragment)" class="hiddenlink" target="rightframe"><b>attach</b>
+(<code>Fragment</code>)</A></nobr><br>
+<!-- Field compatibleWidthLimitDp -->
+<A NAME="C"></A>
+<br><font size="+2">C</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>compatibleWidthLimitDp</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.R.attr.html#android.R.attr.compatibleWidthLimitDp" class="hiddenlink" target="rightframe">android.R.attr</A>
+</nobr><br>
+<!-- Field compatibleWidthLimitDp -->
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.content.pm.ApplicationInfo.html#android.content.pm.ApplicationInfo.compatibleWidthLimitDp" class="hiddenlink" target="rightframe">android.content.pm.ApplicationInfo</A>
+</nobr><br>
+<!-- Field CONFIG_SCREEN_SIZE -->
+<nobr><A HREF="android.content.pm.ActivityInfo.html#android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE" class="hiddenlink" target="rightframe">CONFIG_SCREEN_SIZE</A>
+</nobr><br>
+<!-- Field CONFIG_SMALLEST_SCREEN_SIZE -->
+<nobr><A HREF="android.content.pm.ActivityInfo.html#android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE" class="hiddenlink" target="rightframe">CONFIG_SMALLEST_SCREEN_SIZE</A>
+</nobr><br>
+<!-- Field CREATOR -->
+<i>CREATOR</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.graphics.Point.html#android.graphics.Point.CREATOR" class="hiddenlink" target="rightframe">android.graphics.Point</A>
+</nobr><br>
+<!-- Field CREATOR -->
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.graphics.PointF.html#android.graphics.PointF.CREATOR" class="hiddenlink" target="rightframe">android.graphics.PointF</A>
+</nobr><br>
+<!-- Field DENSITY_TV -->
+<A NAME="D"></A>
+<br><font size="+2">D</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.util.DisplayMetrics.html#android.util.DisplayMetrics.DENSITY_TV" class="hiddenlink" target="rightframe">DENSITY_TV</A>
+</nobr><br>
+<!-- Method describeContents -->
+<i>describeContents</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.Point.html#android.graphics.Point.describeContents_added()" class="hiddenlink" target="rightframe">type&nbsp;<b>
+()</b>&nbsp;in&nbsp;android.graphics.Point
+</A></nobr><br>
+<!-- Method describeContents -->
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.PointF.html#android.graphics.PointF.describeContents_added()" class="hiddenlink" target="rightframe">type&nbsp;<b>
+()</b>&nbsp;in&nbsp;android.graphics.PointF
+</A></nobr><br>
+<!-- Method detach -->
+<nobr><A HREF="android.app.FragmentTransaction.html#android.app.FragmentTransaction.detach_added(android.app.Fragment)" class="hiddenlink" target="rightframe"><b>detach</b>
+(<code>Fragment</code>)</A></nobr><br>
+<!-- Method dumpAsync -->
+<i>dumpAsync</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.os.Binder.html#android.os.Binder.dumpAsync_added(java.io.FileDescriptor, java.lang.String[])" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>FileDescriptor, String[]</code>)</b>&nbsp;in&nbsp;android.os.Binder
+</A></nobr><br>
+<!-- Method dumpAsync -->
+&nbsp;&nbsp;<nobr><A HREF="android.os.IBinder.html#android.os.IBinder.dumpAsync_added(java.io.FileDescriptor, java.lang.String[])" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>FileDescriptor, String[]</code>)</b>&nbsp;in&nbsp;android.os.IBinder
+</A></nobr><br>
+<!-- Method dup -->
+<nobr><A HREF="android.os.ParcelFileDescriptor.html#android.os.ParcelFileDescriptor.dup_added(java.io.FileDescriptor)" class="hiddenlink" target="rightframe"><b>dup</b>
+(<code>FileDescriptor</code>)</A></nobr><br>
+<!-- Field FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT -->
+<A NAME="F"></A>
+<br><font size="+2">F</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT" class="hiddenlink" target="rightframe">FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT</A>
+</nobr><br>
+<!-- Field FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND -->
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND" class="hiddenlink" target="rightframe">FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND</A>
+</nobr><br>
+<!-- Field FEATURE_SCREEN_LANDSCAPE -->
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_SCREEN_LANDSCAPE" class="hiddenlink" target="rightframe">FEATURE_SCREEN_LANDSCAPE</A>
+</nobr><br>
+<!-- Field FEATURE_SCREEN_PORTRAIT -->
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_SCREEN_PORTRAIT" class="hiddenlink" target="rightframe">FEATURE_SCREEN_PORTRAIT</A>
+</nobr><br>
+<!-- Class Fragment.SavedState -->
+<A HREF="pkg_android.app.html#Fragment.SavedState" class="hiddenlink" target="rightframe"><b>Fragment.SavedState</b></A><br>
+<!-- Method fromFd -->
+<nobr><A HREF="android.os.ParcelFileDescriptor.html#android.os.ParcelFileDescriptor.fromFd_added(int)" class="hiddenlink" target="rightframe"><b>fromFd</b>
+(<code>int</code>)</A></nobr><br>
+<!-- Method getModifiers -->
+<A NAME="G"></A>
+<br><font size="+2">G</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.view.KeyEvent.html#android.view.KeyEvent.getModifiers_added()" class="hiddenlink" target="rightframe"><b>getModifiers</b>
+()</A></nobr><br>
+<!-- Method getRawDescriptors -->
+<nobr><A HREF="android.hardware.usb.UsbDeviceConnection.html#android.hardware.usb.UsbDeviceConnection.getRawDescriptors_added()" class="hiddenlink" target="rightframe"><b>getRawDescriptors</b>
+()</A></nobr><br>
+<!-- Method getRectSize -->
+<nobr><A HREF="android.view.Display.html#android.view.Display.getRectSize_added(android.graphics.Rect)" class="hiddenlink" target="rightframe"><b>getRectSize</b>
+(<code>Rect</code>)</A></nobr><br>
+<!-- Method getSize -->
+<nobr><A HREF="android.view.Display.html#android.view.Display.getSize_added(android.graphics.Point)" class="hiddenlink" target="rightframe"><b>getSize</b>
+(<code>Point</code>)</A></nobr><br>
+<!-- Field HONEYCOMB_MR2 -->
+<A NAME="H"></A>
+<br><font size="+2">H</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.os.Build.VERSION_CODES.html#android.os.Build.VERSION_CODES.HONEYCOMB_MR2" class="hiddenlink" target="rightframe">HONEYCOMB_MR2</A>
+</nobr><br>
+<!-- Method isDetached -->
+<A NAME="I"></A>
+<br><font size="+2">I</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.Fragment.html#android.app.Fragment.isDetached_added()" class="hiddenlink" target="rightframe"><b>isDetached</b>
+()</A></nobr><br>
+<!-- Field largestWidthLimitDp -->
+<A NAME="L"></A>
+<br><font size="+2">L</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>largestWidthLimitDp</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.R.attr.html#android.R.attr.largestWidthLimitDp" class="hiddenlink" target="rightframe">android.R.attr</A>
+</nobr><br>
+<!-- Field largestWidthLimitDp -->
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.content.pm.ApplicationInfo.html#android.content.pm.ApplicationInfo.largestWidthLimitDp" class="hiddenlink" target="rightframe">android.content.pm.ApplicationInfo</A>
+</nobr><br>
+<!-- Field NETWORK_TYPE_HSPAP -->
+<A NAME="N"></A>
+<br><font size="+2">N</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.telephony.TelephonyManager.html#android.telephony.TelephonyManager.NETWORK_TYPE_HSPAP" class="hiddenlink" target="rightframe">NETWORK_TYPE_HSPAP</A>
+</nobr><br>
+<!-- Method onViewCreated -->
+<A NAME="O"></A>
+<br><font size="+2">O</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.Fragment.html#android.app.Fragment.onViewCreated_added(android.view.View, android.os.Bundle)" class="hiddenlink" target="rightframe"><b>onViewCreated</b>
+(<code>View, Bundle</code>)</A></nobr><br>
+<!-- Class Parcelable.ClassLoaderCreator -->
+<A NAME="P"></A>
+<br><font size="+2">P</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="pkg_android.os.html#Parcelable.ClassLoaderCreator" class="hiddenlink" target="rightframe"><b><i>Parcelable.ClassLoaderCreator</i></b></A><br>
+<!-- Method readFromParcel -->
+<A NAME="R"></A>
+<br><font size="+2">R</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>readFromParcel</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.Point.html#android.graphics.Point.readFromParcel_added(android.os.Parcel)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel</code>)</b>&nbsp;in&nbsp;android.graphics.Point
+</A></nobr><br>
+<!-- Method readFromParcel -->
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.PointF.html#android.graphics.PointF.readFromParcel_added(android.os.Parcel)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel</code>)</b>&nbsp;in&nbsp;android.graphics.PointF
+</A></nobr><br>
+<!-- Field requiresSmallestWidthDp -->
+<i>requiresSmallestWidthDp</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.R.attr.html#android.R.attr.requiresSmallestWidthDp" class="hiddenlink" target="rightframe">android.R.attr</A>
+</nobr><br>
+<!-- Field requiresSmallestWidthDp -->
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.content.pm.ApplicationInfo.html#android.content.pm.ApplicationInfo.requiresSmallestWidthDp" class="hiddenlink" target="rightframe">android.content.pm.ApplicationInfo</A>
+</nobr><br>
+<!-- Method saveFragmentInstanceState -->
+<A NAME="S"></A>
+<br><font size="+2">S</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.FragmentManager.html#android.app.FragmentManager.saveFragmentInstanceState_added(android.app.Fragment)" class="hiddenlink" target="rightframe"><b>saveFragmentInstanceState</b>
+(<code>Fragment</code>)</A></nobr><br>
+<!-- Field SCREEN_HEIGHT_DP_UNDEFINED -->
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED" class="hiddenlink" target="rightframe">SCREEN_HEIGHT_DP_UNDEFINED</A>
+</nobr><br>
+<!-- Field SCREEN_WIDTH_DP_UNDEFINED -->
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED" class="hiddenlink" target="rightframe">SCREEN_WIDTH_DP_UNDEFINED</A>
+</nobr><br>
+<!-- Field screenHeightDp -->
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.screenHeightDp" class="hiddenlink" target="rightframe">screenHeightDp</A>
+</nobr><br>
+<!-- Field screenWidthDp -->
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.screenWidthDp" class="hiddenlink" target="rightframe">screenWidthDp</A>
+</nobr><br>
+<!-- Field SET_POINTER_SPEED -->
+<nobr><A HREF="android.Manifest.permission.html#android.Manifest.permission.SET_POINTER_SPEED" class="hiddenlink" target="rightframe">SET_POINTER_SPEED</A>
+</nobr><br>
+<!-- Method setCustomAnimations -->
+<nobr><A HREF="android.app.FragmentTransaction.html#android.app.FragmentTransaction.setCustomAnimations_added(int, int, int, int)" class="hiddenlink" target="rightframe"><b>setCustomAnimations</b>
+(<code>int, int, int, int</code>)</A></nobr><br>
+<!-- Method setInitialSavedState -->
+<nobr><A HREF="android.app.Fragment.html#android.app.Fragment.setInitialSavedState_added(android.app.Fragment.SavedState)" class="hiddenlink" target="rightframe"><b>setInitialSavedState</b>
+(<code>SavedState</code>)</A></nobr><br>
+<!-- Field SMALLEST_SCREEN_WIDTH_DP_UNDEFINED -->
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED" class="hiddenlink" target="rightframe">SMALLEST_SCREEN_WIDTH_DP_UNDEFINED</A>
+</nobr><br>
+<!-- Field smallestScreenWidthDp -->
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.smallestScreenWidthDp" class="hiddenlink" target="rightframe">smallestScreenWidthDp</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo -->
+<A NAME="T"></A>
+<br><font size="+2">T</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo" class="hiddenlink" target="rightframe">TextAppearance_Holo</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_DialogWindowTitle -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_DialogWindowTitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_DialogWindowTitle</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Inverse -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Inverse</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Large -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Large" class="hiddenlink" target="rightframe">TextAppearance_Holo_Large</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Large_Inverse -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Large_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Large_Inverse</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Medium -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Medium" class="hiddenlink" target="rightframe">TextAppearance_Holo_Medium</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Medium_Inverse -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Medium_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Medium_Inverse</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_SearchResult_Subtitle -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_SearchResult_Subtitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_SearchResult_Subtitle</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_SearchResult_Title -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_SearchResult_Title" class="hiddenlink" target="rightframe">TextAppearance_Holo_SearchResult_Title</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Small -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Small" class="hiddenlink" target="rightframe">TextAppearance_Holo_Small</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Small_Inverse -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Small_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Small_Inverse</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_ActionBar_Subtitle -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionBar_Subtitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionBar_Subtitle</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_ActionBar_Title -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionBar_Title" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionBar_Title</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_ActionMode_Subtitle -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionMode_Subtitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionMode_Subtitle</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_ActionMode_Title -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionMode_Title" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionMode_Title</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_Button -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_Button" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_Button</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_DropDownHint -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_DropDownHint" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_DropDownHint</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_DropDownItem -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_DropDownItem" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_DropDownItem</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_EditText -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_EditText" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_EditText</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_IconMenu_Item -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_IconMenu_Item" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_IconMenu_Item</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_PopupMenu -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_PopupMenu" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_PopupMenu</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_PopupMenu_Large -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_PopupMenu_Large" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_PopupMenu_Large</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_PopupMenu_Small -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_PopupMenu_Small" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_PopupMenu_Small</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_TabWidget -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TabWidget" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TabWidget</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_TextView -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TextView" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TextView</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_TextView_PopupMenu -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TextView_PopupMenu" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TextView_PopupMenu</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_TextView_SpinnerItem -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TextView_SpinnerItem" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TextView_SpinnerItem</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_WindowTitle -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_WindowTitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_WindowTitle</A>
+</nobr><br>
+<!-- Field Theme_Holo_Light_NoActionBar -->
+<nobr><A HREF="android.R.style.html#android.R.style.Theme_Holo_Light_NoActionBar" class="hiddenlink" target="rightframe">Theme_Holo_Light_NoActionBar</A>
+</nobr><br>
+<!-- Field Theme_Holo_Light_NoActionBar_Fullscreen -->
+<nobr><A HREF="android.R.style.html#android.R.style.Theme_Holo_Light_NoActionBar_Fullscreen" class="hiddenlink" target="rightframe">Theme_Holo_Light_NoActionBar_Fullscreen</A>
+</nobr><br>
+<!-- Field TWEET_TRANSACTION -->
+<nobr><A HREF="android.os.IBinder.html#android.os.IBinder.TWEET_TRANSACTION" class="hiddenlink" target="rightframe">TWEET_TRANSACTION</A>
+</nobr><br>
+<!-- Field TYPE_BLUETOOTH -->
+<nobr><A HREF="android.net.ConnectivityManager.html#android.net.ConnectivityManager.TYPE_BLUETOOTH" class="hiddenlink" target="rightframe">TYPE_BLUETOOTH</A>
+</nobr><br>
+<!-- Field TYPE_ETHERNET -->
+<nobr><A HREF="android.net.ConnectivityManager.html#android.net.ConnectivityManager.TYPE_ETHERNET" class="hiddenlink" target="rightframe">TYPE_ETHERNET</A>
+</nobr><br>
+<!-- Field UI_MODE_TYPE_TELEVISION -->
+<A NAME="U"></A>
+<br><font size="+2">U</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.UI_MODE_TYPE_TELEVISION" class="hiddenlink" target="rightframe">UI_MODE_TYPE_TELEVISION</A>
+</nobr><br>
+<!-- Field Widget_ActionBar_TabBar -->
+<A NAME="W"></A>
+<br><font size="+2">W</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_ActionBar_TabBar" class="hiddenlink" target="rightframe">Widget_ActionBar_TabBar</A>
+</nobr><br>
+<!-- Field Widget_ActionBar_TabText -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_ActionBar_TabText" class="hiddenlink" target="rightframe">Widget_ActionBar_TabText</A>
+</nobr><br>
+<!-- Field Widget_ActionBar_TabView -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_ActionBar_TabView" class="hiddenlink" target="rightframe">Widget_ActionBar_TabView</A>
+</nobr><br>
+<!-- Field Widget_Holo_ActionBar_TabBar -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_ActionBar_TabBar" class="hiddenlink" target="rightframe">Widget_Holo_ActionBar_TabBar</A>
+</nobr><br>
+<!-- Field Widget_Holo_ActionBar_TabText -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_ActionBar_TabText" class="hiddenlink" target="rightframe">Widget_Holo_ActionBar_TabText</A>
+</nobr><br>
+<!-- Field Widget_Holo_ActionBar_TabView -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_ActionBar_TabView" class="hiddenlink" target="rightframe">Widget_Holo_ActionBar_TabView</A>
+</nobr><br>
+<!-- Field Widget_Holo_Light_ActionBar_TabBar -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_Light_ActionBar_TabBar" class="hiddenlink" target="rightframe">Widget_Holo_Light_ActionBar_TabBar</A>
+</nobr><br>
+<!-- Field Widget_Holo_Light_ActionBar_TabText -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_Light_ActionBar_TabText" class="hiddenlink" target="rightframe">Widget_Holo_Light_ActionBar_TabText</A>
+</nobr><br>
+<!-- Field Widget_Holo_Light_ActionBar_TabView -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_Light_ActionBar_TabView" class="hiddenlink" target="rightframe">Widget_Holo_Light_ActionBar_TabView</A>
+</nobr><br>
+<!-- Method writeToParcel -->
+<i>writeToParcel</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.Point.html#android.graphics.Point.writeToParcel_added(android.os.Parcel, int)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel, int</code>)</b>&nbsp;in&nbsp;android.graphics.Point
+</A></nobr><br>
+<!-- Method writeToParcel -->
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.PointF.html#android.graphics.PointF.writeToParcel_added(android.os.Parcel, int)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel, int</code>)</b>&nbsp;in&nbsp;android.graphics.PointF
+</A></nobr><br>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/alldiffs_index_all.html b/docs/html/sdk/api_diff/13/changes/alldiffs_index_all.html
new file mode 100644
index 000000000000..a4e428e40fb4
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/alldiffs_index_all.html
@@ -0,0 +1,941 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+All Differences Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for All Differences" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<b>All Differences</b>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<A HREF="alldiffs_index_additions.html"xclass="hiddenlink">Additions</A>
+ <br>
+<A HREF="alldiffs_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<!-- Class Activity -->
+<A NAME="A"></A>
+<br><font size="+2">A</font>&nbsp;
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.app.Activity.html" class="hiddenlink" target="rightframe">Activity</A><br>
+<!-- Class ActivityGroup -->
+<A HREF="android.app.ActivityGroup.html" class="hiddenlink" target="rightframe">ActivityGroup</A><br>
+<!-- Class ActivityInfo -->
+<A HREF="android.content.pm.ActivityInfo.html" class="hiddenlink" target="rightframe">ActivityInfo</A><br>
+<!-- Method adoptFd -->
+<nobr><A HREF="android.os.ParcelFileDescriptor.html#android.os.ParcelFileDescriptor.adoptFd_added(int)" class="hiddenlink" target="rightframe"><b>adoptFd</b>
+(<code>int</code>)</A></nobr><br>
+<!-- Package android -->
+<A HREF="pkg_android.html" class="hiddenlink" target="rightframe">android</A><br>
+<!-- Package android.app -->
+<A HREF="pkg_android.app.html" class="hiddenlink" target="rightframe">android.app</A><br>
+<!-- Package android.content.pm -->
+<A HREF="pkg_android.content.pm.html" class="hiddenlink" target="rightframe">android.content.pm</A><br>
+<!-- Package android.content.res -->
+<A HREF="pkg_android.content.res.html" class="hiddenlink" target="rightframe">android.content.res</A><br>
+<!-- Package android.graphics -->
+<A HREF="pkg_android.graphics.html" class="hiddenlink" target="rightframe">android.graphics</A><br>
+<!-- Package android.hardware.usb -->
+<A HREF="pkg_android.hardware.usb.html" class="hiddenlink" target="rightframe">android.hardware.usb</A><br>
+<!-- Package android.net -->
+<A HREF="pkg_android.net.html" class="hiddenlink" target="rightframe">android.net</A><br>
+<!-- Package android.os -->
+<A HREF="pkg_android.os.html" class="hiddenlink" target="rightframe">android.os</A><br>
+<!-- Package android.telephony -->
+<A HREF="pkg_android.telephony.html" class="hiddenlink" target="rightframe">android.telephony</A><br>
+<!-- Package android.util -->
+<A HREF="pkg_android.util.html" class="hiddenlink" target="rightframe">android.util</A><br>
+<!-- Package android.view -->
+<A HREF="pkg_android.view.html" class="hiddenlink" target="rightframe">android.view</A><br>
+<!-- Class ApplicationInfo -->
+<A HREF="android.content.pm.ApplicationInfo.html" class="hiddenlink" target="rightframe">ApplicationInfo</A><br>
+<!-- Method attach -->
+<nobr><A HREF="android.app.FragmentTransaction.html#android.app.FragmentTransaction.attach_added(android.app.Fragment)" class="hiddenlink" target="rightframe"><b>attach</b>
+(<code>Fragment</code>)</A></nobr><br>
+<!-- Class Binder -->
+<A NAME="B"></A>
+<br><font size="+2">B</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.os.Binder.html" class="hiddenlink" target="rightframe">Binder</A><br>
+<!-- Class Build.VERSION_CODES -->
+<A HREF="android.os.Build.VERSION_CODES.html" class="hiddenlink" target="rightframe">Build.VERSION_CODES</A><br>
+<!-- Field compatibleWidthLimitDp -->
+<A NAME="C"></A>
+<br><font size="+2">C</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>compatibleWidthLimitDp</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.R.attr.html#android.R.attr.compatibleWidthLimitDp" class="hiddenlink" target="rightframe">android.R.attr</A>
+</nobr><br>
+<!-- Field compatibleWidthLimitDp -->
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.content.pm.ApplicationInfo.html#android.content.pm.ApplicationInfo.compatibleWidthLimitDp" class="hiddenlink" target="rightframe">android.content.pm.ApplicationInfo</A>
+</nobr><br>
+<!-- Field CONFIG_SCREEN_SIZE -->
+<nobr><A HREF="android.content.pm.ActivityInfo.html#android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE" class="hiddenlink" target="rightframe">CONFIG_SCREEN_SIZE</A>
+</nobr><br>
+<!-- Field CONFIG_SMALLEST_SCREEN_SIZE -->
+<nobr><A HREF="android.content.pm.ActivityInfo.html#android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE" class="hiddenlink" target="rightframe">CONFIG_SMALLEST_SCREEN_SIZE</A>
+</nobr><br>
+<!-- Class Configuration -->
+<A HREF="android.content.res.Configuration.html" class="hiddenlink" target="rightframe">Configuration</A><br>
+<!-- Class ConnectivityManager -->
+<A HREF="android.net.ConnectivityManager.html" class="hiddenlink" target="rightframe">ConnectivityManager</A><br>
+<!-- Field CREATOR -->
+<i>CREATOR</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.graphics.Point.html#android.graphics.Point.CREATOR" class="hiddenlink" target="rightframe">android.graphics.Point</A>
+</nobr><br>
+<!-- Field CREATOR -->
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.graphics.PointF.html#android.graphics.PointF.CREATOR" class="hiddenlink" target="rightframe">android.graphics.PointF</A>
+</nobr><br>
+<!-- Field DENSITY_TV -->
+<A NAME="D"></A>
+<br><font size="+2">D</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.util.DisplayMetrics.html#android.util.DisplayMetrics.DENSITY_TV" class="hiddenlink" target="rightframe">DENSITY_TV</A>
+</nobr><br>
+<!-- Method describeContents -->
+<i>describeContents</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.Point.html#android.graphics.Point.describeContents_added()" class="hiddenlink" target="rightframe">type&nbsp;<b>
+()</b>&nbsp;in&nbsp;android.graphics.Point
+</A></nobr><br>
+<!-- Method describeContents -->
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.PointF.html#android.graphics.PointF.describeContents_added()" class="hiddenlink" target="rightframe">type&nbsp;<b>
+()</b>&nbsp;in&nbsp;android.graphics.PointF
+</A></nobr><br>
+<!-- Method detach -->
+<nobr><A HREF="android.app.FragmentTransaction.html#android.app.FragmentTransaction.detach_added(android.app.Fragment)" class="hiddenlink" target="rightframe"><b>detach</b>
+(<code>Fragment</code>)</A></nobr><br>
+<!-- Method dismissDialog -->
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.dismissDialog_changed(int)" class="hiddenlink" target="rightframe">dismissDialog
+(<code>int</code>)</A></nobr><br>
+<!-- Class Display -->
+<A HREF="android.view.Display.html" class="hiddenlink" target="rightframe">Display</A><br>
+<!-- Class DisplayMetrics -->
+<A HREF="android.util.DisplayMetrics.html" class="hiddenlink" target="rightframe">DisplayMetrics</A><br>
+<!-- Method dumpAsync -->
+<i>dumpAsync</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.os.Binder.html#android.os.Binder.dumpAsync_added(java.io.FileDescriptor, java.lang.String[])" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>FileDescriptor, String[]</code>)</b>&nbsp;in&nbsp;android.os.Binder
+</A></nobr><br>
+<!-- Method dumpAsync -->
+&nbsp;&nbsp;<nobr><A HREF="android.os.IBinder.html#android.os.IBinder.dumpAsync_added(java.io.FileDescriptor, java.lang.String[])" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>FileDescriptor, String[]</code>)</b>&nbsp;in&nbsp;android.os.IBinder
+</A></nobr><br>
+<!-- Method dup -->
+<nobr><A HREF="android.os.ParcelFileDescriptor.html#android.os.ParcelFileDescriptor.dup_added(java.io.FileDescriptor)" class="hiddenlink" target="rightframe"><b>dup</b>
+(<code>FileDescriptor</code>)</A></nobr><br>
+<!-- Method exitKeyguardSecurely -->
+<A NAME="E"></A>
+<br><font size="+2">E</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.KeyguardManager.html#android.app.KeyguardManager.exitKeyguardSecurely_changed(android.app.KeyguardManager.OnKeyguardExitResult)" class="hiddenlink" target="rightframe">exitKeyguardSecurely
+(<code>OnKeyguardExitResult</code>)</A></nobr><br>
+<!-- Field FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT -->
+<A NAME="F"></A>
+<br><font size="+2">F</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT" class="hiddenlink" target="rightframe">FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT</A>
+</nobr><br>
+<!-- Field FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND -->
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND" class="hiddenlink" target="rightframe">FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND</A>
+</nobr><br>
+<!-- Field FEATURE_SCREEN_LANDSCAPE -->
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_SCREEN_LANDSCAPE" class="hiddenlink" target="rightframe">FEATURE_SCREEN_LANDSCAPE</A>
+</nobr><br>
+<!-- Field FEATURE_SCREEN_PORTRAIT -->
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_SCREEN_PORTRAIT" class="hiddenlink" target="rightframe">FEATURE_SCREEN_PORTRAIT</A>
+</nobr><br>
+<!-- Class Fragment -->
+<A HREF="android.app.Fragment.html" class="hiddenlink" target="rightframe">Fragment</A><br>
+<!-- Class Fragment.SavedState -->
+<A HREF="pkg_android.app.html#Fragment.SavedState" class="hiddenlink" target="rightframe"><b>Fragment.SavedState</b></A><br>
+<!-- Class FragmentManager -->
+<A HREF="android.app.FragmentManager.html" class="hiddenlink" target="rightframe">FragmentManager</A><br>
+<!-- Class FragmentTransaction -->
+<A HREF="android.app.FragmentTransaction.html" class="hiddenlink" target="rightframe">FragmentTransaction</A><br>
+<!-- Method fromFd -->
+<nobr><A HREF="android.os.ParcelFileDescriptor.html#android.os.ParcelFileDescriptor.fromFd_added(int)" class="hiddenlink" target="rightframe"><b>fromFd</b>
+(<code>int</code>)</A></nobr><br>
+<!-- Method getHeight -->
+<A NAME="G"></A>
+<br><font size="+2">G</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.view.Display.html#android.view.Display.getHeight_changed()" class="hiddenlink" target="rightframe">getHeight
+()</A></nobr><br>
+<!-- Method getLastNonConfigurationInstance -->
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.getLastNonConfigurationInstance_changed()" class="hiddenlink" target="rightframe">getLastNonConfigurationInstance
+()</A></nobr><br>
+<!-- Method getModifiers -->
+<nobr><A HREF="android.view.KeyEvent.html#android.view.KeyEvent.getModifiers_added()" class="hiddenlink" target="rightframe"><b>getModifiers</b>
+()</A></nobr><br>
+<!-- Method getRawDescriptors -->
+<nobr><A HREF="android.hardware.usb.UsbDeviceConnection.html#android.hardware.usb.UsbDeviceConnection.getRawDescriptors_added()" class="hiddenlink" target="rightframe"><b>getRawDescriptors</b>
+()</A></nobr><br>
+<!-- Method getRectSize -->
+<nobr><A HREF="android.view.Display.html#android.view.Display.getRectSize_added(android.graphics.Rect)" class="hiddenlink" target="rightframe"><b>getRectSize</b>
+(<code>Rect</code>)</A></nobr><br>
+<!-- Method getSize -->
+<nobr><A HREF="android.view.Display.html#android.view.Display.getSize_added(android.graphics.Point)" class="hiddenlink" target="rightframe"><b>getSize</b>
+(<code>Point</code>)</A></nobr><br>
+<!-- Method getWidth -->
+<nobr><A HREF="android.view.Display.html#android.view.Display.getWidth_changed()" class="hiddenlink" target="rightframe">getWidth
+()</A></nobr><br>
+<!-- Field HONEYCOMB_MR2 -->
+<A NAME="H"></A>
+<br><font size="+2">H</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.os.Build.VERSION_CODES.html#android.os.Build.VERSION_CODES.HONEYCOMB_MR2" class="hiddenlink" target="rightframe">HONEYCOMB_MR2</A>
+</nobr><br>
+<!-- Class IBinder -->
+<A NAME="I"></A>
+<br><font size="+2">I</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.os.IBinder.html" class="hiddenlink" target="rightframe"><i>IBinder</i></A><br>
+<!-- Method isDetached -->
+<nobr><A HREF="android.app.Fragment.html#android.app.Fragment.isDetached_added()" class="hiddenlink" target="rightframe"><b>isDetached</b>
+()</A></nobr><br>
+<!-- Class KeyEvent -->
+<A NAME="K"></A>
+<br><font size="+2">K</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.view.KeyEvent.html" class="hiddenlink" target="rightframe">KeyEvent</A><br>
+<!-- Class KeyguardManager -->
+<A HREF="android.app.KeyguardManager.html" class="hiddenlink" target="rightframe">KeyguardManager</A><br>
+<!-- Class KeyguardManager.KeyguardLock -->
+<A HREF="android.app.KeyguardManager.KeyguardLock.html" class="hiddenlink" target="rightframe">KeyguardManager.KeyguardLock</A><br>
+<!-- Field largestWidthLimitDp -->
+<A NAME="L"></A>
+<br><font size="+2">L</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>largestWidthLimitDp</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.R.attr.html#android.R.attr.largestWidthLimitDp" class="hiddenlink" target="rightframe">android.R.attr</A>
+</nobr><br>
+<!-- Field largestWidthLimitDp -->
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.content.pm.ApplicationInfo.html#android.content.pm.ApplicationInfo.largestWidthLimitDp" class="hiddenlink" target="rightframe">android.content.pm.ApplicationInfo</A>
+</nobr><br>
+<!-- Class LocalActivityManager -->
+<A HREF="android.app.LocalActivityManager.html" class="hiddenlink" target="rightframe">LocalActivityManager</A><br>
+<!-- Class Manifest.permission -->
+<A NAME="M"></A>
+<br><font size="+2">M</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.Manifest.permission.html" class="hiddenlink" target="rightframe">Manifest.permission</A><br>
+<!-- Field NETWORK_TYPE_HSPAP -->
+<A NAME="N"></A>
+<br><font size="+2">N</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.telephony.TelephonyManager.html#android.telephony.TelephonyManager.NETWORK_TYPE_HSPAP" class="hiddenlink" target="rightframe">NETWORK_TYPE_HSPAP</A>
+</nobr><br>
+<!-- Method newKeyguardLock -->
+<nobr><A HREF="android.app.KeyguardManager.html#android.app.KeyguardManager.newKeyguardLock_changed(java.lang.String)" class="hiddenlink" target="rightframe">newKeyguardLock
+(<code>String</code>)</A></nobr><br>
+<!-- Method onCreateDialog -->
+<A NAME="O"></A>
+<br><font size="+2">O</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.onCreateDialog_changed(int, android.os.Bundle)" class="hiddenlink" target="rightframe">onCreateDialog
+(<code>int, Bundle</code>)</A></nobr><br>
+<!-- Method onPrepareDialog -->
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.onPrepareDialog_changed(int, android.app.Dialog, android.os.Bundle)" class="hiddenlink" target="rightframe">onPrepareDialog
+(<code>int, Dialog, Bundle</code>)</A></nobr><br>
+<!-- Method onRetainNonConfigurationInstance -->
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.onRetainNonConfigurationInstance_changed()" class="hiddenlink" target="rightframe">onRetainNonConfigurationInstance
+()</A></nobr><br>
+<!-- Method onViewCreated -->
+<nobr><A HREF="android.app.Fragment.html#android.app.Fragment.onViewCreated_added(android.view.View, android.os.Bundle)" class="hiddenlink" target="rightframe"><b>onViewCreated</b>
+(<code>View, Bundle</code>)</A></nobr><br>
+<!-- Class PackageManager -->
+<A NAME="P"></A>
+<br><font size="+2">P</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.content.pm.PackageManager.html" class="hiddenlink" target="rightframe">PackageManager</A><br>
+<!-- Class Parcelable.ClassLoaderCreator -->
+<A HREF="pkg_android.os.html#Parcelable.ClassLoaderCreator" class="hiddenlink" target="rightframe"><b><i>Parcelable.ClassLoaderCreator</i></b></A><br>
+<!-- Class ParcelFileDescriptor -->
+<A HREF="android.os.ParcelFileDescriptor.html" class="hiddenlink" target="rightframe">ParcelFileDescriptor</A><br>
+<!-- Class Point -->
+<A HREF="android.graphics.Point.html" class="hiddenlink" target="rightframe">Point</A><br>
+<!-- Class PointF -->
+<A HREF="android.graphics.PointF.html" class="hiddenlink" target="rightframe">PointF</A><br>
+<!-- Class PowerManager -->
+<A HREF="android.os.PowerManager.html" class="hiddenlink" target="rightframe">PowerManager</A><br>
+<!-- Class R.attr -->
+<A NAME="R"></A>
+<br><font size="+2">R</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.R.attr.html" class="hiddenlink" target="rightframe">R.attr</A><br>
+<!-- Class R.style -->
+<A HREF="android.R.style.html" class="hiddenlink" target="rightframe">R.style</A><br>
+<!-- Method readFromParcel -->
+<i>readFromParcel</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.Point.html#android.graphics.Point.readFromParcel_added(android.os.Parcel)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel</code>)</b>&nbsp;in&nbsp;android.graphics.Point
+</A></nobr><br>
+<!-- Method readFromParcel -->
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.PointF.html#android.graphics.PointF.readFromParcel_added(android.os.Parcel)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel</code>)</b>&nbsp;in&nbsp;android.graphics.PointF
+</A></nobr><br>
+<!-- Method removeDialog -->
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.removeDialog_changed(int)" class="hiddenlink" target="rightframe">removeDialog
+(<code>int</code>)</A></nobr><br>
+<!-- Field requiresSmallestWidthDp -->
+<i>requiresSmallestWidthDp</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.R.attr.html#android.R.attr.requiresSmallestWidthDp" class="hiddenlink" target="rightframe">android.R.attr</A>
+</nobr><br>
+<!-- Field requiresSmallestWidthDp -->
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.content.pm.ApplicationInfo.html#android.content.pm.ApplicationInfo.requiresSmallestWidthDp" class="hiddenlink" target="rightframe">android.content.pm.ApplicationInfo</A>
+</nobr><br>
+<!-- Method saveFragmentInstanceState -->
+<A NAME="S"></A>
+<br><font size="+2">S</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.FragmentManager.html#android.app.FragmentManager.saveFragmentInstanceState_added(android.app.Fragment)" class="hiddenlink" target="rightframe"><b>saveFragmentInstanceState</b>
+(<code>Fragment</code>)</A></nobr><br>
+<!-- Field SCREEN_BRIGHT_WAKE_LOCK -->
+<nobr><A HREF="android.os.PowerManager.html#android.os.PowerManager.SCREEN_BRIGHT_WAKE_LOCK" class="hiddenlink" target="rightframe">SCREEN_BRIGHT_WAKE_LOCK</A>
+</nobr><br>
+<!-- Field SCREEN_HEIGHT_DP_UNDEFINED -->
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED" class="hiddenlink" target="rightframe">SCREEN_HEIGHT_DP_UNDEFINED</A>
+</nobr><br>
+<!-- Field SCREEN_WIDTH_DP_UNDEFINED -->
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED" class="hiddenlink" target="rightframe">SCREEN_WIDTH_DP_UNDEFINED</A>
+</nobr><br>
+<!-- Field screenHeightDp -->
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.screenHeightDp" class="hiddenlink" target="rightframe">screenHeightDp</A>
+</nobr><br>
+<!-- Field screenWidthDp -->
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.screenWidthDp" class="hiddenlink" target="rightframe">screenWidthDp</A>
+</nobr><br>
+<!-- Field SET_POINTER_SPEED -->
+<nobr><A HREF="android.Manifest.permission.html#android.Manifest.permission.SET_POINTER_SPEED" class="hiddenlink" target="rightframe">SET_POINTER_SPEED</A>
+</nobr><br>
+<!-- Method setCustomAnimations -->
+<nobr><A HREF="android.app.FragmentTransaction.html#android.app.FragmentTransaction.setCustomAnimations_added(int, int, int, int)" class="hiddenlink" target="rightframe"><b>setCustomAnimations</b>
+(<code>int, int, int, int</code>)</A></nobr><br>
+<!-- Method setInitialSavedState -->
+<nobr><A HREF="android.app.Fragment.html#android.app.Fragment.setInitialSavedState_added(android.app.Fragment.SavedState)" class="hiddenlink" target="rightframe"><b>setInitialSavedState</b>
+(<code>SavedState</code>)</A></nobr><br>
+<!-- Method showDialog -->
+<i>showDialog</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.app.Activity.html#android.app.Activity.showDialog_changed(int, android.os.Bundle)" class="hiddenlink" target="rightframe">type&nbsp;
+(<code>int, Bundle</code>)&nbsp;in&nbsp;android.app.Activity
+</A></nobr><br>
+<!-- Method showDialog -->
+&nbsp;&nbsp;<nobr><A HREF="android.app.Activity.html#android.app.Activity.showDialog_changed(int)" class="hiddenlink" target="rightframe">type&nbsp;
+(<code>int</code>)&nbsp;in&nbsp;android.app.Activity
+</A></nobr><br>
+<!-- Field SMALLEST_SCREEN_WIDTH_DP_UNDEFINED -->
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED" class="hiddenlink" target="rightframe">SMALLEST_SCREEN_WIDTH_DP_UNDEFINED</A>
+</nobr><br>
+<!-- Field smallestScreenWidthDp -->
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.smallestScreenWidthDp" class="hiddenlink" target="rightframe">smallestScreenWidthDp</A>
+</nobr><br>
+<!-- Class TabActivity -->
+<A NAME="T"></A>
+<br><font size="+2">T</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.app.TabActivity.html" class="hiddenlink" target="rightframe">TabActivity</A><br>
+<!-- Class TelephonyManager -->
+<A HREF="android.telephony.TelephonyManager.html" class="hiddenlink" target="rightframe">TelephonyManager</A><br>
+<!-- Field TextAppearance_Holo -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo" class="hiddenlink" target="rightframe">TextAppearance_Holo</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_DialogWindowTitle -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_DialogWindowTitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_DialogWindowTitle</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Inverse -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Inverse</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Large -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Large" class="hiddenlink" target="rightframe">TextAppearance_Holo_Large</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Large_Inverse -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Large_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Large_Inverse</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Medium -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Medium" class="hiddenlink" target="rightframe">TextAppearance_Holo_Medium</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Medium_Inverse -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Medium_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Medium_Inverse</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_SearchResult_Subtitle -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_SearchResult_Subtitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_SearchResult_Subtitle</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_SearchResult_Title -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_SearchResult_Title" class="hiddenlink" target="rightframe">TextAppearance_Holo_SearchResult_Title</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Small -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Small" class="hiddenlink" target="rightframe">TextAppearance_Holo_Small</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Small_Inverse -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Small_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Small_Inverse</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_ActionBar_Subtitle -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionBar_Subtitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionBar_Subtitle</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_ActionBar_Title -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionBar_Title" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionBar_Title</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_ActionMode_Subtitle -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionMode_Subtitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionMode_Subtitle</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_ActionMode_Title -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionMode_Title" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionMode_Title</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_Button -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_Button" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_Button</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_DropDownHint -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_DropDownHint" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_DropDownHint</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_DropDownItem -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_DropDownItem" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_DropDownItem</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_EditText -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_EditText" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_EditText</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_IconMenu_Item -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_IconMenu_Item" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_IconMenu_Item</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_PopupMenu -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_PopupMenu" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_PopupMenu</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_PopupMenu_Large -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_PopupMenu_Large" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_PopupMenu_Large</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_PopupMenu_Small -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_PopupMenu_Small" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_PopupMenu_Small</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_TabWidget -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TabWidget" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TabWidget</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_TextView -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TextView" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TextView</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_TextView_PopupMenu -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TextView_PopupMenu" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TextView_PopupMenu</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_Widget_TextView_SpinnerItem -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TextView_SpinnerItem" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TextView_SpinnerItem</A>
+</nobr><br>
+<!-- Field TextAppearance_Holo_WindowTitle -->
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_WindowTitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_WindowTitle</A>
+</nobr><br>
+<!-- Field Theme_Holo_Light_NoActionBar -->
+<nobr><A HREF="android.R.style.html#android.R.style.Theme_Holo_Light_NoActionBar" class="hiddenlink" target="rightframe">Theme_Holo_Light_NoActionBar</A>
+</nobr><br>
+<!-- Field Theme_Holo_Light_NoActionBar_Fullscreen -->
+<nobr><A HREF="android.R.style.html#android.R.style.Theme_Holo_Light_NoActionBar_Fullscreen" class="hiddenlink" target="rightframe">Theme_Holo_Light_NoActionBar_Fullscreen</A>
+</nobr><br>
+<!-- Field TWEET_TRANSACTION -->
+<nobr><A HREF="android.os.IBinder.html#android.os.IBinder.TWEET_TRANSACTION" class="hiddenlink" target="rightframe">TWEET_TRANSACTION</A>
+</nobr><br>
+<!-- Field TYPE_BLUETOOTH -->
+<nobr><A HREF="android.net.ConnectivityManager.html#android.net.ConnectivityManager.TYPE_BLUETOOTH" class="hiddenlink" target="rightframe">TYPE_BLUETOOTH</A>
+</nobr><br>
+<!-- Field TYPE_ETHERNET -->
+<nobr><A HREF="android.net.ConnectivityManager.html#android.net.ConnectivityManager.TYPE_ETHERNET" class="hiddenlink" target="rightframe">TYPE_ETHERNET</A>
+</nobr><br>
+<!-- Field UI_MODE_TYPE_TELEVISION -->
+<A NAME="U"></A>
+<br><font size="+2">U</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.UI_MODE_TYPE_TELEVISION" class="hiddenlink" target="rightframe">UI_MODE_TYPE_TELEVISION</A>
+</nobr><br>
+<!-- Class UsbDeviceConnection -->
+<A HREF="android.hardware.usb.UsbDeviceConnection.html" class="hiddenlink" target="rightframe">UsbDeviceConnection</A><br>
+<!-- Field Widget_ActionBar_TabBar -->
+<A NAME="W"></A>
+<br><font size="+2">W</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_ActionBar_TabBar" class="hiddenlink" target="rightframe">Widget_ActionBar_TabBar</A>
+</nobr><br>
+<!-- Field Widget_ActionBar_TabText -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_ActionBar_TabText" class="hiddenlink" target="rightframe">Widget_ActionBar_TabText</A>
+</nobr><br>
+<!-- Field Widget_ActionBar_TabView -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_ActionBar_TabView" class="hiddenlink" target="rightframe">Widget_ActionBar_TabView</A>
+</nobr><br>
+<!-- Field Widget_Holo_ActionBar_TabBar -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_ActionBar_TabBar" class="hiddenlink" target="rightframe">Widget_Holo_ActionBar_TabBar</A>
+</nobr><br>
+<!-- Field Widget_Holo_ActionBar_TabText -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_ActionBar_TabText" class="hiddenlink" target="rightframe">Widget_Holo_ActionBar_TabText</A>
+</nobr><br>
+<!-- Field Widget_Holo_ActionBar_TabView -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_ActionBar_TabView" class="hiddenlink" target="rightframe">Widget_Holo_ActionBar_TabView</A>
+</nobr><br>
+<!-- Field Widget_Holo_Light_ActionBar_TabBar -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_Light_ActionBar_TabBar" class="hiddenlink" target="rightframe">Widget_Holo_Light_ActionBar_TabBar</A>
+</nobr><br>
+<!-- Field Widget_Holo_Light_ActionBar_TabText -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_Light_ActionBar_TabText" class="hiddenlink" target="rightframe">Widget_Holo_Light_ActionBar_TabText</A>
+</nobr><br>
+<!-- Field Widget_Holo_Light_ActionBar_TabView -->
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_Light_ActionBar_TabView" class="hiddenlink" target="rightframe">Widget_Holo_Light_ActionBar_TabView</A>
+</nobr><br>
+<!-- Method writeToParcel -->
+<i>writeToParcel</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.Point.html#android.graphics.Point.writeToParcel_added(android.os.Parcel, int)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel, int</code>)</b>&nbsp;in&nbsp;android.graphics.Point
+</A></nobr><br>
+<!-- Method writeToParcel -->
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.PointF.html#android.graphics.PointF.writeToParcel_added(android.os.Parcel, int)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel, int</code>)</b>&nbsp;in&nbsp;android.graphics.PointF
+</A></nobr><br>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/alldiffs_index_changes.html b/docs/html/sdk/api_diff/13/changes/alldiffs_index_changes.html
new file mode 100644
index 000000000000..59e766b646da
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/alldiffs_index_changes.html
@@ -0,0 +1,561 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+All Changes Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for All Differences" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="alldiffs_index_all.html" xclass="hiddenlink">All Differences</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<A HREF="alldiffs_index_additions.html"xclass="hiddenlink">Additions</A>
+ <br>
+<b>Changes</b>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<!-- Class Activity -->
+<A NAME="A"></A>
+<br><font size="+2">A</font>&nbsp;
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.app.Activity.html" class="hiddenlink" target="rightframe">Activity</A><br>
+<!-- Class ActivityGroup -->
+<A HREF="android.app.ActivityGroup.html" class="hiddenlink" target="rightframe">ActivityGroup</A><br>
+<!-- Class ActivityInfo -->
+<A HREF="android.content.pm.ActivityInfo.html" class="hiddenlink" target="rightframe">ActivityInfo</A><br>
+<!-- Package android -->
+<A HREF="pkg_android.html" class="hiddenlink" target="rightframe">android</A><br>
+<!-- Package android.app -->
+<A HREF="pkg_android.app.html" class="hiddenlink" target="rightframe">android.app</A><br>
+<!-- Package android.content.pm -->
+<A HREF="pkg_android.content.pm.html" class="hiddenlink" target="rightframe">android.content.pm</A><br>
+<!-- Package android.content.res -->
+<A HREF="pkg_android.content.res.html" class="hiddenlink" target="rightframe">android.content.res</A><br>
+<!-- Package android.graphics -->
+<A HREF="pkg_android.graphics.html" class="hiddenlink" target="rightframe">android.graphics</A><br>
+<!-- Package android.hardware.usb -->
+<A HREF="pkg_android.hardware.usb.html" class="hiddenlink" target="rightframe">android.hardware.usb</A><br>
+<!-- Package android.net -->
+<A HREF="pkg_android.net.html" class="hiddenlink" target="rightframe">android.net</A><br>
+<!-- Package android.os -->
+<A HREF="pkg_android.os.html" class="hiddenlink" target="rightframe">android.os</A><br>
+<!-- Package android.telephony -->
+<A HREF="pkg_android.telephony.html" class="hiddenlink" target="rightframe">android.telephony</A><br>
+<!-- Package android.util -->
+<A HREF="pkg_android.util.html" class="hiddenlink" target="rightframe">android.util</A><br>
+<!-- Package android.view -->
+<A HREF="pkg_android.view.html" class="hiddenlink" target="rightframe">android.view</A><br>
+<!-- Class ApplicationInfo -->
+<A HREF="android.content.pm.ApplicationInfo.html" class="hiddenlink" target="rightframe">ApplicationInfo</A><br>
+<!-- Class Binder -->
+<A NAME="B"></A>
+<br><font size="+2">B</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.os.Binder.html" class="hiddenlink" target="rightframe">Binder</A><br>
+<!-- Class Build.VERSION_CODES -->
+<A HREF="android.os.Build.VERSION_CODES.html" class="hiddenlink" target="rightframe">Build.VERSION_CODES</A><br>
+<!-- Class Configuration -->
+<A NAME="C"></A>
+<br><font size="+2">C</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.content.res.Configuration.html" class="hiddenlink" target="rightframe">Configuration</A><br>
+<!-- Class ConnectivityManager -->
+<A HREF="android.net.ConnectivityManager.html" class="hiddenlink" target="rightframe">ConnectivityManager</A><br>
+<!-- Method dismissDialog -->
+<A NAME="D"></A>
+<br><font size="+2">D</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.dismissDialog_changed(int)" class="hiddenlink" target="rightframe">dismissDialog
+(<code>int</code>)</A></nobr><br>
+<!-- Class Display -->
+<A HREF="android.view.Display.html" class="hiddenlink" target="rightframe">Display</A><br>
+<!-- Class DisplayMetrics -->
+<A HREF="android.util.DisplayMetrics.html" class="hiddenlink" target="rightframe">DisplayMetrics</A><br>
+<!-- Method exitKeyguardSecurely -->
+<A NAME="E"></A>
+<br><font size="+2">E</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.KeyguardManager.html#android.app.KeyguardManager.exitKeyguardSecurely_changed(android.app.KeyguardManager.OnKeyguardExitResult)" class="hiddenlink" target="rightframe">exitKeyguardSecurely
+(<code>OnKeyguardExitResult</code>)</A></nobr><br>
+<!-- Class Fragment -->
+<A NAME="F"></A>
+<br><font size="+2">F</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.app.Fragment.html" class="hiddenlink" target="rightframe">Fragment</A><br>
+<!-- Class FragmentManager -->
+<A HREF="android.app.FragmentManager.html" class="hiddenlink" target="rightframe">FragmentManager</A><br>
+<!-- Class FragmentTransaction -->
+<A HREF="android.app.FragmentTransaction.html" class="hiddenlink" target="rightframe">FragmentTransaction</A><br>
+<!-- Method getHeight -->
+<A NAME="G"></A>
+<br><font size="+2">G</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.view.Display.html#android.view.Display.getHeight_changed()" class="hiddenlink" target="rightframe">getHeight
+()</A></nobr><br>
+<!-- Method getLastNonConfigurationInstance -->
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.getLastNonConfigurationInstance_changed()" class="hiddenlink" target="rightframe">getLastNonConfigurationInstance
+()</A></nobr><br>
+<!-- Method getWidth -->
+<nobr><A HREF="android.view.Display.html#android.view.Display.getWidth_changed()" class="hiddenlink" target="rightframe">getWidth
+()</A></nobr><br>
+<!-- Class IBinder -->
+<A NAME="I"></A>
+<br><font size="+2">I</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.os.IBinder.html" class="hiddenlink" target="rightframe"><i>IBinder</i></A><br>
+<!-- Class KeyEvent -->
+<A NAME="K"></A>
+<br><font size="+2">K</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.view.KeyEvent.html" class="hiddenlink" target="rightframe">KeyEvent</A><br>
+<!-- Class KeyguardManager -->
+<A HREF="android.app.KeyguardManager.html" class="hiddenlink" target="rightframe">KeyguardManager</A><br>
+<!-- Class KeyguardManager.KeyguardLock -->
+<A HREF="android.app.KeyguardManager.KeyguardLock.html" class="hiddenlink" target="rightframe">KeyguardManager.KeyguardLock</A><br>
+<!-- Class LocalActivityManager -->
+<A NAME="L"></A>
+<br><font size="+2">L</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.app.LocalActivityManager.html" class="hiddenlink" target="rightframe">LocalActivityManager</A><br>
+<!-- Class Manifest.permission -->
+<A NAME="M"></A>
+<br><font size="+2">M</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.Manifest.permission.html" class="hiddenlink" target="rightframe">Manifest.permission</A><br>
+<!-- Method newKeyguardLock -->
+<A NAME="N"></A>
+<br><font size="+2">N</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.KeyguardManager.html#android.app.KeyguardManager.newKeyguardLock_changed(java.lang.String)" class="hiddenlink" target="rightframe">newKeyguardLock
+(<code>String</code>)</A></nobr><br>
+<!-- Method onCreateDialog -->
+<A NAME="O"></A>
+<br><font size="+2">O</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.onCreateDialog_changed(int, android.os.Bundle)" class="hiddenlink" target="rightframe">onCreateDialog
+(<code>int, Bundle</code>)</A></nobr><br>
+<!-- Method onPrepareDialog -->
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.onPrepareDialog_changed(int, android.app.Dialog, android.os.Bundle)" class="hiddenlink" target="rightframe">onPrepareDialog
+(<code>int, Dialog, Bundle</code>)</A></nobr><br>
+<!-- Method onRetainNonConfigurationInstance -->
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.onRetainNonConfigurationInstance_changed()" class="hiddenlink" target="rightframe">onRetainNonConfigurationInstance
+()</A></nobr><br>
+<!-- Class PackageManager -->
+<A NAME="P"></A>
+<br><font size="+2">P</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.content.pm.PackageManager.html" class="hiddenlink" target="rightframe">PackageManager</A><br>
+<!-- Class ParcelFileDescriptor -->
+<A HREF="android.os.ParcelFileDescriptor.html" class="hiddenlink" target="rightframe">ParcelFileDescriptor</A><br>
+<!-- Class Point -->
+<A HREF="android.graphics.Point.html" class="hiddenlink" target="rightframe">Point</A><br>
+<!-- Class PointF -->
+<A HREF="android.graphics.PointF.html" class="hiddenlink" target="rightframe">PointF</A><br>
+<!-- Class PowerManager -->
+<A HREF="android.os.PowerManager.html" class="hiddenlink" target="rightframe">PowerManager</A><br>
+<!-- Class R.attr -->
+<A NAME="R"></A>
+<br><font size="+2">R</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.R.attr.html" class="hiddenlink" target="rightframe">R.attr</A><br>
+<!-- Class R.style -->
+<A HREF="android.R.style.html" class="hiddenlink" target="rightframe">R.style</A><br>
+<!-- Method removeDialog -->
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.removeDialog_changed(int)" class="hiddenlink" target="rightframe">removeDialog
+(<code>int</code>)</A></nobr><br>
+<!-- Field SCREEN_BRIGHT_WAKE_LOCK -->
+<A NAME="S"></A>
+<br><font size="+2">S</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.os.PowerManager.html#android.os.PowerManager.SCREEN_BRIGHT_WAKE_LOCK" class="hiddenlink" target="rightframe">SCREEN_BRIGHT_WAKE_LOCK</A>
+</nobr><br>
+<!-- Method showDialog -->
+<i>showDialog</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.app.Activity.html#android.app.Activity.showDialog_changed(int, android.os.Bundle)" class="hiddenlink" target="rightframe">type&nbsp;
+(<code>int, Bundle</code>)&nbsp;in&nbsp;android.app.Activity
+</A></nobr><br>
+<!-- Method showDialog -->
+&nbsp;&nbsp;<nobr><A HREF="android.app.Activity.html#android.app.Activity.showDialog_changed(int)" class="hiddenlink" target="rightframe">type&nbsp;
+(<code>int</code>)&nbsp;in&nbsp;android.app.Activity
+</A></nobr><br>
+<!-- Class TabActivity -->
+<A NAME="T"></A>
+<br><font size="+2">T</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.app.TabActivity.html" class="hiddenlink" target="rightframe">TabActivity</A><br>
+<!-- Class TelephonyManager -->
+<A HREF="android.telephony.TelephonyManager.html" class="hiddenlink" target="rightframe">TelephonyManager</A><br>
+<!-- Class UsbDeviceConnection -->
+<A NAME="U"></A>
+<br><font size="+2">U</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.hardware.usb.UsbDeviceConnection.html" class="hiddenlink" target="rightframe">UsbDeviceConnection</A><br>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/alldiffs_index_removals.html b/docs/html/sdk/api_diff/13/changes/alldiffs_index_removals.html
new file mode 100644
index 000000000000..68d2c20bf961
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/alldiffs_index_removals.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+All Removals Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for All Differences" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="alldiffs_index_all.html" xclass="hiddenlink">All Differences</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<A HREF="alldiffs_index_additions.html"xclass="hiddenlink">Additions</A>
+ <br>
+<A HREF="alldiffs_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.Manifest.permission.html b/docs/html/sdk/api_diff/13/changes/android.Manifest.permission.html
new file mode 100644
index 000000000000..5d3cbda66bf1
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.Manifest.permission.html
@@ -0,0 +1,122 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.Manifest.permission
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.<A HREF="../../../../reference/android/Manifest.permission.html" target="_top"><font size="+2"><code>Manifest.permission</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.Manifest.permission.SET_POINTER_SPEED"></A>
+ <nobr><code>String</code>&nbsp;<A HREF="../../../../reference/android/Manifest.permission.html#SET_POINTER_SPEED" target="_top"><code>SET_POINTER_SPEED</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.R.attr.html b/docs/html/sdk/api_diff/13/changes/android.R.attr.html
new file mode 100644
index 000000000000..f8eb54b16ada
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.R.attr.html
@@ -0,0 +1,136 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.R.attr
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.<A HREF="../../../../reference/android/R.attr.html" target="_top"><font size="+2"><code>R.attr</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.attr.compatibleWidthLimitDp"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.attr.html#compatibleWidthLimitDp" target="_top"><code>compatibleWidthLimitDp</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.attr.largestWidthLimitDp"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.attr.html#largestWidthLimitDp" target="_top"><code>largestWidthLimitDp</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.attr.requiresSmallestWidthDp"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.attr.html#requiresSmallestWidthDp" target="_top"><code>requiresSmallestWidthDp</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.R.style.html b/docs/html/sdk/api_diff/13/changes/android.R.style.html
new file mode 100644
index 000000000000..9e385e2364a4
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.R.style.html
@@ -0,0 +1,395 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.R.style
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.<A HREF="../../../../reference/android/R.style.html" target="_top"><font size="+2"><code>R.style</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo" target="_top"><code>TextAppearance_Holo</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_DialogWindowTitle"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_DialogWindowTitle" target="_top"><code>TextAppearance_Holo_DialogWindowTitle</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Inverse"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Inverse" target="_top"><code>TextAppearance_Holo_Inverse</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Large"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Large" target="_top"><code>TextAppearance_Holo_Large</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Large_Inverse"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Large_Inverse" target="_top"><code>TextAppearance_Holo_Large_Inverse</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Medium"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Medium" target="_top"><code>TextAppearance_Holo_Medium</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Medium_Inverse"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Medium_Inverse" target="_top"><code>TextAppearance_Holo_Medium_Inverse</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_SearchResult_Subtitle"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_SearchResult_Subtitle" target="_top"><code>TextAppearance_Holo_SearchResult_Subtitle</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_SearchResult_Title"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_SearchResult_Title" target="_top"><code>TextAppearance_Holo_SearchResult_Title</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Small"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Small" target="_top"><code>TextAppearance_Holo_Small</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Small_Inverse"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Small_Inverse" target="_top"><code>TextAppearance_Holo_Small_Inverse</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget" target="_top"><code>TextAppearance_Holo_Widget</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_ActionBar_Subtitle"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_ActionBar_Subtitle" target="_top"><code>TextAppearance_Holo_Widget_ActionBar_Subtitle</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_ActionBar_Title"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_ActionBar_Title" target="_top"><code>TextAppearance_Holo_Widget_ActionBar_Title</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_ActionMode_Subtitle"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_ActionMode_Subtitle" target="_top"><code>TextAppearance_Holo_Widget_ActionMode_Subtitle</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_ActionMode_Title"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_ActionMode_Title" target="_top"><code>TextAppearance_Holo_Widget_ActionMode_Title</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_Button"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_Button" target="_top"><code>TextAppearance_Holo_Widget_Button</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_DropDownHint"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_DropDownHint" target="_top"><code>TextAppearance_Holo_Widget_DropDownHint</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_DropDownItem"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_DropDownItem" target="_top"><code>TextAppearance_Holo_Widget_DropDownItem</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_EditText"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_EditText" target="_top"><code>TextAppearance_Holo_Widget_EditText</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_IconMenu_Item"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_IconMenu_Item" target="_top"><code>TextAppearance_Holo_Widget_IconMenu_Item</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_PopupMenu"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_PopupMenu" target="_top"><code>TextAppearance_Holo_Widget_PopupMenu</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_PopupMenu_Large"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_PopupMenu_Large" target="_top"><code>TextAppearance_Holo_Widget_PopupMenu_Large</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_PopupMenu_Small"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_PopupMenu_Small" target="_top"><code>TextAppearance_Holo_Widget_PopupMenu_Small</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_TabWidget"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_TabWidget" target="_top"><code>TextAppearance_Holo_Widget_TabWidget</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_TextView"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_TextView" target="_top"><code>TextAppearance_Holo_Widget_TextView</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_TextView_PopupMenu"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_TextView_PopupMenu" target="_top"><code>TextAppearance_Holo_Widget_TextView_PopupMenu</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_Widget_TextView_SpinnerItem"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_Widget_TextView_SpinnerItem" target="_top"><code>TextAppearance_Holo_Widget_TextView_SpinnerItem</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.TextAppearance_Holo_WindowTitle"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#TextAppearance_Holo_WindowTitle" target="_top"><code>TextAppearance_Holo_WindowTitle</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.Theme_Holo_Light_NoActionBar"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#Theme_Holo_Light_NoActionBar" target="_top"><code>Theme_Holo_Light_NoActionBar</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.Theme_Holo_Light_NoActionBar_Fullscreen"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#Theme_Holo_Light_NoActionBar_Fullscreen" target="_top"><code>Theme_Holo_Light_NoActionBar_Fullscreen</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.Widget_ActionBar_TabBar"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#Widget_ActionBar_TabBar" target="_top"><code>Widget_ActionBar_TabBar</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.Widget_ActionBar_TabText"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#Widget_ActionBar_TabText" target="_top"><code>Widget_ActionBar_TabText</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.Widget_ActionBar_TabView"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#Widget_ActionBar_TabView" target="_top"><code>Widget_ActionBar_TabView</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.Widget_Holo_ActionBar_TabBar"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#Widget_Holo_ActionBar_TabBar" target="_top"><code>Widget_Holo_ActionBar_TabBar</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.Widget_Holo_ActionBar_TabText"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#Widget_Holo_ActionBar_TabText" target="_top"><code>Widget_Holo_ActionBar_TabText</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.Widget_Holo_ActionBar_TabView"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#Widget_Holo_ActionBar_TabView" target="_top"><code>Widget_Holo_ActionBar_TabView</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.Widget_Holo_Light_ActionBar_TabBar"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#Widget_Holo_Light_ActionBar_TabBar" target="_top"><code>Widget_Holo_Light_ActionBar_TabBar</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.Widget_Holo_Light_ActionBar_TabText"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#Widget_Holo_Light_ActionBar_TabText" target="_top"><code>Widget_Holo_Light_ActionBar_TabText</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.R.style.Widget_Holo_Light_ActionBar_TabView"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/R.style.html#Widget_Holo_Light_ActionBar_TabView" target="_top"><code>Widget_Holo_Light_ActionBar_TabView</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.app.Activity.html b/docs/html/sdk/api_diff/13/changes/android.app.Activity.html
new file mode 100644
index 000000000000..b27816b10360
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.app.Activity.html
@@ -0,0 +1,195 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.app.Activity
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.app.<A HREF="../../../../reference/android/app/Activity.html" target="_top"><font size="+2"><code>Activity</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Methods" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=3>Changed Methods</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.Activity.dismissDialog_changed(int)"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/app/Activity.html#dismissDialog(int)" target="_top"><code>dismissDialog</code></A>(<code>int</code>) </nobr>
+ </TD>
+ <TD VALIGN="TOP" WIDTH="30%">
+<b>Now deprecated</b>.<br>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.Activity.getLastNonConfigurationInstance_changed()"></A>
+ <nobr><code>Object</code>&nbsp;<A HREF="../../../../reference/android/app/Activity.html#getLastNonConfigurationInstance()" target="_top"><code>getLastNonConfigurationInstance</code></A>() </nobr>
+ </TD>
+ <TD VALIGN="TOP" WIDTH="30%">
+<b>Now deprecated</b>.<br>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.Activity.onRetainNonConfigurationInstance_changed()"></A>
+ <nobr><code>Object</code>&nbsp;<A HREF="../../../../reference/android/app/Activity.html#onRetainNonConfigurationInstance()" target="_top"><code>onRetainNonConfigurationInstance</code></A>() </nobr>
+ </TD>
+ <TD VALIGN="TOP" WIDTH="30%">
+<b>Now deprecated</b>.<br>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.Activity.removeDialog_changed(int)"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/app/Activity.html#removeDialog(int)" target="_top"><code>removeDialog</code></A>(<code>int</code>) </nobr>
+ </TD>
+ <TD VALIGN="TOP" WIDTH="30%">
+<b>Now deprecated</b>.<br>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.Activity.onCreateDialog_changed(int, android.os.Bundle)"></A>
+ <nobr><code>Dialog</code>&nbsp;<A HREF="../../../../reference/android/app/Activity.html#onCreateDialog(int, android.os.Bundle)" target="_top"><code>onCreateDialog</code></A>(<code>int,</nobr> Bundle<nobr><nobr></code>) </nobr>
+ </TD>
+ <TD VALIGN="TOP" WIDTH="30%">
+<b>Now deprecated</b>.<br>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.Activity.onPrepareDialog_changed(int, android.app.Dialog, android.os.Bundle)"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/app/Activity.html#onPrepareDialog(int, android.app.Dialog, android.os.Bundle)" target="_top"><code>onPrepareDialog</code></A>(<code>int,</nobr> Dialog<nobr>,</nobr> Bundle<nobr><nobr></code>) </nobr>
+ </TD>
+ <TD VALIGN="TOP" WIDTH="30%">
+<b>Now deprecated</b>.<br>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.Activity.showDialog_changed(int, android.os.Bundle)"></A>
+ <nobr><code>boolean</code>&nbsp;<A HREF="../../../../reference/android/app/Activity.html#showDialog(int, android.os.Bundle)" target="_top"><code>showDialog</code></A>(<code>int,</nobr> Bundle<nobr><nobr></code>) </nobr>
+ </TD>
+ <TD VALIGN="TOP" WIDTH="30%">
+<b>Now deprecated</b>.<br>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.Activity.showDialog_changed(int)"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/app/Activity.html#showDialog(int)" target="_top"><code>showDialog</code></A>(<code>int</code>) </nobr>
+ </TD>
+ <TD VALIGN="TOP" WIDTH="30%">
+<b>Now deprecated</b>.<br>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<a NAME="fields"></a>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.app.ActivityGroup.html b/docs/html/sdk/api_diff/13/changes/android.app.ActivityGroup.html
new file mode 100644
index 000000000000..c755228eb6a9
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.app.ActivityGroup.html
@@ -0,0 +1,108 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.app.ActivityGroup
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.app.<A HREF="../../../../reference/android/app/ActivityGroup.html" target="_top"><font size="+2"><code>ActivityGroup</code></font></A>
+</H2>
+<p><b>Now deprecated</b>.<br>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.app.Fragment.html b/docs/html/sdk/api_diff/13/changes/android.app.Fragment.html
new file mode 100644
index 000000000000..074d4b31592d
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.app.Fragment.html
@@ -0,0 +1,136 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.app.Fragment
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.app.<A HREF="../../../../reference/android/app/Fragment.html" target="_top"><font size="+2"><code>Fragment</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Methods" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.Fragment.isDetached_added()"></A>
+ <nobr><code>boolean</code>&nbsp;<A HREF="../../../../reference/android/app/Fragment.html#isDetached()" target="_top"><code>isDetached</code></A>()</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.Fragment.onViewCreated_added(android.view.View, android.os.Bundle)"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/app/Fragment.html#onViewCreated(android.view.View, android.os.Bundle)" target="_top"><code>onViewCreated</code></A>(<code>View,</nobr> Bundle<nobr><nobr></code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.Fragment.setInitialSavedState_added(android.app.Fragment.SavedState)"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/app/Fragment.html#setInitialSavedState(android.app.Fragment.SavedState)" target="_top"><code>setInitialSavedState</code></A>(<code>SavedState</code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<a NAME="fields"></a>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.app.FragmentManager.html b/docs/html/sdk/api_diff/13/changes/android.app.FragmentManager.html
new file mode 100644
index 000000000000..159b9c9918d6
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.app.FragmentManager.html
@@ -0,0 +1,122 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.app.FragmentManager
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.app.<A HREF="../../../../reference/android/app/FragmentManager.html" target="_top"><font size="+2"><code>FragmentManager</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Methods" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.FragmentManager.saveFragmentInstanceState_added(android.app.Fragment)"></A>
+ <nobr><code>SavedState</code>&nbsp;<A HREF="../../../../reference/android/app/FragmentManager.html#saveFragmentInstanceState(android.app.Fragment)" target="_top"><code>saveFragmentInstanceState</code></A>(<code>Fragment</code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<a NAME="fields"></a>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.app.FragmentTransaction.html b/docs/html/sdk/api_diff/13/changes/android.app.FragmentTransaction.html
new file mode 100644
index 000000000000..dbb7deb12014
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.app.FragmentTransaction.html
@@ -0,0 +1,136 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.app.FragmentTransaction
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.app.<A HREF="../../../../reference/android/app/FragmentTransaction.html" target="_top"><font size="+2"><code>FragmentTransaction</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Methods" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.FragmentTransaction.attach_added(android.app.Fragment)"></A>
+ <nobr><code>FragmentTransaction</code>&nbsp;<A HREF="../../../../reference/android/app/FragmentTransaction.html#attach(android.app.Fragment)" target="_top"><code>attach</code></A>(<code>Fragment</code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.FragmentTransaction.detach_added(android.app.Fragment)"></A>
+ <nobr><code>FragmentTransaction</code>&nbsp;<A HREF="../../../../reference/android/app/FragmentTransaction.html#detach(android.app.Fragment)" target="_top"><code>detach</code></A>(<code>Fragment</code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.FragmentTransaction.setCustomAnimations_added(int, int, int, int)"></A>
+ <nobr><code>FragmentTransaction</code>&nbsp;<A HREF="../../../../reference/android/app/FragmentTransaction.html#setCustomAnimations(int, int, int, int)" target="_top"><code>setCustomAnimations</code></A>(<code>int,</nobr> int<nobr>,</nobr> int<nobr>,</nobr> int<nobr><nobr></code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<a NAME="fields"></a>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.app.KeyguardManager.KeyguardLock.html b/docs/html/sdk/api_diff/13/changes/android.app.KeyguardManager.KeyguardLock.html
new file mode 100644
index 000000000000..3ae02ea97b76
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.app.KeyguardManager.KeyguardLock.html
@@ -0,0 +1,108 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.app.KeyguardManager.KeyguardLock
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.app.<A HREF="../../../../reference/android/app/KeyguardManager.KeyguardLock.html" target="_top"><font size="+2"><code>KeyguardManager.KeyguardLock</code></font></A>
+</H2>
+<p><b>Now deprecated</b>.<br>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.app.KeyguardManager.html b/docs/html/sdk/api_diff/13/changes/android.app.KeyguardManager.html
new file mode 100644
index 000000000000..bc38771c0641
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.app.KeyguardManager.html
@@ -0,0 +1,135 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.app.KeyguardManager
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.app.<A HREF="../../../../reference/android/app/KeyguardManager.html" target="_top"><font size="+2"><code>KeyguardManager</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Methods" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=3>Changed Methods</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.KeyguardManager.exitKeyguardSecurely_changed(android.app.KeyguardManager.OnKeyguardExitResult)"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/app/KeyguardManager.html#exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult)" target="_top"><code>exitKeyguardSecurely</code></A>(<code>OnKeyguardExitResult</code>) </nobr>
+ </TD>
+ <TD VALIGN="TOP" WIDTH="30%">
+<b>Now deprecated</b>.<br>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app.KeyguardManager.newKeyguardLock_changed(java.lang.String)"></A>
+ <nobr><code>KeyguardLock</code>&nbsp;<A HREF="../../../../reference/android/app/KeyguardManager.html#newKeyguardLock(java.lang.String)" target="_top"><code>newKeyguardLock</code></A>(<code>String</code>) </nobr>
+ </TD>
+ <TD VALIGN="TOP" WIDTH="30%">
+<b>Now deprecated</b>.<br>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<a NAME="fields"></a>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.app.LocalActivityManager.html b/docs/html/sdk/api_diff/13/changes/android.app.LocalActivityManager.html
new file mode 100644
index 000000000000..4ea08489c173
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.app.LocalActivityManager.html
@@ -0,0 +1,108 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.app.LocalActivityManager
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.app.<A HREF="../../../../reference/android/app/LocalActivityManager.html" target="_top"><font size="+2"><code>LocalActivityManager</code></font></A>
+</H2>
+<p><b>Now deprecated</b>.<br>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.app.TabActivity.html b/docs/html/sdk/api_diff/13/changes/android.app.TabActivity.html
new file mode 100644
index 000000000000..405f7d8e3f9b
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.app.TabActivity.html
@@ -0,0 +1,108 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.app.TabActivity
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.app.<A HREF="../../../../reference/android/app/TabActivity.html" target="_top"><font size="+2"><code>TabActivity</code></font></A>
+</H2>
+<p><b>Now deprecated</b>.<br>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.content.pm.ActivityInfo.html b/docs/html/sdk/api_diff/13/changes/android.content.pm.ActivityInfo.html
new file mode 100644
index 000000000000..70149a3ddc91
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.content.pm.ActivityInfo.html
@@ -0,0 +1,129 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.content.pm.ActivityInfo
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.content.pm.<A HREF="../../../../reference/android/content/pm/ActivityInfo.html" target="_top"><font size="+2"><code>ActivityInfo</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/content/pm/ActivityInfo.html#CONFIG_SCREEN_SIZE" target="_top"><code>CONFIG_SCREEN_SIZE</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/content/pm/ActivityInfo.html#CONFIG_SMALLEST_SCREEN_SIZE" target="_top"><code>CONFIG_SMALLEST_SCREEN_SIZE</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.content.pm.ApplicationInfo.html b/docs/html/sdk/api_diff/13/changes/android.content.pm.ApplicationInfo.html
new file mode 100644
index 000000000000..4aef49274ca0
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.content.pm.ApplicationInfo.html
@@ -0,0 +1,136 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.content.pm.ApplicationInfo
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.content.pm.<A HREF="../../../../reference/android/content/pm/ApplicationInfo.html" target="_top"><font size="+2"><code>ApplicationInfo</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.pm.ApplicationInfo.compatibleWidthLimitDp"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/content/pm/ApplicationInfo.html#compatibleWidthLimitDp" target="_top"><code>compatibleWidthLimitDp</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.pm.ApplicationInfo.largestWidthLimitDp"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/content/pm/ApplicationInfo.html#largestWidthLimitDp" target="_top"><code>largestWidthLimitDp</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.pm.ApplicationInfo.requiresSmallestWidthDp"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/content/pm/ApplicationInfo.html#requiresSmallestWidthDp" target="_top"><code>requiresSmallestWidthDp</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.content.pm.PackageManager.html b/docs/html/sdk/api_diff/13/changes/android.content.pm.PackageManager.html
new file mode 100644
index 000000000000..ca75d7abf3f1
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.content.pm.PackageManager.html
@@ -0,0 +1,143 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.content.pm.PackageManager
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.content.pm.<A HREF="../../../../reference/android/content/pm/PackageManager.html" target="_top"><font size="+2"><code>PackageManager</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.pm.PackageManager.FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT"></A>
+ <nobr><code>String</code>&nbsp;<A HREF="../../../../reference/android/content/pm/PackageManager.html#FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT" target="_top"><code>FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.pm.PackageManager.FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND"></A>
+ <nobr><code>String</code>&nbsp;<A HREF="../../../../reference/android/content/pm/PackageManager.html#FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND" target="_top"><code>FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.pm.PackageManager.FEATURE_SCREEN_LANDSCAPE"></A>
+ <nobr><code>String</code>&nbsp;<A HREF="../../../../reference/android/content/pm/PackageManager.html#FEATURE_SCREEN_LANDSCAPE" target="_top"><code>FEATURE_SCREEN_LANDSCAPE</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.pm.PackageManager.FEATURE_SCREEN_PORTRAIT"></A>
+ <nobr><code>String</code>&nbsp;<A HREF="../../../../reference/android/content/pm/PackageManager.html#FEATURE_SCREEN_PORTRAIT" target="_top"><code>FEATURE_SCREEN_PORTRAIT</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.content.res.Configuration.html b/docs/html/sdk/api_diff/13/changes/android.content.res.Configuration.html
new file mode 100644
index 000000000000..110a14288db9
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.content.res.Configuration.html
@@ -0,0 +1,164 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.content.res.Configuration
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.content.res.<A HREF="../../../../reference/android/content/res/Configuration.html" target="_top"><font size="+2"><code>Configuration</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/content/res/Configuration.html#SCREEN_HEIGHT_DP_UNDEFINED" target="_top"><code>SCREEN_HEIGHT_DP_UNDEFINED</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/content/res/Configuration.html#SCREEN_WIDTH_DP_UNDEFINED" target="_top"><code>SCREEN_WIDTH_DP_UNDEFINED</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/content/res/Configuration.html#SMALLEST_SCREEN_WIDTH_DP_UNDEFINED" target="_top"><code>SMALLEST_SCREEN_WIDTH_DP_UNDEFINED</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.res.Configuration.UI_MODE_TYPE_TELEVISION"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/content/res/Configuration.html#UI_MODE_TYPE_TELEVISION" target="_top"><code>UI_MODE_TYPE_TELEVISION</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.res.Configuration.screenHeightDp"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/content/res/Configuration.html#screenHeightDp" target="_top"><code>screenHeightDp</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.res.Configuration.screenWidthDp"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/content/res/Configuration.html#screenWidthDp" target="_top"><code>screenWidthDp</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.res.Configuration.smallestScreenWidthDp"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/content/res/Configuration.html#smallestScreenWidthDp" target="_top"><code>smallestScreenWidthDp</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.graphics.Point.html b/docs/html/sdk/api_diff/13/changes/android.graphics.Point.html
new file mode 100644
index 000000000000..e3324d2cf47b
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.graphics.Point.html
@@ -0,0 +1,152 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.graphics.Point
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.graphics.<A HREF="../../../../reference/android/graphics/Point.html" target="_top"><font size="+2"><code>Point</code></font></A>
+</H2>
+<p><font xsize="+1">Added interface <code>android.os.Parcelable</code>.<br></font>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Methods" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.graphics.Point.describeContents_added()"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/graphics/Point.html#describeContents()" target="_top"><code>describeContents</code></A>()</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.graphics.Point.readFromParcel_added(android.os.Parcel)"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/graphics/Point.html#readFromParcel(android.os.Parcel)" target="_top"><code>readFromParcel</code></A>(<code>Parcel</code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.graphics.Point.writeToParcel_added(android.os.Parcel, int)"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/graphics/Point.html#writeToParcel(android.os.Parcel, int)" target="_top"><code>writeToParcel</code></A>(<code>Parcel,</nobr> int<nobr><nobr></code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<a NAME="fields"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.graphics.Point.CREATOR"></A>
+ <nobr><code>Creator</code>&nbsp;<A HREF="../../../../reference/android/graphics/Point.html#CREATOR" target="_top"><code>CREATOR</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.graphics.PointF.html b/docs/html/sdk/api_diff/13/changes/android.graphics.PointF.html
new file mode 100644
index 000000000000..665c2590cafe
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.graphics.PointF.html
@@ -0,0 +1,152 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.graphics.PointF
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.graphics.<A HREF="../../../../reference/android/graphics/PointF.html" target="_top"><font size="+2"><code>PointF</code></font></A>
+</H2>
+<p><font xsize="+1">Added interface <code>android.os.Parcelable</code>.<br></font>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Methods" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.graphics.PointF.describeContents_added()"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/graphics/PointF.html#describeContents()" target="_top"><code>describeContents</code></A>()</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.graphics.PointF.readFromParcel_added(android.os.Parcel)"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/graphics/PointF.html#readFromParcel(android.os.Parcel)" target="_top"><code>readFromParcel</code></A>(<code>Parcel</code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.graphics.PointF.writeToParcel_added(android.os.Parcel, int)"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/graphics/PointF.html#writeToParcel(android.os.Parcel, int)" target="_top"><code>writeToParcel</code></A>(<code>Parcel,</nobr> int<nobr><nobr></code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<a NAME="fields"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.graphics.PointF.CREATOR"></A>
+ <nobr><code>Creator</code>&nbsp;<A HREF="../../../../reference/android/graphics/PointF.html#CREATOR" target="_top"><code>CREATOR</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.hardware.usb.UsbDeviceConnection.html b/docs/html/sdk/api_diff/13/changes/android.hardware.usb.UsbDeviceConnection.html
new file mode 100644
index 000000000000..1eb15ed0734d
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.hardware.usb.UsbDeviceConnection.html
@@ -0,0 +1,122 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.hardware.usb.UsbDeviceConnection
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.hardware.usb.<A HREF="../../../../reference/android/hardware/usb/UsbDeviceConnection.html" target="_top"><font size="+2"><code>UsbDeviceConnection</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Methods" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.hardware.usb.UsbDeviceConnection.getRawDescriptors_added()"></A>
+ <nobr><code>byte[]</code>&nbsp;<A HREF="../../../../reference/android/hardware/usb/UsbDeviceConnection.html#getRawDescriptors()" target="_top"><code>getRawDescriptors</code></A>()</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<a NAME="fields"></a>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.net.ConnectivityManager.html b/docs/html/sdk/api_diff/13/changes/android.net.ConnectivityManager.html
new file mode 100644
index 000000000000..977649fad264
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.net.ConnectivityManager.html
@@ -0,0 +1,129 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.net.ConnectivityManager
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.net.<A HREF="../../../../reference/android/net/ConnectivityManager.html" target="_top"><font size="+2"><code>ConnectivityManager</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.net.ConnectivityManager.TYPE_BLUETOOTH"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/net/ConnectivityManager.html#TYPE_BLUETOOTH" target="_top"><code>TYPE_BLUETOOTH</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.net.ConnectivityManager.TYPE_ETHERNET"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/net/ConnectivityManager.html#TYPE_ETHERNET" target="_top"><code>TYPE_ETHERNET</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.os.Binder.html b/docs/html/sdk/api_diff/13/changes/android.os.Binder.html
new file mode 100644
index 000000000000..fd11dd1c1e39
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.os.Binder.html
@@ -0,0 +1,122 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.os.Binder
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.os.<A HREF="../../../../reference/android/os/Binder.html" target="_top"><font size="+2"><code>Binder</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Methods" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.os.Binder.dumpAsync_added(java.io.FileDescriptor, java.lang.String[])"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/os/Binder.html#dumpAsync(java.io.FileDescriptor, java.lang.String[])" target="_top"><code>dumpAsync</code></A>(<code>FileDescriptor,</nobr> String[]<nobr><nobr></code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<a NAME="fields"></a>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.os.Build.VERSION_CODES.html b/docs/html/sdk/api_diff/13/changes/android.os.Build.VERSION_CODES.html
new file mode 100644
index 000000000000..0e50af4f3722
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.os.Build.VERSION_CODES.html
@@ -0,0 +1,122 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.os.Build.VERSION_CODES
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.os.<A HREF="../../../../reference/android/os/Build.VERSION_CODES.html" target="_top"><font size="+2"><code>Build.VERSION_CODES</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.os.Build.VERSION_CODES.HONEYCOMB_MR2"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/os/Build.VERSION_CODES.html#HONEYCOMB_MR2" target="_top"><code>HONEYCOMB_MR2</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.os.IBinder.html b/docs/html/sdk/api_diff/13/changes/android.os.IBinder.html
new file mode 100644
index 000000000000..1a251cd30cb2
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.os.IBinder.html
@@ -0,0 +1,137 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.os.IBinder
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Interface android.os.<A HREF="../../../../reference/android/os/IBinder.html" target="_top"><font size="+2"><code>IBinder</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Methods" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.os.IBinder.dumpAsync_added(java.io.FileDescriptor, java.lang.String[])"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/os/IBinder.html#dumpAsync(java.io.FileDescriptor, java.lang.String[])" target="_top"><code>dumpAsync</code></A>(<code>FileDescriptor,</nobr> String[]<nobr><nobr></code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<a NAME="fields"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.os.IBinder.TWEET_TRANSACTION"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/os/IBinder.html#TWEET_TRANSACTION" target="_top"><code>TWEET_TRANSACTION</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.os.ParcelFileDescriptor.html b/docs/html/sdk/api_diff/13/changes/android.os.ParcelFileDescriptor.html
new file mode 100644
index 000000000000..3d3d1c3e078e
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.os.ParcelFileDescriptor.html
@@ -0,0 +1,136 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.os.ParcelFileDescriptor
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.os.<A HREF="../../../../reference/android/os/ParcelFileDescriptor.html" target="_top"><font size="+2"><code>ParcelFileDescriptor</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Methods" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.os.ParcelFileDescriptor.adoptFd_added(int)"></A>
+ <nobr><code>ParcelFileDescriptor</code>&nbsp;<A HREF="../../../../reference/android/os/ParcelFileDescriptor.html#adoptFd(int)" target="_top"><code>adoptFd</code></A>(<code>int</code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.os.ParcelFileDescriptor.dup_added(java.io.FileDescriptor)"></A>
+ <nobr><code>ParcelFileDescriptor</code>&nbsp;<A HREF="../../../../reference/android/os/ParcelFileDescriptor.html#dup(java.io.FileDescriptor)" target="_top"><code>dup</code></A>(<code>FileDescriptor</code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.os.ParcelFileDescriptor.fromFd_added(int)"></A>
+ <nobr><code>ParcelFileDescriptor</code>&nbsp;<A HREF="../../../../reference/android/os/ParcelFileDescriptor.html#fromFd(int)" target="_top"><code>fromFd</code></A>(<code>int</code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<a NAME="fields"></a>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.os.PowerManager.html b/docs/html/sdk/api_diff/13/changes/android.os.PowerManager.html
new file mode 100644
index 000000000000..4af746da801b
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.os.PowerManager.html
@@ -0,0 +1,124 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.os.PowerManager
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.os.<A HREF="../../../../reference/android/os/PowerManager.html" target="_top"><font size="+2"><code>PowerManager</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=3>Changed Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.os.PowerManager.SCREEN_BRIGHT_WAKE_LOCK"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/os/PowerManager.html#SCREEN_BRIGHT_WAKE_LOCK" target="_top"><code>SCREEN_BRIGHT_WAKE_LOCK</code></font></A></nobr> </TD>
+ <TD VALIGN="TOP" WIDTH="30%">
+<b>Now deprecated</b>.<br>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.telephony.TelephonyManager.html b/docs/html/sdk/api_diff/13/changes/android.telephony.TelephonyManager.html
new file mode 100644
index 000000000000..43d6cf64a6eb
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.telephony.TelephonyManager.html
@@ -0,0 +1,122 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.telephony.TelephonyManager
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.telephony.<A HREF="../../../../reference/android/telephony/TelephonyManager.html" target="_top"><font size="+2"><code>TelephonyManager</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.telephony.TelephonyManager.NETWORK_TYPE_HSPAP"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/telephony/TelephonyManager.html#NETWORK_TYPE_HSPAP" target="_top"><code>NETWORK_TYPE_HSPAP</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.util.DisplayMetrics.html b/docs/html/sdk/api_diff/13/changes/android.util.DisplayMetrics.html
new file mode 100644
index 000000000000..01c329f6b3f0
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.util.DisplayMetrics.html
@@ -0,0 +1,122 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.util.DisplayMetrics
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.util.<A HREF="../../../../reference/android/util/DisplayMetrics.html" target="_top"><font size="+2"><code>DisplayMetrics</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<a NAME="fields"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Fields" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Fields</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.util.DisplayMetrics.DENSITY_TV"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/util/DisplayMetrics.html#DENSITY_TV" target="_top"><code>DENSITY_TV</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.view.Display.html b/docs/html/sdk/api_diff/13/changes/android.view.Display.html
new file mode 100644
index 000000000000..872532a88412
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.view.Display.html
@@ -0,0 +1,157 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.view.Display
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.view.<A HREF="../../../../reference/android/view/Display.html" target="_top"><font size="+2"><code>Display</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Methods" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.view.Display.getRectSize_added(android.graphics.Rect)"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/view/Display.html#getRectSize(android.graphics.Rect)" target="_top"><code>getRectSize</code></A>(<code>Rect</code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.view.Display.getSize_added(android.graphics.Point)"></A>
+ <nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/view/Display.html#getSize(android.graphics.Point)" target="_top"><code>getSize</code></A>(<code>Point</code>)</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Methods" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=3>Changed Methods</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.view.Display.getHeight_changed()"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/view/Display.html#getHeight()" target="_top"><code>getHeight</code></A>() </nobr>
+ </TD>
+ <TD VALIGN="TOP" WIDTH="30%">
+<b>Now deprecated</b>.<br>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.view.Display.getWidth_changed()"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/view/Display.html#getWidth()" target="_top"><code>getWidth</code></A>() </nobr>
+ </TD>
+ <TD VALIGN="TOP" WIDTH="30%">
+<b>Now deprecated</b>.<br>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<a NAME="fields"></a>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/android.view.KeyEvent.html b/docs/html/sdk/api_diff/13/changes/android.view.KeyEvent.html
new file mode 100644
index 000000000000..eaccac4a35c6
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/android.view.KeyEvent.html
@@ -0,0 +1,122 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.view.KeyEvent
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Class android.view.<A HREF="../../../../reference/android/view/KeyEvent.html" target="_top"><font size="+2"><code>KeyEvent</code></font></A>
+</H2>
+<a NAME="constructors"></a>
+<a NAME="methods"></a>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Methods" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.view.KeyEvent.getModifiers_added()"></A>
+ <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/view/KeyEvent.html#getModifiers()" target="_top"><code>getModifiers</code></A>()</nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<a NAME="fields"></a>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/changes-summary.html b/docs/html/sdk/api_diff/13/changes/changes-summary.html
new file mode 100644
index 000000000000..082fcfb64abc
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/changes-summary.html
@@ -0,0 +1,205 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Android API Differences Report
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<body class="gc-documentation">
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+ <div id="docTitleContainer">
+<h1>Android&nbsp;API&nbsp;Differences&nbsp;Report</h1>
+<p>This report details the changes in the core Android framework API between two <a
+href="http://developer.android.com/guide/appendix/api-levels.html" target="_top">API Level</a>
+specifications. It shows additions, modifications, and removals for packages, classes, methods, and fields.
+The report also includes general statistics that characterize the extent and type of the differences.</p>
+<p>This report is based a comparison of the Android API specifications
+whose API Level identifiers are given in the upper-right corner of this page. It compares a
+newer "to" API to an older "from" API, noting all changes relative to the
+older API. So, for example, API elements marked as removed are no longer present in the "to"
+API specification.</p>
+<p>To navigate the report, use the "Select a Diffs Index" and "Filter the Index"
+controls on the left. The report uses text formatting to indicate <em>interface names</em>,
+<a href= ><code>links to reference documentation</code></a>, and <a href= >links to change
+description</a>. The statistics are accessible from the "Statistics" link in the upper-right corner.</p>
+<p>For more information about the Android framework API and SDK,
+see the <a href="http://developer.android.com/index.html" target="_top">Android Developers site</a>.</p>
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Packages" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=3>Changed Packages</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android"></A>
+ <nobr><A HREF="pkg_android.html">android</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.app"></A>
+ <nobr><A HREF="pkg_android.app.html">android.app</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.pm"></A>
+ <nobr><A HREF="pkg_android.content.pm.html">android.content.pm</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.content.res"></A>
+ <nobr><A HREF="pkg_android.content.res.html">android.content.res</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.graphics"></A>
+ <nobr><A HREF="pkg_android.graphics.html">android.graphics</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.hardware.usb"></A>
+ <nobr><A HREF="pkg_android.hardware.usb.html">android.hardware.usb</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.net"></A>
+ <nobr><A HREF="pkg_android.net.html">android.net</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.os"></A>
+ <nobr><A HREF="pkg_android.os.html">android.os</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.telephony"></A>
+ <nobr><A HREF="pkg_android.telephony.html">android.telephony</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.util"></A>
+ <nobr><A HREF="pkg_android.util.html">android.util</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="android.view"></A>
+ <nobr><A HREF="pkg_android.view.html">android.view</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<!-- End of API section -->
+<!-- Start of packages section -->
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/classes_index_additions.html b/docs/html/sdk/api_diff/13/changes/classes_index_additions.html
new file mode 100644
index 000000000000..9ca1958f69de
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/classes_index_additions.html
@@ -0,0 +1,73 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Class Additions Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Classes" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="classes_index_all.html" class="staysblack">All Classes</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<b>Additions</b>
+ <br>
+<A HREF="classes_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<A NAME="F"></A>
+<br><font size="+2">F</font>&nbsp;
+<a href="#P"><font size="-2">P</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="pkg_android.app.html#Fragment.SavedState" class="hiddenlink" target="rightframe"><b>Fragment.SavedState</b></A><br>
+<A NAME="P"></A>
+<br><font size="+2">P</font>&nbsp;
+<a href="#F"><font size="-2">F</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="pkg_android.os.html#Parcelable.ClassLoaderCreator" class="hiddenlink" target="rightframe"><b><i>Parcelable.ClassLoaderCreator</i></b></A><br>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/classes_index_all.html b/docs/html/sdk/api_diff/13/changes/classes_index_all.html
new file mode 100644
index 000000000000..6bd102178699
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/classes_index_all.html
@@ -0,0 +1,300 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Class Differences Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Classes" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<b>Classes</b>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<A HREF="classes_index_additions.html"xclass="hiddenlink">Additions</A>
+ <br>
+<A HREF="classes_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<A NAME="A"></A>
+<br><font size="+2">A</font>&nbsp;
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.app.Activity.html" class="hiddenlink" target="rightframe">Activity</A><br>
+<A HREF="android.app.ActivityGroup.html" class="hiddenlink" target="rightframe">ActivityGroup</A><br>
+<A HREF="android.content.pm.ActivityInfo.html" class="hiddenlink" target="rightframe">ActivityInfo</A><br>
+<A HREF="android.content.pm.ApplicationInfo.html" class="hiddenlink" target="rightframe">ApplicationInfo</A><br>
+<A NAME="B"></A>
+<br><font size="+2">B</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.os.Binder.html" class="hiddenlink" target="rightframe">Binder</A><br>
+<A HREF="android.os.Build.VERSION_CODES.html" class="hiddenlink" target="rightframe">Build.VERSION_CODES</A><br>
+<A NAME="C"></A>
+<br><font size="+2">C</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.content.res.Configuration.html" class="hiddenlink" target="rightframe">Configuration</A><br>
+<A HREF="android.net.ConnectivityManager.html" class="hiddenlink" target="rightframe">ConnectivityManager</A><br>
+<A NAME="D"></A>
+<br><font size="+2">D</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.view.Display.html" class="hiddenlink" target="rightframe">Display</A><br>
+<A HREF="android.util.DisplayMetrics.html" class="hiddenlink" target="rightframe">DisplayMetrics</A><br>
+<A NAME="F"></A>
+<br><font size="+2">F</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.app.Fragment.html" class="hiddenlink" target="rightframe">Fragment</A><br>
+<A HREF="pkg_android.app.html#Fragment.SavedState" class="hiddenlink" target="rightframe"><b>Fragment.SavedState</b></A><br>
+<A HREF="android.app.FragmentManager.html" class="hiddenlink" target="rightframe">FragmentManager</A><br>
+<A HREF="android.app.FragmentTransaction.html" class="hiddenlink" target="rightframe">FragmentTransaction</A><br>
+<A NAME="I"></A>
+<br><font size="+2">I</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.os.IBinder.html" class="hiddenlink" target="rightframe"><i>IBinder</i></A><br>
+<A NAME="K"></A>
+<br><font size="+2">K</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.view.KeyEvent.html" class="hiddenlink" target="rightframe">KeyEvent</A><br>
+<A HREF="android.app.KeyguardManager.html" class="hiddenlink" target="rightframe">KeyguardManager</A><br>
+<A HREF="android.app.KeyguardManager.KeyguardLock.html" class="hiddenlink" target="rightframe">KeyguardManager.KeyguardLock</A><br>
+<A NAME="L"></A>
+<br><font size="+2">L</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.app.LocalActivityManager.html" class="hiddenlink" target="rightframe">LocalActivityManager</A><br>
+<A NAME="M"></A>
+<br><font size="+2">M</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.Manifest.permission.html" class="hiddenlink" target="rightframe">Manifest.permission</A><br>
+<A NAME="P"></A>
+<br><font size="+2">P</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.content.pm.PackageManager.html" class="hiddenlink" target="rightframe">PackageManager</A><br>
+<A HREF="pkg_android.os.html#Parcelable.ClassLoaderCreator" class="hiddenlink" target="rightframe"><b><i>Parcelable.ClassLoaderCreator</i></b></A><br>
+<A HREF="android.os.ParcelFileDescriptor.html" class="hiddenlink" target="rightframe">ParcelFileDescriptor</A><br>
+<A HREF="android.graphics.Point.html" class="hiddenlink" target="rightframe">Point</A><br>
+<A HREF="android.graphics.PointF.html" class="hiddenlink" target="rightframe">PointF</A><br>
+<A HREF="android.os.PowerManager.html" class="hiddenlink" target="rightframe">PowerManager</A><br>
+<A NAME="R"></A>
+<br><font size="+2">R</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.R.attr.html" class="hiddenlink" target="rightframe">R.attr</A><br>
+<A HREF="android.R.style.html" class="hiddenlink" target="rightframe">R.style</A><br>
+<A NAME="T"></A>
+<br><font size="+2">T</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.app.TabActivity.html" class="hiddenlink" target="rightframe">TabActivity</A><br>
+<A HREF="android.telephony.TelephonyManager.html" class="hiddenlink" target="rightframe">TelephonyManager</A><br>
+<A NAME="U"></A>
+<br><font size="+2">U</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.hardware.usb.UsbDeviceConnection.html" class="hiddenlink" target="rightframe">UsbDeviceConnection</A><br>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/classes_index_changes.html b/docs/html/sdk/api_diff/13/changes/classes_index_changes.html
new file mode 100644
index 000000000000..d76983f29e28
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/classes_index_changes.html
@@ -0,0 +1,298 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Class Changes Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Classes" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="classes_index_all.html" class="staysblack">All Classes</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<A HREF="classes_index_additions.html"xclass="hiddenlink">Additions</A>
+ <br>
+<b>Changes</b>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<A NAME="A"></A>
+<br><font size="+2">A</font>&nbsp;
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.app.Activity.html" class="hiddenlink" target="rightframe">Activity</A><br>
+<A HREF="android.app.ActivityGroup.html" class="hiddenlink" target="rightframe">ActivityGroup</A><br>
+<A HREF="android.content.pm.ActivityInfo.html" class="hiddenlink" target="rightframe">ActivityInfo</A><br>
+<A HREF="android.content.pm.ApplicationInfo.html" class="hiddenlink" target="rightframe">ApplicationInfo</A><br>
+<A NAME="B"></A>
+<br><font size="+2">B</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.os.Binder.html" class="hiddenlink" target="rightframe">Binder</A><br>
+<A HREF="android.os.Build.VERSION_CODES.html" class="hiddenlink" target="rightframe">Build.VERSION_CODES</A><br>
+<A NAME="C"></A>
+<br><font size="+2">C</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.content.res.Configuration.html" class="hiddenlink" target="rightframe">Configuration</A><br>
+<A HREF="android.net.ConnectivityManager.html" class="hiddenlink" target="rightframe">ConnectivityManager</A><br>
+<A NAME="D"></A>
+<br><font size="+2">D</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.view.Display.html" class="hiddenlink" target="rightframe">Display</A><br>
+<A HREF="android.util.DisplayMetrics.html" class="hiddenlink" target="rightframe">DisplayMetrics</A><br>
+<A NAME="F"></A>
+<br><font size="+2">F</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.app.Fragment.html" class="hiddenlink" target="rightframe">Fragment</A><br>
+<A HREF="android.app.FragmentManager.html" class="hiddenlink" target="rightframe">FragmentManager</A><br>
+<A HREF="android.app.FragmentTransaction.html" class="hiddenlink" target="rightframe">FragmentTransaction</A><br>
+<A NAME="I"></A>
+<br><font size="+2">I</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.os.IBinder.html" class="hiddenlink" target="rightframe"><i>IBinder</i></A><br>
+<A NAME="K"></A>
+<br><font size="+2">K</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.view.KeyEvent.html" class="hiddenlink" target="rightframe">KeyEvent</A><br>
+<A HREF="android.app.KeyguardManager.html" class="hiddenlink" target="rightframe">KeyguardManager</A><br>
+<A HREF="android.app.KeyguardManager.KeyguardLock.html" class="hiddenlink" target="rightframe">KeyguardManager.KeyguardLock</A><br>
+<A NAME="L"></A>
+<br><font size="+2">L</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.app.LocalActivityManager.html" class="hiddenlink" target="rightframe">LocalActivityManager</A><br>
+<A NAME="M"></A>
+<br><font size="+2">M</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.Manifest.permission.html" class="hiddenlink" target="rightframe">Manifest.permission</A><br>
+<A NAME="P"></A>
+<br><font size="+2">P</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.content.pm.PackageManager.html" class="hiddenlink" target="rightframe">PackageManager</A><br>
+<A HREF="android.os.ParcelFileDescriptor.html" class="hiddenlink" target="rightframe">ParcelFileDescriptor</A><br>
+<A HREF="android.graphics.Point.html" class="hiddenlink" target="rightframe">Point</A><br>
+<A HREF="android.graphics.PointF.html" class="hiddenlink" target="rightframe">PointF</A><br>
+<A HREF="android.os.PowerManager.html" class="hiddenlink" target="rightframe">PowerManager</A><br>
+<A NAME="R"></A>
+<br><font size="+2">R</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.R.attr.html" class="hiddenlink" target="rightframe">R.attr</A><br>
+<A HREF="android.R.style.html" class="hiddenlink" target="rightframe">R.style</A><br>
+<A NAME="T"></A>
+<br><font size="+2">T</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.app.TabActivity.html" class="hiddenlink" target="rightframe">TabActivity</A><br>
+<A HREF="android.telephony.TelephonyManager.html" class="hiddenlink" target="rightframe">TelephonyManager</A><br>
+<A NAME="U"></A>
+<br><font size="+2">U</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#B"><font size="-2">B</font></a>
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#K"><font size="-2">K</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#M"><font size="-2">M</font></a>
+<a href="#P"><font size="-2">P</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<A HREF="android.hardware.usb.UsbDeviceConnection.html" class="hiddenlink" target="rightframe">UsbDeviceConnection</A><br>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/classes_index_removals.html b/docs/html/sdk/api_diff/13/changes/classes_index_removals.html
new file mode 100644
index 000000000000..e6da73f487d3
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/classes_index_removals.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Class Removals Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Classes" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="classes_index_all.html" class="staysblack">All Classes</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<A HREF="classes_index_additions.html"xclass="hiddenlink">Additions</A>
+ <br>
+<A HREF="classes_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/constructors_index_additions.html b/docs/html/sdk/api_diff/13/changes/constructors_index_additions.html
new file mode 100644
index 000000000000..3237ba33faee
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/constructors_index_additions.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Constructor Additions Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Constructors" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="constructors_index_all.html" class="staysblack">All Constructors</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<font color="#999999">Additions</font>
+ <br>
+<font color="#999999">Changes</font>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/constructors_index_all.html b/docs/html/sdk/api_diff/13/changes/constructors_index_all.html
new file mode 100644
index 000000000000..637582e518a9
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/constructors_index_all.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Constructor Differences Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Constructors" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<b>Constructors</b>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<font color="#999999">Additions</font>
+ <br>
+<font color="#999999">Changes</font>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/constructors_index_changes.html b/docs/html/sdk/api_diff/13/changes/constructors_index_changes.html
new file mode 100644
index 000000000000..728fa2d6b45e
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/constructors_index_changes.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Constructor Changes Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Constructors" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="constructors_index_all.html" class="staysblack">All Constructors</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<font color="#999999">Additions</font>
+ <br>
+<font color="#999999">Changes</font>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/constructors_index_removals.html b/docs/html/sdk/api_diff/13/changes/constructors_index_removals.html
new file mode 100644
index 000000000000..1b95544e7f51
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/constructors_index_removals.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Constructor Removals Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Constructors" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="constructors_index_all.html" class="staysblack">All Constructors</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<font color="#999999">Additions</font>
+ <br>
+<font color="#999999">Changes</font>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/fields_index_additions.html b/docs/html/sdk/api_diff/13/changes/fields_index_additions.html
new file mode 100644
index 000000000000..271c9aaa1d50
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/fields_index_additions.html
@@ -0,0 +1,363 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Field Additions Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Fields" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="fields_index_all.html" class="staysblack">All Fields</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<b>Additions</b>
+ <br>
+<A HREF="fields_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<A NAME="C"></A>
+<br><font size="+2">C</font>&nbsp;
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>compatibleWidthLimitDp</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.R.attr.html#android.R.attr.compatibleWidthLimitDp" class="hiddenlink" target="rightframe">android.R.attr</A>
+</nobr><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.content.pm.ApplicationInfo.html#android.content.pm.ApplicationInfo.compatibleWidthLimitDp" class="hiddenlink" target="rightframe">android.content.pm.ApplicationInfo</A>
+</nobr><br>
+<nobr><A HREF="android.content.pm.ActivityInfo.html#android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE" class="hiddenlink" target="rightframe">CONFIG_SCREEN_SIZE</A>
+</nobr><br>
+<nobr><A HREF="android.content.pm.ActivityInfo.html#android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE" class="hiddenlink" target="rightframe">CONFIG_SMALLEST_SCREEN_SIZE</A>
+</nobr><br>
+<i>CREATOR</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.graphics.Point.html#android.graphics.Point.CREATOR" class="hiddenlink" target="rightframe">android.graphics.Point</A>
+</nobr><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.graphics.PointF.html#android.graphics.PointF.CREATOR" class="hiddenlink" target="rightframe">android.graphics.PointF</A>
+</nobr><br>
+<A NAME="D"></A>
+<br><font size="+2">D</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.util.DisplayMetrics.html#android.util.DisplayMetrics.DENSITY_TV" class="hiddenlink" target="rightframe">DENSITY_TV</A>
+</nobr><br>
+<A NAME="F"></A>
+<br><font size="+2">F</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT" class="hiddenlink" target="rightframe">FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT</A>
+</nobr><br>
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND" class="hiddenlink" target="rightframe">FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND</A>
+</nobr><br>
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_SCREEN_LANDSCAPE" class="hiddenlink" target="rightframe">FEATURE_SCREEN_LANDSCAPE</A>
+</nobr><br>
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_SCREEN_PORTRAIT" class="hiddenlink" target="rightframe">FEATURE_SCREEN_PORTRAIT</A>
+</nobr><br>
+<A NAME="H"></A>
+<br><font size="+2">H</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.os.Build.VERSION_CODES.html#android.os.Build.VERSION_CODES.HONEYCOMB_MR2" class="hiddenlink" target="rightframe">HONEYCOMB_MR2</A>
+</nobr><br>
+<A NAME="L"></A>
+<br><font size="+2">L</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>largestWidthLimitDp</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.R.attr.html#android.R.attr.largestWidthLimitDp" class="hiddenlink" target="rightframe">android.R.attr</A>
+</nobr><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.content.pm.ApplicationInfo.html#android.content.pm.ApplicationInfo.largestWidthLimitDp" class="hiddenlink" target="rightframe">android.content.pm.ApplicationInfo</A>
+</nobr><br>
+<A NAME="N"></A>
+<br><font size="+2">N</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.telephony.TelephonyManager.html#android.telephony.TelephonyManager.NETWORK_TYPE_HSPAP" class="hiddenlink" target="rightframe">NETWORK_TYPE_HSPAP</A>
+</nobr><br>
+<A NAME="R"></A>
+<br><font size="+2">R</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>requiresSmallestWidthDp</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.R.attr.html#android.R.attr.requiresSmallestWidthDp" class="hiddenlink" target="rightframe">android.R.attr</A>
+</nobr><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.content.pm.ApplicationInfo.html#android.content.pm.ApplicationInfo.requiresSmallestWidthDp" class="hiddenlink" target="rightframe">android.content.pm.ApplicationInfo</A>
+</nobr><br>
+<A NAME="S"></A>
+<br><font size="+2">S</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED" class="hiddenlink" target="rightframe">SCREEN_HEIGHT_DP_UNDEFINED</A>
+</nobr><br>
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED" class="hiddenlink" target="rightframe">SCREEN_WIDTH_DP_UNDEFINED</A>
+</nobr><br>
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.screenHeightDp" class="hiddenlink" target="rightframe">screenHeightDp</A>
+</nobr><br>
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.screenWidthDp" class="hiddenlink" target="rightframe">screenWidthDp</A>
+</nobr><br>
+<nobr><A HREF="android.Manifest.permission.html#android.Manifest.permission.SET_POINTER_SPEED" class="hiddenlink" target="rightframe">SET_POINTER_SPEED</A>
+</nobr><br>
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED" class="hiddenlink" target="rightframe">SMALLEST_SCREEN_WIDTH_DP_UNDEFINED</A>
+</nobr><br>
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.smallestScreenWidthDp" class="hiddenlink" target="rightframe">smallestScreenWidthDp</A>
+</nobr><br>
+<A NAME="T"></A>
+<br><font size="+2">T</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo" class="hiddenlink" target="rightframe">TextAppearance_Holo</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_DialogWindowTitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_DialogWindowTitle</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Inverse</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Large" class="hiddenlink" target="rightframe">TextAppearance_Holo_Large</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Large_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Large_Inverse</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Medium" class="hiddenlink" target="rightframe">TextAppearance_Holo_Medium</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Medium_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Medium_Inverse</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_SearchResult_Subtitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_SearchResult_Subtitle</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_SearchResult_Title" class="hiddenlink" target="rightframe">TextAppearance_Holo_SearchResult_Title</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Small" class="hiddenlink" target="rightframe">TextAppearance_Holo_Small</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Small_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Small_Inverse</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionBar_Subtitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionBar_Subtitle</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionBar_Title" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionBar_Title</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionMode_Subtitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionMode_Subtitle</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionMode_Title" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionMode_Title</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_Button" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_Button</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_DropDownHint" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_DropDownHint</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_DropDownItem" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_DropDownItem</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_EditText" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_EditText</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_IconMenu_Item" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_IconMenu_Item</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_PopupMenu" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_PopupMenu</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_PopupMenu_Large" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_PopupMenu_Large</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_PopupMenu_Small" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_PopupMenu_Small</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TabWidget" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TabWidget</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TextView" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TextView</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TextView_PopupMenu" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TextView_PopupMenu</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TextView_SpinnerItem" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TextView_SpinnerItem</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_WindowTitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_WindowTitle</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Theme_Holo_Light_NoActionBar" class="hiddenlink" target="rightframe">Theme_Holo_Light_NoActionBar</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Theme_Holo_Light_NoActionBar_Fullscreen" class="hiddenlink" target="rightframe">Theme_Holo_Light_NoActionBar_Fullscreen</A>
+</nobr><br>
+<nobr><A HREF="android.os.IBinder.html#android.os.IBinder.TWEET_TRANSACTION" class="hiddenlink" target="rightframe">TWEET_TRANSACTION</A>
+</nobr><br>
+<nobr><A HREF="android.net.ConnectivityManager.html#android.net.ConnectivityManager.TYPE_BLUETOOTH" class="hiddenlink" target="rightframe">TYPE_BLUETOOTH</A>
+</nobr><br>
+<nobr><A HREF="android.net.ConnectivityManager.html#android.net.ConnectivityManager.TYPE_ETHERNET" class="hiddenlink" target="rightframe">TYPE_ETHERNET</A>
+</nobr><br>
+<A NAME="U"></A>
+<br><font size="+2">U</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.UI_MODE_TYPE_TELEVISION" class="hiddenlink" target="rightframe">UI_MODE_TYPE_TELEVISION</A>
+</nobr><br>
+<A NAME="W"></A>
+<br><font size="+2">W</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_ActionBar_TabBar" class="hiddenlink" target="rightframe">Widget_ActionBar_TabBar</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_ActionBar_TabText" class="hiddenlink" target="rightframe">Widget_ActionBar_TabText</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_ActionBar_TabView" class="hiddenlink" target="rightframe">Widget_ActionBar_TabView</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_ActionBar_TabBar" class="hiddenlink" target="rightframe">Widget_Holo_ActionBar_TabBar</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_ActionBar_TabText" class="hiddenlink" target="rightframe">Widget_Holo_ActionBar_TabText</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_ActionBar_TabView" class="hiddenlink" target="rightframe">Widget_Holo_ActionBar_TabView</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_Light_ActionBar_TabBar" class="hiddenlink" target="rightframe">Widget_Holo_Light_ActionBar_TabBar</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_Light_ActionBar_TabText" class="hiddenlink" target="rightframe">Widget_Holo_Light_ActionBar_TabText</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_Light_ActionBar_TabView" class="hiddenlink" target="rightframe">Widget_Holo_Light_ActionBar_TabView</A>
+</nobr><br>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/fields_index_all.html b/docs/html/sdk/api_diff/13/changes/fields_index_all.html
new file mode 100644
index 000000000000..f18340830b7f
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/fields_index_all.html
@@ -0,0 +1,365 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Field Differences Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Fields" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<b>Fields</b>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<A HREF="fields_index_additions.html"xclass="hiddenlink">Additions</A>
+ <br>
+<A HREF="fields_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<A NAME="C"></A>
+<br><font size="+2">C</font>&nbsp;
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>compatibleWidthLimitDp</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.R.attr.html#android.R.attr.compatibleWidthLimitDp" class="hiddenlink" target="rightframe">android.R.attr</A>
+</nobr><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.content.pm.ApplicationInfo.html#android.content.pm.ApplicationInfo.compatibleWidthLimitDp" class="hiddenlink" target="rightframe">android.content.pm.ApplicationInfo</A>
+</nobr><br>
+<nobr><A HREF="android.content.pm.ActivityInfo.html#android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE" class="hiddenlink" target="rightframe">CONFIG_SCREEN_SIZE</A>
+</nobr><br>
+<nobr><A HREF="android.content.pm.ActivityInfo.html#android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE" class="hiddenlink" target="rightframe">CONFIG_SMALLEST_SCREEN_SIZE</A>
+</nobr><br>
+<i>CREATOR</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.graphics.Point.html#android.graphics.Point.CREATOR" class="hiddenlink" target="rightframe">android.graphics.Point</A>
+</nobr><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.graphics.PointF.html#android.graphics.PointF.CREATOR" class="hiddenlink" target="rightframe">android.graphics.PointF</A>
+</nobr><br>
+<A NAME="D"></A>
+<br><font size="+2">D</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.util.DisplayMetrics.html#android.util.DisplayMetrics.DENSITY_TV" class="hiddenlink" target="rightframe">DENSITY_TV</A>
+</nobr><br>
+<A NAME="F"></A>
+<br><font size="+2">F</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT" class="hiddenlink" target="rightframe">FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT</A>
+</nobr><br>
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND" class="hiddenlink" target="rightframe">FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND</A>
+</nobr><br>
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_SCREEN_LANDSCAPE" class="hiddenlink" target="rightframe">FEATURE_SCREEN_LANDSCAPE</A>
+</nobr><br>
+<nobr><A HREF="android.content.pm.PackageManager.html#android.content.pm.PackageManager.FEATURE_SCREEN_PORTRAIT" class="hiddenlink" target="rightframe">FEATURE_SCREEN_PORTRAIT</A>
+</nobr><br>
+<A NAME="H"></A>
+<br><font size="+2">H</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.os.Build.VERSION_CODES.html#android.os.Build.VERSION_CODES.HONEYCOMB_MR2" class="hiddenlink" target="rightframe">HONEYCOMB_MR2</A>
+</nobr><br>
+<A NAME="L"></A>
+<br><font size="+2">L</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>largestWidthLimitDp</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.R.attr.html#android.R.attr.largestWidthLimitDp" class="hiddenlink" target="rightframe">android.R.attr</A>
+</nobr><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.content.pm.ApplicationInfo.html#android.content.pm.ApplicationInfo.largestWidthLimitDp" class="hiddenlink" target="rightframe">android.content.pm.ApplicationInfo</A>
+</nobr><br>
+<A NAME="N"></A>
+<br><font size="+2">N</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.telephony.TelephonyManager.html#android.telephony.TelephonyManager.NETWORK_TYPE_HSPAP" class="hiddenlink" target="rightframe">NETWORK_TYPE_HSPAP</A>
+</nobr><br>
+<A NAME="R"></A>
+<br><font size="+2">R</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>requiresSmallestWidthDp</i><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.R.attr.html#android.R.attr.requiresSmallestWidthDp" class="hiddenlink" target="rightframe">android.R.attr</A>
+</nobr><br>
+<nobr>&nbsp;in&nbsp;
+<A HREF="android.content.pm.ApplicationInfo.html#android.content.pm.ApplicationInfo.requiresSmallestWidthDp" class="hiddenlink" target="rightframe">android.content.pm.ApplicationInfo</A>
+</nobr><br>
+<A NAME="S"></A>
+<br><font size="+2">S</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.os.PowerManager.html#android.os.PowerManager.SCREEN_BRIGHT_WAKE_LOCK" class="hiddenlink" target="rightframe">SCREEN_BRIGHT_WAKE_LOCK</A>
+</nobr><br>
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED" class="hiddenlink" target="rightframe">SCREEN_HEIGHT_DP_UNDEFINED</A>
+</nobr><br>
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED" class="hiddenlink" target="rightframe">SCREEN_WIDTH_DP_UNDEFINED</A>
+</nobr><br>
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.screenHeightDp" class="hiddenlink" target="rightframe">screenHeightDp</A>
+</nobr><br>
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.screenWidthDp" class="hiddenlink" target="rightframe">screenWidthDp</A>
+</nobr><br>
+<nobr><A HREF="android.Manifest.permission.html#android.Manifest.permission.SET_POINTER_SPEED" class="hiddenlink" target="rightframe">SET_POINTER_SPEED</A>
+</nobr><br>
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED" class="hiddenlink" target="rightframe">SMALLEST_SCREEN_WIDTH_DP_UNDEFINED</A>
+</nobr><br>
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.smallestScreenWidthDp" class="hiddenlink" target="rightframe">smallestScreenWidthDp</A>
+</nobr><br>
+<A NAME="T"></A>
+<br><font size="+2">T</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#U"><font size="-2">U</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo" class="hiddenlink" target="rightframe">TextAppearance_Holo</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_DialogWindowTitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_DialogWindowTitle</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Inverse</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Large" class="hiddenlink" target="rightframe">TextAppearance_Holo_Large</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Large_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Large_Inverse</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Medium" class="hiddenlink" target="rightframe">TextAppearance_Holo_Medium</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Medium_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Medium_Inverse</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_SearchResult_Subtitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_SearchResult_Subtitle</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_SearchResult_Title" class="hiddenlink" target="rightframe">TextAppearance_Holo_SearchResult_Title</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Small" class="hiddenlink" target="rightframe">TextAppearance_Holo_Small</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Small_Inverse" class="hiddenlink" target="rightframe">TextAppearance_Holo_Small_Inverse</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionBar_Subtitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionBar_Subtitle</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionBar_Title" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionBar_Title</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionMode_Subtitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionMode_Subtitle</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_ActionMode_Title" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_ActionMode_Title</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_Button" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_Button</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_DropDownHint" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_DropDownHint</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_DropDownItem" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_DropDownItem</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_EditText" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_EditText</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_IconMenu_Item" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_IconMenu_Item</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_PopupMenu" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_PopupMenu</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_PopupMenu_Large" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_PopupMenu_Large</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_PopupMenu_Small" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_PopupMenu_Small</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TabWidget" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TabWidget</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TextView" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TextView</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TextView_PopupMenu" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TextView_PopupMenu</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_Widget_TextView_SpinnerItem" class="hiddenlink" target="rightframe">TextAppearance_Holo_Widget_TextView_SpinnerItem</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.TextAppearance_Holo_WindowTitle" class="hiddenlink" target="rightframe">TextAppearance_Holo_WindowTitle</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Theme_Holo_Light_NoActionBar" class="hiddenlink" target="rightframe">Theme_Holo_Light_NoActionBar</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Theme_Holo_Light_NoActionBar_Fullscreen" class="hiddenlink" target="rightframe">Theme_Holo_Light_NoActionBar_Fullscreen</A>
+</nobr><br>
+<nobr><A HREF="android.os.IBinder.html#android.os.IBinder.TWEET_TRANSACTION" class="hiddenlink" target="rightframe">TWEET_TRANSACTION</A>
+</nobr><br>
+<nobr><A HREF="android.net.ConnectivityManager.html#android.net.ConnectivityManager.TYPE_BLUETOOTH" class="hiddenlink" target="rightframe">TYPE_BLUETOOTH</A>
+</nobr><br>
+<nobr><A HREF="android.net.ConnectivityManager.html#android.net.ConnectivityManager.TYPE_ETHERNET" class="hiddenlink" target="rightframe">TYPE_ETHERNET</A>
+</nobr><br>
+<A NAME="U"></A>
+<br><font size="+2">U</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.content.res.Configuration.html#android.content.res.Configuration.UI_MODE_TYPE_TELEVISION" class="hiddenlink" target="rightframe">UI_MODE_TYPE_TELEVISION</A>
+</nobr><br>
+<A NAME="W"></A>
+<br><font size="+2">W</font>&nbsp;
+<a href="#C"><font size="-2">C</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#H"><font size="-2">H</font></a>
+<a href="#L"><font size="-2">L</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#T"><font size="-2">T</font></a>
+<a href="#U"><font size="-2">U</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_ActionBar_TabBar" class="hiddenlink" target="rightframe">Widget_ActionBar_TabBar</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_ActionBar_TabText" class="hiddenlink" target="rightframe">Widget_ActionBar_TabText</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_ActionBar_TabView" class="hiddenlink" target="rightframe">Widget_ActionBar_TabView</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_ActionBar_TabBar" class="hiddenlink" target="rightframe">Widget_Holo_ActionBar_TabBar</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_ActionBar_TabText" class="hiddenlink" target="rightframe">Widget_Holo_ActionBar_TabText</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_ActionBar_TabView" class="hiddenlink" target="rightframe">Widget_Holo_ActionBar_TabView</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_Light_ActionBar_TabBar" class="hiddenlink" target="rightframe">Widget_Holo_Light_ActionBar_TabBar</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_Light_ActionBar_TabText" class="hiddenlink" target="rightframe">Widget_Holo_Light_ActionBar_TabText</A>
+</nobr><br>
+<nobr><A HREF="android.R.style.html#android.R.style.Widget_Holo_Light_ActionBar_TabView" class="hiddenlink" target="rightframe">Widget_Holo_Light_ActionBar_TabView</A>
+</nobr><br>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/fields_index_changes.html b/docs/html/sdk/api_diff/13/changes/fields_index_changes.html
new file mode 100644
index 000000000000..953047cc8a55
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/fields_index_changes.html
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Field Changes Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Fields" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="fields_index_all.html" class="staysblack">All Fields</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<A HREF="fields_index_additions.html"xclass="hiddenlink">Additions</A>
+ <br>
+<b>Changes</b>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<A NAME="S"></A>
+<br><font size="+2">S</font>&nbsp;
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.os.PowerManager.html#android.os.PowerManager.SCREEN_BRIGHT_WAKE_LOCK" class="hiddenlink" target="rightframe">SCREEN_BRIGHT_WAKE_LOCK</A>
+</nobr><br>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/fields_index_removals.html b/docs/html/sdk/api_diff/13/changes/fields_index_removals.html
new file mode 100644
index 000000000000..9f62d88abf0d
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/fields_index_removals.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Field Removals Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Fields" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="fields_index_all.html" class="staysblack">All Fields</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<A HREF="fields_index_additions.html"xclass="hiddenlink">Additions</A>
+ <br>
+<A HREF="fields_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/jdiff_help.html b/docs/html/sdk/api_diff/13/changes/jdiff_help.html
new file mode 100644
index 000000000000..ec659d498e69
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/jdiff_help.html
@@ -0,0 +1,134 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+JDiff Help
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<TABLE summary="Navigation bar" BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+ <TABLE summary="Navigation bar" BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../../reference/index.html" target="_top"><FONT CLASS="NavBarFont1"><B><code>13</code></B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="changes-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> &nbsp;<FONT CLASS="NavBarFont1">Package</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1"> &nbsp;<FONT CLASS="NavBarFont1">Class</FONT>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="jdiff_statistics.html"><FONT CLASS="NavBarFont1"><B>Statistics</B></FONT></A>&nbsp;</TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1Rev"> &nbsp;<FONT CLASS="NavBarFont1Rev"><B>Help</B></FONT>&nbsp;</TD>
+ </TR>
+ </TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM><b>Generated by<br><a href="http://www.jdiff.org" class="staysblack" target="_top">JDiff</a></b></EM></TD>
+</TR>
+<TR>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell2"><FONT SIZE="-2"></FONT>
+</TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../changes.html" TARGET="_top"><B>FRAMES</B></A> &nbsp;
+ &nbsp;<A HREF="jdiff_help.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<HR>
+<!-- End of nav bar -->
+<center>
+<H1>JDiff Documentation</H1>
+</center>
+<BLOCKQUOTE>
+JDiff is a <a href="http://java.sun.com/j2se/javadoc/" target="_top">Javadoc</a> doclet which generates a report of the API differences between two versions of a product. It does not report changes in Javadoc comments, or changes in what a class or method does.
+This help page describes the different parts of the output from JDiff.
+</BLOCKQUOTE>
+<BLOCKQUOTE>
+ See the reference page in the <a href="http://www.jdiff.org">source for JDiff</a> for information about how to generate a report like this one.
+</BLOCKQUOTE>
+<BLOCKQUOTE>
+The indexes shown in the top-left frame help show each type of change in more detail. The index "All Differences" contains all the differences between the APIs, in alphabetical order.
+These indexes all use the same format:
+<ul>
+<li>Removed packages, classes, constructors, methods and fields are <strike>struck through</strike>.</li>
+<li>Added packages, classes, constructors, methods and fields appear in <b>bold</b>.</li>
+<li>Changed packages, classes, constructors, methods and fields appear in normal text.</li>
+</ul>
+</BLOCKQUOTE>
+<BLOCKQUOTE>
+You can always tell when you are reading a JDiff page, rather than a Javadoc page, by the color of the index bar and the color of the background.
+Links which take you to a Javadoc page are always in a <code>typewriter</code> font.
+Just like Javadoc, all interface names are in <i>italic</i>, and class names are not italicized. Where there are multiple entries in an index with the same name, the heading for them is also in italics, but is not a link.
+</BLOCKQUOTE>
+<BLOCKQUOTE>
+<H3><b><code>Javadoc</code></b></H3>
+This is a link to the <a href="../../../../reference/index.html" target="_top">top-level</a> Javadoc page for the new version of the product.
+</BLOCKQUOTE>
+<BLOCKQUOTE>
+<H3>Overview</H3>
+The <a href="changes-summary.html">overview</a> is the top-level summary of what was removed, added and changed between versions.
+</BLOCKQUOTE>
+<BLOCKQUOTE>
+<H3>Package</H3>
+This is a link to the package containing the current changed class or interface.
+</BLOCKQUOTE>
+<BLOCKQUOTE>
+<H3>Class</H3>
+This is highlighted when you are looking at the changed class or interface.
+</BLOCKQUOTE>
+<BLOCKQUOTE>
+<H3>Text Changes</H3>
+This is a link to the top-level index of all documentation changes for the current package or class.
+If it is not present, then there are no documentation changes for the current package or class.
+This link can be removed entirely by not using the <code>-docchanges</code> option.
+</BLOCKQUOTE>
+<BLOCKQUOTE>
+<H3>Statistics</H3>
+This is a link to a page which shows statistics about the changes between the two APIs.
+This link can be removed entirely by not using the <code>-stats</code> option.
+</BLOCKQUOTE>
+<BLOCKQUOTE>
+<H3>Help</H3>
+A link to this Help page for JDiff.
+</BLOCKQUOTE>
+<BLOCKQUOTE>
+<H3>Prev/Next</H3>
+These links take you to the previous and next changed package or class.
+</BLOCKQUOTE>
+<BLOCKQUOTE>
+<H3>Frames/No Frames</H3>
+These links show and hide the HTML frames. All pages are available with or without frames.
+</BLOCKQUOTE>
+<BLOCKQUOTE>
+<H2>Complex Changes</H2>
+There are some complex changes which can occur between versions, for example, when two or more methods with the same name change simultaneously, or when a method or field is moved into or from a superclass.
+In these cases, the change will be seen as a removal and an addition, rather than as a change. Unexpected removals or additions are often part of one of these type of changes.
+</BLOCKQUOTE>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/jdiff_statistics.html b/docs/html/sdk/api_diff/13/changes/jdiff_statistics.html
new file mode 100644
index 000000000000..626c7659da0f
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/jdiff_statistics.html
@@ -0,0 +1,382 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+API Change Statistics
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<body class="gc-documentation">
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;xborder-bottom:none;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="../changes.html" target="_top">Top of Report</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<h1>API&nbsp;Change&nbsp;Statistics</h1>
+<p>The overall difference between API Levels 12 and 13 is approximately <span style="color:222;font-weight:bold;">0.04%</span>.
+</p>
+<br>
+<a name="numbers"></a>
+<h2>Total of Differences, by Number and Type</h2>
+<p>
+The table below lists the numbers of program elements (packages, classes, constructors, methods, and fields) that were added, changed, or removed. The table includes only the highest-level program elements &mdash; that is, if a class with two methods was added, the number of methods added does not include those two methods, but the number of classes added does include that class.
+</p>
+<TABLE summary="Number of differences" WIDTH="100%">
+<TR>
+ <th>Type</th>
+ <TH ALIGN="center"><b>Additions</b></TH>
+ <TH ALIGN="center"><b>Changes</b></TH>
+ <TH ALIGN="center">Removals</TH>
+ <TH ALIGN="center"><b>Total</b></TH>
+</TR>
+<TR>
+ <TD>Packages</TD>
+ <TD ALIGN="right">0</TD>
+ <TD ALIGN="right">11</TD>
+ <TD ALIGN="right">0</TD>
+ <TD ALIGN="right">11</TD>
+</TR>
+<TR>
+ <TD>Classes and <i>Interfaces</i></TD>
+ <TD ALIGN="right">2</TD>
+ <TD ALIGN="right">29</TD>
+ <TD ALIGN="right">0</TD>
+ <TD ALIGN="right">31</TD>
+</TR>
+<TR>
+ <TD>Constructors</TD>
+ <TD ALIGN="right">0</TD>
+ <TD ALIGN="right">0</TD>
+ <TD ALIGN="right">0</TD>
+ <TD ALIGN="right">0</TD>
+</TR>
+<TR>
+ <TD>Methods</TD>
+ <TD ALIGN="right">22</TD>
+ <TD ALIGN="right">12</TD>
+ <TD ALIGN="right">0</TD>
+ <TD ALIGN="right">34</TD>
+</TR>
+<TR>
+ <TD>Fields</TD>
+ <TD ALIGN="right">68</TD>
+ <TD ALIGN="right">1</TD>
+ <TD ALIGN="right">0</TD>
+ <TD ALIGN="right">69</TD>
+</TR>
+<TR>
+ <TD style="background-color:#FAFAFA"><b>Total</b></TD>
+ <TD style="background-color:#FAFAFA" ALIGN="right"><strong>92</strong></TD>
+ <TD style="background-color:#FAFAFA" ALIGN="right"><strong>53</strong></TD>
+ <TD style="background-color:#FAFAFA" ALIGN="right"><strong>0</strong></TD>
+ <TD style="background-color:#FAFAFA" ALIGN="right"><strong>145</strong></TD>
+</TR>
+</TABLE>
+<br>
+<a name="packages"></a>
+<h2>Changed Packages, Sorted by Percentage Difference</h2>
+<TABLE summary="Packages sorted by percentage difference" WIDTH="100%">
+<TR>
+ <TH WIDTH="10%">Percentage Difference*</TH>
+ <TH>Package</TH>
+</TR>
+<TR>
+ <TD ALIGN="center">2</TD>
+ <TD><A HREF="pkg_android.app.html">android.app</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">1</TD>
+ <TD><A HREF="pkg_android.os.html">android.os</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">&lt;1</TD>
+ <TD><A HREF="pkg_android.hardware.usb.html">android.hardware.usb</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">&lt;1</TD>
+ <TD><A HREF="pkg_android.graphics.html">android.graphics</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">&lt;1</TD>
+ <TD><A HREF="pkg_android.html">android</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">&lt;1</TD>
+ <TD><A HREF="pkg_android.content.res.html">android.content.res</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">&lt;1</TD>
+ <TD><A HREF="pkg_android.content.pm.html">android.content.pm</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">&lt;1</TD>
+ <TD><A HREF="pkg_android.view.html">android.view</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">&lt;1</TD>
+ <TD><A HREF="pkg_android.net.html">android.net</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">&lt;1</TD>
+ <TD><A HREF="pkg_android.util.html">android.util</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">&lt;1</TD>
+ <TD><A HREF="pkg_android.telephony.html">android.telephony</A></TD>
+</TR>
+</TABLE>
+<p style="font-size:10px">* See <a href="#calculation">Calculation of Change Percentages</a>, below.</p>
+<br>
+<a name="classes"></a>
+<h2>Changed Classes and <i>Interfaces</i>, Sorted by Percentage Difference</h2>
+<TABLE summary="Classes sorted by percentage difference" WIDTH="100%">
+<TR WIDTH="20%">
+ <TH WIDTH="10%">Percentage<br>Difference*</TH>
+ <TH><b>Class or <i>Interface</i></b></TH>
+</TR>
+<TR>
+ <TD ALIGN="center">33</TD>
+ <TD><A HREF="android.app.KeyguardManager.html">
+android.app.KeyguardManager</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">25</TD>
+ <TD><A HREF="android.app.KeyguardManager.KeyguardLock.html">
+android.app.KeyguardManager.KeyguardLock</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">20</TD>
+ <TD><A HREF="android.view.Display.html">
+android.view.Display</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">18</TD>
+ <TD><A HREF="android.graphics.Point.html">
+android.graphics.Point</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">14</TD>
+ <TD><A HREF="android.graphics.PointF.html">
+android.graphics.PointF</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">12</TD>
+ <TD><A HREF="android.app.ActivityGroup.html">
+android.app.ActivityGroup</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">10</TD>
+ <TD><A HREF="android.app.TabActivity.html">
+android.app.TabActivity</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">7</TD>
+ <TD><A HREF="android.R.style.html">
+android.R.style</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">6</TD>
+ <TD><A HREF="android.os.ParcelFileDescriptor.html">
+android.os.ParcelFileDescriptor</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">6</TD>
+ <TD><A HREF="android.os.IBinder.html">
+<i>android.os.IBinder</i></A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">5</TD>
+ <TD><A HREF="android.hardware.usb.UsbDeviceConnection.html">
+android.hardware.usb.UsbDeviceConnection</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">4</TD>
+ <TD><A HREF="android.app.FragmentTransaction.html">
+android.app.FragmentTransaction</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">4</TD>
+ <TD><A HREF="android.content.res.Configuration.html">
+android.content.res.Configuration</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">4</TD>
+ <TD><A HREF="android.os.PowerManager.html">
+android.os.PowerManager</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">3</TD>
+ <TD><A HREF="android.app.LocalActivityManager.html">
+android.app.LocalActivityManager</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">3</TD>
+ <TD><A HREF="android.net.ConnectivityManager.html">
+android.net.ConnectivityManager</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">3</TD>
+ <TD><A HREF="android.app.Activity.html">
+android.app.Activity</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">3</TD>
+ <TD><A HREF="android.os.Build.VERSION_CODES.html">
+android.os.Build.VERSION_CODES</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">3</TD>
+ <TD><A HREF="android.content.pm.ApplicationInfo.html">
+android.content.pm.ApplicationInfo</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">3</TD>
+ <TD><A HREF="android.util.DisplayMetrics.html">
+android.util.DisplayMetrics</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">2</TD>
+ <TD><A HREF="android.os.Binder.html">
+android.os.Binder</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">2</TD>
+ <TD><A HREF="android.app.Fragment.html">
+android.app.Fragment</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">2</TD>
+ <TD><A HREF="android.app.FragmentManager.html">
+android.app.FragmentManager</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">1</TD>
+ <TD><A HREF="android.content.pm.ActivityInfo.html">
+android.content.pm.ActivityInfo</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">1</TD>
+ <TD><A HREF="android.content.pm.PackageManager.html">
+android.content.pm.PackageManager</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">&lt;1</TD>
+ <TD><A HREF="android.telephony.TelephonyManager.html">
+android.telephony.TelephonyManager</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">&lt;1</TD>
+ <TD><A HREF="android.Manifest.permission.html">
+android.Manifest.permission</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">&lt;1</TD>
+ <TD><A HREF="android.R.attr.html">
+android.R.attr</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">&lt;1</TD>
+ <TD><A HREF="android.view.KeyEvent.html">
+android.view.KeyEvent</A></TD>
+</TR>
+</TABLE>
+<p style="font-size:10px">* See <a href="#calculation">Calculation of Change Percentages</a>, below.</p>
+<br>
+<h2 id="calculation">Calculation of Change Percentages</h2>
+<p>
+The percent change statistic reported for all elements in the &quot;to&quot; API Level specification is defined recursively as follows:</p>
+<pre>
+Percentage difference = 100 * (added + removed + 2*changed)
+ -----------------------------------
+ sum of public elements in BOTH APIs
+</pre>
+<p>where <code>added</code> is the number of packages added, <code>removed</code> is the number of packages removed, and <code>changed</code> is the number of packages changed.
+This definition is applied recursively for the classes and their program elements, so the value for a changed package will be less than 1, unless every class in that package has changed.
+The definition ensures that if all packages are removed and all new packages are
+added, the change will be 100%.</p>
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY></HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/jdiff_topleftframe.html b/docs/html/sdk/api_diff/13/changes/jdiff_topleftframe.html
new file mode 100644
index 000000000000..36f9836e4478
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/jdiff_topleftframe.html
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Android API Version Differences
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<table class="jdiffIndex" summary="Links to diff index files" BORDER="0" WIDTH="100%" cellspacing="0" cellpadding="0" style="margin:0">
+<TR>
+ <th class="indexHeader" nowrap>
+ Select a Diffs Index:</th>
+</TR>
+<TR>
+ <TD><FONT CLASS="indexText" size="-2"><A HREF="alldiffs_index_all.html" TARGET="bottomleftframe">All Differences</A></FONT><br></TD>
+</TR>
+<TR>
+ <TD NOWRAP><FONT CLASS="indexText" size="-2"><A HREF="packages_index_all.html" TARGET="bottomleftframe">By Package</A></FONT><br></TD>
+</TR>
+<TR>
+ <TD NOWRAP><FONT CLASS="indexText" size="-2"><A HREF="classes_index_all.html" TARGET="bottomleftframe">By Class</A></FONT><br></TD>
+</TR>
+<TR>
+ <TD NOWRAP><FONT CLASS="indexText" size="-2"><A HREF="constructors_index_all.html" TARGET="bottomleftframe">By Constructor</A></FONT><br></TD>
+</TR>
+<TR>
+ <TD NOWRAP><FONT CLASS="indexText" size="-2"><A HREF="methods_index_all.html" TARGET="bottomleftframe">By Method</A></FONT><br></TD>
+</TR>
+<TR>
+ <TD NOWRAP><FONT CLASS="indexText" size="-2"><A HREF="fields_index_all.html" TARGET="bottomleftframe">By Field</A></FONT><br></TD>
+</TR>
+</TABLE>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/methods_index_additions.html b/docs/html/sdk/api_diff/13/changes/methods_index_additions.html
new file mode 100644
index 000000000000..fbbf5a69ea50
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/methods_index_additions.html
@@ -0,0 +1,225 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Method Additions Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Methods" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="methods_index_all.html" class="staysblack">All Methods</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<b>Additions</b>
+ <br>
+<A HREF="methods_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<A NAME="A"></A>
+<br><font size="+2">A</font>&nbsp;
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.os.ParcelFileDescriptor.html#android.os.ParcelFileDescriptor.adoptFd_added(int)" class="hiddenlink" target="rightframe"><b>adoptFd</b>
+(<code>int</code>)</A></nobr><br>
+<nobr><A HREF="android.app.FragmentTransaction.html#android.app.FragmentTransaction.attach_added(android.app.Fragment)" class="hiddenlink" target="rightframe"><b>attach</b>
+(<code>Fragment</code>)</A></nobr><br>
+<A NAME="D"></A>
+<br><font size="+2">D</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>describeContents</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.Point.html#android.graphics.Point.describeContents_added()" class="hiddenlink" target="rightframe">type&nbsp;<b>
+()</b>&nbsp;in&nbsp;android.graphics.Point
+</A></nobr><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.PointF.html#android.graphics.PointF.describeContents_added()" class="hiddenlink" target="rightframe">type&nbsp;<b>
+()</b>&nbsp;in&nbsp;android.graphics.PointF
+</A></nobr><br>
+<nobr><A HREF="android.app.FragmentTransaction.html#android.app.FragmentTransaction.detach_added(android.app.Fragment)" class="hiddenlink" target="rightframe"><b>detach</b>
+(<code>Fragment</code>)</A></nobr><br>
+<i>dumpAsync</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.os.Binder.html#android.os.Binder.dumpAsync_added(java.io.FileDescriptor, java.lang.String[])" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>FileDescriptor, String[]</code>)</b>&nbsp;in&nbsp;android.os.Binder
+</A></nobr><br>
+&nbsp;&nbsp;<nobr><A HREF="android.os.IBinder.html#android.os.IBinder.dumpAsync_added(java.io.FileDescriptor, java.lang.String[])" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>FileDescriptor, String[]</code>)</b>&nbsp;in&nbsp;android.os.IBinder
+</A></nobr><br>
+<nobr><A HREF="android.os.ParcelFileDescriptor.html#android.os.ParcelFileDescriptor.dup_added(java.io.FileDescriptor)" class="hiddenlink" target="rightframe"><b>dup</b>
+(<code>FileDescriptor</code>)</A></nobr><br>
+<A NAME="F"></A>
+<br><font size="+2">F</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.os.ParcelFileDescriptor.html#android.os.ParcelFileDescriptor.fromFd_added(int)" class="hiddenlink" target="rightframe"><b>fromFd</b>
+(<code>int</code>)</A></nobr><br>
+<A NAME="G"></A>
+<br><font size="+2">G</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.view.KeyEvent.html#android.view.KeyEvent.getModifiers_added()" class="hiddenlink" target="rightframe"><b>getModifiers</b>
+()</A></nobr><br>
+<nobr><A HREF="android.hardware.usb.UsbDeviceConnection.html#android.hardware.usb.UsbDeviceConnection.getRawDescriptors_added()" class="hiddenlink" target="rightframe"><b>getRawDescriptors</b>
+()</A></nobr><br>
+<nobr><A HREF="android.view.Display.html#android.view.Display.getRectSize_added(android.graphics.Rect)" class="hiddenlink" target="rightframe"><b>getRectSize</b>
+(<code>Rect</code>)</A></nobr><br>
+<nobr><A HREF="android.view.Display.html#android.view.Display.getSize_added(android.graphics.Point)" class="hiddenlink" target="rightframe"><b>getSize</b>
+(<code>Point</code>)</A></nobr><br>
+<A NAME="I"></A>
+<br><font size="+2">I</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.Fragment.html#android.app.Fragment.isDetached_added()" class="hiddenlink" target="rightframe"><b>isDetached</b>
+()</A></nobr><br>
+<A NAME="O"></A>
+<br><font size="+2">O</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.Fragment.html#android.app.Fragment.onViewCreated_added(android.view.View, android.os.Bundle)" class="hiddenlink" target="rightframe"><b>onViewCreated</b>
+(<code>View, Bundle</code>)</A></nobr><br>
+<A NAME="R"></A>
+<br><font size="+2">R</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>readFromParcel</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.Point.html#android.graphics.Point.readFromParcel_added(android.os.Parcel)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel</code>)</b>&nbsp;in&nbsp;android.graphics.Point
+</A></nobr><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.PointF.html#android.graphics.PointF.readFromParcel_added(android.os.Parcel)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel</code>)</b>&nbsp;in&nbsp;android.graphics.PointF
+</A></nobr><br>
+<A NAME="S"></A>
+<br><font size="+2">S</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.FragmentManager.html#android.app.FragmentManager.saveFragmentInstanceState_added(android.app.Fragment)" class="hiddenlink" target="rightframe"><b>saveFragmentInstanceState</b>
+(<code>Fragment</code>)</A></nobr><br>
+<nobr><A HREF="android.app.FragmentTransaction.html#android.app.FragmentTransaction.setCustomAnimations_added(int, int, int, int)" class="hiddenlink" target="rightframe"><b>setCustomAnimations</b>
+(<code>int, int, int, int</code>)</A></nobr><br>
+<nobr><A HREF="android.app.Fragment.html#android.app.Fragment.setInitialSavedState_added(android.app.Fragment.SavedState)" class="hiddenlink" target="rightframe"><b>setInitialSavedState</b>
+(<code>SavedState</code>)</A></nobr><br>
+<A NAME="W"></A>
+<br><font size="+2">W</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>writeToParcel</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.Point.html#android.graphics.Point.writeToParcel_added(android.os.Parcel, int)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel, int</code>)</b>&nbsp;in&nbsp;android.graphics.Point
+</A></nobr><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.PointF.html#android.graphics.PointF.writeToParcel_added(android.os.Parcel, int)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel, int</code>)</b>&nbsp;in&nbsp;android.graphics.PointF
+</A></nobr><br>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/methods_index_all.html b/docs/html/sdk/api_diff/13/changes/methods_index_all.html
new file mode 100644
index 000000000000..84d0a2c4d94c
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/methods_index_all.html
@@ -0,0 +1,298 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Method Differences Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Methods" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<b>Methods</b>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<A HREF="methods_index_additions.html"xclass="hiddenlink">Additions</A>
+ <br>
+<A HREF="methods_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<A NAME="A"></A>
+<br><font size="+2">A</font>&nbsp;
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.os.ParcelFileDescriptor.html#android.os.ParcelFileDescriptor.adoptFd_added(int)" class="hiddenlink" target="rightframe"><b>adoptFd</b>
+(<code>int</code>)</A></nobr><br>
+<nobr><A HREF="android.app.FragmentTransaction.html#android.app.FragmentTransaction.attach_added(android.app.Fragment)" class="hiddenlink" target="rightframe"><b>attach</b>
+(<code>Fragment</code>)</A></nobr><br>
+<A NAME="D"></A>
+<br><font size="+2">D</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>describeContents</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.Point.html#android.graphics.Point.describeContents_added()" class="hiddenlink" target="rightframe">type&nbsp;<b>
+()</b>&nbsp;in&nbsp;android.graphics.Point
+</A></nobr><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.PointF.html#android.graphics.PointF.describeContents_added()" class="hiddenlink" target="rightframe">type&nbsp;<b>
+()</b>&nbsp;in&nbsp;android.graphics.PointF
+</A></nobr><br>
+<nobr><A HREF="android.app.FragmentTransaction.html#android.app.FragmentTransaction.detach_added(android.app.Fragment)" class="hiddenlink" target="rightframe"><b>detach</b>
+(<code>Fragment</code>)</A></nobr><br>
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.dismissDialog_changed(int)" class="hiddenlink" target="rightframe">dismissDialog
+(<code>int</code>)</A></nobr><br>
+<i>dumpAsync</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.os.Binder.html#android.os.Binder.dumpAsync_added(java.io.FileDescriptor, java.lang.String[])" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>FileDescriptor, String[]</code>)</b>&nbsp;in&nbsp;android.os.Binder
+</A></nobr><br>
+&nbsp;&nbsp;<nobr><A HREF="android.os.IBinder.html#android.os.IBinder.dumpAsync_added(java.io.FileDescriptor, java.lang.String[])" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>FileDescriptor, String[]</code>)</b>&nbsp;in&nbsp;android.os.IBinder
+</A></nobr><br>
+<nobr><A HREF="android.os.ParcelFileDescriptor.html#android.os.ParcelFileDescriptor.dup_added(java.io.FileDescriptor)" class="hiddenlink" target="rightframe"><b>dup</b>
+(<code>FileDescriptor</code>)</A></nobr><br>
+<A NAME="E"></A>
+<br><font size="+2">E</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.KeyguardManager.html#android.app.KeyguardManager.exitKeyguardSecurely_changed(android.app.KeyguardManager.OnKeyguardExitResult)" class="hiddenlink" target="rightframe">exitKeyguardSecurely
+(<code>OnKeyguardExitResult</code>)</A></nobr><br>
+<A NAME="F"></A>
+<br><font size="+2">F</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.os.ParcelFileDescriptor.html#android.os.ParcelFileDescriptor.fromFd_added(int)" class="hiddenlink" target="rightframe"><b>fromFd</b>
+(<code>int</code>)</A></nobr><br>
+<A NAME="G"></A>
+<br><font size="+2">G</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.view.Display.html#android.view.Display.getHeight_changed()" class="hiddenlink" target="rightframe">getHeight
+()</A></nobr><br>
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.getLastNonConfigurationInstance_changed()" class="hiddenlink" target="rightframe">getLastNonConfigurationInstance
+()</A></nobr><br>
+<nobr><A HREF="android.view.KeyEvent.html#android.view.KeyEvent.getModifiers_added()" class="hiddenlink" target="rightframe"><b>getModifiers</b>
+()</A></nobr><br>
+<nobr><A HREF="android.hardware.usb.UsbDeviceConnection.html#android.hardware.usb.UsbDeviceConnection.getRawDescriptors_added()" class="hiddenlink" target="rightframe"><b>getRawDescriptors</b>
+()</A></nobr><br>
+<nobr><A HREF="android.view.Display.html#android.view.Display.getRectSize_added(android.graphics.Rect)" class="hiddenlink" target="rightframe"><b>getRectSize</b>
+(<code>Rect</code>)</A></nobr><br>
+<nobr><A HREF="android.view.Display.html#android.view.Display.getSize_added(android.graphics.Point)" class="hiddenlink" target="rightframe"><b>getSize</b>
+(<code>Point</code>)</A></nobr><br>
+<nobr><A HREF="android.view.Display.html#android.view.Display.getWidth_changed()" class="hiddenlink" target="rightframe">getWidth
+()</A></nobr><br>
+<A NAME="I"></A>
+<br><font size="+2">I</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.Fragment.html#android.app.Fragment.isDetached_added()" class="hiddenlink" target="rightframe"><b>isDetached</b>
+()</A></nobr><br>
+<A NAME="N"></A>
+<br><font size="+2">N</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.KeyguardManager.html#android.app.KeyguardManager.newKeyguardLock_changed(java.lang.String)" class="hiddenlink" target="rightframe">newKeyguardLock
+(<code>String</code>)</A></nobr><br>
+<A NAME="O"></A>
+<br><font size="+2">O</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.onCreateDialog_changed(int, android.os.Bundle)" class="hiddenlink" target="rightframe">onCreateDialog
+(<code>int, Bundle</code>)</A></nobr><br>
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.onPrepareDialog_changed(int, android.app.Dialog, android.os.Bundle)" class="hiddenlink" target="rightframe">onPrepareDialog
+(<code>int, Dialog, Bundle</code>)</A></nobr><br>
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.onRetainNonConfigurationInstance_changed()" class="hiddenlink" target="rightframe">onRetainNonConfigurationInstance
+()</A></nobr><br>
+<nobr><A HREF="android.app.Fragment.html#android.app.Fragment.onViewCreated_added(android.view.View, android.os.Bundle)" class="hiddenlink" target="rightframe"><b>onViewCreated</b>
+(<code>View, Bundle</code>)</A></nobr><br>
+<A NAME="R"></A>
+<br><font size="+2">R</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#S"><font size="-2">S</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>readFromParcel</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.Point.html#android.graphics.Point.readFromParcel_added(android.os.Parcel)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel</code>)</b>&nbsp;in&nbsp;android.graphics.Point
+</A></nobr><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.PointF.html#android.graphics.PointF.readFromParcel_added(android.os.Parcel)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel</code>)</b>&nbsp;in&nbsp;android.graphics.PointF
+</A></nobr><br>
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.removeDialog_changed(int)" class="hiddenlink" target="rightframe">removeDialog
+(<code>int</code>)</A></nobr><br>
+<A NAME="S"></A>
+<br><font size="+2">S</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#W"><font size="-2">W</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.FragmentManager.html#android.app.FragmentManager.saveFragmentInstanceState_added(android.app.Fragment)" class="hiddenlink" target="rightframe"><b>saveFragmentInstanceState</b>
+(<code>Fragment</code>)</A></nobr><br>
+<nobr><A HREF="android.app.FragmentTransaction.html#android.app.FragmentTransaction.setCustomAnimations_added(int, int, int, int)" class="hiddenlink" target="rightframe"><b>setCustomAnimations</b>
+(<code>int, int, int, int</code>)</A></nobr><br>
+<nobr><A HREF="android.app.Fragment.html#android.app.Fragment.setInitialSavedState_added(android.app.Fragment.SavedState)" class="hiddenlink" target="rightframe"><b>setInitialSavedState</b>
+(<code>SavedState</code>)</A></nobr><br>
+<i>showDialog</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.app.Activity.html#android.app.Activity.showDialog_changed(int, android.os.Bundle)" class="hiddenlink" target="rightframe">type&nbsp;
+(<code>int, Bundle</code>)&nbsp;in&nbsp;android.app.Activity
+</A></nobr><br>
+&nbsp;&nbsp;<nobr><A HREF="android.app.Activity.html#android.app.Activity.showDialog_changed(int)" class="hiddenlink" target="rightframe">type&nbsp;
+(<code>int</code>)&nbsp;in&nbsp;android.app.Activity
+</A></nobr><br>
+<A NAME="W"></A>
+<br><font size="+2">W</font>&nbsp;
+<a href="#A"><font size="-2">A</font></a>
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#F"><font size="-2">F</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#I"><font size="-2">I</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>writeToParcel</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.Point.html#android.graphics.Point.writeToParcel_added(android.os.Parcel, int)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel, int</code>)</b>&nbsp;in&nbsp;android.graphics.Point
+</A></nobr><br>
+&nbsp;&nbsp;<nobr><A HREF="android.graphics.PointF.html#android.graphics.PointF.writeToParcel_added(android.os.Parcel, int)" class="hiddenlink" target="rightframe">type&nbsp;<b>
+(<code>Parcel, int</code>)</b>&nbsp;in&nbsp;android.graphics.PointF
+</A></nobr><br>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/methods_index_changes.html b/docs/html/sdk/api_diff/13/changes/methods_index_changes.html
new file mode 100644
index 000000000000..97cc3ef5bad4
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/methods_index_changes.html
@@ -0,0 +1,158 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Method Changes Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Methods" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="methods_index_all.html" class="staysblack">All Methods</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<A HREF="methods_index_additions.html"xclass="hiddenlink">Additions</A>
+ <br>
+<b>Changes</b>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<A NAME="D"></A>
+<br><font size="+2">D</font>&nbsp;
+<a href="#E"><font size="-2">E</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.dismissDialog_changed(int)" class="hiddenlink" target="rightframe">dismissDialog
+(<code>int</code>)</A></nobr><br>
+<A NAME="E"></A>
+<br><font size="+2">E</font>&nbsp;
+<a href="#D"><font size="-2">D</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.KeyguardManager.html#android.app.KeyguardManager.exitKeyguardSecurely_changed(android.app.KeyguardManager.OnKeyguardExitResult)" class="hiddenlink" target="rightframe">exitKeyguardSecurely
+(<code>OnKeyguardExitResult</code>)</A></nobr><br>
+<A NAME="G"></A>
+<br><font size="+2">G</font>&nbsp;
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.view.Display.html#android.view.Display.getHeight_changed()" class="hiddenlink" target="rightframe">getHeight
+()</A></nobr><br>
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.getLastNonConfigurationInstance_changed()" class="hiddenlink" target="rightframe">getLastNonConfigurationInstance
+()</A></nobr><br>
+<nobr><A HREF="android.view.Display.html#android.view.Display.getWidth_changed()" class="hiddenlink" target="rightframe">getWidth
+()</A></nobr><br>
+<A NAME="N"></A>
+<br><font size="+2">N</font>&nbsp;
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.KeyguardManager.html#android.app.KeyguardManager.newKeyguardLock_changed(java.lang.String)" class="hiddenlink" target="rightframe">newKeyguardLock
+(<code>String</code>)</A></nobr><br>
+<A NAME="O"></A>
+<br><font size="+2">O</font>&nbsp;
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#R"><font size="-2">R</font></a>
+<a href="#S"><font size="-2">S</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.onCreateDialog_changed(int, android.os.Bundle)" class="hiddenlink" target="rightframe">onCreateDialog
+(<code>int, Bundle</code>)</A></nobr><br>
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.onPrepareDialog_changed(int, android.app.Dialog, android.os.Bundle)" class="hiddenlink" target="rightframe">onPrepareDialog
+(<code>int, Dialog, Bundle</code>)</A></nobr><br>
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.onRetainNonConfigurationInstance_changed()" class="hiddenlink" target="rightframe">onRetainNonConfigurationInstance
+()</A></nobr><br>
+<A NAME="R"></A>
+<br><font size="+2">R</font>&nbsp;
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#S"><font size="-2">S</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<nobr><A HREF="android.app.Activity.html#android.app.Activity.removeDialog_changed(int)" class="hiddenlink" target="rightframe">removeDialog
+(<code>int</code>)</A></nobr><br>
+<A NAME="S"></A>
+<br><font size="+2">S</font>&nbsp;
+<a href="#D"><font size="-2">D</font></a>
+<a href="#E"><font size="-2">E</font></a>
+<a href="#G"><font size="-2">G</font></a>
+<a href="#N"><font size="-2">N</font></a>
+<a href="#O"><font size="-2">O</font></a>
+<a href="#R"><font size="-2">R</font></a>
+ <a href="#topheader"><font size="-2">TOP</font></a>
+<p><div style="line-height:1.5em;color:black">
+<i>showDialog</i><br>
+&nbsp;&nbsp;<nobr><A HREF="android.app.Activity.html#android.app.Activity.showDialog_changed(int, android.os.Bundle)" class="hiddenlink" target="rightframe">type&nbsp;
+(<code>int, Bundle</code>)&nbsp;in&nbsp;android.app.Activity
+</A></nobr><br>
+&nbsp;&nbsp;<nobr><A HREF="android.app.Activity.html#android.app.Activity.showDialog_changed(int)" class="hiddenlink" target="rightframe">type&nbsp;
+(<code>int</code>)&nbsp;in&nbsp;android.app.Activity
+</A></nobr><br>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/methods_index_removals.html b/docs/html/sdk/api_diff/13/changes/methods_index_removals.html
new file mode 100644
index 000000000000..b5aea4f9d673
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/methods_index_removals.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Method Removals Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Methods" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="methods_index_all.html" class="staysblack">All Methods</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<A HREF="methods_index_additions.html"xclass="hiddenlink">Additions</A>
+ <br>
+<A HREF="methods_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/packages_index_additions.html b/docs/html/sdk/api_diff/13/changes/packages_index_additions.html
new file mode 100644
index 000000000000..1776064fe6a9
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/packages_index_additions.html
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Package Additions Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Packages" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="packages_index_all.html" class="staysblack">All Packages</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<font color="#999999">Additions</font>
+ <br>
+<A HREF="packages_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<br>
+<div id="indexTableEntries">
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/packages_index_all.html b/docs/html/sdk/api_diff/13/changes/packages_index_all.html
new file mode 100644
index 000000000000..c23f4a6f815f
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/packages_index_all.html
@@ -0,0 +1,75 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Package Differences Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Packages" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<b>Packages</b>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<font color="#999999">Additions</font>
+ <br>
+<A HREF="packages_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<br>
+<div id="indexTableEntries">
+<A NAME="A"></A>
+<A HREF="pkg_android.html" class="hiddenlink" target="rightframe">android</A><br>
+<A HREF="pkg_android.app.html" class="hiddenlink" target="rightframe">android.app</A><br>
+<A HREF="pkg_android.content.pm.html" class="hiddenlink" target="rightframe">android.content.pm</A><br>
+<A HREF="pkg_android.content.res.html" class="hiddenlink" target="rightframe">android.content.res</A><br>
+<A HREF="pkg_android.graphics.html" class="hiddenlink" target="rightframe">android.graphics</A><br>
+<A HREF="pkg_android.hardware.usb.html" class="hiddenlink" target="rightframe">android.hardware.usb</A><br>
+<A HREF="pkg_android.net.html" class="hiddenlink" target="rightframe">android.net</A><br>
+<A HREF="pkg_android.os.html" class="hiddenlink" target="rightframe">android.os</A><br>
+<A HREF="pkg_android.telephony.html" class="hiddenlink" target="rightframe">android.telephony</A><br>
+<A HREF="pkg_android.util.html" class="hiddenlink" target="rightframe">android.util</A><br>
+<A HREF="pkg_android.view.html" class="hiddenlink" target="rightframe">android.view</A><br>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/packages_index_changes.html b/docs/html/sdk/api_diff/13/changes/packages_index_changes.html
new file mode 100644
index 000000000000..d00b44953c61
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/packages_index_changes.html
@@ -0,0 +1,75 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Package Changes Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Packages" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="packages_index_all.html" class="staysblack">All Packages</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<font color="#999999">Additions</font>
+ <br>
+<b>Changes</b>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<br>
+<div id="indexTableEntries">
+<A NAME="A"></A>
+<A HREF="pkg_android.html" class="hiddenlink" target="rightframe">android</A><br>
+<A HREF="pkg_android.app.html" class="hiddenlink" target="rightframe">android.app</A><br>
+<A HREF="pkg_android.content.pm.html" class="hiddenlink" target="rightframe">android.content.pm</A><br>
+<A HREF="pkg_android.content.res.html" class="hiddenlink" target="rightframe">android.content.res</A><br>
+<A HREF="pkg_android.graphics.html" class="hiddenlink" target="rightframe">android.graphics</A><br>
+<A HREF="pkg_android.hardware.usb.html" class="hiddenlink" target="rightframe">android.hardware.usb</A><br>
+<A HREF="pkg_android.net.html" class="hiddenlink" target="rightframe">android.net</A><br>
+<A HREF="pkg_android.os.html" class="hiddenlink" target="rightframe">android.os</A><br>
+<A HREF="pkg_android.telephony.html" class="hiddenlink" target="rightframe">android.telephony</A><br>
+<A HREF="pkg_android.util.html" class="hiddenlink" target="rightframe">android.util</A><br>
+<A HREF="pkg_android.view.html" class="hiddenlink" target="rightframe">android.view</A><br>
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/packages_index_removals.html b/docs/html/sdk/api_diff/13/changes/packages_index_removals.html
new file mode 100644
index 000000000000..9fd0f7e9a8e7
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/packages_index_removals.html
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+Package Removals Index
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY class="gc-documentation" style="padding:12px;">
+<a NAME="topheader"></a>
+<table summary="Index for Packages" width="100%" class="jdiffIndex" border="0" cellspacing="0" cellpadding="0" style="padding-bottom:0;margin-bottom:0;">
+ <tr>
+ <th class="indexHeader">
+ Filter the Index:
+ </th>
+ </tr>
+ <tr>
+ <td class="indexText" style="line-height:1.3em;padding-left:2em;">
+<a href="packages_index_all.html" class="staysblack">All Packages</a>
+ <br>
+<font color="#999999">Removals</font>
+ <br>
+<font color="#999999">Additions</font>
+ <br>
+<A HREF="packages_index_changes.html"xclass="hiddenlink">Changes</A>
+ </td>
+ </tr>
+</table>
+<div id="indexTableCaption" style="background-color:#eee;padding:0 4px 0 4px;font-size:11px;margin-bottom:1em;">
+Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style="color:#069"><strike>Removed</strike></span>, <span style="color:#069">Changed</span></font>
+</div>
+<br>
+<div id="indexTableEntries">
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/pkg_android.app.html b/docs/html/sdk/api_diff/13/changes/pkg_android.app.html
new file mode 100644
index 000000000000..d728895ae2fe
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/pkg_android.app.html
@@ -0,0 +1,190 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.app
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Package <A HREF="../../../../reference/android/app/package-summary.html" target="_top"><font size="+1"><code>android.app</code></font></A>
+</H2>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Classes" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Classes</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="Fragment.SavedState"></A>
+ <nobr><A HREF="../../../../reference/android/app/Fragment.SavedState.html" target="_top"><code>Fragment.SavedState</code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Classes" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="Activity"></A>
+ <nobr><A HREF="android.app.Activity.html">Activity</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="ActivityGroup"></A>
+ <nobr><A HREF="android.app.ActivityGroup.html">ActivityGroup</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="Fragment"></A>
+ <nobr><A HREF="android.app.Fragment.html">Fragment</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="FragmentManager"></A>
+ <nobr><A HREF="android.app.FragmentManager.html">FragmentManager</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="FragmentTransaction"></A>
+ <nobr><A HREF="android.app.FragmentTransaction.html">FragmentTransaction</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="KeyguardManager"></A>
+ <nobr><A HREF="android.app.KeyguardManager.html">KeyguardManager</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="KeyguardManager.KeyguardLock"></A>
+ <nobr><A HREF="android.app.KeyguardManager.KeyguardLock.html">KeyguardManager.KeyguardLock</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="LocalActivityManager"></A>
+ <nobr><A HREF="android.app.LocalActivityManager.html">LocalActivityManager</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="TabActivity"></A>
+ <nobr><A HREF="android.app.TabActivity.html">TabActivity</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/pkg_android.content.pm.html b/docs/html/sdk/api_diff/13/changes/pkg_android.content.pm.html
new file mode 100644
index 000000000000..60ab502ada65
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/pkg_android.content.pm.html
@@ -0,0 +1,133 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.content.pm
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Package <A HREF="../../../../reference/android/content/pm/package-summary.html" target="_top"><font size="+1"><code>android.content.pm</code></font></A>
+</H2>
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Classes" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="ActivityInfo"></A>
+ <nobr><A HREF="android.content.pm.ActivityInfo.html">ActivityInfo</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="ApplicationInfo"></A>
+ <nobr><A HREF="android.content.pm.ApplicationInfo.html">ApplicationInfo</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="PackageManager"></A>
+ <nobr><A HREF="android.content.pm.PackageManager.html">PackageManager</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/pkg_android.content.res.html b/docs/html/sdk/api_diff/13/changes/pkg_android.content.res.html
new file mode 100644
index 000000000000..01c31d04d4dd
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/pkg_android.content.res.html
@@ -0,0 +1,119 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.content.res
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Package <A HREF="../../../../reference/android/content/res/package-summary.html" target="_top"><font size="+1"><code>android.content.res</code></font></A>
+</H2>
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Classes" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="Configuration"></A>
+ <nobr><A HREF="android.content.res.Configuration.html">Configuration</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/pkg_android.graphics.html b/docs/html/sdk/api_diff/13/changes/pkg_android.graphics.html
new file mode 100644
index 000000000000..31ddb13aa945
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/pkg_android.graphics.html
@@ -0,0 +1,126 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.graphics
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Package <A HREF="../../../../reference/android/graphics/package-summary.html" target="_top"><font size="+1"><code>android.graphics</code></font></A>
+</H2>
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Classes" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="Point"></A>
+ <nobr><A HREF="android.graphics.Point.html">Point</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="PointF"></A>
+ <nobr><A HREF="android.graphics.PointF.html">PointF</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/pkg_android.hardware.usb.html b/docs/html/sdk/api_diff/13/changes/pkg_android.hardware.usb.html
new file mode 100644
index 000000000000..ec768c93c528
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/pkg_android.hardware.usb.html
@@ -0,0 +1,119 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.hardware.usb
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Package <A HREF="../../../../reference/android/hardware/usb/package-summary.html" target="_top"><font size="+1"><code>android.hardware.usb</code></font></A>
+</H2>
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Classes" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="UsbDeviceConnection"></A>
+ <nobr><A HREF="android.hardware.usb.UsbDeviceConnection.html">UsbDeviceConnection</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/pkg_android.html b/docs/html/sdk/api_diff/13/changes/pkg_android.html
new file mode 100644
index 000000000000..6b146371b993
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/pkg_android.html
@@ -0,0 +1,133 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Package <A HREF="../../../../reference/android/package-summary.html" target="_top"><font size="+1"><code>android</code></font></A>
+</H2>
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Classes" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="Manifest.permission"></A>
+ <nobr><A HREF="android.Manifest.permission.html">Manifest.permission</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="R.attr"></A>
+ <nobr><A HREF="android.R.attr.html">R.attr</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="R.style"></A>
+ <nobr><A HREF="android.R.style.html">R.style</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/pkg_android.net.html b/docs/html/sdk/api_diff/13/changes/pkg_android.net.html
new file mode 100644
index 000000000000..f3f82cc9bdcc
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/pkg_android.net.html
@@ -0,0 +1,119 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.net
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Package <A HREF="../../../../reference/android/net/package-summary.html" target="_top"><font size="+1"><code>android.net</code></font></A>
+</H2>
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Classes" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="ConnectivityManager"></A>
+ <nobr><A HREF="android.net.ConnectivityManager.html">ConnectivityManager</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/pkg_android.os.html b/docs/html/sdk/api_diff/13/changes/pkg_android.os.html
new file mode 100644
index 000000000000..b9a8c09c3c83
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/pkg_android.os.html
@@ -0,0 +1,162 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.os
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Package <A HREF="../../../../reference/android/os/package-summary.html" target="_top"><font size="+1"><code>android.os</code></font></A>
+</H2>
+<p>
+<a NAME="Added"></a>
+<TABLE summary="Added Interfaces" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Added Interfaces</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="Parcelable.ClassLoaderCreator"></A>
+ <nobr><A HREF="../../../../reference/android/os/Parcelable.ClassLoaderCreator.html" target="_top"><code><I>Parcelable.ClassLoaderCreator</I></code></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Classes and Interfaces" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Changed Classes and Interfaces</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="Binder"></A>
+ <nobr><A HREF="android.os.Binder.html">Binder</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="Build.VERSION_CODES"></A>
+ <nobr><A HREF="android.os.Build.VERSION_CODES.html">Build.VERSION_CODES</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="IBinder"></A>
+ <nobr><A HREF="android.os.IBinder.html"><I>IBinder</I></A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="ParcelFileDescriptor"></A>
+ <nobr><A HREF="android.os.ParcelFileDescriptor.html">ParcelFileDescriptor</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="PowerManager"></A>
+ <nobr><A HREF="android.os.PowerManager.html">PowerManager</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/pkg_android.telephony.html b/docs/html/sdk/api_diff/13/changes/pkg_android.telephony.html
new file mode 100644
index 000000000000..9a00876b5b1d
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/pkg_android.telephony.html
@@ -0,0 +1,119 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.telephony
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Package <A HREF="../../../../reference/android/telephony/package-summary.html" target="_top"><font size="+1"><code>android.telephony</code></font></A>
+</H2>
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Classes" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="TelephonyManager"></A>
+ <nobr><A HREF="android.telephony.TelephonyManager.html">TelephonyManager</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/pkg_android.util.html b/docs/html/sdk/api_diff/13/changes/pkg_android.util.html
new file mode 100644
index 000000000000..0d9295650420
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/pkg_android.util.html
@@ -0,0 +1,119 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.util
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Package <A HREF="../../../../reference/android/util/package-summary.html" target="_top"><font size="+1"><code>android.util</code></font></A>
+</H2>
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Classes" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="DisplayMetrics"></A>
+ <nobr><A HREF="android.util.DisplayMetrics.html">DisplayMetrics</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/changes/pkg_android.view.html b/docs/html/sdk/api_diff/13/changes/pkg_android.view.html
new file mode 100644
index 000000000000..22fde469fa1e
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/changes/pkg_android.view.html
@@ -0,0 +1,126 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML style="overflow:auto;">
+<HEAD>
+<meta name="generator" content="JDiff v1.1.0">
+<!-- Generated by the JDiff Javadoc doclet -->
+<!-- (http://www.jdiff.org) -->
+<meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
+<meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
+<TITLE>
+android.view
+</TITLE>
+<link href="../../../../assets/android-developer-docs.css" rel="stylesheet" type="text/css" />
+<link href="../stylesheet-jdiff.css" rel="stylesheet" type="text/css" />
+<noscript>
+<style type="text/css">
+body{overflow:auto;}
+#body-content{position:relative; top:0;}
+#doc-content{overflow:visible;border-left:3px solid #666;}
+#side-nav{padding:0;}
+#side-nav .toggle-list ul {display:block;}
+#resize-packages-nav{border-bottom:3px solid #666;}
+</style>
+</noscript>
+<style type="text/css">
+</style>
+</HEAD>
+<BODY>
+<!-- Start of nav bar -->
+<a name="top"></a>
+<div id="header" style="margin-bottom:0;padding-bottom:0;">
+<div id="headerLeft">
+<a href="../../../../index.html" tabindex="-1" target="_top"><img src="../../../../assets/images/bg_logo.png" alt="Android Developers" /></a>
+</div>
+ <div id="headerRight">
+ <div id="headerLinks">
+<!-- <img src="/assets/images/icon_world.jpg" alt="" /> -->
+<span class="text">
+<!-- &nbsp;<a href="#">English</a> | -->
+<nobr><a href="http://developer.android.com" target="_top">Android Developers</a> | <a href="http://www.android.com" target="_top">Android.com</a></nobr>
+</span>
+</div>
+ <div class="and-diff-id" style="margin-top:6px;margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td colspan="2" class="diffspechead">API Diff Specification</td>
+ </tr>
+ <tr>
+ <td class="diffspec" style="padding-top:.25em">To Level:</td>
+ <td class="diffvaluenew" style="padding-top:.25em">13</td>
+ </tr>
+ <tr>
+ <td class="diffspec">From Level:</td>
+ <td class="diffvalueold">12</td>
+ </tr>
+ <tr>
+ <td class="diffspec">Generated</td>
+ <td class="diffvalue">2011.06.29 10:50</td>
+ </tr>
+ </table>
+ </div><!-- End and-diff-id -->
+ <div class="and-diff-id" style="margin-right:8px;">
+ <table class="diffspectable">
+ <tr>
+ <td class="diffspec" colspan="2"><a href="jdiff_statistics.html">Statistics</a>
+ </tr>
+ </table>
+ </div> <!-- End and-diff-id -->
+ </div> <!-- End headerRight -->
+ </div> <!-- End header -->
+<div id="body-content" xstyle="padding:12px;padding-right:18px;">
+<div id="doc-content" style="position:relative;">
+<div id="mainBodyFluid">
+<H2>
+Package <A HREF="../../../../reference/android/view/package-summary.html" target="_top"><font size="+1"><code>android.view</code></font></A>
+</H2>
+<p>
+<a NAME="Changed"></a>
+<TABLE summary="Changed Classes" WIDTH="100%">
+<TR>
+ <TH VALIGN="TOP" COLSPAN=2>Changed Classes</FONT></TD>
+</TH>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="Display"></A>
+ <nobr><A HREF="android.view.Display.html">Display</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
+ <TD VALIGN="TOP" WIDTH="25%">
+ <A NAME="KeyEvent"></A>
+ <nobr><A HREF="android.view.KeyEvent.html">KeyEvent</A></nobr>
+ </TD>
+ <TD>&nbsp;</TD>
+</TR>
+</TABLE>
+&nbsp;
+ </div>
+ <div id="footer">
+ <div id="copyright">
+ Except as noted, this content is licensed under
+ <a href="http://creativecommons.org/licenses/by/2.5/"> Creative Commons Attribution 2.5</a>.
+ For details and restrictions, see the <a href="/license.html">Content License</a>.
+ </div>
+ <div id="footerlinks">
+ <p>
+ <a href="http://www.android.com/terms.html">Site Terms of Service</a> -
+ <a href="http://www.android.com/privacy.html">Privacy Policy</a> -
+ <a href="http://www.android.com/branding.html">Brand Guidelines</a>
+ </p>
+ </div>
+ </div> <!-- end footer -->
+ </div><!-- end doc-content -->
+ </div> <!-- end body-content -->
+<script src="http://www.google-analytics.com/ga.js" type="text/javascript">
+</script>
+<script type="text/javascript">
+ try {
+ var pageTracker = _gat._getTracker("UA-5831155-1");
+ pageTracker._setAllowAnchor(true);
+ pageTracker._initData();
+ pageTracker._trackPageview();
+ } catch(e) {}
+</script>
+</BODY>
+</HTML>
diff --git a/docs/html/sdk/api_diff/13/stylesheet-jdiff.css b/docs/html/sdk/api_diff/13/stylesheet-jdiff.css
new file mode 100644
index 000000000000..edafaa3da3e5
--- /dev/null
+++ b/docs/html/sdk/api_diff/13/stylesheet-jdiff.css
@@ -0,0 +1,44 @@
+
+/* (http://www.jdiff.org) */
+
+div.and-diff-id {border: 1px solid #eee;position:relative;float:right;clear:both;padding:0px;}
+table.diffspectable {border:1px;padding:0px;margin:0px;}
+.diffspechead {background-color:#eee;}
+.diffspectable tr {border:0px;padding:0px;}
+.diffspectable td {background-color:eee;border:0px;font-size:90%;font-weight:normal;padding:0px;padding-left:1px;padding-right:1px;text-align:center;color:777;}
+td.diffvalueold {color:orange;background-color:white;border:0px;font-size:80%;font-style:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;}
+td.diffvaluenew {color:green;background-color:white;border:0px;font-size:80%;font-weight:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;}
+td.diffvalue {color:444;background-color:white;border:0px;font-size:80%;font-weight:normal;text-align:left;padding:0px;padding-left:1px;padding-right:1px;line-height:.95em;}
+td.diffspec {background-color:white;border:0px;font-size:80%;font-weight:normal;padding:1px;color:444;text-align:right;padding-right:.5em;line-height:.95em;}
+tt {font-size:11pt;font-family:monospace;}
+.indexHeader {
+ font-size:96%;
+ line-height:.8em;}
+.jdiffIndex td {
+ font-size:96%;
+ xline-height:.8em;
+ padding:2px;
+ padding-left:1em;}
+.indexText {
+ font-size:100%;
+ padding-left:1em;}
+#indexTableCaption {
+ font-size:96%;
+ margin-top:.25em;
+ margin-bottom:0;
+ }
+.hiddenlink {
+ font-size:96%;
+ line-height:.8em;
+ text-decoration:none;}
+a {
+ text-decoration:none;}
+a:hover {
+ text-decoration:underline;}
+.indexBox {
+ border: 1px solid red;
+ margin:1em 0 0 0;}
+.letterIndexHead {
+ font-size: 1.5em;font-weight:9;
+ margin:0 0 0em 0;
+ border: 1px solid red;}
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 0539adb20a14..829ed52a73d9 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -76,6 +76,14 @@ class="new">new!</span></li>
</ul>
<ul>
<li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>sdk/android-3.2.html">
+ <span class="en">Android 3.2 Platform</span></a> <span class="new">new!</span></div>
+ <ul>
+ <!-- <li><a href="<?cs var:toroot ?>sdk/android-3.2-highlights.html">Platform Highlights</a></li> -->
+ <li><a href="<?cs var:toroot ?>sdk/api_diff/13/changes.html">API Differences Report &raquo;</a></li>
+ </ul>
+ </li>
+ <li class="toggle-list">
<div><a href="<?cs var:toroot ?>sdk/android-3.1.html">
<span class="en">Android 3.1 Platform</span></a></div>
<ul>
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 4a85faf7dd2e..3476bd5aa646 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -504,6 +504,7 @@ nAllocationCopyToBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc,
void* ptr = bitmap.getPixels();
rsAllocationCopyToBitmap(con, (RsAllocation)alloc, ptr, bitmap.getSize());
bitmap.unlockPixels();
+ bitmap.notifyPixelsChanged();
}
static void ReleaseBitmapCallback(void *bmp)
diff --git a/include/gui/ISurfaceTexture.h b/include/gui/ISurfaceTexture.h
index e76442549839..1eda64669599 100644
--- a/include/gui/ISurfaceTexture.h
+++ b/include/gui/ISurfaceTexture.h
@@ -51,7 +51,7 @@ protected:
// the given slot index, and the client is expected to mirror the
// slot->buffer mapping so that it's not necessary to transfer a
// GraphicBuffer for every dequeue operation.
- virtual sp<GraphicBuffer> requestBuffer(int slot) = 0;
+ virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0;
// setBufferCount sets the number of buffer slots available. Calling this
// will also cause all buffer slots to be emptied. The caller should empty
@@ -79,8 +79,8 @@ protected:
// must be monotonically increasing. Its other properties (zero point, etc)
// are client-dependent, and should be documented by the client.
//
- // outWidth, outHeight and outTransform are filed with the default width
- // default height of the window and current transform applied to buffers,
+ // outWidth, outHeight and outTransform are filled with the default width
+ // and height of the window and current transform applied to buffers,
// respectively.
virtual status_t queueBuffer(int slot, int64_t timestamp,
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) = 0;
@@ -94,12 +94,6 @@ protected:
virtual status_t setTransform(uint32_t transform) = 0;
virtual status_t setScalingMode(int mode) = 0;
- // getAllocator retrieves the binder object that must be referenced as long
- // as the GraphicBuffers dequeued from this ISurfaceTexture are referenced.
- // Holding this binder reference prevents SurfaceFlinger from freeing the
- // buffers before the client is done with them.
- virtual sp<IBinder> getAllocator() = 0;
-
// query retrieves some information for this surface
// 'what' tokens allowed are that of android_natives.h
virtual int query(int what, int* value) = 0;
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index 945f4bcd6890..134c208f4d26 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -69,7 +69,7 @@ public:
// SurfaceTexture object (i.e. they are not owned by the client).
virtual status_t setBufferCount(int bufferCount);
- virtual sp<GraphicBuffer> requestBuffer(int buf);
+ virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf);
// dequeueBuffer gets the next buffer slot index for the client to use. If a
// buffer slot is available then that slot index is written to the location
@@ -190,6 +190,17 @@ public:
// getCurrentScalingMode returns the scaling mode of the current buffer
uint32_t getCurrentScalingMode() const;
+ // abandon frees all the buffers and puts the SurfaceTexture into the
+ // 'abandoned' state. Once put in this state the SurfaceTexture can never
+ // leave it. When in the 'abandoned' state, all methods of the
+ // ISurfaceTexture interface will fail with the NO_INIT error.
+ //
+ // Note that while calling this method causes all the buffers to be freed
+ // from the perspective of the the SurfaceTexture, if there are additional
+ // references on the buffers (e.g. if a buffer is referenced by a client or
+ // by OpenGL ES as a texture) then those buffer will remain allocated.
+ void abandon();
+
// dump our state in a String
void dump(String8& result) const;
void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
@@ -343,8 +354,7 @@ private:
// mCurrentTextureBuf is the graphic buffer of the current texture. It's
// possible that this buffer is not associated with any buffer slot, so we
- // must track it separately in order to properly use
- // IGraphicBufferAlloc::freeAllGraphicBuffersExcept.
+ // must track it separately in order to support the getCurrentBuffer method.
sp<GraphicBuffer> mCurrentTextureBuf;
// mCurrentCrop is the crop rectangle that applies to the current texture.
@@ -412,6 +422,13 @@ private:
typedef Vector<int> Fifo;
Fifo mQueue;
+ // mAbandoned indicates that the SurfaceTexture will no longer be used to
+ // consume images buffers pushed to it using the ISurfaceTexture interface.
+ // It is initialized to false, and set to true in the abandon method. A
+ // SurfaceTexture that has been abandoned will return the NO_INIT error from
+ // all ISurfaceTexture methods capable of returning an error.
+ bool mAbandoned;
+
// mMutex is the mutex used to prevent concurrent access to the member
// variables of SurfaceTexture objects. It must be locked whenever the
// member variables are accessed.
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index 829d8abf7057..56f029f0c254 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -106,10 +106,6 @@ private:
// interactions with the server using this interface.
sp<ISurfaceTexture> mSurfaceTexture;
- // mAllocator is the binder object that is referenced to prevent the
- // dequeued buffers from being freed prematurely.
- sp<IBinder> mAllocator;
-
// mSlots stores the buffers that have been allocated for each buffer slot.
// It is initialized to null pointers, and gets filled in with the result of
// ISurfaceTexture::requestBuffer when the client dequeues a buffer from a
diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h
index dd93fd8c1a42..496b23e5f04f 100644
--- a/include/media/AudioEffect.h
+++ b/include/media/AudioEffect.h
@@ -188,7 +188,7 @@ public:
* sessionID: audio session this effect is associated to. If 0, the effect will be global to
* the output mix. If not 0, the effect will be applied to all players
* (AudioTrack or MediaPLayer) within the same audio session.
- * output: HAL audio output stream to which this effect must be attached. Leave at 0 for
+ * io: HAL audio output or input stream to which this effect must be attached. Leave at 0 for
* automatic output selection by AudioFlinger.
*/
@@ -198,7 +198,7 @@ public:
effect_callback_t cbf = 0,
void* user = 0,
int sessionId = 0,
- audio_io_handle_t output = 0
+ audio_io_handle_t io = 0
);
/* Constructor.
@@ -210,7 +210,7 @@ public:
effect_callback_t cbf = 0,
void* user = 0,
int sessionId = 0,
- audio_io_handle_t output = 0
+ audio_io_handle_t io = 0
);
/* Terminates the AudioEffect and unregisters it from AudioFlinger.
@@ -232,7 +232,7 @@ public:
effect_callback_t cbf = 0,
void* user = 0,
int sessionId = 0,
- audio_io_handle_t output = 0
+ audio_io_handle_t io = 0
);
/* Result of constructing the AudioEffect. This must be checked
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 89213b7086e4..f20e2343d3c9 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -160,7 +160,8 @@ public:
uint32_t samplingRate = 0,
uint32_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = AUDIO_CHANNEL_IN_MONO,
- audio_in_acoustics_t acoustics = (audio_in_acoustics_t)0);
+ audio_in_acoustics_t acoustics = (audio_in_acoustics_t)0,
+ int sessionId = 0);
static status_t startInput(audio_io_handle_t input);
static status_t stopInput(audio_io_handle_t input);
static void releaseInput(audio_io_handle_t input);
@@ -175,7 +176,7 @@ public:
static audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc);
static status_t registerEffect(effect_descriptor_t *desc,
- audio_io_handle_t output,
+ audio_io_handle_t io,
uint32_t strategy,
int session,
int id);
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 0fc8dbf127f9..86b9f85f8635 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -65,7 +65,8 @@ public:
uint32_t samplingRate = 0,
uint32_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = 0,
- audio_in_acoustics_t acoustics = (audio_in_acoustics_t)0) = 0;
+ audio_in_acoustics_t acoustics = (audio_in_acoustics_t)0,
+ int audioSession = 0) = 0;
virtual status_t startInput(audio_io_handle_t input) = 0;
virtual status_t stopInput(audio_io_handle_t input) = 0;
virtual void releaseInput(audio_io_handle_t input) = 0;
@@ -78,7 +79,7 @@ public:
virtual uint32_t getDevicesForStream(audio_stream_type_t stream) = 0;
virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc) = 0;
virtual status_t registerEffect(effect_descriptor_t *desc,
- audio_io_handle_t output,
+ audio_io_handle_t io,
uint32_t strategy,
int session,
int id) = 0;
diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h
index a73267d92587..007aea6c0362 100644
--- a/include/media/IMediaRecorder.h
+++ b/include/media/IMediaRecorder.h
@@ -26,6 +26,7 @@ class Surface;
class ICamera;
class ICameraRecordingProxy;
class IMediaRecorderClient;
+class ISurfaceTexture;
class IMediaRecorder: public IInterface
{
@@ -55,6 +56,7 @@ public:
virtual status_t init() = 0;
virtual status_t close() = 0;
virtual status_t release() = 0;
+ virtual sp<ISurfaceTexture> querySurfaceMediaSource() = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index ed26e63da9e3..69d50011d16f 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -45,6 +45,18 @@ enum camcorder_quality {
CAMCORDER_QUALITY_TIME_LAPSE_LIST_END = 1006,
};
+/**
+ *Set CIF as default maximum import and export resolution of video editor.
+ *The maximum import and export resolutions are platform specific,
+ *which should be defined in media_profiles.xml.
+ */
+enum videoeditor_capability {
+ VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH = 352,
+ VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT = 288,
+ VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH = 352,
+ VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT = 288,
+};
+
enum video_decoder {
VIDEO_DECODER_WMV,
};
@@ -117,6 +129,17 @@ public:
int getVideoEncoderParamByName(const char *name, video_encoder codec) const;
/**
+ * Returns the value for the given param name for the video editor cap
+ * param or -1 if error.
+ * Supported param name are:
+ * videoeditor.input.width.max - max input video frame width
+ * videoeditor.input.height.max - max input video frame height
+ * videoeditor.output.width.max - max output video frame width
+ * videoeditor.output.height.max - max output video frame height
+ */
+ int getVideoEditorCapParamByName(const char *name) const;
+
+ /**
* Returns the audio encoders supported.
*/
Vector<audio_encoder> getAudioEncoders() const;
@@ -164,7 +187,7 @@ private:
MediaProfiles& operator=(const MediaProfiles&); // Don't call me
MediaProfiles(const MediaProfiles&); // Don't call me
- MediaProfiles() {} // Dummy default constructor
+ MediaProfiles() { mVideoEditorCap = NULL; } // Dummy default constructor
~MediaProfiles(); // Don't delete me
struct VideoCodec {
@@ -310,6 +333,22 @@ private:
Vector<int> mLevels;
};
+ struct VideoEditorCap {
+ VideoEditorCap(int inFrameWidth, int inFrameHeight,
+ int outFrameWidth, int outFrameHeight)
+ : mMaxInputFrameWidth(inFrameWidth),
+ mMaxInputFrameHeight(inFrameHeight),
+ mMaxOutputFrameWidth(outFrameWidth),
+ mMaxOutputFrameHeight(outFrameHeight) {}
+
+ ~VideoEditorCap() {}
+
+ int mMaxInputFrameWidth;
+ int mMaxInputFrameHeight;
+ int mMaxOutputFrameWidth;
+ int mMaxOutputFrameHeight;
+ };
+
int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const;
void initRequiredProfileRefs(const Vector<int>& cameraIds);
int getRequiredProfileRefIndex(int cameraId);
@@ -321,6 +360,7 @@ private:
static void logAudioEncoderCap(const AudioEncoderCap& cap);
static void logVideoDecoderCap(const VideoDecoderCap& cap);
static void logAudioDecoderCap(const AudioDecoderCap& cap);
+ static void logVideoEditorCap(const VideoEditorCap& cap);
// If the xml configuration file does exist, use the settings
// from the xml
@@ -332,6 +372,8 @@ private:
static VideoDecoderCap* createVideoDecoderCap(const char **atts);
static VideoEncoderCap* createVideoEncoderCap(const char **atts);
static AudioEncoderCap* createAudioEncoderCap(const char **atts);
+ static VideoEditorCap* createVideoEditorCap(
+ const char **atts, MediaProfiles *profiles);
static CamcorderProfile* createCamcorderProfile(
int cameraId, const char **atts, Vector<int>& cameraIds);
@@ -375,6 +417,7 @@ private:
static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles);
static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles);
static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles);
+ static void createDefaultVideoEditorCap(MediaProfiles *profiles);
static VideoEncoderCap* createDefaultH263VideoEncoderCap();
static VideoEncoderCap* createDefaultM4vVideoEncoderCap();
static AudioEncoderCap* createDefaultAmrNBEncoderCap();
@@ -431,6 +474,7 @@ private:
RequiredProfiles *mRequiredProfileRefs;
Vector<int> mCameraIds;
+ VideoEditorCap* mVideoEditorCap;
};
}; // namespace android
diff --git a/include/media/MediaRecorderBase.h b/include/media/MediaRecorderBase.h
index 1c08969a0d5c..ef799f5cff26 100644
--- a/include/media/MediaRecorderBase.h
+++ b/include/media/MediaRecorderBase.h
@@ -26,6 +26,7 @@ namespace android {
class ICameraRecordingProxy;
class Surface;
+class ISurfaceTexture;
struct MediaRecorderBase {
MediaRecorderBase() {}
@@ -54,6 +55,7 @@ struct MediaRecorderBase {
virtual status_t reset() = 0;
virtual status_t getMaxAmplitude(int *max) = 0;
virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
+ virtual sp<ISurfaceTexture> querySurfaceMediaSource() const = 0;
private:
MediaRecorderBase(const MediaRecorderBase &);
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index af12d3c59c1f..72d3736296d1 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -31,12 +31,15 @@ class Surface;
class IMediaRecorder;
class ICamera;
class ICameraRecordingProxy;
+class ISurfaceTexture;
+class SurfaceTextureClient;
typedef void (*media_completion_f)(status_t status, void *cookie);
enum video_source {
VIDEO_SOURCE_DEFAULT = 0,
VIDEO_SOURCE_CAMERA = 1,
+ VIDEO_SOURCE_GRALLOC_BUFFER = 2,
VIDEO_SOURCE_LIST_END // must be last - used to validate audio source type
};
@@ -226,6 +229,7 @@ public:
status_t close();
status_t release();
void notify(int msg, int ext1, int ext2);
+ sp<ISurfaceTexture> querySurfaceMediaSourceFromMediaServer();
private:
void doCleanUp();
@@ -233,6 +237,12 @@ private:
sp<IMediaRecorder> mMediaRecorder;
sp<MediaRecorderListener> mListener;
+
+ // Reference toISurfaceTexture
+ // for encoding GL Frames. That is useful only when the
+ // video source is set to VIDEO_SOURCE_GRALLOC_BUFFER
+ sp<ISurfaceTexture> mSurfaceMediaSource;
+
media_recorder_states mCurrentState;
bool mIsAudioSourceSet;
bool mIsVideoSourceSet;
diff --git a/include/media/mediascanner.h b/include/media/mediascanner.h
index 765c0399be30..803bffb77f17 100644
--- a/include/media/mediascanner.h
+++ b/include/media/mediascanner.h
@@ -23,23 +23,33 @@
#include <utils/Errors.h>
#include <pthread.h>
+struct dirent;
+
namespace android {
class MediaScannerClient;
class StringArray;
+enum MediaScanResult {
+ // This file or directory was scanned successfully.
+ MEDIA_SCAN_RESULT_OK,
+ // This file or directory was skipped because it was not found, could
+ // not be opened, was of an unsupported type, or was malfored in some way.
+ MEDIA_SCAN_RESULT_SKIPPED,
+ // The scan should be aborted due to a fatal error such as out of memory
+ // or an exception.
+ MEDIA_SCAN_RESULT_ERROR,
+};
+
struct MediaScanner {
MediaScanner();
virtual ~MediaScanner();
- virtual status_t processFile(
- const char *path, const char *mimeType,
- MediaScannerClient &client) = 0;
+ virtual MediaScanResult processFile(
+ const char *path, const char *mimeType, MediaScannerClient &client) = 0;
- typedef bool (*ExceptionCheck)(void* env);
- virtual status_t processDirectory(
- const char *path, MediaScannerClient &client,
- ExceptionCheck exceptionCheck, void *exceptionEnv);
+ virtual MediaScanResult processDirectory(
+ const char *path, MediaScannerClient &client);
void setLocale(const char *locale);
@@ -53,9 +63,11 @@ private:
// current locale (like "ja_JP"), created/destroyed with strdup()/free()
char *mLocale;
- status_t doProcessDirectory(
- char *path, int pathRemaining, MediaScannerClient &client,
- bool noMedia, ExceptionCheck exceptionCheck, void *exceptionEnv);
+ MediaScanResult doProcessDirectory(
+ char *path, int pathRemaining, MediaScannerClient &client, bool noMedia);
+ MediaScanResult doProcessDirectoryEntry(
+ char *path, int pathRemaining, MediaScannerClient &client, bool noMedia,
+ struct dirent* entry, char* fileSpot);
MediaScanner(const MediaScanner &);
MediaScanner &operator=(const MediaScanner &);
@@ -68,13 +80,13 @@ public:
virtual ~MediaScannerClient();
void setLocale(const char* locale);
void beginFile();
- bool addStringTag(const char* name, const char* value);
+ status_t addStringTag(const char* name, const char* value);
void endFile();
- virtual bool scanFile(const char* path, long long lastModified,
+ virtual status_t scanFile(const char* path, long long lastModified,
long long fileSize, bool isDirectory, bool noMedia) = 0;
- virtual bool handleStringTag(const char* name, const char* value) = 0;
- virtual bool setMimeType(const char* mimeType) = 0;
+ virtual status_t handleStringTag(const char* name, const char* value) = 0;
+ virtual status_t setMimeType(const char* mimeType) = 0;
protected:
void convertValues(uint32_t encoding);
diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h
index 48d1464336a1..713af92860ef 100644
--- a/include/media/stagefright/DataSource.h
+++ b/include/media/stagefright/DataSource.h
@@ -20,6 +20,7 @@
#include <sys/types.h>
+#include <media/stagefright/MediaErrors.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/List.h>
@@ -61,6 +62,10 @@ public:
return 0;
}
+ virtual status_t reconnectAtOffset(off64_t offset) {
+ return ERROR_UNSUPPORTED;
+ }
+
////////////////////////////////////////////////////////////////////////////
bool sniff(String8 *mimeType, float *confidence, sp<AMessage> *meta);
diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h
index 946a0aaa8f6c..32eed3f79c6c 100644
--- a/include/media/stagefright/HardwareAPI.h
+++ b/include/media/stagefright/HardwareAPI.h
@@ -99,6 +99,13 @@ struct GetAndroidNativeBufferUsageParams {
OMX_U32 nUsage; // OUT
};
+// An enum OMX_COLOR_FormatAndroidOpaque to indicate an opaque colorformat
+// is declared in media/stagefright/openmax/OMX_IVCommon.h
+// This will inform the encoder that the actual
+// colorformat will be relayed by the GRalloc Buffers.
+// OMX_COLOR_FormatAndroidOpaque = 0x7F000001,
+
+
} // namespace android
extern android::OMXPluginBase *createOMXPlugin();
diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h
index 37dbcd8eae84..3818e63ff4e9 100644
--- a/include/media/stagefright/MediaSource.h
+++ b/include/media/stagefright/MediaSource.h
@@ -29,7 +29,7 @@ namespace android {
class MediaBuffer;
class MetaData;
-struct MediaSource : public RefBase {
+struct MediaSource : public virtual RefBase {
MediaSource();
// To be called before any other methods on this object, except
diff --git a/include/media/stagefright/StagefrightMediaScanner.h b/include/media/stagefright/StagefrightMediaScanner.h
index 108acb4c3515..6510a597e9a4 100644
--- a/include/media/stagefright/StagefrightMediaScanner.h
+++ b/include/media/stagefright/StagefrightMediaScanner.h
@@ -26,7 +26,7 @@ struct StagefrightMediaScanner : public MediaScanner {
StagefrightMediaScanner();
virtual ~StagefrightMediaScanner();
- virtual status_t processFile(
+ virtual MediaScanResult processFile(
const char *path, const char *mimeType,
MediaScannerClient &client);
@@ -35,6 +35,10 @@ struct StagefrightMediaScanner : public MediaScanner {
private:
StagefrightMediaScanner(const StagefrightMediaScanner &);
StagefrightMediaScanner &operator=(const StagefrightMediaScanner &);
+
+ MediaScanResult processFileInternal(
+ const char *path, const char *mimeType,
+ MediaScannerClient &client);
};
} // namespace android
diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h
new file mode 100644
index 000000000000..56bd9c315005
--- /dev/null
+++ b/include/media/stagefright/SurfaceMediaSource.h
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_GUI_SURFACEMEDIASOURCE_H
+#define ANDROID_GUI_SURFACEMEDIASOURCE_H
+
+#include <gui/ISurfaceTexture.h>
+
+#include <utils/threads.h>
+#include <utils/Vector.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MediaBuffer.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class IGraphicBufferAlloc;
+class String8;
+class GraphicBuffer;
+
+class SurfaceMediaSource : public BnSurfaceTexture, public MediaSource,
+ public MediaBufferObserver {
+public:
+ enum { MIN_UNDEQUEUED_BUFFERS = 3 };
+ enum {
+ MIN_ASYNC_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS + 1,
+ MIN_SYNC_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS
+ };
+ enum { NUM_BUFFER_SLOTS = 32 };
+ enum { NO_CONNECTED_API = 0 };
+
+ struct FrameAvailableListener : public virtual RefBase {
+ // onFrameAvailable() is called from queueBuffer() is the FIFO is
+ // empty. You can use SurfaceMediaSource::getQueuedCount() to
+ // figure out if there are more frames waiting.
+ // This is called without any lock held can be called concurrently by
+ // multiple threads.
+ virtual void onFrameAvailable() = 0;
+ };
+
+ SurfaceMediaSource(uint32_t bufW, uint32_t bufH);
+
+ virtual ~SurfaceMediaSource();
+
+
+ // For the MediaSource interface for use by StageFrightRecorder:
+ virtual status_t start(MetaData *params = NULL);
+ virtual status_t stop();
+ virtual status_t read(
+ MediaBuffer **buffer, const ReadOptions *options = NULL);
+ virtual sp<MetaData> getFormat();
+
+ // Get / Set the frame rate used for encoding. Default fps = 30
+ status_t setFrameRate(int32_t fps) ;
+ int32_t getFrameRate( ) const;
+
+ // The call for the StageFrightRecorder to tell us that
+ // it is done using the MediaBuffer data so that its state
+ // can be set to FREE for dequeuing
+ virtual void signalBufferReturned(MediaBuffer* buffer);
+ // end of MediaSource interface
+
+ uint32_t getBufferCount( ) const { return mBufferCount;}
+
+
+ // setBufferCount updates the number of available buffer slots. After
+ // calling this all buffer slots are both unallocated and owned by the
+ // SurfaceMediaSource object (i.e. they are not owned by the client).
+ virtual status_t setBufferCount(int bufferCount);
+
+ virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf);
+
+ // dequeueBuffer gets the next buffer slot index for the client to use. If a
+ // buffer slot is available then that slot index is written to the location
+ // pointed to by the buf argument and a status of OK is returned. If no
+ // slot is available then a status of -EBUSY is returned and buf is
+ // unmodified.
+ virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
+ uint32_t format, uint32_t usage);
+
+ // queueBuffer returns a filled buffer to the SurfaceMediaSource. In addition, a
+ // timestamp must be provided for the buffer. The timestamp is in
+ // nanoseconds, and must be monotonically increasing. Its other semantics
+ // (zero point, etc) are client-dependent and should be documented by the
+ // client.
+ virtual status_t queueBuffer(int buf, int64_t timestamp,
+ uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform);
+ virtual void cancelBuffer(int buf);
+
+ // onFrameReceivedLocked informs the buffer consumers (StageFrightRecorder)
+ // or listeners that a frame has been received
+ // The buffer is not made available for dequeueing immediately. We need to
+ // wait to hear from StageFrightRecorder to set the buffer FREE
+ // Make sure this is called when the mutex is locked
+ virtual status_t onFrameReceivedLocked();
+
+ virtual status_t setScalingMode(int mode) { } // no op for encoding
+ virtual int query(int what, int* value);
+
+ // Just confirming to the ISurfaceTexture interface as of now
+ virtual status_t setCrop(const Rect& reg) { return OK; }
+ virtual status_t setTransform(uint32_t transform) {return OK;}
+
+ // setSynchronousMode set whether dequeueBuffer is synchronous or
+ // asynchronous. In synchronous mode, dequeueBuffer blocks until
+ // a buffer is available, the currently bound buffer can be dequeued and
+ // queued buffers will be retired in order.
+ // The default mode is synchronous.
+ // TODO: Clarify the minute differences bet sycn /async
+ // modes (S.Encoder vis-a-vis SurfaceTexture)
+ virtual status_t setSynchronousMode(bool enabled);
+
+ // connect attempts to connect a client API to the SurfaceMediaSource. This
+ // must be called before any other ISurfaceTexture methods are called except
+ // for getAllocator.
+ //
+ // This method will fail if the connect was previously called on the
+ // SurfaceMediaSource and no corresponding disconnect call was made.
+ virtual status_t connect(int api);
+
+ // disconnect attempts to disconnect a client API from the SurfaceMediaSource.
+ // Calling this method will cause any subsequent calls to other
+ // ISurfaceTexture methods to fail except for getAllocator and connect.
+ // Successfully calling connect after this will allow the other methods to
+ // succeed again.
+ //
+ // This method will fail if the the SurfaceMediaSource is not currently
+ // connected to the specified client API.
+ virtual status_t disconnect(int api);
+
+ // getqueuedCount returns the number of queued frames waiting in the
+ // FIFO. In asynchronous mode, this always returns 0 or 1 since
+ // frames are not accumulating in the FIFO.
+ size_t getQueuedCount() const;
+
+ // setBufferCountServer set the buffer count. If the client has requested
+ // a buffer count using setBufferCount, the server-buffer count will
+ // take effect once the client sets the count back to zero.
+ status_t setBufferCountServer(int bufferCount);
+
+ // getTimestamp retrieves the timestamp associated with the image
+ // set by the most recent call to updateFrameInfoLocked().
+ //
+ // The timestamp is in nanoseconds, and is monotonically increasing. Its
+ // other semantics (zero point, etc) are source-dependent and should be
+ // documented by the source.
+ int64_t getTimestamp();
+
+ // setFrameAvailableListener sets the listener object that will be notified
+ // when a new frame becomes available.
+ void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
+
+ // getCurrentBuffer returns the buffer associated with the current image.
+ sp<GraphicBuffer> getCurrentBuffer() const;
+
+ // dump our state in a String
+ void dump(String8& result) const;
+ void dump(String8& result, const char* prefix, char* buffer,
+ size_t SIZE) const;
+
+ // isMetaDataStoredInVideoBuffers tells the encoder whether we will
+ // pass metadata through the buffers. Currently, it is force set to true
+ bool isMetaDataStoredInVideoBuffers() const;
+
+protected:
+
+ // freeAllBuffers frees the resources (both GraphicBuffer and EGLImage) for
+ // all slots.
+ void freeAllBuffers();
+ static bool isExternalFormat(uint32_t format);
+
+private:
+
+ status_t setBufferCountServerLocked(int bufferCount);
+
+ enum { INVALID_BUFFER_SLOT = -1 };
+
+ struct BufferSlot {
+
+ BufferSlot()
+ : mBufferState(BufferSlot::FREE),
+ mRequestBufferCalled(false),
+ mTimestamp(0) {
+ }
+
+ // mGraphicBuffer points to the buffer allocated for this slot or is
+ // NULL if no buffer has been allocated.
+ sp<GraphicBuffer> mGraphicBuffer;
+
+ // BufferState represents the different states in which a buffer slot
+ // can be.
+ enum BufferState {
+ // FREE indicates that the buffer is not currently being used and
+ // will not be used in the future until it gets dequeued and
+ // subseqently queued by the client.
+ FREE = 0,
+
+ // DEQUEUED indicates that the buffer has been dequeued by the
+ // client, but has not yet been queued or canceled. The buffer is
+ // considered 'owned' by the client, and the server should not use
+ // it for anything.
+ //
+ // Note that when in synchronous-mode (mSynchronousMode == true),
+ // the buffer that's currently attached to the texture may be
+ // dequeued by the client. That means that the current buffer can
+ // be in either the DEQUEUED or QUEUED state. In asynchronous mode,
+ // however, the current buffer is always in the QUEUED state.
+ DEQUEUED = 1,
+
+ // QUEUED indicates that the buffer has been queued by the client,
+ // and has not since been made available for the client to dequeue.
+ // Attaching the buffer to the texture does NOT transition the
+ // buffer away from the QUEUED state. However, in Synchronous mode
+ // the current buffer may be dequeued by the client under some
+ // circumstances. See the note about the current buffer in the
+ // documentation for DEQUEUED.
+ QUEUED = 2,
+ };
+
+ // mBufferState is the current state of this buffer slot.
+ BufferState mBufferState;
+
+ // mRequestBufferCalled is used for validating that the client did
+ // call requestBuffer() when told to do so. Technically this is not
+ // needed but useful for debugging and catching client bugs.
+ bool mRequestBufferCalled;
+
+ // mTimestamp is the current timestamp for this buffer slot. This gets
+ // to set by queueBuffer each time this slot is queued.
+ int64_t mTimestamp;
+ };
+
+ // mSlots is the array of buffer slots that must be mirrored on the client
+ // side. This allows buffer ownership to be transferred between the client
+ // and server without sending a GraphicBuffer over binder. The entire array
+ // is initialized to NULL at construction time, and buffers are allocated
+ // for a slot when requestBuffer is called with that slot's index.
+ BufferSlot mSlots[NUM_BUFFER_SLOTS];
+
+ // mDefaultWidth holds the default width of allocated buffers. It is used
+ // in requestBuffers() if a width and height of zero is specified.
+ uint32_t mDefaultWidth;
+
+ // mDefaultHeight holds the default height of allocated buffers. It is used
+ // in requestBuffers() if a width and height of zero is specified.
+ uint32_t mDefaultHeight;
+
+ // mPixelFormat holds the pixel format of allocated buffers. It is used
+ // in requestBuffers() if a format of zero is specified.
+ uint32_t mPixelFormat;
+
+ // mBufferCount is the number of buffer slots that the client and server
+ // must maintain. It defaults to MIN_ASYNC_BUFFER_SLOTS and can be changed
+ // by calling setBufferCount or setBufferCountServer
+ int mBufferCount;
+
+ // mClientBufferCount is the number of buffer slots requested by the
+ // client. The default is zero, which means the client doesn't care how
+ // many buffers there are
+ int mClientBufferCount;
+
+ // mServerBufferCount buffer count requested by the server-side
+ int mServerBufferCount;
+
+ // mCurrentSlot is the buffer slot index of the buffer that is currently
+ // being used by buffer consumer
+ // (e.g. StageFrightRecorder in the case of SurfaceMediaSource or GLTexture
+ // in the case of SurfaceTexture).
+ // It is initialized to INVALID_BUFFER_SLOT,
+ // indicating that no buffer slot is currently bound to the texture. Note,
+ // however, that a value of INVALID_BUFFER_SLOT does not necessarily mean
+ // that no buffer is bound to the texture. A call to setBufferCount will
+ // reset mCurrentTexture to INVALID_BUFFER_SLOT.
+ int mCurrentSlot;
+
+
+ // mCurrentBuf is the graphic buffer of the current slot to be used by
+ // buffer consumer. It's possible that this buffer is not associated
+ // with any buffer slot, so we must track it separately in order to
+ // properly use IGraphicBufferAlloc::freeAllGraphicBuffersExcept.
+ sp<GraphicBuffer> mCurrentBuf;
+
+
+ // mCurrentTimestamp is the timestamp for the current texture. It
+ // gets set to mLastQueuedTimestamp each time updateTexImage is called.
+ int64_t mCurrentTimestamp;
+
+ // mGraphicBufferAlloc is the connection to SurfaceFlinger that is used to
+ // allocate new GraphicBuffer objects.
+ sp<IGraphicBufferAlloc> mGraphicBufferAlloc;
+
+ // mFrameAvailableListener is the listener object that will be called when a
+ // new frame becomes available. If it is not NULL it will be called from
+ // queueBuffer.
+ sp<FrameAvailableListener> mFrameAvailableListener;
+
+ // mSynchronousMode whether we're in synchronous mode or not
+ bool mSynchronousMode;
+
+ // mConnectedApi indicates the API that is currently connected to this
+ // SurfaceTexture. It defaults to NO_CONNECTED_API (= 0), and gets updated
+ // by the connect and disconnect methods.
+ int mConnectedApi;
+
+ // mDequeueCondition condition used for dequeueBuffer in synchronous mode
+ mutable Condition mDequeueCondition;
+
+
+ // mQueue is a FIFO of queued buffers used in synchronous mode
+ typedef Vector<int> Fifo;
+ Fifo mQueue;
+
+ // mMutex is the mutex used to prevent concurrent access to the member
+ // variables of SurfaceMediaSource objects. It must be locked whenever the
+ // member variables are accessed.
+ mutable Mutex mMutex;
+
+ ////////////////////////// For MediaSource
+ // Set to a default of 30 fps if not specified by the client side
+ int32_t mFrameRate;
+
+ // mStarted is a flag to check if the recording has started
+ bool mStarted;
+
+ // mFrameAvailableCondition condition used to indicate whether there
+ // is a frame available for dequeuing
+ Condition mFrameAvailableCondition;
+ Condition mFrameCompleteCondition;
+
+ // Avoid copying and equating and default constructor
+ DISALLOW_IMPLICIT_CONSTRUCTORS(SurfaceMediaSource);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_SURFACEMEDIASOURCE_H
diff --git a/include/media/stagefright/openmax/OMX_IVCommon.h b/include/media/stagefright/openmax/OMX_IVCommon.h
index 7ed072b73f96..97170d7e7dbe 100644
--- a/include/media/stagefright/openmax/OMX_IVCommon.h
+++ b/include/media/stagefright/openmax/OMX_IVCommon.h
@@ -16,29 +16,29 @@
* -------------------------------------------------------------------
*/
/**
- * Copyright (c) 2008 The Khronos Group Inc.
- *
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject
- * to the following conditions:
+ * to the following conditions:
* The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
+ * in all copies or substantial portions of the Software.
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
-/**
+/**
* @file OMX_IVCommon.h - OpenMax IL version 1.1.2
* The structures needed by Video and Image components to exchange
* parameters and configuration data with the components.
@@ -53,7 +53,7 @@ extern "C" {
/**
* Each OMX header must include all required header files to allow the header
* to compile without errors. The includes below are required for this header
- * file to compile successfully
+ * file to compile successfully
*/
#include <OMX_Core.h>
@@ -64,8 +64,8 @@ extern "C" {
*/
-/**
- * Enumeration defining possible uncompressed image/video formats.
+/**
+ * Enumeration defining possible uncompressed image/video formats.
*
* ENUMS:
* Unused : Placeholder value when format is N/A
@@ -113,7 +113,7 @@ typedef enum OMX_COLOR_FORMATTYPE {
OMX_COLOR_Format16bitBGR565,
OMX_COLOR_Format18bitRGB666,
OMX_COLOR_Format18bitARGB1665,
- OMX_COLOR_Format19bitARGB1666,
+ OMX_COLOR_Format19bitARGB1666,
OMX_COLOR_Format24bitRGB888,
OMX_COLOR_Format24bitBGR888,
OMX_COLOR_Format24bitARGB1887,
@@ -136,55 +136,62 @@ typedef enum OMX_COLOR_FORMATTYPE {
OMX_COLOR_FormatRawBayer8bit,
OMX_COLOR_FormatRawBayer10bit,
OMX_COLOR_FormatRawBayer8bitcompressed,
- OMX_COLOR_FormatL2,
- OMX_COLOR_FormatL4,
- OMX_COLOR_FormatL8,
- OMX_COLOR_FormatL16,
- OMX_COLOR_FormatL24,
+ OMX_COLOR_FormatL2,
+ OMX_COLOR_FormatL4,
+ OMX_COLOR_FormatL8,
+ OMX_COLOR_FormatL16,
+ OMX_COLOR_FormatL24,
OMX_COLOR_FormatL32,
OMX_COLOR_FormatYUV420PackedSemiPlanar,
OMX_COLOR_FormatYUV422PackedSemiPlanar,
OMX_COLOR_Format18BitBGR666,
OMX_COLOR_Format24BitARGB6666,
OMX_COLOR_Format24BitABGR6666,
- OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ /**<Reserved android opaque colorformat. Tells the encoder that
+ * the actual colorformat will be relayed by the
+ * Gralloc Buffers.
+ * FIXME: In the process of reserving some enum values for
+ * Android-specific OMX IL colorformats. Change this enum to
+ * an acceptable range once that is done.*/
+ OMX_COLOR_FormatAndroidOpaque = 0x7F000001,
OMX_TI_COLOR_FormatYUV420PackedSemiPlanar = 0x7F000100,
OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00,
OMX_COLOR_FormatMax = 0x7FFFFFFF
} OMX_COLOR_FORMATTYPE;
-/**
+/**
* Defines the matrix for conversion from RGB to YUV or vice versa.
- * iColorMatrix should be initialized with the fixed point values
+ * iColorMatrix should be initialized with the fixed point values
* used in converting between formats.
*/
typedef struct OMX_CONFIG_COLORCONVERSIONTYPE {
OMX_U32 nSize; /**< Size of the structure in bytes */
- OMX_VERSIONTYPE nVersion; /**< OMX specification version info */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version info */
OMX_U32 nPortIndex; /**< Port that this struct applies to */
OMX_S32 xColorMatrix[3][3]; /**< Stored in signed Q16 format */
OMX_S32 xColorOffset[4]; /**< Stored in signed Q16 format */
}OMX_CONFIG_COLORCONVERSIONTYPE;
-/**
- * Structure defining percent to scale each frame dimension. For example:
+/**
+ * Structure defining percent to scale each frame dimension. For example:
* To make the width 50% larger, use fWidth = 1.5 and to make the width
* 1/2 the original size, use fWidth = 0.5
*/
typedef struct OMX_CONFIG_SCALEFACTORTYPE {
OMX_U32 nSize; /**< Size of the structure in bytes */
- OMX_VERSIONTYPE nVersion; /**< OMX specification version info */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version info */
OMX_U32 nPortIndex; /**< Port that this struct applies to */
OMX_S32 xWidth; /**< Fixed point value stored as Q16 */
OMX_S32 xHeight; /**< Fixed point value stored as Q16 */
}OMX_CONFIG_SCALEFACTORTYPE;
-/**
- * Enumeration of possible image filter types
+/**
+ * Enumeration of possible image filter types
*/
typedef enum OMX_IMAGEFILTERTYPE {
OMX_ImageFilterNone,
@@ -195,23 +202,23 @@ typedef enum OMX_IMAGEFILTERTYPE {
OMX_ImageFilterOilPaint,
OMX_ImageFilterHatch,
OMX_ImageFilterGpen,
- OMX_ImageFilterAntialias,
- OMX_ImageFilterDeRing,
+ OMX_ImageFilterAntialias,
+ OMX_ImageFilterDeRing,
OMX_ImageFilterSolarize,
- OMX_ImageFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_ImageFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_ImageFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_ImageFilterMax = 0x7FFFFFFF
} OMX_IMAGEFILTERTYPE;
-/**
- * Image filter configuration
+/**
+ * Image filter configuration
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
- * eImageFilter : Image filter type enumeration
+ * nPortIndex : Port that this structure applies to
+ * eImageFilter : Image filter type enumeration
*/
typedef struct OMX_CONFIG_IMAGEFILTERTYPE {
OMX_U32 nSize;
@@ -221,22 +228,22 @@ typedef struct OMX_CONFIG_IMAGEFILTERTYPE {
} OMX_CONFIG_IMAGEFILTERTYPE;
-/**
- * Customized U and V for color enhancement
+/**
+ * Customized U and V for color enhancement
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
+ * nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* bColorEnhancement : Enable/disable color enhancement
- * nCustomizedU : Practical values: 16-240, range: 0-255, value set for
+ * nCustomizedU : Practical values: 16-240, range: 0-255, value set for
* U component
- * nCustomizedV : Practical values: 16-240, range: 0-255, value set for
+ * nCustomizedV : Practical values: 16-240, range: 0-255, value set for
* V component
*/
typedef struct OMX_CONFIG_COLORENHANCEMENTTYPE {
OMX_U32 nSize;
- OMX_VERSIONTYPE nVersion;
+ OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_BOOL bColorEnhancement;
OMX_U8 nCustomizedU;
@@ -244,12 +251,12 @@ typedef struct OMX_CONFIG_COLORENHANCEMENTTYPE {
} OMX_CONFIG_COLORENHANCEMENTTYPE;
-/**
- * Define color key and color key mask
+/**
+ * Define color key and color key mask
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
+ * nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nARGBColor : 32bit Alpha, Red, Green, Blue Color
* nARGBMask : 32bit Mask for Alpha, Red, Green, Blue channels
@@ -263,12 +270,12 @@ typedef struct OMX_CONFIG_COLORKEYTYPE {
} OMX_CONFIG_COLORKEYTYPE;
-/**
- * List of color blend types for pre/post processing
+/**
+ * List of color blend types for pre/post processing
*
* ENUMS:
* None : No color blending present
- * AlphaConstant : Function is (alpha_constant * src) +
+ * AlphaConstant : Function is (alpha_constant * src) +
* (1 - alpha_constant) * dst)
* AlphaPerPixel : Function is (alpha * src) + (1 - alpha) * dst)
* Alternate : Function is alternating pixels from src and dst
@@ -284,21 +291,21 @@ typedef enum OMX_COLORBLENDTYPE {
OMX_ColorBlendAnd,
OMX_ColorBlendOr,
OMX_ColorBlendInvert,
- OMX_ColorBlendKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_ColorBlendKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_ColorBlendVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_ColorBlendMax = 0x7FFFFFFF
} OMX_COLORBLENDTYPE;
-/**
- * Color blend configuration
+/**
+ * Color blend configuration
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
* nRGBAlphaConstant : Constant global alpha values when global alpha is used
- * eColorBlend : Color blend type enumeration
+ * eColorBlend : Color blend type enumeration
*/
typedef struct OMX_CONFIG_COLORBLENDTYPE {
OMX_U32 nSize;
@@ -309,15 +316,15 @@ typedef struct OMX_CONFIG_COLORBLENDTYPE {
} OMX_CONFIG_COLORBLENDTYPE;
-/**
+/**
* Hold frame dimension
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
- * nWidth : Frame width in pixels
- * nHeight : Frame height in pixels
+ * nPortIndex : Port that this structure applies to
+ * nWidth : Frame width in pixels
+ * nHeight : Frame height in pixels
*/
typedef struct OMX_FRAMESIZETYPE {
OMX_U32 nSize;
@@ -329,69 +336,69 @@ typedef struct OMX_FRAMESIZETYPE {
/**
- * Rotation configuration
+ * Rotation configuration
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
- * nRotation : +/- integer rotation value
+ * nRotation : +/- integer rotation value
*/
typedef struct OMX_CONFIG_ROTATIONTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
- OMX_S32 nRotation;
+ OMX_S32 nRotation;
} OMX_CONFIG_ROTATIONTYPE;
-/**
- * Possible mirroring directions for pre/post processing
+/**
+ * Possible mirroring directions for pre/post processing
*
* ENUMS:
- * None : No mirroring
- * Vertical : Vertical mirroring, flip on X axis
- * Horizontal : Horizontal mirroring, flip on Y axis
+ * None : No mirroring
+ * Vertical : Vertical mirroring, flip on X axis
+ * Horizontal : Horizontal mirroring, flip on Y axis
* Both : Both vertical and horizontal mirroring
*/
typedef enum OMX_MIRRORTYPE {
OMX_MirrorNone = 0,
OMX_MirrorVertical,
OMX_MirrorHorizontal,
- OMX_MirrorBoth,
- OMX_MirrorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_MirrorBoth,
+ OMX_MirrorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_MirrorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
- OMX_MirrorMax = 0x7FFFFFFF
+ OMX_MirrorMax = 0x7FFFFFFF
} OMX_MIRRORTYPE;
-/**
- * Mirroring configuration
+/**
+ * Mirroring configuration
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
- * eMirror : Mirror type enumeration
+ * nPortIndex : Port that this structure applies to
+ * eMirror : Mirror type enumeration
*/
typedef struct OMX_CONFIG_MIRRORTYPE {
OMX_U32 nSize;
- OMX_VERSIONTYPE nVersion;
+ OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex;
OMX_MIRRORTYPE eMirror;
} OMX_CONFIG_MIRRORTYPE;
-/**
- * Position information only
+/**
+ * Position information only
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
- * nX : X coordinate for the point
- * nY : Y coordinate for the point
- */
+ * nX : X coordinate for the point
+ * nY : Y coordinate for the point
+ */
typedef struct OMX_CONFIG_POINTTYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
@@ -401,37 +408,37 @@ typedef struct OMX_CONFIG_POINTTYPE {
} OMX_CONFIG_POINTTYPE;
-/**
- * Frame size plus position
+/**
+ * Frame size plus position
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
* nLeft : X Coordinate of the top left corner of the rectangle
* nTop : Y Coordinate of the top left corner of the rectangle
- * nWidth : Width of the rectangle
- * nHeight : Height of the rectangle
+ * nWidth : Width of the rectangle
+ * nHeight : Height of the rectangle
*/
typedef struct OMX_CONFIG_RECTTYPE {
OMX_U32 nSize;
- OMX_VERSIONTYPE nVersion;
- OMX_U32 nPortIndex;
- OMX_S32 nLeft;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_S32 nLeft;
OMX_S32 nTop;
OMX_U32 nWidth;
OMX_U32 nHeight;
} OMX_CONFIG_RECTTYPE;
-/**
- * Deblocking state; it is required to be set up before starting the codec
+/**
+ * Deblocking state; it is required to be set up before starting the codec
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
- * bDeblocking : Enable/disable deblocking mode
+ * bDeblocking : Enable/disable deblocking mode
*/
typedef struct OMX_PARAM_DEBLOCKINGTYPE {
OMX_U32 nSize;
@@ -441,13 +448,13 @@ typedef struct OMX_PARAM_DEBLOCKINGTYPE {
} OMX_PARAM_DEBLOCKINGTYPE;
-/**
- * Stabilization state
+/**
+ * Stabilization state
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
* bStab : Enable/disable frame stabilization state
*/
typedef struct OMX_CONFIG_FRAMESTABTYPE {
@@ -458,8 +465,8 @@ typedef struct OMX_CONFIG_FRAMESTABTYPE {
} OMX_CONFIG_FRAMESTABTYPE;
-/**
- * White Balance control type
+/**
+ * White Balance control type
*
* STRUCT MEMBERS:
* SunLight : Referenced in JSR-234
@@ -476,20 +483,20 @@ typedef enum OMX_WHITEBALCONTROLTYPE {
OMX_WhiteBalControlIncandescent,
OMX_WhiteBalControlFlash,
OMX_WhiteBalControlHorizon,
- OMX_WhiteBalControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_WhiteBalControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_WhiteBalControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_WhiteBalControlMax = 0x7FFFFFFF
} OMX_WHITEBALCONTROLTYPE;
-/**
- * White Balance control configuration
+/**
+ * White Balance control configuration
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
- * eWhiteBalControl : White balance enumeration
+ * nPortIndex : Port that this structure applies to
+ * eWhiteBalControl : White balance enumeration
*/
typedef struct OMX_CONFIG_WHITEBALCONTROLTYPE {
OMX_U32 nSize;
@@ -499,8 +506,8 @@ typedef struct OMX_CONFIG_WHITEBALCONTROLTYPE {
} OMX_CONFIG_WHITEBALCONTROLTYPE;
-/**
- * Exposure control type
+/**
+ * Exposure control type
*/
typedef enum OMX_EXPOSURECONTROLTYPE {
OMX_ExposureControlOff = 0,
@@ -513,20 +520,20 @@ typedef enum OMX_EXPOSURECONTROLTYPE {
OMX_ExposureControlBeach,
OMX_ExposureControlLargeAperture,
OMX_ExposureControlSmallApperture,
- OMX_ExposureControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_ExposureControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_ExposureControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_ExposureControlMax = 0x7FFFFFFF
} OMX_EXPOSURECONTROLTYPE;
-/**
- * White Balance control configuration
+/**
+ * White Balance control configuration
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
- * eExposureControl : Exposure control enumeration
+ * nPortIndex : Port that this structure applies to
+ * eExposureControl : Exposure control enumeration
*/
typedef struct OMX_CONFIG_EXPOSURECONTROLTYPE {
OMX_U32 nSize;
@@ -536,16 +543,16 @@ typedef struct OMX_CONFIG_EXPOSURECONTROLTYPE {
} OMX_CONFIG_EXPOSURECONTROLTYPE;
-/**
- * Defines sensor supported mode.
+/**
+ * Defines sensor supported mode.
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
- * nFrameRate : Single shot mode is indicated by a 0
+ * nPortIndex : Port that this structure applies to
+ * nFrameRate : Single shot mode is indicated by a 0
* bOneShot : Enable for single shot, disable for streaming
- * sFrameSize : Framesize
+ * sFrameSize : Framesize
*/
typedef struct OMX_PARAM_SENSORMODETYPE {
OMX_U32 nSize;
@@ -557,13 +564,13 @@ typedef struct OMX_PARAM_SENSORMODETYPE {
} OMX_PARAM_SENSORMODETYPE;
-/**
- * Defines contrast level
+/**
+ * Defines contrast level
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
* nContrast : Values allowed for contrast -100 to 100, zero means no change
*/
typedef struct OMX_CONFIG_CONTRASTTYPE {
@@ -574,14 +581,14 @@ typedef struct OMX_CONFIG_CONTRASTTYPE {
} OMX_CONFIG_CONTRASTTYPE;
-/**
- * Defines brightness level
+/**
+ * Defines brightness level
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
- * nPortIndex : Port that this structure applies to
- * nBrightness : 0-100%
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nBrightness : 0-100%
*/
typedef struct OMX_CONFIG_BRIGHTNESSTYPE {
OMX_U32 nSize;
@@ -591,16 +598,16 @@ typedef struct OMX_CONFIG_BRIGHTNESSTYPE {
} OMX_CONFIG_BRIGHTNESSTYPE;
-/**
- * Defines backlight level configuration for a video sink, e.g. LCD panel
+/**
+ * Defines backlight level configuration for a video sink, e.g. LCD panel
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
+ * nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nBacklight : Values allowed for backlight 0-100%
- * nTimeout : Number of milliseconds before backlight automatically turns
- * off. A value of 0x0 disables backight timeout
+ * nTimeout : Number of milliseconds before backlight automatically turns
+ * off. A value of 0x0 disables backight timeout
*/
typedef struct OMX_CONFIG_BACKLIGHTTYPE {
OMX_U32 nSize;
@@ -611,12 +618,12 @@ typedef struct OMX_CONFIG_BACKLIGHTTYPE {
} OMX_CONFIG_BACKLIGHTTYPE;
-/**
- * Defines setting for Gamma
+/**
+ * Defines setting for Gamma
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
+ * nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* nGamma : Values allowed for gamma -100 to 100, zero means no change
*/
@@ -628,14 +635,14 @@ typedef struct OMX_CONFIG_GAMMATYPE {
} OMX_CONFIG_GAMMATYPE;
-/**
- * Define for setting saturation
- *
+/**
+ * Define for setting saturation
+ *
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
- * nSaturation : Values allowed for saturation -100 to 100, zero means
+ * nSaturation : Values allowed for saturation -100 to 100, zero means
* no change
*/
typedef struct OMX_CONFIG_SATURATIONTYPE {
@@ -646,14 +653,14 @@ typedef struct OMX_CONFIG_SATURATIONTYPE {
} OMX_CONFIG_SATURATIONTYPE;
-/**
- * Define for setting Lightness
+/**
+ * Define for setting Lightness
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
- * nLightness : Values allowed for lightness -100 to 100, zero means no
+ * nLightness : Values allowed for lightness -100 to 100, zero means no
* change
*/
typedef struct OMX_CONFIG_LIGHTNESSTYPE {
@@ -664,17 +671,17 @@ typedef struct OMX_CONFIG_LIGHTNESSTYPE {
} OMX_CONFIG_LIGHTNESSTYPE;
-/**
- * Plane blend configuration
+/**
+ * Plane blend configuration
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
+ * nSize : Size of the structure in bytes
* nVersion : OMX specification version information
* nPortIndex : Index of input port associated with the plane.
- * nDepth : Depth of the plane in relation to the screen. Higher
- * numbered depths are "behind" lower number depths.
+ * nDepth : Depth of the plane in relation to the screen. Higher
+ * numbered depths are "behind" lower number depths.
* This number defaults to the Port Index number.
- * nAlpha : Transparency blending component for the entire plane.
+ * nAlpha : Transparency blending component for the entire plane.
* See blending modes for more detail.
*/
typedef struct OMX_CONFIG_PLANEBLENDTYPE {
@@ -686,17 +693,17 @@ typedef struct OMX_CONFIG_PLANEBLENDTYPE {
} OMX_CONFIG_PLANEBLENDTYPE;
-/**
+/**
* Define interlace type
*
* STRUCT MEMBERS:
- * nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
- * bEnable : Enable control variable for this functionality
+ * bEnable : Enable control variable for this functionality
* (see below)
- * nInterleavePortIndex : Index of input or output port associated with
- * the interleaved plane.
+ * nInterleavePortIndex : Index of input or output port associated with
+ * the interleaved plane.
* pPlanarPortIndexes[4] : Index of input or output planar ports.
*/
typedef struct OMX_PARAM_INTERLEAVETYPE {
@@ -708,8 +715,8 @@ typedef struct OMX_PARAM_INTERLEAVETYPE {
} OMX_PARAM_INTERLEAVETYPE;
-/**
- * Defines the picture effect used for an input picture
+/**
+ * Defines the picture effect used for an input picture
*/
typedef enum OMX_TRANSITIONEFFECTTYPE {
OMX_EffectNone,
@@ -719,18 +726,18 @@ typedef enum OMX_TRANSITIONEFFECTTYPE {
OMX_EffectDissolve,
OMX_EffectWipe,
OMX_EffectUnspecifiedMixOfTwoScenes,
- OMX_EffectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_EffectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_EffectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_EffectMax = 0x7FFFFFFF
} OMX_TRANSITIONEFFECTTYPE;
-/**
- * Structure used to configure current transition effect
+/**
+ * Structure used to configure current transition effect
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
- * nVersion : OMX specification version information
+ * nVersion : OMX specification version information
* nPortIndex : Port that this structure applies to
* eEffect : Effect to enable
*/
@@ -742,43 +749,43 @@ typedef struct OMX_CONFIG_TRANSITIONEFFECTTYPE {
} OMX_CONFIG_TRANSITIONEFFECTTYPE;
-/**
- * Defines possible data unit types for encoded video data. The data unit
+/**
+ * Defines possible data unit types for encoded video data. The data unit
* types are used both for encoded video input for playback as well as
- * encoded video output from recording.
+ * encoded video output from recording.
*/
typedef enum OMX_DATAUNITTYPE {
OMX_DataUnitCodedPicture,
OMX_DataUnitVideoSegment,
OMX_DataUnitSeveralSegments,
OMX_DataUnitArbitraryStreamSection,
- OMX_DataUnitKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_DataUnitKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_DataUnitVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_DataUnitMax = 0x7FFFFFFF
} OMX_DATAUNITTYPE;
-/**
- * Defines possible encapsulation types for coded video data unit. The
- * encapsulation information is used both for encoded video input for
- * playback as well as encoded video output from recording.
+/**
+ * Defines possible encapsulation types for coded video data unit. The
+ * encapsulation information is used both for encoded video input for
+ * playback as well as encoded video output from recording.
*/
typedef enum OMX_DATAUNITENCAPSULATIONTYPE {
OMX_DataEncapsulationElementaryStream,
OMX_DataEncapsulationGenericPayload,
OMX_DataEncapsulationRtpPayload,
- OMX_DataEncapsulationKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_DataEncapsulationKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_DataEncapsulationVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_DataEncapsulationMax = 0x7FFFFFFF
} OMX_DATAUNITENCAPSULATIONTYPE;
-/**
- * Structure used to configure the type of being decoded/encoded
+/**
+ * Structure used to configure the type of being decoded/encoded
*/
typedef struct OMX_PARAM_DATAUNITTYPE {
OMX_U32 nSize; /**< Size of the structure in bytes */
- OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
OMX_U32 nPortIndex; /**< Port that this structure applies to */
OMX_DATAUNITTYPE eUnitType;
OMX_DATAUNITENCAPSULATIONTYPE eEncapsulationType;
@@ -786,25 +793,25 @@ typedef struct OMX_PARAM_DATAUNITTYPE {
/**
- * Defines dither types
+ * Defines dither types
*/
typedef enum OMX_DITHERTYPE {
OMX_DitherNone,
OMX_DitherOrdered,
OMX_DitherErrorDiffusion,
OMX_DitherOther,
- OMX_DitherKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_DitherKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_DitherVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_DitherMax = 0x7FFFFFFF
} OMX_DITHERTYPE;
-/**
- * Structure used to configure current type of dithering
+/**
+ * Structure used to configure current type of dithering
*/
typedef struct OMX_CONFIG_DITHERTYPE {
OMX_U32 nSize; /**< Size of the structure in bytes */
- OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
OMX_U32 nPortIndex; /**< Port that this structure applies to */
OMX_DITHERTYPE eDither; /**< Type of dithering to use */
} OMX_CONFIG_DITHERTYPE;
@@ -813,28 +820,28 @@ typedef struct OMX_CONFIG_CAPTUREMODETYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
OMX_U32 nPortIndex; /**< Port that this structure applies to */
- OMX_BOOL bContinuous; /**< If true then ignore frame rate and emit capture
+ OMX_BOOL bContinuous; /**< If true then ignore frame rate and emit capture
* data as fast as possible (otherwise obey port's frame rate). */
- OMX_BOOL bFrameLimited; /**< If true then terminate capture after the port emits the
- * specified number of frames (otherwise the port does not
- * terminate the capture until instructed to do so by the client).
- * Even if set, the client may manually terminate the capture prior
+ OMX_BOOL bFrameLimited; /**< If true then terminate capture after the port emits the
+ * specified number of frames (otherwise the port does not
+ * terminate the capture until instructed to do so by the client).
+ * Even if set, the client may manually terminate the capture prior
* to reaching the limit. */
OMX_U32 nFrameLimit; /**< Limit on number of frames emitted during a capture (only
* valid if bFrameLimited is set). */
} OMX_CONFIG_CAPTUREMODETYPE;
typedef enum OMX_METERINGTYPE {
-
+
OMX_MeteringModeAverage, /**< Center-weighted average metering. */
OMX_MeteringModeSpot, /**< Spot (partial) metering. */
OMX_MeteringModeMatrix, /**< Matrix or evaluative metering. */
-
- OMX_MeteringKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+
+ OMX_MeteringKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_MeteringVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_EVModeMax = 0x7fffffff
} OMX_METERINGTYPE;
-
+
typedef struct OMX_CONFIG_EXPOSUREVALUETYPE {
OMX_U32 nSize;
OMX_VERSIONTYPE nVersion;
@@ -843,14 +850,14 @@ typedef struct OMX_CONFIG_EXPOSUREVALUETYPE {
OMX_S32 xEVCompensation; /**< Fixed point value stored as Q16 */
OMX_U32 nApertureFNumber; /**< e.g. nApertureFNumber = 2 implies "f/2" - Q16 format */
OMX_BOOL bAutoAperture; /**< Whether aperture number is defined automatically */
- OMX_U32 nShutterSpeedMsec; /**< Shutterspeed in milliseconds */
- OMX_BOOL bAutoShutterSpeed; /**< Whether shutter speed is defined automatically */
+ OMX_U32 nShutterSpeedMsec; /**< Shutterspeed in milliseconds */
+ OMX_BOOL bAutoShutterSpeed; /**< Whether shutter speed is defined automatically */
OMX_U32 nSensitivity; /**< e.g. nSensitivity = 100 implies "ISO 100" */
OMX_BOOL bAutoSensitivity; /**< Whether sensitivity is defined automatically */
} OMX_CONFIG_EXPOSUREVALUETYPE;
-/**
- * Focus region configuration
+/**
+ * Focus region configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
@@ -881,8 +888,8 @@ typedef struct OMX_CONFIG_FOCUSREGIONTYPE {
OMX_BOOL bBottomRight;
} OMX_CONFIG_FOCUSREGIONTYPE;
-/**
- * Focus Status type
+/**
+ * Focus Status type
*/
typedef enum OMX_FOCUSSTATUSTYPE {
OMX_FocusStatusOff = 0,
@@ -890,13 +897,13 @@ typedef enum OMX_FOCUSSTATUSTYPE {
OMX_FocusStatusReached,
OMX_FocusStatusUnableToReach,
OMX_FocusStatusLost,
- OMX_FocusStatusKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_FocusStatusKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
OMX_FocusStatusVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
OMX_FocusStatusMax = 0x7FFFFFFF
} OMX_FOCUSSTATUSTYPE;
-/**
- * Focus status configuration
+/**
+ * Focus status configuration
*
* STRUCT MEMBERS:
* nSize : Size of the structure in bytes
diff --git a/include/surfaceflinger/ISurfaceComposerClient.h b/include/surfaceflinger/ISurfaceComposerClient.h
index 6e9a654642c5..02cabc1cdc31 100644
--- a/include/surfaceflinger/ISurfaceComposerClient.h
+++ b/include/surfaceflinger/ISurfaceComposerClient.h
@@ -45,9 +45,6 @@ public:
struct surface_data_t {
int32_t token;
int32_t identity;
- uint32_t width;
- uint32_t height;
- uint32_t format;
status_t readFromParcel(const Parcel& parcel);
status_t writeToParcel(Parcel* parcel) const;
};
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index c2a494de41b6..9c352ad9ab53 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -57,7 +57,6 @@ public:
static bool isSameSurface(
const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);
- uint32_t getFlags() const { return mFlags; }
uint32_t getIdentity() const { return mIdentity; }
// release surface data from java
@@ -86,25 +85,13 @@ private:
SurfaceControl& operator = (SurfaceControl& rhs);
SurfaceControl(const SurfaceControl& rhs);
-
friend class SurfaceComposerClient;
-
- // camera and camcorder need access to the ISurface binder interface for preview
- friend class CameraService;
- friend class MediaRecorder;
- // mediaplayer needs access to ISurface for display
- friend class MediaPlayer;
- // for testing
- friend class Test;
- // videoEditor preview classes
- friend class VideoEditorPreviewController;
friend class Surface;
SurfaceControl(
const sp<SurfaceComposerClient>& client,
const sp<ISurface>& surface,
- const ISurfaceComposerClient::surface_data_t& data,
- uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
+ const ISurfaceComposerClient::surface_data_t& data);
~SurfaceControl();
@@ -115,10 +102,6 @@ private:
sp<ISurface> mSurface;
SurfaceID mToken;
uint32_t mIdentity;
- uint32_t mWidth;
- uint32_t mHeight;
- PixelFormat mFormat;
- uint32_t mFlags;
mutable Mutex mLock;
mutable sp<Surface> mSurfaceData;
@@ -139,17 +122,13 @@ public:
uint32_t reserved[2];
};
- static status_t writeToParcel(
- const sp<Surface>& control, Parcel* parcel);
-
+ static status_t writeToParcel(const sp<Surface>& control, Parcel* parcel);
static sp<Surface> readFromParcel(const Parcel& data);
-
static bool isValid(const sp<Surface>& surface) {
return (surface != 0) && surface->isValid();
}
bool isValid();
- uint32_t getFlags() const { return mFlags; }
uint32_t getIdentity() const { return mIdentity; }
sp<ISurfaceTexture> getSurfaceTexture();
@@ -176,22 +155,14 @@ private:
* private stuff...
*/
void init();
- status_t validate(bool inCancelBuffer = false) const;
static void cleanCachedSurfacesLocked();
virtual int query(int what, int* value) const;
// constants
- status_t mInitCheck;
sp<ISurface> mSurface;
uint32_t mIdentity;
- PixelFormat mFormat;
- uint32_t mFlags;
-
- // query() must be called from dequeueBuffer() thread
- uint32_t mWidth;
- uint32_t mHeight;
// A cache of Surface objects that have been deserialized into this process.
static Mutex sCachedSurfacesLock;
diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h
index f46f25c36d14..848c5a114907 100644
--- a/include/ui/PixelFormat.h
+++ b/include/ui/PixelFormat.h
@@ -55,7 +55,7 @@ enum {
PIXEL_FORMAT_OPAQUE = -1,
// System chooses an opaque format (no alpha bits required)
-
+
// real pixel formats supported for rendering -----------------------------
PIXEL_FORMAT_RGBA_8888 = HAL_PIXEL_FORMAT_RGBA_8888, // 4x8-bit RGBA
@@ -84,7 +84,7 @@ struct PixelFormatInfo
INDEX_GREEN = 2,
INDEX_BLUE = 3
};
-
+
enum { // components
ALPHA = 1,
RGB = 2,
@@ -98,10 +98,10 @@ struct PixelFormatInfo
uint8_t h;
uint8_t l;
};
-
+
inline PixelFormatInfo() : version(sizeof(PixelFormatInfo)) { }
size_t getScanlineSize(unsigned int width) const;
- size_t getSize(size_t ci) const {
+ size_t getSize(size_t ci) const {
return (ci <= 3) ? (cinfo[ci].h - cinfo[ci].l) : 0;
}
size_t version;
@@ -112,7 +112,7 @@ struct PixelFormatInfo
szinfo cinfo[4];
struct {
uint8_t h_alpha;
- uint8_t l_alpha;
+ uint8_t l_alpha;
uint8_t h_red;
uint8_t l_red;
uint8_t h_green;
diff --git a/include/utils/Pool.h b/include/utils/Pool.h
deleted file mode 100644
index 2ee768eef1aa..000000000000
--- a/include/utils/Pool.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef UTILS_POOL_H
-#define UTILS_POOL_H
-
-#include <utils/TypeHelpers.h>
-
-namespace android {
-
-class PoolImpl {
-public:
- PoolImpl(size_t objSize);
- ~PoolImpl();
-
- void* allocImpl();
- void freeImpl(void* obj);
-
-private:
- size_t mObjSize;
-};
-
-/*
- * A homogeneous typed memory pool for fixed size objects.
- * Not intended to be thread-safe.
- */
-template<typename T>
-class Pool : private PoolImpl {
-public:
- /* Creates an initially empty pool. */
- Pool() : PoolImpl(sizeof(T)) { }
-
- /* Destroys the pool.
- * Assumes that the pool is empty. */
- ~Pool() { }
-
- /* Allocates an object from the pool, growing the pool if needed. */
- inline T* alloc() {
- void* mem = allocImpl();
- if (! traits<T>::has_trivial_ctor) {
- return new (mem) T();
- } else {
- return static_cast<T*>(mem);
- }
- }
-
- /* Frees an object from the pool. */
- inline void free(T* obj) {
- if (! traits<T>::has_trivial_dtor) {
- obj->~T();
- }
- freeImpl(obj);
- }
-};
-
-} // namespace android
-
-#endif // UTILS_POOL_H
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index bc97cacbe0a3..ace16aaae47c 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -132,9 +132,6 @@ status_t ISurfaceComposerClient::surface_data_t::readFromParcel(const Parcel& pa
{
token = parcel.readInt32();
identity = parcel.readInt32();
- width = parcel.readInt32();
- height = parcel.readInt32();
- format = parcel.readInt32();
return NO_ERROR;
}
@@ -142,9 +139,6 @@ status_t ISurfaceComposerClient::surface_data_t::writeToParcel(Parcel* parcel) c
{
parcel->writeInt32(token);
parcel->writeInt32(identity);
- parcel->writeInt32(width);
- parcel->writeInt32(height);
- parcel->writeInt32(format);
return NO_ERROR;
}
diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp
index be90e2eec00f..55246dc902e5 100644
--- a/libs/gui/ISurfaceTexture.cpp
+++ b/libs/gui/ISurfaceTexture.cpp
@@ -38,7 +38,6 @@ enum {
CANCEL_BUFFER,
SET_CROP,
SET_TRANSFORM,
- GET_ALLOCATOR,
QUERY,
SET_SYNCHRONOUS_MODE,
CONNECT,
@@ -55,18 +54,18 @@ public:
{
}
- virtual sp<GraphicBuffer> requestBuffer(int bufferIdx) {
+ virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(bufferIdx);
remote()->transact(REQUEST_BUFFER, data, &reply);
- sp<GraphicBuffer> buffer;
bool nonNull = reply.readInt32();
if (nonNull) {
- buffer = new GraphicBuffer();
- reply.read(*buffer);
+ *buf = new GraphicBuffer();
+ reply.read(**buf);
}
- return buffer;
+ status_t result = reply.readInt32();
+ return result;
}
virtual status_t setBufferCount(int bufferCount)
@@ -144,13 +143,6 @@ public:
return result;
}
- virtual sp<IBinder> getAllocator() {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
- remote()->transact(GET_ALLOCATOR, data, &reply);
- return reply.readStrongBinder();
- }
-
virtual int query(int what, int* value) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
@@ -200,11 +192,13 @@ status_t BnSurfaceTexture::onTransact(
case REQUEST_BUFFER: {
CHECK_INTERFACE(ISurfaceTexture, data, reply);
int bufferIdx = data.readInt32();
- sp<GraphicBuffer> buffer(requestBuffer(bufferIdx));
+ sp<GraphicBuffer> buffer;
+ int result = requestBuffer(bufferIdx, &buffer);
reply->writeInt32(buffer != 0);
if (buffer != 0) {
reply->write(*buffer);
}
+ reply->writeInt32(result);
return NO_ERROR;
} break;
case SET_BUFFER_COUNT: {
@@ -270,12 +264,6 @@ status_t BnSurfaceTexture::onTransact(
reply->writeInt32(result);
return NO_ERROR;
} break;
- case GET_ALLOCATOR: {
- CHECK_INTERFACE(ISurfaceTexture, data, reply);
- sp<IBinder> result = getAllocator();
- reply->writeStrongBinder(result);
- return NO_ERROR;
- } break;
case QUERY: {
CHECK_INTERFACE(ISurfaceTexture, data, reply);
int value;
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index dabe643f270c..c4f9e53d5dcc 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -26,15 +26,12 @@
#include <utils/Log.h>
#include <utils/threads.h>
-#include <binder/IMemory.h>
#include <binder/IPCThreadState.h>
#include <gui/SurfaceTextureClient.h>
#include <ui/DisplayInfo.h>
#include <ui/GraphicBuffer.h>
-#include <ui/GraphicBufferMapper.h>
-#include <ui/GraphicLog.h>
#include <ui/Rect.h>
#include <surfaceflinger/ISurface.h>
@@ -42,8 +39,6 @@
#include <surfaceflinger/Surface.h>
#include <surfaceflinger/SurfaceComposerClient.h>
-#include <private/surfaceflinger/LayerState.h>
-
namespace android {
// ============================================================================
@@ -53,12 +48,9 @@ namespace android {
SurfaceControl::SurfaceControl(
const sp<SurfaceComposerClient>& client,
const sp<ISurface>& surface,
- const ISurfaceComposerClient::surface_data_t& data,
- uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
+ const ISurfaceComposerClient::surface_data_t& data)
: mClient(client), mSurface(surface),
- mToken(data.token), mIdentity(data.identity),
- mWidth(data.width), mHeight(data.height), mFormat(data.format),
- mFlags(flags)
+ mToken(data.token), mIdentity(data.identity)
{
}
@@ -187,24 +179,12 @@ status_t SurfaceControl::writeSurfaceToParcel(
{
sp<ISurface> sur;
uint32_t identity = 0;
- uint32_t width = 0;
- uint32_t height = 0;
- uint32_t format = 0;
- uint32_t flags = 0;
if (SurfaceControl::isValid(control)) {
sur = control->mSurface;
identity = control->mIdentity;
- width = control->mWidth;
- height = control->mHeight;
- format = control->mFormat;
- flags = control->mFlags;
}
parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
parcel->writeInt32(identity);
- parcel->writeInt32(width);
- parcel->writeInt32(height);
- parcel->writeInt32(format);
- parcel->writeInt32(flags);
return NO_ERROR;
}
@@ -225,25 +205,17 @@ sp<Surface> SurfaceControl::getSurface() const
Surface::Surface(const sp<SurfaceControl>& surface)
: SurfaceTextureClient(),
- mInitCheck(NO_INIT),
mSurface(surface->mSurface),
- mIdentity(surface->mIdentity),
- mFormat(surface->mFormat), mFlags(surface->mFlags),
- mWidth(surface->mWidth), mHeight(surface->mHeight)
+ mIdentity(surface->mIdentity)
{
init();
}
Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref)
- : SurfaceTextureClient(),
- mInitCheck(NO_INIT)
+ : SurfaceTextureClient()
{
mSurface = interface_cast<ISurface>(ref);
mIdentity = parcel.readInt32();
- mWidth = parcel.readInt32();
- mHeight = parcel.readInt32();
- mFormat = parcel.readInt32();
- mFlags = parcel.readInt32();
init();
}
@@ -252,31 +224,16 @@ status_t Surface::writeToParcel(
{
sp<ISurface> sur;
uint32_t identity = 0;
- uint32_t width = 0;
- uint32_t height = 0;
- uint32_t format = 0;
- uint32_t flags = 0;
if (Surface::isValid(surface)) {
sur = surface->mSurface;
identity = surface->mIdentity;
- width = surface->mWidth;
- height = surface->mHeight;
- format = surface->mFormat;
- flags = surface->mFlags;
} else if (surface != 0 && surface->mSurface != 0) {
LOGW("Parceling invalid surface with non-NULL ISurface as NULL: "
- "mSurface = %p, mIdentity = %d, mWidth = %d, mHeight = %d, "
- "mFormat = %d, mFlags = 0x%08x, mInitCheck = %d",
- surface->mSurface.get(), surface->mIdentity, surface->mWidth,
- surface->mHeight, surface->mFormat, surface->mFlags,
- surface->mInitCheck);
+ "mSurface = %p, mIdentity = %d",
+ surface->mSurface.get(), surface->mIdentity);
}
parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
parcel->writeInt32(identity);
- parcel->writeInt32(width);
- parcel->writeInt32(height);
- parcel->writeInt32(format);
- parcel->writeInt32(flags);
return NO_ERROR;
}
@@ -325,10 +282,6 @@ void Surface::init()
const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;
const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;
const_cast<uint32_t&>(ANativeWindow::flags) = 0;
-
- if (surfaceTexture != NULL) {
- mInitCheck = NO_ERROR;
- }
}
}
@@ -341,21 +294,11 @@ Surface::~Surface()
}
bool Surface::isValid() {
- return mInitCheck == NO_ERROR;
-}
-
-status_t Surface::validate(bool inCancelBuffer) const
-{
- // check that we initialized ourself properly
- if (mInitCheck != NO_ERROR) {
- LOGE("invalid token (identity=%u)", mIdentity);
- return mInitCheck;
- }
- return NO_ERROR;
+ return getISurfaceTexture() != NULL;
}
sp<ISurfaceTexture> Surface::getSurfaceTexture() {
- return mSurface != NULL ? mSurface->getSurfaceTexture() : NULL;
+ return getISurfaceTexture();
}
sp<IBinder> Surface::asBinder() const {
@@ -367,7 +310,6 @@ sp<IBinder> Surface::asBinder() const {
int Surface::query(int what, int* value) const {
switch (what) {
case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
- // TODO: this is not needed anymore
*value = 1;
return NO_ERROR;
case NATIVE_WINDOW_CONCRETE_TYPE:
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 8cead808a1b2..3b0ffea0ff1f 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -339,7 +339,7 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface(
sp<ISurface> surface = mClient->createSurface(&data, name,
display, w, h, format, flags);
if (surface != 0) {
- result = new SurfaceControl(this, surface, data, w, h, format, flags);
+ result = new SurfaceControl(this, surface, data);
}
}
return result;
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 0f08570ef76f..c190195b53d0 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -94,7 +94,8 @@ SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode) :
mTexName(tex),
mSynchronousMode(false),
mAllowSynchronousMode(allowSynchronousMode),
- mConnectedApi(NO_CONNECTED_API) {
+ mConnectedApi(NO_CONNECTED_API),
+ mAbandoned(false) {
LOGV("SurfaceTexture::SurfaceTexture");
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
@@ -150,6 +151,11 @@ status_t SurfaceTexture::setBufferCount(int bufferCount) {
LOGV("SurfaceTexture::setBufferCount");
Mutex::Autolock lock(mMutex);
+ if (mAbandoned) {
+ LOGE("setBufferCount: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+
if (bufferCount > NUM_BUFFER_SLOTS) {
LOGE("setBufferCount: bufferCount larger than slots available");
return BAD_VALUE;
@@ -199,22 +205,32 @@ status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h)
return OK;
}
-sp<GraphicBuffer> SurfaceTexture::requestBuffer(int buf) {
+status_t SurfaceTexture::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
LOGV("SurfaceTexture::requestBuffer");
Mutex::Autolock lock(mMutex);
- if (buf < 0 || mBufferCount <= buf) {
+ if (mAbandoned) {
+ LOGE("requestBuffer: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+ if (slot < 0 || mBufferCount <= slot) {
LOGE("requestBuffer: slot index out of range [0, %d]: %d",
- mBufferCount, buf);
- return 0;
+ mBufferCount, slot);
+ return BAD_VALUE;
}
- mSlots[buf].mRequestBufferCalled = true;
- return mSlots[buf].mGraphicBuffer;
+ mSlots[slot].mRequestBufferCalled = true;
+ *buf = mSlots[slot].mGraphicBuffer;
+ return NO_ERROR;
}
status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
uint32_t format, uint32_t usage) {
LOGV("SurfaceTexture::dequeueBuffer");
+ if (mAbandoned) {
+ LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+
if ((w && !h) || (!w && h)) {
LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
return BAD_VALUE;
@@ -252,6 +268,11 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
// wait for the FIFO to drain
while (!mQueue.isEmpty()) {
mDequeueCondition.wait(mMutex);
+ if (mAbandoned) {
+ LOGE("dequeueBuffer: SurfaceTexture was abandoned while "
+ "blocked!");
+ return NO_INIT;
+ }
}
minBufferCountNeeded = mSynchronousMode ?
MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
@@ -380,6 +401,11 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
status_t SurfaceTexture::setSynchronousMode(bool enabled) {
Mutex::Autolock lock(mMutex);
+ if (mAbandoned) {
+ LOGE("setSynchronousMode: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+
status_t err = OK;
if (!mAllowSynchronousMode && enabled)
return err;
@@ -410,6 +436,10 @@ status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp,
{ // scope for the lock
Mutex::Autolock lock(mMutex);
+ if (mAbandoned) {
+ LOGE("queueBuffer: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
if (buf < 0 || buf >= mBufferCount) {
LOGE("queueBuffer: slot index out of range [0, %d]: %d",
mBufferCount, buf);
@@ -475,6 +505,12 @@ status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp,
void SurfaceTexture::cancelBuffer(int buf) {
LOGV("SurfaceTexture::cancelBuffer");
Mutex::Autolock lock(mMutex);
+
+ if (mAbandoned) {
+ LOGW("cancelBuffer: SurfaceTexture has been abandoned!");
+ return;
+ }
+
if (buf < 0 || buf >= mBufferCount) {
LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
mBufferCount, buf);
@@ -491,6 +527,10 @@ void SurfaceTexture::cancelBuffer(int buf) {
status_t SurfaceTexture::setCrop(const Rect& crop) {
LOGV("SurfaceTexture::setCrop");
Mutex::Autolock lock(mMutex);
+ if (mAbandoned) {
+ LOGE("setCrop: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
mNextCrop = crop;
return OK;
}
@@ -498,6 +538,10 @@ status_t SurfaceTexture::setCrop(const Rect& crop) {
status_t SurfaceTexture::setTransform(uint32_t transform) {
LOGV("SurfaceTexture::setTransform");
Mutex::Autolock lock(mMutex);
+ if (mAbandoned) {
+ LOGE("setTransform: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
mNextTransform = transform;
return OK;
}
@@ -505,6 +549,12 @@ status_t SurfaceTexture::setTransform(uint32_t transform) {
status_t SurfaceTexture::connect(int api) {
LOGV("SurfaceTexture::connect(this=%p, %d)", this, api);
Mutex::Autolock lock(mMutex);
+
+ if (mAbandoned) {
+ LOGE("connect: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+
int err = NO_ERROR;
switch (api) {
case NATIVE_WINDOW_API_EGL:
@@ -529,6 +579,12 @@ status_t SurfaceTexture::connect(int api) {
status_t SurfaceTexture::disconnect(int api) {
LOGV("SurfaceTexture::disconnect(this=%p, %d)", this, api);
Mutex::Autolock lock(mMutex);
+
+ if (mAbandoned) {
+ LOGE("connect: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+
int err = NO_ERROR;
switch (api) {
case NATIVE_WINDOW_API_EGL:
@@ -786,11 +842,6 @@ void SurfaceTexture::setFrameAvailableListener(
mFrameAvailableListener = listener;
}
-sp<IBinder> SurfaceTexture::getAllocator() {
- LOGV("SurfaceTexture::getAllocator");
- return mGraphicBufferAlloc->asBinder();
-}
-
void SurfaceTexture::freeAllBuffers() {
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
mSlots[i].mGraphicBuffer = 0;
@@ -842,6 +893,12 @@ uint32_t SurfaceTexture::getCurrentScalingMode() const {
int SurfaceTexture::query(int what, int* outValue)
{
Mutex::Autolock lock(mMutex);
+
+ if (mAbandoned) {
+ LOGE("query: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+
int value;
switch (what) {
case NATIVE_WINDOW_WIDTH:
@@ -868,6 +925,13 @@ int SurfaceTexture::query(int what, int* outValue)
return NO_ERROR;
}
+void SurfaceTexture::abandon() {
+ Mutex::Autolock lock(mMutex);
+ freeAllBuffers();
+ mAbandoned = true;
+ mDequeueCondition.signal();
+}
+
void SurfaceTexture::dump(String8& result) const
{
char buffer[1024];
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 1dc6cd2cf751..df0ad5abe3e2 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -55,6 +55,9 @@ void SurfaceTextureClient::init() {
mQueryWidth = 0;
mQueryHeight = 0;
mQueryFormat = 0;
+ mDefaultWidth = 0;
+ mDefaultHeight = 0;
+ mTransformHint = 0;
mConnectedToCpu = false;
}
@@ -62,9 +65,6 @@ void SurfaceTextureClient::setISurfaceTexture(
const sp<ISurfaceTexture>& surfaceTexture)
{
mSurfaceTexture = surfaceTexture;
-
- // Get a reference to the allocator.
- mAllocator = mSurfaceTexture->getAllocator();
}
sp<ISurfaceTexture> SurfaceTextureClient::getISurfaceTexture() const {
@@ -148,10 +148,11 @@ int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
}
if ((result & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
- gbuf = mSurfaceTexture->requestBuffer(buf);
- if (gbuf == 0) {
- LOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed");
- return NO_MEMORY;
+ result = mSurfaceTexture->requestBuffer(buf, &gbuf);
+ if (result != NO_ERROR) {
+ LOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed: %d",
+ result);
+ return result;
}
mQueryWidth = gbuf->width;
mQueryHeight = gbuf->height;
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index 2b8f204563cd..c1a3c98d6a13 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -116,11 +116,6 @@ TEST_F(SurfaceTextureClientTest, ConcreteTypeIsSurfaceTextureClient) {
EXPECT_EQ(NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT, result);
}
-TEST_F(SurfaceTextureClientTest, ANativeWindowLockFails) {
- ANativeWindow_Buffer buf;
- ASSERT_EQ(BAD_VALUE, ANativeWindow_lock(mANW.get(), &buf, NULL));
-}
-
TEST_F(SurfaceTextureClientTest, EglCreateWindowSurfaceSucceeds) {
EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
ASSERT_EQ(EGL_SUCCESS, eglGetError());
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index 9abe89d9709c..0fac6cda05a4 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -1018,6 +1018,83 @@ TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromGLFilledRGBABufferPow2) {
EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153));
}
+TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
+ class ProducerThread : public Thread {
+ public:
+ ProducerThread(const sp<ANativeWindow>& anw):
+ mANW(anw),
+ mDequeueError(NO_ERROR) {
+ }
+
+ virtual ~ProducerThread() {
+ }
+
+ virtual bool threadLoop() {
+ Mutex::Autolock lock(mMutex);
+ ANativeWindowBuffer* anb;
+
+ // Frame 1
+ if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
+ return false;
+ }
+ if (anb == NULL) {
+ return false;
+ }
+ if (mANW->queueBuffer(mANW.get(), anb)
+ != NO_ERROR) {
+ return false;
+ }
+
+ // Frame 2
+ if (mANW->dequeueBuffer(mANW.get(), &anb) != NO_ERROR) {
+ return false;
+ }
+ if (anb == NULL) {
+ return false;
+ }
+ if (mANW->queueBuffer(mANW.get(), anb)
+ != NO_ERROR) {
+ return false;
+ }
+
+ // Frame 3 - error expected
+ mDequeueError = mANW->dequeueBuffer(mANW.get(), &anb);
+ return false;
+ }
+
+ status_t getDequeueError() {
+ Mutex::Autolock lock(mMutex);
+ return mDequeueError;
+ }
+
+ private:
+ sp<ANativeWindow> mANW;
+ status_t mDequeueError;
+ Mutex mMutex;
+ };
+
+ sp<FrameWaiter> fw(new FrameWaiter);
+ mST->setFrameAvailableListener(fw);
+ ASSERT_EQ(OK, mST->setSynchronousMode(true));
+ ASSERT_EQ(OK, mST->setBufferCountServer(2));
+
+ sp<Thread> pt(new ProducerThread(mANW));
+ pt->run();
+
+ fw->waitForFrame();
+ fw->waitForFrame();
+
+ // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
+ // block waiting for a buffer to become available.
+ usleep(100000);
+
+ mST->abandon();
+
+ pt->requestExitAndWait();
+ ASSERT_EQ(NO_INIT,
+ reinterpret_cast<ProducerThread*>(pt.get())->getDequeueError());
+}
+
/*
* This test is for testing GL -> GL texture streaming via SurfaceTexture. It
* contains functionality to create a producer thread that will perform GL
@@ -1205,7 +1282,7 @@ protected:
sp<FrameCondition> mFC;
};
-TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageBeforeFrameFinishedWorks) {
+TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageBeforeFrameFinishedCompletes) {
class PT : public ProducerThread {
virtual void render() {
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
@@ -1223,7 +1300,7 @@ TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageBeforeFrameFinishedWorks) {
// TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
}
-TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageAfterFrameFinishedWorks) {
+TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageAfterFrameFinishedCompletes) {
class PT : public ProducerThread {
virtual void render() {
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
@@ -1241,7 +1318,7 @@ TEST_F(SurfaceTextureGLToGLTest, UpdateTexImageAfterFrameFinishedWorks) {
// TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
}
-TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageBeforeFrameFinishedWorks) {
+TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageBeforeFrameFinishedCompletes) {
enum { NUM_ITERATIONS = 1024 };
class PT : public ProducerThread {
@@ -1269,7 +1346,7 @@ TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageBeforeFrameFinishedWorks)
}
}
-TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageAfterFrameFinishedWorks) {
+TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageAfterFrameFinishedCompletes) {
enum { NUM_ITERATIONS = 1024 };
class PT : public ProducerThread {
@@ -1297,4 +1374,70 @@ TEST_F(SurfaceTextureGLToGLTest, RepeatedUpdateTexImageAfterFrameFinishedWorks)
}
}
+// XXX: This test is disabled because it is currently hanging on some devices.
+TEST_F(SurfaceTextureGLToGLTest, DISABLED_RepeatedSwapBuffersWhileDequeueStalledCompletes) {
+ enum { NUM_ITERATIONS = 64 };
+
+ class PT : public ProducerThread {
+ virtual void render() {
+ for (int i = 0; i < NUM_ITERATIONS; i++) {
+ glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ LOGV("+swapBuffers");
+ swapBuffers();
+ LOGV("-swapBuffers");
+ }
+ }
+ };
+
+ ASSERT_EQ(OK, mST->setSynchronousMode(true));
+ ASSERT_EQ(OK, mST->setBufferCountServer(2));
+
+ runProducerThread(new PT());
+
+ // Allow three frames to be rendered and queued before starting the
+ // rendering in this thread. For the latter two frames we don't call
+ // updateTexImage so the next dequeue from the producer thread will block
+ // waiting for a frame to become available.
+ mFC->waitForFrame();
+ mFC->finishFrame();
+
+ // We must call updateTexImage to consume the first frame so that the
+ // SurfaceTexture is able to reduce the buffer count to 2. This is because
+ // the GL driver may dequeue a buffer when the EGLSurface is created, and
+ // that happens before we call setBufferCountServer. It's possible that the
+ // driver does not dequeue a buffer at EGLSurface creation time, so we
+ // cannot rely on this to cause the second dequeueBuffer call to block.
+ mST->updateTexImage();
+
+ mFC->waitForFrame();
+ mFC->finishFrame();
+ mFC->waitForFrame();
+ mFC->finishFrame();
+
+ // Sleep for 100ms to allow the producer thread's dequeueBuffer call to
+ // block waiting for a buffer to become available.
+ usleep(100000);
+
+ // Render and present a number of images. This thread should not be blocked
+ // by the fact that the producer thread is blocking in dequeue.
+ for (int i = 0; i < NUM_ITERATIONS; i++) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ eglSwapBuffers(mEglDisplay, mEglSurface);
+ }
+
+ // Consume the two pending buffers to unblock the producer thread.
+ mST->updateTexImage();
+ mST->updateTexImage();
+
+ // Consume the remaining buffers from the producer thread.
+ for (int i = 0; i < NUM_ITERATIONS-3; i++) {
+ mFC->waitForFrame();
+ mFC->finishFrame();
+ LOGV("+updateTexImage");
+ mST->updateTexImage();
+ LOGV("-updateTexImage");
+ }
+}
+
} // namespace android
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 8b1caeeedf59..886c05c64c07 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -883,7 +883,6 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level)
///////////////////////////////////////////////////////////////////////////////
DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE) {
- mDisplayList = NULL;
}
DisplayListRenderer::~DisplayListRenderer() {
@@ -923,13 +922,13 @@ void DisplayListRenderer::reset() {
// Operations
///////////////////////////////////////////////////////////////////////////////
-DisplayList* DisplayListRenderer::getDisplayList() {
- if (mDisplayList == NULL) {
- mDisplayList = new DisplayList(*this);
+DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) {
+ if (!displayList) {
+ displayList = new DisplayList(*this);
} else {
- mDisplayList->initFromDisplayListRenderer(*this, true);
+ displayList->initFromDisplayListRenderer(*this, true);
}
- return mDisplayList;
+ return displayList;
}
void DisplayListRenderer::setViewport(int width, int height) {
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index b83259f82450..81576313c15f 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -217,7 +217,7 @@ public:
DisplayListRenderer();
~DisplayListRenderer();
- DisplayList* getDisplayList();
+ DisplayList* getDisplayList(DisplayList* displayList);
void setViewport(int width, int height);
void prepareDirty(float left, float top, float right, float bottom, bool opaque);
@@ -474,8 +474,6 @@ private:
SkWriter32 mWriter;
- DisplayList *mDisplayList;
-
int mRestoreSaveCount;
friend class DisplayList;
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 412552ec8eca..0e8ae619fc5c 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -310,35 +310,21 @@ int FramebufferNativeWindow::perform(ANativeWindow* window,
int operation, ...)
{
switch (operation) {
- case NATIVE_WINDOW_SET_USAGE:
- // TODO: we should implement this
- return NO_ERROR;
case NATIVE_WINDOW_CONNECT:
- // TODO: we should implement this
- return NO_ERROR;
case NATIVE_WINDOW_DISCONNECT:
- // TODO: we should implement this
+ case NATIVE_WINDOW_SET_USAGE:
+ case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
+ case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
+ case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
+ case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
+ // TODO: we should implement these
return NO_ERROR;
+
case NATIVE_WINDOW_LOCK:
- return INVALID_OPERATION;
case NATIVE_WINDOW_UNLOCK_AND_POST:
- return INVALID_OPERATION;
case NATIVE_WINDOW_SET_CROP:
- return INVALID_OPERATION;
case NATIVE_WINDOW_SET_BUFFER_COUNT:
- // TODO: we should implement this
- return INVALID_OPERATION;
- case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
- return INVALID_OPERATION;
- case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
- return INVALID_OPERATION;
case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
- return INVALID_OPERATION;
- case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
- return INVALID_OPERATION;
- case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
- // TODO: we should implement this
- return NO_ERROR;
case NATIVE_WINDOW_SET_SCALING_MODE:
return INVALID_OPERATION;
}
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index f6333576a142..e4eadbd0046d 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -29,7 +29,6 @@ commonSources:= \
Flattenable.cpp \
LinearTransform.cpp \
ObbFile.cpp \
- Pool.cpp \
PropertyMap.cpp \
RefBase.cpp \
ResourceTypes.cpp \
diff --git a/libs/utils/Pool.cpp b/libs/utils/Pool.cpp
deleted file mode 100644
index 8f18cb913ea4..000000000000
--- a/libs/utils/Pool.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-// A simple memory pool.
-//
-#define LOG_TAG "Pool"
-
-//#define LOG_NDEBUG 0
-
-#include <cutils/log.h>
-#include <utils/Pool.h>
-
-#include <stdlib.h>
-
-namespace android {
-
-// TODO Provide a real implementation of a pool. This is just a stub for initial development.
-
-PoolImpl::PoolImpl(size_t objSize) :
- mObjSize(objSize) {
-}
-
-PoolImpl::~PoolImpl() {
-}
-
-void* PoolImpl::allocImpl() {
- void* ptr = malloc(mObjSize);
- LOG_ALWAYS_FATAL_IF(ptr == NULL, "Cannot allocate new pool object.");
- return ptr;
-}
-
-void PoolImpl::freeImpl(void* obj) {
- LOG_ALWAYS_FATAL_IF(obj == NULL, "Caller attempted to free NULL pool object.");
- return free(obj);
-}
-
-} // namespace android
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index c567a6e252e8..855e831541ce 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -185,7 +185,10 @@ public class AudioRecord
* Size of the native audio buffer.
*/
private int mNativeBufferSizeInBytes = 0;
-
+ /**
+ * Audio session ID
+ */
+ private int mSessionId = 0;
//---------------------------------------------------------
// Constructor, Finalize
@@ -227,15 +230,20 @@ public class AudioRecord
audioBuffSizeCheck(bufferSizeInBytes);
// native initialization
+ int[] session = new int[1];
+ session[0] = 0;
//TODO: update native initialization when information about hardware init failure
// due to capture device already open is available.
int initResult = native_setup( new WeakReference<AudioRecord>(this),
- mRecordSource, mSampleRate, mChannels, mAudioFormat, mNativeBufferSizeInBytes);
+ mRecordSource, mSampleRate, mChannels, mAudioFormat, mNativeBufferSizeInBytes,
+ session);
if (initResult != SUCCESS) {
loge("Error code "+initResult+" when initializing native AudioRecord object.");
return; // with mState == STATE_UNINITIALIZED
}
+ mSessionId = session[0];
+
mState = STATE_INITIALIZED;
}
@@ -485,6 +493,15 @@ public class AudioRecord
}
}
+ /**
+ * Returns the audio session ID.
+ *
+ * @return the ID of the audio session this AudioRecord belongs to.
+ * @hide
+ */
+ public int getAudioSessionId() {
+ return mSessionId;
+ }
//---------------------------------------------------------
// Transport control methods
@@ -763,7 +780,8 @@ public class AudioRecord
//--------------------
private native final int native_setup(Object audiorecord_this,
- int recordSource, int sampleRate, int nbChannels, int audioFormat, int buffSizeInBytes);
+ int recordSource, int sampleRate, int nbChannels, int audioFormat,
+ int buffSizeInBytes, int[] sessionId);
private native final void native_finalize();
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index e3cbd5783c8f..72069ac19a90 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -81,9 +81,6 @@ public class MediaRecorder
private String mPath;
private FileDescriptor mFd;
- private boolean mPrepareAuxiliaryFile = false;
- private String mPathAux;
- private FileDescriptor mFdAux;
private EventHandler mEventHandler;
private OnErrorListener mOnErrorListener;
private OnInfoListener mOnInfoListener;
@@ -557,84 +554,23 @@ public class MediaRecorder
}
/**
- * Sets the auxiliary time lapse video's resolution and bitrate.
- *
- * The auxiliary video's resolution and bitrate are determined by the CamcorderProfile
- * quality level {@link android.media.CamcorderProfile#QUALITY_HIGH}.
- */
- private void setAuxVideoParameters() {
- CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
- setParameter(String.format("video-aux-param-width=%d", profile.videoFrameWidth));
- setParameter(String.format("video-aux-param-height=%d", profile.videoFrameHeight));
- setParameter(String.format("video-aux-param-encoding-bitrate=%d", profile.videoBitRate));
- }
-
- /**
- * Pass in the file descriptor for the auxiliary time lapse video. Call this before
- * prepare().
- *
- * Sets file descriptor and parameters for auxiliary time lapse video. Time lapse mode
- * can capture video (using the still camera) at resolutions higher than that can be
- * played back on the device. This function or
- * {@link #setAuxiliaryOutputFile(String)} enable capture of a smaller video in
- * parallel with the main time lapse video, which can be used to play back on the
- * device. The smaller video is created by downsampling the main video. This call is
- * optional and does not have to be called if parallel capture of a downsampled video
- * is not desired.
- *
- * Note that while the main video resolution and bitrate is determined from the
- * CamcorderProfile in {@link #setProfile(CamcorderProfile)}, the auxiliary video's
- * resolution and bitrate are determined by the CamcorderProfile quality level
- * {@link android.media.CamcorderProfile#QUALITY_HIGH}. All other encoding parameters
- * remain the same for the main video and the auxiliary video.
- *
- * E.g. if the device supports the time lapse profile quality level
- * {@link android.media.CamcorderProfile#QUALITY_TIME_LAPSE_1080P} but can playback at
- * most 480p, the application might want to capture an auxiliary video of resolution
- * 480p using this call.
- *
- * @param fd an open file descriptor to be written into.
+ * Currently not implemented. It does nothing.
+ * @deprecated Time lapse mode video recording using camera still image capture
+ * is not desirable, and will not be supported.
*/
public void setAuxiliaryOutputFile(FileDescriptor fd)
{
- mPrepareAuxiliaryFile = true;
- mPathAux = null;
- mFdAux = fd;
- setAuxVideoParameters();
+ Log.w(TAG, "setAuxiliaryOutputFile(FileDescriptor) is no longer supported.");
}
/**
- * Pass in the file path for the auxiliary time lapse video. Call this before
- * prepare().
- *
- * Sets file path and parameters for auxiliary time lapse video. Time lapse mode can
- * capture video (using the still camera) at resolutions higher than that can be
- * played back on the device. This function or
- * {@link #setAuxiliaryOutputFile(FileDescriptor)} enable capture of a smaller
- * video in parallel with the main time lapse video, which can be used to play back on
- * the device. The smaller video is created by downsampling the main video. This call
- * is optional and does not have to be called if parallel capture of a downsampled
- * video is not desired.
- *
- * Note that while the main video resolution and bitrate is determined from the
- * CamcorderProfile in {@link #setProfile(CamcorderProfile)}, the auxiliary video's
- * resolution and bitrate are determined by the CamcorderProfile quality level
- * {@link android.media.CamcorderProfile#QUALITY_HIGH}. All other encoding parameters
- * remain the same for the main video and the auxiliary video.
- *
- * E.g. if the device supports the time lapse profile quality level
- * {@link android.media.CamcorderProfile#QUALITY_TIME_LAPSE_1080P} but can playback at
- * most 480p, the application might want to capture an auxiliary video of resolution
- * 480p using this call.
- *
- * @param path The pathname to use.
+ * Currently not implemented. It does nothing.
+ * @deprecated Time lapse mode video recording using camera still image capture
+ * is not desirable, and will not be supported.
*/
public void setAuxiliaryOutputFile(String path)
{
- mPrepareAuxiliaryFile = true;
- mFdAux = null;
- mPathAux = path;
- setAuxVideoParameters();
+ Log.w(TAG, "setAuxiliaryOutputFile(String) is no longer supported.");
}
/**
@@ -668,8 +604,6 @@ public class MediaRecorder
// native implementation
private native void _setOutputFile(FileDescriptor fd, long offset, long length)
throws IllegalStateException, IOException;
- private native void _setOutputFileAux(FileDescriptor fd)
- throws IllegalStateException, IOException;
private native void _prepare() throws IllegalStateException, IOException;
/**
@@ -696,21 +630,6 @@ public class MediaRecorder
throw new IOException("No valid output file");
}
- if (mPrepareAuxiliaryFile) {
- if (mPathAux != null) {
- FileOutputStream fos = new FileOutputStream(mPathAux);
- try {
- _setOutputFileAux(fos.getFD());
- } finally {
- fos.close();
- }
- } else if (mFdAux != null) {
- _setOutputFileAux(mFdAux);
- } else {
- throw new IOException("No valid output file");
- }
- }
-
_prepare();
}
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index 0d2bcd5376e5..6b0fb12d86db 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -912,11 +912,14 @@ class MediaArtistNativeHelper {
/** 720p 1280 X 720 */
public static final int V720p = 10;
- /** 1080 x 720 */
+ /** W720p 1080 x 720 */
public static final int W720p = 11;
- /** 1080 960 x 720 */
+ /** S720p 960 x 720 */
public static final int S720p = 12;
+
+ /** 1080p 1920 x 1080 */
+ public static final int V1080p = 13;
}
/**
@@ -3548,6 +3551,8 @@ class MediaArtistNativeHelper {
retValue = VideoFrameSize.WVGA16x9;
else if (height == MediaProperties.HEIGHT_720)
retValue = VideoFrameSize.V720p;
+ else if (height == MediaProperties.HEIGHT_1080)
+ retValue = VideoFrameSize.V1080p;
break;
case MediaProperties.ASPECT_RATIO_4_3:
if (height == MediaProperties.HEIGHT_480)
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java
index 4faa83a02fe3..73cc7e2add21 100755
--- a/media/java/android/media/videoeditor/MediaImageItem.java
+++ b/media/java/android/media/videoeditor/MediaImageItem.java
@@ -503,51 +503,75 @@ public class MediaImageItem extends MediaItem {
return adjustedOverlays;
}
-
-
/**
- * This function sets the Ken Burn effect generated clip
- * name.
+ * This function get the proper width by given aspect ratio
+ * and height.
*
- * @param generatedFilePath The name of the generated clip
+ * @param aspectRatio Given aspect ratio
+ * @param height Given height
*/
- @Override
- void setGeneratedImageClip(String generatedFilePath) {
- super.setGeneratedImageClip(generatedFilePath);
+ private int getWidthByAspectRatioAndHeight(int aspectRatio, int height) {
+ int width = 0;
-
- // set the Kenburns clip width and height
- mGeneratedClipHeight = getScaledHeight();
- switch (mVideoEditor.getAspectRatio()) {
+ switch (aspectRatio) {
case MediaProperties.ASPECT_RATIO_3_2:
- if (mGeneratedClipHeight == MediaProperties.HEIGHT_480)
- mGeneratedClipWidth = 720;
- else if (mGeneratedClipHeight == MediaProperties.HEIGHT_720)
- mGeneratedClipWidth = 1080;
+ if (height == MediaProperties.HEIGHT_480)
+ width = 720;
+ else if (height == MediaProperties.HEIGHT_720)
+ width = 1080;
break;
+
case MediaProperties.ASPECT_RATIO_16_9:
- if (mGeneratedClipHeight == MediaProperties.HEIGHT_360)
- mGeneratedClipWidth = 640;
- else if (mGeneratedClipHeight == MediaProperties.HEIGHT_480)
- mGeneratedClipWidth = 854;
- else if (mGeneratedClipHeight == MediaProperties.HEIGHT_720)
- mGeneratedClipWidth = 1280;
+ if (height == MediaProperties.HEIGHT_360)
+ width = 640;
+ else if (height == MediaProperties.HEIGHT_480)
+ width = 854;
+ else if (height == MediaProperties.HEIGHT_720)
+ width = 1280;
+ else if (height == MediaProperties.HEIGHT_1080)
+ width = 1920;
break;
+
case MediaProperties.ASPECT_RATIO_4_3:
- if (mGeneratedClipHeight == MediaProperties.HEIGHT_480)
- mGeneratedClipWidth = 640;
- if (mGeneratedClipHeight == MediaProperties.HEIGHT_720)
- mGeneratedClipWidth = 960;
+ if (height == MediaProperties.HEIGHT_480)
+ width = 640;
+ if (height == MediaProperties.HEIGHT_720)
+ width = 960;
break;
+
case MediaProperties.ASPECT_RATIO_5_3:
- if (mGeneratedClipHeight == MediaProperties.HEIGHT_480)
- mGeneratedClipWidth = 800;
+ if (height == MediaProperties.HEIGHT_480)
+ width = 800;
break;
+
case MediaProperties.ASPECT_RATIO_11_9:
- if (mGeneratedClipHeight == MediaProperties.HEIGHT_144)
- mGeneratedClipWidth = 176;
+ if (height == MediaProperties.HEIGHT_144)
+ width = 176;
break;
+
+ default : {
+ throw new IllegalArgumentException(
+ "Illegal arguments for aspectRatio");
+ }
}
+
+ return width;
+ }
+
+ /**
+ * This function sets the Ken Burn effect generated clip
+ * name.
+ *
+ * @param generatedFilePath The name of the generated clip
+ */
+ @Override
+ void setGeneratedImageClip(String generatedFilePath) {
+ super.setGeneratedImageClip(generatedFilePath);
+
+ // set the Kenburns clip width and height
+ mGeneratedClipHeight = getScaledHeight();
+ mGeneratedClipWidth = getWidthByAspectRatioAndHeight(
+ mVideoEditor.getAspectRatio(), mGeneratedClipHeight);
}
/**
@@ -841,37 +865,8 @@ public class MediaImageItem extends MediaItem {
clipSettings.fileType = FileType.THREE_GPP;
mGeneratedClipHeight = getScaledHeight();
- switch (mVideoEditor.getAspectRatio()) {
- case MediaProperties.ASPECT_RATIO_3_2:
- if (mGeneratedClipHeight == MediaProperties.HEIGHT_480)
- mGeneratedClipWidth = 720;
- else if (mGeneratedClipHeight == MediaProperties.HEIGHT_720)
- mGeneratedClipWidth = 1080;
- break;
- case MediaProperties.ASPECT_RATIO_16_9:
- if (mGeneratedClipHeight == MediaProperties.HEIGHT_360)
- mGeneratedClipWidth = 640;
- else if (mGeneratedClipHeight == MediaProperties.HEIGHT_480)
- mGeneratedClipWidth = 854;
- else if (mGeneratedClipHeight == MediaProperties.HEIGHT_720)
- mGeneratedClipWidth = 1280;
- break;
- case MediaProperties.ASPECT_RATIO_4_3:
- if (mGeneratedClipHeight == MediaProperties.HEIGHT_480)
- mGeneratedClipWidth = 640;
- if (mGeneratedClipHeight == MediaProperties.HEIGHT_720)
- mGeneratedClipWidth = 960;
- break;
- case MediaProperties.ASPECT_RATIO_5_3:
- if (mGeneratedClipHeight == MediaProperties.HEIGHT_480)
- mGeneratedClipWidth = 800;
- break;
- case MediaProperties.ASPECT_RATIO_11_9:
- if (mGeneratedClipHeight == MediaProperties.HEIGHT_144)
- mGeneratedClipWidth = 176;
- break;
- }
-
+ mGeneratedClipWidth = getWidthByAspectRatioAndHeight(
+ mVideoEditor.getAspectRatio(), mGeneratedClipHeight);
} else {
if (getGeneratedImageClip() == null) {
clipSettings.clipPath = getDecodedImageFileName();
diff --git a/media/java/android/media/videoeditor/MediaProperties.java b/media/java/android/media/videoeditor/MediaProperties.java
index 022580779c37..ff13e5dbe4af 100755
--- a/media/java/android/media/videoeditor/MediaProperties.java
+++ b/media/java/android/media/videoeditor/MediaProperties.java
@@ -17,8 +17,9 @@
package android.media.videoeditor;
+import android.media.videoeditor.VideoEditorProfile;
import android.util.Pair;
-
+import java.lang.System;
/**
* This class defines all properties of a media file such as supported height,
* aspect ratio, bitrate for export function.
@@ -33,7 +34,7 @@ public class MediaProperties {
public static final int HEIGHT_360 = 360;
public static final int HEIGHT_480 = 480;
public static final int HEIGHT_720 = 720;
- public static final int HEIGHT_1088 = 1088;
+ public static final int HEIGHT_1080 = 1080;
/**
* Supported aspect ratios
@@ -63,8 +64,7 @@ public class MediaProperties {
private static final Pair<Integer, Integer>[] ASPECT_RATIO_3_2_RESOLUTIONS =
new Pair[] {
new Pair<Integer, Integer>(720, HEIGHT_480),
-//*tmpLSA*/ new Pair<Integer, Integer>(1080, HEIGHT_720)
-/*tmpLSA*/ new Pair<Integer, Integer>(1088, HEIGHT_720)
+ new Pair<Integer, Integer>(1080, HEIGHT_720)
};
@SuppressWarnings({"unchecked"})
@@ -92,6 +92,7 @@ public class MediaProperties {
new Pair[] {
new Pair<Integer, Integer>(848, HEIGHT_480),
new Pair<Integer, Integer>(1280, HEIGHT_720),
+ new Pair<Integer, Integer>(1920, HEIGHT_1080),
};
/**
@@ -345,7 +346,31 @@ public class MediaProperties {
}
}
- return resolutions;
+ /** Check the platform specific maximum export resolution */
+ VideoEditorProfile veProfile = VideoEditorProfile.get();
+ if (veProfile == null) {
+ throw new RuntimeException("Can't get the video editor profile");
+ }
+ final int maxWidth = veProfile.maxOutputVideoFrameWidth;
+ final int maxHeight = veProfile.maxOutputVideoFrameHeight;
+ Pair<Integer, Integer>[] tmpResolutions = new Pair[resolutions.length];
+ int numSupportedResolution = 0;
+ int i = 0;
+
+ /** Get supported resolution list */
+ for (i = 0; i < resolutions.length; i++) {
+ if ((resolutions[i].first <= maxWidth) &&
+ (resolutions[i].second <= maxHeight)) {
+ tmpResolutions[numSupportedResolution] = resolutions[i];
+ numSupportedResolution++;
+ }
+ }
+ final Pair<Integer, Integer>[] supportedResolutions =
+ new Pair[numSupportedResolution];
+ System.arraycopy(tmpResolutions, 0,
+ supportedResolutions, 0, numSupportedResolution);
+
+ return supportedResolutions;
}
/**
diff --git a/media/java/android/media/videoeditor/MediaVideoItem.java b/media/java/android/media/videoeditor/MediaVideoItem.java
index 4758de6bb40e..62486515548f 100755
--- a/media/java/android/media/videoeditor/MediaVideoItem.java
+++ b/media/java/android/media/videoeditor/MediaVideoItem.java
@@ -23,6 +23,7 @@ import java.lang.ref.SoftReference;
import android.graphics.Bitmap;
import android.media.videoeditor.MediaArtistNativeHelper.ClipSettings;
import android.media.videoeditor.MediaArtistNativeHelper.Properties;
+import android.media.videoeditor.VideoEditorProfile;
import android.view.Surface;
import android.view.SurfaceHolder;
@@ -118,6 +119,21 @@ public class MediaVideoItem extends MediaItem {
throw new IllegalArgumentException(e.getMessage() + " : " + filename);
}
+ /** Check the platform specific maximum import resolution */
+ VideoEditorProfile veProfile = VideoEditorProfile.get();
+ if (veProfile == null) {
+ throw new RuntimeException("Can't get the video editor profile");
+ }
+ final int maxInputWidth = veProfile.maxInputVideoFrameWidth;
+ final int maxInputHeight = veProfile.maxInputVideoFrameHeight;
+ if ((properties.width > maxInputWidth) ||
+ (properties.height > maxInputHeight)) {
+ throw new IllegalArgumentException(
+ "Unsupported import resolution. Supported maximum width:" +
+ maxInputWidth + " height:" + maxInputHeight +
+ ", current width:" + properties.width +
+ " height:" + properties.height);
+ }
switch (mMANativeHelper.getFileType(properties.fileType)) {
case MediaProperties.FILE_3GP:
case MediaProperties.FILE_MP4:
diff --git a/media/java/android/media/videoeditor/VideoEditor.java b/media/java/android/media/videoeditor/VideoEditor.java
index 59e454086f04..720e80227382 100755
--- a/media/java/android/media/videoeditor/VideoEditor.java
+++ b/media/java/android/media/videoeditor/VideoEditor.java
@@ -370,7 +370,7 @@ public interface VideoEditor {
*/
public void export(String filename, int height, int bitrate,
ExportProgressListener listener)
- throws IOException;
+ throws IOException;
/**
* Create the output movie based on all media items added and the applied
@@ -413,7 +413,7 @@ public interface VideoEditor {
*/
public void export(String filename, int height, int bitrate, int audioCodec,
int videoCodec, ExportProgressListener listener)
- throws IOException;
+ throws IOException;
/**
* Cancel the running export operation. This method blocks until the export
diff --git a/media/java/android/media/videoeditor/VideoEditorImpl.java b/media/java/android/media/videoeditor/VideoEditorImpl.java
index 649b98a6fa57..ea7fe63e30d9 100755
--- a/media/java/android/media/videoeditor/VideoEditorImpl.java
+++ b/media/java/android/media/videoeditor/VideoEditorImpl.java
@@ -337,7 +337,8 @@ public class VideoEditorImpl implements VideoEditor {
*/
public void export(String filename, int height, int bitrate,
int audioCodec, int videoCodec,
- ExportProgressListener listener) throws IOException {
+ ExportProgressListener listener)
+ throws IOException {
switch (audioCodec) {
case MediaProperties.ACODEC_AAC_LC:
@@ -372,7 +373,8 @@ public class VideoEditorImpl implements VideoEditor {
* {@inheritDoc}
*/
public void export(String filename, int height, int bitrate,
- ExportProgressListener listener) throws IOException {
+ ExportProgressListener listener)
+ throws IOException {
if (filename == null) {
throw new IllegalArgumentException("export: filename is null");
}
@@ -386,6 +388,20 @@ public class VideoEditorImpl implements VideoEditor {
throw new IllegalStateException("No MediaItems added");
}
+ /** Check the platform specific maximum export resolution */
+ VideoEditorProfile veProfile = VideoEditorProfile.get();
+ if (veProfile == null) {
+ throw new RuntimeException("Can't get the video editor profile");
+ }
+ final int maxOutputHeight = veProfile.maxOutputVideoFrameHeight;
+ final int maxOutputWidth = veProfile.maxOutputVideoFrameWidth;
+ if (height > maxOutputHeight) {
+ throw new IllegalArgumentException(
+ "Unsupported export resolution. Supported maximum width:" +
+ maxOutputWidth + " height:" + maxOutputHeight +
+ " current height:" + height);
+ }
+
switch (height) {
case MediaProperties.HEIGHT_144:
break;
@@ -397,6 +413,8 @@ public class VideoEditorImpl implements VideoEditor {
break;
case MediaProperties.HEIGHT_720:
break;
+ case MediaProperties.HEIGHT_1080:
+ break;
default: {
String message = "Unsupported height value " + height;
diff --git a/media/java/android/media/videoeditor/VideoEditorProfile.java b/media/java/android/media/videoeditor/VideoEditorProfile.java
new file mode 100755
index 000000000000..7d9fc8fa6a44
--- /dev/null
+++ b/media/java/android/media/videoeditor/VideoEditorProfile.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media.videoeditor;
+
+/**
+ * The VideoEditorProfile class is used to retrieve the
+ * predefined videoeditor profile settings for videoeditor applications.
+ * These settings are read-only.
+ *
+ * <p>The videoeditor profile specifies the following set of parameters:
+ * <ul>
+ * <li> max input video frame width
+ * <li> max input video frame height
+ * <li> max output video frame width
+ * <li> max output video frame height
+ * </ul>
+ * {@hide}
+ */
+public class VideoEditorProfile
+{
+ /**
+ * The max input video frame width
+ */
+ public int maxInputVideoFrameWidth;
+
+ /**
+ * The max input video frame height
+ */
+ public int maxInputVideoFrameHeight;
+
+ /**
+ * The max ouput video frame width
+ */
+ public int maxOutputVideoFrameWidth;
+
+ /**
+ * The max ouput video frame height
+ */
+ public int maxOutputVideoFrameHeight;
+
+ /**
+ * Returns the videoeditor profile
+ */
+ public static VideoEditorProfile get() {
+ return native_get_videoeditor_profile();
+ }
+
+ static {
+ System.loadLibrary("media_jni");
+ native_init();
+ }
+
+ // Private constructor called by JNI
+ private VideoEditorProfile(int inputWidth,
+ int inputHeight,
+ int outputWidth,
+ int outputHeight) {
+
+ this.maxInputVideoFrameWidth = inputWidth;
+ this.maxInputVideoFrameHeight = inputHeight;
+ this.maxOutputVideoFrameWidth = outputWidth;
+ this.maxOutputVideoFrameHeight = outputHeight;
+ }
+
+ // Methods implemented by JNI
+ private static native final void native_init();
+ private static native final VideoEditorProfile
+ native_get_videoeditor_profile();
+}
diff --git a/media/jni/android_media_MediaProfiles.cpp b/media/jni/android_media_MediaProfiles.cpp
index 08a6de119bd7..2b8dfe4dd20b 100644
--- a/media/jni/android_media_MediaProfiles.cpp
+++ b/media/jni/android_media_MediaProfiles.cpp
@@ -286,6 +286,44 @@ android_media_MediaProfiles_native_get_image_encoding_quality_level(JNIEnv *env,
}
return static_cast<jint>(levels[index]);
}
+static jobject
+android_media_MediaProfiles_native_get_videoeditor_profile(JNIEnv *env, jobject thiz)
+{
+ LOGV("native_get_videoeditor_profile");
+
+ int maxInputFrameWidth =
+ sProfiles->getVideoEditorCapParamByName("videoeditor.input.width.max");
+ int maxInputFrameHeight =
+ sProfiles->getVideoEditorCapParamByName("videoeditor.input.height.max");
+ int maxOutputFrameWidth =
+ sProfiles->getVideoEditorCapParamByName("videoeditor.output.width.max");
+ int maxOutputFrameHeight =
+ sProfiles->getVideoEditorCapParamByName("videoeditor.output.height.max");
+
+ // Check on the values retrieved
+ if (maxInputFrameWidth == -1 || maxInputFrameHeight == -1 ||
+ maxOutputFrameWidth == -1 || maxOutputFrameHeight == -1) {
+
+ jniThrowException(env, "java/lang/RuntimeException",\
+ "Error retrieving videoeditor profile params");
+ return NULL;
+ }
+ LOGV("native_get_videoeditor_profile \
+ inWidth:%d inHeight:%d,outWidth:%d, outHeight:%d",\
+ maxInputFrameWidth,maxInputFrameHeight,\
+ maxOutputFrameWidth,maxOutputFrameHeight);
+
+ jclass VideoEditorProfileClazz =
+ env->FindClass("android/media/videoeditor/VideoEditorProfile");
+ jmethodID VideoEditorProfileConstructorMethodID =
+ env->GetMethodID(VideoEditorProfileClazz, "<init>", "(IIII)V");
+ return env->NewObject(VideoEditorProfileClazz,
+ VideoEditorProfileConstructorMethodID,
+ maxInputFrameWidth,
+ maxInputFrameHeight,
+ maxOutputFrameWidth,
+ maxOutputFrameHeight);
+}
static JNINativeMethod gMethodsForEncoderCapabilitiesClass[] = {
{"native_init", "()V", (void *)android_media_MediaProfiles_native_init},
@@ -324,10 +362,17 @@ static JNINativeMethod gMethodsForCameraProfileClass[] = {
{"native_get_image_encoding_quality_level","(II)I", (void *)android_media_MediaProfiles_native_get_image_encoding_quality_level},
};
+static JNINativeMethod gMethodsForVideoEditorProfileClass[] = {
+ {"native_init", "()V", (void *)android_media_MediaProfiles_native_init},
+ {"native_get_videoeditor_profile", "()Landroid/media/videoeditor/VideoEditorProfile;",
+ (void *)android_media_MediaProfiles_native_get_videoeditor_profile},
+};
+
static const char* const kEncoderCapabilitiesClassPathName = "android/media/EncoderCapabilities";
static const char* const kDecoderCapabilitiesClassPathName = "android/media/DecoderCapabilities";
static const char* const kCamcorderProfileClassPathName = "android/media/CamcorderProfile";
static const char* const kCameraProfileClassPathName = "android/media/CameraProfile";
+static const char* const kVideoEditorProfileClassPathName = "android/media/videoeditor/VideoEditorProfile";
// This function only registers the native methods, and is called from
// JNI_OnLoad in android_media_MediaPlayer.cpp
@@ -353,6 +398,11 @@ int register_android_media_MediaProfiles(JNIEnv *env)
gMethodsForCameraProfileClass,
NELEM(gMethodsForCameraProfileClass));
+ int ret5 = AndroidRuntime::registerNativeMethods(env,
+ kVideoEditorProfileClassPathName,
+ gMethodsForVideoEditorProfileClass,
+ NELEM(gMethodsForVideoEditorProfileClass));
+
// Success if all return values from above are 0
- return (ret1 || ret2 || ret3 || ret4);
+ return (ret1 || ret2 || ret3 || ret4 || ret5);
}
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 12391c87171e..922f7edcb721 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -127,7 +127,7 @@ static bool process_media_recorder_call(JNIEnv *env, status_t opStatus, const ch
return false;
}
-static sp<MediaRecorder> getMediaRecorder(JNIEnv* env, jobject thiz)
+sp<MediaRecorder> getMediaRecorder(JNIEnv* env, jobject thiz)
{
Mutex::Autolock l(sLock);
MediaRecorder* const p = (MediaRecorder*)env->GetIntField(thiz, fields.context);
@@ -261,20 +261,6 @@ android_media_MediaRecorder_setOutputFileFD(JNIEnv *env, jobject thiz, jobject f
}
static void
-android_media_MediaRecorder_setOutputFileAuxFD(JNIEnv *env, jobject thiz, jobject fileDescriptor)
-{
- LOGV("setOutputFile");
- if (fileDescriptor == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
- return;
- }
- int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
- sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
- status_t opStatus = mr->setOutputFileAuxiliary(fd);
- process_media_recorder_call(env, opStatus, "java/io/IOException", "setOutputFile failed.");
-}
-
-static void
android_media_MediaRecorder_setVideoSize(JNIEnv *env, jobject thiz, jint width, jint height)
{
LOGV("setVideoSize(%d, %d)", width, height);
@@ -475,7 +461,6 @@ static JNINativeMethod gMethods[] = {
{"setAudioEncoder", "(I)V", (void *)android_media_MediaRecorder_setAudioEncoder},
{"setParameter", "(Ljava/lang/String;)V", (void *)android_media_MediaRecorder_setParameter},
{"_setOutputFile", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaRecorder_setOutputFileFD},
- {"_setOutputFileAux", "(Ljava/io/FileDescriptor;)V", (void *)android_media_MediaRecorder_setOutputFileAuxFD},
{"setVideoSize", "(II)V", (void *)android_media_MediaRecorder_setVideoSize},
{"setVideoFrameRate", "(I)V", (void *)android_media_MediaRecorder_setVideoFrameRate},
{"setMaxDuration", "(I)V", (void *)android_media_MediaRecorder_setMaxDuration},
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index d0d2d1e6f92f..b88296fb4b72 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -46,6 +46,16 @@ struct fields_t {
};
static fields_t fields;
+static status_t checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
+ if (env->ExceptionCheck()) {
+ LOGE("An exception was thrown by callback '%s'.", methodName);
+ LOGE_EX(env);
+ env->ExceptionClear();
+ return UNKNOWN_ERROR;
+ }
+ return OK;
+}
+
class MyMediaScannerClient : public MediaScannerClient
{
public:
@@ -86,9 +96,7 @@ public:
mEnv->DeleteGlobalRef(mClient);
}
- // Returns true if it succeeded, false if an exception occured
- // in the Java code
- virtual bool scanFile(const char* path, long long lastModified,
+ virtual status_t scanFile(const char* path, long long lastModified,
long long fileSize, bool isDirectory, bool noMedia)
{
LOGV("scanFile: path(%s), time(%lld), size(%lld) and isDir(%d)",
@@ -96,27 +104,29 @@ public:
jstring pathStr;
if ((pathStr = mEnv->NewStringUTF(path)) == NULL) {
- return false;
+ mEnv->ExceptionClear();
+ return NO_MEMORY;
}
mEnv->CallVoidMethod(mClient, mScanFileMethodID, pathStr, lastModified,
fileSize, isDirectory, noMedia);
mEnv->DeleteLocalRef(pathStr);
- return (!mEnv->ExceptionCheck());
+ return checkAndClearExceptionFromCallback(mEnv, "scanFile");
}
- // Returns true if it succeeded, false if an exception occured
- // in the Java code
- virtual bool handleStringTag(const char* name, const char* value)
+ virtual status_t handleStringTag(const char* name, const char* value)
{
LOGV("handleStringTag: name(%s) and value(%s)", name, value);
jstring nameStr, valueStr;
if ((nameStr = mEnv->NewStringUTF(name)) == NULL) {
- return false;
+ mEnv->ExceptionClear();
+ return NO_MEMORY;
}
if ((valueStr = mEnv->NewStringUTF(value)) == NULL) {
- return false;
+ mEnv->DeleteLocalRef(nameStr);
+ mEnv->ExceptionClear();
+ return NO_MEMORY;
}
mEnv->CallVoidMethod(
@@ -124,23 +134,22 @@ public:
mEnv->DeleteLocalRef(nameStr);
mEnv->DeleteLocalRef(valueStr);
- return (!mEnv->ExceptionCheck());
+ return checkAndClearExceptionFromCallback(mEnv, "handleStringTag");
}
- // Returns true if it succeeded, false if an exception occured
- // in the Java code
- virtual bool setMimeType(const char* mimeType)
+ virtual status_t setMimeType(const char* mimeType)
{
LOGV("setMimeType: %s", mimeType);
jstring mimeTypeStr;
if ((mimeTypeStr = mEnv->NewStringUTF(mimeType)) == NULL) {
- return false;
+ mEnv->ExceptionClear();
+ return NO_MEMORY;
}
mEnv->CallVoidMethod(mClient, mSetMimeTypeMethodID, mimeTypeStr);
mEnv->DeleteLocalRef(mimeTypeStr);
- return (!mEnv->ExceptionCheck());
+ return checkAndClearExceptionFromCallback(mEnv, "setMimeType");
}
private:
@@ -152,12 +161,6 @@ private:
};
-static bool ExceptionCheck(void* env)
-{
- LOGV("ExceptionCheck");
- return ((JNIEnv *)env)->ExceptionCheck();
-}
-
static MediaScanner *getNativeScanner_l(JNIEnv* env, jobject thiz)
{
return (MediaScanner *) env->GetIntField(thiz, fields.context);
@@ -190,7 +193,10 @@ android_media_MediaScanner_processDirectory(
}
MyMediaScannerClient myClient(env, client);
- mp->processDirectory(pathStr, myClient, ExceptionCheck, env);
+ MediaScanResult result = mp->processDirectory(pathStr, myClient);
+ if (result == MEDIA_SCAN_RESULT_ERROR) {
+ LOGE("An error occurred while scanning directory '%s'.", pathStr);
+ }
env->ReleaseStringUTFChars(path, pathStr);
}
@@ -227,7 +233,10 @@ android_media_MediaScanner_processFile(
}
MyMediaScannerClient myClient(env, client);
- mp->processFile(pathStr, mimeTypeStr, myClient);
+ MediaScanResult result = mp->processFile(pathStr, mimeTypeStr, myClient);
+ if (result == MEDIA_SCAN_RESULT_ERROR) {
+ LOGE("An error occurred while scanning file '%s'.", pathStr);
+ }
env->ReleaseStringUTFChars(path, pathStr);
if (mimeType) {
env->ReleaseStringUTFChars(mimeType, mimeTypeStr);
diff --git a/media/jni/mediaeditor/VideoEditorClasses.cpp b/media/jni/mediaeditor/VideoEditorClasses.cpp
index 277e16c4dc3b..4c0e73157c60 100755
--- a/media/jni/mediaeditor/VideoEditorClasses.cpp
+++ b/media/jni/mediaeditor/VideoEditorClasses.cpp
@@ -439,9 +439,10 @@ VIDEOEDIT_JAVA_DEFINE_CONSTANTS(VideoFrameSize)
VIDEOEDIT_JAVA_CONSTANT_INIT("NTSC", M4VIDEOEDITING_kNTSC),
VIDEOEDIT_JAVA_CONSTANT_INIT("nHD", M4VIDEOEDITING_k640_360),
VIDEOEDIT_JAVA_CONSTANT_INIT("WVGA16x9", M4VIDEOEDITING_k854_480),
- VIDEOEDIT_JAVA_CONSTANT_INIT("V720p", M4VIDEOEDITING_kHD1280),
- VIDEOEDIT_JAVA_CONSTANT_INIT("W720p", M4VIDEOEDITING_kHD1080),
- VIDEOEDIT_JAVA_CONSTANT_INIT("S720p", M4VIDEOEDITING_kHD960)
+ VIDEOEDIT_JAVA_CONSTANT_INIT("V720p", M4VIDEOEDITING_k1280_720),
+ VIDEOEDIT_JAVA_CONSTANT_INIT("W720p", M4VIDEOEDITING_k1080_720),
+ VIDEOEDIT_JAVA_CONSTANT_INIT("S720p", M4VIDEOEDITING_k960_720),
+ VIDEOEDIT_JAVA_CONSTANT_INIT("V1080p", M4VIDEOEDITING_k1920_1080)
};
VIDEOEDIT_JAVA_DEFINE_CONSTANT_CLASS(VideoFrameSize, VIDEO_FRAME_SIZE_CLASS_NAME,
diff --git a/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp b/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp
index 9de720768c40..93fe70238349 100755
--- a/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorPropertiesMain.cpp
@@ -214,18 +214,6 @@ jobject videoEditProp_getProperties(
"Invalid File or File not found ");
}
- /**
- * Max resolution supported is 1280 x 720.
- */
- if ( (pClipProperties->uiVideoWidth > 1280)
- || (pClipProperties->uiVideoHeight > 720) )
- {
- result = M4MCS_ERR_INVALID_INPUT_VIDEO_FRAME_SIZE;
- videoEditJava_checkAndThrowIllegalArgumentException(
- &gotten, pEnv, (M4NO_ERROR != result),
- "Unsupported input video frame size");
- }
-
#ifdef USE_SOFTWARE_DECODER
/**
* Input clip with non-multiples of 16 is not supported.
diff --git a/media/libeffects/data/audio_effects.conf b/media/libeffects/data/audio_effects.conf
index e6a7b370c386..b8fa4875c4fe 100644
--- a/media/libeffects/data/audio_effects.conf
+++ b/media/libeffects/data/audio_effects.conf
@@ -1,5 +1,10 @@
# List of effect libraries to load. Each library element must contain a "path" element
# giving the full path of the library .so file.
+# libraries {
+# <lib name> {
+# path <lib path>
+# }
+# }
libraries {
bundle {
path /system/lib/soundfx/libbundlewrapper.so
@@ -10,6 +15,9 @@ libraries {
visualizer {
path /system/lib/soundfx/libvisualizer.so
}
+ pre_processing {
+ path /system/lib/soundfx/libaudiopreprocessing.so
+ }
}
# list of effects to load. Each effect element must contain a "library" and a "uuid" element.
@@ -17,6 +25,16 @@ libraries {
# "libraries" element.
# The name of the effect element is indicative, only the value of the "uuid" element
# designates the effect.
+# The uuid is the implementation specific UUID as specified by the effect vendor. This is not the
+# generic effect type UUID.
+# effects {
+# <fx name> {
+# library <lib name>
+# uuid <effect uuid>
+# }
+# ...
+# }
+
effects {
bassboost {
library bundle
@@ -54,4 +72,55 @@ effects {
library visualizer
uuid d069d9e0-8329-11df-9168-0002a5d5c51b
}
+ agc {
+ library pre_processing
+ uuid aa8130e0-66fc-11e0-bad0-0002a5d5c51b
+ }
+ aec {
+ library pre_processing
+ uuid bb392ec0-8d4d-11e0-a896-0002a5d5c51b
+ }
+ ns {
+ library pre_processing
+ uuid c06c8400-8e06-11e0-9cb6-0002a5d5c51b
+ }
}
+# Audio preprocessor configurations.
+# The pre processor configuration consists in a list of elements each describing
+# pre processor settings for a given input source. Valid input source names are:
+# "mic", "camcorder", "voice_recognition", "voice_communication"
+# Each input source element contains a list of effects elements. The name of the effect
+# element must be the name of one of the effects in the "effects" list of the file.
+# Each effect element may optionally contain a list of parameters and their
+# default value to apply when the pre processor effect is created.
+# A parameter is defined by a "param" element and a "value" element. Each of these elements
+# consists in one or more elements specifying a type followed by a value.
+# The types defined are: "int", "short", "float", "bool" and "string"
+# When both "param" and "value" are a single int, a simple form is allowed where just
+# the param and value pair is present in the parameter description
+# pre_processing {
+# <input source name> {
+# <fx name> {
+# <param 1 name> {
+# param {
+# int|short|float|bool|string <value>
+# [ int|short|float|bool|string <value> ]
+# ...
+# }
+# value {
+# int|short|float|bool|string <value>
+# [ int|short|float|bool|string <value> ]
+# ...
+# }
+# }
+# <param 2 name > {<param> <value>}
+# ...
+# }
+# ...
+# }
+# ...
+# }
+
+#
+# TODO: add default audio pre processor configurations after debug and tuning phase
+#
diff --git a/media/libeffects/factory/Android.mk b/media/libeffects/factory/Android.mk
index 26265ae0d988..2f2b974773d0 100644
--- a/media/libeffects/factory/Android.mk
+++ b/media/libeffects/factory/Android.mk
@@ -14,4 +14,7 @@ LOCAL_MODULE:= libeffects
LOCAL_SHARED_LIBRARIES += libdl
+LOCAL_C_INCLUDES := \
+ system/media/audio_effects/include
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c
index a9689bcad839..d333510c72fe 100644
--- a/media/libeffects/factory/EffectsFactory.c
+++ b/media/libeffects/factory/EffectsFactory.c
@@ -24,6 +24,7 @@
#include <cutils/misc.h>
#include <cutils/config_utils.h>
+#include <audio_effects/audio_effects_conf.h>
static list_elem_t *gEffectList; // list of effect_entry_t: all currently created effects
static list_elem_t *gLibraryList; // list of lib_entry_t: all currently loaded libraries
diff --git a/media/libeffects/factory/EffectsFactory.h b/media/libeffects/factory/EffectsFactory.h
index fcc0dbad3d60..c1d4319798d5 100644
--- a/media/libeffects/factory/EffectsFactory.h
+++ b/media/libeffects/factory/EffectsFactory.h
@@ -26,13 +26,6 @@
extern "C" {
#endif
-#define AUDIO_EFFECT_DEFAULT_CONFIG_FILE "/system/etc/audio_effects.conf"
-#define AUDIO_EFFECT_VENDOR_CONFIG_FILE "/vendor/etc/audio_effects.conf"
-#define EFFECTS_TAG "effects"
-#define LIBRARIES_TAG "libraries"
-#define PATH_TAG "path"
-#define LIBRARY_TAG "library"
-#define UUID_TAG "uuid"
typedef struct list_elem_s {
void *object;
diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp
index 8d98900c0ac1..39195516fff6 100644
--- a/media/libmedia/AudioEffect.cpp
+++ b/media/libmedia/AudioEffect.cpp
@@ -47,11 +47,11 @@ AudioEffect::AudioEffect(const effect_uuid_t *type,
effect_callback_t cbf,
void* user,
int sessionId,
- audio_io_handle_t output
+ audio_io_handle_t io
)
: mStatus(NO_INIT)
{
- mStatus = set(type, uuid, priority, cbf, user, sessionId, output);
+ mStatus = set(type, uuid, priority, cbf, user, sessionId, io);
}
AudioEffect::AudioEffect(const char *typeStr,
@@ -60,7 +60,7 @@ AudioEffect::AudioEffect(const char *typeStr,
effect_callback_t cbf,
void* user,
int sessionId,
- audio_io_handle_t output
+ audio_io_handle_t io
)
: mStatus(NO_INIT)
{
@@ -83,7 +83,7 @@ AudioEffect::AudioEffect(const char *typeStr,
}
}
- mStatus = set(pType, pUuid, priority, cbf, user, sessionId, output);
+ mStatus = set(pType, pUuid, priority, cbf, user, sessionId, io);
}
status_t AudioEffect::set(const effect_uuid_t *type,
@@ -92,13 +92,13 @@ status_t AudioEffect::set(const effect_uuid_t *type,
effect_callback_t cbf,
void* user,
int sessionId,
- audio_io_handle_t output)
+ audio_io_handle_t io)
{
sp<IEffect> iEffect;
sp<IMemory> cblk;
int enabled;
- LOGV("set %p mUserData: %p", this, user);
+ LOGV("set %p mUserData: %p uuid: %p timeLow %08x", this, user, type, type ? type->timeLow : 0);
if (mIEffect != 0) {
LOGW("Effect already in use");
@@ -135,7 +135,7 @@ status_t AudioEffect::set(const effect_uuid_t *type,
mIEffectClient = new EffectClient(this);
iEffect = audioFlinger->createEffect(getpid(), (effect_descriptor_t *)&mDescriptor,
- mIEffectClient, priority, output, mSessionId, &mStatus, &mId, &enabled);
+ mIEffectClient, priority, io, mSessionId, &mStatus, &mId, &enabled);
if (iEffect == 0 || (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS)) {
LOGE("set(): AudioFlinger could not create effect, status: %d", mStatus);
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 4c4aad0ababf..1ec596e80d3d 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -162,8 +162,19 @@ status_t AudioRecord::set(
int channelCount = popcount(channelMask);
+ if (sessionId == 0 ) {
+ mSessionId = AudioSystem::newAudioSessionId();
+ } else {
+ mSessionId = sessionId;
+ }
+ LOGV("set(): mSessionId %d", mSessionId);
+
audio_io_handle_t input = AudioSystem::getInput(inputSource,
- sampleRate, format, channelMask, (audio_in_acoustics_t)flags);
+ sampleRate,
+ format,
+ channelMask,
+ (audio_in_acoustics_t)flags,
+ mSessionId);
if (input == 0) {
LOGE("Could not get audio input for record source %d", inputSource);
return BAD_VALUE;
@@ -187,8 +198,6 @@ status_t AudioRecord::set(
notificationFrames = frameCount/2;
}
- mSessionId = sessionId;
-
// create the IAudioRecord
status = openRecord_l(sampleRate, format, channelMask,
frameCount, flags, input);
@@ -589,8 +598,10 @@ audio_io_handle_t AudioRecord::getInput_l()
{
mInput = AudioSystem::getInput(mInputSource,
mCblk->sampleRate,
- mFormat, mChannelMask,
- (audio_in_acoustics_t)mFlags);
+ mFormat,
+ mChannelMask,
+ (audio_in_acoustics_t)mFlags,
+ mSessionId);
return mInput;
}
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 6cb38478985c..5009957abc3b 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -605,11 +605,12 @@ audio_io_handle_t AudioSystem::getInput(int inputSource,
uint32_t samplingRate,
uint32_t format,
uint32_t channels,
- audio_in_acoustics_t acoustics)
+ audio_in_acoustics_t acoustics,
+ int sessionId)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return 0;
- return aps->getInput(inputSource, samplingRate, format, channels, acoustics);
+ return aps->getInput(inputSource, samplingRate, format, channels, acoustics, sessionId);
}
status_t AudioSystem::startInput(audio_io_handle_t input)
@@ -678,14 +679,14 @@ audio_io_handle_t AudioSystem::getOutputForEffect(effect_descriptor_t *desc)
}
status_t AudioSystem::registerEffect(effect_descriptor_t *desc,
- audio_io_handle_t output,
+ audio_io_handle_t io,
uint32_t strategy,
int session,
int id)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- return aps->registerEffect(desc, output, strategy, session, id);
+ return aps->registerEffect(desc, io, strategy, session, id);
}
status_t AudioSystem::unregisterEffect(int id)
@@ -695,9 +696,11 @@ status_t AudioSystem::unregisterEffect(int id)
return aps->unregisterEffect(id);
}
-status_t AudioSystem::isStreamActive(int stream, bool* state, uint32_t inPastMs) {
+status_t AudioSystem::isStreamActive(int stream, bool* state, uint32_t inPastMs)
+{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
+ if (state == NULL) return BAD_VALUE;
*state = aps->isStreamActive(stream, inPastMs);
return NO_ERROR;
}
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 9fbcee0e09b7..49d410f4ce86 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -184,7 +184,8 @@ public:
uint32_t samplingRate,
uint32_t format,
uint32_t channels,
- audio_in_acoustics_t acoustics)
+ audio_in_acoustics_t acoustics,
+ int audioSession)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@@ -193,6 +194,7 @@ public:
data.writeInt32(static_cast <uint32_t>(format));
data.writeInt32(channels);
data.writeInt32(static_cast <uint32_t>(acoustics));
+ data.writeInt32(audioSession);
remote()->transact(GET_INPUT, data, &reply);
return static_cast <audio_io_handle_t> (reply.readInt32());
}
@@ -285,7 +287,7 @@ public:
}
virtual status_t registerEffect(effect_descriptor_t *desc,
- audio_io_handle_t output,
+ audio_io_handle_t io,
uint32_t strategy,
int session,
int id)
@@ -293,7 +295,7 @@ public:
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.write(desc, sizeof(effect_descriptor_t));
- data.writeInt32(output);
+ data.writeInt32(io);
data.writeInt32(strategy);
data.writeInt32(session);
data.writeInt32(id);
@@ -439,11 +441,13 @@ status_t BnAudioPolicyService::onTransact(
uint32_t channels = data.readInt32();
audio_in_acoustics_t acoustics =
static_cast <audio_in_acoustics_t>(data.readInt32());
+ int audioSession = data.readInt32();
audio_io_handle_t input = getInput(inputSource,
samplingRate,
format,
channels,
- acoustics);
+ acoustics,
+ audioSession);
reply->writeInt32(static_cast <int>(input));
return NO_ERROR;
} break;
@@ -528,12 +532,12 @@ status_t BnAudioPolicyService::onTransact(
CHECK_INTERFACE(IAudioPolicyService, data, reply);
effect_descriptor_t desc;
data.read(&desc, sizeof(effect_descriptor_t));
- audio_io_handle_t output = data.readInt32();
+ audio_io_handle_t io = data.readInt32();
uint32_t strategy = data.readInt32();
int session = data.readInt32();
int id = data.readInt32();
reply->writeInt32(static_cast <int32_t>(registerEffect(&desc,
- output,
+ io,
strategy,
session,
id)));
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index a44ef5ab1b95..7e44c2991c5c 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -23,14 +23,17 @@
#include <camera/ICamera.h>
#include <media/IMediaRecorderClient.h>
#include <media/IMediaRecorder.h>
+#include <gui/ISurfaceTexture.h>
#include <unistd.h>
+
namespace android {
enum {
RELEASE = IBinder::FIRST_CALL_TRANSACTION,
INIT,
CLOSE,
+ QUERY_SURFACE_MEDIASOURCE,
RESET,
STOP,
START,
@@ -71,6 +74,19 @@ public:
return reply.readInt32();
}
+ sp<ISurfaceTexture> querySurfaceMediaSource()
+ {
+ LOGV("Query SurfaceMediaSource");
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
+ remote()->transact(QUERY_SURFACE_MEDIASOURCE, data, &reply);
+ int returnedNull = reply.readInt32();
+ if (returnedNull) {
+ return NULL;
+ }
+ return interface_cast<ISurfaceTexture>(reply.readStrongBinder());
+ }
+
status_t setPreviewSurface(const sp<Surface>& surface)
{
LOGV("setPreviewSurface(%p)", surface.get());
@@ -440,6 +456,20 @@ status_t BnMediaRecorder::onTransact(
reply->writeInt32(setCamera(camera, proxy));
return NO_ERROR;
} break;
+ case QUERY_SURFACE_MEDIASOURCE: {
+ LOGV("QUERY_SURFACE_MEDIASOURCE");
+ CHECK_INTERFACE(IMediaRecorder, data, reply);
+ // call the mediaserver side to create
+ // a surfacemediasource
+ sp<ISurfaceTexture> surfaceMediaSource = querySurfaceMediaSource();
+ // The mediaserver might have failed to create a source
+ int returnedNull= (surfaceMediaSource == NULL) ? 1 : 0 ;
+ reply->writeInt32(returnedNull);
+ if (!returnedNull) {
+ reply->writeStrongBinder(surfaceMediaSource->asBinder());
+ }
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index 069bbb7dcf85..f0f07a2151f0 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -132,6 +132,16 @@ MediaProfiles::logAudioDecoderCap(const MediaProfiles::AudioDecoderCap& cap)
LOGV("codec = %d", cap.mCodec);
}
+/*static*/ void
+MediaProfiles::logVideoEditorCap(const MediaProfiles::VideoEditorCap& cap)
+{
+ LOGV("videoeditor cap:");
+ LOGV("mMaxInputFrameWidth = %d", cap.mMaxInputFrameWidth);
+ LOGV("mMaxInputFrameHeight = %d", cap.mMaxInputFrameHeight);
+ LOGV("mMaxOutputFrameWidth = %d", cap.mMaxOutputFrameWidth);
+ LOGV("mMaxOutputFrameHeight = %d", cap.mMaxOutputFrameHeight);
+}
+
/*static*/ int
MediaProfiles::findTagForName(const MediaProfiles::NameToTagMap *map, size_t nMappings, const char *name)
{
@@ -368,6 +378,24 @@ void MediaProfiles::addStartTimeOffset(int cameraId, const char** atts)
mStartTimeOffsets.replaceValueFor(cameraId, offsetTimeMs);
}
+/*static*/ MediaProfiles::VideoEditorCap*
+MediaProfiles::createVideoEditorCap(const char **atts, MediaProfiles *profiles)
+{
+ CHECK(!strcmp("maxInputFrameWidth", atts[0]) &&
+ !strcmp("maxInputFrameHeight", atts[2]) &&
+ !strcmp("maxOutputFrameWidth", atts[4]) &&
+ !strcmp("maxOutputFrameHeight", atts[6]));
+
+ MediaProfiles::VideoEditorCap *pVideoEditorCap =
+ new MediaProfiles::VideoEditorCap(atoi(atts[1]), atoi(atts[3]),
+ atoi(atts[5]), atoi(atts[7]));
+
+ logVideoEditorCap(*pVideoEditorCap);
+ profiles->mVideoEditorCap = pVideoEditorCap;
+
+ return pVideoEditorCap;
+}
+
/*static*/ void
MediaProfiles::startElementHandler(void *userData, const char *name, const char **atts)
{
@@ -398,6 +426,8 @@ MediaProfiles::startElementHandler(void *userData, const char *name, const char
createCamcorderProfile(profiles->mCurrentCameraId, atts, profiles->mCameraIds));
} else if (strcmp("ImageEncoding", name) == 0) {
profiles->addImageEncodingQualityLevel(profiles->mCurrentCameraId, atts);
+ } else if (strcmp("VideoEditorCap", name) == 0) {
+ createVideoEditorCap(atts, profiles);
}
}
@@ -790,6 +820,17 @@ MediaProfiles::createDefaultImageEncodingQualityLevels(MediaProfiles *profiles)
profiles->mImageEncodingQualityLevels.add(levels);
}
+/*static*/ void
+MediaProfiles::createDefaultVideoEditorCap(MediaProfiles *profiles)
+{
+ profiles->mVideoEditorCap =
+ new MediaProfiles::VideoEditorCap(
+ VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH,
+ VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT,
+ VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH,
+ VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT);
+}
+
/*static*/ MediaProfiles*
MediaProfiles::createDefaultInstance()
{
@@ -801,6 +842,7 @@ MediaProfiles::createDefaultInstance()
createDefaultAudioDecoders(profiles);
createDefaultEncoderOutputFileFormats(profiles);
createDefaultImageEncodingQualityLevels(profiles);
+ createDefaultVideoEditorCap(profiles);
return profiles;
}
@@ -899,6 +941,28 @@ int MediaProfiles::getVideoEncoderParamByName(const char *name, video_encoder co
return -1;
}
+int MediaProfiles::getVideoEditorCapParamByName(const char *name) const
+{
+ LOGV("getVideoEditorCapParamByName: %s", name);
+
+ if (mVideoEditorCap == NULL) {
+ LOGE("The mVideoEditorCap is not created, then create default cap.");
+ createDefaultVideoEditorCap(sInstance);
+ }
+
+ if (!strcmp("videoeditor.input.width.max", name))
+ return mVideoEditorCap->mMaxInputFrameWidth;
+ if (!strcmp("videoeditor.input.height.max", name))
+ return mVideoEditorCap->mMaxInputFrameHeight;
+ if (!strcmp("videoeditor.output.width.max", name))
+ return mVideoEditorCap->mMaxOutputFrameWidth;
+ if (!strcmp("videoeditor.output.height.max", name))
+ return mVideoEditorCap->mMaxOutputFrameHeight;
+
+ LOGE("The given video editor param name %s is not found", name);
+ return -1;
+}
+
Vector<audio_encoder> MediaProfiles::getAudioEncoders() const
{
Vector<audio_encoder> encoders;
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index 45bdff4cd4a4..41f8593a9033 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -47,16 +47,15 @@ const char *MediaScanner::locale() const {
return mLocale;
}
-status_t MediaScanner::processDirectory(
- const char *path, MediaScannerClient &client,
- ExceptionCheck exceptionCheck, void *exceptionEnv) {
+MediaScanResult MediaScanner::processDirectory(
+ const char *path, MediaScannerClient &client) {
int pathLength = strlen(path);
if (pathLength >= PATH_MAX) {
- return UNKNOWN_ERROR;
+ return MEDIA_SCAN_RESULT_SKIPPED;
}
char* pathBuffer = (char *)malloc(PATH_MAX + 1);
if (!pathBuffer) {
- return UNKNOWN_ERROR;
+ return MEDIA_SCAN_RESULT_ERROR;
}
int pathRemaining = PATH_MAX - pathLength;
@@ -69,21 +68,18 @@ status_t MediaScanner::processDirectory(
client.setLocale(locale());
- status_t result =
- doProcessDirectory(pathBuffer, pathRemaining, client, false, exceptionCheck, exceptionEnv);
+ MediaScanResult result = doProcessDirectory(pathBuffer, pathRemaining, client, false);
free(pathBuffer);
return result;
}
-status_t MediaScanner::doProcessDirectory(
- char *path, int pathRemaining, MediaScannerClient &client,
- bool noMedia, ExceptionCheck exceptionCheck, void *exceptionEnv) {
+MediaScanResult MediaScanner::doProcessDirectory(
+ char *path, int pathRemaining, MediaScannerClient &client, bool noMedia) {
// place to copy file or directory name
char* fileSpot = path + strlen(path);
struct dirent* entry;
- struct stat statbuf;
// Treat all files as non-media in directories that contain a ".nomedia" file
if (pathRemaining >= 8 /* strlen(".nomedia") */ ) {
@@ -99,76 +95,88 @@ status_t MediaScanner::doProcessDirectory(
DIR* dir = opendir(path);
if (!dir) {
- LOGD("opendir %s failed, errno: %d", path, errno);
- return UNKNOWN_ERROR;
+ LOGW("Error opening directory '%s', skipping: %s.", path, strerror(errno));
+ return MEDIA_SCAN_RESULT_SKIPPED;
}
+ MediaScanResult result = MEDIA_SCAN_RESULT_OK;
while ((entry = readdir(dir))) {
- const char* name = entry->d_name;
-
- // ignore "." and ".."
- if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
- continue;
+ if (doProcessDirectoryEntry(path, pathRemaining, client, noMedia, entry, fileSpot)
+ == MEDIA_SCAN_RESULT_ERROR) {
+ result = MEDIA_SCAN_RESULT_ERROR;
+ break;
}
+ }
+ closedir(dir);
+ return result;
+}
- int nameLength = strlen(name);
- if (nameLength + 1 > pathRemaining) {
- // path too long!
- continue;
- }
- strcpy(fileSpot, name);
-
- int type = entry->d_type;
- if (type == DT_UNKNOWN) {
- // If the type is unknown, stat() the file instead.
- // This is sometimes necessary when accessing NFS mounted filesystems, but
- // could be needed in other cases well.
- if (stat(path, &statbuf) == 0) {
- if (S_ISREG(statbuf.st_mode)) {
- type = DT_REG;
- } else if (S_ISDIR(statbuf.st_mode)) {
- type = DT_DIR;
- }
- } else {
- LOGD("stat() failed for %s: %s", path, strerror(errno) );
+MediaScanResult MediaScanner::doProcessDirectoryEntry(
+ char *path, int pathRemaining, MediaScannerClient &client, bool noMedia,
+ struct dirent* entry, char* fileSpot) {
+ struct stat statbuf;
+ const char* name = entry->d_name;
+
+ // ignore "." and ".."
+ if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
+ return MEDIA_SCAN_RESULT_SKIPPED;
+ }
+
+ int nameLength = strlen(name);
+ if (nameLength + 1 > pathRemaining) {
+ // path too long!
+ return MEDIA_SCAN_RESULT_SKIPPED;
+ }
+ strcpy(fileSpot, name);
+
+ int type = entry->d_type;
+ if (type == DT_UNKNOWN) {
+ // If the type is unknown, stat() the file instead.
+ // This is sometimes necessary when accessing NFS mounted filesystems, but
+ // could be needed in other cases well.
+ if (stat(path, &statbuf) == 0) {
+ if (S_ISREG(statbuf.st_mode)) {
+ type = DT_REG;
+ } else if (S_ISDIR(statbuf.st_mode)) {
+ type = DT_DIR;
}
+ } else {
+ LOGD("stat() failed for %s: %s", path, strerror(errno) );
}
- if (type == DT_REG || type == DT_DIR) {
- if (type == DT_DIR) {
- bool childNoMedia = noMedia;
- // set noMedia flag on directories with a name that starts with '.'
- // for example, the Mac ".Trashes" directory
- if (name[0] == '.')
- childNoMedia = true;
-
- // report the directory to the client
- if (stat(path, &statbuf) == 0) {
- client.scanFile(path, statbuf.st_mtime, 0, true, childNoMedia);
- }
-
- // and now process its contents
- strcat(fileSpot, "/");
- int err = doProcessDirectory(path, pathRemaining - nameLength - 1, client,
- childNoMedia, exceptionCheck, exceptionEnv);
- if (err) {
- // pass exceptions up - ignore other errors
- if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure;
- LOGE("Error processing '%s' - skipping\n", path);
- continue;
- }
- } else {
- stat(path, &statbuf);
- client.scanFile(path, statbuf.st_mtime, statbuf.st_size, false, noMedia);
- if (exceptionCheck && exceptionCheck(exceptionEnv)) goto failure;
+ }
+ if (type == DT_DIR) {
+ bool childNoMedia = noMedia;
+ // set noMedia flag on directories with a name that starts with '.'
+ // for example, the Mac ".Trashes" directory
+ if (name[0] == '.')
+ childNoMedia = true;
+
+ // report the directory to the client
+ if (stat(path, &statbuf) == 0) {
+ status_t status = client.scanFile(path, statbuf.st_mtime, 0,
+ true /*isDirectory*/, childNoMedia);
+ if (status) {
+ return MEDIA_SCAN_RESULT_ERROR;
}
}
+
+ // and now process its contents
+ strcat(fileSpot, "/");
+ MediaScanResult result = doProcessDirectory(path, pathRemaining - nameLength - 1,
+ client, childNoMedia);
+ if (result == MEDIA_SCAN_RESULT_ERROR) {
+ return MEDIA_SCAN_RESULT_ERROR;
+ }
+ } else if (type == DT_REG) {
+ stat(path, &statbuf);
+ status_t status = client.scanFile(path, statbuf.st_mtime, statbuf.st_size,
+ false /*isDirectory*/, noMedia);
+ if (status) {
+ return MEDIA_SCAN_RESULT_ERROR;
+ }
}
- closedir(dir);
- return OK;
-failure:
- closedir(dir);
- return -1;
+ return MEDIA_SCAN_RESULT_OK;
}
} // namespace android
diff --git a/media/libmedia/MediaScannerClient.cpp b/media/libmedia/MediaScannerClient.cpp
index bd3596e3781c..7a7aeb638b25 100644
--- a/media/libmedia/MediaScannerClient.cpp
+++ b/media/libmedia/MediaScannerClient.cpp
@@ -62,7 +62,7 @@ void MediaScannerClient::beginFile()
mValues = new StringArray;
}
-bool MediaScannerClient::addStringTag(const char* name, const char* value)
+status_t MediaScannerClient::addStringTag(const char* name, const char* value)
{
if (mLocaleEncoding != kEncodingNone) {
// don't bother caching strings that are all ASCII.
@@ -212,8 +212,10 @@ void MediaScannerClient::endFile()
// finally, push all name/value pairs to the client
for (int i = 0; i < mNames->size(); i++) {
- if (!handleStringTag(mNames->getEntry(i), mValues->getEntry(i)))
+ status_t status = handleStringTag(mNames->getEntry(i), mValues->getEntry(i));
+ if (status) {
break;
+ }
}
}
// else addStringTag() has done all the work so we have nothing to do
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index ed6e3c7aa7a5..a11fb804f134 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -228,6 +228,7 @@ status_t MediaPlayer::setVideoSurface(const sp<Surface>& surface)
NATIVE_WINDOW_API_MEDIA);
if (err != OK) {
+ LOGE("setVideoSurface failed: %d", err);
// Note that we must do the reset before disconnecting from the ANW.
// Otherwise queue/dequeue calls could be made on the disconnected
// ANW, which may result in errors.
@@ -277,6 +278,7 @@ status_t MediaPlayer::setVideoSurfaceTexture(
NATIVE_WINDOW_API_MEDIA);
if (err != OK) {
+ LOGE("setVideoSurfaceTexture failed: %d", err);
// Note that we must do the reset before disconnecting from the ANW.
// Otherwise queue/dequeue calls could be made on the disconnected
// ANW, which may result in errors.
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 9e4edd09c8c9..fab674ca515c 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -25,6 +25,7 @@
#include <media/IMediaPlayerService.h>
#include <media/IMediaRecorder.h>
#include <media/mediaplayer.h> // for MEDIA_ERROR_SERVER_DIED
+#include <gui/ISurfaceTexture.h>
namespace android {
@@ -127,7 +128,9 @@ status_t MediaRecorder::setVideoSource(int vs)
return INVALID_OPERATION;
}
+ // following call is made over the Binder Interface
status_t ret = mMediaRecorder->setVideoSource(vs);
+
if (OK != ret) {
LOGV("setVideoSource failed: %d", ret);
mCurrentState = MEDIA_RECORDER_ERROR;
@@ -357,7 +360,7 @@ status_t MediaRecorder::setVideoSize(int width, int height)
return INVALID_OPERATION;
}
if (!mIsVideoSourceSet) {
- LOGE("try to set video size without setting video source first");
+ LOGE("Cannot set video size without setting video source first");
return INVALID_OPERATION;
}
@@ -367,9 +370,27 @@ status_t MediaRecorder::setVideoSize(int width, int height)
mCurrentState = MEDIA_RECORDER_ERROR;
return ret;
}
+
return ret;
}
+// Query a SurfaceMediaSurface through the Mediaserver, over the
+// binder interface. This is used by the Filter Framework (MeidaEncoder)
+// to get an <ISurfaceTexture> object to hook up to ANativeWindow.
+sp<ISurfaceTexture> MediaRecorder::
+ querySurfaceMediaSourceFromMediaServer()
+{
+ Mutex::Autolock _l(mLock);
+ mSurfaceMediaSource =
+ mMediaRecorder->querySurfaceMediaSource();
+ if (mSurfaceMediaSource == NULL) {
+ LOGE("SurfaceMediaSource could not be initialized!");
+ }
+ return mSurfaceMediaSource;
+}
+
+
+
status_t MediaRecorder::setVideoFrameRate(int frames_per_second)
{
LOGV("setVideoFrameRate(%d)", frames_per_second);
@@ -382,7 +403,7 @@ status_t MediaRecorder::setVideoFrameRate(int frames_per_second)
return INVALID_OPERATION;
}
if (!mIsVideoSourceSet) {
- LOGE("try to set video frame rate without setting video source first");
+ LOGE("Cannot set video frame rate without setting video source first");
return INVALID_OPERATION;
}
@@ -621,7 +642,7 @@ status_t MediaRecorder::release()
return INVALID_OPERATION;
}
-MediaRecorder::MediaRecorder()
+MediaRecorder::MediaRecorder() : mSurfaceMediaSource(NULL)
{
LOGV("constructor");
@@ -632,6 +653,8 @@ MediaRecorder::MediaRecorder()
if (mMediaRecorder != NULL) {
mCurrentState = MEDIA_RECORDER_IDLE;
}
+
+
doCleanUp();
}
@@ -646,6 +669,10 @@ MediaRecorder::~MediaRecorder()
if (mMediaRecorder != NULL) {
mMediaRecorder.clear();
}
+
+ if (mSurfaceMediaSource != NULL) {
+ mSurfaceMediaSource.clear();
+ }
}
status_t MediaRecorder::setListener(const sp<MediaRecorderListener>& listener)
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 115db1ad2904..905b88568eb7 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -41,6 +41,7 @@
#include "MediaPlayerService.h"
#include "StagefrightRecorder.h"
+#include <gui/ISurfaceTexture.h>
namespace android {
@@ -57,6 +58,20 @@ static bool checkPermission(const char* permissionString) {
return ok;
}
+
+sp<ISurfaceTexture> MediaRecorderClient::querySurfaceMediaSource()
+{
+ LOGV("Query SurfaceMediaSource");
+ Mutex::Autolock lock(mLock);
+ if (mRecorder == NULL) {
+ LOGE("recorder is not initialized");
+ return NULL;
+ }
+ return mRecorder->querySurfaceMediaSource();
+}
+
+
+
status_t MediaRecorderClient::setCamera(const sp<ICamera>& camera,
const sp<ICameraRecordingProxy>& proxy)
{
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index bbca5291cd5c..c87a3c0a23e8 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -25,45 +25,51 @@ namespace android {
class MediaRecorderBase;
class MediaPlayerService;
class ICameraRecordingProxy;
+class ISurfaceTexture;
class MediaRecorderClient : public BnMediaRecorder
{
public:
- virtual status_t setCamera(const sp<ICamera>& camera,
- const sp<ICameraRecordingProxy>& proxy);
- virtual status_t setPreviewSurface(const sp<Surface>& surface);
- virtual status_t setVideoSource(int vs);
- virtual status_t setAudioSource(int as);
- virtual status_t setOutputFormat(int of);
- virtual status_t setVideoEncoder(int ve);
- virtual status_t setAudioEncoder(int ae);
- virtual status_t setOutputFile(const char* path);
- virtual status_t setOutputFile(int fd, int64_t offset, int64_t length);
- virtual status_t setOutputFileAuxiliary(int fd);
- virtual status_t setVideoSize(int width, int height);
- virtual status_t setVideoFrameRate(int frames_per_second);
- virtual status_t setParameters(const String8& params);
- virtual status_t setListener(const sp<IMediaRecorderClient>& listener);
- virtual status_t prepare();
- virtual status_t getMaxAmplitude(int* max);
- virtual status_t start();
- virtual status_t stop();
- virtual status_t reset();
- virtual status_t init();
- virtual status_t close();
- virtual status_t release();
+ virtual status_t setCamera(const sp<ICamera>& camera,
+ const sp<ICameraRecordingProxy>& proxy);
+ virtual status_t setPreviewSurface(const sp<Surface>& surface);
+ virtual status_t setVideoSource(int vs);
+ virtual status_t setAudioSource(int as);
+ virtual status_t setOutputFormat(int of);
+ virtual status_t setVideoEncoder(int ve);
+ virtual status_t setAudioEncoder(int ae);
+ virtual status_t setOutputFile(const char* path);
+ virtual status_t setOutputFile(int fd, int64_t offset,
+ int64_t length);
+ virtual status_t setOutputFileAuxiliary(int fd);
+ virtual status_t setVideoSize(int width, int height);
+ virtual status_t setVideoFrameRate(int frames_per_second);
+ virtual status_t setParameters(const String8& params);
+ virtual status_t setListener(
+ const sp<IMediaRecorderClient>& listener);
+ virtual status_t prepare();
+ virtual status_t getMaxAmplitude(int* max);
+ virtual status_t start();
+ virtual status_t stop();
+ virtual status_t reset();
+ virtual status_t init();
+ virtual status_t close();
+ virtual status_t release();
+ virtual status_t dump(int fd, const Vector<String16>& args) const;
+ virtual sp<ISurfaceTexture> querySurfaceMediaSource();
- virtual status_t dump(int fd, const Vector<String16>& args) const;
private:
- friend class MediaPlayerService; // for accessing private constructor
+ friend class MediaPlayerService; // for accessing private constructor
- MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid);
- virtual ~MediaRecorderClient();
+ MediaRecorderClient(
+ const sp<MediaPlayerService>& service,
+ pid_t pid);
+ virtual ~MediaRecorderClient();
- pid_t mPid;
- Mutex mLock;
- MediaRecorderBase *mRecorder;
- sp<MediaPlayerService> mMediaPlayerService;
+ pid_t mPid;
+ Mutex mLock;
+ MediaRecorderBase *mRecorder;
+ sp<MediaPlayerService> mMediaPlayerService;
};
}; // namespace android
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 223e0be21a75..6427bb701646 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -38,10 +38,12 @@
#include <media/stagefright/MetaData.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
+#include <media/stagefright/SurfaceMediaSource.h>
#include <media/MediaProfiles.h>
#include <camera/ICamera.h>
#include <camera/CameraParameters.h>
#include <surfaceflinger/Surface.h>
+
#include <utils/Errors.h>
#include <sys/types.h>
#include <ctype.h>
@@ -69,7 +71,7 @@ StagefrightRecorder::StagefrightRecorder()
mOutputFd(-1), mOutputFdAux(-1),
mAudioSource(AUDIO_SOURCE_CNT),
mVideoSource(VIDEO_SOURCE_LIST_END),
- mStarted(false) {
+ mStarted(false), mSurfaceMediaSource(NULL) {
LOGV("Constructor");
reset();
@@ -85,6 +87,14 @@ status_t StagefrightRecorder::init() {
return OK;
}
+// The client side of mediaserver asks it to creat a SurfaceMediaSource
+// and return a interface reference. The client side will use that
+// while encoding GL Frames
+sp<ISurfaceTexture> StagefrightRecorder::querySurfaceMediaSource() const {
+ LOGV("Get SurfaceMediaSource");
+ return mSurfaceMediaSource;
+}
+
status_t StagefrightRecorder::setAudioSource(audio_source_t as) {
LOGV("setAudioSource: %d", as);
if (as < AUDIO_SOURCE_DEFAULT ||
@@ -1006,13 +1016,13 @@ status_t StagefrightRecorder::startRTPRecording() {
source = createAudioSource();
} else {
- sp<CameraSource> cameraSource;
- status_t err = setupCameraSource(&cameraSource);
+ sp<MediaSource> mediaSource;
+ status_t err = setupMediaSource(&mediaSource);
if (err != OK) {
return err;
}
- err = setupVideoEncoder(cameraSource, mVideoBitRate, &source);
+ err = setupVideoEncoder(mediaSource, mVideoBitRate, &source);
if (err != OK) {
return err;
}
@@ -1042,20 +1052,19 @@ status_t StagefrightRecorder::startMPEG2TSRecording() {
}
}
- if (mVideoSource == VIDEO_SOURCE_DEFAULT
- || mVideoSource == VIDEO_SOURCE_CAMERA) {
+ if (mVideoSource < VIDEO_SOURCE_LIST_END) {
if (mVideoEncoder != VIDEO_ENCODER_H264) {
return ERROR_UNSUPPORTED;
}
- sp<CameraSource> cameraSource;
- status_t err = setupCameraSource(&cameraSource);
+ sp<MediaSource> mediaSource;
+ status_t err = setupMediaSource(&mediaSource);
if (err != OK) {
return err;
}
sp<MediaSource> encoder;
- err = setupVideoEncoder(cameraSource, mVideoBitRate, &encoder);
+ err = setupVideoEncoder(mediaSource, mVideoBitRate, &encoder);
if (err != OK) {
return err;
@@ -1289,6 +1298,60 @@ void StagefrightRecorder::clipVideoFrameHeight() {
}
}
+// Set up the appropriate MediaSource depending on the chosen option
+status_t StagefrightRecorder::setupMediaSource(
+ sp<MediaSource> *mediaSource) {
+ if (mVideoSource == VIDEO_SOURCE_DEFAULT
+ || mVideoSource == VIDEO_SOURCE_CAMERA) {
+ sp<CameraSource> cameraSource;
+ status_t err = setupCameraSource(&cameraSource);
+ if (err != OK) {
+ return err;
+ }
+ *mediaSource = cameraSource;
+ } else if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) {
+ // If using GRAlloc buffers, setup surfacemediasource.
+ // Later a handle to that will be passed
+ // to the client side when queried
+ status_t err = setupSurfaceMediaSource();
+ if (err != OK) {
+ return err;
+ }
+ *mediaSource = mSurfaceMediaSource;
+ } else {
+ return INVALID_OPERATION;
+ }
+ return OK;
+}
+
+// setupSurfaceMediaSource creates a source with the given
+// width and height and framerate.
+// TODO: This could go in a static function inside SurfaceMediaSource
+// similar to that in CameraSource
+status_t StagefrightRecorder::setupSurfaceMediaSource() {
+ status_t err = OK;
+ mSurfaceMediaSource = new SurfaceMediaSource(mVideoWidth, mVideoHeight);
+ if (mSurfaceMediaSource == NULL) {
+ return NO_INIT;
+ }
+
+ if (mFrameRate == -1) {
+ int32_t frameRate = 0;
+ CHECK (mSurfaceMediaSource->getFormat()->findInt32(
+ kKeyFrameRate, &frameRate));
+ LOGI("Frame rate is not explicitly set. Use the current frame "
+ "rate (%d fps)", frameRate);
+ mFrameRate = frameRate;
+ } else {
+ err = mSurfaceMediaSource->setFrameRate(mFrameRate);
+ }
+ CHECK(mFrameRate != -1);
+
+ mIsMetaDataStoredInVideoBuffers =
+ mSurfaceMediaSource->isMetaDataStoredInVideoBuffers();
+ return err;
+}
+
status_t StagefrightRecorder::setupCameraSource(
sp<CameraSource> *cameraSource) {
status_t err = OK;
@@ -1465,29 +1528,37 @@ status_t StagefrightRecorder::setupMPEG4Recording(
status_t err = OK;
sp<MediaWriter> writer = new MPEG4Writer(outputFd);
- if (mVideoSource == VIDEO_SOURCE_DEFAULT
- || mVideoSource == VIDEO_SOURCE_CAMERA) {
+ if (mVideoSource < VIDEO_SOURCE_LIST_END) {
- sp<MediaSource> cameraMediaSource;
+ sp<MediaSource> mediaSource;
if (useSplitCameraSource) {
+ // TODO: Check if there is a better way to handle this
+ if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) {
+ LOGE("Cannot use split camera when encoding frames");
+ return INVALID_OPERATION;
+ }
LOGV("Using Split camera source");
- cameraMediaSource = mCameraSourceSplitter->createClient();
+ mediaSource = mCameraSourceSplitter->createClient();
} else {
- sp<CameraSource> cameraSource;
- err = setupCameraSource(&cameraSource);
- cameraMediaSource = cameraSource;
+ err = setupMediaSource(&mediaSource);
}
+
if ((videoWidth != mVideoWidth) || (videoHeight != mVideoHeight)) {
+ // TODO: Might be able to handle downsampling even if using GRAlloc
+ if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) {
+ LOGE("Cannot change size or Downsample when encoding frames");
+ return INVALID_OPERATION;
+ }
// Use downsampling from the original source.
- cameraMediaSource =
- new VideoSourceDownSampler(cameraMediaSource, videoWidth, videoHeight);
+ mediaSource =
+ new VideoSourceDownSampler(mediaSource, videoWidth, videoHeight);
}
if (err != OK) {
return err;
}
sp<MediaSource> encoder;
- err = setupVideoEncoder(cameraMediaSource, videoBitRate, &encoder);
+ err = setupVideoEncoder(mediaSource, videoBitRate, &encoder);
if (err != OK) {
return err;
}
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 034b373337dc..1618b92a78ae 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -36,6 +36,8 @@ struct MediaWriter;
class MetaData;
struct AudioSource;
class MediaProfiles;
+class ISurfaceTexture;
+class SurfaceMediaSource;
struct StagefrightRecorder : public MediaRecorderBase {
StagefrightRecorder();
@@ -64,6 +66,8 @@ struct StagefrightRecorder : public MediaRecorderBase {
virtual status_t reset();
virtual status_t getMaxAmplitude(int *max);
virtual status_t dump(int fd, const Vector<String16>& args) const;
+ // Querying a SurfaceMediaSourcer
+ virtual sp<ISurfaceTexture> querySurfaceMediaSource() const;
private:
sp<ICamera> mCamera;
@@ -109,12 +113,18 @@ private:
sp<MediaSourceSplitter> mCameraSourceSplitter;
sp<CameraSourceTimeLapse> mCameraSourceTimeLapse;
+
String8 mParams;
bool mIsMetaDataStoredInVideoBuffers;
MediaProfiles *mEncoderProfiles;
bool mStarted;
+ // Needed when GLFrames are encoded.
+ // An <ISurfaceTexture> pointer
+ // will be sent to the client side using which the
+ // frame buffers will be queued and dequeued
+ sp<SurfaceMediaSource> mSurfaceMediaSource;
status_t setupMPEG4Recording(
bool useSplitCameraSource,
@@ -134,7 +144,14 @@ private:
sp<MediaSource> createAudioSource();
status_t checkVideoEncoderCapabilities();
status_t checkAudioEncoderCapabilities();
+ // Generic MediaSource set-up. Returns the appropriate
+ // source (CameraSource or SurfaceMediaSource)
+ // depending on the videosource type
+ status_t setupMediaSource(sp<MediaSource> *mediaSource);
status_t setupCameraSource(sp<CameraSource> *cameraSource);
+ // setup the surfacemediasource for the encoder
+ status_t setupSurfaceMediaSource();
+
status_t setupAudioEncoder(const sp<MediaWriter>& writer);
status_t setupVideoEncoder(
sp<MediaSource> cameraSource,
@@ -176,6 +193,7 @@ private:
void clipNumberOfAudioChannels();
void setDefaultProfileIfNecessary();
+
StagefrightRecorder(const StagefrightRecorder &);
StagefrightRecorder &operator=(const StagefrightRecorder &);
};
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index e17e1e835797..3a3c082b08de 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -42,6 +42,7 @@ LOCAL_SRC_FILES:= \
SampleTable.cpp \
StagefrightMediaScanner.cpp \
StagefrightMetadataRetriever.cpp \
+ SurfaceMediaSource.cpp \
ThrottledSource.cpp \
TimeSource.cpp \
TimedEventQueue.cpp \
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 1bc2fb9eecd7..de66d99b7bf2 100755
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -179,9 +179,6 @@ status_t CameraSource::isCameraAvailable(
if (camera == 0) {
mCamera = Camera::connect(cameraId);
if (mCamera == 0) return -EBUSY;
- // If proxy is not passed in by applications, still use the proxy of
- // our own Camera to simplify the code.
- mCameraRecordingProxy = mCamera->getRecordingProxy();
mCameraFlags &= ~FLAGS_HOT_CAMERA;
} else {
// We get the proxy from Camera, not ICamera. We need to get the proxy
@@ -192,12 +189,12 @@ status_t CameraSource::isCameraAvailable(
if (mCamera == 0) return -EBUSY;
mCameraRecordingProxy = proxy;
mCameraFlags |= FLAGS_HOT_CAMERA;
+ mDeathNotifier = new DeathNotifier();
+ // isBinderAlive needs linkToDeath to work.
+ mCameraRecordingProxy->asBinder()->linkToDeath(mDeathNotifier);
}
mCamera->lock();
- mDeathNotifier = new DeathNotifier();
- // isBinderAlive needs linkToDeath to work.
- mCameraRecordingProxy->asBinder()->linkToDeath(mDeathNotifier);
return OK;
}
@@ -292,7 +289,7 @@ status_t CameraSource::configureCamera(
CameraParameters* params,
int32_t width, int32_t height,
int32_t frameRate) {
-
+ LOGV("configureCamera");
Vector<Size> sizes;
bool isSetVideoSizeSupportedByCamera = true;
getSupportedVideoSizes(*params, &isSetVideoSizeSupportedByCamera, sizes);
@@ -368,6 +365,7 @@ status_t CameraSource::checkVideoSize(
const CameraParameters& params,
int32_t width, int32_t height) {
+ LOGV("checkVideoSize");
// The actual video size is the same as the preview size
// if the camera hal does not support separate video and
// preview output. In this case, we retrieve the video
@@ -419,6 +417,7 @@ status_t CameraSource::checkFrameRate(
const CameraParameters& params,
int32_t frameRate) {
+ LOGV("checkFrameRate");
int32_t frameRateActual = params.getPreviewFrameRate();
if (frameRateActual < 0) {
LOGE("Failed to retrieve preview frame rate (%d)", frameRateActual);
@@ -464,6 +463,7 @@ status_t CameraSource::init(
int32_t frameRate,
bool storeMetaDataInVideoBuffers) {
+ LOGV("init");
status_t err = OK;
int64_t token = IPCThreadState::self()->clearCallingIdentity();
err = initWithCameraAccess(camera, proxy, cameraId,
@@ -480,6 +480,7 @@ status_t CameraSource::initWithCameraAccess(
Size videoSize,
int32_t frameRate,
bool storeMetaDataInVideoBuffers) {
+ LOGV("initWithCameraAccess");
status_t err = OK;
if ((err = isCameraAvailable(camera, proxy, cameraId)) != OK) {
@@ -552,17 +553,25 @@ CameraSource::~CameraSource() {
}
void CameraSource::startCameraRecording() {
+ LOGV("startCameraRecording");
// Reset the identity to the current thread because media server owns the
// camera and recording is started by the applications. The applications
// will connect to the camera in ICameraRecordingProxy::startRecording.
int64_t token = IPCThreadState::self()->clearCallingIdentity();
- mCamera->unlock();
- mCamera.clear();
+ if (mCameraFlags & FLAGS_HOT_CAMERA) {
+ mCamera->unlock();
+ mCamera.clear();
+ CHECK_EQ(OK, mCameraRecordingProxy->startRecording(new ProxyListener(this)));
+ } else {
+ mCamera->setListener(new CameraSourceListener(this));
+ mCamera->startRecording();
+ CHECK(mCamera->recordingEnabled());
+ }
IPCThreadState::self()->restoreCallingIdentity(token);
- CHECK_EQ(OK, mCameraRecordingProxy->startRecording(new ProxyListener(this)));
}
status_t CameraSource::start(MetaData *meta) {
+ LOGV("start");
CHECK(!mStarted);
if (mInitCheck != OK) {
LOGE("CameraSource is not initialized yet");
@@ -588,7 +597,13 @@ status_t CameraSource::start(MetaData *meta) {
}
void CameraSource::stopCameraRecording() {
- mCameraRecordingProxy->stopRecording();
+ LOGV("stopCameraRecording");
+ if (mCameraFlags & FLAGS_HOT_CAMERA) {
+ mCameraRecordingProxy->stopRecording();
+ } else {
+ mCamera->setListener(NULL);
+ mCamera->stopRecording();
+ }
}
void CameraSource::releaseCamera() {
@@ -599,11 +614,10 @@ void CameraSource::releaseCamera() {
LOGV("Camera was cold when we started, stopping preview");
mCamera->stopPreview();
mCamera->disconnect();
- } else {
- // Unlock the camera so the application can lock it back.
- mCamera->unlock();
}
+ mCamera->unlock();
mCamera.clear();
+ mCamera = 0;
IPCThreadState::self()->restoreCallingIdentity(token);
}
if (mCameraRecordingProxy != 0) {
@@ -646,8 +660,13 @@ status_t CameraSource::stop() {
}
void CameraSource::releaseRecordingFrame(const sp<IMemory>& frame) {
+ LOGV("releaseRecordingFrame");
if (mCameraRecordingProxy != NULL) {
mCameraRecordingProxy->releaseRecordingFrame(frame);
+ } else {
+ int64_t token = IPCThreadState::self()->clearCallingIdentity();
+ mCamera->releaseRecordingFrame(frame);
+ IPCThreadState::self()->restoreCallingIdentity(token);
}
}
@@ -707,7 +726,8 @@ status_t CameraSource::read(
while (mStarted && mFramesReceived.empty()) {
if (NO_ERROR !=
mFrameAvailableCondition.waitRelative(mLock, 1000000000LL)) {
- if (!mCameraRecordingProxy->asBinder()->isBinderAlive()) {
+ if (mCameraRecordingProxy != 0 &&
+ !mCameraRecordingProxy->asBinder()->isBinderAlive()) {
LOGW("camera recording proxy is gone");
return ERROR_END_OF_STREAM;
}
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 77a66024a60d..4edb613c33b6 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -185,7 +185,8 @@ NuCachedSource2::NuCachedSource2(const sp<DataSource> &source)
mFinalStatus(OK),
mLastAccessPos(0),
mFetching(true),
- mLastFetchTimeUs(-1) {
+ mLastFetchTimeUs(-1),
+ mNumRetriesLeft(kMaxNumRetries) {
mLooper->setName("NuCachedSource2");
mLooper->registerHandler(mReflector);
mLooper->start();
@@ -254,7 +255,27 @@ void NuCachedSource2::onMessageReceived(const sp<AMessage> &msg) {
void NuCachedSource2::fetchInternal() {
LOGV("fetchInternal");
- CHECK_EQ(mFinalStatus, (status_t)OK);
+ {
+ Mutex::Autolock autoLock(mLock);
+ CHECK(mFinalStatus == OK || mNumRetriesLeft > 0);
+
+ if (mFinalStatus != OK) {
+ --mNumRetriesLeft;
+
+ status_t err =
+ mSource->reconnectAtOffset(mCacheOffset + mCache->totalSize());
+
+ if (err == ERROR_UNSUPPORTED) {
+ mNumRetriesLeft = 0;
+ return;
+ } else if (err != OK) {
+ LOGI("The attempt to reconnect failed, %d retries remaining",
+ mNumRetriesLeft);
+
+ return;
+ }
+ }
+ }
PageCache::Page *page = mCache->acquirePage();
@@ -264,14 +285,23 @@ void NuCachedSource2::fetchInternal() {
Mutex::Autolock autoLock(mLock);
if (n < 0) {
- LOGE("source returned error %ld", n);
+ LOGE("source returned error %ld, %d retries left", n, mNumRetriesLeft);
mFinalStatus = n;
mCache->releasePage(page);
} else if (n == 0) {
LOGI("ERROR_END_OF_STREAM");
+
+ mNumRetriesLeft = 0;
mFinalStatus = ERROR_END_OF_STREAM;
+
mCache->releasePage(page);
} else {
+ if (mFinalStatus != OK) {
+ LOGI("retrying a previously failed read succeeded.");
+ }
+ mNumRetriesLeft = kMaxNumRetries;
+ mFinalStatus = OK;
+
page->mSize = n;
mCache->appendPage(page);
}
@@ -280,7 +310,7 @@ void NuCachedSource2::fetchInternal() {
void NuCachedSource2::onFetch() {
LOGV("onFetch");
- if (mFinalStatus != OK) {
+ if (mFinalStatus != OK && mNumRetriesLeft == 0) {
LOGV("EOS reached, done prefetching for now");
mFetching = false;
}
@@ -308,8 +338,19 @@ void NuCachedSource2::onFetch() {
restartPrefetcherIfNecessary_l();
}
- (new AMessage(kWhatFetchMore, mReflector->id()))->post(
- mFetching ? 0 : 100000ll);
+ int64_t delayUs;
+ if (mFetching) {
+ if (mFinalStatus != OK && mNumRetriesLeft > 0) {
+ // We failed this time and will try again in 3 seconds.
+ delayUs = 3000000ll;
+ } else {
+ delayUs = 0;
+ }
+ } else {
+ delayUs = 100000ll;
+ }
+
+ (new AMessage(kWhatFetchMore, mReflector->id()))->post(delayUs);
}
void NuCachedSource2::onRead(const sp<AMessage> &msg) {
@@ -345,7 +386,7 @@ void NuCachedSource2::restartPrefetcherIfNecessary_l(
bool ignoreLowWaterThreshold, bool force) {
static const size_t kGrayArea = 1024 * 1024;
- if (mFetching || mFinalStatus != OK) {
+ if (mFetching || (mFinalStatus != OK && mNumRetriesLeft == 0)) {
return;
}
@@ -427,6 +468,12 @@ size_t NuCachedSource2::approxDataRemaining(status_t *finalStatus) {
size_t NuCachedSource2::approxDataRemaining_l(status_t *finalStatus) {
*finalStatus = mFinalStatus;
+
+ if (mFinalStatus != OK && mNumRetriesLeft > 0) {
+ // Pretend that everything is fine until we're out of retries.
+ *finalStatus = OK;
+ }
+
off64_t lastBytePosCached = mCacheOffset + mCache->totalSize();
if (mLastAccessPos < lastBytePosCached) {
return lastBytePosCached - mLastAccessPos;
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index 89faff76a08a..571e8be27ec8 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -52,13 +52,13 @@ static bool FileHasAcceptableExtension(const char *extension) {
return false;
}
-static status_t HandleMIDI(
+static MediaScanResult HandleMIDI(
const char *filename, MediaScannerClient *client) {
// get the library configuration and do sanity check
const S_EAS_LIB_CONFIG* pLibConfig = EAS_Config();
if ((pLibConfig == NULL) || (LIB_VERSION != pLibConfig->libVersion)) {
LOGE("EAS library/header mismatch\n");
- return UNKNOWN_ERROR;
+ return MEDIA_SCAN_RESULT_ERROR;
}
EAS_I32 temp;
@@ -88,34 +88,41 @@ static status_t HandleMIDI(
}
if (result != EAS_SUCCESS) {
- return UNKNOWN_ERROR;
+ return MEDIA_SCAN_RESULT_SKIPPED;
}
char buffer[20];
sprintf(buffer, "%ld", temp);
- if (!client->addStringTag("duration", buffer)) return UNKNOWN_ERROR;
-
- return OK;
+ status_t status = client->addStringTag("duration", buffer);
+ if (status) {
+ return MEDIA_SCAN_RESULT_ERROR;
+ }
+ return MEDIA_SCAN_RESULT_OK;
}
-status_t StagefrightMediaScanner::processFile(
+MediaScanResult StagefrightMediaScanner::processFile(
const char *path, const char *mimeType,
MediaScannerClient &client) {
LOGV("processFile '%s'.", path);
client.setLocale(locale());
client.beginFile();
+ MediaScanResult result = processFileInternal(path, mimeType, client);
+ client.endFile();
+ return result;
+}
+MediaScanResult StagefrightMediaScanner::processFileInternal(
+ const char *path, const char *mimeType,
+ MediaScannerClient &client) {
const char *extension = strrchr(path, '.');
if (!extension) {
- return UNKNOWN_ERROR;
+ return MEDIA_SCAN_RESULT_SKIPPED;
}
if (!FileHasAcceptableExtension(extension)) {
- client.endFile();
-
- return UNKNOWN_ERROR;
+ return MEDIA_SCAN_RESULT_SKIPPED;
}
if (!strcasecmp(extension, ".mid")
@@ -127,53 +134,57 @@ status_t StagefrightMediaScanner::processFile(
|| !strcasecmp(extension, ".rtx")
|| !strcasecmp(extension, ".ota")
|| !strcasecmp(extension, ".mxmf")) {
- status_t status = HandleMIDI(path, &client);
- if (status != OK) {
- return status;
+ return HandleMIDI(path, &client);
+ }
+
+ sp<MediaMetadataRetriever> mRetriever(new MediaMetadataRetriever);
+
+ status_t status = mRetriever->setDataSource(path);
+ if (status) {
+ return MEDIA_SCAN_RESULT_ERROR;
+ }
+
+ const char *value;
+ if ((value = mRetriever->extractMetadata(
+ METADATA_KEY_MIMETYPE)) != NULL) {
+ status = client.setMimeType(value);
+ if (status) {
+ return MEDIA_SCAN_RESULT_ERROR;
}
- } else {
- sp<MediaMetadataRetriever> mRetriever(new MediaMetadataRetriever);
-
- if (mRetriever->setDataSource(path) == OK) {
- const char *value;
- if ((value = mRetriever->extractMetadata(
- METADATA_KEY_MIMETYPE)) != NULL) {
- client.setMimeType(value);
- }
+ }
- struct KeyMap {
- const char *tag;
- int key;
- };
- static const KeyMap kKeyMap[] = {
- { "tracknumber", METADATA_KEY_CD_TRACK_NUMBER },
- { "discnumber", METADATA_KEY_DISC_NUMBER },
- { "album", METADATA_KEY_ALBUM },
- { "artist", METADATA_KEY_ARTIST },
- { "albumartist", METADATA_KEY_ALBUMARTIST },
- { "composer", METADATA_KEY_COMPOSER },
- { "genre", METADATA_KEY_GENRE },
- { "title", METADATA_KEY_TITLE },
- { "year", METADATA_KEY_YEAR },
- { "duration", METADATA_KEY_DURATION },
- { "writer", METADATA_KEY_WRITER },
- { "compilation", METADATA_KEY_COMPILATION },
- { "isdrm", METADATA_KEY_IS_DRM },
- };
- static const size_t kNumEntries = sizeof(kKeyMap) / sizeof(kKeyMap[0]);
-
- for (size_t i = 0; i < kNumEntries; ++i) {
- const char *value;
- if ((value = mRetriever->extractMetadata(kKeyMap[i].key)) != NULL) {
- client.addStringTag(kKeyMap[i].tag, value);
- }
+ struct KeyMap {
+ const char *tag;
+ int key;
+ };
+ static const KeyMap kKeyMap[] = {
+ { "tracknumber", METADATA_KEY_CD_TRACK_NUMBER },
+ { "discnumber", METADATA_KEY_DISC_NUMBER },
+ { "album", METADATA_KEY_ALBUM },
+ { "artist", METADATA_KEY_ARTIST },
+ { "albumartist", METADATA_KEY_ALBUMARTIST },
+ { "composer", METADATA_KEY_COMPOSER },
+ { "genre", METADATA_KEY_GENRE },
+ { "title", METADATA_KEY_TITLE },
+ { "year", METADATA_KEY_YEAR },
+ { "duration", METADATA_KEY_DURATION },
+ { "writer", METADATA_KEY_WRITER },
+ { "compilation", METADATA_KEY_COMPILATION },
+ { "isdrm", METADATA_KEY_IS_DRM },
+ };
+ static const size_t kNumEntries = sizeof(kKeyMap) / sizeof(kKeyMap[0]);
+
+ for (size_t i = 0; i < kNumEntries; ++i) {
+ const char *value;
+ if ((value = mRetriever->extractMetadata(kKeyMap[i].key)) != NULL) {
+ status = client.addStringTag(kKeyMap[i].tag, value);
+ if (status) {
+ return MEDIA_SCAN_RESULT_ERROR;
}
}
}
- client.endFile();
-
- return OK;
+ return MEDIA_SCAN_RESULT_OK;
}
char *StagefrightMediaScanner::extractAlbumArt(int fd) {
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
new file mode 100644
index 000000000000..ff4b08fb6c3f
--- /dev/null
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -0,0 +1,756 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define LOG_TAG "SurfaceMediaSource"
+
+#include <media/stagefright/SurfaceMediaSource.h>
+#include <ui/GraphicBuffer.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/openmax/OMX_IVCommon.h>
+
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+#include <surfaceflinger/IGraphicBufferAlloc.h>
+#include <OMX_Component.h>
+
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+namespace android {
+
+SurfaceMediaSource::SurfaceMediaSource(uint32_t bufW, uint32_t bufH) :
+ mDefaultWidth(bufW),
+ mDefaultHeight(bufH),
+ mPixelFormat(0),
+ mBufferCount(MIN_ASYNC_BUFFER_SLOTS),
+ mClientBufferCount(0),
+ mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS),
+ mCurrentSlot(INVALID_BUFFER_SLOT),
+ mCurrentTimestamp(0),
+ mSynchronousMode(true),
+ mConnectedApi(NO_CONNECTED_API),
+ mFrameRate(30),
+ mStarted(false) {
+ LOGV("SurfaceMediaSource::SurfaceMediaSource");
+ sp<ISurfaceComposer> composer(ComposerService::getComposerService());
+ mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
+}
+
+SurfaceMediaSource::~SurfaceMediaSource() {
+ LOGV("SurfaceMediaSource::~SurfaceMediaSource");
+ if (mStarted) {
+ stop();
+ }
+ freeAllBuffers();
+}
+
+size_t SurfaceMediaSource::getQueuedCount() const {
+ Mutex::Autolock lock(mMutex);
+ return mQueue.size();
+}
+
+status_t SurfaceMediaSource::setBufferCountServerLocked(int bufferCount) {
+ if (bufferCount > NUM_BUFFER_SLOTS)
+ return BAD_VALUE;
+
+ // special-case, nothing to do
+ if (bufferCount == mBufferCount)
+ return OK;
+
+ if (!mClientBufferCount &&
+ bufferCount >= mBufferCount) {
+ // easy, we just have more buffers
+ mBufferCount = bufferCount;
+ mServerBufferCount = bufferCount;
+ mDequeueCondition.signal();
+ } else {
+ // we're here because we're either
+ // - reducing the number of available buffers
+ // - or there is a client-buffer-count in effect
+
+ // less than 2 buffers is never allowed
+ if (bufferCount < 2)
+ return BAD_VALUE;
+
+ // when there is non client-buffer-count in effect, the client is not
+ // allowed to dequeue more than one buffer at a time,
+ // so the next time they dequeue a buffer, we know that they don't
+ // own one. the actual resizing will happen during the next
+ // dequeueBuffer.
+
+ mServerBufferCount = bufferCount;
+ }
+ return OK;
+}
+
+// Called from the consumer side
+status_t SurfaceMediaSource::setBufferCountServer(int bufferCount) {
+ Mutex::Autolock lock(mMutex);
+ return setBufferCountServerLocked(bufferCount);
+}
+
+status_t SurfaceMediaSource::setBufferCount(int bufferCount) {
+ LOGV("SurfaceMediaSource::setBufferCount");
+ if (bufferCount > NUM_BUFFER_SLOTS) {
+ LOGE("setBufferCount: bufferCount is larger than the number of buffer slots");
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mMutex);
+ // Error out if the user has dequeued buffers
+ for (int i = 0 ; i < mBufferCount ; i++) {
+ if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
+ LOGE("setBufferCount: client owns some buffers");
+ return INVALID_OPERATION;
+ }
+ }
+
+ if (bufferCount == 0) {
+ const int minBufferSlots = mSynchronousMode ?
+ MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
+ mClientBufferCount = 0;
+ bufferCount = (mServerBufferCount >= minBufferSlots) ?
+ mServerBufferCount : minBufferSlots;
+ return setBufferCountServerLocked(bufferCount);
+ }
+
+ // We don't allow the client to set a buffer-count less than
+ // MIN_ASYNC_BUFFER_SLOTS (3), there is no reason for it.
+ if (bufferCount < MIN_ASYNC_BUFFER_SLOTS) {
+ return BAD_VALUE;
+ }
+
+ // here we're guaranteed that the client doesn't have dequeued buffers
+ // and will release all of its buffer references.
+ freeAllBuffers();
+ mBufferCount = bufferCount;
+ mClientBufferCount = bufferCount;
+ mCurrentSlot = INVALID_BUFFER_SLOT;
+ mQueue.clear();
+ mDequeueCondition.signal();
+ return OK;
+}
+
+status_t SurfaceMediaSource::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
+ LOGV("SurfaceMediaSource::requestBuffer");
+ Mutex::Autolock lock(mMutex);
+ if (slot < 0 || mBufferCount <= slot) {
+ LOGE("requestBuffer: slot index out of range [0, %d]: %d",
+ mBufferCount, slot);
+ return BAD_VALUE;
+ }
+ mSlots[slot].mRequestBufferCalled = true;
+ *buf = mSlots[slot].mGraphicBuffer;
+ return NO_ERROR;
+}
+
+status_t SurfaceMediaSource::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
+ uint32_t format, uint32_t usage) {
+ LOGV("dequeueBuffer");
+
+
+ // Check for the buffer size- the client should just use the
+ // default width and height, and not try to set those.
+ // This is needed since
+ // the getFormat() returns mDefaultWidth/ Height for the OMX. It is
+ // queried by OMX in the beginning and not every time a frame comes.
+ // Not sure if there is a way to update the
+ // frame size while recording. So as of now, the client side
+ // sets the default values via the constructor, and the encoder is
+ // setup to encode frames of that size
+ // The design might need to change in the future.
+ // TODO: Currently just uses mDefaultWidth/Height. In the future
+ // we might declare mHeight and mWidth and check against those here.
+ if ((w != 0) || (h != 0)) {
+ LOGE("dequeuebuffer: invalid buffer size! Req: %dx%d, Found: %dx%d",
+ mDefaultWidth, mDefaultHeight, w, h);
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mMutex);
+
+ status_t returnFlags(OK);
+
+ int found, foundSync;
+ int dequeuedCount = 0;
+ bool tryAgain = true;
+ while (tryAgain) {
+ // We need to wait for the FIFO to drain if the number of buffer
+ // needs to change.
+ //
+ // The condition "number of buffer needs to change" is true if
+ // - the client doesn't care about how many buffers there are
+ // - AND the actual number of buffer is different from what was
+ // set in the last setBufferCountServer()
+ // - OR -
+ // setBufferCountServer() was set to a value incompatible with
+ // the synchronization mode (for instance because the sync mode
+ // changed since)
+ //
+ // As long as this condition is true AND the FIFO is not empty, we
+ // wait on mDequeueCondition.
+
+ int minBufferCountNeeded = mSynchronousMode ?
+ MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
+
+ if (!mClientBufferCount &&
+ ((mServerBufferCount != mBufferCount) ||
+ (mServerBufferCount < minBufferCountNeeded))) {
+ // wait for the FIFO to drain
+ while (!mQueue.isEmpty()) {
+ LOGV("Waiting for the FIFO to drain");
+ mDequeueCondition.wait(mMutex);
+ }
+ // need to check again since the mode could have changed
+ // while we were waiting
+ minBufferCountNeeded = mSynchronousMode ?
+ MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
+ }
+
+ if (!mClientBufferCount &&
+ ((mServerBufferCount != mBufferCount) ||
+ (mServerBufferCount < minBufferCountNeeded))) {
+ // here we're guaranteed that mQueue is empty
+ freeAllBuffers();
+ mBufferCount = mServerBufferCount;
+ if (mBufferCount < minBufferCountNeeded)
+ mBufferCount = minBufferCountNeeded;
+ mCurrentSlot = INVALID_BUFFER_SLOT;
+ returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
+ }
+
+ // look for a free buffer to give to the client
+ found = INVALID_BUFFER_SLOT;
+ foundSync = INVALID_BUFFER_SLOT;
+ dequeuedCount = 0;
+ for (int i = 0; i < mBufferCount; i++) {
+ const int state = mSlots[i].mBufferState;
+ if (state == BufferSlot::DEQUEUED) {
+ dequeuedCount++;
+ continue; // won't be continuing if could
+ // dequeue a non 'FREE' current slot like
+ // that in SurfaceTexture
+ }
+ // In case of Encoding, we do not deque the mCurrentSlot buffer
+ // since we follow synchronous mode (unlike possibly in
+ // SurfaceTexture that could be using the asynch mode
+ // or has some mechanism in GL to be able to wait till the
+ // currentslot is done using the data)
+ // Here, we have to wait for the MPEG4Writer(or equiv)
+ // to tell us when it's done using the current buffer
+ if (state == BufferSlot::FREE) {
+ foundSync = i;
+ // Unlike that in SurfaceTexture,
+ // We don't need to worry if it is the
+ // currentslot or not as it is in state FREE
+ found = i;
+ break;
+ }
+ }
+
+ // clients are not allowed to dequeue more than one buffer
+ // if they didn't set a buffer count.
+ if (!mClientBufferCount && dequeuedCount) {
+ return -EINVAL;
+ }
+
+ // See whether a buffer has been queued since the last setBufferCount so
+ // we know whether to perform the MIN_UNDEQUEUED_BUFFERS check below.
+ bool bufferHasBeenQueued = mCurrentSlot != INVALID_BUFFER_SLOT;
+ if (bufferHasBeenQueued) {
+ // make sure the client is not trying to dequeue more buffers
+ // than allowed.
+ const int avail = mBufferCount - (dequeuedCount+1);
+ if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) {
+ LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded (dequeued=%d)",
+ MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode),
+ dequeuedCount);
+ return -EBUSY;
+ }
+ }
+
+ // we're in synchronous mode and didn't find a buffer, we need to wait
+ // for for some buffers to be consumed
+ tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT);
+ if (tryAgain) {
+ LOGW("Waiting..In synchronous mode and no buffer to dQ");
+ mDequeueCondition.wait(mMutex);
+ }
+ }
+
+ if (mSynchronousMode && found == INVALID_BUFFER_SLOT) {
+ // foundSync guaranteed to be != INVALID_BUFFER_SLOT
+ found = foundSync;
+ }
+
+ if (found == INVALID_BUFFER_SLOT) {
+ return -EBUSY;
+ }
+
+ const int buf = found;
+ *outBuf = found;
+
+ const bool useDefaultSize = !w && !h;
+ if (useDefaultSize) {
+ // use the default size
+ w = mDefaultWidth;
+ h = mDefaultHeight;
+ }
+
+ const bool updateFormat = (format != 0);
+ if (!updateFormat) {
+ // keep the current (or default) format
+ format = mPixelFormat;
+ }
+
+ // buffer is now in DEQUEUED (but can also be current at the same time,
+ // if we're in synchronous mode)
+ mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
+
+ const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
+ if ((buffer == NULL) ||
+ (uint32_t(buffer->width) != w) ||
+ (uint32_t(buffer->height) != h) ||
+ (uint32_t(buffer->format) != format) ||
+ ((uint32_t(buffer->usage) & usage) != usage)) {
+ usage |= GraphicBuffer::USAGE_HW_TEXTURE;
+ status_t error;
+ sp<GraphicBuffer> graphicBuffer(
+ mGraphicBufferAlloc->createGraphicBuffer(
+ w, h, format, usage, &error));
+ if (graphicBuffer == 0) {
+ LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer failed");
+ return error;
+ }
+ if (updateFormat) {
+ mPixelFormat = format;
+ }
+ mSlots[buf].mGraphicBuffer = graphicBuffer;
+ mSlots[buf].mRequestBufferCalled = false;
+ returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
+ }
+ return returnFlags;
+}
+
+status_t SurfaceMediaSource::setSynchronousMode(bool enabled) {
+ Mutex::Autolock lock(mMutex);
+
+ status_t err = OK;
+ if (!enabled) {
+ // going to asynchronous mode, drain the queue
+ while (mSynchronousMode != enabled && !mQueue.isEmpty()) {
+ mDequeueCondition.wait(mMutex);
+ }
+ }
+
+ if (mSynchronousMode != enabled) {
+ // - if we're going to asynchronous mode, the queue is guaranteed to be
+ // empty here
+ // - if the client set the number of buffers, we're guaranteed that
+ // we have at least 3 (because we don't allow less)
+ mSynchronousMode = enabled;
+ mDequeueCondition.signal();
+ }
+ return err;
+}
+
+status_t SurfaceMediaSource::connect(int api) {
+ LOGV("SurfaceMediaSource::connect");
+ Mutex::Autolock lock(mMutex);
+ status_t err = NO_ERROR;
+ switch (api) {
+ case NATIVE_WINDOW_API_EGL:
+ case NATIVE_WINDOW_API_CPU:
+ case NATIVE_WINDOW_API_MEDIA:
+ case NATIVE_WINDOW_API_CAMERA:
+ if (mConnectedApi != NO_CONNECTED_API) {
+ err = -EINVAL;
+ } else {
+ mConnectedApi = api;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
+status_t SurfaceMediaSource::disconnect(int api) {
+ LOGV("SurfaceMediaSource::disconnect");
+ Mutex::Autolock lock(mMutex);
+ status_t err = NO_ERROR;
+ switch (api) {
+ case NATIVE_WINDOW_API_EGL:
+ case NATIVE_WINDOW_API_CPU:
+ case NATIVE_WINDOW_API_MEDIA:
+ case NATIVE_WINDOW_API_CAMERA:
+ if (mConnectedApi == api) {
+ mConnectedApi = NO_CONNECTED_API;
+ } else {
+ err = -EINVAL;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
+status_t SurfaceMediaSource::queueBuffer(int buf, int64_t timestamp,
+ uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
+ LOGV("queueBuffer");
+
+ Mutex::Autolock lock(mMutex);
+ if (buf < 0 || buf >= mBufferCount) {
+ LOGE("queueBuffer: slot index out of range [0, %d]: %d",
+ mBufferCount, buf);
+ return -EINVAL;
+ } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
+ LOGE("queueBuffer: slot %d is not owned by the client (state=%d)",
+ buf, mSlots[buf].mBufferState);
+ return -EINVAL;
+ } else if (!mSlots[buf].mRequestBufferCalled) {
+ LOGE("queueBuffer: slot %d was enqueued without requesting a "
+ "buffer", buf);
+ return -EINVAL;
+ }
+
+ if (mSynchronousMode) {
+ // in synchronous mode we queue all buffers in a FIFO
+ mQueue.push_back(buf);
+ LOGV("Client queued buffer on slot: %d, Q size = %d",
+ buf, mQueue.size());
+ } else {
+ // in asynchronous mode we only keep the most recent buffer
+ if (mQueue.empty()) {
+ mQueue.push_back(buf);
+ } else {
+ Fifo::iterator front(mQueue.begin());
+ // buffer currently queued is freed
+ mSlots[*front].mBufferState = BufferSlot::FREE;
+ // and we record the new buffer index in the queued list
+ *front = buf;
+ }
+ }
+
+ mSlots[buf].mBufferState = BufferSlot::QUEUED;
+ mSlots[buf].mTimestamp = timestamp;
+ // TODO: (Confirm) Don't want to signal dequeue here.
+ // May be just in asynchronous mode?
+ // mDequeueCondition.signal();
+
+ // Once the queuing is done, we need to let the listener
+ // and signal the buffer consumer (encoder) know that a
+ // buffer is available
+ onFrameReceivedLocked();
+
+ *outWidth = mDefaultWidth;
+ *outHeight = mDefaultHeight;
+ *outTransform = 0;
+
+ return OK;
+}
+
+
+// onFrameReceivedLocked informs the buffer consumers (StageFrightRecorder)
+// or listeners that a frame has been received
+// It is supposed to be called only from queuebuffer.
+// The buffer is NOT made available for dequeueing immediately. We need to
+// wait to hear from StageFrightRecorder to set the buffer FREE
+// Make sure this is called when the mutex is locked
+status_t SurfaceMediaSource::onFrameReceivedLocked() {
+ LOGV("On Frame Received");
+ // Signal the encoder that a new frame has arrived
+ mFrameAvailableCondition.signal();
+
+ // call back the listener
+ // TODO: The listener may not be needed in SurfaceMediaSource at all.
+ // This can be made a SurfaceTexture specific thing
+ sp<FrameAvailableListener> listener;
+ if (mSynchronousMode || mQueue.empty()) {
+ listener = mFrameAvailableListener;
+ }
+
+ if (listener != 0) {
+ listener->onFrameAvailable();
+ }
+ return OK;
+}
+
+
+void SurfaceMediaSource::cancelBuffer(int buf) {
+ LOGV("SurfaceMediaSource::cancelBuffer");
+ Mutex::Autolock lock(mMutex);
+ if (buf < 0 || buf >= mBufferCount) {
+ LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
+ mBufferCount, buf);
+ return;
+ } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
+ LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
+ buf, mSlots[buf].mBufferState);
+ return;
+ }
+ mSlots[buf].mBufferState = BufferSlot::FREE;
+ mDequeueCondition.signal();
+}
+
+nsecs_t SurfaceMediaSource::getTimestamp() {
+ LOGV("SurfaceMediaSource::getTimestamp");
+ Mutex::Autolock lock(mMutex);
+ return mCurrentTimestamp;
+}
+
+
+void SurfaceMediaSource::setFrameAvailableListener(
+ const sp<FrameAvailableListener>& listener) {
+ LOGV("SurfaceMediaSource::setFrameAvailableListener");
+ Mutex::Autolock lock(mMutex);
+ mFrameAvailableListener = listener;
+}
+
+void SurfaceMediaSource::freeAllBuffers() {
+ LOGV("freeAllBuffers");
+ for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
+ mSlots[i].mGraphicBuffer = 0;
+ mSlots[i].mBufferState = BufferSlot::FREE;
+ }
+}
+
+sp<GraphicBuffer> SurfaceMediaSource::getCurrentBuffer() const {
+ Mutex::Autolock lock(mMutex);
+ return mCurrentBuf;
+}
+
+int SurfaceMediaSource::query(int what, int* outValue)
+{
+ LOGV("query");
+ Mutex::Autolock lock(mMutex);
+ int value;
+ switch (what) {
+ case NATIVE_WINDOW_WIDTH:
+ value = mDefaultWidth;
+ if (!mDefaultWidth && !mDefaultHeight && mCurrentBuf != 0)
+ value = mCurrentBuf->width;
+ break;
+ case NATIVE_WINDOW_HEIGHT:
+ value = mDefaultHeight;
+ if (!mDefaultWidth && !mDefaultHeight && mCurrentBuf != 0)
+ value = mCurrentBuf->height;
+ break;
+ case NATIVE_WINDOW_FORMAT:
+ value = mPixelFormat;
+ break;
+ case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
+ value = mSynchronousMode ?
+ (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS;
+ break;
+ default:
+ return BAD_VALUE;
+ }
+ outValue[0] = value;
+ return NO_ERROR;
+}
+
+void SurfaceMediaSource::dump(String8& result) const
+{
+ char buffer[1024];
+ dump(result, "", buffer, 1024);
+}
+
+void SurfaceMediaSource::dump(String8& result, const char* prefix,
+ char* buffer, size_t SIZE) const
+{
+ Mutex::Autolock _l(mMutex);
+ snprintf(buffer, SIZE,
+ "%smBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
+ "mPixelFormat=%d, \n",
+ prefix, mBufferCount, mSynchronousMode, mDefaultWidth, mDefaultHeight,
+ mPixelFormat);
+ result.append(buffer);
+
+ String8 fifo;
+ int fifoSize = 0;
+ Fifo::const_iterator i(mQueue.begin());
+ while (i != mQueue.end()) {
+ snprintf(buffer, SIZE, "%02d ", *i++);
+ fifoSize++;
+ fifo.append(buffer);
+ }
+
+ result.append(buffer);
+
+ struct {
+ const char * operator()(int state) const {
+ switch (state) {
+ case BufferSlot::DEQUEUED: return "DEQUEUED";
+ case BufferSlot::QUEUED: return "QUEUED";
+ case BufferSlot::FREE: return "FREE";
+ default: return "Unknown";
+ }
+ }
+ } stateName;
+
+ for (int i = 0; i < mBufferCount; i++) {
+ const BufferSlot& slot(mSlots[i]);
+ snprintf(buffer, SIZE,
+ "%s%s[%02d] state=%-8s, "
+ "timestamp=%lld\n",
+ prefix, (i==mCurrentSlot)?">":" ", i, stateName(slot.mBufferState),
+ slot.mTimestamp
+ );
+ result.append(buffer);
+ }
+}
+
+status_t SurfaceMediaSource::setFrameRate(int32_t fps)
+{
+ Mutex::Autolock lock(mMutex);
+ const int MAX_FRAME_RATE = 60;
+ if (fps < 0 || fps > MAX_FRAME_RATE) {
+ return BAD_VALUE;
+ }
+ mFrameRate = fps;
+ return OK;
+}
+
+bool SurfaceMediaSource::isMetaDataStoredInVideoBuffers() const {
+ LOGV("isMetaDataStoredInVideoBuffers");
+ return true;
+}
+
+int32_t SurfaceMediaSource::getFrameRate( ) const {
+ Mutex::Autolock lock(mMutex);
+ return mFrameRate;
+}
+
+status_t SurfaceMediaSource::start(MetaData *params)
+{
+ LOGV("start");
+ Mutex::Autolock lock(mMutex);
+ CHECK(!mStarted);
+ mStarted = true;
+ return OK;
+}
+
+
+status_t SurfaceMediaSource::stop()
+{
+ LOGV("Stop");
+
+ Mutex::Autolock lock(mMutex);
+ // TODO: Add waiting on mFrameCompletedCondition here?
+ mStarted = false;
+ mFrameAvailableCondition.signal();
+
+ return OK;
+}
+
+sp<MetaData> SurfaceMediaSource::getFormat()
+{
+ LOGV("getFormat");
+ Mutex::Autolock autoLock(mMutex);
+ sp<MetaData> meta = new MetaData;
+
+ meta->setInt32(kKeyWidth, mDefaultWidth);
+ meta->setInt32(kKeyHeight, mDefaultHeight);
+ // The encoder format is set as an opaque colorformat
+ // The encoder will later find out the actual colorformat
+ // from the GL Frames itself.
+ meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatAndroidOpaque);
+ meta->setInt32(kKeyStride, mDefaultWidth);
+ meta->setInt32(kKeySliceHeight, mDefaultHeight);
+ meta->setInt32(kKeyFrameRate, mFrameRate);
+ meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
+ return meta;
+}
+
+status_t SurfaceMediaSource::read( MediaBuffer **buffer,
+ const ReadOptions *options)
+{
+ LOGV("Read. Size of queued buffer: %d", mQueue.size());
+ *buffer = NULL;
+
+ Mutex::Autolock autoLock(mMutex) ;
+ // If the recording has started and the queue is empty, then just
+ // wait here till the frames come in from the client side
+ while (mStarted && mQueue.empty()) {
+ LOGV("NO FRAMES! Recorder waiting for FrameAvailableCondition");
+ mFrameAvailableCondition.wait(mMutex);
+ }
+
+ // If the loop was exited as a result of stopping the recording,
+ // it is OK
+ if (!mStarted) {
+ return OK;
+ }
+
+ // Update the current buffer info
+ // TODO: mCurrentSlot can be made a bufferstate since there
+ // can be more than one "current" slots.
+ Fifo::iterator front(mQueue.begin());
+ mCurrentSlot = *front;
+ mCurrentBuf = mSlots[mCurrentSlot].mGraphicBuffer;
+ mCurrentTimestamp = mSlots[mCurrentSlot].mTimestamp;
+
+ // Pass the data to the MediaBuffer
+ // TODO: Change later to pass in only the metadata
+ *buffer = new MediaBuffer(mCurrentBuf);
+ (*buffer)->setObserver(this);
+ (*buffer)->add_ref();
+ (*buffer)->meta_data()->setInt64(kKeyTime, mCurrentTimestamp);
+
+ return OK;
+}
+
+void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
+ LOGV("signalBufferReturned");
+
+ bool foundBuffer = false;
+ Mutex::Autolock autoLock(mMutex);
+
+ if (!mStarted) {
+ LOGV("started = false. Nothing to do");
+ return;
+ }
+
+ for (Fifo::iterator it = mQueue.begin(); it != mQueue.end(); ++it) {
+ if (mSlots[*it].mGraphicBuffer == buffer->graphicBuffer()) {
+ LOGV("Buffer %d returned. Setting it 'FREE'. New Queue size = %d",
+ *it, mQueue.size()-1);
+ mSlots[*it].mBufferState = BufferSlot::FREE;
+ mQueue.erase(it);
+ buffer->setObserver(0);
+ buffer->release();
+ mDequeueCondition.signal();
+ mFrameCompleteCondition.signal();
+ foundBuffer = true;
+ break;
+ }
+ }
+
+ if (!foundBuffer) {
+ CHECK_EQ(0, "signalBufferReturned: bogus buffer");
+ }
+}
+
+
+
+} // end of namespace android
diff --git a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
index 588a74d99242..07a9eb892c5d 100644
--- a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
+++ b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
@@ -25,6 +25,8 @@
#include "support.h"
+#include <cutils/properties.h> // for property_get
+
namespace android {
ChromiumHTTPDataSource::ChromiumHTTPDataSource(uint32_t flags)
@@ -111,7 +113,7 @@ void ChromiumHTTPDataSource::onConnectionFailed(status_t err) {
mState = DISCONNECTED;
mCondition.broadcast();
- mURI.clear();
+ // mURI.clear();
mIOResult = err;
@@ -150,8 +152,18 @@ ssize_t ChromiumHTTPDataSource::readAt(off64_t offset, void *data, size_t size)
Mutex::Autolock autoLock(mLock);
if (mState != CONNECTED) {
- return ERROR_NOT_CONNECTED;
+ return INVALID_OPERATION;
+ }
+
+#if 0
+ char value[PROPERTY_VALUE_MAX];
+ if (property_get("media.stagefright.disable-net", value, 0)
+ && (!strcasecmp(value, "true") || !strcmp(value, "1"))) {
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "Simulating that the network is down.");
+ disconnect_l();
+ return ERROR_IO;
}
+#endif
if (offset != mCurrentOffset) {
AString tmp = mURI;
@@ -236,7 +248,7 @@ void ChromiumHTTPDataSource::onDisconnectComplete() {
CHECK_EQ((int)mState, (int)DISCONNECTING);
mState = DISCONNECTED;
- mURI.clear();
+ // mURI.clear();
mCondition.broadcast();
@@ -299,5 +311,21 @@ void ChromiumHTTPDataSource::clearDRMState_l() {
}
}
+status_t ChromiumHTTPDataSource::reconnectAtOffset(off64_t offset) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mURI.empty()) {
+ return INVALID_OPERATION;
+ }
+
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "Reconnecting...");
+ status_t err = connect_l(mURI.c_str(), &mHeaders, offset);
+ if (err != OK) {
+ LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "Reconnect failed w/ err 0x%08x", err);
+ }
+
+ return err;
+}
+
} // namespace android
diff --git a/media/libstagefright/include/ChromiumHTTPDataSource.h b/media/libstagefright/include/ChromiumHTTPDataSource.h
index d833e2efc1ba..18f89130c747 100644
--- a/media/libstagefright/include/ChromiumHTTPDataSource.h
+++ b/media/libstagefright/include/ChromiumHTTPDataSource.h
@@ -51,6 +51,8 @@ struct ChromiumHTTPDataSource : public HTTPBase {
virtual String8 getMIMEType() const;
+ virtual status_t reconnectAtOffset(off64_t offset);
+
protected:
virtual ~ChromiumHTTPDataSource();
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index 2d6cb848292a..22b2855204e9 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -77,6 +77,10 @@ private:
kWhatRead = 'read',
};
+ enum {
+ kMaxNumRetries = 10,
+ };
+
sp<DataSource> mSource;
sp<AHandlerReflector<NuCachedSource2> > mReflector;
sp<ALooper> mLooper;
@@ -93,6 +97,8 @@ private:
bool mFetching;
int64_t mLastFetchTimeUs;
+ int32_t mNumRetriesLeft;
+
void onMessageReceived(const sp<AMessage> &msg);
void onFetch();
void onRead(const sp<AMessage> &msg);
diff --git a/media/libstagefright/tests/Android.mk b/media/libstagefright/tests/Android.mk
new file mode 100644
index 000000000000..3ea8f39ba699
--- /dev/null
+++ b/media/libstagefright/tests/Android.mk
@@ -0,0 +1,53 @@
+# Build the unit tests.
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_MODULE := SurfaceMediaSource_test
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := \
+ SurfaceMediaSource_test.cpp \
+ DummyRecorder.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ libEGL \
+ libGLESv2 \
+ libandroid \
+ libbinder \
+ libcutils \
+ libgui \
+ libstlport \
+ libui \
+ libutils \
+ libstagefright \
+ libstagefright_omx \
+ libstagefright_foundation \
+
+LOCAL_STATIC_LIBRARIES := \
+ libgtest \
+ libgtest_main \
+
+LOCAL_C_INCLUDES := \
+ bionic \
+ bionic/libstdc++/include \
+ external/gtest/include \
+ external/stlport/stlport \
+ frameworks/base/media/libstagefright \
+ frameworks/base/media/libstagefright/include \
+ $(TOP)/frameworks/base/include/media/stagefright/openmax \
+
+include $(BUILD_EXECUTABLE)
+
+endif
+
+# Include subdirectory makefiles
+# ============================================================
+
+# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
+# team really wants is to build the stuff defined by this makefile.
+ifeq (,$(ONE_SHOT_MAKEFILE))
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/media/libstagefright/tests/DummyRecorder.cpp b/media/libstagefright/tests/DummyRecorder.cpp
new file mode 100644
index 000000000000..8d75d6bc86ae
--- /dev/null
+++ b/media/libstagefright/tests/DummyRecorder.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "DummyRecorder"
+// #define LOG_NDEBUG 0
+
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaSource.h>
+#include "DummyRecorder.h"
+
+#include <utils/Log.h>
+
+namespace android {
+
+// static
+void *DummyRecorder::threadWrapper(void *pthis) {
+ LOGV("ThreadWrapper: %p", pthis);
+ DummyRecorder *writer = static_cast<DummyRecorder *>(pthis);
+ writer->readFromSource();
+ return NULL;
+}
+
+
+status_t DummyRecorder::start() {
+ LOGV("Start");
+ mStarted = true;
+
+ mSource->start();
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+ int err = pthread_create(&mThread, &attr, threadWrapper, this);
+ pthread_attr_destroy(&attr);
+
+ if (err) {
+ LOGE("Error creating thread!");
+ return -ENODEV;
+ }
+ return OK;
+}
+
+
+status_t DummyRecorder::stop() {
+ LOGV("Stop");
+ mStarted = false;
+
+ mSource->stop();
+ void *dummy;
+ pthread_join(mThread, &dummy);
+ status_t err = (status_t) dummy;
+
+ LOGV("Ending the reading thread");
+ return err;
+}
+
+// pretend to read the source buffers
+void DummyRecorder::readFromSource() {
+ LOGV("ReadFromSource");
+ if (!mStarted) {
+ return;
+ }
+
+ status_t err = OK;
+ MediaBuffer *buffer;
+ LOGV("A fake writer accessing the frames");
+ while (mStarted && (err = mSource->read(&buffer)) == OK){
+ // if not getting a valid buffer from source, then exit
+ if (buffer == NULL) {
+ return;
+ }
+ buffer->release();
+ buffer = NULL;
+ }
+}
+
+
+} // end of namespace android
diff --git a/media/libstagefright/tests/DummyRecorder.h b/media/libstagefright/tests/DummyRecorder.h
new file mode 100644
index 000000000000..1cbea1b0dea2
--- /dev/null
+++ b/media/libstagefright/tests/DummyRecorder.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DUMMY_RECORDER_H_
+#define DUMMY_RECORDER_H_
+
+#include <pthread.h>
+#include <utils/String8.h>
+#include <media/stagefright/foundation/ABase.h>
+
+
+namespace android {
+
+class MediaSource;
+class MediaBuffer;
+
+class DummyRecorder {
+ public:
+ // The media source from which this will receive frames
+ sp<MediaSource> mSource;
+ bool mStarted;
+ pthread_t mThread;
+
+ status_t start();
+ status_t stop();
+
+ // actual entry point for the thread
+ void readFromSource();
+
+ // static function to wrap the actual thread entry point
+ static void *threadWrapper(void *pthis);
+
+ DummyRecorder(const sp<MediaSource> &source) : mSource(source)
+ , mStarted(false) {}
+ ~DummyRecorder( ) {}
+
+ private:
+
+ DISALLOW_EVIL_CONSTRUCTORS(DummyRecorder);
+};
+
+} // end of namespace android
+#endif
+
+
diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
new file mode 100644
index 000000000000..ce108122b8f7
--- /dev/null
+++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SurfaceMediaSource_test"
+// #define LOG_NDEBUG 0
+
+#include <gtest/gtest.h>
+#include <utils/String8.h>
+#include <utils/Errors.h>
+
+#include <media/stagefright/SurfaceMediaSource.h>
+
+#include <gui/SurfaceTextureClient.h>
+#include <ui/GraphicBuffer.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+
+#include <binder/ProcessState.h>
+#include <ui/FramebufferNativeWindow.h>
+
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MPEG4Writer.h>
+#include <media/stagefright/OMXClient.h>
+#include <media/stagefright/OMXCodec.h>
+#include <OMX_Component.h>
+
+#include "DummyRecorder.h"
+
+namespace android {
+
+
+class SurfaceMediaSourceTest : public ::testing::Test {
+public:
+
+ SurfaceMediaSourceTest( ): mYuvTexWidth(64), mYuvTexHeight(66) { }
+ sp<MPEG4Writer> setUpWriter(OMXClient &client );
+ void oneBufferPass(int width, int height );
+ static void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) ;
+ static void fillYV12BufferRect(uint8_t* buf, int w, int h,
+ int stride, const android_native_rect_t& rect) ;
+protected:
+
+ virtual void SetUp() {
+ mSMS = new SurfaceMediaSource(mYuvTexWidth, mYuvTexHeight);
+ mSMS->setSynchronousMode(true);
+ mSTC = new SurfaceTextureClient(mSMS);
+ mANW = mSTC;
+
+ }
+
+
+ virtual void TearDown() {
+ mSMS.clear();
+ mSTC.clear();
+ mANW.clear();
+ }
+
+ const int mYuvTexWidth;// = 64;
+ const int mYuvTexHeight;// = 66;
+
+ sp<SurfaceMediaSource> mSMS;
+ sp<SurfaceTextureClient> mSTC;
+ sp<ANativeWindow> mANW;
+
+};
+
+void SurfaceMediaSourceTest::oneBufferPass(int width, int height ) {
+ LOGV("One Buffer Pass");
+ ANativeWindowBuffer* anb;
+ ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+ ASSERT_TRUE(anb != NULL);
+
+ sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
+ ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer()));
+
+ // Fill the buffer with the a checkerboard pattern
+ uint8_t* img = NULL;
+ buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
+ SurfaceMediaSourceTest::fillYV12Buffer(img, width, height, buf->getStride());
+ buf->unlock();
+
+ ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer()));
+}
+
+sp<MPEG4Writer> SurfaceMediaSourceTest::setUpWriter(OMXClient &client ) {
+ // Writing to a file
+ const char *fileName = "/sdcard/outputSurfEnc.mp4";
+ sp<MetaData> enc_meta = new MetaData;
+ enc_meta->setInt32(kKeyBitRate, 300000);
+ enc_meta->setInt32(kKeyFrameRate, 30);
+
+ enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
+
+ sp<MetaData> meta = mSMS->getFormat();
+
+ int32_t width, height, stride, sliceHeight, colorFormat;
+ CHECK(meta->findInt32(kKeyWidth, &width));
+ CHECK(meta->findInt32(kKeyHeight, &height));
+ CHECK(meta->findInt32(kKeyStride, &stride));
+ CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight));
+ CHECK(meta->findInt32(kKeyColorFormat, &colorFormat));
+
+ enc_meta->setInt32(kKeyWidth, width);
+ enc_meta->setInt32(kKeyHeight, height);
+ enc_meta->setInt32(kKeyIFramesInterval, 1);
+ enc_meta->setInt32(kKeyStride, stride);
+ enc_meta->setInt32(kKeySliceHeight, sliceHeight);
+ // TODO: overwriting the colorformat since the format set by GRAlloc
+ // could be wrong or not be read by OMX
+ enc_meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
+ // colorFormat);
+
+
+ sp<MediaSource> encoder =
+ OMXCodec::Create(
+ client.interface(), enc_meta, true /* createEncoder */, mSMS);
+
+ sp<MPEG4Writer> writer = new MPEG4Writer(fileName);
+ writer->addSource(encoder);
+
+ return writer;
+}
+
+// Fill a YV12 buffer with a multi-colored checkerboard pattern
+void SurfaceMediaSourceTest::fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
+ const int blockWidth = w > 16 ? w / 16 : 1;
+ const int blockHeight = h > 16 ? h / 16 : 1;
+ const int yuvTexOffsetY = 0;
+ int yuvTexStrideY = stride;
+ int yuvTexOffsetV = yuvTexStrideY * h;
+ int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+ int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
+ int yuvTexStrideU = yuvTexStrideV;
+ for (int x = 0; x < w; x++) {
+ for (int y = 0; y < h; y++) {
+ int parityX = (x / blockWidth) & 1;
+ int parityY = (y / blockHeight) & 1;
+ unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
+ buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
+ if (x < w / 2 && y < h / 2) {
+ buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
+ if (x * 2 < w / 2 && y * 2 < h / 2) {
+ buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
+ buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
+ buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
+ buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
+ intensity;
+ }
+ }
+ }
+ }
+}
+
+// Fill a YV12 buffer with red outside a given rectangle and green inside it.
+void SurfaceMediaSourceTest::fillYV12BufferRect(uint8_t* buf, int w,
+ int h, int stride, const android_native_rect_t& rect) {
+ const int yuvTexOffsetY = 0;
+ int yuvTexStrideY = stride;
+ int yuvTexOffsetV = yuvTexStrideY * h;
+ int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
+ int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
+ int yuvTexStrideU = yuvTexStrideV;
+ for (int x = 0; x < w; x++) {
+ for (int y = 0; y < h; y++) {
+ bool inside = rect.left <= x && x < rect.right &&
+ rect.top <= y && y < rect.bottom;
+ buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
+ if (x < w / 2 && y < h / 2) {
+ bool inside = rect.left <= 2*x && 2*x < rect.right &&
+ rect.top <= 2*y && 2*y < rect.bottom;
+ buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
+ buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
+ inside ? 16 : 255;
+ }
+ }
+ }
+} ///////// End of class SurfaceMediaSourceTest
+
+///////////////////////////////////////////////////////////////////
+// Class to imitate the recording /////////////////////////////
+// ////////////////////////////////////////////////////////////////
+struct SimpleDummyRecorder {
+ sp<MediaSource> mSource;
+
+ SimpleDummyRecorder
+ (const sp<MediaSource> &source): mSource(source) {}
+
+ status_t start() { return mSource->start();}
+ status_t stop() { return mSource->stop();}
+
+ // fakes reading from a media source
+ status_t readFromSource() {
+ MediaBuffer *buffer;
+ status_t err = mSource->read(&buffer);
+ if (err != OK) {
+ return err;
+ }
+ buffer->release();
+ buffer = NULL;
+ return OK;
+ }
+};
+
+///////////////////////////////////////////////////////////////////
+// TESTS
+// Just pass one buffer from the native_window to the SurfaceMediaSource
+TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotOneBufferPass) {
+ LOGV("Testing OneBufferPass ******************************");
+
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+ 0, 0, HAL_PIXEL_FORMAT_YV12));
+ // OMX_COLOR_FormatYUV420Planar)); // ));
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+ oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+}
+
+// Pass the buffer with the wrong height and weight and should not be accepted
+TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotWrongSizeBufferPass) {
+ LOGV("Testing Wrong size BufferPass ******************************");
+
+ // setting the client side buffer size different than the server size
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+ 10, 10, HAL_PIXEL_FORMAT_YV12));
+ // OMX_COLOR_FormatYUV420Planar)); // ));
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+ ANativeWindowBuffer* anb;
+
+ // make sure we get an error back when dequeuing!
+ ASSERT_NE(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb));
+}
+
+
+// pass multiple buffers from the native_window the SurfaceMediaSource
+// A dummy writer is used to simulate actual MPEG4Writer
+TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPass) {
+ LOGV("Testing MultiBufferPass, Dummy Recorder *********************");
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+ 0, 0, HAL_PIXEL_FORMAT_YV12));
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+ SimpleDummyRecorder writer(mSMS);
+ writer.start();
+
+ int32_t nFramesCount = 0;
+ while (nFramesCount < 300) {
+ oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+
+ ASSERT_EQ(NO_ERROR, writer.readFromSource());
+
+ nFramesCount++;
+ }
+ writer.stop();
+}
+
+// Delayed pass of multiple buffers from the native_window the SurfaceMediaSource
+// A dummy writer is used to simulate actual MPEG4Writer
+TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPassLag) {
+ LOGV("Testing MultiBufferPass, Dummy Recorder Lagging **************");
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+ 0, 0, HAL_PIXEL_FORMAT_YV12));
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+ SimpleDummyRecorder writer(mSMS);
+ writer.start();
+
+ int32_t nFramesCount = 1;
+ const int FRAMES_LAG = mSMS->getBufferCount() - 1;
+ while (nFramesCount <= 300) {
+ oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+ // Forcing the writer to lag behind a few frames
+ if (nFramesCount > FRAMES_LAG) {
+ ASSERT_EQ(NO_ERROR, writer.readFromSource());
+ }
+ nFramesCount++;
+ }
+ writer.stop();
+}
+
+// pass multiple buffers from the native_window the SurfaceMediaSource
+// A dummy writer (MULTITHREADED) is used to simulate actual MPEG4Writer
+TEST_F(SurfaceMediaSourceTest, EncodingFromCpuFilledYV12BufferNpotMultiBufferPassThreaded) {
+ LOGV("Testing MultiBufferPass, Dummy Recorder Multi-Threaded **********");
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+ 0, 0, HAL_PIXEL_FORMAT_YV12));
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+ DummyRecorder writer(mSMS);
+ writer.start();
+
+ int32_t nFramesCount = 0;
+ while (nFramesCount <= 300) {
+ oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+
+ nFramesCount++;
+ }
+ writer.stop();
+}
+
+// Test to examine the actual encoding. Temporarily disabled till the
+// colorformat and encoding from GRAlloc data is resolved
+TEST_F(SurfaceMediaSourceTest, DISABLED_EncodingFromCpuFilledYV12BufferNpotWrite) {
+ LOGV("Testing the whole pipeline with actual Recorder");
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
+ 0, 0, HAL_PIXEL_FORMAT_YV12)); // OMX_COLOR_FormatYUV420Planar)); // ));
+ ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+ OMXClient client;
+ CHECK_EQ(OK, client.connect());
+
+ sp<MPEG4Writer> writer = setUpWriter(client);
+ int64_t start = systemTime();
+ CHECK_EQ(OK, writer->start());
+
+ int32_t nFramesCount = 0;
+ while (nFramesCount <= 300) {
+ oneBufferPass(mYuvTexWidth, mYuvTexHeight);
+ nFramesCount++;
+ }
+
+ CHECK_EQ(OK, writer->stop());
+ writer.clear();
+ int64_t end = systemTime();
+ client.disconnect();
+}
+
+
+} // namespace android
diff --git a/packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml b/packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml
index d29e4959b93d..a354336e4a2c 100644
--- a/packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml
+++ b/packages/SystemUI/res/layout-sw600dp/compat_mode_help.xml
@@ -43,6 +43,7 @@
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/compat_mode_help_diagram"
+ android:contentDescription="@string/accessibility_compatibility_zoom_example"
/>
<RelativeLayout
android:orientation="horizontal"
@@ -61,6 +62,7 @@
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/compat_mode_help_icon"
+ android:contentDescription="@string/accessibility_compatibility_zoom_button"
/>
<TextView
android:id="@+id/explanation"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar.xml b/packages/SystemUI/res/layout-sw600dp/status_bar.xml
index d9f3f2324499..a2a64738d029 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar.xml
@@ -49,6 +49,7 @@
android:src="@drawable/ic_sysbar_back"
android:layout_alignParentLeft="true"
systemui:keyCode="4"
+ android:contentDescription="@string/accessibility_back"
/>
<LinearLayout
android:id="@+id/navigationArea"
@@ -62,11 +63,13 @@
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_home"
systemui:keyCode="3"
+ android:contentDescription="@string/accessibility_home"
/>
<ImageView android:id="@+id/recent_apps"
android:layout_width="80dip"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_recent"
+ android:contentDescription="@string/accessibility_menu"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
android:layout_width="80dip"
@@ -74,6 +77,7 @@
android:src="@drawable/ic_sysbar_menu"
systemui:keyCode="82"
android:visibility="invisible"
+ android:contentDescription="@string/accessibility_menu"
/>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_item.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_item.xml
index 3fef7e078cac..41a20fb039c9 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_item.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_input_methods_item.xml
@@ -53,7 +53,8 @@
android:id="@+id/item_icon"
android:layout_width="@android:dimen/app_icon_size"
android:layout_height="wrap_content"
- android:scaleType="fitCenter" />
+ android:scaleType="fitCenter"
+ android:contentDescription="@null" />
<LinearLayout
android:orientation="vertical"
android:layout_width="0px"
@@ -94,7 +95,8 @@
android:visibility="visible"
android:clickable="true"
android:focusable="true"
- android:background="?android:attr/selectableItemBackground" />
+ android:background="?android:attr/selectableItemBackground"
+ android:contentDescription="@string/accessibility_settings_button" />
</LinearLayout>
<View
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml
index fecfe7f1ae1b..1e3099dc3571 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml
@@ -16,7 +16,7 @@
-->
<!-- notification icons & panel access -->
-<LinearLayout
+<com.android.systemui.statusbar.tablet.NotificationArea
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
android:id="@+id/notificationArea"
@@ -40,6 +40,7 @@
android:layout_marginLeft="8dip"
android:src="@drawable/ic_sysbar_ime_default"
android:visibility="gone"
+ android:contentDescription="@string/accessibility_ime_switch_button"
/>
<com.android.systemui.statusbar.policy.CompatModeButton
@@ -49,6 +50,7 @@
android:layout_marginLeft="8dip"
android:src="@drawable/ic_sysbar_zoom"
android:visibility="gone"
+ android:contentDescription="@string/accessibility_compatibility_zoom_button"
/>
<com.android.systemui.statusbar.tablet.NotificationIconArea
@@ -152,4 +154,4 @@
/>
</LinearLayout>
</LinearLayout>
-</LinearLayout>
+</com.android.systemui.statusbar.tablet.NotificationArea>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
index 543f4eda576a..bbb2bc65dfbb 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
@@ -14,15 +14,17 @@
limitations under the License.
-->
-<RelativeLayout
+<com.android.systemui.statusbar.tablet.NotificationPanelTitle
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
android:id="@+id/title_area"
- android:layout_width="0dp"
- android:layout_height="0dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clickable="true"
android:orientation="vertical"
android:background="@drawable/notify_panel_clock_bg"
>
+
<LinearLayout
android:id="@+id/icons"
android:layout_width="wrap_content"
@@ -34,6 +36,7 @@
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
>
+
<ImageView
android:id="@+id/bluetooth"
android:layout_height="32dp"
@@ -41,6 +44,7 @@
android:scaleType="centerInside"
android:baseline="22dp"
android:visibility="gone"
+ android:contentDescription="@null"
/>
<FrameLayout
@@ -49,21 +53,28 @@
android:layout_width="32dp"
android:layout_marginRight="4dp"
>
+
<ImageView
android:id="@+id/network_signal"
android:layout_height="match_parent"
android:layout_width="match_parent"
+ android:contentDescription="@null"
/>
+
<ImageView
android:id="@+id/network_type"
android:layout_height="match_parent"
android:layout_width="match_parent"
+ android:contentDescription="@null"
/>
+
<ImageView
android:id="@+id/network_direction"
android:layout_height="match_parent"
android:layout_width="match_parent"
+ android:contentDescription="@null"
/>
+
</FrameLayout>
<TextView
@@ -86,6 +97,7 @@
android:layout_toRightOf="@id/network_text"
android:layout_alignBaseline="@id/network_signal"
android:baseline="22dp"
+ android:contentDescription="@null"
/>
<TextView
@@ -110,6 +122,7 @@
android:paddingRight="16dp"
android:src="@drawable/ic_sysbar_quicksettings"
android:baseline="21dp"
+ android:contentDescription="@string/accessibility_settings_button"
/>
<ImageView
@@ -122,6 +135,7 @@
android:src="@drawable/ic_notification_open"
android:baseline="21dp"
android:visibility="invisible"
+ android:contentDescription="@string/accessibility_notifications_button"
/>
<View
@@ -138,7 +152,7 @@
<com.android.systemui.statusbar.tablet.HoloClock
android:id="@+id/clock"
android:layout_height="wrap_content"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:layout_above="@id/title_divider"
android:layout_marginRight="6dip"
@@ -164,19 +178,11 @@
android:id="@+id/date"
style="@style/StatusBarNotificationText"
android:layout_height="wrap_content"
- android:layout_width="120dp"
+ android:layout_width="wrap_content"
android:layout_alignBottom="@id/clock"
android:layout_alignParentLeft="true"
android:gravity="left"
android:layout_marginLeft="32dp"
/>
- <view
- class="com.android.systemui.statusbar.tablet.NotificationPanel$ModeToggle"
- android:id="@+id/mode_toggle"
- android:background="@null"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clickable="true"
- />
-</RelativeLayout>
+</com.android.systemui.statusbar.tablet.NotificationPanelTitle>
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index 51e7d97ef1ec..5d7e8de463d4 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -54,6 +54,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
+ android:contentDescription="@string/accessibility_back"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
android:layout_width="80dp"
@@ -66,6 +67,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
+ android:contentDescription="@string/accessibility_home"
/>
<ImageView android:id="@+id/recent_apps"
android:layout_width="80dp"
@@ -80,6 +82,7 @@
systemui:keyCode="82"
android:layout_weight="0"
android:visibility="invisible"
+ android:contentDescription="@string/accessibility_menu"
/>
</LinearLayout>
@@ -124,6 +127,7 @@
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="1"
+ android:contentDescription="@string/accessibility_menu"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
android:layout_height="80dp"
@@ -131,11 +135,13 @@
android:src="@drawable/ic_sysbar_home_default_land"
systemui:keyCode="3"
android:layout_weight="0"
+ android:contentDescription="@string/accessibility_home"
/>
<View
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="1"
+ android:contentDescription="@string/accessibility_back"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
android:layout_height="80dp"
@@ -148,6 +154,7 @@
android:layout_height="40dp"
android:layout_width="match_parent"
android:layout_weight="0"
+ android:contentDescription="@string/accessibility_menu"
/>
</LinearLayout>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 5298f2e66927..d7d7817fc15b 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -34,7 +34,7 @@
<string name="config_systemBarComponent" translatable="false">com.android.systemui.statusbar.tablet.TabletStatusBar</string>
<!-- Whether or not we show the number in the bar. -->
- <bool name="config_statusBarShowNumber">true</bool>
+ <bool name="config_statusBarShowNumber">false</bool>
<!-- How many icons may be shown at once in the system bar. Includes any
slots that may be reused for things like IME control. -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 01cf2dcf4a6f..082dab312aeb 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -169,4 +169,135 @@
<string name="screenshot_saving_toast">Screenshot saved to Gallery</string>
<!-- toast message displayed when we fail to take a screenshot. -->
<string name="screenshot_failed_toast">Could not save screenshot</string>
+
+ <!-- Title for the USB function chooser in UsbPreferenceActivity. [CHAR LIMIT=30] -->
+ <string name="usb_preference_title">USB file transfer options</string>
+ <!-- Label for the MTP USB function in UsbPreferenceActivity. [CHAR LIMIT=50] -->
+ <string name="use_mtp_button_title">Mount as a media player (MTP)</string>
+ <!-- Label for the PTP USB function in UsbPreferenceActivity. [CHAR LIMIT=50] -->
+ <string name="use_ptp_button_title">Mount as a camera (PTP)</string>
+ <!-- Label for the installer CD image option in UsbPreferenceActivity. [CHAR LIMIT=50] -->
+ <string name="installer_cd_button_title">Install Android File Transfer application for Mac</string>
+
+ <!-- Content description of the back button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_back">Back</string>
+ <!-- Content description of the home button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_home">Home</string>
+ <!-- Content description of the menu button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_menu">Menu</string>
+
+ <!-- Content description of the switch input method button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_ime_switch_button">Switch input method button.</string>
+ <!-- Content description of the compatibility zoom button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_compatibility_zoom_button">Compatibility zoom button.</string>
+
+ <!-- Content description of picture of the compatibility zoom example for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_compatibility_zoom_example">Zoom smaller to larger screen.</string>
+
+ <!-- Content description of the bluetooth icon when connected for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_bluetooth_connected">Bluetooth connected.</string>
+ <!-- Content description of the bluetooth icon when connecting for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_bluetooth_disconnected">Bluetooth disconnected.</string>
+
+ <!-- Content description of the battery when no battery for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_no_battery">No battery.</string>
+ <!-- Content description of the battery when it is one bar for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_battery_one_bar">Battery one bar.</string>
+ <!-- Content description of the battery when it is two bars for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_battery_two_bars">Battery two bars.</string>
+ <!-- Content description of the battery when it is three bars for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_battery_three_bars">Battery three bars.</string>
+ <!-- Content description of the battery when it is full for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_battery_full">Battery full.</string>
+
+ <!-- Content description of the phone signal when no signal for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_no_phone">No phone.</string>
+ <!-- Content description of the phone signal when it is one bar for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_phone_one_bar">Phone one bar.</string>
+ <!-- Content description of the phone signal when it is two bars for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_phone_two_bars">Phone two bars.</string>
+ <!-- Content description of the phone signal when it is three bars for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_phone_three_bars">Phone three bars.</string>
+ <!-- Content description of the phone signal when it is full for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_phone_signal_full">Phone signal full.</string>
+
+ <!-- Content description of the data signal when no signal for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_no_data">No data.</string>
+ <!-- Content description of the data signal when it is one bar for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_data_one_bar">Data one bar.</string>
+ <!-- Content description of the data signal when it is two bars for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_data_two_bars">Data two bars.</string>
+ <!-- Content description of the data signal when it is three bars for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_data_three_bars">Data three bars.</string>
+ <!-- Content description of the data signal when it is full for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_data_signal_full">Data signal full.</string>
+
+ <!-- Content description of the WIFI signal when no signal for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_no_wifi">No WiFi.</string>
+ <!-- Content description of the WIFI signal when it is one bar for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_wifi_one_bar">WiFi one bar.</string>
+ <!-- Content description of the WIFI signal when it is two bars for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_wifi_two_bars">WiFi two bars.</string>
+ <!-- Content description of the WIFI signal when it is three bars for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_wifi_three_bars">WiFi three bars.</string>
+ <!-- Content description of the WIFI signal when it is full for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_wifi_signal_full">WiFi signal full.</string>
+
+ <!-- Content description of the data connection type GPRS for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_data_connection_gprs">GPRS</string>
+
+ <!-- Content description of the data connection type 3G for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_data_connection_3g">3G</string>
+
+ <!-- Content description of the data connection type 3.5G for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_data_connection_3.5g">3.5G</string>
+
+ <!-- Content description of the data connection type 4G for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_data_connection_4g">4G</string>
+
+ <!-- Content description of the data connection type CDMA for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_data_connection_cdma">CDMA</string>
+
+ <!-- Content description of the data connection type Edge for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_data_connection_edge">Edge</string>
+
+ <!-- Content description of the data connection type WiFi for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_data_connection_wifi">WiFi</string>
+
+ <!-- Content description of the data connection with no SIM for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_no_sim">No SIM.</string>
+
+ <!-- Content description of the bluetooth tethering icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_bluetooth_tether">Bluetooth tethering.</string>
+
+ <!-- Content description of the airplane mode icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_airplane_mode">Airplane mode.</string>
+
+ <!-- Content description of the battery level icon for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_battery_level">Battery <xliff:g id="number">%d</xliff:g> percent.</string>
+
+ <!-- Content description of the button for showing a settings panel in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_settings_button">Settings button.</string>
+
+ <!-- Content description of the button for showing a notifications panel in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_notifications_button">Notifications button.</string>
+
+ <!-- Content description of the button for removing a notification in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_remove_notification">Remove notification.</string>
+
+ <!-- Content description of the enabled GPS icon in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_gps_enabled">GPS enabled.</string>
+
+ <!-- Content description of the acquiring GPS icon in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_gps_acquiring">GPS acquiring.</string>
+
+ <!-- Content description of the TeleTypewriter(TTY) enabled icon in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_tty_enabled">TeleTypewriter enabled.</string>
+
+ <!-- Content description of the ringer vibrate icon in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_ringer_vibrate">Ringer vibrate.</string>
+
+ <!-- Content description of the ringer silent icon in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_ringer_silent">Ringer silent.</string>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index bc0a508c06a7..ea544456430d 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -22,7 +22,6 @@ import java.util.List;
import android.animation.Animator;
import android.animation.LayoutTransition;
import android.app.ActivityManager;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -48,6 +47,7 @@ import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
@@ -112,7 +112,7 @@ public class RecentsPanelView extends RelativeLayout
position = _pos;
packageName = _packageName;
}
- };
+ }
private final class OnLongClickDelegate implements View.OnLongClickListener {
View mOtherView;
@@ -252,6 +252,19 @@ public class RecentsPanelView extends RelativeLayout
mChoreo.setPanelHeight(mRecentsContainer.getHeight());
}
+ @Override
+ public boolean dispatchHoverEvent(MotionEvent event) {
+ // Ignore hover events outside of this panel bounds since such events
+ // generate spurious accessibility events with the panel content when
+ // tapping outside of it, thus confusing the user.
+ final int x = (int) event.getX();
+ final int y = (int) event.getY();
+ if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
+ return super.dispatchHoverEvent(event);
+ }
+ return true;
+ }
+
/**
* Whether the panel is showing, or, if it's animating, whether it will be
* when the animation is done.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java b/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
index 64ec0633810c..641977756647 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LatestItemView.java
@@ -18,8 +18,8 @@ package com.android.systemui.statusbar;
import android.content.Context;
import android.util.AttributeSet;
-import android.util.Slog;
-import android.view.MotionEvent;
+import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
public class LatestItemView extends FrameLayout {
@@ -27,7 +27,22 @@ public class LatestItemView extends FrameLayout {
super(context, attrs);
}
+ @Override
public void setOnClickListener(OnClickListener l) {
super.setOnClickListener(l);
}
+
+ @Override
+ public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
+ if (super.onRequestSendAccessibilityEvent(child, event)) {
+ // Add a record for the entire layout since its content is somehow small.
+ // The event comes from a leaf view that is interacted with.
+ AccessibilityEvent record = AccessibilityEvent.obtain();
+ onInitializeAccessibilityEvent(record);
+ dispatchPopulateAccessibilityEvent(record);
+ event.appendRecord(record);
+ return true;
+ }
+ return false;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index d9d9c06061a3..be4b39539cdb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar;
+import android.app.Notification;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
@@ -23,11 +24,11 @@ import android.graphics.drawable.Drawable;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
+import android.text.TextUtils;
import android.util.Slog;
import android.util.Log;
-import android.view.View;
import android.view.ViewDebug;
-import android.widget.FrameLayout;
+import android.view.accessibility.AccessibilityEvent;
import java.text.NumberFormat;
@@ -45,8 +46,9 @@ public class StatusBarIconView extends AnimatedImageView {
private int mNumberX;
private int mNumberY;
private String mNumberText;
+ private Notification mNotification;
- public StatusBarIconView(Context context, String slot) {
+ public StatusBarIconView(Context context, String slot, Notification notification) {
super(context);
final Resources res = context.getResources();
mSlot = slot;
@@ -54,6 +56,8 @@ public class StatusBarIconView extends AnimatedImageView {
mNumberPain.setTextAlign(Paint.Align.CENTER);
mNumberPain.setColor(res.getColor(R.drawable.notification_number_text_color));
mNumberPain.setAntiAlias(true);
+ mNotification = notification;
+ setContentDescription(notification);
}
private static boolean streq(String a, String b) {
@@ -83,6 +87,7 @@ public class StatusBarIconView extends AnimatedImageView {
final boolean numberEquals = mIcon != null
&& mIcon.number == icon.number;
mIcon = icon.clone();
+ setContentDescription(icon.contentDescription);
if (!iconEquals) {
Drawable drawable = getIcon(icon);
if (drawable == null) {
@@ -159,6 +164,15 @@ public class StatusBarIconView extends AnimatedImageView {
return mIcon;
}
+ @Override
+ public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(event);
+ if (mNotification != null) {
+ event.setParcelableData(mNotification);
+ }
+ }
+
+ @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mNumberBackground != null) {
@@ -166,6 +180,7 @@ public class StatusBarIconView extends AnimatedImageView {
}
}
+ @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
@@ -175,6 +190,7 @@ public class StatusBarIconView extends AnimatedImageView {
}
}
+ @Override
protected void debug(int depth) {
super.debug(depth);
Log.d("View", debugIndent(depth) + "slot=" + mSlot);
@@ -213,4 +229,13 @@ public class StatusBarIconView extends AnimatedImageView {
mNumberY = h-r.bottom-((dh-r.top-th-r.bottom)/2);
mNumberBackground.setBounds(w-dw, h-dh, w, h);
}
+
+ private void setContentDescription(Notification notification) {
+ if (notification != null) {
+ CharSequence tickerText = notification.tickerText;
+ if (!TextUtils.isEmpty(tickerText)) {
+ setContentDescription(tickerText);
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
index e1d17a891607..f6aa159555fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
@@ -33,7 +33,8 @@ public class IconMerger extends LinearLayout {
private int mIconSize;
private StatusBarIconView mMoreView;
- private StatusBarIcon mMoreIcon = new StatusBarIcon(null, R.drawable.stat_notify_more, 0);
+ private StatusBarIcon mMoreIcon = new StatusBarIcon(null, R.drawable.stat_notify_more, 0, 0,
+ null);
public IconMerger(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -41,7 +42,7 @@ public class IconMerger extends LinearLayout {
mIconSize = context.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_icon_size);
- mMoreView = new StatusBarIconView(context, "more");
+ mMoreView = new StatusBarIconView(context, "more", null);
mMoreView.set(mMoreIcon);
addView(mMoreView, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index f4c4bbcf935e..b93ad684311b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -472,7 +472,7 @@ public class PhoneStatusBar extends StatusBar {
public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
if (SPEW) Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
+ " icon=" + icon);
- StatusBarIconView view = new StatusBarIconView(mContext, slot);
+ StatusBarIconView view = new StatusBarIconView(mContext, slot, null);
view.set(icon);
mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize));
}
@@ -607,7 +607,7 @@ public class PhoneStatusBar extends StatusBar {
// Update the icon.
final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
notification.notification.icon, notification.notification.iconLevel,
- notification.notification.number);
+ notification.notification.number, notification.notification.tickerText);
if (!oldEntry.icon.set(ic)) {
handleNotificationError(key, notification, "Couldn't update icon: " + ic);
return;
@@ -765,9 +765,11 @@ public class PhoneStatusBar extends StatusBar {
final View expanded = views[2];
// Construct the icon.
final StatusBarIconView iconView = new StatusBarIconView(mContext,
- notification.pkg + "/0x" + Integer.toHexString(notification.id));
+ notification.pkg + "/0x" + Integer.toHexString(notification.id),
+ notification.notification);
final StatusBarIcon ic = new StatusBarIcon(notification.pkg, notification.notification.icon,
- notification.notification.iconLevel, notification.notification.number);
+ notification.notification.iconLevel, notification.notification.number,
+ notification.notification.tickerText);
if (!iconView.set(ic)) {
handleNotificationError(key, notification, "Coulding create icon: " + ic);
return null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index af5c72d92cdc..7b5098534915 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -18,25 +18,17 @@ package com.android.systemui.statusbar.phone;
import android.app.StatusBarManager;
import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothPbap;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.res.TypedArray;
-import android.graphics.PixelFormat;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
import android.location.LocationManager;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
-import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Handler;
-import android.os.Message;
import android.os.RemoteException;
import android.os.storage.StorageManager;
import android.provider.Settings;
@@ -44,18 +36,7 @@ import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
-import android.text.format.DateFormat;
-import android.text.style.CharacterStyle;
-import android.text.style.RelativeSizeSpan;
-import android.text.style.ForegroundColorSpan;
-import android.text.style.StyleSpan;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
import android.util.Slog;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
import com.android.internal.app.IBatteryStats;
import com.android.internal.telephony.IccCard;
@@ -63,7 +44,6 @@ import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.cdma.EriInfo;
import com.android.internal.telephony.cdma.TtyIntent;
import com.android.server.am.BatteryStatsService;
-
import com.android.systemui.R;
/**
@@ -447,6 +427,32 @@ public class PhoneStatusBarPolicy {
R.drawable.stat_sys_data_fully_inandout_1x }
};
+ // Accessibility;
+
+ private static final int[] sPhoneSignalStrength = {
+ R.string.accessibility_no_phone,
+ R.string.accessibility_phone_one_bar,
+ R.string.accessibility_phone_two_bars,
+ R.string.accessibility_phone_three_bars,
+ R.string.accessibility_phone_signal_full
+ };
+
+ private static final int[] sDataConnectionStrength = {
+ R.string.accessibility_no_data,
+ R.string.accessibility_data_one_bar,
+ R.string.accessibility_data_two_bars,
+ R.string.accessibility_data_three_bars,
+ R.string.accessibility_data_signal_full
+ };
+
+ private static final int[] sWifiConnectionStrength = {
+ R.string.accessibility_no_wifi,
+ R.string.accessibility_wifi_one_bar,
+ R.string.accessibility_wifi_two_bars,
+ R.string.accessibility_wifi_three_bars,
+ R.string.accessibility_wifi_signal_full
+ };
+
// Assume it's all good unless we hear otherwise. We don't always seem
// to get broadcasts that it *is* there.
IccCard.State mSimState = IccCard.State.READY;
@@ -546,12 +552,13 @@ public class PhoneStatusBarPolicy {
new com.android.systemui.usb.StorageNotification(context));
// battery
- mService.setIcon("battery", com.android.internal.R.drawable.stat_sys_battery_unknown, 0);
+ mService.setIcon("battery", com.android.internal.R.drawable.stat_sys_battery_unknown, 0,
+ null);
// phone_signal
mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
- mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
+ mService.setIcon("phone_signal", mPhoneSignalIconId, 0, null);
// register for phone state notifications.
((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE))
@@ -563,24 +570,24 @@ public class PhoneStatusBarPolicy {
| PhoneStateListener.LISTEN_DATA_ACTIVITY);
// data_connection
- mService.setIcon("data_connection", R.drawable.stat_sys_data_connected_g, 0);
+ mService.setIcon("data_connection", R.drawable.stat_sys_data_connected_g, 0, null);
mService.setIconVisibility("data_connection", false);
// wifi
- mService.setIcon("wifi", sWifiSignalImages[0][0], 0);
+ mService.setIcon("wifi", sWifiSignalImages[0][0], 0, null);
mService.setIconVisibility("wifi", false);
// wifi will get updated by the sticky intents
// TTY status
- mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0);
+ mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0, null);
mService.setIconVisibility("tty", false);
// Cdma Roaming Indicator, ERI
- mService.setIcon("cdma_eri", R.drawable.stat_sys_roaming_cdma_0, 0);
+ mService.setIcon("cdma_eri", R.drawable.stat_sys_roaming_cdma_0, 0, null);
mService.setIconVisibility("cdma_eri", false);
// bluetooth status
- mService.setIcon("bluetooth", R.drawable.stat_sys_data_bluetooth, 0);
+ mService.setIcon("bluetooth", R.drawable.stat_sys_data_bluetooth, 0, null);
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
mBluetoothEnabled = adapter.isEnabled();
@@ -590,21 +597,23 @@ public class PhoneStatusBarPolicy {
mService.setIconVisibility("bluetooth", mBluetoothEnabled);
// Gps status
- mService.setIcon("gps", R.drawable.stat_sys_gps_acquiring_anim, 0);
+ mService.setIcon("gps", R.drawable.stat_sys_gps_acquiring_anim, 0, null);
mService.setIconVisibility("gps", false);
// Alarm clock
- mService.setIcon("alarm_clock", R.drawable.stat_notify_alarm, 0);
+ mService.setIcon("alarm_clock", R.drawable.stat_notify_alarm, 0, null);
mService.setIconVisibility("alarm_clock", false);
// Sync state
- mService.setIcon("sync_active", com.android.internal.R.drawable.stat_notify_sync_anim0, 0);
- mService.setIcon("sync_failing", com.android.internal.R.drawable.stat_notify_sync_error, 0);
+ mService.setIcon("sync_active", com.android.internal.R.drawable.stat_notify_sync_anim0,
+ 0, null);
+ mService.setIcon("sync_failing", com.android.internal.R.drawable.stat_notify_sync_error,
+ 0, null);
mService.setIconVisibility("sync_active", false);
mService.setIconVisibility("sync_failing", false);
// volume
- mService.setIcon("volume", R.drawable.stat_sys_ringer_silent, 0);
+ mService.setIcon("volume", R.drawable.stat_sys_ringer_silent, 0, null);
mService.setIconVisibility("volume", false);
updateVolume();
@@ -655,7 +664,8 @@ public class PhoneStatusBarPolicy {
private final void updateBattery(Intent intent) {
final int id = intent.getIntExtra("icon-small", 0);
int level = intent.getIntExtra("level", 0);
- mService.setIcon("battery", id, level);
+ String contentDescription = mContext.getString(R.string.accessibility_battery_level, level);
+ mService.setIcon("battery", id, level, contentDescription);
}
private void updateConnectivity(Intent intent) {
@@ -677,12 +687,16 @@ public class PhoneStatusBarPolicy {
if (info.isConnected()) {
mIsWifiConnected = true;
int iconId;
+ String contentDescription = null;
if (mLastWifiSignalLevel == -1) {
iconId = sWifiSignalImages[mInetCondition][0];
+ contentDescription = mContext.getString(sWifiConnectionStrength[0]);
} else {
iconId = sWifiSignalImages[mInetCondition][mLastWifiSignalLevel];
- }
- mService.setIcon("wifi", iconId, 0);
+ contentDescription = mContext.getString(
+ sWifiConnectionStrength[mLastWifiSignalLevel]);
+ }
+ mService.setIcon("wifi", iconId, 0, contentDescription);
// Show the icon since wi-fi is connected
mService.setIconVisibility("wifi", true);
} else {
@@ -690,7 +704,8 @@ public class PhoneStatusBarPolicy {
mIsWifiConnected = false;
int iconId = sWifiSignalImages[0][0];
- mService.setIcon("wifi", iconId, 0);
+ String contentDescription = mContext.getString(R.string.accessibility_no_wifi);
+ mService.setIcon("wifi", iconId, 0, contentDescription);
// Hide the icon since we're not connected
mService.setIconVisibility("wifi", false);
}
@@ -781,6 +796,7 @@ public class PhoneStatusBarPolicy {
private final void updateSignalStrength() {
int[] iconList;
+ String contentDescription = null;
// Display signal strength while in "emergency calls only" mode
if (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly())) {
@@ -788,10 +804,12 @@ public class PhoneStatusBarPolicy {
if (Settings.System.getInt(mContext.getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, 0) == 1) {
mPhoneSignalIconId = R.drawable.stat_sys_signal_flightmode;
+ contentDescription = mContext.getString(R.string.accessibility_airplane_mode);
} else {
mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
+ contentDescription = mContext.getString(R.string.accessibility_no_phone);
}
- mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
+ mService.setIcon("phone_signal", mPhoneSignalIconId, 0, contentDescription);
return;
}
@@ -805,8 +823,11 @@ public class PhoneStatusBarPolicy {
} else {
iconList = sSignalImages[mInetCondition];
}
- mPhoneSignalIconId = iconList[mSignalStrength.getLevel()];
- mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
+
+ final int signalLevel = mSignalStrength.getLevel();
+ mPhoneSignalIconId = iconList[signalLevel];
+ contentDescription = mContext.getString(sPhoneSignalStrength[signalLevel]);
+ mService.setIcon("phone_signal", mPhoneSignalIconId, 0, contentDescription);
}
private final void updateDataNetType(int net) {
@@ -850,6 +871,7 @@ public class PhoneStatusBarPolicy {
private final void updateDataIcon() {
int iconId;
+ String contentDescription = null;
boolean visible = true;
if (!isCdma()) {
@@ -870,13 +892,15 @@ public class PhoneStatusBarPolicy {
iconId = mDataIconList[0];
break;
}
- mService.setIcon("data_connection", iconId, 0);
+ contentDescription = mContext.getString(sDataConnectionStrength[mDataActivity]);
+ mService.setIcon("data_connection", iconId, 0, contentDescription);
} else {
visible = false;
}
} else {
iconId = R.drawable.stat_sys_no_sim;
- mService.setIcon("data_connection", iconId, 0);
+ contentDescription = mContext.getString(R.string.accessibility_no_sim);
+ mService.setIcon("data_connection", iconId, 0, contentDescription);
}
} else {
// CDMA case, mDataActivity can be also DATA_ACTIVITY_DORMANT
@@ -896,7 +920,7 @@ public class PhoneStatusBarPolicy {
iconId = mDataIconList[0];
break;
}
- mService.setIcon("data_connection", iconId, 0);
+ mService.setIcon("data_connection", iconId, 0, null);
} else {
visible = false;
}
@@ -921,12 +945,19 @@ public class PhoneStatusBarPolicy {
final int ringerMode = audioManager.getRingerMode();
final boolean visible = ringerMode == AudioManager.RINGER_MODE_SILENT ||
ringerMode == AudioManager.RINGER_MODE_VIBRATE;
- final int iconId = audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER)
- ? R.drawable.stat_sys_ringer_vibrate
- : R.drawable.stat_sys_ringer_silent;
+
+ final int iconId;
+ String contentDescription = null;
+ if (audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER)) {
+ iconId = R.drawable.stat_sys_ringer_vibrate;
+ contentDescription = mContext.getString(R.string.accessibility_ringer_vibrate);
+ } else {
+ iconId = R.drawable.stat_sys_ringer_silent;
+ contentDescription = mContext.getString(R.string.accessibility_ringer_silent);
+ }
if (visible) {
- mService.setIcon("volume", iconId, 0);
+ mService.setIcon("volume", iconId, 0, contentDescription);
}
if (visible != mVolumeVisible) {
mService.setIconVisibility("volume", visible);
@@ -936,6 +967,7 @@ public class PhoneStatusBarPolicy {
private final void updateBluetooth(Intent intent) {
int iconId = R.drawable.stat_sys_data_bluetooth;
+ String contentDescription = null;
String action = intent.getAction();
if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
@@ -945,12 +977,16 @@ public class PhoneStatusBarPolicy {
BluetoothAdapter.STATE_DISCONNECTED);
if (state == BluetoothAdapter.STATE_CONNECTED) {
iconId = R.drawable.stat_sys_data_bluetooth_connected;
+ contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected);
+ } else {
+ contentDescription = mContext.getString(
+ R.string.accessibility_bluetooth_disconnected);
}
} else {
return;
}
- mService.setIcon("bluetooth", iconId, 0);
+ mService.setIcon("bluetooth", iconId, 0, contentDescription);
mService.setIconVisibility("bluetooth", mBluetoothEnabled);
}
@@ -974,6 +1010,7 @@ public class PhoneStatusBarPolicy {
}
} else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
int iconId;
+ String contentDescription = null;
final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
int newSignalLevel = WifiManager.calculateSignalLevel(newRssi,
sWifiSignalImages[0].length);
@@ -981,10 +1018,13 @@ public class PhoneStatusBarPolicy {
mLastWifiSignalLevel = newSignalLevel;
if (mIsWifiConnected) {
iconId = sWifiSignalImages[mInetCondition][newSignalLevel];
+ contentDescription = mContext.getString(
+ sWifiConnectionStrength[newSignalLevel]);
} else {
iconId = sWifiTemporarilyNotConnectedImage;
+ contentDescription = mContext.getString(R.string.accessibility_no_wifi);
}
- mService.setIcon("wifi", iconId, 0);
+ mService.setIcon("wifi", iconId, 0, contentDescription);
}
}
}
@@ -995,14 +1035,16 @@ public class PhoneStatusBarPolicy {
if (action.equals(LocationManager.GPS_FIX_CHANGE_ACTION) && enabled) {
// GPS is getting fixes
- mService.setIcon("gps", com.android.internal.R.drawable.stat_sys_gps_on, 0);
+ mService.setIcon("gps", com.android.internal.R.drawable.stat_sys_gps_on, 0,
+ mContext.getString(R.string.accessibility_gps_enabled));
mService.setIconVisibility("gps", true);
} else if (action.equals(LocationManager.GPS_ENABLED_CHANGE_ACTION) && !enabled) {
// GPS is off
mService.setIconVisibility("gps", false);
} else {
// GPS is on, but not receiving fixes
- mService.setIcon("gps", R.drawable.stat_sys_gps_acquiring_anim, 0);
+ mService.setIcon("gps", R.drawable.stat_sys_gps_acquiring_anim, 0,
+ mContext.getString(R.string.accessibility_gps_acquiring));
mService.setIconVisibility("gps", true);
}
}
@@ -1016,7 +1058,8 @@ public class PhoneStatusBarPolicy {
if (enabled) {
// TTY is on
if (false) Slog.v(TAG, "updateTTY: set TTY on");
- mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0);
+ mService.setIcon("tty", R.drawable.stat_sys_tty_mode, 0,
+ mContext.getString(R.string.accessibility_tty_enabled));
mService.setIconVisibility("tty", true);
} else {
// TTY is off
@@ -1058,15 +1101,15 @@ public class PhoneStatusBarPolicy {
switch (iconMode) {
case EriInfo.ROAMING_ICON_MODE_NORMAL:
- mService.setIcon("cdma_eri", iconList[iconIndex], 0);
+ mService.setIcon("cdma_eri", iconList[iconIndex], 0, null);
mService.setIconVisibility("cdma_eri", true);
break;
case EriInfo.ROAMING_ICON_MODE_FLASH:
- mService.setIcon("cdma_eri", R.drawable.stat_sys_roaming_cdma_flash, 0);
+ mService.setIcon("cdma_eri", R.drawable.stat_sys_roaming_cdma_flash, 0, null);
mService.setIconVisibility("cdma_eri", true);
break;
}
- mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
+ mService.setIcon("phone_signal", mPhoneSignalIconId, 0, null);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 84c524a496d8..c2390e851313 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -26,6 +26,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
+import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
import com.android.systemui.R;
@@ -203,5 +204,19 @@ public class PhoneStatusBarView extends FrameLayout {
return mService.interceptTouchEvent(event)
? true : super.onInterceptTouchEvent(event);
}
-}
+ @Override
+ public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
+ if (super.onRequestSendAccessibilityEvent(child, event)) {
+ // The status bar is very small so augment the view that the user is touching
+ // with the content of the status bar a whole. This way an accessibility service
+ // may announce the current item as well as the entire content if appropriate.
+ AccessibilityEvent record = AccessibilityEvent.obtain();
+ onInitializeAccessibilityEvent(record);
+ dispatchPopulateAccessibilityEvent(record);
+ event.appendRecord(record);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
index 8ee12deb29a8..e76fe517e0e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java
@@ -183,7 +183,8 @@ public abstract class Ticker {
}
final Drawable icon = StatusBarIconView.getIcon(mContext,
- new StatusBarIcon(n.pkg, n.notification.icon, n.notification.iconLevel, 0));
+ new StatusBarIcon(n.pkg, n.notification.icon, n.notification.iconLevel, 0,
+ n.notification.tickerText));
final Segment newSegment = new Segment(n, icon, n.notification.tickerText);
// If there's already a notification schedule for this package and id, remove it.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityContentDescriptions.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityContentDescriptions.java
new file mode 100644
index 000000000000..13fb03e6c677
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AccessibilityContentDescriptions.java
@@ -0,0 +1,37 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+package com.android.systemui.statusbar.policy;
+
+import com.android.systemui.R;
+
+/**
+ * Content descriptions for accessibility support.
+ */
+public class AccessibilityContentDescriptions {
+
+ private AccessibilityContentDescriptions() {}
+
+ static final int[] PHONE_SIGNAL_STRENGTH = {
+ R.string.accessibility_no_phone,
+ R.string.accessibility_phone_one_bar,
+ R.string.accessibility_phone_two_bars,
+ R.string.accessibility_phone_three_bars,
+ R.string.accessibility_phone_signal_full
+ };
+
+ static final int[] DATA_CONNECTION_STRENGTH = {
+ R.string.accessibility_no_data,
+ R.string.accessibility_data_one_bar,
+ R.string.accessibility_data_two_bars,
+ R.string.accessibility_data_three_bars,
+ R.string.accessibility_data_signal_full
+ };
+
+ static final int[] WIFI_CONNECTION_STRENGTH = {
+ R.string.accessibility_no_wifi,
+ R.string.accessibility_wifi_one_bar,
+ R.string.accessibility_wifi_two_bars,
+ R.string.accessibility_wifi_three_bars,
+ R.string.accessibility_wifi_signal_full
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index ae2b6b2c8c24..3957c1b80ab3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -62,12 +62,15 @@ public class BatteryController extends BroadcastReceiver {
ImageView v = mIconViews.get(i);
v.setImageResource(icon);
v.setImageLevel(level);
+ v.setContentDescription(mContext.getString(R.string.accessibility_battery_level,
+ level));
}
N = mLabelViews.size();
for (int i=0; i<N; i++) {
//final boolean plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
TextView v = mLabelViews.get(i);
- v.setText(mContext.getString(R.string.status_bar_settings_battery_meter_format, level));
+ v.setText(mContext.getString(R.string.status_bar_settings_battery_meter_format,
+ level));
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
index 0525054b4aaa..c6f416f5ff8a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java
@@ -19,12 +19,10 @@ package com.android.systemui.statusbar.policy;
import java.util.ArrayList;
import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.util.Slog;
import android.view.View;
import android.widget.ImageView;
@@ -54,26 +52,24 @@ public class BluetoothController extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
- int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
- mEnabled = state == BluetoothAdapter.STATE_ON;
- } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
- int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
+ int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
BluetoothAdapter.STATE_DISCONNECTED);
- if (state == BluetoothAdapter.STATE_CONNECTED) {
- mIconId = R.drawable.stat_sys_data_bluetooth_connected;
- } else {
- mIconId = R.drawable.stat_sys_data_bluetooth;
- }
- }
+ int contentDescriptionResId = 0;
+ if (state == BluetoothAdapter.STATE_CONNECTED) {
+ mIconId = R.drawable.stat_sys_data_bluetooth_connected;
+ contentDescriptionResId = R.string.accessibility_bluetooth_connected;
+ } else {
+ mIconId = R.drawable.stat_sys_data_bluetooth;
+ contentDescriptionResId = R.string.accessibility_bluetooth_disconnected;
+ }
int N = mIconViews.size();
for (int i=0; i<N; i++) {
ImageView v = mIconViews.get(i);
v.setImageResource(mIconId);
v.setVisibility(mEnabled ? View.VISIBLE : View.GONE);
+ v.setContentDescription(mContext.getString(contentDescriptionResId));
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 3175a99fb482..829855b697ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -28,14 +28,11 @@ import android.content.IntentFilter;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
-import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
@@ -87,6 +84,11 @@ public class NetworkController extends BroadcastReceiver {
int mDataTypeIconId;
boolean mDataActive;
+ String mContentDescriptionPhoneSignal;
+ String mContentDescriptionWifi;
+ String mContentDescriptionCombinedSignal;
+ String mContentDescriptionDataType;
+
// wifi
final WifiManager mWifiManager;
AsyncChannel mWifiChannel;
@@ -366,6 +368,8 @@ public class NetworkController extends BroadcastReceiver {
if (mSignalStrength == null) {
mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
mDataSignalIconId = R.drawable.stat_sys_signal_0; // note we use 0 instead of null
+ mContentDescriptionPhoneSignal = mContext.getString(
+ AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[0]);
} else {
int iconLevel;
int[] iconList;
@@ -385,6 +389,9 @@ public class NetworkController extends BroadcastReceiver {
}
}
mPhoneSignalIconId = iconList[iconLevel];
+ mContentDescriptionPhoneSignal = mContext.getString(
+ AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[iconLevel]);
+
mDataSignalIconId = TelephonyIcons.DATA_SIGNAL_STRENGTH[mInetCondition][iconLevel];
}
}
@@ -395,14 +402,20 @@ public class NetworkController extends BroadcastReceiver {
case TelephonyManager.NETWORK_TYPE_UNKNOWN:
mDataIconList = TelephonyIcons.DATA_G[mInetCondition];
mDataTypeIconId = 0;
+ mContentDescriptionDataType = mContext.getString(
+ R.string.accessibility_data_connection_gprs);
break;
case TelephonyManager.NETWORK_TYPE_EDGE:
mDataIconList = TelephonyIcons.DATA_E[mInetCondition];
mDataTypeIconId = R.drawable.stat_sys_signal_edge;
+ mContentDescriptionDataType = mContext.getString(
+ R.string.accessibility_data_connection_edge);
break;
case TelephonyManager.NETWORK_TYPE_UMTS:
mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
mDataTypeIconId = R.drawable.stat_sys_signal_3g;
+ mContentDescriptionDataType = mContext.getString(
+ R.string.accessibility_data_connection_3g);
break;
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
@@ -410,19 +423,27 @@ public class NetworkController extends BroadcastReceiver {
if (mHspaDataDistinguishable) {
mDataIconList = TelephonyIcons.DATA_H[mInetCondition];
mDataTypeIconId = R.drawable.stat_sys_signal_hsdpa;
+ mContentDescriptionDataType = mContext.getString(
+ R.string.accessibility_data_connection_3_5g);
} else {
mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
mDataTypeIconId = R.drawable.stat_sys_signal_3g;
+ mContentDescriptionDataType = mContext.getString(
+ R.string.accessibility_data_connection_3g);
}
break;
case TelephonyManager.NETWORK_TYPE_CDMA:
// display 1xRTT for IS95A/B
mDataIconList = TelephonyIcons.DATA_1X[mInetCondition];
mDataTypeIconId = R.drawable.stat_sys_signal_1x;
+ mContentDescriptionDataType = mContext.getString(
+ R.string.accessibility_data_connection_cdma);
break;
case TelephonyManager.NETWORK_TYPE_1xRTT:
mDataIconList = TelephonyIcons.DATA_1X[mInetCondition];
mDataTypeIconId = R.drawable.stat_sys_signal_1x;
+ mContentDescriptionDataType = mContext.getString(
+ R.string.accessibility_data_connection_cdma);
break;
case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through
case TelephonyManager.NETWORK_TYPE_EVDO_A:
@@ -430,14 +451,20 @@ public class NetworkController extends BroadcastReceiver {
case TelephonyManager.NETWORK_TYPE_EHRPD:
mDataIconList = TelephonyIcons.DATA_3G[mInetCondition];
mDataTypeIconId = R.drawable.stat_sys_signal_3g;
+ mContentDescriptionDataType = mContext.getString(
+ R.string.accessibility_data_connection_3g);
break;
case TelephonyManager.NETWORK_TYPE_LTE:
mDataIconList = TelephonyIcons.DATA_4G[mInetCondition];
mDataTypeIconId = R.drawable.stat_sys_signal_4g;
+ mContentDescriptionDataType = mContext.getString(
+ R.string.accessibility_data_connection_4g);
break;
default:
mDataIconList = TelephonyIcons.DATA_G[mInetCondition];
mDataTypeIconId = R.drawable.stat_sys_signal_gprs;
+ mContentDescriptionDataType = mContext.getString(
+ R.string.accessibility_data_connection_gprs);
break;
}
if ((isCdma() && isCdmaEri()) || mPhone.isNetworkRoaming()) {
@@ -618,8 +645,11 @@ public class NetworkController extends BroadcastReceiver {
private void updateWifiIcons() {
if (mWifiConnected) {
mWifiIconId = WifiIcons.WIFI_SIGNAL_STRENGTH[mInetCondition][mWifiLevel];
+ mContentDescriptionWifi = mContext.getString(
+ AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH[mWifiLevel]);
} else {
mWifiIconId = WifiIcons.WIFI_SIGNAL_STRENGTH[0][0];
+ mContentDescriptionWifi = mContext.getString(R.string.accessibility_no_wifi);
}
}
@@ -704,6 +734,7 @@ public class NetworkController extends BroadcastReceiver {
}
}
combinedSignalIconId = mWifiIconId;
+ mContentDescriptionCombinedSignal = mContentDescriptionWifi;
dataTypeIconId = 0;
} else if (mDataConnected) {
label = mNetworkName;
@@ -723,22 +754,29 @@ public class NetworkController extends BroadcastReceiver {
break;
}
combinedSignalIconId = mDataSignalIconId;
+ mContentDescriptionCombinedSignal = mContentDescriptionDataType;
dataTypeIconId = mDataTypeIconId;
} else if (mBluetoothTethered) {
label = mContext.getString(R.string.bluetooth_tethered);
combinedSignalIconId = mBluetoothTetherIconId;
+ mContentDescriptionCombinedSignal = mContext.getString(
+ R.string.accessibility_bluetooth_tether);
dataTypeIconId = 0;
} else if (mAirplaneMode &&
(mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly()))) {
// Only display the flight-mode icon if not in "emergency calls only" mode.
label = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
combinedSignalIconId = R.drawable.stat_sys_signal_flightmode;
+ mContentDescriptionCombinedSignal = mContext.getString(
+ R.string.accessibility_airplane_mode);
dataTypeIconId = 0;
} else {
label = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
// On devices without mobile radios, we want to show the wifi icon
combinedSignalIconId =
hasMobileDataFeature() ? mDataSignalIconId : mWifiIconId;
+ mContentDescriptionCombinedSignal = hasMobileDataFeature()
+ ? mContentDescriptionDataType : mContentDescriptionWifi;
dataTypeIconId = 0;
}
@@ -764,6 +802,7 @@ public class NetworkController extends BroadcastReceiver {
for (int i=0; i<N; i++) {
final ImageView v = mPhoneSignalIconViews.get(i);
v.setImageResource(mPhoneSignalIconId);
+ v.setContentDescription(mContentDescriptionPhoneSignal);
}
}
@@ -774,6 +813,7 @@ public class NetworkController extends BroadcastReceiver {
for (int i=0; i<N; i++) {
final ImageView v = mDataDirectionIconViews.get(i);
v.setImageResource(mDataDirectionIconId);
+ v.setContentDescription(mContentDescriptionDataType);
}
}
@@ -784,6 +824,7 @@ public class NetworkController extends BroadcastReceiver {
for (int i=0; i<N; i++) {
final ImageView v = mWifiIconViews.get(i);
v.setImageResource(mWifiIconId);
+ v.setContentDescription(mContentDescriptionWifi);
}
}
@@ -794,6 +835,7 @@ public class NetworkController extends BroadcastReceiver {
for (int i=0; i<N; i++) {
final ImageView v = mCombinedSignalIconViews.get(i);
v.setImageResource(combinedSignalIconId);
+ v.setContentDescription(mContentDescriptionCombinedSignal);
}
}
@@ -808,6 +850,7 @@ public class NetworkController extends BroadcastReceiver {
} else {
v.setVisibility(View.VISIBLE);
v.setImageResource(dataTypeIconId);
+ v.setContentDescription(mContentDescriptionDataType);
}
}
}
@@ -826,6 +869,7 @@ public class NetworkController extends BroadcastReceiver {
} else {
v.setVisibility(View.VISIBLE);
v.setImageResource(dataDirectionOverlayIconId);
+ v.setContentDescription(mContentDescriptionDataType);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
index b4d2a14ecb07..d5885bb81c25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
@@ -148,6 +148,11 @@ public class NotificationRowLayout extends ViewGroup {
"now sliding child %d: %s (touchY=%.1f, rowHeight=%d, count=%d)",
childIdx, mSlidingChild, mInitialTouchY, mRowHeight, count));
}
+
+
+ // We need to prevent the surrounding ScrollView from intercepting us now;
+ // the scroll position will be locked while we swipe
+ requestDisallowInterceptTouchEvent(true);
}
}
break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java
index c62c4ad872cf..8c4ae197d3b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/CompatModePanel.java
@@ -22,6 +22,7 @@ import android.content.res.TypedArray;
import android.os.RemoteException;
import android.util.AttributeSet;
import android.util.Slog;
+import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -90,6 +91,19 @@ public class CompatModePanel extends FrameLayout implements StatusBarPanel,
return false;
}
+ @Override
+ public boolean dispatchHoverEvent(MotionEvent event) {
+ // Ignore hover events outside of this panel bounds since such events
+ // generate spurious accessibility events with the panel content when
+ // tapping outside of it, thus confusing the user.
+ final int x = (int) event.getX();
+ final int y = (int) event.getY();
+ if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
+ return super.dispatchHoverEvent(event);
+ }
+ return true;
+ }
+
public void setTrigger(View v) {
mTrigger = v;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
index 339e3f3812b9..1e417acdd41c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
@@ -30,6 +30,7 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
+import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
@@ -160,6 +161,19 @@ public class InputMethodsPanel extends LinearLayout implements StatusBarPanel,
}
}
+ @Override
+ public boolean dispatchHoverEvent(MotionEvent event) {
+ // Ignore hover events outside of this panel bounds since such events
+ // generate spurious accessibility events with the panel content when
+ // tapping outside of it, thus confusing the user.
+ final int x = (int) event.getX();
+ final int y = (int) event.getY();
+ if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
+ return super.dispatchHoverEvent(event);
+ }
+ return true;
+ }
+
private void updateHardKeyboardEnabled() {
if (mHardKeyboardAvailable) {
final boolean checked = mHardKeyboardSwitch.isChecked();
@@ -222,6 +236,7 @@ public class InputMethodsPanel extends LinearLayout implements StatusBarPanel,
itemSubtitle.setText(imiName);
}
subtypeIcon.setImageDrawable(icon);
+ subtypeIcon.setContentDescription(itemTitle.getText());
final String settingsActivity = imi.getSettingsActivity();
if (!TextUtils.isEmpty(settingsActivity)) {
settingsIcon.setOnClickListener(new View.OnClickListener() {
@@ -463,4 +478,5 @@ public class InputMethodsPanel extends LinearLayout implements StatusBarPanel,
public interface OnHardKeyboardEnabledChangeListener {
public void onHardKeyboardEnabledChange(boolean enabled);
}
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationArea.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationArea.java
new file mode 100644
index 000000000000..42bdf3d925e3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationArea.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.tablet;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.widget.LinearLayout;
+
+public class NotificationArea extends LinearLayout {
+
+ public NotificationArea(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
+ if (super.onRequestSendAccessibilityEvent(child, event)) {
+ // The event is coming from a descendant like battery but append
+ // the content of the entire notification area so accessibility
+ // services can choose how to present the content to the user.
+ AccessibilityEvent record = AccessibilityEvent.obtain();
+ onInitializeAccessibilityEvent(record);
+ dispatchPopulateAccessibilityEvent(record);
+ event.appendRecord(record);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index 64a4f160830f..a316e4b4b023 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -20,27 +20,15 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Slog;
-import android.view.accessibility.AccessibilityEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
-import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewGroup;
-import android.view.animation.AccelerateInterpolator;
-import android.widget.FrameLayout;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
import android.widget.RelativeLayout;
-import android.widget.TextView;
import com.android.systemui.R;
@@ -53,8 +41,7 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
boolean mShowing;
int mNotificationCount = 0;
- View mTitleArea;
- ModeToggle mModeToggle;
+ NotificationPanelTitle mTitleArea;
View mSettingsButton;
View mNotificationButton;
View mNotificationScroller;
@@ -68,48 +55,6 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
Choreographer mChoreo = new Choreographer();
- static class ModeToggle extends View {
- NotificationPanel mPanel;
- View mTitle;
- public ModeToggle(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public void setPanel(NotificationPanel p) {
- mPanel = p;
- }
- public void setTitleArea(View v) {
- mTitle = v;
- }
- @Override
- public boolean onTouchEvent(MotionEvent e) {
- final int x = (int)e.getX();
- final int y = (int)e.getY();
- switch (e.getAction()) {
- case MotionEvent.ACTION_DOWN:
- mTitle.setPressed(true);
- break;
- case MotionEvent.ACTION_MOVE:
- mTitle.setPressed(x >= 0
- && x < getWidth()
- && y >= 0
- && y < getHeight());
- break;
- case MotionEvent.ACTION_CANCEL:
- mTitle.setPressed(false);
- break;
- case MotionEvent.ACTION_UP:
- if (mTitle.isPressed()) {
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
- playSoundEffect(SoundEffectConstants.CLICK);
- mPanel.swapPanels();
- mTitle.setPressed(false);
- }
- break;
- }
- return true;
- }
- }
-
public NotificationPanel(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@@ -126,14 +71,11 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
mContentParent = (ViewGroup)findViewById(R.id.content_parent);
mContentParent.bringToFront();
- mTitleArea = findViewById(R.id.title_area);
- mModeToggle = (ModeToggle) findViewById(R.id.mode_toggle);
- mModeToggle.setOnClickListener(this);
- mModeToggle.setPanel(this);
- mModeToggle.setTitleArea(mTitleArea);
+ mTitleArea = (NotificationPanelTitle) findViewById(R.id.title_area);
+ mTitleArea.setPanel(this);
- mSettingsButton = (ImageView)findViewById(R.id.settings_button);
- mNotificationButton = (ImageView)findViewById(R.id.notification_button);
+ mSettingsButton = findViewById(R.id.settings_button);
+ mNotificationButton = findViewById(R.id.notification_button);
mNotificationScroller = findViewById(R.id.notification_scroller);
mContentFrame = (ViewGroup)findViewById(R.id.content_frame);
@@ -185,6 +127,19 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
}
}
+ @Override
+ public boolean dispatchHoverEvent(MotionEvent event) {
+ // Ignore hover events outside of this panel bounds since such events
+ // generate spurious accessibility events with the panel content when
+ // tapping outside of it, thus confusing the user.
+ final int x = (int) event.getX();
+ final int y = (int) event.getY();
+ if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
+ return super.dispatchHoverEvent(event);
+ }
+ return true;
+ }
+
/*
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
@@ -205,7 +160,7 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
*/
public void onClick(View v) {
- if (v == mModeToggle) {
+ if (v == mTitleArea) {
swapPanels();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanelTitle.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanelTitle.java
new file mode 100644
index 000000000000..689bc36a4320
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanelTitle.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.tablet;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.SoundEffectConstants;
+import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
+import android.widget.RelativeLayout;
+
+public class NotificationPanelTitle extends RelativeLayout implements View.OnClickListener {
+ private NotificationPanel mPanel;
+
+ public NotificationPanelTitle(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setOnClickListener(this);
+ }
+
+ public void setPanel(NotificationPanel p) {
+ mPanel = p;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent e) {
+ switch (e.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ setPressed(true);
+ break;
+ case MotionEvent.ACTION_MOVE:
+ final int x = (int) e.getX();
+ final int y = (int) e.getY();
+ setPressed(x > 0 && x < getWidth() && y > 0 && y < getHeight());
+ break;
+ case MotionEvent.ACTION_UP:
+ if (isPressed()) {
+ playSoundEffect(SoundEffectConstants.CLICK);
+ mPanel.swapPanels();
+ setPressed(false);
+ }
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ setPressed(false);
+ break;
+ }
+ return true;
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v == this) {
+ mPanel.swapPanels();
+ }
+ }
+
+ @Override
+ public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
+ if (super.onRequestSendAccessibilityEvent(child, event)) {
+ AccessibilityEvent record = AccessibilityEvent.obtain();
+ onInitializeAccessibilityEvent(record);
+ dispatchPopulateAccessibilityEvent(record);
+ event.appendRecord(record);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPeekPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPeekPanel.java
index 8b682403fb29..ba2830605fce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPeekPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPeekPanel.java
@@ -18,12 +18,9 @@ package com.android.systemui.statusbar.tablet;
import android.content.Context;
import android.util.AttributeSet;
-import android.util.Slog;
import android.view.MotionEvent;
import android.widget.RelativeLayout;
-import com.android.systemui.R;
-
public class NotificationPeekPanel extends RelativeLayout implements StatusBarPanel {
TabletStatusBar mBar;
@@ -54,5 +51,17 @@ public class NotificationPeekPanel extends RelativeLayout implements StatusBarPa
mBar.resetNotificationPeekFadeTimer();
return false;
}
-}
+ @Override
+ public boolean dispatchHoverEvent(MotionEvent event) {
+ // Ignore hover events outside of this panel bounds since such events
+ // generate spurious accessibility events with the panel content when
+ // tapping outside of it, thus confusing the user.
+ final int x = (int) event.getX();
+ final int y = (int) event.getY();
+ if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
+ return super.dispatchHoverEvent(event);
+ }
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index df09f84e5c51..13846ed1e237 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -808,7 +808,8 @@ public class TabletStatusBar extends StatusBar implements
// Update the icon.
final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
notification.notification.icon, notification.notification.iconLevel,
- notification.notification.number);
+ notification.notification.number,
+ notification.notification.tickerText);
if (!oldEntry.icon.set(ic)) {
handleNotificationError(key, notification, "Couldn't update icon: " + ic);
return;
@@ -1012,10 +1013,7 @@ public class TabletStatusBar extends StatusBar implements
mCompatModeButton.refresh();
if (mCompatModeButton.getVisibility() == View.VISIBLE) {
- if (DEBUG_COMPAT_HELP
- || ! Prefs.read(mContext).getBoolean(Prefs.SHOWN_COMPAT_MODE_HELP, false)) {
showCompatibilityHelp();
- }
} else {
hideCompatibilityHelp();
mCompatModePanel.closePanel();
@@ -1451,13 +1449,15 @@ public class TabletStatusBar extends StatusBar implements
}
// Construct the icon.
final StatusBarIconView iconView = new StatusBarIconView(mContext,
- notification.pkg + "/0x" + Integer.toHexString(notification.id));
+ notification.pkg + "/0x" + Integer.toHexString(notification.id),
+ notification.notification);
iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
notification.notification.icon,
notification.notification.iconLevel,
- notification.notification.number);
+ notification.notification.number,
+ notification.notification.tickerText);
if (!iconView.set(ic)) {
handleNotificationError(key, notification, "Couldn't attach StatusBarIcon: " + ic);
return null;
@@ -1501,11 +1501,6 @@ public class TabletStatusBar extends StatusBar implements
// alternate behavior in DND mode
if (mNotificationDNDMode) {
if (mIconLayout.getChildCount() == 0) {
- final StatusBarIconView iconView = new StatusBarIconView(mContext, "_dnd");
- iconView.setImageResource(R.drawable.ic_notification_dnd);
- iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
- iconView.setPadding(mIconHPadding, 0, mIconHPadding, 0);
-
final Notification dndNotification = new Notification.Builder(mContext)
.setContentTitle(mContext.getText(R.string.notifications_off_title))
.setContentText(mContext.getText(R.string.notifications_off_text))
@@ -1513,6 +1508,12 @@ public class TabletStatusBar extends StatusBar implements
.setOngoing(true)
.getNotification();
+ final StatusBarIconView iconView = new StatusBarIconView(mContext, "_dnd",
+ dndNotification);
+ iconView.setImageResource(R.drawable.ic_notification_dnd);
+ iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+ iconView.setPadding(mIconHPadding, 0, mIconHPadding, 0);
+
mNotificationDNDDummyEntry = new NotificationData.Entry(
null,
new StatusBarNotification("", 0, "", 0, 0, dndNotification),
@@ -1634,19 +1635,24 @@ public class TabletStatusBar extends StatusBar implements
} else {
if ((sbn.notification.flags & Notification.FLAG_ONGOING_EVENT) == 0) {
vetoButton.setVisibility(View.INVISIBLE);
+ vetoButton.setContentDescription("VETO");
} else {
vetoButton.setVisibility(View.GONE);
}
}
+ vetoButton.setContentDescription(mContext.getString(
+ R.string.accessibility_remove_notification));
// the large icon
ImageView largeIcon = (ImageView)row.findViewById(R.id.large_icon);
if (sbn.notification.largeIcon != null) {
largeIcon.setImageBitmap(sbn.notification.largeIcon);
+ largeIcon.setContentDescription(sbn.notification.tickerText);
} else {
largeIcon.getLayoutParams().width = 0;
largeIcon.setVisibility(View.INVISIBLE);
}
+ largeIcon.setContentDescription(sbn.notification.tickerText);
// bind the click event to the content area
ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
index a8f4262aff79..6045e31d3ad7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -284,7 +284,7 @@ public class TabletTicker
} else if (n.tickerText != null) {
group = (ViewGroup)inflater.inflate(R.layout.status_bar_ticker_compat, mWindow, false);
final Drawable icon = StatusBarIconView.getIcon(mContext,
- new StatusBarIcon(notification.pkg, n.icon, n.iconLevel, 0));
+ new StatusBarIcon(notification.pkg, n.icon, n.iconLevel, 0, n.tickerText));
ImageView iv = (ImageView)group.findViewById(iconId);
iv.setImageDrawable(icon);
iv.setVisibility(View.VISIBLE);
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 935f4ad0cb6d..47d34b3261de 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -35,7 +35,6 @@ import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Handler;
-import android.os.IBinder;
import android.os.LocalPowerManager;
import android.os.Message;
import android.os.PowerManager;
@@ -43,7 +42,6 @@ import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
import android.telephony.TelephonyManager;
import android.util.EventLog;
import android.util.Log;
@@ -1117,8 +1115,11 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
// Give feedback to user when secure keyguard is active and engaged
if (mShowing && isSecure()) {
if (!mShowingLockIcon) {
+ String contentDescription = mContext.getString(
+ com.android.internal.R.string.status_bar_device_locked);
mStatusBarManager.setIcon("secure",
- com.android.internal.R.drawable.stat_sys_secure, 0);
+ com.android.internal.R.drawable.stat_sys_secure, 0,
+ contentDescription);
mShowingLockIcon = true;
}
} else {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index b963b131f59f..e0debf7ca994 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -388,6 +388,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
st.isHandled = false;
mPreparedPanel = st;
+ if (st.frozenActionViewState != null) {
+ st.menu.restoreActionViewStates(st.frozenActionViewState);
+ st.frozenActionViewState = null;
+ }
+
return true;
}
@@ -652,7 +657,13 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
@Override
public void invalidatePanelMenu(int featureId) {
PanelFeatureState st = getPanelState(featureId, true);
+ Bundle savedActionViewStates = null;
if (st.menu != null) {
+ savedActionViewStates = new Bundle();
+ st.menu.saveActionViewStates(savedActionViewStates);
+ if (savedActionViewStates.size() > 0) {
+ st.frozenActionViewState = savedActionViewStates;
+ }
st.menu.clear();
}
st.refreshMenuContent = true;
@@ -3024,6 +3035,12 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
*/
Bundle frozenMenuState;
+ /**
+ * Contains the state of associated action views when told to freeze.
+ * These are saved across invalidations.
+ */
+ Bundle frozenActionViewState;
+
PanelFeatureState(int featureId) {
this.featureId = featureId;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index ad6cebb60b78..ae13ab5a17a9 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -166,22 +166,22 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final int SYSTEM_DIALOG_LAYER = 6;
// toasts and the plugged-in battery thing
static final int TOAST_LAYER = 7;
- static final int STATUS_BAR_LAYER = 8;
- static final int STATUS_BAR_PANEL_LAYER = 9;
// SIM errors and unlock. Not sure if this really should be in a high layer.
- static final int PRIORITY_PHONE_LAYER = 10;
+ static final int PRIORITY_PHONE_LAYER = 8;
// like the ANR / app crashed dialogs
- static final int SYSTEM_ALERT_LAYER = 11;
+ static final int SYSTEM_ALERT_LAYER = 9;
// system-level error dialogs
- static final int SYSTEM_ERROR_LAYER = 12;
+ static final int SYSTEM_ERROR_LAYER = 10;
// on-screen keyboards and other such input method user interfaces go here.
- static final int INPUT_METHOD_LAYER = 13;
+ static final int INPUT_METHOD_LAYER = 11;
// on-screen keyboards and other such input method user interfaces go here.
- static final int INPUT_METHOD_DIALOG_LAYER = 14;
+ static final int INPUT_METHOD_DIALOG_LAYER = 12;
// the keyguard; nothing on top of these can take focus, since they are
// responsible for power management when displayed.
- static final int KEYGUARD_LAYER = 15;
- static final int KEYGUARD_DIALOG_LAYER = 16;
+ static final int KEYGUARD_LAYER = 13;
+ static final int KEYGUARD_DIALOG_LAYER = 14;
+ static final int STATUS_BAR_LAYER = 15;
+ static final int STATUS_BAR_PANEL_LAYER = 16;
// the navigation bar, if available, shows atop most things
static final int NAVIGATION_BAR_LAYER = 17;
// the drag layer: input for drag-and-drop is associated with this window,
@@ -1703,7 +1703,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
}
- if (DEBUG_LAYOUT) Log.i(TAG, "mNavigationBar frame: " + navr);
+ if (DEBUG_LAYOUT) {
+ Log.i(TAG, "mNavigationBar frame: " + navr);
+ Log.i(TAG, String.format("mDock rect: (%d,%d - %d,%d)",
+ mDockLeft, mDockTop, mDockRight, mDockBottom));
+ }
// apply navigation bar insets
pf.left = df.left = vf.left = mDockLeft;
@@ -1713,6 +1717,25 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mStatusBar.computeFrameLw(pf, df, vf, vf);
+ // now, let's consider the navigation bar; if it exists, it must be removed from the
+ // available screen real estate (like an un-hideable status bar)
+ if (navr != null) {
+ if (navr.top == 0) {
+ // Navigation bar is vertical
+ if (mRestrictedScreenLeft == navr.left) {
+ mRestrictedScreenLeft = navr.right;
+ mRestrictedScreenWidth -= (navr.right - navr.left);
+ } else if ((mRestrictedScreenLeft+mRestrictedScreenWidth) == navr.right) {
+ mRestrictedScreenWidth -= (navr.right - navr.left);
+ }
+ } else {
+ // Navigation bar horizontal, at bottom
+ if ((mRestrictedScreenHeight+mRestrictedScreenTop) == navr.bottom) {
+ mRestrictedScreenHeight -= (navr.bottom-navr.top);
+ }
+ }
+ }
+
if (mStatusBar.isVisibleLw()) {
// If the status bar is hidden, we don't want to cause
// windows behind it to scroll.
@@ -1745,23 +1768,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mRestrictedScreenHeight -= (r.bottom-r.top);
}
- if (navr != null) {
- if (navr.top == 0) {
- // Navigation bar is vertical
- if (mRestrictedScreenLeft == navr.left) {
- mRestrictedScreenLeft = navr.right;
- mRestrictedScreenWidth -= (navr.right - navr.left);
- } else if ((mRestrictedScreenLeft+mRestrictedScreenWidth) == navr.right) {
- mRestrictedScreenWidth -= (navr.right - navr.left);
- }
- } else {
- // Navigation bar horizontal, at bottom
- if ((mRestrictedScreenHeight-mRestrictedScreenTop) == r.bottom) {
- mRestrictedScreenHeight -= (navr.bottom-navr.top);
- }
- }
- }
-
mContentTop = mCurTop = mDockTop = mRestrictedScreenTop;
mContentBottom = mCurBottom = mDockBottom
= mRestrictedScreenTop + mRestrictedScreenHeight;
@@ -1873,19 +1879,22 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// permission, so they have the same privileges as the status
// bar itself.
//
- // However, they should still dodge the navigation bar if it exists. A
- // straightforward way to do this is to only allow the status bar panels to
- // extend to the extrema of the allowable region for the IME dock.
+ // However, they should still dodge the navigation bar if it exists.
pf.left = df.left = hasNavBar ? mDockLeft : mUnrestrictedScreenLeft;
pf.top = df.top = mUnrestrictedScreenTop;
pf.right = df.right = hasNavBar
- ? mDockRight
+ ? mRestrictedScreenLeft+mRestrictedScreenWidth
: mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
pf.bottom = df.bottom = hasNavBar
- ? mDockBottom
+ ? mRestrictedScreenTop+mRestrictedScreenHeight
: mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
+ if (DEBUG_LAYOUT) {
+ Log.v(TAG, String.format(
+ "Laying out status bar window: (%d,%d - %d,%d)",
+ pf.left, pf.top, pf.right, pf.bottom));
+ }
} else {
pf.left = df.left = mRestrictedScreenLeft;
pf.top = df.top = mRestrictedScreenTop;
@@ -1922,12 +1931,23 @@ public class PhoneWindowManager implements WindowManagerPolicy {
pf.left = df.left = cf.left = hasNavBar ? mDockLeft : mUnrestrictedScreenLeft;
pf.top = df.top = cf.top = mUnrestrictedScreenTop;
pf.right = df.right = cf.right = hasNavBar
- ? mDockRight
+ ? mRestrictedScreenLeft+mRestrictedScreenWidth
: mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
pf.bottom = df.bottom = cf.bottom = hasNavBar
- ? mDockBottom
+ ? mRestrictedScreenTop+mRestrictedScreenHeight
: mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
+ } else if (attrs.type == TYPE_NAVIGATION_BAR) {
+ // The navigation bar has Real Ultimate Power.
+ pf.left = df.left = mUnrestrictedScreenLeft;
+ pf.top = df.top = mUnrestrictedScreenTop;
+ pf.right = df.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
+ pf.bottom = df.bottom = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
+ if (DEBUG_LAYOUT) {
+ Log.v(TAG, String.format(
+ "Laying out navigation bar window: (%d,%d - %d,%d)",
+ pf.left, pf.top, pf.right, pf.bottom));
+ }
} else {
pf.left = df.left = cf.left = mRestrictedScreenLeft;
pf.top = df.top = cf.top = mRestrictedScreenTop;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 86d4cc3f304e..0323fe0001a3 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -81,6 +81,8 @@ static const int kDumpLockSleep = 20000;
static const nsecs_t kWarningThrottle = seconds(5);
+// RecordThread loop sleep time upon application overrun or audio HAL read error
+static const int kRecordThreadSleepUs = 5000;
// ----------------------------------------------------------------------------
@@ -417,7 +419,7 @@ sp<IAudioTrack> AudioFlinger::createTrack(
lSessionId = *sessionId;
} else {
// if no audio session id is provided, create one here
- lSessionId = nextUniqueId_l();
+ lSessionId = nextUniqueId();
if (sessionId != NULL) {
*sessionId = lSessionId;
}
@@ -725,6 +727,15 @@ status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs)
thread = checkPlaybackThread_l(ioHandle);
if (thread == NULL) {
thread = checkRecordThread_l(ioHandle);
+ } else if (thread.get() == primaryPlaybackThread_l()) {
+ // indicate output device change to all input threads for pre processing
+ AudioParameter param = AudioParameter(keyValuePairs);
+ int value;
+ if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
+ for (size_t i = 0; i < mRecordThreads.size(); i++) {
+ mRecordThreads.valueAt(i)->setParameters(keyValuePairs);
+ }
+ }
}
}
if (thread != NULL) {
@@ -873,10 +884,10 @@ void AudioFlinger::removeClient_l(pid_t pid)
// ----------------------------------------------------------------------------
-AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id)
+AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id, uint32_t device)
: Thread(false),
mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mChannelCount(0),
- mFrameSize(1), mFormat(0), mStandby(false), mId(id), mExiting(false)
+ mFrameSize(1), mFormat(0), mStandby(false), mId(id), mExiting(false), mDevice(device)
{
}
@@ -1032,14 +1043,15 @@ status_t AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args
return NO_ERROR;
}
-
// ----------------------------------------------------------------------------
-AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
- : ThreadBase(audioFlinger, id),
+AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger,
+ AudioStreamOut* output,
+ int id,
+ uint32_t device)
+ : ThreadBase(audioFlinger, id, device),
mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output),
- mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
- mDevice(device)
+ mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false)
{
readOutputParameters();
@@ -1199,9 +1211,9 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTra
}
}
- if (mOutput == 0) {
+ lStatus = initCheck();
+ if (lStatus != NO_ERROR) {
LOGE("Audio driver not initialized.");
- lStatus = NO_INIT;
goto Exit;
}
@@ -1423,7 +1435,7 @@ status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, ui
if (halFrames == 0 || dspFrames == 0) {
return BAD_VALUE;
}
- if (mOutput == 0) {
+ if (initCheck() != NO_ERROR) {
return INVALID_OPERATION;
}
*halFrames = mBytesWritten / audio_stream_frame_size(&mOutput->stream->common);
@@ -1468,34 +1480,6 @@ uint32_t AudioFlinger::PlaybackThread::getStrategyForSession_l(int sessionId)
return AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
}
-sp<AudioFlinger::EffectChain> AudioFlinger::PlaybackThread::getEffectChain(int sessionId)
-{
- Mutex::Autolock _l(mLock);
- return getEffectChain_l(sessionId);
-}
-
-sp<AudioFlinger::EffectChain> AudioFlinger::PlaybackThread::getEffectChain_l(int sessionId)
-{
- sp<EffectChain> chain;
-
- size_t size = mEffectChains.size();
- for (size_t i = 0; i < size; i++) {
- if (mEffectChains[i]->sessionId() == sessionId) {
- chain = mEffectChains[i];
- break;
- }
- }
- return chain;
-}
-
-void AudioFlinger::PlaybackThread::setMode(uint32_t mode)
-{
- Mutex::Autolock _l(mLock);
- size_t size = mEffectChains.size();
- for (size_t i = 0; i < size; i++) {
- mEffectChains[i]->setMode_l(mode);
- }
-}
// ----------------------------------------------------------------------------
@@ -1503,7 +1487,7 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud
: PlaybackThread(audioFlinger, output, id, device),
mAudioMixer(0)
{
- mType = PlaybackThread::MIXER;
+ mType = ThreadBase::MIXER;
mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
// FIXME - Current mixer implementation only supports stereo output
@@ -2072,7 +2056,7 @@ uint32_t AudioFlinger::MixerThread::suspendSleepTimeUs()
AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
: PlaybackThread(audioFlinger, output, id, device)
{
- mType = PlaybackThread::DIRECT;
+ mType = ThreadBase::DIRECT;
}
AudioFlinger::DirectOutputThread::~DirectOutputThread()
@@ -2551,7 +2535,7 @@ uint32_t AudioFlinger::DirectOutputThread::suspendSleepTimeUs()
AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::MixerThread* mainThread, int id)
: MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->device()), mWaitTimeMs(UINT_MAX)
{
- mType = PlaybackThread::DUPLICATING;
+ mType = ThreadBase::DUPLICATING;
addOutputTrack(mainThread);
}
@@ -2970,7 +2954,7 @@ AudioFlinger::PlaybackThread::Track::Track(
mStreamType = streamType;
// NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of
// 16 bit because data is converted to 16 bit before being stored in buffer by AudioTrack
- mCblk->frameSize = audio_is_linear_pcm(format) ? mChannelCount * audio_bytes_per_sample(format) : sizeof(uint8_t);
+ mCblk->frameSize = audio_is_linear_pcm(format) ? mChannelCount * sizeof(int16_t) : sizeof(uint8_t);
}
}
@@ -3751,21 +3735,26 @@ sp<IAudioRecord> AudioFlinger::openRecord(
if (sessionId != NULL && *sessionId != AUDIO_SESSION_OUTPUT_MIX) {
lSessionId = *sessionId;
} else {
- lSessionId = nextUniqueId_l();
+ lSessionId = nextUniqueId();
if (sessionId != NULL) {
*sessionId = lSessionId;
}
}
// create new record track. The record track uses one track in mHardwareMixerThread by convention.
- recordTrack = new RecordThread::RecordTrack(thread, client, sampleRate,
- format, channelMask, frameCount, flags, lSessionId);
- }
- if (recordTrack->getCblk() == NULL) {
+ recordTrack = thread->createRecordTrack_l(client,
+ sampleRate,
+ format,
+ channelMask,
+ frameCount,
+ flags,
+ lSessionId,
+ &lStatus);
+ }
+ if (lStatus != NO_ERROR) {
// remove local strong reference to Client before deleting the RecordTrack so that the Client
// destructor is called by the TrackBase destructor with mLock held
client.clear();
recordTrack.clear();
- lStatus = NO_MEMORY;
goto Exit;
}
@@ -3814,10 +3803,16 @@ status_t AudioFlinger::RecordHandle::onTransact(
// ----------------------------------------------------------------------------
-AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, AudioStreamIn *input, uint32_t sampleRate, uint32_t channels, int id) :
- ThreadBase(audioFlinger, id),
- mInput(input), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0)
+AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger,
+ AudioStreamIn *input,
+ uint32_t sampleRate,
+ uint32_t channels,
+ int id,
+ uint32_t device) :
+ ThreadBase(audioFlinger, id, device),
+ mInput(input), mTrack(NULL), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0)
{
+ mType = ThreadBase::RECORD;
mReqChannelCount = popcount(channels);
mReqSampleRate = sampleRate;
readInputParameters();
@@ -3847,6 +3842,7 @@ bool AudioFlinger::RecordThread::threadLoop()
{
AudioBufferProvider::Buffer buffer;
sp<RecordTrack> activeTrack;
+ Vector< sp<EffectChain> > effectChains;
nsecs_t lastWarning = 0;
@@ -3897,14 +3893,22 @@ bool AudioFlinger::RecordThread::threadLoop()
mStandby = false;
}
}
+ lockEffectChains_l(effectChains);
}
if (mActiveTrack != 0) {
if (mActiveTrack->mState != TrackBase::ACTIVE &&
mActiveTrack->mState != TrackBase::RESUMING) {
- usleep(5000);
+ unlockEffectChains(effectChains);
+ usleep(kRecordThreadSleepUs);
continue;
}
+ for (size_t i = 0; i < effectChains.size(); i ++) {
+ effectChains[i]->process_l();
+ }
+ // enable changes in effect chain
+ unlockEffectChains(effectChains);
+
buffer.frameCount = mFrameCount;
if (LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
size_t framesOut = buffer.frameCount;
@@ -3953,7 +3957,7 @@ bool AudioFlinger::RecordThread::threadLoop()
// Force input into standby so that it tries to
// recover at next read attempt
mInput->stream->common.standby(&mInput->stream->common);
- usleep(5000);
+ usleep(kRecordThreadSleepUs);
}
mRsmpInIndex = mFrameCount;
framesOut = 0;
@@ -4001,9 +4005,12 @@ bool AudioFlinger::RecordThread::threadLoop()
// Release the processor for a while before asking for a new buffer.
// This will give the application more chance to read from the buffer and
// clear the overflow.
- usleep(5000);
+ usleep(kRecordThreadSleepUs);
}
+ } else {
+ unlockEffectChains(effectChains);
}
+ effectChains.clear();
}
if (!mStandby) {
@@ -4017,6 +4024,49 @@ bool AudioFlinger::RecordThread::threadLoop()
return false;
}
+
+sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRecordTrack_l(
+ const sp<AudioFlinger::Client>& client,
+ uint32_t sampleRate,
+ int format,
+ int channelMask,
+ int frameCount,
+ uint32_t flags,
+ int sessionId,
+ status_t *status)
+{
+ sp<RecordTrack> track;
+ status_t lStatus;
+
+ lStatus = initCheck();
+ if (lStatus != NO_ERROR) {
+ LOGE("Audio driver not initialized.");
+ goto Exit;
+ }
+
+ { // scope for mLock
+ Mutex::Autolock _l(mLock);
+
+ track = new RecordTrack(this, client, sampleRate,
+ format, channelMask, frameCount, flags, sessionId);
+
+ if (track->getCblk() == NULL) {
+ lStatus = NO_MEMORY;
+ goto Exit;
+ }
+
+ mTrack = track.get();
+
+ }
+ lStatus = NO_ERROR;
+
+Exit:
+ if (status) {
+ *status = lStatus;
+ }
+ return track;
+}
+
status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack)
{
LOGV("RecordThread::start");
@@ -4146,7 +4196,7 @@ status_t AudioFlinger::RecordThread::getNextBuffer(AudioBufferProvider::Buffer*
// Force input into standby so that it tries to
// recover at next read attempt
mInput->stream->common.standby(&mInput->stream->common);
- usleep(5000);
+ usleep(kRecordThreadSleepUs);
}
buffer->raw = 0;
buffer->frameCount = 0;
@@ -4211,6 +4261,23 @@ bool AudioFlinger::RecordThread::checkForNewParameters_l()
reconfig = true;
}
}
+ if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
+ // forward device change to effects that have requested to be
+ // aware of attached audio device.
+ for (size_t i = 0; i < mEffectChains.size(); i++) {
+ mEffectChains[i]->setDevice_l(value);
+ }
+ // store input device and output device but do not forward output device to audio HAL.
+ // Note that status is ignored by the caller for output device
+ // (see AudioFlinger::setParameters()
+ if (value & AUDIO_DEVICE_OUT_ALL) {
+ mDevice &= (uint32_t)~(value & AUDIO_DEVICE_OUT_ALL);
+ status = BAD_VALUE;
+ } else {
+ mDevice &= (uint32_t)~(value & AUDIO_DEVICE_IN_ALL);
+ }
+ mDevice |= (uint32_t)value;
+ }
if (status == NO_ERROR) {
status = mInput->stream->common.set_parameters(&mInput->stream->common, keyValuePair.string());
if (status == INVALID_OPERATION) {
@@ -4320,6 +4387,21 @@ unsigned int AudioFlinger::RecordThread::getInputFramesLost()
return mInput->stream->get_input_frames_lost(mInput->stream);
}
+uint32_t AudioFlinger::RecordThread::hasAudioSession(int sessionId)
+{
+ Mutex::Autolock _l(mLock);
+ uint32_t result = 0;
+ if (getEffectChain_l(sessionId) != 0) {
+ result = EFFECT_SESSION;
+ }
+
+ if (mTrack != NULL && sessionId == mTrack->sessionId()) {
+ result |= TRACK_SESSION;
+ }
+
+ return result;
+}
+
// ----------------------------------------------------------------------------
int AudioFlinger::openOutput(uint32_t *pDevices,
@@ -4368,7 +4450,7 @@ int AudioFlinger::openOutput(uint32_t *pDevices,
mHardwareStatus = AUDIO_HW_IDLE;
if (outStream != NULL) {
AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream);
- int id = nextUniqueId_l();
+ int id = nextUniqueId();
if ((flags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT) ||
(format != AUDIO_FORMAT_PCM_16_BIT) ||
@@ -4405,7 +4487,7 @@ int AudioFlinger::openDuplicateOutput(int output1, int output2)
return 0;
}
- int id = nextUniqueId_l();
+ int id = nextUniqueId();
DuplicatingThread *thread = new DuplicatingThread(this, thread1, id);
thread->addOutputTrack(thread2);
mPlaybackThreads.add(id, thread);
@@ -4428,9 +4510,9 @@ status_t AudioFlinger::closeOutput(int output)
LOGV("closeOutput() %d", output);
- if (thread->type() == PlaybackThread::MIXER) {
+ if (thread->type() == ThreadBase::MIXER) {
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- if (mPlaybackThreads.valueAt(i)->type() == PlaybackThread::DUPLICATING) {
+ if (mPlaybackThreads.valueAt(i)->type() == ThreadBase::DUPLICATING) {
DuplicatingThread *dupThread = (DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
dupThread->removeOutputTrack((MixerThread *)thread.get());
}
@@ -4442,7 +4524,7 @@ status_t AudioFlinger::closeOutput(int output)
}
thread->exit();
- if (thread->type() != PlaybackThread::DUPLICATING) {
+ if (thread->type() != ThreadBase::DUPLICATING) {
AudioStreamOut *out = thread->getOutput();
out->hwDev->close_output_stream(out->hwDev, out->stream);
delete out;
@@ -4537,9 +4619,17 @@ int AudioFlinger::openInput(uint32_t *pDevices,
if (inStream != NULL) {
AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);
- int id = nextUniqueId_l();
- // Start record thread
- thread = new RecordThread(this, input, reqSamplingRate, reqChannels, id);
+ int id = nextUniqueId();
+ // Start record thread
+ // RecorThread require both input and output device indication to forward to audio
+ // pre processing modules
+ uint32_t device = (*pDevices) | primaryOutputDevice_l();
+ thread = new RecordThread(this,
+ input,
+ reqSamplingRate,
+ reqChannels,
+ id,
+ device);
mRecordThreads.add(id, thread);
LOGV("openInput() created record thread: ID %d thread %p", id, thread);
if (pSamplingRate) *pSamplingRate = reqSamplingRate;
@@ -4597,7 +4687,7 @@ status_t AudioFlinger::setStreamOutput(uint32_t stream, int output)
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
if (thread != dstThread &&
- thread->type() != PlaybackThread::DIRECT) {
+ thread->type() != ThreadBase::DIRECT) {
MixerThread *srcThread = (MixerThread *)thread;
srcThread->invalidateTracks(stream);
}
@@ -4609,8 +4699,7 @@ status_t AudioFlinger::setStreamOutput(uint32_t stream, int output)
int AudioFlinger::newAudioSessionId()
{
- AutoMutex _l(mLock);
- return nextUniqueId_l();
+ return nextUniqueId();
}
// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
@@ -4628,7 +4717,7 @@ AudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(int output) const
{
PlaybackThread *thread = checkPlaybackThread_l(output);
if (thread != NULL) {
- if (thread->type() == PlaybackThread::DIRECT) {
+ if (thread->type() == ThreadBase::DIRECT) {
thread = NULL;
}
}
@@ -4645,12 +4734,34 @@ AudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(int input) const
return thread;
}
-// nextUniqueId_l() must be called with AudioFlinger::mLock held
-int AudioFlinger::nextUniqueId_l()
+uint32_t AudioFlinger::nextUniqueId()
+{
+ return android_atomic_inc(&mNextUniqueId);
+}
+
+AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l()
{
- return mNextUniqueId++;
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+ PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
+ if (thread->getOutput()->hwDev == mPrimaryHardwareDev) {
+ return thread;
+ }
+ }
+ return NULL;
+}
+
+uint32_t AudioFlinger::primaryOutputDevice_l()
+{
+ PlaybackThread *thread = primaryPlaybackThread_l();
+
+ if (thread == NULL) {
+ return 0;
+ }
+
+ return thread->device();
}
+
// ----------------------------------------------------------------------------
// Effect management
// ----------------------------------------------------------------------------
@@ -4683,7 +4794,7 @@ sp<IEffect> AudioFlinger::createEffect(pid_t pid,
effect_descriptor_t *pDesc,
const sp<IEffectClient>& effectClient,
int32_t priority,
- int output,
+ int io,
int sessionId,
status_t *status,
int *id,
@@ -4695,8 +4806,8 @@ sp<IEffect> AudioFlinger::createEffect(pid_t pid,
sp<Client> client;
wp<Client> wclient;
- LOGV("createEffect pid %d, client %p, priority %d, sessionId %d, output %d",
- pid, effectClient.get(), priority, sessionId, output);
+ LOGV("createEffect pid %d, client %p, priority %d, sessionId %d, io %d",
+ pid, effectClient.get(), priority, sessionId, io);
if (pDesc == NULL) {
lStatus = BAD_VALUE;
@@ -4724,7 +4835,7 @@ sp<IEffect> AudioFlinger::createEffect(pid_t pid,
goto Exit;
}
- if (output == 0) {
+ if (io == 0) {
if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
// output must be specified by AudioPolicyManager when using session
// AUDIO_SESSION_OUTPUT_STAGE
@@ -4732,9 +4843,9 @@ sp<IEffect> AudioFlinger::createEffect(pid_t pid,
goto Exit;
} else if (sessionId == AUDIO_SESSION_OUTPUT_MIX) {
// if the output returned by getOutputForEffect() is removed before we lock the
- // mutex below, the call to checkPlaybackThread_l(output) below will detect it
+ // mutex below, the call to checkPlaybackThread_l(io) below will detect it
// and we will exit safely
- output = AudioSystem::getOutputForEffect(&desc);
+ io = AudioSystem::getOutputForEffect(&desc);
}
}
@@ -4811,31 +4922,41 @@ sp<IEffect> AudioFlinger::createEffect(pid_t pid,
// output threads.
// If output is 0 here, sessionId is neither SESSION_OUTPUT_STAGE nor SESSION_OUTPUT_MIX
// because of code checking output when entering the function.
- if (output == 0) {
+ // Note: io is never 0 when creating an effect on an input
+ if (io == 0) {
// look for the thread where the specified audio session is present
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
if (mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
- output = mPlaybackThreads.keyAt(i);
+ io = mPlaybackThreads.keyAt(i);
break;
}
}
+ if (io == 0) {
+ for (size_t i = 0; i < mRecordThreads.size(); i++) {
+ if (mRecordThreads.valueAt(i)->hasAudioSession(sessionId) != 0) {
+ io = mRecordThreads.keyAt(i);
+ break;
+ }
+ }
+ }
// If no output thread contains the requested session ID, default to
// first output. The effect chain will be moved to the correct output
// thread when a track with the same session ID is created
- if (output == 0 && mPlaybackThreads.size()) {
- output = mPlaybackThreads.keyAt(0);
+ if (io == 0 && mPlaybackThreads.size()) {
+ io = mPlaybackThreads.keyAt(0);
}
+ LOGV("createEffect() got io %d for effect %s", io, desc.name);
}
- LOGV("createEffect() got output %d for effect %s", output, desc.name);
- PlaybackThread *thread = checkPlaybackThread_l(output);
+ ThreadBase *thread = checkRecordThread_l(io);
if (thread == NULL) {
- LOGE("createEffect() unknown output thread");
- lStatus = BAD_VALUE;
- goto Exit;
+ thread = checkPlaybackThread_l(io);
+ if (thread == NULL) {
+ LOGE("createEffect() unknown output thread");
+ lStatus = BAD_VALUE;
+ goto Exit;
+ }
}
- // TODO: allow attachment of effect to inputs
-
wclient = mClients.valueFor(pid);
if (wclient != NULL) {
@@ -4943,8 +5064,9 @@ status_t AudioFlinger::moveEffectChain_l(int session,
return NO_ERROR;
}
+
// PlaybackThread::createEffect_l() must be called with AudioFlinger::mLock held
-sp<AudioFlinger::EffectHandle> AudioFlinger::PlaybackThread::createEffect_l(
+sp<AudioFlinger::EffectHandle> AudioFlinger::ThreadBase::createEffect_l(
const sp<AudioFlinger::Client>& client,
const sp<IEffectClient>& effectClient,
int32_t priority,
@@ -4957,24 +5079,14 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::PlaybackThread::createEffect_l(
sp<EffectModule> effect;
sp<EffectHandle> handle;
status_t lStatus;
- sp<Track> track;
sp<EffectChain> chain;
bool chainCreated = false;
bool effectCreated = false;
bool effectRegistered = false;
- if (mOutput == 0) {
+ lStatus = initCheck();
+ if (lStatus != NO_ERROR) {
LOGW("createEffect_l() Audio driver not initialized.");
- lStatus = NO_INIT;
- goto Exit;
- }
-
- // Do not allow auxiliary effect on session other than 0
- if ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY &&
- sessionId != AUDIO_SESSION_OUTPUT_MIX) {
- LOGW("createEffect_l() Cannot add auxiliary effect %s to session %d",
- desc->name, sessionId);
- lStatus = BAD_VALUE;
goto Exit;
}
@@ -4986,6 +5098,16 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::PlaybackThread::createEffect_l(
lStatus = BAD_VALUE;
goto Exit;
}
+ // Only Pre processor effects are allowed on input threads and only on input threads
+ if ((mType == RECORD &&
+ (desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC) ||
+ (mType != RECORD &&
+ (desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC)) {
+ LOGW("createEffect_l() effect %s (flags %08x) created on wrong thread type %d",
+ desc->name, desc->flags, mType);
+ lStatus = BAD_VALUE;
+ goto Exit;
+ }
LOGV("createEffect_l() thread %p effect %s on session %d", this, desc->name, sessionId);
@@ -5008,7 +5130,7 @@ sp<AudioFlinger::EffectHandle> AudioFlinger::PlaybackThread::createEffect_l(
LOGV("createEffect_l() got effect %p on chain %p", effect == 0 ? 0 : effect.get(), chain.get());
if (effect == 0) {
- int id = mAudioFlinger->nextUniqueId_l();
+ int id = mAudioFlinger->nextUniqueId();
// Check CPU and memory usage
lStatus = AudioSystem::registerEffect(desc, mId, chain->strategy(), sessionId, id);
if (lStatus != NO_ERROR) {
@@ -5059,9 +5181,20 @@ Exit:
return handle;
}
+sp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect_l(int sessionId, int effectId)
+{
+ sp<EffectModule> effect;
+
+ sp<EffectChain> chain = getEffectChain_l(sessionId);
+ if (chain != 0) {
+ effect = chain->getEffectFromId_l(effectId);
+ }
+ return effect;
+}
+
// PlaybackThread::addEffect_l() must be called with AudioFlinger::mLock and
// PlaybackThread::mLock held
-status_t AudioFlinger::PlaybackThread::addEffect_l(const sp<EffectModule>& effect)
+status_t AudioFlinger::ThreadBase::addEffect_l(const sp<EffectModule>& effect)
{
// check for existing effect chain with the requested audio session
int sessionId = effect->sessionId();
@@ -5097,7 +5230,7 @@ status_t AudioFlinger::PlaybackThread::addEffect_l(const sp<EffectModule>& effec
return NO_ERROR;
}
-void AudioFlinger::PlaybackThread::removeEffect_l(const sp<EffectModule>& effect) {
+void AudioFlinger::ThreadBase::removeEffect_l(const sp<EffectModule>& effect) {
LOGV("removeEffect_l() %p effect %p", this, effect.get());
effect_descriptor_t desc = effect->desc();
@@ -5116,7 +5249,53 @@ void AudioFlinger::PlaybackThread::removeEffect_l(const sp<EffectModule>& effect
}
}
-void AudioFlinger::PlaybackThread::disconnectEffect(const sp<EffectModule>& effect,
+void AudioFlinger::ThreadBase::lockEffectChains_l(
+ Vector<sp <AudioFlinger::EffectChain> >& effectChains)
+{
+ effectChains = mEffectChains;
+ for (size_t i = 0; i < mEffectChains.size(); i++) {
+ mEffectChains[i]->lock();
+ }
+}
+
+void AudioFlinger::ThreadBase::unlockEffectChains(
+ Vector<sp <AudioFlinger::EffectChain> >& effectChains)
+{
+ for (size_t i = 0; i < effectChains.size(); i++) {
+ effectChains[i]->unlock();
+ }
+}
+
+sp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain(int sessionId)
+{
+ Mutex::Autolock _l(mLock);
+ return getEffectChain_l(sessionId);
+}
+
+sp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain_l(int sessionId)
+{
+ sp<EffectChain> chain;
+
+ size_t size = mEffectChains.size();
+ for (size_t i = 0; i < size; i++) {
+ if (mEffectChains[i]->sessionId() == sessionId) {
+ chain = mEffectChains[i];
+ break;
+ }
+ }
+ return chain;
+}
+
+void AudioFlinger::ThreadBase::setMode(uint32_t mode)
+{
+ Mutex::Autolock _l(mLock);
+ size_t size = mEffectChains.size();
+ for (size_t i = 0; i < size; i++) {
+ mEffectChains[i]->setMode_l(mode);
+ }
+}
+
+void AudioFlinger::ThreadBase::disconnectEffect(const sp<EffectModule>& effect,
const wp<EffectHandle>& handle) {
Mutex::Autolock _l(mLock);
LOGV("disconnectEffect() %p effect %p", this, effect.get());
@@ -5222,35 +5401,6 @@ size_t AudioFlinger::PlaybackThread::removeEffectChain_l(const sp<EffectChain>&
return mEffectChains.size();
}
-void AudioFlinger::PlaybackThread::lockEffectChains_l(
- Vector<sp <AudioFlinger::EffectChain> >& effectChains)
-{
- effectChains = mEffectChains;
- for (size_t i = 0; i < mEffectChains.size(); i++) {
- mEffectChains[i]->lock();
- }
-}
-
-void AudioFlinger::PlaybackThread::unlockEffectChains(
- Vector<sp <AudioFlinger::EffectChain> >& effectChains)
-{
- for (size_t i = 0; i < effectChains.size(); i++) {
- effectChains[i]->unlock();
- }
-}
-
-
-sp<AudioFlinger::EffectModule> AudioFlinger::PlaybackThread::getEffect_l(int sessionId, int effectId)
-{
- sp<EffectModule> effect;
-
- sp<EffectChain> chain = getEffectChain_l(sessionId);
- if (chain != 0) {
- effect = chain->getEffectFromId_l(effectId);
- }
- return effect;
-}
-
status_t AudioFlinger::PlaybackThread::attachAuxEffect(
const sp<AudioFlinger::PlaybackThread::Track> track, int EffectId)
{
@@ -5291,6 +5441,34 @@ void AudioFlinger::PlaybackThread::detachAuxEffect_l(int effectId)
}
}
+status_t AudioFlinger::RecordThread::addEffectChain_l(const sp<EffectChain>& chain)
+{
+ // only one chain per input thread
+ if (mEffectChains.size() != 0) {
+ return INVALID_OPERATION;
+ }
+ LOGV("addEffectChain_l() %p on thread %p", chain.get(), this);
+
+ chain->setInBuffer(NULL);
+ chain->setOutBuffer(NULL);
+
+ mEffectChains.add(chain);
+
+ return NO_ERROR;
+}
+
+size_t AudioFlinger::RecordThread::removeEffectChain_l(const sp<EffectChain>& chain)
+{
+ LOGV("removeEffectChain_l() %p from thread %p", chain.get(), this);
+ LOGW_IF(mEffectChains.size() != 1,
+ "removeEffectChain_l() %p invalid chain size %d on thread %p",
+ chain.get(), mEffectChains.size(), this);
+ if (mEffectChains.size() == 1) {
+ mEffectChains.removeAt(0);
+ }
+ return 0;
+}
+
// ----------------------------------------------------------------------------
// EffectModule implementation
// ----------------------------------------------------------------------------
@@ -5312,12 +5490,11 @@ AudioFlinger::EffectModule::EffectModule(const wp<ThreadBase>& wThread,
if (thread == 0) {
return;
}
- PlaybackThread *p = (PlaybackThread *)thread.get();
memcpy(&mDescriptor, desc, sizeof(effect_descriptor_t));
// create effect engine from effect factory
- mStatus = EffectCreate(&desc->uuid, sessionId, p->id(), &mEffectInterface);
+ mStatus = EffectCreate(&desc->uuid, sessionId, thread->id(), &mEffectInterface);
if (mStatus != NO_ERROR) {
return;
@@ -5340,6 +5517,13 @@ AudioFlinger::EffectModule::~EffectModule()
{
LOGV("Destructor %p", this);
if (mEffectInterface != NULL) {
+ if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
+ (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread != 0) {
+ thread->stream()->remove_audio_effect(thread->stream(), mEffectInterface);
+ }
+ }
// release effect engine
EffectRelease(mEffectInterface);
}
@@ -5415,8 +5599,7 @@ void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle)
{
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
- playbackThread->disconnectEffect(keep, handle);
+ thread->disconnectEffect(keep, handle);
}
}
}
@@ -5626,6 +5809,14 @@ status_t AudioFlinger::EffectModule::start_l()
if (status == 0) {
status = cmdStatus;
}
+ if (status == 0 &&
+ ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
+ (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC)) {
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread != 0) {
+ thread->stream()->add_audio_effect(thread->stream(), mEffectInterface);
+ }
+ }
return status;
}
@@ -5645,6 +5836,14 @@ status_t AudioFlinger::EffectModule::stop_l()
if (status == 0) {
status = cmdStatus;
}
+ if (status == 0 &&
+ ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
+ (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC)) {
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread != 0) {
+ thread->stream()->remove_audio_effect(thread->stream(), mEffectInterface);
+ }
+ }
return status;
}
@@ -5784,17 +5983,41 @@ status_t AudioFlinger::EffectModule::setDevice(uint32_t device)
{
Mutex::Autolock _l(mLock);
status_t status = NO_ERROR;
- if ((mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
- status_t cmdStatus;
- uint32_t size = sizeof(status_t);
- status = (*mEffectInterface)->command(mEffectInterface,
- EFFECT_CMD_SET_DEVICE,
- sizeof(uint32_t),
- &device,
- &size,
- &cmdStatus);
- if (status == NO_ERROR) {
- status = cmdStatus;
+ if (device && (mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
+ // audio pre processing modules on RecordThread can receive both output and
+ // input device indication in the same call
+ uint32_t dev = device & AUDIO_DEVICE_OUT_ALL;
+ if (dev) {
+ status_t cmdStatus;
+ uint32_t size = sizeof(status_t);
+
+ status = (*mEffectInterface)->command(mEffectInterface,
+ EFFECT_CMD_SET_DEVICE,
+ sizeof(uint32_t),
+ &dev,
+ &size,
+ &cmdStatus);
+ if (status == NO_ERROR) {
+ status = cmdStatus;
+ }
+ }
+ dev = device & AUDIO_DEVICE_IN_ALL;
+ if (dev) {
+ status_t cmdStatus;
+ uint32_t size = sizeof(status_t);
+
+ status_t status2 = (*mEffectInterface)->command(mEffectInterface,
+ EFFECT_CMD_SET_INPUT_DEVICE,
+ sizeof(uint32_t),
+ &dev,
+ &size,
+ &cmdStatus);
+ if (status2 == NO_ERROR) {
+ status2 = cmdStatus;
+ }
+ if (status == NO_ERROR) {
+ status = status2;
+ }
}
}
return status;
@@ -6168,7 +6391,6 @@ void AudioFlinger::EffectChain::process_l()
LOGW("process_l(): cannot promote mixer thread");
return;
}
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
bool isGlobalSession = (mSessionId == AUDIO_SESSION_OUTPUT_MIX) ||
(mSessionId == AUDIO_SESSION_OUTPUT_STAGE);
bool tracksOnSession = false;
@@ -6180,7 +6402,7 @@ void AudioFlinger::EffectChain::process_l()
// will not do it
if (tracksOnSession &&
activeTrackCnt() == 0) {
- size_t numSamples = playbackThread->frameCount() * playbackThread->channelCount();
+ size_t numSamples = thread->frameCount() * thread->channelCount();
memset(mInBuffer, 0, numSamples * sizeof(int16_t));
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 1fad9874fbaf..fff4f06ace47 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -157,7 +157,7 @@ public:
effect_descriptor_t *pDesc,
const sp<IEffectClient>& effectClient,
int32_t priority,
- int output,
+ int io,
int sessionId,
status_t *status,
int *id,
@@ -273,9 +273,17 @@ private:
class ThreadBase : public Thread {
public:
- ThreadBase (const sp<AudioFlinger>& audioFlinger, int id);
+ ThreadBase (const sp<AudioFlinger>& audioFlinger, int id, uint32_t device);
virtual ~ThreadBase();
+
+ enum type {
+ MIXER, // Thread class is MixerThread
+ DIRECT, // Thread class is DirectOutputThread
+ DUPLICATING, // Thread class is DuplicatingThread
+ RECORD // Thread class is RecordThread
+ };
+
status_t dumpBase(int fd, const Vector<String16>& args);
// base for record and playback
@@ -377,6 +385,8 @@ private:
int mParam;
};
+ virtual status_t initCheck() const = 0;
+ int type() const { return mType; }
uint32_t sampleRate() const;
int channelCount() const;
uint32_t format() const;
@@ -392,6 +402,60 @@ private:
void processConfigEvents();
int id() const { return mId;}
bool standby() { return mStandby; }
+ uint32_t device() { return mDevice; }
+ virtual audio_stream_t* stream() = 0;
+
+ sp<EffectHandle> createEffect_l(
+ const sp<AudioFlinger::Client>& client,
+ const sp<IEffectClient>& effectClient,
+ int32_t priority,
+ int sessionId,
+ effect_descriptor_t *desc,
+ int *enabled,
+ status_t *status);
+ void disconnectEffect(const sp< EffectModule>& effect,
+ const wp<EffectHandle>& handle);
+
+ // return values for hasAudioSession (bit field)
+ enum effect_state {
+ EFFECT_SESSION = 0x1, // the audio session corresponds to at least one
+ // effect
+ TRACK_SESSION = 0x2 // the audio session corresponds to at least one
+ // track
+ };
+
+ // get effect chain corresponding to session Id.
+ sp<EffectChain> getEffectChain(int sessionId);
+ // same as getEffectChain() but must be called with ThreadBase mutex locked
+ sp<EffectChain> getEffectChain_l(int sessionId);
+ // add an effect chain to the chain list (mEffectChains)
+ virtual status_t addEffectChain_l(const sp<EffectChain>& chain) = 0;
+ // remove an effect chain from the chain list (mEffectChains)
+ virtual size_t removeEffectChain_l(const sp<EffectChain>& chain) = 0;
+ // lock mall effect chains Mutexes. Must be called before releasing the
+ // ThreadBase mutex before processing the mixer and effects. This guarantees the
+ // integrity of the chains during the process.
+ void lockEffectChains_l(Vector<sp <EffectChain> >& effectChains);
+ // unlock effect chains after process
+ void unlockEffectChains(Vector<sp <EffectChain> >& effectChains);
+ // set audio mode to all effect chains
+ void setMode(uint32_t mode);
+ // get effect module with corresponding ID on specified audio session
+ sp<AudioFlinger::EffectModule> getEffect_l(int sessionId, int effectId);
+ // add and effect module. Also creates the effect chain is none exists for
+ // the effects audio session
+ status_t addEffect_l(const sp< EffectModule>& effect);
+ // remove and effect module. Also removes the effect chain is this was the last
+ // effect
+ void removeEffect_l(const sp< EffectModule>& effect);
+ // detach all tracks connected to an auxiliary effect
+ virtual void detachAuxEffect_l(int effectId) {}
+ // returns either EFFECT_SESSION if effects on this audio session exist in one
+ // chain, or TRACK_SESSION if tracks on this audio session exist, or both
+ virtual uint32_t hasAudioSession(int sessionId) = 0;
+ // the value returned by default implementation is not important as the
+ // strategy is only meaningful for PlaybackThread which implements this method
+ virtual uint32_t getStrategyForSession_l(int sessionId) { return 0; }
mutable Mutex mLock;
@@ -406,6 +470,7 @@ private:
friend class RecordThread;
friend class RecordTrack;
+ int mType;
Condition mWaitWorkCV;
sp<AudioFlinger> mAudioFlinger;
uint32_t mSampleRate;
@@ -421,18 +486,15 @@ private:
bool mStandby;
int mId;
bool mExiting;
+ Vector< sp<EffectChain> > mEffectChains;
+ uint32_t mDevice; // output device for PlaybackThread
+ // input + output devices for RecordThread
};
// --- PlaybackThread ---
class PlaybackThread : public ThreadBase {
public:
- enum type {
- MIXER,
- DIRECT,
- DUPLICATING
- };
-
enum mixer_state {
MIXER_IDLE,
MIXER_TRACKS_ENABLED,
@@ -569,6 +631,8 @@ private:
virtual status_t readyToRun();
virtual void onFirstRef();
+ virtual status_t initCheck() const { return (mOutput == 0) ? NO_INIT : NO_ERROR; }
+
virtual uint32_t latency() const;
virtual status_t setMasterVolume(float value);
@@ -595,8 +659,8 @@ private:
status_t *status);
AudioStreamOut* getOutput() { return mOutput; }
+ virtual audio_stream_t* stream() { return &mOutput->stream->common; }
- virtual int type() const { return mType; }
void suspend() { mSuspended++; }
void restore() { if (mSuspended) mSuspended--; }
bool isSuspended() { return (mSuspended != 0); }
@@ -605,45 +669,16 @@ private:
virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
int16_t *mixBuffer() { return mMixBuffer; };
- sp<EffectHandle> createEffect_l(
- const sp<AudioFlinger::Client>& client,
- const sp<IEffectClient>& effectClient,
- int32_t priority,
- int sessionId,
- effect_descriptor_t *desc,
- int *enabled,
- status_t *status);
- void disconnectEffect(const sp< EffectModule>& effect,
- const wp<EffectHandle>& handle);
-
- // return values for hasAudioSession (bit field)
- enum effect_state {
- EFFECT_SESSION = 0x1, // the audio session corresponds to at least one
- // effect
- TRACK_SESSION = 0x2 // the audio session corresponds to at least one
- // track
- };
-
- uint32_t hasAudioSession(int sessionId);
- sp<EffectChain> getEffectChain(int sessionId);
- sp<EffectChain> getEffectChain_l(int sessionId);
- status_t addEffectChain_l(const sp<EffectChain>& chain);
- size_t removeEffectChain_l(const sp<EffectChain>& chain);
- void lockEffectChains_l(Vector<sp <EffectChain> >& effectChains);
- void unlockEffectChains(Vector<sp <EffectChain> >& effectChains);
-
- sp<AudioFlinger::EffectModule> getEffect_l(int sessionId, int effectId);
- void detachAuxEffect_l(int effectId);
+ virtual void detachAuxEffect_l(int effectId);
status_t attachAuxEffect(const sp<AudioFlinger::PlaybackThread::Track> track,
int EffectId);
status_t attachAuxEffect_l(const sp<AudioFlinger::PlaybackThread::Track> track,
int EffectId);
- void setMode(uint32_t mode);
- status_t addEffect_l(const sp< EffectModule>& effect);
- void removeEffect_l(const sp< EffectModule>& effect);
-
- uint32_t getStrategyForSession_l(int sessionId);
+ virtual status_t addEffectChain_l(const sp<EffectChain>& chain);
+ virtual size_t removeEffectChain_l(const sp<EffectChain>& chain);
+ virtual uint32_t hasAudioSession(int sessionId);
+ virtual uint32_t getStrategyForSession_l(int sessionId);
struct stream_type_t {
stream_type_t()
@@ -656,7 +691,6 @@ private:
};
protected:
- int mType;
int16_t* mMixBuffer;
int mSuspended;
int mBytesWritten;
@@ -688,8 +722,6 @@ private:
void readOutputParameters();
- uint32_t device() { return mDevice; }
-
virtual status_t dumpInternals(int fd, const Vector<String16>& args);
status_t dumpTracks(int fd, const Vector<String16>& args);
status_t dumpEffectChains(int fd, const Vector<String16>& args);
@@ -703,8 +735,6 @@ private:
int mNumWrites;
int mNumDelayedWrites;
bool mInWrite;
- Vector< sp<EffectChain> > mEffectChains;
- uint32_t mDevice;
};
class MixerThread : public PlaybackThread {
@@ -788,11 +818,13 @@ private:
float streamVolumeInternal(int stream) const { return mStreamTypes[stream].volume; }
void audioConfigChanged_l(int event, int ioHandle, void *param2);
- int nextUniqueId_l();
+ uint32_t nextUniqueId();
status_t moveEffectChain_l(int session,
AudioFlinger::PlaybackThread *srcThread,
AudioFlinger::PlaybackThread *dstThread,
bool reRegister);
+ PlaybackThread *primaryPlaybackThread_l();
+ uint32_t primaryOutputDevice_l();
friend class AudioBuffer;
@@ -864,18 +896,33 @@ private:
AudioStreamIn *input,
uint32_t sampleRate,
uint32_t channels,
- int id);
+ int id,
+ uint32_t device);
~RecordThread();
virtual bool threadLoop();
virtual status_t readyToRun() { return NO_ERROR; }
virtual void onFirstRef();
+ virtual status_t initCheck() const { return (mInput == 0) ? NO_INIT : NO_ERROR; }
+ sp<AudioFlinger::RecordThread::RecordTrack> createRecordTrack_l(
+ const sp<AudioFlinger::Client>& client,
+ uint32_t sampleRate,
+ int format,
+ int channelMask,
+ int frameCount,
+ uint32_t flags,
+ int sessionId,
+ status_t *status);
+
status_t start(RecordTrack* recordTrack);
void stop(RecordTrack* recordTrack);
status_t dump(int fd, const Vector<String16>& args);
AudioStreamIn* getInput() { return mInput; }
+ virtual audio_stream_t* stream() { return &mInput->stream->common; }
+
+ void setTrack(RecordTrack *recordTrack) { mTrack = recordTrack; }
virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
virtual bool checkForNewParameters_l();
@@ -884,9 +931,14 @@ private:
void readInputParameters();
virtual unsigned int getInputFramesLost();
+ virtual status_t addEffectChain_l(const sp<EffectChain>& chain);
+ virtual size_t removeEffectChain_l(const sp<EffectChain>& chain);
+ virtual uint32_t hasAudioSession(int sessionId);
+
private:
RecordThread();
AudioStreamIn *mInput;
+ RecordTrack* mTrack;
sp<RecordTrack> mActiveTrack;
Condition mStartStopCond;
AudioResampler *mResampler;
@@ -1103,9 +1155,8 @@ private:
status_t addEffect_l(const sp<EffectModule>& handle);
size_t removeEffect_l(const sp<EffectModule>& handle);
- int sessionId() {
- return mSessionId;
- }
+ int sessionId() { return mSessionId; }
+ void setSessionId(int sessionId) { mSessionId = sessionId; }
sp<EffectModule> getEffectFromDesc_l(effect_descriptor_t *descriptor);
sp<EffectModule> getEffectFromId_l(int id);
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 8e16d944356d..dd1e153621c7 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -33,11 +33,14 @@
#include <cutils/properties.h>
#include <dlfcn.h>
#include <hardware_legacy/power.h>
+#include <media/AudioEffect.h>
+#include <media/EffectsFactoryApi.h>
#include <hardware/hardware.h>
#include <system/audio.h>
#include <system/audio_policy.h>
#include <hardware/audio_policy.h>
+#include <audio_effects/audio_effects_conf.h>
namespace android {
@@ -101,6 +104,13 @@ AudioPolicyService::AudioPolicyService()
mpAudioPolicy->set_can_mute_enforced_audible(mpAudioPolicy, !forced_val);
LOGI("Loaded audio policy from %s (%s)", module->name, module->id);
+
+ // load audio pre processing modules
+ if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
+ loadPreProcessorConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
+ } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
+ loadPreProcessorConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
+ }
}
AudioPolicyService::~AudioPolicyService()
@@ -110,6 +120,31 @@ AudioPolicyService::~AudioPolicyService()
mAudioCommandThread->exit();
mAudioCommandThread.clear();
+
+ // release audio pre processing resources
+ for (size_t i = 0; i < mInputSources.size(); i++) {
+ InputSourceDesc *source = mInputSources.valueAt(i);
+ Vector <EffectDesc *> effects = source->mEffects;
+ for (size_t j = 0; j < effects.size(); j++) {
+ delete effects[j]->mName;
+ Vector <effect_param_t *> params = effects[j]->mParams;
+ for (size_t k = 0; k < params.size(); k++) {
+ delete params[k];
+ }
+ params.clear();
+ delete effects[j];
+ }
+ effects.clear();
+ delete source;
+ }
+ mInputSources.clear();
+
+ for (size_t i = 0; i < mInputs.size(); i++) {
+ mInputs.valueAt(i)->mEffects.clear();
+ delete mInputs.valueAt(i);
+ }
+ mInputs.clear();
+
if (mpAudioPolicy && mpAudioPolicyDev)
mpAudioPolicyDev->destroy_audio_policy(mpAudioPolicyDev, mpAudioPolicy);
if (mpAudioPolicyDev)
@@ -276,13 +311,51 @@ audio_io_handle_t AudioPolicyService::getInput(int inputSource,
uint32_t samplingRate,
uint32_t format,
uint32_t channels,
- audio_in_acoustics_t acoustics)
+ audio_in_acoustics_t acoustics,
+ int audioSession)
{
if (mpAudioPolicy == NULL) {
return 0;
}
Mutex::Autolock _l(mLock);
- return mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate, format, channels, acoustics);
+ audio_io_handle_t input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
+ format, channels, acoustics);
+
+ if (input == 0) {
+ return input;
+ }
+ // create audio pre processors according to input source
+ ssize_t index = mInputSources.indexOfKey((audio_source_t)inputSource);
+ if (index < 0) {
+ return input;
+ }
+ ssize_t idx = mInputs.indexOfKey(input);
+ InputDesc *inputDesc;
+ if (idx < 0) {
+ inputDesc = new InputDesc();
+ inputDesc->mSessionId = audioSession;
+ mInputs.add(input, inputDesc);
+ } else {
+ inputDesc = mInputs.valueAt(idx);
+ }
+
+ Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
+ for (size_t i = 0; i < effects.size(); i++) {
+ EffectDesc *effect = effects[i];
+ sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0, audioSession, input);
+ status_t status = fx->initCheck();
+ if (status != NO_ERROR && status != ALREADY_EXISTS) {
+ LOGW("Failed to create Fx %s on input %d", effect->mName, input);
+ // fx goes out of scope and strong ref on AudioEffect is released
+ continue;
+ }
+ for (size_t j = 0; j < effect->mParams.size(); j++) {
+ fx->setParameter(effect->mParams[j]);
+ }
+ inputDesc->mEffects.add(fx);
+ }
+ setPreProcessorEnabled(inputDesc, true);
+ return input;
}
status_t AudioPolicyService::startInput(audio_io_handle_t input)
@@ -291,6 +364,7 @@ status_t AudioPolicyService::startInput(audio_io_handle_t input)
return NO_INIT;
}
Mutex::Autolock _l(mLock);
+
return mpAudioPolicy->start_input(mpAudioPolicy, input);
}
@@ -300,6 +374,7 @@ status_t AudioPolicyService::stopInput(audio_io_handle_t input)
return NO_INIT;
}
Mutex::Autolock _l(mLock);
+
return mpAudioPolicy->stop_input(mpAudioPolicy, input);
}
@@ -310,6 +385,16 @@ void AudioPolicyService::releaseInput(audio_io_handle_t input)
}
Mutex::Autolock _l(mLock);
mpAudioPolicy->release_input(mpAudioPolicy, input);
+
+ ssize_t index = mInputs.indexOfKey(input);
+ if (index < 0) {
+ return;
+ }
+ InputDesc *inputDesc = mInputs.valueAt(index);
+ setPreProcessorEnabled(inputDesc, false);
+ inputDesc->mEffects.clear();
+ delete inputDesc;
+ mInputs.removeItemsAt(index);
}
status_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,
@@ -384,7 +469,7 @@ audio_io_handle_t AudioPolicyService::getOutputForEffect(effect_descriptor_t *de
}
status_t AudioPolicyService::registerEffect(effect_descriptor_t *desc,
- audio_io_handle_t output,
+ audio_io_handle_t io,
uint32_t strategy,
int session,
int id)
@@ -392,7 +477,7 @@ status_t AudioPolicyService::registerEffect(effect_descriptor_t *desc,
if (mpAudioPolicy == NULL) {
return NO_INIT;
}
- return mpAudioPolicy->register_effect(mpAudioPolicy, desc, output, strategy, session, id);
+ return mpAudioPolicy->register_effect(mpAudioPolicy, desc, io, strategy, session, id);
}
status_t AudioPolicyService::unregisterEffect(int id)
@@ -489,6 +574,15 @@ status_t AudioPolicyService::dumpPermissionDenial(int fd)
return NO_ERROR;
}
+void AudioPolicyService::setPreProcessorEnabled(InputDesc *inputDesc, bool enabled)
+{
+ Vector<sp<AudioEffect> > fxVector = inputDesc->mEffects;
+ for (size_t i = 0; i < fxVector.size(); i++) {
+ sp<AudioEffect> fx = fxVector.itemAt(i);
+ fx->setEnabled(enabled);
+ }
+}
+
status_t AudioPolicyService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
@@ -918,6 +1012,300 @@ int AudioPolicyService::setVoiceVolume(float volume, int delayMs)
return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
}
+// ----------------------------------------------------------------------------
+// Audio pre-processing configuration
+// ----------------------------------------------------------------------------
+
+const char *AudioPolicyService::kInputSourceNames[AUDIO_SOURCE_CNT -1] = {
+ MIC_SRC_TAG,
+ VOICE_UL_SRC_TAG,
+ VOICE_DL_SRC_TAG,
+ VOICE_CALL_SRC_TAG,
+ CAMCORDER_SRC_TAG,
+ VOICE_REC_SRC_TAG,
+ VOICE_COMM_SRC_TAG
+};
+
+// returns the audio_source_t enum corresponding to the input source name or
+// AUDIO_SOURCE_CNT is no match found
+audio_source_t AudioPolicyService::inputSourceNameToEnum(const char *name)
+{
+ int i;
+ for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) {
+ if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) {
+ LOGV("inputSourceNameToEnum found source %s %d", name, i);
+ break;
+ }
+ }
+ return (audio_source_t)i;
+}
+
+size_t AudioPolicyService::growParamSize(char *param,
+ size_t size,
+ size_t *curSize,
+ size_t *totSize)
+{
+ // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int)
+ size_t pos = ((*curSize - 1 ) / size + 1) * size;
+
+ if (pos + size > *totSize) {
+ while (pos + size > *totSize) {
+ *totSize += ((*totSize + 7) / 8) * 4;
+ }
+ param = (char *)realloc(param, *totSize);
+ }
+ *curSize = pos + size;
+ return pos;
+}
+
+size_t AudioPolicyService::readParamValue(cnode *node,
+ char *param,
+ size_t *curSize,
+ size_t *totSize)
+{
+ if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) {
+ size_t pos = growParamSize(param, sizeof(short), curSize, totSize);
+ *(short *)((char *)param + pos) = (short)atoi(node->value);
+ LOGV("readParamValue() reading short %d", *(short *)((char *)param + pos));
+ return sizeof(short);
+ } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) {
+ size_t pos = growParamSize(param, sizeof(int), curSize, totSize);
+ *(int *)((char *)param + pos) = atoi(node->value);
+ LOGV("readParamValue() reading int %d", *(int *)((char *)param + pos));
+ return sizeof(int);
+ } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) {
+ size_t pos = growParamSize(param, sizeof(float), curSize, totSize);
+ *(float *)((char *)param + pos) = (float)atof(node->value);
+ LOGV("readParamValue() reading float %f",*(float *)((char *)param + pos));
+ return sizeof(float);
+ } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) {
+ size_t pos = growParamSize(param, sizeof(bool), curSize, totSize);
+ if (strncmp(node->value, "false", strlen("false") + 1) == 0) {
+ *(bool *)((char *)param + pos) = false;
+ } else {
+ *(bool *)((char *)param + pos) = true;
+ }
+ LOGV("readParamValue() reading bool %s",*(bool *)((char *)param + pos) ? "true" : "false");
+ return sizeof(bool);
+ } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) {
+ size_t len = strnlen(node->value, EFFECT_STRING_LEN_MAX);
+ if (*curSize + len + 1 > *totSize) {
+ *totSize = *curSize + len + 1;
+ param = (char *)realloc(param, *totSize);
+ }
+ strncpy(param + *curSize, node->value, len);
+ *curSize += len;
+ param[*curSize] = '\0';
+ LOGV("readParamValue() reading string %s", param + *curSize - len);
+ return len;
+ }
+ LOGW("readParamValue() unknown param type %s", node->name);
+ return 0;
+}
+
+effect_param_t *AudioPolicyService::loadEffectParameter(cnode *root)
+{
+ cnode *param;
+ cnode *value;
+ size_t curSize = sizeof(effect_param_t);
+ size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int);
+ effect_param_t *fx_param = (effect_param_t *)malloc(totSize);
+
+ param = config_find(root, PARAM_TAG);
+ value = config_find(root, VALUE_TAG);
+ if (param == NULL && value == NULL) {
+ // try to parse simple parameter form {int int}
+ param = root->first_child;
+ if (param) {
+ // Note: that a pair of random strings is read as 0 0
+ int *ptr = (int *)fx_param->data;
+ int *ptr2 = (int *)((char *)param + sizeof(effect_param_t));
+ LOGW("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2);
+ *ptr++ = atoi(param->name);
+ *ptr = atoi(param->value);
+ fx_param->psize = sizeof(int);
+ fx_param->vsize = sizeof(int);
+ return fx_param;
+ }
+ }
+ if (param == NULL || value == NULL) {
+ LOGW("loadEffectParameter() invalid parameter description %s", root->name);
+ goto error;
+ }
+
+ fx_param->psize = 0;
+ param = param->first_child;
+ while (param) {
+ LOGV("loadEffectParameter() reading param of type %s", param->name);
+ size_t size = readParamValue(param, (char *)fx_param, &curSize, &totSize);
+ if (size == 0) {
+ goto error;
+ }
+ fx_param->psize += size;
+ param = param->next;
+ }
+
+ // align start of value field on 32 bit boundary
+ curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int);
+
+ fx_param->vsize = 0;
+ value = value->first_child;
+ while (value) {
+ LOGV("loadEffectParameter() reading value of type %s", value->name);
+ size_t size = readParamValue(value, (char *)fx_param, &curSize, &totSize);
+ if (size == 0) {
+ goto error;
+ }
+ fx_param->vsize += size;
+ value = value->next;
+ }
+
+ return fx_param;
+
+error:
+ delete fx_param;
+ return NULL;
+}
+
+void AudioPolicyService::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params)
+{
+ cnode *node = root->first_child;
+ while (node) {
+ LOGV("loadEffectParameters() loading param %s", node->name);
+ effect_param_t *param = loadEffectParameter(node);
+ if (param == NULL) {
+ node = node->next;
+ continue;
+ }
+ params.add(param);
+ node = node->next;
+ }
+}
+
+AudioPolicyService::InputSourceDesc *AudioPolicyService::loadInputSource(
+ cnode *root,
+ const Vector <EffectDesc *>& effects)
+{
+ cnode *node = root->first_child;
+ if (node == NULL) {
+ LOGW("loadInputSource() empty element %s", root->name);
+ return NULL;
+ }
+ InputSourceDesc *source = new InputSourceDesc();
+ while (node) {
+ size_t i;
+ for (i = 0; i < effects.size(); i++) {
+ if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) {
+ LOGV("loadInputSource() found effect %s in list", node->name);
+ break;
+ }
+ }
+ if (i == effects.size()) {
+ LOGV("loadInputSource() effect %s not in list", node->name);
+ node = node->next;
+ continue;
+ }
+ EffectDesc *effect = new EffectDesc(*effects[i]);
+ loadEffectParameters(node, effect->mParams);
+ LOGV("loadInputSource() adding effect %s uuid %08x", effect->mName, effect->mUuid.timeLow);
+ source->mEffects.add(effect);
+ node = node->next;
+ }
+ if (source->mEffects.size() == 0) {
+ LOGW("loadInputSource() no valid effects found in source %s", root->name);
+ delete source;
+ return NULL;
+ }
+ return source;
+}
+
+status_t AudioPolicyService::loadInputSources(cnode *root, const Vector <EffectDesc *>& effects)
+{
+ cnode *node = config_find(root, PREPROCESSING_TAG);
+ if (node == NULL) {
+ return -ENOENT;
+ }
+ node = node->first_child;
+ while (node) {
+ audio_source_t source = inputSourceNameToEnum(node->name);
+ if (source == AUDIO_SOURCE_CNT) {
+ LOGW("loadInputSources() invalid input source %s", node->name);
+ node = node->next;
+ continue;
+ }
+ LOGV("loadInputSources() loading input source %s", node->name);
+ InputSourceDesc *desc = loadInputSource(node, effects);
+ if (desc == NULL) {
+ node = node->next;
+ continue;
+ }
+ mInputSources.add(source, desc);
+ node = node->next;
+ }
+ return NO_ERROR;
+}
+
+AudioPolicyService::EffectDesc *AudioPolicyService::loadEffect(cnode *root)
+{
+ cnode *node = config_find(root, UUID_TAG);
+ if (node == NULL) {
+ return NULL;
+ }
+ effect_uuid_t uuid;
+ if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) {
+ LOGW("loadEffect() invalid uuid %s", node->value);
+ return NULL;
+ }
+ EffectDesc *effect = new EffectDesc();
+ effect->mName = strdup(root->name);
+ memcpy(&effect->mUuid, &uuid, sizeof(effect_uuid_t));
+
+ return effect;
+}
+
+status_t AudioPolicyService::loadEffects(cnode *root, Vector <EffectDesc *>& effects)
+{
+ cnode *node = config_find(root, EFFECTS_TAG);
+ if (node == NULL) {
+ return -ENOENT;
+ }
+ node = node->first_child;
+ while (node) {
+ LOGV("loadEffects() loading effect %s", node->name);
+ EffectDesc *effect = loadEffect(node);
+ if (effect == NULL) {
+ node = node->next;
+ continue;
+ }
+ effects.add(effect);
+ node = node->next;
+ }
+ return NO_ERROR;
+}
+
+status_t AudioPolicyService::loadPreProcessorConfig(const char *path)
+{
+ cnode *root;
+ char *data;
+
+ data = (char *)load_file(path, NULL);
+ if (data == NULL) {
+ return -ENODEV;
+ }
+ root = config_node("", "");
+ config_load(root, data);
+
+ Vector <EffectDesc *> effects;
+ loadEffects(root, effects);
+ loadInputSources(root, effects);
+
+ config_free(root);
+ free(root);
+ free(data);
+
+ return NO_ERROR;
+}
+
/* implementation of the interface to the policy manager */
extern "C" {
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index b8301209cd2a..62ad29ee5219 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -17,14 +17,17 @@
#ifndef ANDROID_AUDIOPOLICYSERVICE_H
#define ANDROID_AUDIOPOLICYSERVICE_H
-#include <media/IAudioPolicyService.h>
-#include <media/ToneGenerator.h>
+#include <cutils/misc.h>
+#include <cutils/config_utils.h>
#include <utils/Vector.h>
+#include <utils/SortedVector.h>
#include <binder/BinderService.h>
-
#include <system/audio.h>
#include <system/audio_policy.h>
#include <hardware/audio_policy.h>
+#include <media/IAudioPolicyService.h>
+#include <media/ToneGenerator.h>
+#include <media/AudioEffect.h>
namespace android {
@@ -78,7 +81,8 @@ public:
uint32_t format = AUDIO_FORMAT_DEFAULT,
uint32_t channels = 0,
audio_in_acoustics_t acoustics =
- (audio_in_acoustics_t)0);
+ (audio_in_acoustics_t)0,
+ int audioSession = 0);
virtual status_t startInput(audio_io_handle_t input);
virtual status_t stopInput(audio_io_handle_t input);
virtual void releaseInput(audio_io_handle_t input);
@@ -93,7 +97,7 @@ public:
virtual audio_io_handle_t getOutputForEffect(effect_descriptor_t *desc);
virtual status_t registerEffect(effect_descriptor_t *desc,
- audio_io_handle_t output,
+ audio_io_handle_t io,
uint32_t strategy,
int session,
int id);
@@ -218,6 +222,51 @@ private:
String8 mName; // string used by wake lock fo delayed commands
};
+ class EffectDesc {
+ public:
+ EffectDesc() {}
+ virtual ~EffectDesc() {}
+ char *mName;
+ effect_uuid_t mUuid;
+ Vector <effect_param_t *> mParams;
+ };
+
+ class InputSourceDesc {
+ public:
+ InputSourceDesc() {}
+ virtual ~InputSourceDesc() {}
+ Vector <EffectDesc *> mEffects;
+ };
+
+
+ class InputDesc {
+ public:
+ InputDesc() {}
+ virtual ~InputDesc() {}
+ int mSessionId;
+ Vector< sp<AudioEffect> >mEffects;
+ };
+
+ static const char *kInputSourceNames[AUDIO_SOURCE_CNT -1];
+
+ void setPreProcessorEnabled(InputDesc *inputDesc, bool enabled);
+ status_t loadPreProcessorConfig(const char *path);
+ status_t loadEffects(cnode *root, Vector <EffectDesc *>& effects);
+ EffectDesc *loadEffect(cnode *root);
+ status_t loadInputSources(cnode *root, const Vector <EffectDesc *>& effects);
+ audio_source_t inputSourceNameToEnum(const char *name);
+ InputSourceDesc *loadInputSource(cnode *root, const Vector <EffectDesc *>& effects);
+ void loadEffectParameters(cnode *root, Vector <effect_param_t *>& params);
+ effect_param_t *loadEffectParameter(cnode *root);
+ size_t readParamValue(cnode *node,
+ char *param,
+ size_t *curSize,
+ size_t *totSize);
+ size_t growParamSize(char *param,
+ size_t size,
+ size_t *curSize,
+ size_t *totSize);
+
// Internal dump utilities.
status_t dumpPermissionDenial(int fd);
@@ -226,9 +275,10 @@ private:
// device connection state or routing
sp <AudioCommandThread> mAudioCommandThread; // audio commands thread
sp <AudioCommandThread> mTonePlaybackThread; // tone playback thread
-
struct audio_policy_device *mpAudioPolicyDev;
struct audio_policy *mpAudioPolicy;
+ KeyedVector< audio_source_t, InputSourceDesc* > mInputSources;
+ KeyedVector< audio_io_handle_t, InputDesc* > mInputs;
};
}; // namespace android
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 1cac502562be..039b00356800 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -215,14 +215,6 @@ InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& polic
mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
mLooper = new Looper(false);
- mInboundQueue.headSentinel.refCount = -1;
- mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
- mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
-
- mInboundQueue.tailSentinel.refCount = -1;
- mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
- mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
-
mKeyRepeatState.lastKeyEntry = NULL;
policy->getDispatcherConfiguration(&mConfig);
@@ -319,7 +311,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
}
} else {
// Inbound queue has at least one entry.
- EventEntry* entry = mInboundQueue.headSentinel.next;
+ EventEntry* entry = mInboundQueue.head;
// Throttle the entry if it is a move event and there are no
// other events behind it in the queue. Due to movement batching, additional
@@ -335,7 +327,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
int32_t deviceId = motionEntry->deviceId;
uint32_t source = motionEntry->source;
if (! isAppSwitchDue
- && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
+ && !motionEntry->next // exactly one event, no successors
&& (motionEntry->action == AMOTION_EVENT_ACTION_MOVE
|| motionEntry->action == AMOTION_EVENT_ACTION_HOVER_MOVE)
&& deviceId == mThrottleState.lastDeviceId
@@ -641,13 +633,13 @@ bool InputDispatcher::runCommandsLockedInterruptible() {
(this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
commandEntry->connection.clear();
- mAllocator.releaseCommandEntry(commandEntry);
+ delete commandEntry;
} while (! mCommandQueue.isEmpty());
return true;
}
InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
- CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
+ CommandEntry* commandEntry = new CommandEntry(command);
mCommandQueue.enqueueAtTail(commandEntry);
return commandEntry;
}
@@ -674,12 +666,12 @@ void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
#endif
setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
}
- mAllocator.releaseEventEntry(entry);
+ entry->release();
}
void InputDispatcher::resetKeyRepeatLocked() {
if (mKeyRepeatState.lastKeyEntry) {
- mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
+ mKeyRepeatState.lastKeyEntry->release();
mKeyRepeatState.lastKeyEntry = NULL;
}
}
@@ -691,18 +683,18 @@ InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t cu
uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
| POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
if (entry->refCount == 1) {
- mAllocator.recycleKeyEntry(entry);
+ entry->recycle();
entry->eventTime = currentTime;
entry->policyFlags = policyFlags;
entry->repeatCount += 1;
} else {
- KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
+ KeyEntry* newEntry = new KeyEntry(currentTime,
entry->deviceId, entry->source, policyFlags,
entry->action, entry->flags, entry->keyCode, entry->scanCode,
entry->metaState, entry->repeatCount + 1, entry->downTime);
mKeyRepeatState.lastKeyEntry = newEntry;
- mAllocator.releaseKeyEntry(entry);
+ entry->release();
entry = newEntry;
}
@@ -887,7 +879,7 @@ bool InputDispatcher::dispatchMotionLocked(
uint32_t originalSampleCount = entry->countSamples();
#endif
MotionSample* nextSample = splitBatchAfterSample->next;
- MotionEntry* nextEntry = mAllocator.obtainMotionEntry(nextSample->eventTime,
+ MotionEntry* nextEntry = new MotionEntry(nextSample->eventTime,
entry->deviceId, entry->source, entry->policyFlags,
entry->action, entry->flags,
entry->metaState, entry->buttonState, entry->edgeFlags,
@@ -897,7 +889,7 @@ bool InputDispatcher::dispatchMotionLocked(
nextEntry->firstSample.next = nextSample->next;
nextEntry->lastSample = entry->lastSample;
}
- mAllocator.freeMotionSample(nextSample);
+ delete nextSample;
entry->lastSample = const_cast<MotionSample*>(splitBatchAfterSample);
entry->lastSample->next = NULL;
@@ -1992,7 +1984,7 @@ void InputDispatcher::enqueueDispatchEntryLocked(
// This is a new event.
// Enqueue a new dispatch entry onto the outbound queue for this connection.
- DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
+ DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
inputTarget->scaleFactor);
if (dispatchEntry->hasForegroundTarget()) {
@@ -2087,7 +2079,7 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
LOG_ASSERT(connection->status == Connection::STATUS_NORMAL);
LOG_ASSERT(! connection->outboundQueue.isEmpty());
- DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
+ DispatchEntry* dispatchEntry = connection->outboundQueue.head;
LOG_ASSERT(! dispatchEntry->inProgress);
// Mark the dispatch entry as in progress.
@@ -2276,7 +2268,7 @@ void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
const sp<Connection>& connection) {
// Start the next dispatch cycle for this connection.
while (! connection->outboundQueue.isEmpty()) {
- DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
+ DispatchEntry* dispatchEntry = connection->outboundQueue.head;
if (dispatchEntry->inProgress) {
// Finish or resume current event in progress.
if (dispatchEntry->tailMotionSample) {
@@ -2293,7 +2285,7 @@ void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
if (dispatchEntry->hasForegroundTarget()) {
decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
}
- mAllocator.releaseDispatchEntry(dispatchEntry);
+ delete dispatchEntry;
} else {
// If the head is not in progress, then we must have already dequeued the in
// progress event, which means we actually aborted it.
@@ -2333,7 +2325,7 @@ void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
if (dispatchEntry->hasForegroundTarget()) {
decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
}
- mAllocator.releaseDispatchEntry(dispatchEntry);
+ delete dispatchEntry;
}
deactivateConnectionLocked(connection);
@@ -2407,7 +2399,7 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
nsecs_t currentTime = now();
mTempCancelationEvents.clear();
- connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
+ connection->inputState.synthesizeCancelationEvents(currentTime,
mTempCancelationEvents, options);
if (! mTempCancelationEvents.isEmpty()
@@ -2448,10 +2440,10 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
&target, false, InputTarget::FLAG_DISPATCH_AS_IS);
- mAllocator.releaseEventEntry(cancelationEventEntry);
+ cancelationEventEntry->release();
}
- if (!connection->outboundQueue.headSentinel.next->inProgress) {
+ if (!connection->outboundQueue.head->inProgress) {
startDispatchCycleLocked(currentTime, connection);
}
}
@@ -2523,7 +2515,7 @@ InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet
}
}
- MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
+ MotionEntry* splitMotionEntry = new MotionEntry(
originalMotionEntry->eventTime,
originalMotionEntry->deviceId,
originalMotionEntry->source,
@@ -2547,8 +2539,7 @@ InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet
originalMotionSample->pointerCoords[originalPointerIndex]);
}
- mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
- splitPointerCoords);
+ splitMotionEntry->appendSample(originalMotionSample->eventTime, splitPointerCoords);
}
if (originalMotionEntry->injectionState) {
@@ -2568,7 +2559,7 @@ void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
{ // acquire lock
AutoMutex _l(mLock);
- ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
+ ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(eventTime);
needWake = enqueueInboundEventLocked(newEntry);
} // release lock
@@ -2638,7 +2629,7 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t so
}
int32_t repeatCount = 0;
- KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
+ KeyEntry* newEntry = new KeyEntry(eventTime,
deviceId, source, policyFlags, action, flags, keyCode, scanCode,
metaState, repeatCount, downTime);
@@ -2718,8 +2709,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
// Try to append a move sample to the tail of the inbound queue for this device.
// Give up if we encounter a non-move motion event for this device since that
// means we cannot append any new samples until a new motion event has started.
- for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
- entry != & mInboundQueue.headSentinel; entry = entry->prev) {
+ for (EventEntry* entry = mInboundQueue.tail; entry; entry = entry->prev) {
if (entry->type != EventEntry::TYPE_MOTION) {
// Keep looking for motion events.
continue;
@@ -2798,7 +2788,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
continue;
}
- DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
+ DispatchEntry* dispatchEntry = connection->outboundQueue.head;
if (! dispatchEntry->inProgress
|| dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
|| dispatchEntry->isSplit()) {
@@ -2844,7 +2834,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
// Hurray! This foreground target is currently dispatching a move event
// that we can stream onto. Append the motion sample and resume dispatch.
- mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
+ motionEntry->appendSample(eventTime, pointerCoords);
#if DEBUG_BATCHING
LOGD("Appended motion sample onto batch for most recently dispatched "
"motion event for this device and source in the outbound queues. "
@@ -2864,7 +2854,7 @@ NoBatchingOrStreaming:;
}
// Just enqueue a new motion event.
- MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
+ MotionEntry* newEntry = new MotionEntry(eventTime,
deviceId, source, policyFlags, action, flags, metaState, buttonState, edgeFlags,
xPrecision, yPrecision, downTime,
pointerCount, pointerProperties, pointerCoords);
@@ -2901,7 +2891,7 @@ void InputDispatcher::batchMotionLocked(MotionEntry* entry, nsecs_t eventTime,
}
// Append the sample.
- mAllocator.appendMotionSample(entry, eventTime, pointerCoords);
+ entry->appendSample(eventTime, pointerCoords);
#if DEBUG_BATCHING
LOGD("Appended motion sample onto batch for %s, events were %0.3f ms apart",
eventDescription, interval * 0.000001f);
@@ -2958,7 +2948,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
}
mLock.lock();
- injectedEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
+ injectedEntry = new KeyEntry(keyEvent->getEventTime(),
keyEvent->getDeviceId(), keyEvent->getSource(),
policyFlags, action, flags,
keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
@@ -2983,7 +2973,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
mLock.lock();
const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
- MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
+ MotionEntry* motionEntry = new MotionEntry(*sampleEventTimes,
motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
action, motionEvent->getFlags(),
motionEvent->getMetaState(), motionEvent->getButtonState(),
@@ -2994,7 +2984,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
sampleEventTimes += 1;
samplePointerCoords += pointerCount;
- mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
+ motionEntry->appendSample(*sampleEventTimes, samplePointerCoords);
}
injectedEntry = motionEntry;
break;
@@ -3005,7 +2995,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
return INPUT_EVENT_INJECTION_FAILED;
}
- InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
+ InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
injectionState->injectionIsAsync = true;
}
@@ -3068,7 +3058,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
}
}
- mAllocator.releaseInjectionState(injectionState);
+ injectionState->release();
} // release lock
#if DEBUG_INJECTION
@@ -3704,7 +3694,7 @@ void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
entry->interceptKeyResult = consumed
? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
: KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
- mAllocator.releaseKeyEntry(entry);
+ entry->release();
}
void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
@@ -3714,7 +3704,7 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
bool skipNext = false;
if (!connection->outboundQueue.isEmpty()) {
- DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
+ DispatchEntry* dispatchEntry = connection->outboundQueue.head;
if (dispatchEntry->inProgress) {
if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
@@ -3796,7 +3786,7 @@ bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& con
return true; // skip next cycle
}
- LOG_ASSERT(connection->outboundQueue.headSentinel.next == dispatchEntry);
+ LOG_ASSERT(connection->outboundQueue.head == dispatchEntry);
// Latch the fallback keycode for this key on an initial down.
// The fallback keycode cannot change at any other point in the lifecycle.
@@ -3929,230 +3919,137 @@ void InputDispatcher::dump(String8& dump) {
template <typename T>
uint32_t InputDispatcher::Queue<T>::count() const {
uint32_t result = 0;
- for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
+ for (const T* entry = head; entry; entry = entry->next) {
result += 1;
}
return result;
}
-// --- InputDispatcher::Allocator ---
+// --- InputDispatcher::InjectionState ---
-InputDispatcher::Allocator::Allocator() {
+InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
+ refCount(1),
+ injectorPid(injectorPid), injectorUid(injectorUid),
+ injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
+ pendingForegroundDispatches(0) {
}
-InputDispatcher::InjectionState*
-InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
- InjectionState* injectionState = mInjectionStatePool.alloc();
- injectionState->refCount = 1;
- injectionState->injectorPid = injectorPid;
- injectionState->injectorUid = injectorUid;
- injectionState->injectionIsAsync = false;
- injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
- injectionState->pendingForegroundDispatches = 0;
- return injectionState;
+InputDispatcher::InjectionState::~InjectionState() {
}
-void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
- nsecs_t eventTime, uint32_t policyFlags) {
- entry->type = type;
- entry->refCount = 1;
- entry->dispatchInProgress = false;
- entry->eventTime = eventTime;
- entry->policyFlags = policyFlags;
- entry->injectionState = NULL;
-}
-
-void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
- if (entry->injectionState) {
- releaseInjectionState(entry->injectionState);
- entry->injectionState = NULL;
+void InputDispatcher::InjectionState::release() {
+ refCount -= 1;
+ if (refCount == 0) {
+ delete this;
+ } else {
+ LOG_ASSERT(refCount > 0);
}
}
-InputDispatcher::ConfigurationChangedEntry*
-InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
- ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
- initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
- return entry;
-}
-InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
- int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
- int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
- int32_t repeatCount, nsecs_t downTime) {
- KeyEntry* entry = mKeyEntryPool.alloc();
- initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
-
- entry->deviceId = deviceId;
- entry->source = source;
- entry->action = action;
- entry->flags = flags;
- entry->keyCode = keyCode;
- entry->scanCode = scanCode;
- entry->metaState = metaState;
- entry->repeatCount = repeatCount;
- entry->downTime = downTime;
- entry->syntheticRepeat = false;
- entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
- return entry;
-}
+// --- InputDispatcher::EventEntry ---
-InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
- int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
- int32_t metaState, int32_t buttonState,
- int32_t edgeFlags, float xPrecision, float yPrecision,
- nsecs_t downTime, uint32_t pointerCount,
- const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) {
- MotionEntry* entry = mMotionEntryPool.alloc();
- initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
-
- entry->eventTime = eventTime;
- entry->deviceId = deviceId;
- entry->source = source;
- entry->action = action;
- entry->flags = flags;
- entry->metaState = metaState;
- entry->buttonState = buttonState;
- entry->edgeFlags = edgeFlags;
- entry->xPrecision = xPrecision;
- entry->yPrecision = yPrecision;
- entry->downTime = downTime;
- entry->pointerCount = pointerCount;
- entry->firstSample.eventTime = eventTime;
- entry->firstSample.eventTimeBeforeCoalescing = eventTime;
- entry->firstSample.next = NULL;
- entry->lastSample = & entry->firstSample;
- for (uint32_t i = 0; i < pointerCount; i++) {
- entry->pointerProperties[i].copyFrom(pointerProperties[i]);
- entry->firstSample.pointerCoords[i].copyFrom(pointerCoords[i]);
- }
- return entry;
+InputDispatcher::EventEntry::EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags) :
+ refCount(1), type(type), eventTime(eventTime), policyFlags(policyFlags),
+ injectionState(NULL), dispatchInProgress(false) {
}
-InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
- EventEntry* eventEntry,
- int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) {
- DispatchEntry* entry = mDispatchEntryPool.alloc();
- entry->eventEntry = eventEntry;
- eventEntry->refCount += 1;
- entry->targetFlags = targetFlags;
- entry->xOffset = xOffset;
- entry->yOffset = yOffset;
- entry->scaleFactor = scaleFactor;
- entry->inProgress = false;
- entry->headMotionSample = NULL;
- entry->tailMotionSample = NULL;
- return entry;
+InputDispatcher::EventEntry::~EventEntry() {
+ releaseInjectionState();
}
-InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
- CommandEntry* entry = mCommandEntryPool.alloc();
- entry->command = command;
- return entry;
-}
-
-void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
- injectionState->refCount -= 1;
- if (injectionState->refCount == 0) {
- mInjectionStatePool.free(injectionState);
+void InputDispatcher::EventEntry::release() {
+ refCount -= 1;
+ if (refCount == 0) {
+ delete this;
} else {
- LOG_ASSERT(injectionState->refCount > 0);
+ LOG_ASSERT(refCount > 0);
}
}
-void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
- switch (entry->type) {
- case EventEntry::TYPE_CONFIGURATION_CHANGED:
- releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
- break;
- case EventEntry::TYPE_KEY:
- releaseKeyEntry(static_cast<KeyEntry*>(entry));
- break;
- case EventEntry::TYPE_MOTION:
- releaseMotionEntry(static_cast<MotionEntry*>(entry));
- break;
- default:
- LOG_ASSERT(false);
- break;
+void InputDispatcher::EventEntry::releaseInjectionState() {
+ if (injectionState) {
+ injectionState->release();
+ injectionState = NULL;
}
}
-void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
- ConfigurationChangedEntry* entry) {
- entry->refCount -= 1;
- if (entry->refCount == 0) {
- releaseEventEntryInjectionState(entry);
- mConfigurationChangeEntryPool.free(entry);
- } else {
- LOG_ASSERT(entry->refCount > 0);
- }
-}
-void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
- entry->refCount -= 1;
- if (entry->refCount == 0) {
- releaseEventEntryInjectionState(entry);
- mKeyEntryPool.free(entry);
- } else {
- LOG_ASSERT(entry->refCount > 0);
- }
-}
+// --- InputDispatcher::ConfigurationChangedEntry ---
-void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
- entry->refCount -= 1;
- if (entry->refCount == 0) {
- releaseEventEntryInjectionState(entry);
- for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
- MotionSample* next = sample->next;
- mMotionSamplePool.free(sample);
- sample = next;
- }
- mMotionEntryPool.free(entry);
- } else {
- LOG_ASSERT(entry->refCount > 0);
- }
+InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(nsecs_t eventTime) :
+ EventEntry(TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
}
-void InputDispatcher::Allocator::freeMotionSample(MotionSample* sample) {
- mMotionSamplePool.free(sample);
+InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
}
-void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
- releaseEventEntry(entry->eventEntry);
- mDispatchEntryPool.free(entry);
+
+// --- InputDispatcher::KeyEntry ---
+
+InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
+ int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
+ int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
+ int32_t repeatCount, nsecs_t downTime) :
+ EventEntry(TYPE_KEY, eventTime, policyFlags),
+ deviceId(deviceId), source(source), action(action), flags(flags),
+ keyCode(keyCode), scanCode(scanCode), metaState(metaState),
+ repeatCount(repeatCount), downTime(downTime),
+ syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
}
-void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
- mCommandEntryPool.free(entry);
+InputDispatcher::KeyEntry::~KeyEntry() {
}
-void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
- nsecs_t eventTime, const PointerCoords* pointerCoords) {
- MotionSample* sample = mMotionSamplePool.alloc();
- sample->eventTime = eventTime;
- sample->eventTimeBeforeCoalescing = eventTime;
- uint32_t pointerCount = motionEntry->pointerCount;
- for (uint32_t i = 0; i < pointerCount; i++) {
- sample->pointerCoords[i].copyFrom(pointerCoords[i]);
- }
+void InputDispatcher::KeyEntry::recycle() {
+ releaseInjectionState();
- sample->next = NULL;
- motionEntry->lastSample->next = sample;
- motionEntry->lastSample = sample;
+ dispatchInProgress = false;
+ syntheticRepeat = false;
+ interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
}
-void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
- releaseEventEntryInjectionState(keyEntry);
- keyEntry->dispatchInProgress = false;
- keyEntry->syntheticRepeat = false;
- keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
+// --- InputDispatcher::MotionSample ---
+
+InputDispatcher::MotionSample::MotionSample(nsecs_t eventTime,
+ const PointerCoords* pointerCoords, uint32_t pointerCount) :
+ next(NULL), eventTime(eventTime), eventTimeBeforeCoalescing(eventTime) {
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ this->pointerCoords[i].copyFrom(pointerCoords[i]);
+ }
}
// --- InputDispatcher::MotionEntry ---
+InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,
+ int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
+ int32_t metaState, int32_t buttonState,
+ int32_t edgeFlags, float xPrecision, float yPrecision,
+ nsecs_t downTime, uint32_t pointerCount,
+ const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) :
+ EventEntry(TYPE_MOTION, eventTime, policyFlags),
+ deviceId(deviceId), source(source), action(action), flags(flags),
+ metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
+ xPrecision(xPrecision), yPrecision(yPrecision),
+ downTime(downTime), pointerCount(pointerCount),
+ firstSample(eventTime, pointerCoords, pointerCount),
+ lastSample(&firstSample) {
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ this->pointerProperties[i].copyFrom(pointerProperties[i]);
+ }
+}
+
+InputDispatcher::MotionEntry::~MotionEntry() {
+ for (MotionSample* sample = firstSample.next; sample != NULL; ) {
+ MotionSample* next = sample->next;
+ delete sample;
+ sample = next;
+ }
+}
+
uint32_t InputDispatcher::MotionEntry::countSamples() const {
uint32_t count = 1;
for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
@@ -4176,6 +4073,31 @@ bool InputDispatcher::MotionEntry::canAppendSamples(int32_t action, uint32_t poi
return true;
}
+void InputDispatcher::MotionEntry::appendSample(
+ nsecs_t eventTime, const PointerCoords* pointerCoords) {
+ MotionSample* sample = new MotionSample(eventTime, pointerCoords, pointerCount);
+
+ lastSample->next = sample;
+ lastSample = sample;
+}
+
+
+// --- InputDispatcher::DispatchEntry ---
+
+InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
+ int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) :
+ eventEntry(eventEntry), targetFlags(targetFlags),
+ xOffset(xOffset), yOffset(yOffset), scaleFactor(scaleFactor),
+ inProgress(false),
+ resolvedAction(0), resolvedFlags(0),
+ headMotionSample(NULL), tailMotionSample(NULL) {
+ eventEntry->refCount += 1;
+}
+
+InputDispatcher::DispatchEntry::~DispatchEntry() {
+ eventEntry->release();
+}
+
// --- InputDispatcher::InputState ---
@@ -4380,12 +4302,11 @@ void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry*
}
void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
- Allocator* allocator, Vector<EventEntry*>& outEvents,
- const CancelationOptions& options) {
+ Vector<EventEntry*>& outEvents, const CancelationOptions& options) {
for (size_t i = 0; i < mKeyMementos.size(); i++) {
const KeyMemento& memento = mKeyMementos.itemAt(i);
if (shouldCancelKey(memento, options)) {
- outEvents.push(allocator->obtainKeyEntry(currentTime,
+ outEvents.push(new KeyEntry(currentTime,
memento.deviceId, memento.source, 0,
AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
@@ -4395,7 +4316,7 @@ void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTim
for (size_t i = 0; i < mMotionMementos.size(); i++) {
const MotionMemento& memento = mMotionMementos.itemAt(i);
if (shouldCancelMotion(memento, options)) {
- outEvents.push(allocator->obtainMotionEntry(currentTime,
+ outEvents.push(new MotionEntry(currentTime,
memento.deviceId, memento.source, 0,
memento.hovering
? AMOTION_EVENT_ACTION_HOVER_EXIT
@@ -4516,8 +4437,8 @@ const char* InputDispatcher::Connection::getStatusLabel() const {
InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
const EventEntry* eventEntry) const {
- for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
- dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
+ for (DispatchEntry* dispatchEntry = outboundQueue.tail; dispatchEntry;
+ dispatchEntry = dispatchEntry->prev) {
if (dispatchEntry->eventEntry == eventEntry) {
return dispatchEntry;
}
@@ -4528,8 +4449,8 @@ InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchE
// --- InputDispatcher::CommandEntry ---
-InputDispatcher::CommandEntry::CommandEntry() :
- keyEntry(NULL) {
+InputDispatcher::CommandEntry::CommandEntry(Command command) :
+ command(command), eventTime(0), keyEntry(NULL), userActivityEventType(0), handled(false) {
}
InputDispatcher::CommandEntry::~CommandEntry() {
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 15fd274f5e50..1d39b2e6cbb8 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -26,7 +26,6 @@
#include <utils/RefBase.h>
#include <utils/String8.h>
#include <utils/Looper.h>
-#include <utils/Pool.h>
#include <utils/BitSet.h>
#include <stddef.h>
@@ -434,11 +433,16 @@ private:
int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING
bool injectionIsAsync; // set to true if injection is not waiting for the result
int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress
+
+ InjectionState(int32_t injectorPid, int32_t injectorUid);
+ void release();
+
+ private:
+ ~InjectionState();
};
struct EventEntry : Link<EventEntry> {
enum {
- TYPE_SENTINEL,
TYPE_CONFIGURATION_CHANGED,
TYPE_KEY,
TYPE_MOTION
@@ -453,9 +457,20 @@ private:
bool dispatchInProgress; // initially false, set to true while dispatching
inline bool isInjected() const { return injectionState != NULL; }
+
+ void release();
+
+ protected:
+ EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags);
+ virtual ~EventEntry();
+ void releaseInjectionState();
};
struct ConfigurationChangedEntry : EventEntry {
+ ConfigurationChangedEntry(nsecs_t eventTime);
+
+ protected:
+ virtual ~ConfigurationChangedEntry();
};
struct KeyEntry : EventEntry {
@@ -477,6 +492,15 @@ private:
INTERCEPT_KEY_RESULT_CONTINUE,
};
InterceptKeyResult interceptKeyResult; // set based on the interception result
+
+ KeyEntry(nsecs_t eventTime,
+ int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
+ int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
+ int32_t repeatCount, nsecs_t downTime);
+ void recycle();
+
+ protected:
+ virtual ~KeyEntry();
};
struct MotionSample {
@@ -485,6 +509,9 @@ private:
nsecs_t eventTime; // may be updated during coalescing
nsecs_t eventTimeBeforeCoalescing; // not updated during coalescing
PointerCoords pointerCoords[MAX_POINTERS];
+
+ MotionSample(nsecs_t eventTime, const PointerCoords* pointerCoords,
+ uint32_t pointerCount);
};
struct MotionEntry : EventEntry {
@@ -505,11 +532,23 @@ private:
MotionSample firstSample;
MotionSample* lastSample;
+ MotionEntry(nsecs_t eventTime,
+ int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
+ int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
+ float xPrecision, float yPrecision,
+ nsecs_t downTime, uint32_t pointerCount,
+ const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
+
uint32_t countSamples() const;
// Checks whether we can append samples, assuming the device id and source are the same.
bool canAppendSamples(int32_t action, uint32_t pointerCount,
const PointerProperties* pointerProperties) const;
+
+ void appendSample(nsecs_t eventTime, const PointerCoords* pointerCoords);
+
+ protected:
+ virtual ~MotionEntry();
};
// Tracks the progress of dispatching a particular event to a particular connection.
@@ -540,6 +579,10 @@ private:
// will be set to NULL.
MotionSample* tailMotionSample;
+ DispatchEntry(EventEntry* eventEntry,
+ int32_t targetFlags, float xOffset, float yOffset, float scaleFactor);
+ ~DispatchEntry();
+
inline bool hasForegroundTarget() const {
return targetFlags & InputTarget::FLAG_FOREGROUND;
}
@@ -570,7 +613,7 @@ private:
class Connection;
struct CommandEntry : Link<CommandEntry> {
- CommandEntry();
+ CommandEntry(Command command);
~CommandEntry();
Command command;
@@ -588,99 +631,65 @@ private:
// Generic queue implementation.
template <typename T>
struct Queue {
- T headSentinel;
- T tailSentinel;
-
- inline Queue() {
- headSentinel.prev = NULL;
- headSentinel.next = & tailSentinel;
- tailSentinel.prev = & headSentinel;
- tailSentinel.next = NULL;
+ T* head;
+ T* tail;
+
+ inline Queue() : head(NULL), tail(NULL) {
}
inline bool isEmpty() const {
- return headSentinel.next == & tailSentinel;
+ return !head;
}
inline void enqueueAtTail(T* entry) {
- T* last = tailSentinel.prev;
- last->next = entry;
- entry->prev = last;
- entry->next = & tailSentinel;
- tailSentinel.prev = entry;
+ entry->prev = tail;
+ if (tail) {
+ tail->next = entry;
+ } else {
+ head = entry;
+ }
+ entry->next = NULL;
+ tail = entry;
}
inline void enqueueAtHead(T* entry) {
- T* first = headSentinel.next;
- headSentinel.next = entry;
- entry->prev = & headSentinel;
- entry->next = first;
- first->prev = entry;
+ entry->next = head;
+ if (head) {
+ head->prev = entry;
+ } else {
+ tail = entry;
+ }
+ entry->prev = NULL;
+ head = entry;
}
inline void dequeue(T* entry) {
- entry->prev->next = entry->next;
- entry->next->prev = entry->prev;
+ if (entry->prev) {
+ entry->prev->next = entry->next;
+ } else {
+ head = entry->next;
+ }
+ if (entry->next) {
+ entry->next->prev = entry->prev;
+ } else {
+ tail = entry->prev;
+ }
}
inline T* dequeueAtHead() {
- T* first = headSentinel.next;
- dequeue(first);
- return first;
+ T* entry = head;
+ head = entry->next;
+ if (head) {
+ head->prev = NULL;
+ } else {
+ tail = NULL;
+ }
+ return entry;
}
uint32_t count() const;
};
- /* Allocates queue entries and performs reference counting as needed. */
- class Allocator {
- public:
- Allocator();
-
- InjectionState* obtainInjectionState(int32_t injectorPid, int32_t injectorUid);
- ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime);
- KeyEntry* obtainKeyEntry(nsecs_t eventTime,
- int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
- int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
- int32_t repeatCount, nsecs_t downTime);
- MotionEntry* obtainMotionEntry(nsecs_t eventTime,
- int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
- int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
- float xPrecision, float yPrecision,
- nsecs_t downTime, uint32_t pointerCount,
- const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
- DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry,
- int32_t targetFlags, float xOffset, float yOffset, float scaleFactor);
- CommandEntry* obtainCommandEntry(Command command);
-
- void releaseInjectionState(InjectionState* injectionState);
- void releaseEventEntry(EventEntry* entry);
- void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry);
- void releaseKeyEntry(KeyEntry* entry);
- void releaseMotionEntry(MotionEntry* entry);
- void freeMotionSample(MotionSample* sample);
- void releaseDispatchEntry(DispatchEntry* entry);
- void releaseCommandEntry(CommandEntry* entry);
-
- void recycleKeyEntry(KeyEntry* entry);
-
- void appendMotionSample(MotionEntry* motionEntry,
- nsecs_t eventTime, const PointerCoords* pointerCoords);
-
- private:
- Pool<InjectionState> mInjectionStatePool;
- Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool;
- Pool<KeyEntry> mKeyEntryPool;
- Pool<MotionEntry> mMotionEntryPool;
- Pool<MotionSample> mMotionSamplePool;
- Pool<DispatchEntry> mDispatchEntryPool;
- Pool<CommandEntry> mCommandEntryPool;
-
- void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime,
- uint32_t policyFlags);
- void releaseEventEntryInjectionState(EventEntry* entry);
- };
-
/* Specifies which events are to be canceled and why. */
struct CancelationOptions {
enum Mode {
@@ -728,7 +737,7 @@ private:
bool trackMotion(const MotionEntry* entry, int32_t action, int32_t flags);
// Synthesizes cancelation events for the current state and resets the tracked state.
- void synthesizeCancelationEvents(nsecs_t currentTime, Allocator* allocator,
+ void synthesizeCancelationEvents(nsecs_t currentTime,
Vector<EventEntry*>& outEvents, const CancelationOptions& options);
// Clears the current state.
@@ -856,7 +865,6 @@ private:
Mutex mLock;
- Allocator mAllocator;
sp<Looper> mLooper;
EventEntry* mPendingEvent;
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 438883e9caf3..a679ca72daa2 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -230,8 +230,14 @@ class AppWidgetService extends IAppWidgetService.Stub
pw.println(':');
pw.print(" min=("); pw.print(info.minWidth);
pw.print("x"); pw.print(info.minHeight);
+ pw.print(") minResize=("); pw.print(info.minResizeWidth);
+ pw.print("x"); pw.print(info.minResizeHeight);
pw.print(") updatePeriodMillis=");
pw.print(info.updatePeriodMillis);
+ pw.print(" resizeMode=");
+ pw.print(info.resizeMode);
+ pw.print(" autoAdvanceViewId=");
+ pw.print(info.autoAdvanceViewId);
pw.print(" initialLayout=#");
pw.print(Integer.toHexString(info.initialLayout));
pw.print(" zombie="); pw.println(p.zombie);
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 5dd3a6a3a11f..79c067570982 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -1090,7 +1090,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
try {
InetAddress addr = InetAddress.getByAddress(hostAddress);
LinkProperties lp = tracker.getLinkProperties();
- return addRoute(lp, RouteInfo.makeHostRoute(addr));
+ return addRouteToAddress(lp, addr);
} catch (UnknownHostException e) {}
return false;
}
@@ -1103,6 +1103,31 @@ public class ConnectivityService extends IConnectivityManager.Stub {
return modifyRoute(p.getInterfaceName(), p, r, 0, false);
}
+ private boolean addRouteToAddress(LinkProperties lp, InetAddress addr) {
+ return modifyRouteToAddress(lp, addr, true);
+ }
+
+ private boolean removeRouteToAddress(LinkProperties lp, InetAddress addr) {
+ return modifyRouteToAddress(lp, addr, false);
+ }
+
+ private boolean modifyRouteToAddress(LinkProperties lp, InetAddress addr, boolean doAdd) {
+ RouteInfo bestRoute = RouteInfo.selectBestRoute(lp.getRoutes(), addr);
+ if (bestRoute == null) {
+ bestRoute = RouteInfo.makeHostRoute(addr);
+ } else {
+ if (bestRoute.getGateway().equals(addr)) {
+ // if there is no better route, add the implied hostroute for our gateway
+ bestRoute = RouteInfo.makeHostRoute(addr);
+ } else {
+ // if we will connect to this through another route, add a direct route
+ // to it's gateway
+ bestRoute = RouteInfo.makeHostRoute(addr, bestRoute.getGateway());
+ }
+ }
+ return modifyRoute(lp.getInterfaceName(), lp, bestRoute, 0, doAdd);
+ }
+
private boolean modifyRoute(String ifaceName, LinkProperties lp, RouteInfo r, int cycleCount,
boolean doAdd) {
if ((ifaceName == null) || (lp == null) || (r == null)) return false;
@@ -1713,49 +1738,50 @@ public class ConnectivityService extends IConnectivityManager.Stub {
*/
private void updateRoutes(LinkProperties newLp, LinkProperties curLp, boolean isLinkDefault) {
Collection<RouteInfo> routesToAdd = null;
- CompareResult<InetAddress> dnsDiff = null;
-
+ CompareResult<InetAddress> dnsDiff = new CompareResult<InetAddress>();
+ CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>();
if (curLp != null) {
// check for the delta between the current set and the new
- CompareResult<RouteInfo> routeDiff = curLp.compareRoutes(newLp);
+ routeDiff = curLp.compareRoutes(newLp);
dnsDiff = curLp.compareDnses(newLp);
-
- for (RouteInfo r : routeDiff.removed) {
- if (isLinkDefault || ! r.isDefaultRoute()) {
- removeRoute(curLp, r);
- }
- }
- routesToAdd = routeDiff.added;
+ } else if (newLp != null) {
+ routeDiff.added = newLp.getRoutes();
+ dnsDiff.added = newLp.getDnses();
}
- if (newLp != null) {
- // if we didn't get a diff from cur -> new, then just use the new
- if (routesToAdd == null) {
- routesToAdd = newLp.getRoutes();
+ for (RouteInfo r : routeDiff.removed) {
+ if (isLinkDefault || ! r.isDefaultRoute()) {
+ removeRoute(curLp, r);
}
+ }
- for (RouteInfo r : routesToAdd) {
- if (isLinkDefault || ! r.isDefaultRoute()) {
- addRoute(newLp, r);
- }
+ for (RouteInfo r : routeDiff.added) {
+ if (isLinkDefault || ! r.isDefaultRoute()) {
+ addRoute(newLp, r);
}
}
if (!isLinkDefault) {
// handle DNS routes
- Collection<InetAddress> dnsToAdd = null;
- if (dnsDiff != null) {
- dnsToAdd = dnsDiff.added;
- for (InetAddress dnsAddress : dnsDiff.removed) {
- removeRoute(curLp, RouteInfo.makeHostRoute(dnsAddress));
+ if (routeDiff.removed.size() == 0 && routeDiff.added.size() == 0) {
+ // no change in routes, check for change in dns themselves
+ for (InetAddress oldDns : dnsDiff.removed) {
+ removeRouteToAddress(curLp, oldDns);
}
- }
- if (newLp != null) {
- if (dnsToAdd == null) {
- dnsToAdd = newLp.getDnses();
+ for (InetAddress newDns : dnsDiff.added) {
+ addRouteToAddress(newLp, newDns);
}
- for(InetAddress dnsAddress : dnsToAdd) {
- addRoute(newLp, RouteInfo.makeHostRoute(dnsAddress));
+ } else {
+ // routes changed - remove all old dns entries and add new
+ if (curLp != null) {
+ for (InetAddress oldDns : curLp.getDnses()) {
+ removeRouteToAddress(curLp, oldDns);
+ }
+ }
+ if (newLp != null) {
+ for (InetAddress newDns : newLp.getDnses()) {
+ addRouteToAddress(newLp, newDns);
+ }
}
}
}
@@ -2236,6 +2262,15 @@ public class ConnectivityService extends IConnectivityManager.Stub {
}
}
+ public int setUsbTethering(boolean enable) {
+ enforceTetherAccessPermission();
+ if (isTetheringSupported()) {
+ return mTethering.setUsbTethering(enable);
+ } else {
+ return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
+ }
+ }
+
// TODO - move iface listing, queries, etc to new module
// javadoc from interface
public String[] getTetherableIfaces() {
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 25979782afde..73d790a073c0 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -50,6 +50,7 @@ import android.content.ServiceConnection;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Configuration;
@@ -165,7 +166,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private final KeyguardManager mKeyguardManager;
private final Notification mImeSwitcherNotification;
private final PendingIntent mImeSwitchPendingIntent;
- private final boolean mShowOngoingImeSwitcherForPhones;
+ private boolean mShowOngoingImeSwitcherForPhones;
private boolean mNotificationShown;
class SessionState {
@@ -537,8 +538,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mImeSwitcherNotification.vibrate = null;
Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER);
mImeSwitchPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
- mShowOngoingImeSwitcherForPhones = mRes.getBoolean(
- com.android.internal.R.bool.show_ongoing_ime_switcher);
+
+ mShowOngoingImeSwitcherForPhones = false;
synchronized (mMethodMap) {
mFileManager = new InputMethodFileManager(mMethodMap);
@@ -611,6 +612,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
synchronized (mMethodMap) {
if (!mSystemReady) {
mSystemReady = true;
+ mShowOngoingImeSwitcherForPhones = mRes.getBoolean(
+ com.android.internal.R.bool.show_ongoing_ime_switcher);
try {
startInputInnerLocked();
} catch (RuntimeException e) {
@@ -1046,7 +1049,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mStatusBar.setIconVisibility("ime", false);
} else if (packageName != null) {
if (DEBUG) Slog.d(TAG, "show a small icon for the input method");
- mStatusBar.setIcon("ime", packageName, iconId, 0);
+ CharSequence contentDescription = null;
+ try {
+ PackageManager packageManager = mContext.getPackageManager();
+ contentDescription = packageManager.getApplicationLabel(
+ packageManager.getApplicationInfo(packageName, 0));
+ } catch (NameNotFoundException nnfe) {
+ /* ignore */
+ }
+ mStatusBar.setIcon("ime", packageName, iconId, 0,
+ contentDescription != null ? contentDescription.toString() : null);
mStatusBar.setIconVisibility("ime", true);
}
}
@@ -1115,13 +1127,21 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mBackDisposition = backDisposition;
mStatusBar.setImeWindowStatus(token, vis, backDisposition);
final boolean iconVisibility = (vis & InputMethodService.IME_ACTIVE) != 0;
- if (iconVisibility && needsToShowImeSwitchOngoingNotification()) {
+ final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
+ if (imi != null && iconVisibility && needsToShowImeSwitchOngoingNotification()) {
final PackageManager pm = mContext.getPackageManager();
- final CharSequence label = mMethodMap.get(mCurMethodId).loadLabel(pm);
final CharSequence title = mRes.getText(
com.android.internal.R.string.select_input_method);
+ final CharSequence imiLabel = imi.loadLabel(pm);
+ final CharSequence summary = mCurrentSubtype != null
+ ? TextUtils.concat(mCurrentSubtype.getDisplayName(mContext,
+ imi.getPackageName(), imi.getServiceInfo().applicationInfo),
+ (TextUtils.isEmpty(imiLabel) ?
+ "" : " (" + imiLabel + ")"))
+ : imiLabel;
+
mImeSwitcherNotification.setLatestEventInfo(
- mContext, title, label, mImeSwitchPendingIntent);
+ mContext, title, summary, mImeSwitchPendingIntent);
mNotificationManager.notify(
com.android.internal.R.string.select_input_method,
mImeSwitcherNotification);
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 41e8a3148223..17ad268f0386 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -93,6 +93,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
private static final String KEY_TX = "tx_bytes";
class NetdResponseCode {
+ /* Keep in sync with system/netd/ResponseCode.h */
public static final int InterfaceListResult = 110;
public static final int TetherInterfaceListResult = 111;
public static final int TetherDnsFwdTgtListResult = 112;
@@ -108,6 +109,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
public static final int InterfaceTxThrottleResult = 219;
public static final int InterfaceChange = 600;
+ public static final int BandwidthControl = 601;
}
/**
@@ -265,6 +267,20 @@ class NetworkManagementService extends INetworkManagementService.Stub {
}
/**
+ * Notify our observers of a limit reached.
+ */
+ private void notifyLimitReached(String limitName, String iface) {
+ for (INetworkManagementEventObserver obs : mObservers) {
+ try {
+ obs.limitReached(limitName, iface);
+ Slog.d(TAG, "Observer notified limit reached for " + limitName + " " + iface);
+ } catch (Exception ex) {
+ Slog.w(TAG, "Observer notifier failed", ex);
+ }
+ }
+ }
+
+ /**
* Let us know the daemon is connected
*/
protected void onConnected() {
@@ -286,33 +302,52 @@ class NetworkManagementService extends INetworkManagementService.Stub {
}.start();
}
public boolean onEvent(int code, String raw, String[] cooked) {
- if (code == NetdResponseCode.InterfaceChange) {
- /*
- * a network interface change occured
- * Format: "NNN Iface added <name>"
- * "NNN Iface removed <name>"
- * "NNN Iface changed <name> <up/down>"
- * "NNN Iface linkstatus <name> <up/down>"
- */
- if (cooked.length < 4 || !cooked[1].equals("Iface")) {
+ switch (code) {
+ case NetdResponseCode.InterfaceChange:
+ /*
+ * a network interface change occured
+ * Format: "NNN Iface added <name>"
+ * "NNN Iface removed <name>"
+ * "NNN Iface changed <name> <up/down>"
+ * "NNN Iface linkstatus <name> <up/down>"
+ */
+ if (cooked.length < 4 || !cooked[1].equals("Iface")) {
+ throw new IllegalStateException(
+ String.format("Invalid event from daemon (%s)", raw));
+ }
+ if (cooked[2].equals("added")) {
+ notifyInterfaceAdded(cooked[3]);
+ return true;
+ } else if (cooked[2].equals("removed")) {
+ notifyInterfaceRemoved(cooked[3]);
+ return true;
+ } else if (cooked[2].equals("changed") && cooked.length == 5) {
+ notifyInterfaceStatusChanged(cooked[3], cooked[4].equals("up"));
+ return true;
+ } else if (cooked[2].equals("linkstate") && cooked.length == 5) {
+ notifyInterfaceLinkStateChanged(cooked[3], cooked[4].equals("up"));
+ return true;
+ }
throw new IllegalStateException(
String.format("Invalid event from daemon (%s)", raw));
- }
- if (cooked[2].equals("added")) {
- notifyInterfaceAdded(cooked[3]);
- return true;
- } else if (cooked[2].equals("removed")) {
- notifyInterfaceRemoved(cooked[3]);
- return true;
- } else if (cooked[2].equals("changed") && cooked.length == 5) {
- notifyInterfaceStatusChanged(cooked[3], cooked[4].equals("up"));
- return true;
- } else if (cooked[2].equals("linkstate") && cooked.length == 5) {
- notifyInterfaceLinkStateChanged(cooked[3], cooked[4].equals("up"));
- return true;
- }
- throw new IllegalStateException(
- String.format("Invalid event from daemon (%s)", raw));
+ // break;
+ case NetdResponseCode.BandwidthControl:
+ /*
+ * Bandwidth control needs some attention
+ * Format: "NNN limit alert <alertName> <ifaceName>"
+ */
+ if (cooked.length < 5 || !cooked[1].equals("limit")) {
+ throw new IllegalStateException(
+ String.format("Invalid event from daemon (%s)", raw));
+ }
+ if (cooked[2].equals("alert")) {
+ notifyLimitReached(cooked[3], cooked[4]);
+ return true;
+ }
+ throw new IllegalStateException(
+ String.format("Invalid event from daemon (%s)", raw));
+ // break;
+ default: break;
}
return false;
}
@@ -814,7 +849,6 @@ class NetworkManagementService extends INetworkManagementService.Stub {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
try {
- mConnector.doCommand(String.format("softap stop " + wlanIface));
mConnector.doCommand(String.format("softap fwreload " + wlanIface + " AP"));
mConnector.doCommand(String.format("softap start " + wlanIface));
if (wifiConfig == null) {
@@ -862,13 +896,15 @@ class NetworkManagementService extends INetworkManagementService.Stub {
}
}
- public void stopAccessPoint() throws IllegalStateException {
+ public void stopAccessPoint(String wlanIface) throws IllegalStateException {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
try {
mConnector.doCommand("softap stopap");
+ mConnector.doCommand("softap stop " + wlanIface);
+ mConnector.doCommand(String.format("softap fwreload " + wlanIface + " STA"));
} catch (NativeDaemonConnectorException e) {
throw new IllegalStateException("Error communicating to native daemon to stop soft AP",
e);
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 4ecdfed687c3..5d7a48f491f4 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -262,7 +262,7 @@ public class NotificationManagerService extends INotificationManager.Stub
public void onNotificationClick(String pkg, String tag, int id) {
cancelNotification(pkg, tag, id, Notification.FLAG_AUTO_CANCEL,
- Notification.FLAG_FOREGROUND_SERVICE, true);
+ Notification.FLAG_FOREGROUND_SERVICE, false);
}
public void onNotificationClear(String pkg, String tag, int id) {
diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java
index 286a9376981d..4ced83c9c672 100644
--- a/services/java/com/android/server/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -22,10 +22,10 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
-import android.os.IBinder;
-import android.os.RemoteException;
import android.os.Binder;
import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
import android.util.Slog;
import android.view.View;
@@ -175,7 +175,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub
}
}
- public void setIcon(String slot, String iconPackage, int iconId, int iconLevel) {
+ public void setIcon(String slot, String iconPackage, int iconId, int iconLevel,
+ String contentDescription) {
enforceStatusBar();
synchronized (mIcons) {
@@ -184,7 +185,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub
throw new SecurityException("invalid status bar icon slot: " + slot);
}
- StatusBarIcon icon = new StatusBarIcon(iconPackage, iconId, iconLevel);
+ StatusBarIcon icon = new StatusBarIcon(iconPackage, iconId, iconLevel, 0,
+ contentDescription);
//Slog.d(TAG, "setIcon slot=" + slot + " index=" + index + " icon=" + icon);
mIcons.setIcon(index, icon);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 8c7e279b7132..766659153821 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -230,6 +230,7 @@ class ServerThread extends Thread {
WallpaperManagerService wallpaper = null;
LocationManagerService location = null;
CountryDetectorService countryDetector = null;
+ TextServicesManagerService tsms = null;
if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
try {
@@ -273,6 +274,14 @@ class ServerThread extends Thread {
}
try {
+ Slog.i(TAG, "Text Service Manager Service");
+ tsms = new TextServicesManagerService(context);
+ ServiceManager.addService(Context.TEXT_SERVICES_MANAGER_SERVICE, tsms);
+ } catch (Throwable e) {
+ Slog.e(TAG, "Failure starting Text Service Manager Service", e);
+ }
+
+ try {
Slog.i(TAG, "NetworkStats Service");
networkStats = new NetworkStatsService(context, networkManagement, alarm);
ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
@@ -538,6 +547,7 @@ class ServerThread extends Thread {
final LocationManagerService locationF = location;
final CountryDetectorService countryDetectorF = countryDetector;
final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
+ final TextServicesManagerService textServiceManagerServiceF = tsms;
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
@@ -571,6 +581,7 @@ class ServerThread extends Thread {
if (countryDetectorF != null) countryDetectorF.systemReady();
if (throttleF != null) throttleF.systemReady();
if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemReady();
+ if (textServiceManagerServiceF != null) textServiceManagerServiceF.systemReady();
}
});
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
new file mode 100644
index 000000000000..4a0c837df0c6
--- /dev/null
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import com.android.internal.content.PackageMonitor;
+import com.android.internal.textservice.ISpellCheckerService;
+import com.android.internal.textservice.ISpellCheckerSession;
+import com.android.internal.textservice.ISpellCheckerSessionListener;
+import com.android.internal.textservice.ITextServicesManager;
+import com.android.internal.textservice.ITextServicesSessionListener;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.service.textservice.SpellCheckerService;
+import android.util.Log;
+import android.util.Slog;
+import android.view.textservice.SpellCheckerInfo;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+
+public class TextServicesManagerService extends ITextServicesManager.Stub {
+ private static final String TAG = TextServicesManagerService.class.getSimpleName();
+ private static final boolean DBG = false;
+
+ private final Context mContext;
+ private boolean mSystemReady;
+ private final TextServicesMonitor mMonitor;
+ private final HashMap<String, SpellCheckerInfo> mSpellCheckerMap =
+ new HashMap<String, SpellCheckerInfo>();
+ private final ArrayList<SpellCheckerInfo> mSpellCheckerList = new ArrayList<SpellCheckerInfo>();
+ private final HashMap<String, SpellCheckerBindGroup> mSpellCheckerBindGroups =
+ new HashMap<String, SpellCheckerBindGroup>();
+
+ public void systemReady() {
+ if (!mSystemReady) {
+ mSystemReady = true;
+ }
+ }
+
+ public TextServicesManagerService(Context context) {
+ mSystemReady = false;
+ mContext = context;
+ mMonitor = new TextServicesMonitor();
+ mMonitor.register(context, true);
+ synchronized (mSpellCheckerMap) {
+ buildSpellCheckerMapLocked(context, mSpellCheckerList, mSpellCheckerMap);
+ }
+ }
+
+ private class TextServicesMonitor extends PackageMonitor {
+ @Override
+ public void onSomePackagesChanged() {
+ synchronized (mSpellCheckerMap) {
+ buildSpellCheckerMapLocked(mContext, mSpellCheckerList, mSpellCheckerMap);
+ // TODO: Update for each locale
+ SpellCheckerInfo sci = getCurrentSpellChecker(null);
+ if (sci == null) {
+ sci = findAvailSpellCheckerLocked(null, null);
+ if (sci == null) return;
+ // Set the current spell checker if there is one or more spell checkers
+ // available. In this case, "sci" is the first one in the available spell
+ // checkers.
+ setCurrentSpellChecker(sci);
+ }
+ final String packageName = sci.getPackageName();
+ final int change = isPackageDisappearing(packageName);
+ if (change == PACKAGE_PERMANENT_CHANGE || change == PACKAGE_TEMPORARY_CHANGE) {
+ // Package disappearing
+ setCurrentSpellChecker(findAvailSpellCheckerLocked(null, packageName));
+ } else if (isPackageModified(packageName)) {
+ // Package modified
+ setCurrentSpellChecker(findAvailSpellCheckerLocked(null, packageName));
+ }
+ }
+ }
+ }
+
+ private static void buildSpellCheckerMapLocked(Context context,
+ ArrayList<SpellCheckerInfo> list, HashMap<String, SpellCheckerInfo> map) {
+ list.clear();
+ map.clear();
+ final PackageManager pm = context.getPackageManager();
+ List<ResolveInfo> services = pm.queryIntentServices(
+ new Intent(SpellCheckerService.SERVICE_INTERFACE), PackageManager.GET_META_DATA);
+ final int N = services.size();
+ for (int i = 0; i < N; ++i) {
+ final ResolveInfo ri = services.get(i);
+ final ServiceInfo si = ri.serviceInfo;
+ final ComponentName compName = new ComponentName(si.packageName, si.name);
+ if (!android.Manifest.permission.BIND_TEXT_SERVICE.equals(si.permission)) {
+ Slog.w(TAG, "Skipping text service " + compName
+ + ": it does not require the permission "
+ + android.Manifest.permission.BIND_TEXT_SERVICE);
+ continue;
+ }
+ if (DBG) Slog.d(TAG, "Add: " + compName);
+ final SpellCheckerInfo sci = new SpellCheckerInfo(context, ri);
+ list.add(sci);
+ map.put(sci.getId(), sci);
+ }
+ }
+
+ // TODO: find an appropriate spell checker for specified locale
+ private SpellCheckerInfo findAvailSpellCheckerLocked(String locale, String prefPackage) {
+ final int spellCheckersCount = mSpellCheckerList.size();
+ if (spellCheckersCount == 0) {
+ Slog.w(TAG, "no available spell checker services found");
+ return null;
+ }
+ if (prefPackage != null) {
+ for (int i = 0; i < spellCheckersCount; ++i) {
+ final SpellCheckerInfo sci = mSpellCheckerList.get(i);
+ if (prefPackage.equals(sci.getPackageName())) {
+ return sci;
+ }
+ }
+ }
+ if (spellCheckersCount > 1) {
+ Slog.w(TAG, "more than one spell checker service found, picking first");
+ }
+ return mSpellCheckerList.get(0);
+ }
+
+ // TODO: Save SpellCheckerService by supported languages. Currently only one spell
+ // checker is saved.
+ @Override
+ public SpellCheckerInfo getCurrentSpellChecker(String locale) {
+ synchronized (mSpellCheckerMap) {
+ final String curSpellCheckerId =
+ Settings.Secure.getString(mContext.getContentResolver(),
+ Settings.Secure.SPELL_CHECKER_SERVICE);
+ if (TextUtils.isEmpty(curSpellCheckerId)) {
+ return null;
+ }
+ return mSpellCheckerMap.get(curSpellCheckerId);
+ }
+ }
+
+ @Override
+ public void getSpellCheckerService(SpellCheckerInfo info, String locale,
+ ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener) {
+ if (!mSystemReady) {
+ return;
+ }
+ if (info == null || tsListener == null) {
+ Slog.e(TAG, "getSpellCheckerService: Invalid input.");
+ return;
+ }
+ final String sciId = info.getId();
+ synchronized(mSpellCheckerMap) {
+ if (!mSpellCheckerMap.containsKey(sciId)) {
+ return;
+ }
+ if (mSpellCheckerBindGroups.containsKey(sciId)) {
+ mSpellCheckerBindGroups.get(sciId).addListener(tsListener, locale, scListener);
+ return;
+ }
+ final InternalServiceConnection connection = new InternalServiceConnection(
+ sciId, locale, scListener);
+ final Intent serviceIntent = new Intent(SpellCheckerService.SERVICE_INTERFACE);
+ serviceIntent.setComponent(info.getComponent());
+ if (!mContext.bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE)) {
+ Slog.e(TAG, "Failed to get a spell checker service.");
+ return;
+ }
+ final SpellCheckerBindGroup group = new SpellCheckerBindGroup(
+ connection, tsListener, locale, scListener);
+ mSpellCheckerBindGroups.put(sciId, group);
+ }
+ return;
+ }
+
+ @Override
+ public void finishSpellCheckerService(ISpellCheckerSessionListener listener) {
+ synchronized(mSpellCheckerMap) {
+ for (SpellCheckerBindGroup group : mSpellCheckerBindGroups.values()) {
+ if (group == null) continue;
+ group.removeListener(listener);
+ }
+ }
+ }
+
+ private void setCurrentSpellChecker(SpellCheckerInfo sci) {
+ if (sci == null || mSpellCheckerMap.containsKey(sci.getId())) return;
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.SPELL_CHECKER_SERVICE, sci == null ? "" : sci.getId());
+ }
+
+ // SpellCheckerBindGroup contains active text service session listeners.
+ // If there are no listeners anymore, the SpellCheckerBindGroup instance will be removed from
+ // mSpellCheckerBindGroups
+ private class SpellCheckerBindGroup {
+ final InternalServiceConnection mInternalConnection;
+ final ArrayList<InternalDeathRecipient> mListeners =
+ new ArrayList<InternalDeathRecipient>();
+
+ public SpellCheckerBindGroup(InternalServiceConnection connection,
+ ITextServicesSessionListener listener, String locale,
+ ISpellCheckerSessionListener scListener) {
+ mInternalConnection = connection;
+ addListener(listener, locale, scListener);
+ }
+
+ public void onServiceConnected(ISpellCheckerService spellChecker) {
+ synchronized(mSpellCheckerMap) {
+ for (InternalDeathRecipient listener : mListeners) {
+ try {
+ final ISpellCheckerSession session = spellChecker.getISpellCheckerSession(
+ listener.mScLocale, listener.mScListener);
+ listener.mTsListener.onServiceConnected(session);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ }
+
+ public void addListener(ITextServicesSessionListener tsListener, String locale,
+ ISpellCheckerSessionListener scListener) {
+ synchronized(mSpellCheckerMap) {
+ try {
+ final int size = mListeners.size();
+ for (int i = 0; i < size; ++i) {
+ if (mListeners.get(i).hasSpellCheckerListener(scListener)) {
+ // do not add the lister if the group already contains this.
+ return;
+ }
+ }
+ final InternalDeathRecipient recipient = new InternalDeathRecipient(
+ this, tsListener, locale, scListener);
+ scListener.asBinder().linkToDeath(recipient, 0);
+ mListeners.add(new InternalDeathRecipient(
+ this, tsListener, locale, scListener));
+ } catch(RemoteException e) {
+ // do nothing
+ }
+ cleanLocked();
+ }
+ }
+
+ public void removeListener(ISpellCheckerSessionListener listener) {
+ synchronized(mSpellCheckerMap) {
+ final int size = mListeners.size();
+ final ArrayList<InternalDeathRecipient> removeList =
+ new ArrayList<InternalDeathRecipient>();
+ for (int i = 0; i < size; ++i) {
+ final InternalDeathRecipient tempRecipient = mListeners.get(i);
+ if(tempRecipient.hasSpellCheckerListener(listener)) {
+ removeList.add(tempRecipient);
+ }
+ }
+ final int removeSize = removeList.size();
+ for (int i = 0; i < removeSize; ++i) {
+ mListeners.remove(removeList.get(i));
+ }
+ cleanLocked();
+ }
+ }
+
+ private void cleanLocked() {
+ if (mListeners.isEmpty()) {
+ mSpellCheckerBindGroups.remove(this);
+ // Unbind service when there is no active clients.
+ mContext.unbindService(mInternalConnection);
+ }
+ }
+ }
+
+ private class InternalServiceConnection implements ServiceConnection {
+ private final ISpellCheckerSessionListener mListener;
+ private final String mSciId;
+ private final String mLocale;
+ public InternalServiceConnection(
+ String id, String locale, ISpellCheckerSessionListener listener) {
+ mSciId = id;
+ mLocale = locale;
+ mListener = listener;
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ synchronized(mSpellCheckerMap) {
+ ISpellCheckerService spellChecker = ISpellCheckerService.Stub.asInterface(service);
+ final SpellCheckerBindGroup group = mSpellCheckerBindGroups.get(mSciId);
+ if (group != null) {
+ group.onServiceConnected(spellChecker);
+ }
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ mSpellCheckerBindGroups.remove(mSciId);
+ }
+ }
+
+ private class InternalDeathRecipient implements IBinder.DeathRecipient {
+ public final ITextServicesSessionListener mTsListener;
+ public final ISpellCheckerSessionListener mScListener;
+ public final String mScLocale;
+ private final SpellCheckerBindGroup mGroup;
+ public InternalDeathRecipient(SpellCheckerBindGroup group,
+ ITextServicesSessionListener tsListener, String scLocale,
+ ISpellCheckerSessionListener scListener) {
+ mTsListener = tsListener;
+ mScListener = scListener;
+ mScLocale = scLocale;
+ mGroup = group;
+ }
+
+ public boolean hasSpellCheckerListener(ISpellCheckerSessionListener listener) {
+ return mScListener.equals(listener);
+ }
+
+ @Override
+ public void binderDied() {
+ mGroup.removeListener(mScListener);
+ }
+ }
+}
diff --git a/services/java/com/android/server/ThrottleService.java b/services/java/com/android/server/ThrottleService.java
index b8890aa2aa8e..cd649ce4c554 100644
--- a/services/java/com/android/server/ThrottleService.java
+++ b/services/java/com/android/server/ThrottleService.java
@@ -194,6 +194,7 @@ public class ThrottleService extends IThrottleManager.Stub {
}
public void interfaceRemoved(String iface) {}
+ public void limitReached(String limitName, String iface) {}
}
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 711255327499..f9f63b1d1bd6 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -1461,7 +1461,7 @@ public class WifiService extends IWifiManager.Stub {
if (mMulticasters.size() != 0) {
return;
} else {
- mWifiStateMachine.startPacketFiltering();
+ mWifiStateMachine.startFilteringMulticastV4Packets();
}
}
}
@@ -1472,11 +1472,11 @@ public class WifiService extends IWifiManager.Stub {
synchronized (mMulticasters) {
mMulticastEnabled++;
mMulticasters.add(new Multicaster(tag, binder));
- // Note that we could call stopPacketFiltering only when
+ // Note that we could call stopFilteringMulticastV4Packets only when
// our new size == 1 (first call), but this function won't
// be called often and by making the stopPacket call each
// time we're less fragile and self-healing.
- mWifiStateMachine.stopPacketFiltering();
+ mWifiStateMachine.stopFilteringMulticastV4Packets();
}
int uid = Binder.getCallingUid();
@@ -1513,7 +1513,7 @@ public class WifiService extends IWifiManager.Stub {
removed.unlinkDeathRecipient();
}
if (mMulticasters.size() == 0) {
- mWifiStateMachine.startPacketFiltering();
+ mWifiStateMachine.startFilteringMulticastV4Packets();
}
Long ident = Binder.clearCallingIdentity();
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 0924b862c251..3389f339a7f2 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3628,6 +3628,7 @@ public final class ActivityManagerService extends ActivityManagerNative
app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
app.forcingToForeground = null;
app.foregroundServices = false;
+ app.hasShownUi = false;
app.debugging = false;
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
@@ -9218,6 +9219,7 @@ public final class ActivityManagerService extends ActivityManagerNative
app.forcingToForeground = null;
app.foregroundServices = false;
app.foregroundActivities = false;
+ app.hasShownUi = false;
killServicesLocked(app, true);
@@ -9331,8 +9333,6 @@ public final class ActivityManagerService extends ActivityManagerNative
// This app is persistent, so we need to keep its record around.
// If it is not already on the pending app list, add it there
// and start a new process for it.
- app.forcingToForeground = null;
- app.foregroundServices = false;
if (mPersistentStartingProcesses.indexOf(app) < 0) {
mPersistentStartingProcesses.add(app);
restart = true;
@@ -12728,21 +12728,31 @@ public final class ActivityManagerService extends ActivityManagerNative
while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
ServiceRecord s = jt.next();
if (s.startRequested) {
- if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
- // This service has seen some activity within
- // recent memory, so we will keep its process ahead
- // of the background processes.
+ if (app.hasShownUi) {
+ // If this process has shown some UI, let it immediately
+ // go to the LRU list because it may be pretty heavy with
+ // UI stuff. We'll tag it with a label just to help
+ // debug and understand what is going on.
if (adj > SECONDARY_SERVER_ADJ) {
- adj = SECONDARY_SERVER_ADJ;
- app.adjType = "started-services";
- app.hidden = false;
+ app.adjType = "started-bg-ui-services";
+ }
+ } else {
+ if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
+ // This service has seen some activity within
+ // recent memory, so we will keep its process ahead
+ // of the background processes.
+ if (adj > SECONDARY_SERVER_ADJ) {
+ adj = SECONDARY_SERVER_ADJ;
+ app.adjType = "started-services";
+ app.hidden = false;
+ }
+ }
+ // If we have let the service slide into the background
+ // state, still have some text describing what it is doing
+ // even though the service no longer has an impact.
+ if (adj > SECONDARY_SERVER_ADJ) {
+ app.adjType = "started-bg-services";
}
- }
- // If we have let the service slide into the background
- // state, still have some text describing what it is doing
- // even though the service no longer has an impact.
- if (adj > SECONDARY_SERVER_ADJ) {
- app.adjType = "started-bg-services";
}
// Don't kill this process because it is doing work; it
// has said it is doing work.
@@ -13351,15 +13361,15 @@ public final class ActivityManagerService extends ActivityManagerNative
break;
}
}
- } else if (app.curAdj >= PERCEPTIBLE_APP_ADJ) {
- if (app.trimMemoryLevel < ComponentCallbacks.TRIM_MEMORY_INVISIBLE
+ } else if (app.curAdj == HEAVY_WEIGHT_APP_ADJ) {
+ if (app.trimMemoryLevel < ComponentCallbacks.TRIM_MEMORY_BACKGROUND
&& app.thread != null) {
try {
- app.thread.scheduleTrimMemory(ComponentCallbacks.TRIM_MEMORY_INVISIBLE);
+ app.thread.scheduleTrimMemory(ComponentCallbacks.TRIM_MEMORY_BACKGROUND);
} catch (RemoteException e) {
}
}
- app.trimMemoryLevel = ComponentCallbacks.TRIM_MEMORY_INVISIBLE;
+ app.trimMemoryLevel = ComponentCallbacks.TRIM_MEMORY_BACKGROUND;
} else {
app.trimMemoryLevel = 0;
}
@@ -13442,7 +13452,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
public boolean profileControl(String process, boolean start,
- String path, ParcelFileDescriptor fd) throws RemoteException {
+ String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
try {
synchronized (this) {
@@ -13487,7 +13497,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- proc.thread.profilerControl(start, path, fd);
+ proc.thread.profilerControl(start, path, fd, profileType);
fd = null;
return true;
}
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 0d89081b0813..cc58eafe8872 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -559,6 +559,7 @@ final class ActivityStack {
r.forceNewConfig = false;
showAskCompatModeDialogLocked(r);
r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
+ app.hasShownUi = true;
app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
System.identityHashCode(r),
r.info, r.compat, r.icicle, results, newIntents, !andResume,
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 9e597aa93d18..5b593638f31a 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -66,6 +66,7 @@ class ProcessRecord {
boolean setIsForeground; // Running foreground UI when last set?
boolean foregroundServices; // Running any services that are foreground?
boolean foregroundActivities; // Running any activities that are foreground?
+ boolean hasShownUi; // Has UI been shown in this process since it was started?
boolean bad; // True if disabled in the bad process list
boolean killedBackground; // True when proc has been killed due to too many bg
String waitingToKill; // Process is waiting to be killed when in the bg; reason
@@ -185,6 +186,7 @@ class ProcessRecord {
pw.print(prefix); pw.print("curSchedGroup="); pw.print(curSchedGroup);
pw.print(" setSchedGroup="); pw.print(setSchedGroup);
pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel);
+ pw.print(" hasShownUi="); pw.println(hasShownUi);
pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground);
pw.print(" foregroundServices="); pw.print(foregroundServices);
pw.print(" forcingToForeground="); pw.println(forcingToForeground);
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index d7d4b0346795..a5a6d8e50b39 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -36,7 +36,6 @@ import android.net.LinkProperties;
import android.net.NetworkInfo;
import android.net.NetworkUtils;
import android.os.Binder;
-import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -76,10 +75,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
private final static String TAG = "Tethering";
private final static boolean DEBUG = true;
- private boolean mBooted = false;
- //used to remember if we got connected before boot finished
- private boolean mDeferedUsbConnection = false;
-
// TODO - remove both of these - should be part of interface inspection/selection stuff
private String[] mTetherableUsbRegexs;
private String[] mTetherableWifiRegexs;
@@ -126,10 +121,9 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
private Notification mTetheredNotification;
- // whether we can tether is the && of these two - they come in as separate
- // broadcasts so track them so we can decide what to do when either changes
- private boolean mUsbMassStorageOff; // track the status of USB Mass Storage
- private boolean mUsbConnected; // track the status of USB connection
+ private boolean mRndisEnabled; // track the RNDIS function enabled state
+ private boolean mUsbTetherRequested; // true if USB tethering should be started
+ // when RNDIS is enabled
public Tethering(Context context, INetworkManagementService nmService, Looper looper) {
mContext = context;
@@ -149,7 +143,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_STATE);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
- filter.addAction(Intent.ACTION_BOOT_COMPLETED);
mContext.registerReceiver(mStateReceiver, filter);
filter = new IntentFilter();
@@ -158,9 +151,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
filter.addDataScheme("file");
mContext.registerReceiver(mStateReceiver, filter);
- mUsbMassStorageOff = !Environment.MEDIA_SHARED.equals(
- Environment.getExternalStorageState());
-
mDhcpRange = context.getResources().getStringArray(
com.android.internal.R.array.config_tether_dhcp_range);
if ((mDhcpRange.length == 0) || (mDhcpRange.length % 2 ==1)) {
@@ -221,6 +211,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
}
public void interfaceLinkStateChanged(String iface, boolean up) {
+ if (DEBUG) Log.d(TAG, "interfaceLinkStateChanged " + iface + ", " + up);
+ interfaceStatusChanged(iface, up);
}
private boolean isUsb(String iface) {
@@ -243,6 +235,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
}
return false;
}
+
public void interfaceAdded(String iface) {
boolean found = false;
boolean usb = false;
@@ -288,6 +281,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
}
}
+ public void limitReached(String limitName, String iface) {}
+
public int tether(String iface) {
Log.d(TAG, "Tethering " + iface);
TetherInterfaceSM sm = null;
@@ -454,47 +449,28 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
}
}
- private void updateUsbStatus() {
- boolean enable = mUsbConnected && mUsbMassStorageOff;
-
- if (mBooted) {
- enableUsbIfaces(enable);
- }
- }
-
private class StateReceiver extends BroadcastReceiver {
public void onReceive(Context content, Intent intent) {
String action = intent.getAction();
if (action.equals(UsbManager.ACTION_USB_STATE)) {
- mUsbConnected = intent.getExtras().getBoolean(UsbManager.USB_CONNECTED);
- updateUsbStatus();
- } else if (action.equals(Intent.ACTION_MEDIA_SHARED)) {
- mUsbMassStorageOff = false;
- updateUsbStatus();
- }
- else if (action.equals(Intent.ACTION_MEDIA_UNSHARED)) {
- mUsbMassStorageOff = true;
- updateUsbStatus();
+ synchronized (Tethering.this) {
+ boolean usbConnected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
+ mRndisEnabled = intent.getBooleanExtra(UsbManager.USB_FUNCTION_RNDIS, false);
+ // start tethering if we have a request pending
+ if (usbConnected && mRndisEnabled && mUsbTetherRequested) {
+ tetherUsb(true);
+ }
+ mUsbTetherRequested = false;
+ }
} else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
if (DEBUG) Log.d(TAG, "Tethering got CONNECTIVITY_ACTION");
mTetherMasterSM.sendMessage(TetherMasterSM.CMD_UPSTREAM_CHANGED);
- } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
- mBooted = true;
- updateUsbStatus();
}
}
}
- // used on cable insert/remove
- private void enableUsbIfaces(boolean enable) {
- // add/remove USB interfaces when USB is connected/disconnected
- for (String intf : mTetherableUsbRegexs) {
- if (enable) {
- interfaceAdded(intf);
- } else {
- interfaceRemoved(intf);
- }
- }
+ private void tetherUsb(boolean enable) {
+ if (DEBUG) Log.d(TAG, "tetherUsb " + enable);
String[] ifaces = new String[0];
try {
@@ -505,83 +481,50 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
}
for (String iface : ifaces) {
if (isUsb(iface)) {
- if (enable) {
- interfaceAdded(iface);
- } else {
- interfaceRemoved(iface);
+ int result = (enable ? tether(iface) : untether(iface));
+ if (result == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+ return;
}
}
}
- }
-
- // toggled when we enter/leave the fully tethered state
- private boolean enableUsbRndis(boolean enabled) {
- if (DEBUG) Log.d(TAG, "enableUsbRndis(" + enabled + ")");
-
- UsbManager usbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
- if (usbManager == null) {
- Log.d(TAG, "could not get UsbManager");
- return false;
- }
- try {
- if (enabled) {
- usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS, false);
- } else {
- usbManager.setCurrentFunction(null, false);
- }
- } catch (Exception e) {
- Log.e(TAG, "Error toggling usb RNDIS", e);
- return false;
- }
- return true;
+ Log.e(TAG, "unable start or stop USB tethering");
}
// configured when we start tethering and unconfig'd on error or conclusion
private boolean configureUsbIface(boolean enabled) {
if (DEBUG) Log.d(TAG, "configureUsbIface(" + enabled + ")");
- if (enabled) {
- // must enable RNDIS first to create the interface
- enableUsbRndis(enabled);
- }
-
+ // toggle the USB interfaces
+ String[] ifaces = new String[0];
try {
- // bring toggle the interfaces
- String[] ifaces = new String[0];
- try {
- ifaces = mNMService.listInterfaces();
- } catch (Exception e) {
- Log.e(TAG, "Error listing Interfaces", e);
- return false;
- }
- for (String iface : ifaces) {
- if (isUsb(iface)) {
- InterfaceConfiguration ifcg = null;
- try {
- ifcg = mNMService.getInterfaceConfig(iface);
- if (ifcg != null) {
- InetAddress addr = NetworkUtils.numericToInetAddress(USB_NEAR_IFACE_ADDR);
- ifcg.addr = new LinkAddress(addr, USB_PREFIX_LENGTH);
- if (enabled) {
- ifcg.interfaceFlags = ifcg.interfaceFlags.replace("down", "up");
- } else {
- ifcg.interfaceFlags = ifcg.interfaceFlags.replace("up", "down");
- }
- ifcg.interfaceFlags = ifcg.interfaceFlags.replace("running", "");
- ifcg.interfaceFlags = ifcg.interfaceFlags.replace(" "," ");
- mNMService.setInterfaceConfig(iface, ifcg);
+ ifaces = mNMService.listInterfaces();
+ } catch (Exception e) {
+ Log.e(TAG, "Error listing Interfaces", e);
+ return false;
+ }
+ for (String iface : ifaces) {
+ if (isUsb(iface)) {
+ InterfaceConfiguration ifcg = null;
+ try {
+ ifcg = mNMService.getInterfaceConfig(iface);
+ if (ifcg != null) {
+ InetAddress addr = NetworkUtils.numericToInetAddress(USB_NEAR_IFACE_ADDR);
+ ifcg.addr = new LinkAddress(addr, USB_PREFIX_LENGTH);
+ if (enabled) {
+ ifcg.interfaceFlags = ifcg.interfaceFlags.replace("down", "up");
+ } else {
+ ifcg.interfaceFlags = ifcg.interfaceFlags.replace("up", "down");
}
- } catch (Exception e) {
- Log.e(TAG, "Error configuring interface " + iface, e);
- return false;
+ ifcg.interfaceFlags = ifcg.interfaceFlags.replace("running", "");
+ ifcg.interfaceFlags = ifcg.interfaceFlags.replace(" "," ");
+ mNMService.setInterfaceConfig(iface, ifcg);
}
+ } catch (Exception e) {
+ Log.e(TAG, "Error configuring interface " + iface, e);
+ return false;
}
- }
- } finally {
- if (!enabled) {
- enableUsbRndis(false);
}
- }
+ }
return true;
}
@@ -598,6 +541,28 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
return mTetherableBluetoothRegexs;
}
+ public int setUsbTethering(boolean enable) {
+ UsbManager usbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
+
+ synchronized (this) {
+ if (enable) {
+ if (mRndisEnabled) {
+ tetherUsb(true);
+ } else {
+ mUsbTetherRequested = true;
+ usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS, false);
+ }
+ } else {
+ tetherUsb(false);
+ if (mRndisEnabled) {
+ usbManager.setCurrentFunction(null, false);
+ }
+ mUsbTetherRequested = false;
+ }
+ }
+ return ConnectivityManager.TETHER_ERROR_NO_ERROR;
+ }
+
public int[] getUpstreamIfaceTypes() {
int values[] = new int[mUpstreamIfaceTypes.size()];
Iterator<Integer> iterator = mUpstreamIfaceTypes.iterator();
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index 05e95a7d3d89..9cb772eb315a 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -248,6 +248,8 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
}
}
+ public void limitReached(String limitName, String iface) {}
+
private void showNotification(VpnConfig config, String label, Bitmap icon) {
NotificationManager nm = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -394,7 +396,7 @@ public class Vpn extends INetworkManagementEventObserver.Stub {
if (mTimer == -1) {
mTimer = now;
Thread.sleep(1);
- } else if (now - mTimer <= 30000) {
+ } else if (now - mTimer <= 60000) {
Thread.sleep(yield ? 200 : 1);
} else {
mInfo.state = LegacyVpnInfo.STATE_TIMEOUT;
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index c80cd0a87115..f183f83cfba0 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -19,6 +19,7 @@ package com.android.server.usb;
import android.app.PendingIntent;
import android.app.Notification;
import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -80,6 +81,7 @@ public class UsbDeviceManager {
private static final int MSG_ENABLE_ADB = 1;
private static final int MSG_SET_CURRENT_FUNCTION = 2;
private static final int MSG_SYSTEM_READY = 3;
+ private static final int MSG_BOOT_COMPLETED = 4;
// Delay for debouncing USB disconnects.
// We often get rapid connect/disconnect events when enabling USB functions,
@@ -87,7 +89,7 @@ public class UsbDeviceManager {
private static final int UPDATE_DELAY = 1000;
private UsbHandler mHandler;
- private boolean mSystemReady;
+ private boolean mBootCompleted;
private final Context mContext;
private final ContentResolver mContentResolver;
@@ -141,10 +143,15 @@ public class UsbDeviceManager {
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
mHandler = new UsbHandler(thread.getLooper());
+
+ if (nativeIsStartRequested()) {
+ if (DEBUG) Slog.d(TAG, "accessory attached at boot");
+ setCurrentFunction(UsbManager.USB_FUNCTION_ACCESSORY, false);
+ }
}
public void systemReady() {
- mSystemReady = true;
+ if (DEBUG) Slog.d(TAG, "systemReady");
mNotificationManager = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -236,15 +243,22 @@ public class UsbDeviceManager {
private String mCurrentFunctions;
private String mDefaultFunctions;
private UsbAccessory mCurrentAccessory;
- private boolean mDeferAccessoryAttached;
private int mUsbNotificationId;
private boolean mAdbNotificationShown;
+ private final BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ if (DEBUG) Slog.d(TAG, "boot completed");
+ mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
+ }
+ };
+
private static final int NOTIFICATION_NONE = 0;
private static final int NOTIFICATION_MTP = 1;
private static final int NOTIFICATION_PTP = 2;
private static final int NOTIFICATION_INSTALLER = 3;
- private static final int NOTIFICATION_ADB = 4;
+ private static final int NOTIFICATION_ACCESSORY = 4;
+ private static final int NOTIFICATION_ADB = 5;
public UsbHandler(Looper looper) {
super(looper);
@@ -285,6 +299,9 @@ public class UsbDeviceManager {
// Watch for USB configuration changes
mUEventObserver.startObserving(USB_STATE_MATCH);
mUEventObserver.startObserving(ACCESSORY_START_MATCH);
+
+ mContext.registerReceiver(mBootCompletedReceiver,
+ new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
} catch (Exception e) {
Slog.e(TAG, "Error initializing UsbHandler", e);
}
@@ -406,11 +423,9 @@ public class UsbDeviceManager {
mCurrentAccessory = new UsbAccessory(strings);
Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory);
// defer accessoryAttached if system is not ready
- if (mSystemReady) {
+ if (mBootCompleted) {
mSettingsManager.accessoryAttached(mCurrentAccessory);
- } else {
- mDeferAccessoryAttached = true;
- }
+ } // else handle in mBootCompletedReceiver
} else {
Slog.e(TAG, "nativeGetAccessoryStrings failed");
}
@@ -421,7 +436,7 @@ public class UsbDeviceManager {
setEnabledFunctions(mDefaultFunctions);
if (mCurrentAccessory != null) {
- if (mSystemReady) {
+ if (mBootCompleted) {
mSettingsManager.accessoryDetached(mCurrentAccessory);
}
mCurrentAccessory = null;
@@ -463,7 +478,7 @@ public class UsbDeviceManager {
// restore defaults when USB is disconnected
doSetCurrentFunctions(mDefaultFunctions);
}
- if (mSystemReady) {
+ if (mBootCompleted) {
updateUsbState();
}
break;
@@ -497,7 +512,10 @@ public class UsbDeviceManager {
updateUsbNotification();
updateAdbNotification();
updateUsbState();
- if (mCurrentAccessory != null && mDeferAccessoryAttached) {
+ break;
+ case MSG_BOOT_COMPLETED:
+ mBootCompleted = true;
+ if (mCurrentAccessory != null) {
mSettingsManager.accessoryAttached(mCurrentAccessory);
}
break;
@@ -527,6 +545,10 @@ public class UsbDeviceManager {
title = r.getText(
com.android.internal.R.string.usb_cd_installer_notification_title);
id = NOTIFICATION_INSTALLER;
+ } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ACCESSORY)) {
+ title = r.getText(
+ com.android.internal.R.string.usb_accessory_notification_title);
+ id = NOTIFICATION_ACCESSORY;
} else {
Slog.e(TAG, "No known USB function in updateUsbNotification");
}
@@ -671,4 +693,5 @@ public class UsbDeviceManager {
private native String[] nativeGetAccessoryStrings();
private native ParcelFileDescriptor nativeOpenAccessory();
+ private native boolean nativeIsStartRequested();
}
diff --git a/services/java/com/android/server/wm/BlackFrame.java b/services/java/com/android/server/wm/BlackFrame.java
index d8fd7fe84a73..36f5dcb97056 100644
--- a/services/java/com/android/server/wm/BlackFrame.java
+++ b/services/java/com/android/server/wm/BlackFrame.java
@@ -32,10 +32,12 @@ public class BlackFrame {
final int top;
final Surface surface;
- BlackSurface(SurfaceSession session, int layer, int l, int t, int w, int h)
+ BlackSurface(SurfaceSession session, int layer, int l, int t, int r, int b)
throws Surface.OutOfResourcesException {
left = l;
top = t;
+ int w = r-l;
+ int h = b-t;
surface = new Surface(session, 0, "BlackSurface",
-1, w, h, PixelFormat.OPAQUE, Surface.FX_SURFACE_DIM);
if (WindowManagerService.SHOW_TRANSACTIONS ||
diff --git a/services/jni/com_android_server_UsbDeviceManager.cpp b/services/jni/com_android_server_UsbDeviceManager.cpp
index 69541714260e..40f0dbd81430 100644
--- a/services/jni/com_android_server_UsbDeviceManager.cpp
+++ b/services/jni/com_android_server_UsbDeviceManager.cpp
@@ -99,11 +99,26 @@ static jobject android_server_UsbDeviceManager_openAccessory(JNIEnv *env, jobjec
gParcelFileDescriptorOffsets.mConstructor, fileDescriptor);
}
+static jboolean android_server_UsbDeviceManager_isStartRequested(JNIEnv *env, jobject thiz)
+{
+ int fd = open(DRIVER_NAME, O_RDWR);
+ if (fd < 0) {
+ LOGE("could not open %s", DRIVER_NAME);
+ return false;
+ }
+ int result = ioctl(fd, ACCESSORY_IS_START_REQUESTED);
+ close(fd);
+ return (result == 1);
+}
+
+
static JNINativeMethod method_table[] = {
{ "nativeGetAccessoryStrings", "()[Ljava/lang/String;",
(void*)android_server_UsbDeviceManager_getAccessoryStrings },
{ "nativeOpenAccessory", "()Landroid/os/ParcelFileDescriptor;",
(void*)android_server_UsbDeviceManager_openAccessory },
+ { "nativeIsStartRequested", "()Z",
+ (void*)android_server_UsbDeviceManager_isStartRequested },
};
int register_android_server_UsbDeviceManager(JNIEnv *env)
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index e0dce1ff9d25..5b74fb809c33 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -586,12 +586,12 @@ status_t SensorService::SensorEventConnection::sendEvents(
if (size == -EAGAIN) {
// the destination doesn't accept events anymore, it's probably
// full. For now, we just drop the events on the floor.
- LOGW("dropping %d events on the floor", count);
+ //LOGW("dropping %d events on the floor", count);
return size;
}
- LOGE_IF(size<0, "dropping %d events on the floor (%s)",
- count, strerror(-size));
+ //LOGE_IF(size<0, "dropping %d events on the floor (%s)",
+ // count, strerror(-size));
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 680814cf230a..4a2770191013 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1318,9 +1318,6 @@ sp<ISurface> SurfaceFlinger::createSurface(
if (surfaceHandle != 0) {
params->token = token;
params->identity = layer->getIdentity();
- params->width = w;
- params->height = h;
- params->format = format;
if (normalLayer != 0) {
Mutex::Autolock _l(mStateLock);
mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
diff --git a/services/surfaceflinger/SurfaceTextureLayer.cpp b/services/surfaceflinger/SurfaceTextureLayer.cpp
index 11f61ccb1ada..91e010f90fe8 100644
--- a/services/surfaceflinger/SurfaceTextureLayer.cpp
+++ b/services/surfaceflinger/SurfaceTextureLayer.cpp
@@ -60,7 +60,11 @@ status_t SurfaceTextureLayer::queueBuffer(int buf, int64_t timestamp,
sp<Layer> layer(mLayer.promote());
if (layer != NULL) {
- *outTransform = layer->getOrientation();
+ uint32_t orientation = layer->getOrientation();
+ if (orientation & Transform::ROT_INVALID) {
+ orientation = 0;
+ }
+ *outTransform = orientation;
}
return res;
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 4f8b5256ee82..3bd78e043255 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -36,6 +36,7 @@ import android.os.Messenger;
import android.os.SystemProperties;
import android.preference.PreferenceManager;
import android.provider.Settings;
+import android.telephony.ServiceState;
import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;
import android.util.Log;
@@ -1031,6 +1032,27 @@ public abstract class DataConnectionTracker extends Handler {
protected void onSetDependencyMet(String apnType, boolean met) {
}
+ protected String getReryConfig(boolean forDefault) {
+ int rt = mPhone.getServiceState().getRadioTechnology();
+
+ if ((rt == ServiceState.RADIO_TECHNOLOGY_IS95A) ||
+ (rt == ServiceState.RADIO_TECHNOLOGY_IS95B) ||
+ (rt == ServiceState.RADIO_TECHNOLOGY_1xRTT) ||
+ (rt == ServiceState.RADIO_TECHNOLOGY_EVDO_0) ||
+ (rt == ServiceState.RADIO_TECHNOLOGY_EVDO_A) ||
+ (rt == ServiceState.RADIO_TECHNOLOGY_EVDO_B) ||
+ (rt == ServiceState.RADIO_TECHNOLOGY_EHRPD)) {
+ // CDMA variant
+ return SystemProperties.get("ro.cdma.data_retry_config");
+ } else {
+ // Use GSM varient for all others.
+ if (forDefault) {
+ return SystemProperties.get("ro.gsm.data_retry_config");
+ } else {
+ return SystemProperties.get("ro.gsm.2nd_data_retry_config");
+ }
+ }
+ }
protected void resetAllRetryCounts() {
for (DataConnection dc : mDataConnections.values()) {
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 40a70a806ce1..a0961caaa40d 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -806,10 +806,10 @@ public abstract class PhoneBase extends Handler implements Phone {
mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
}
- public void notifyDataConnection() {
+ public void notifyDataConnection(String reason) {
String types[] = getActiveApnTypes();
for (String apnType : types) {
- mNotifier.notifyDataConnection(this, null, apnType, getDataConnectionState(apnType));
+ mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
}
}
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 93fc9cebd81e..facee5f67bdc 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -31,6 +31,8 @@ public interface RILConstants {
// From the top of ril.cpp
int RIL_ERRNO_INVALID_RESPONSE = -1;
+ int MAX_INT = 0x7FFFFFFF;
+
// from RIL_Errno
int SUCCESS = 0;
int RADIO_NOT_AVAILABLE = 1; /* If radio did not start or is resetting */
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index 0d551aade502..d3bb6a546d94 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -134,8 +134,6 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
}
}
- // Not sure if this is needed in CDMALTE phone.
- // mDataRoaming = regCodeIsRoaming(regState);
mLteSS.setRadioTechnology(type);
mLteSS.setState(regCodeToServiceState(regState));
} else {
@@ -249,10 +247,11 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
boolean hasLocationChanged = !newCellLoc.equals(cellLoc);
boolean has4gHandoff =
- ((networkType == ServiceState.RADIO_TECHNOLOGY_LTE) &&
- (newNetworkType == ServiceState.RADIO_TECHNOLOGY_EHRPD)) ||
- ((networkType == ServiceState.RADIO_TECHNOLOGY_EHRPD) &&
- (newNetworkType == ServiceState.RADIO_TECHNOLOGY_LTE));
+ mNewDataConnectionState == ServiceState.STATE_IN_SERVICE &&
+ (((networkType == ServiceState.RADIO_TECHNOLOGY_LTE) &&
+ (newNetworkType == ServiceState.RADIO_TECHNOLOGY_EHRPD)) ||
+ ((networkType == ServiceState.RADIO_TECHNOLOGY_EHRPD) &&
+ (newNetworkType == ServiceState.RADIO_TECHNOLOGY_LTE)));
boolean hasMultiApnSupport =
(((newNetworkType == ServiceState.RADIO_TECHNOLOGY_LTE) ||
@@ -345,13 +344,14 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
}
if (cm.getSimState().isSIMReady()) {
- // SIM is found on the device. If ERI roaming is OFF, use operator name
- // from CSIM record.
+ // SIM is found on the device. If ERI roaming is OFF and SID/NID matches
+ // one configfured in SIM, use operator name from CSIM record.
boolean showSpn =
((CdmaLteUiccRecords)phone.mIccRecords).getCsimSpnDisplayCondition();
int iconIndex = ss.getCdmaEriIconIndex();
- if (showSpn && (iconIndex == EriInfo.ROAMING_INDICATOR_OFF)) {
+ if (showSpn && (iconIndex == EriInfo.ROAMING_INDICATOR_OFF) &&
+ isInHomeSidNid(ss.getSystemId(), ss.getNetworkId())) {
ss.setOperatorAlphaLong(phone.mIccRecords.getServiceProviderName());
}
}
@@ -392,7 +392,7 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
phone.notifyServiceStateChanged(ss);
}
- if (hasCdmaDataConnectionAttached) {
+ if (hasCdmaDataConnectionAttached || has4gHandoff) {
mAttachedRegistrants.notifyRegistrants();
}
@@ -401,7 +401,7 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
}
if ((hasCdmaDataConnectionChanged || hasNetworkTypeChanged)) {
- phone.notifyDataConnection();
+ phone.notifyDataConnection(null);
}
if (hasRoamingOn) {
@@ -469,6 +469,34 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker {
}
/**
+ * Check whether the specified SID and NID pair appears in the HOME SID/NID list
+ * read from NV or SIM.
+ *
+ * @return true if provided sid/nid pair belongs to operator's home network.
+ */
+ private boolean isInHomeSidNid(int sid, int nid) {
+ // if SID/NID is not available, assume this is home network.
+ if (isSidsAllZeros()) return true;
+
+ // length of SID/NID shold be same
+ if (mHomeSystemId.length != mHomeNetworkId.length) return true;
+
+ if (sid == 0) return true;
+
+ for (int i = 0; i < mHomeSystemId.length; i++) {
+ // Use SID only if NID is a reserved value.
+ // SID 0 and NID 0 and 65535 are reserved. (C.0005 2.6.5.2)
+ if ((mHomeSystemId[i] == sid) &&
+ ((mHomeNetworkId[i] == 0) || (mHomeNetworkId[i] == 65535) ||
+ (nid == 0) || (nid == 65535) || (mHomeNetworkId[i] == nid))) {
+ return true;
+ }
+ }
+ // SID/NID are not in the list. So device is not in home network
+ return false;
+ }
+
+ /**
* Returns OTASP_NOT_NEEDED as its not needed for LTE
*/
@Override
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 24a468a7d2c1..2cf4b8812a37 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -130,8 +130,8 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
protected String mCurPlmn = null;
protected String mMdn;
- private int mHomeSystemId[] = null;
- private int mHomeNetworkId[] = null;
+ protected int mHomeSystemId[] = null;
+ protected int mHomeNetworkId[] = null;
protected String mMin;
protected String mPrlVersion;
protected boolean mIsMinInfoReady = false;
@@ -999,7 +999,7 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
}
if (hasCdmaDataConnectionChanged || hasNetworkTypeChanged) {
- phone.notifyDataConnection();
+ phone.notifyDataConnection(null);
}
if (hasRoamingOn) {
@@ -1481,7 +1481,7 @@ public class CdmaServiceStateTracker extends ServiceStateTracker {
}
}
- private boolean isSidsAllZeros() {
+ protected boolean isSidsAllZeros() {
if (mHomeSystemId != null) {
for (int i=0; i < mHomeSystemId.length; i++) {
if (mHomeSystemId[i] != 0) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index ccdb0bf69a5b..be129d56346a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -609,9 +609,20 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
for (DataConnectionAc dcac : mDataConnectionAsyncChannels.values()) {
if (dcac.getReconnectIntentSync() != null) {
cancelReconnectAlarm(dcac);
- if (dcac.dataConnection != null) {
- dcac.dataConnection.resetRetryCount();
+ }
+ // update retry config for existing calls to match up
+ // ones for the new RAT.
+ if (dcac.dataConnection != null) {
+ Collection<ApnContext> apns = dcac.getApnListSync();
+
+ boolean hasDefault = false;
+ for (ApnContext apnContext : apns) {
+ if (apnContext.getApnType().equals(Phone.APN_TYPE_DEFAULT)) {
+ hasDefault = true;
+ break;
+ }
}
+ configureRetry(dcac.dataConnection, hasDefault);
}
}
@@ -973,7 +984,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
// configure retry count if no other Apn is using the same connection.
if (refCount == 0) {
- configureRetry(dc, apnContext.getApnType());
+ configureRetry(dc, apn.canHandleType(Phone.APN_TYPE_DEFAULT));
}
apnContext.setDataConnectionAc(dcac);
apnContext.setDataConnection(dc);
@@ -1834,7 +1845,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
retryOverride =
((DataConnection.CallSetupException)ar.exception).getRetryOverride();
}
- startDelayedRetry(cause, apnContext, retryOverride);
+ if (retryOverride == RILConstants.MAX_INT) {
+ if (DBG) log("No retry is suggested.");
+ } else {
+ startDelayedRetry(cause, apnContext, retryOverride);
+ }
}
} else {
if (DBG) log("onDataSetupComplete: Try next APN");
@@ -2022,20 +2037,18 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
return conn;
}
- private void configureRetry(DataConnection dc, String apnType) {
- if ((dc == null) || (apnType == null)) return;
+ private void configureRetry(DataConnection dc, boolean forDefault) {
+ if (dc == null) return;
- if (apnType.equals(Phone.APN_TYPE_DEFAULT)) {
- if (!dc.configureRetry(SystemProperties.get("ro.gsm.data_retry_config"))) {
+ if (!dc.configureRetry(getReryConfig(forDefault))) {
+ if (forDefault) {
if (!dc.configureRetry(DEFAULT_DATA_RETRY_CONFIG)) {
// Should never happen, log an error and default to a simple linear sequence.
loge("configureRetry: Could not configure using " +
"DEFAULT_DATA_RETRY_CONFIG=" + DEFAULT_DATA_RETRY_CONFIG);
dc.configureRetry(20, 2000, 1000);
}
- }
- } else {
- if (!dc.configureRetry(SystemProperties.get("ro.gsm.2nd_data_retry_config"))) {
+ } else {
if (!dc.configureRetry(SECONDARY_DATA_RETRY_CONFIG)) {
// Should never happen, log an error and default to a simple sequence.
loge("configureRetry: Could note configure using " +
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index 93f4b4ea579a..d3645faba86f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -915,7 +915,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
if (hasRadioTechnologyChanged) {
- phone.notifyDataConnection(Phone.REASON_NW_TYPE_CHANGED, Phone.APN_TYPE_ALL);
+ phone.notifyDataConnection(Phone.REASON_NW_TYPE_CHANGED);
}
if (hasRoamingOn) {
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
index 1493ab9ffcd8..13b6129ab1ac 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ListActivity.java
@@ -93,12 +93,9 @@ public class ListActivity extends Activity {
}
public void startProfiling(View v) {
- ViewDebug.startLooperProfiling(new File(Environment.getExternalStorageDirectory(),
- "looper.trace"));
}
public void stopProfiling(View v) {
- ViewDebug.stopLooperProfiling();
}
@Override
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index e77646397f9e..9aa70b0e0b60 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -87,8 +87,6 @@ public class ImageProcessingActivity extends Activity
mIsProcessing = false;
}
- // This is a hack to work around an invalidation bug
- mBitmapOut.setPixel(0, 0, 0);
mOutPixelsAllocation.copyTo(mBitmapOut);
mDisplayView.invalidate();
}
diff --git a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
index b21253342093..e75a0797dfa7 100644
--- a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
@@ -100,22 +100,22 @@ public class StatusBarTest extends TestActivity
new Test("Double Remove") {
public void run() {
Log.d(TAG, "set 0");
- mStatusBarManager.setIcon("speakerphone", R.drawable.stat_sys_phone, 0);
+ mStatusBarManager.setIcon("speakerphone", R.drawable.stat_sys_phone, 0, null);
Log.d(TAG, "remove 1");
mStatusBarManager.removeIcon("tty");
SystemClock.sleep(1000);
Log.d(TAG, "set 1");
- mStatusBarManager.setIcon("tty", R.drawable.stat_sys_phone, 0);
+ mStatusBarManager.setIcon("tty", R.drawable.stat_sys_phone, 0, null);
if (false) {
Log.d(TAG, "set 2");
- mStatusBarManager.setIcon("tty", R.drawable.stat_sys_phone, 0);
+ mStatusBarManager.setIcon("tty", R.drawable.stat_sys_phone, 0, null);
}
Log.d(TAG, "remove 2");
mStatusBarManager.removeIcon("tty");
Log.d(TAG, "set 3");
- mStatusBarManager.setIcon("speakerphone", R.drawable.stat_sys_phone, 0);
+ mStatusBarManager.setIcon("speakerphone", R.drawable.stat_sys_phone, 0, null);
}
},
new Test("Hide (FLAG_FULLSCREEN)") {
diff --git a/tests/TileBenchmark/AndroidManifest.xml b/tests/TileBenchmark/AndroidManifest.xml
index 663cc0dbea6f..ab61a9e25bb7 100644
--- a/tests/TileBenchmark/AndroidManifest.xml
+++ b/tests/TileBenchmark/AndroidManifest.xml
@@ -7,14 +7,16 @@
android:label="@string/app_name"
android:hardwareAccelerated="true">
<activity android:name=".ProfileActivity"
- android:label="@string/profile_activity">
+ android:label="@string/profile_activity"
+ android:theme="@android:style/Theme.Holo.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".PlaybackActivity"
- android:label="@string/playback_activity">
+ android:label="@string/playback_activity"
+ android:theme="@android:style/Theme.Holo.NoActionBar">
</activity>
</application>
</manifest>
diff --git a/tests/TileBenchmark/res/layout/main.xml b/tests/TileBenchmark/res/layout/main.xml
index 4a81da65edb9..577c466e3847 100644
--- a/tests/TileBenchmark/res/layout/main.xml
+++ b/tests/TileBenchmark/res/layout/main.xml
@@ -23,11 +23,11 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
- <Button
- android:id="@+id/inspect"
+ <Spinner
+ android:id="@+id/movement"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/inspect_log"
+ android:prompt="@string/movement_method"
/>
<Spinner
android:id="@+id/velocity"
@@ -36,6 +36,13 @@
android:gravity="center_horizontal"
android:prompt="@string/desired_scroll_velocity"
/>
+ <ToggleButton
+ android:id="@+id/capture"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textOn="@string/capture_stop"
+ android:textOff="@string/capture_start"
+ />
<EditText
android:id="@+id/url"
android:layout_width="0dip"
@@ -44,6 +51,12 @@
android:imeOptions="actionGo"
android:layout_weight="1"
/>
+ <Button
+ android:id="@+id/inspect"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/inspect_log"
+ />
</LinearLayout>
<com.test.tilebenchmark.ProfiledWebView
android:id="@+id/web"
diff --git a/tests/TileBenchmark/res/values/colors.xml b/tests/TileBenchmark/res/values/colors.xml
index 3958083febd5..dbb8e7295b8b 100644
--- a/tests/TileBenchmark/res/values/colors.xml
+++ b/tests/TileBenchmark/res/values/colors.xml
@@ -18,8 +18,17 @@
<color name="ready_tile">#ff4ac230</color>
<!-- The color of tiles with stale / invalid textures -->
<color name="unready_tile">#ff744400</color>
- <!-- Background color for logged URLs -->
- <color name="finished_url">#ff004000</color>
- <!-- Background color for URLs with logging in progress -->
- <color name="unfinished_url">#ff400000</color>
+ <!-- Viewport overlay in playback -->
+ <color name="view">#50000050</color>
+ <!-- Invalidated region overlay in playback - start color -->
+ <color name="inval_region_start">#80ff0000</color>
+ <!-- Invalidated region overlay in playback - stop color-->
+ <color name="inval_region_stop">#80ffffff</color>
+
+ <!-- Background color for not testing -->
+ <color name="background_not_testing">#ff000000</color>
+ <!-- Background color for during testing -->
+ <color name="background_start_testing">#ff400000</color>
+ <!-- Background color for testing complete -->
+ <color name="background_stop_testing">#ff004000</color>
</resources>
diff --git a/tests/TileBenchmark/res/values/strings.xml b/tests/TileBenchmark/res/values/strings.xml
index f70ee2c04a3f..66972ac26bab 100644
--- a/tests/TileBenchmark/res/values/strings.xml
+++ b/tests/TileBenchmark/res/values/strings.xml
@@ -28,6 +28,10 @@
<string name="loadbutton">Load</string>
<!-- Button, opens the playback activity [CHAR LIMIT=20] -->
<string name="inspect_log">Inspect Log</string>
+ <!-- ToggleButton label when pressing starts capture [CHAR LIMIT=15] -->
+ <string name="capture_start">Start Capture</string>
+ <!-- ToggleButton label when pressing stops capture [CHAR LIMIT=15] -->
+ <string name="capture_stop">Stop Capture</string>
<!-- The speed of auto-scrolling [CHAR LIMIT=30] -->
<string name="desired_scroll_velocity">Choose Scroll Velocity</string>
<!-- Pixels moved per frame [CHAR LIMIT=10] -->
@@ -39,6 +43,21 @@
<item>200</item>
<item>400</item>
</string-array>
+ <!-- Drop down menu for selecting scrolling vs manual navigation for
+ capturing [CHAR LIMIT=15] -->
+ <string name="movement_method">Movement Method</string>
+ <!-- Drop down menu entry - automatically scroll to the end of the page
+ with scrollBy() [CHAR LIMIT=15] -->
+ <string name="movement_auto_scroll">Auto-scroll</string>
+ <!-- Drop down menu entry - [CHAR LIMIT=15] -->
+ <string name="movement_auto_fling">Auto-fling</string>
+ <!-- Drop down menu entry - manually navigate the page(s), hit 'capture'
+ button [CHAR LIMIT=15] -->
+ <string name="movement_manual">Manual</string>
+
+ <!-- Error popup indicating log data couldn't be loaded [CHAR LIMIT=60] -->
+ <string name="error_no_data">Error: log data could not be loaded.</string>
+
<!-- 25th percentile - 25% of frames fall below this value [CHAR LIMIT=12]
-->
<string name="percentile_25">25%ile</string>
@@ -56,7 +75,7 @@
<string name="format_stat">%4.4f</string>
<!-- Format string for displaying aggregate stats+values (nr of valid tiles,
etc.) [CHAR LIMIT=20] -->
- <string name="format_stat_name">%1$9s %2$3d</string>
+ <string name="format_stat_name">%1$-20s %2$3d</string>
<!-- Text hovering over canvas, number of tiles ready [CHAR LIMIT=15] -->
<string name="ready_tiles">Ready Tiles</string>
<!-- Text hovering over canvas, number tiles not ready [CHAR LIMIT=15] -->
@@ -64,4 +83,7 @@
<!-- Text hovering over canvas, number of tiles that haven't been
allocated to a place on the page [CHAR LIMIT=15] -->
<string name="unplaced_tiles">Unplaced Tiles</string>
+ <!-- Text hovering over canvas, number of invalidated regions this frame
+ [CHAR LIMIT=15] -->
+ <string name="number_invalidates">Invalidates</string>
</resources>
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java
index 5130f5d3ab3f..36694a7476f4 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackActivity.java
@@ -27,6 +27,7 @@ import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
+import android.widget.Toast;
import java.io.FileInputStream;
import java.io.IOException;
@@ -102,7 +103,10 @@ public class PlaybackActivity extends Activity {
@Override
protected void onPostExecute(TileData data[][]) {
if (data == null) {
- data = genTestPattern();
+ Toast.makeText(getApplicationContext(),
+ getResources().getString(R.string.error_no_data),
+ Toast.LENGTH_LONG).show();
+ return;
}
mPlaybackView.setData(data);
@@ -166,23 +170,4 @@ public class PlaybackActivity extends Activity {
new LoadFileTask().execute(ProfileActivity.TEMP_FILENAME);
}
-
- private TileData[][] genTestPattern() {
- final int XMAX = 5;
- final int FRAMEMAX = 99;
-
- TileData example[][] = new TileData[FRAMEMAX][];
- for (int frame = 0; frame < FRAMEMAX; frame++) {
- int numTiles = frame + 10;
-
- example[frame] = new TileData[numTiles];
- for (int t = 0; t < numTiles; t++) {
- int x = t % XMAX;
- int y = t / XMAX;
- boolean isReady = y * 10 < frame;
- example[frame][t] = new TileData(x, y, isReady, 0);
- }
- }
- return example;
- }
}
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
index db4a34182bac..35b1563ed895 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
@@ -28,19 +28,17 @@ import java.util.ArrayList;
import java.util.Arrays;
public class PlaybackGraphs {
- private static final int BAR_WIDTH = PlaybackView.TILEX * 3;
+ private static final int BAR_WIDTH = PlaybackView.TILE_SCALE * 3;
private static final float CANVAS_SCALE = 0.2f;
private static final double IDEAL_FRAMES = 60;
private static final int LABELOFFSET = 100;
private static Paint whiteLabels;
- private static double viewportCoverage(int l, int b, int r, int t,
- int tileIndexX,
- int tileIndexY) {
- if (tileIndexX * PlaybackView.TILEX < r
- && (tileIndexX + 1) * PlaybackView.TILEX >= l
- && tileIndexY * PlaybackView.TILEY < t
- && (tileIndexY + 1) * PlaybackView.TILEY >= b) {
+ private static double viewportCoverage(TileData view, TileData tile) {
+ if (tile.left < view.right
+ && tile.right >= view.left
+ && tile.top < view.bottom
+ && tile.bottom >= view.top) {
return 1.0f;
}
return 0.0f;
@@ -76,13 +74,10 @@ public class PlaybackGraphs {
// coverage graph
@Override
public double getValue(TileData[] frame) {
- int l = frame[0].x, b = frame[0].y;
- int r = frame[1].x, t = frame[1].y;
double total = 0, totalCount = 0;
- for (int tileID = 2; tileID < frame.length; tileID++) {
+ for (int tileID = 1; tileID < frame.length; tileID++) {
TileData data = frame[tileID];
- double coverage = viewportCoverage(l, b, r, t, data.x,
- data.y);
+ double coverage = viewportCoverage(frame[0], data);
total += coverage * (data.isReady ? 1 : 0);
totalCount += coverage;
}
@@ -158,7 +153,7 @@ public class PlaybackGraphs {
public PlaybackGraphs() {
whiteLabels = new Paint();
whiteLabels.setColor(Color.WHITE);
- whiteLabels.setTextSize(PlaybackView.TILEY / 3);
+ whiteLabels.setTextSize(PlaybackView.TILE_SCALE / 3);
}
private ArrayList<ShapeDrawable> mShapes = new ArrayList<ShapeDrawable>();
@@ -177,11 +172,13 @@ public class PlaybackGraphs {
int lastBar = 0;
for (int frameIndex = 0; frameIndex < tileProfilingData.length; frameIndex++) {
TileData frame[] = tileProfilingData[frameIndex];
- int newBar = (frame[0].y + frame[1].y) / 2;
+ int newBar = (frame[0].top + frame[0].bottom) / 2;
MetricGen s = Metrics[metricIndex];
double absoluteValue = s.getValue(frame);
double relativeValue = absoluteValue / s.getMax();
+ relativeValue = Math.min(1,relativeValue);
+ relativeValue = Math.max(0,relativeValue);
int rightPos = (int) (-BAR_WIDTH * metricIndex);
int leftPos = (int) (-BAR_WIDTH * (metricIndex + relativeValue));
@@ -207,7 +204,7 @@ public class PlaybackGraphs {
ArrayList<ShapeDrawable> shapes) {
// Shapes drawn here are drawn relative to the viewRect
Rect viewRect = shapes.get(shapes.size() - 1).getBounds();
- canvas.translate(0, 5 * PlaybackView.TILEY - viewRect.top);
+ canvas.translate(0, 5 * PlaybackView.TILE_SCALE - viewRect.top);
for (ShapeDrawable shape : mShapes) {
shape.draw(canvas);
@@ -234,13 +231,15 @@ public class PlaybackGraphs {
int yPos = LABELOFFSET;
canvas.drawText(label, xPos, yPos, whiteLabels);
for (int statIndex = 0; statIndex < Stats.length; statIndex++) {
- label = resources.getString(R.string.format_stat, mStats[metricIndex][statIndex]);
- yPos = LABELOFFSET + (1 + statIndex) * PlaybackView.TILEY / 2;
+ label = resources.getString(R.string.format_stat,
+ mStats[metricIndex][statIndex]);
+ yPos = LABELOFFSET + (1 + statIndex) * PlaybackView.TILE_SCALE
+ / 2;
canvas.drawText(label, xPos, yPos, whiteLabels);
}
}
for (int stringIndex = 0; stringIndex < strings.length; stringIndex++) {
- int yPos = LABELOFFSET + stringIndex * PlaybackView.TILEY / 2;
+ int yPos = LABELOFFSET + stringIndex * PlaybackView.TILE_SCALE / 2;
canvas.drawText(strings[stringIndex], 0, yPos, whiteLabels);
}
}
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java
index f104eac21b89..edc8643e5b24 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackView.java
@@ -16,6 +16,9 @@
package com.test.tilebenchmark;
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -30,8 +33,9 @@ import android.view.View;
import java.util.ArrayList;
public class PlaybackView extends View {
- public static final int TILEX = 300;
- public static final int TILEY = 300;
+ public static final int TILE_SCALE = 300;
+ private static final int INVAL_FLAG = -2;
+ private static final int INVAL_CYCLE = 250;
private Paint levelPaint = null, coordPaint = null, goldPaint = null;
private PlaybackGraphs mGraphs;
@@ -39,28 +43,46 @@ public class PlaybackView extends View {
private ArrayList<ShapeDrawable> mTempShapes = new ArrayList<ShapeDrawable>();
private TileData mProfData[][] = null;
private GestureDetector mGestureDetector = null;
- private String mRenderStrings[] = new String[3];
+ private String mRenderStrings[] = new String[4];
private class TileDrawable extends ShapeDrawable {
TileData tile;
+ String label;
- public TileDrawable(TileData t) {
- int tileColorId = t.isReady ? R.color.ready_tile
- : R.color.unready_tile;
- getPaint().setColor(getResources().getColor(tileColorId));
-
- setBounds(t.x * TILEX, t.y * TILEY, (t.x + 1) * TILEX, (t.y + 1)
- * TILEY);
+ public TileDrawable(TileData t, int colorId) {
this.tile = t;
+ getPaint().setColor(getResources().getColor(colorId));
+ if (colorId == R.color.ready_tile
+ || colorId == R.color.unready_tile) {
+
+ label = (int) (t.left / TILE_SCALE) + ", "
+ + (int) (t.top / TILE_SCALE);
+ // ignore scale value for tiles
+ setBounds(t.left, t.top,
+ t.right, t.bottom);
+ } else {
+ setBounds((int) (t.left * t.scale),
+ (int) (t.top * t.scale),
+ (int) (t.right * t.scale),
+ (int) (t.bottom * t.scale));
+ }
+ }
+
+ @SuppressWarnings("unused")
+ public void setColor(int color) {
+ getPaint().setColor(color);
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
- canvas.drawText(Integer.toString(tile.level), getBounds().left,
- getBounds().bottom, levelPaint);
- canvas.drawText(tile.x + "," + tile.y, getBounds().left,
- ((getBounds().bottom + getBounds().top) / 2), coordPaint);
+ if (label != null) {
+ canvas.drawText(Integer.toString(tile.level), getBounds().left,
+ getBounds().bottom, levelPaint);
+ canvas.drawText(label, getBounds().left,
+ ((getBounds().bottom + getBounds().top) / 2),
+ coordPaint);
+ }
}
}
@@ -92,10 +114,10 @@ public class PlaybackView extends View {
private void init() {
levelPaint = new Paint();
levelPaint.setColor(Color.WHITE);
- levelPaint.setTextSize(TILEY / 2);
+ levelPaint.setTextSize(TILE_SCALE / 2);
coordPaint = new Paint();
coordPaint.setColor(Color.BLACK);
- coordPaint.setTextSize(TILEY / 3);
+ coordPaint.setTextSize(TILE_SCALE / 3);
goldPaint = new Paint();
goldPaint.setColor(0xffa0e010);
mGraphs = new PlaybackGraphs();
@@ -110,6 +132,7 @@ public class PlaybackView extends View {
}
mGraphs.draw(canvas, mTempShapes, mRenderStrings, getResources());
+ invalidate(); // may have animations, force redraw
}
public int setFrame(int frame) {
@@ -117,35 +140,66 @@ public class PlaybackView extends View {
return 0;
}
- int readyTiles = 0, unreadyTiles = 0, unplacedTiles = 0;
+ int readyTiles = 0, unreadyTiles = 0, unplacedTiles = 0, numInvals = 0;
mTempShapes.clear();
- // draw actual tiles
- for (int tileID = 2; tileID < mProfData[frame].length; tileID++) {
- TileData t = mProfData[frame][tileID];
- mTempShapes.add(new TileDrawable(t));
- if (t.isReady) {
- readyTiles++;
+ // create tile shapes (as they're drawn on bottom)
+ for (TileData t : mProfData[frame]) {
+ if (t.level != INVAL_FLAG && t != mProfData[frame][0]) {
+ int colorId;
+ if (t.isReady) {
+ readyTiles++;
+ colorId = R.color.ready_tile;
+ } else {
+ unreadyTiles++;
+ colorId = R.color.unready_tile;
+ }
+ if (t.left < 0 || t.top < 0) {
+ unplacedTiles++;
+ }
+ mTempShapes.add(new TileDrawable(t, colorId));
} else {
- unreadyTiles++;
+ numInvals++;
}
- if (t.x < 0 || t.y < 0) {
- unplacedTiles++;
+ }
+
+ // create invalidate shapes (drawn above tiles)
+ int invalId = 0;
+ for (TileData t : mProfData[frame]) {
+ if (t.level == INVAL_FLAG && t != mProfData[frame][0]) {
+ TileDrawable invalShape = new TileDrawable(t,
+ R.color.inval_region_start);
+ ValueAnimator tileAnimator = ObjectAnimator.ofInt(invalShape,
+ "color",
+ getResources().getColor(R.color.inval_region_start),
+ getResources().getColor(R.color.inval_region_stop));
+ tileAnimator.setDuration(numInvals * INVAL_CYCLE);
+ tileAnimator.setEvaluator(new ArgbEvaluator());
+ tileAnimator.setRepeatCount(ValueAnimator.INFINITE);
+ tileAnimator.setRepeatMode(ValueAnimator.RESTART);
+ float delay = (float) (invalId) * INVAL_CYCLE;
+ tileAnimator.setStartDelay((int) delay);
+ invalId++;
+ tileAnimator.start();
+
+ mTempShapes.add(invalShape);
}
}
+
mRenderStrings[0] = getResources().getString(R.string.format_stat_name,
getResources().getString(R.string.ready_tiles), readyTiles);
mRenderStrings[1] = getResources().getString(R.string.format_stat_name,
getResources().getString(R.string.unready_tiles), unreadyTiles);
mRenderStrings[2] = getResources().getString(R.string.format_stat_name,
- getResources().getString(R.string.unplaced_tiles), unplacedTiles);
-
- // draw view rect (using first two TileData objects)
- ShapeDrawable viewShape = new ShapeDrawable();
- viewShape.getPaint().setColor(0xff0000ff);
- viewShape.setAlpha(64);
- viewShape.setBounds(mProfData[frame][0].x, mProfData[frame][0].y,
- mProfData[frame][1].x, mProfData[frame][1].y);
+ getResources().getString(R.string.unplaced_tiles),
+ unplacedTiles);
+ mRenderStrings[3] = getResources().getString(R.string.format_stat_name,
+ getResources().getString(R.string.number_invalidates),
+ numInvals);
+
+ // draw view rect (using first TileData object, on top)
+ TileDrawable viewShape = new TileDrawable(mProfData[frame][0],
+ R.color.view);
mTempShapes.add(viewShape);
this.invalidate();
return frame;
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java
index 23b62751b931..1521807eb1dc 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java
@@ -38,6 +38,7 @@ import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
+import android.widget.ToggleButton;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -58,11 +59,24 @@ public class ProfileActivity extends Activity {
// before test
Button mInspectButton;
+ ToggleButton mCaptureButton;
Spinner mVelocitySpinner;
+ Spinner mMovementSpinner;
EditText mUrl;
ProfiledWebView mWeb;
ProfileCallback mCallback;
+ LoggingWebViewClient mLoggingWebViewClient = new LoggingWebViewClient();
+ AutoLoggingWebViewClient mAutoLoggingWebViewClient = new AutoLoggingWebViewClient();
+
+ private enum TestingState {
+ NOT_TESTING,
+ PRE_TESTING,
+ START_TESTING,
+ STOP_TESTING,
+ SAVED_TESTING
+ };
+
private class VelocitySelectedListener implements OnItemSelectedListener {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
@@ -77,6 +91,31 @@ public class ProfileActivity extends Activity {
}
}
+ private class MovementSelectedListener implements OnItemSelectedListener {
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view,
+ int position, long id) {
+ String movementStr = parent.getItemAtPosition(position).toString();
+ if (movementStr == getResources().getString(
+ R.string.movement_auto_scroll)
+ || movementStr == getResources().getString(
+ R.string.movement_auto_fling)) {
+ mWeb.setWebViewClient(mAutoLoggingWebViewClient);
+ mCaptureButton.setEnabled(false);
+ mVelocitySpinner.setEnabled(true);
+ } else if (movementStr == getResources().getString(
+ R.string.movement_manual)) {
+ mWeb.setWebViewClient(mLoggingWebViewClient);
+ mCaptureButton.setEnabled(true);
+ mVelocitySpinner.setEnabled(false);
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ }
+ }
+
private class LoggingWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
@@ -88,6 +127,9 @@ public class ProfileActivity extends Activity {
super.onPageStarted(view, url, favicon);
mUrl.setText(url);
}
+ }
+
+ private class AutoLoggingWebViewClient extends LoggingWebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
@@ -100,10 +142,16 @@ public class ProfileActivity extends Activity {
@Override
public void onFinish() {
- mWeb.startScrollTest(mCallback);
+ startViewProfiling(true);
}
}.start();
}
+
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ super.onPageStarted(view, url, favicon);
+ setTestingState(TestingState.PRE_TESTING);
+ }
}
private class StoreFileTask extends
@@ -125,24 +173,65 @@ public class ProfileActivity extends Activity {
@Override
protected void onPostExecute(Void v) {
- mUrl.setBackgroundResource(R.color.finished_url);
+ setTestingState(TestingState.SAVED_TESTING);
}
}
+ public void setTestingState(TestingState state) {
+ switch (state) {
+ case NOT_TESTING:
+ mUrl.setBackgroundResource(R.color.background_not_testing);
+ mInspectButton.setEnabled(true);
+ mMovementSpinner.setEnabled(true);
+ break;
+ case PRE_TESTING:
+ mInspectButton.setEnabled(false);
+ mMovementSpinner.setEnabled(false);
+ break;
+ case START_TESTING:
+ mUrl.setBackgroundResource(R.color.background_start_testing);
+ mInspectButton.setEnabled(false);
+ mMovementSpinner.setEnabled(false);
+ break;
+ case STOP_TESTING:
+ mUrl.setBackgroundResource(R.color.background_stop_testing);
+ break;
+ case SAVED_TESTING:
+ mInspectButton.setEnabled(true);
+ mMovementSpinner.setEnabled(true);
+ break;
+ }
+ }
+
+ /** auto - automatically scroll. */
+ private void startViewProfiling(boolean auto) {
+ if (!auto) {
+ // manual, toggle capture button to indicate capture state to user
+ mCaptureButton.setChecked(true);
+ }
+ mWeb.startScrollTest(mCallback, auto);
+ setTestingState(TestingState.START_TESTING);
+ }
+
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mInspectButton = (Button) findViewById(R.id.inspect);
+ mCaptureButton = (ToggleButton) findViewById(R.id.capture);
mVelocitySpinner = (Spinner) findViewById(R.id.velocity);
+ mMovementSpinner = (Spinner) findViewById(R.id.movement);
mUrl = (EditText) findViewById(R.id.url);
mWeb = (ProfiledWebView) findViewById(R.id.web);
mCallback = new ProfileCallback() {
@SuppressWarnings("unchecked")
@Override
public void profileCallback(TileData[][] data) {
- new StoreFileTask().execute(new Pair<String, TileData[][]>(TEMP_FILENAME, data));
+ new StoreFileTask().execute(new Pair<String, TileData[][]>(
+ TEMP_FILENAME, data));
+ mCaptureButton.setChecked(false);
+ setTestingState(TestingState.STOP_TESTING);
}
};
@@ -166,6 +255,33 @@ public class ProfileActivity extends Activity {
new VelocitySelectedListener());
mVelocitySpinner.setSelection(3);
+ // Movement spinner
+ String content[] = {
+ getResources().getString(R.string.movement_auto_scroll),
+ getResources().getString(R.string.movement_auto_fling),
+ getResources().getString(R.string.movement_manual)
+ };
+ adapter = new ArrayAdapter<CharSequence>(this,
+ android.R.layout.simple_spinner_item, content);
+ adapter.setDropDownViewResource(
+ android.R.layout.simple_spinner_dropdown_item);
+ mMovementSpinner.setAdapter(adapter);
+ mMovementSpinner.setOnItemSelectedListener(
+ new MovementSelectedListener());
+ mMovementSpinner.setSelection(0);
+
+ // Capture toggle button
+ mCaptureButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mCaptureButton.isChecked()) {
+ startViewProfiling(false);
+ } else {
+ mWeb.stopScrollTest();
+ }
+ }
+ });
+
// Custom profiling WebView
WebSettings settings = mWeb.getSettings();
settings.setJavaScriptEnabled(true);
@@ -180,12 +296,13 @@ public class ProfileActivity extends Activity {
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
String url = mUrl.getText().toString();
- mUrl.setBackgroundResource(R.color.unfinished_url);
mWeb.loadUrl(url);
mWeb.requestFocus();
return true;
}
});
+
+ setTestingState(TestingState.NOT_TESTING);
}
public void setCallback(ProfileCallback callback) {
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
index 656062421b97..d3941be41302 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java
@@ -59,12 +59,13 @@ public class ProfiledWebView extends WebView {
}
/*
- * Called once the page is loaded to start scrolling for evaluating tiles
+ * Called once the page is loaded to start scrolling for evaluating tiles.
+ * If autoScrolling isn't set, stop must be called manually.
*/
- public void startScrollTest(ProfileCallback callback) {
- isScrolling = true;
+ public void startScrollTest(ProfileCallback callback, boolean autoScrolling) {
+ isScrolling = autoScrolling;
mCallback = callback;
- super.tileProfilingStart();
+ tileProfilingStart();
invalidate();
}
@@ -72,19 +73,31 @@ public class ProfiledWebView extends WebView {
* Called once the page has stopped scrolling
*/
public void stopScrollTest() {
- float testRatio = super.tileProfilingStop();
+ super.tileProfilingStop();
+
+ if (mCallback == null) {
+ tileProfilingClear();
+ return;
+ }
TileData data[][] = new TileData[super.tileProfilingNumFrames()][];
for (int frame = 0; frame < data.length; frame++) {
data[frame] = new TileData[
- super.tileProfilingNumTilesInFrame(frame)];
+ tileProfilingNumTilesInFrame(frame)];
for (int tile = 0; tile < data[frame].length; tile++) {
- int x = super.tileProfilingGetX(frame, tile);
- int y = super.tileProfilingGetY(frame, tile);
- boolean isReady = super.tileProfilingGetReady(frame, tile);
- int level = super.tileProfilingGetLevel(frame, tile);
+ int left = tileProfilingGetInt(frame, tile, "left");
+ int top = tileProfilingGetInt(frame, tile, "top");
+ int right = tileProfilingGetInt(frame, tile, "right");
+ int bottom = tileProfilingGetInt(frame, tile, "bottom");
+
+ boolean isReady = super.tileProfilingGetInt(
+ frame, tile, "isReady") == 1;
+ int level = tileProfilingGetInt(frame, tile, "level");
+
+ float scale = tileProfilingGetFloat(frame, tile, "scale");
- data[frame][tile] = new TileData(x, y, isReady, level);
+ data[frame][tile] = new TileData(left, top, right, bottom,
+ isReady, level, scale);
}
}
super.tileProfilingClear();
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/TileData.java b/tests/TileBenchmark/src/com/test/tilebenchmark/TileData.java
index 7d4bb9f5217f..3e729a6282be 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/TileData.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/TileData.java
@@ -19,14 +19,24 @@ package com.test.tilebenchmark;
import java.io.Serializable;
public class TileData implements Serializable {
- public int x, y;
+ int left, top, right, bottom;
public boolean isReady;
public int level;
+ public float scale;
- public TileData(int x, int y, boolean isReady, int level) {
- this.x = x;
- this.y = y;
+ public TileData(int left, int top, int right, int bottom, boolean isReady,
+ int level, float scale) {
+ this.left = left;
+ this.right = right;
+ this.top = top;
+ this.bottom = bottom;
this.isReady = isReady;
this.level = level;
+ this.scale = scale;
+ }
+
+ public String toString() {
+ return "Tile (" + left + "," + top + ")->("
+ + right + "," + bottom + ")";
}
}
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index b35878a7b313..d66cdf01c1f5 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -1852,7 +1852,7 @@ ssize_t AaptAssets::slurpFromArgs(Bundle* bundle)
sp<AaptDir> assetAaptDir = makeDir(String8(kAssetDir));
AaptGroupEntry group;
count = assetAaptDir->slurpFullTree(bundle, assetRoot, group,
- String8(), mFullResPaths);
+ String8(), mFullAssetPaths);
if (count < 0) {
totalCount = count;
goto bail;
@@ -1926,7 +1926,7 @@ ssize_t AaptAssets::slurpFromArgs(Bundle* bundle)
* guarantees about ordering, so we're okay with an inorder search
* using whatever order the OS happens to hand back to us.
*/
- count = slurpFullTree(bundle, assetRoot, AaptGroupEntry(), String8(), mFullResPaths);
+ count = slurpFullTree(bundle, assetRoot, AaptGroupEntry(), String8(), mFullAssetPaths);
if (count < 0) {
/* failure; report error and remove archive */
totalCount = count;
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index a1c7c40818dd..82dfd71be8e4 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -560,6 +560,10 @@ public:
inline void
setFullResPaths(sp<FilePathStore>& res) { mFullResPaths = res; }
+ inline sp<FilePathStore>& getFullAssetPaths() { return mFullAssetPaths; }
+ inline void
+ setFullAssetPaths(sp<FilePathStore>& res) { mFullAssetPaths = res; }
+
private:
String8 mPackage;
SortedVector<AaptGroupEntry> mGroupEntries;
@@ -575,6 +579,7 @@ private:
KeyedVector<String8, sp<ResourceTypeSet> >* mRes;
sp<FilePathStore> mFullResPaths;
+ sp<FilePathStore> mFullAssetPaths;
};
#endif // __AAPT_ASSETS_H
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index 094b7db3b4c4..e507fb908c3b 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -13,6 +13,8 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
AaptAssets.cpp \
Command.cpp \
+ CrunchCache.cpp \
+ FileFinder.cpp \
Main.cpp \
Package.cpp \
StringPool.cpp \
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 56fe5249f018..539c312a57ad 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -25,6 +25,7 @@ typedef enum Command {
kCommandAdd,
kCommandRemove,
kCommandPackage,
+ kCommandCrunch,
} Command;
/*
@@ -42,13 +43,14 @@ public:
mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),
mIsOverlayPackage(false),
mAutoAddOverlay(false), mGenDependencies(false),
- mAssetSourceDir(NULL), mProguardFile(NULL),
+ mAssetSourceDir(NULL),
+ mCrunchedOutputDir(NULL), mProguardFile(NULL),
mAndroidManifestFile(NULL), mPublicOutputFile(NULL),
mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL), mExtraPackages(NULL),
mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), mProduct(NULL),
- mArgc(0), mArgv(NULL)
+ mUseCrunchCache(false), mArgc(0), mArgv(NULL)
{}
~Bundle(void) {}
@@ -106,6 +108,8 @@ public:
*/
const char* getAssetSourceDir() const { return mAssetSourceDir; }
void setAssetSourceDir(const char* dir) { mAssetSourceDir = dir; }
+ const char* getCrunchedOutputDir() const { return mCrunchedOutputDir; }
+ void setCrunchedOutputDir(const char* dir) { mCrunchedOutputDir = dir; }
const char* getProguardFile() const { return mProguardFile; }
void setProguardFile(const char* file) { mProguardFile = file; }
const android::Vector<const char*>& getResourceSourceDirs() const { return mResourceSourceDirs; }
@@ -151,6 +155,8 @@ public:
void setNonConstantId(bool val) { mNonConstantId = val; }
const char* getProduct() const { return mProduct; }
void setProduct(const char * val) { mProduct = val; }
+ void setUseCrunchCache(bool val) { mUseCrunchCache = val; }
+ bool getUseCrunchCache() { return mUseCrunchCache; }
/*
* Set and get the file specification.
@@ -231,6 +237,7 @@ private:
bool mAutoAddOverlay;
bool mGenDependencies;
const char* mAssetSourceDir;
+ const char* mCrunchedOutputDir;
const char* mProguardFile;
const char* mAndroidManifestFile;
const char* mPublicOutputFile;
@@ -254,6 +261,7 @@ private:
bool mDebugMode;
bool mNonConstantId;
const char* mProduct;
+ bool mUseCrunchCache;
/* file specification */
int mArgc;
diff --git a/tools/aapt/CacheUpdater.h b/tools/aapt/CacheUpdater.h
new file mode 100644
index 000000000000..0e65589529e5
--- /dev/null
+++ b/tools/aapt/CacheUpdater.h
@@ -0,0 +1,107 @@
+//
+// Copyright 2011 The Android Open Source Project
+//
+// Abstraction of calls to system to make directories and delete files and
+// wrapper to image processing.
+
+#ifndef CACHE_UPDATER_H
+#define CACHE_UPDATER_H
+
+#include <utils/String8.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include "Images.h"
+
+using namespace android;
+
+/** CacheUpdater
+ * This is a pure virtual class that declares abstractions of functions useful
+ * for managing a cache files. This manager is set up to be used in a
+ * mirror cache where the source tree is duplicated and filled with processed
+ * images. This class is abstracted to allow for dependency injection during
+ * unit testing.
+ * Usage:
+ * To update/add a file to the cache, call processImage
+ * To remove a file from the cache, call deleteFile
+ */
+class CacheUpdater {
+public:
+ // Make sure all the directories along this path exist
+ virtual void ensureDirectoriesExist(String8 path) = 0;
+
+ // Delete a file
+ virtual void deleteFile(String8 path) = 0;
+
+ // Process an image from source out to dest
+ virtual void processImage(String8 source, String8 dest) = 0;
+private:
+};
+
+/** SystemCacheUpdater
+ * This is an implementation of the above virtual cache updater specification.
+ * This implementations hits the filesystem to manage a cache and calls out to
+ * the PNG crunching in images.h to process images out to its cache components.
+ */
+class SystemCacheUpdater : public CacheUpdater {
+public:
+ // Constructor to set bundle to pass to preProcessImage
+ SystemCacheUpdater (Bundle* b)
+ : bundle(b) { };
+
+ // Make sure all the directories along this path exist
+ virtual void ensureDirectoriesExist(String8 path)
+ {
+ // Check to see if we're dealing with a fully qualified path
+ String8 existsPath;
+ String8 toCreate;
+ String8 remains;
+ struct stat s;
+
+ // Check optomistically to see if all directories exist.
+ // If something in the path doesn't exist, then walk the path backwards
+ // and find the place to start creating directories forward.
+ if (stat(path.string(),&s) == -1) {
+ // Walk backwards to find place to start creating directories
+ existsPath = path;
+ do {
+ // As we remove the end of existsPath add it to
+ // the string of paths to create.
+ toCreate = existsPath.getPathLeaf().appendPath(toCreate);
+ existsPath = existsPath.getPathDir();
+ } while (stat(existsPath.string(),&s) == -1);
+
+ // Walk forwards and build directories as we go
+ do {
+ // Advance to the next segment of the path
+ existsPath.appendPath(toCreate.walkPath(&remains));
+ toCreate = remains;
+#ifdef HAVE_MS_C_RUNTIME
+ _mkdir(existsPath.string());
+#else
+ mkdir(existsPath.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
+#endif
+ } while (remains.length() > 0);
+ } //if
+ };
+
+ // Delete a file
+ virtual void deleteFile(String8 path)
+ {
+ if (remove(path.string()) != 0)
+ fprintf(stderr,"ERROR DELETING %s\n",path.string());
+ };
+
+ // Process an image from source out to dest
+ virtual void processImage(String8 source, String8 dest)
+ {
+ // Make sure we're trying to write to a directory that is extant
+ ensureDirectoriesExist(dest.getPathDir());
+
+ preProcessImageToCache(bundle, source, dest);
+ };
+private:
+ Bundle* bundle;
+};
+
+#endif // CACHE_UPDATER_H \ No newline at end of file
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 903c62cef1fe..daf53e06bd75 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -1545,10 +1545,13 @@ int doPackage(Bundle* bundle)
// Load the assets.
assets = new AaptAssets();
- // Set up the resource gathering in assets if we're trying to make R.java
+ // Set up the resource gathering in assets if we're going to generate
+ // dependency files
if (bundle->getGenDependencies()) {
- sp<FilePathStore> pathStore = new FilePathStore;
- assets->setFullResPaths(pathStore);
+ sp<FilePathStore> resPathStore = new FilePathStore;
+ assets->setFullResPaths(resPathStore);
+ sp<FilePathStore> assetPathStore = new FilePathStore;
+ assets->setFullAssetPaths(assetPathStore);
}
err = assets->slurpFromArgs(bundle);
@@ -1575,9 +1578,16 @@ int doPackage(Bundle* bundle)
}
if (bundle->getGenDependencies()) {
- dependencyFile = String8(bundle->getRClassDir());
+ if (outputAPKFile) {
+ dependencyFile = String8(outputAPKFile);
+ // Strip the extension and add new one
+ dependencyFile = dependencyFile.getBasePath();
+ dependencyFile.append(".d");
+ } else {
+ dependencyFile = String8(bundle->getRClassDir());
+ dependencyFile.appendPath("R.d");
+ }
// Make sure we have a clean dependency file to start with
- dependencyFile.appendPath("R.d");
fp = fopen(dependencyFile, "w");
fclose(fp);
}
@@ -1615,19 +1625,6 @@ int doPackage(Bundle* bundle)
}
}
- if (bundle->getGenDependencies()) {
- // Now that writeResourceSymbols has taken care of writing the
- // dependency targets to the dependencyFile, we'll write the
- // pre-requisites.
- fp = fopen(dependencyFile, "a+");
- fprintf(fp, " : ");
- err = writeDependencyPreReqs(bundle, assets, fp);
-
- // Also manually add the AndroidManifeset since it's a non-asset
- fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile());
- fclose(fp);
- }
-
// Write out the ProGuard file
err = writeProguardFile(bundle, assets);
if (err < 0) {
@@ -1643,6 +1640,18 @@ int doPackage(Bundle* bundle)
}
}
+ if (bundle->getGenDependencies()) {
+ // Now that writeResourceSymbols or writeAPK has taken care of writing
+ // the targets to our dependency file, we'll write the prereqs
+ fp = fopen(dependencyFile, "a+");
+ fprintf(fp, " : ");
+ bool includeRaw = (outputAPKFile != NULL);
+ err = writeDependencyPreReqs(bundle, assets, fp, includeRaw);
+ // Also manually add the AndroidManifeset since it's a non-asset
+ fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile());
+ fclose(fp);
+ }
+
retVal = 0;
bail:
if (SourcePos::hasErrors()) {
@@ -1650,3 +1659,25 @@ bail:
}
return retVal;
}
+
+/*
+ * Do PNG Crunching
+ * PRECONDITIONS
+ * -S flag points to a source directory containing drawable* folders
+ * -C flag points to destination directory. The folder structure in the
+ * source directory will be mirrored to the destination (cache) directory
+ *
+ * POSTCONDITIONS
+ * Destination directory will be updated to match the PNG files in
+ * the source directory.
+ */
+int doCrunch(Bundle* bundle)
+{
+ fprintf(stdout, "Crunching PNG Files in ");
+ fprintf(stdout, "source dir: %s\n", bundle->getResourceSourceDirs()[0]);
+ fprintf(stdout, "To destination dir: %s\n", bundle->getCrunchedOutputDir());
+
+ updatePreProcessedCache(bundle);
+
+ return NO_ERROR;
+}
diff --git a/tools/aapt/CrunchCache.cpp b/tools/aapt/CrunchCache.cpp
new file mode 100644
index 000000000000..c4cf6bc8494f
--- /dev/null
+++ b/tools/aapt/CrunchCache.cpp
@@ -0,0 +1,104 @@
+//
+// Copyright 2011 The Android Open Source Project
+//
+// Implementation file for CrunchCache
+// This file defines functions laid out and documented in
+// CrunchCache.h
+
+#include <utils/Vector.h>
+#include <utils/String8.h>
+
+#include "DirectoryWalker.h"
+#include "FileFinder.h"
+#include "CacheUpdater.h"
+#include "CrunchCache.h"
+
+using namespace android;
+
+CrunchCache::CrunchCache(String8 sourcePath, String8 destPath, FileFinder* ff)
+ : mSourcePath(sourcePath), mDestPath(destPath), mSourceFiles(0), mDestFiles(0), mFileFinder(ff)
+{
+ // We initialize the default value to return to 0 so if a file doesn't exist
+ // then all files are automatically "newer" than it.
+
+ // Set file extensions to look for. Right now just pngs.
+ mExtensions.push(String8(".png"));
+
+ // Load files into our data members
+ loadFiles();
+}
+
+size_t CrunchCache::crunch(CacheUpdater* cu, bool forceOverwrite)
+{
+ size_t numFilesUpdated = 0;
+
+ // Iterate through the source files and compare to cache.
+ // After processing a file, remove it from the source files and
+ // from the dest files.
+ // We're done when we're out of files in source.
+ String8 relativePath;
+ while (mSourceFiles.size() > 0) {
+ // Get the full path to the source file, then convert to a c-string
+ // and offset our beginning pointer to the length of the sourcePath
+ // This efficiently strips the source directory prefix from our path.
+ // Also, String8 doesn't have a substring method so this is what we've
+ // got to work with.
+ const char* rPathPtr = mSourceFiles.keyAt(0).string()+mSourcePath.length();
+ // Strip leading slash if present
+ int offset = 0;
+ if (rPathPtr[0] == OS_PATH_SEPARATOR)
+ offset = 1;
+ relativePath = String8(rPathPtr + offset);
+
+ if (forceOverwrite || needsUpdating(relativePath)) {
+ cu->processImage(mSourcePath.appendPathCopy(relativePath),
+ mDestPath.appendPathCopy(relativePath));
+ numFilesUpdated++;
+ // crunchFile(relativePath);
+ }
+ // Delete this file from the source files and (if it exists) from the
+ // dest files.
+ mSourceFiles.removeItemsAt(0);
+ mDestFiles.removeItem(mDestPath.appendPathCopy(relativePath));
+ }
+
+ // Iterate through what's left of destFiles and delete leftovers
+ while (mDestFiles.size() > 0) {
+ cu->deleteFile(mDestFiles.keyAt(0));
+ mDestFiles.removeItemsAt(0);
+ }
+
+ // Update our knowledge of the files cache
+ // both source and dest should be empty by now.
+ loadFiles();
+
+ return numFilesUpdated;
+}
+
+void CrunchCache::loadFiles()
+{
+ // Clear out our data structures to avoid putting in duplicates
+ mSourceFiles.clear();
+ mDestFiles.clear();
+
+ // Make a directory walker that points to the system.
+ DirectoryWalker* dw = new SystemDirectoryWalker();
+
+ // Load files in the source directory
+ mFileFinder->findFiles(mSourcePath, mExtensions, mSourceFiles,dw);
+
+ // Load files in the destination directory
+ mFileFinder->findFiles(mDestPath,mExtensions,mDestFiles,dw);
+
+ delete dw;
+}
+
+bool CrunchCache::needsUpdating(String8 relativePath) const
+{
+ // Retrieve modification dates for this file entry under the source and
+ // cache directory trees. The vectors will return a modification date of 0
+ // if the file doesn't exist.
+ time_t sourceDate = mSourceFiles.valueFor(mSourcePath.appendPathCopy(relativePath));
+ time_t destDate = mDestFiles.valueFor(mDestPath.appendPathCopy(relativePath));
+ return sourceDate > destDate;
+} \ No newline at end of file
diff --git a/tools/aapt/CrunchCache.h b/tools/aapt/CrunchCache.h
new file mode 100644
index 000000000000..be3da5c40b25
--- /dev/null
+++ b/tools/aapt/CrunchCache.h
@@ -0,0 +1,102 @@
+//
+// Copyright 2011 The Android Open Source Project
+//
+// Cache manager for pre-processed PNG files.
+// Contains code for managing which PNG files get processed
+// at build time.
+//
+
+#ifndef CRUNCHCACHE_H
+#define CRUNCHCACHE_H
+
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include "FileFinder.h"
+#include "CacheUpdater.h"
+
+using namespace android;
+
+/** CrunchCache
+ * This class is a cache manager which can pre-process PNG files and store
+ * them in a mirror-cache. It's capable of doing incremental updates to its
+ * cache.
+ *
+ * Usage:
+ * Create an instance initialized with the root of the source tree, the
+ * root location to store the cache files, and an instance of a file finder.
+ * Then update the cache by calling crunch.
+ */
+class CrunchCache {
+public:
+ // Constructor
+ CrunchCache(String8 sourcePath, String8 destPath, FileFinder* ff);
+
+ // Nobody should be calling the default constructor
+ // So this space is intentionally left blank
+
+ // Default Copy Constructor and Destructor are fine
+
+ /** crunch is the workhorse of this class.
+ * It goes through all the files found in the sourcePath and compares
+ * them to the cached versions in the destPath. If the optional
+ * argument forceOverwrite is set to true, then all source files are
+ * re-crunched even if they have not been modified recently. Otherwise,
+ * source files are only crunched when they needUpdating. Afterwards,
+ * we delete any leftover files in the cache that are no longer present
+ * in source.
+ *
+ * PRECONDITIONS:
+ * No setup besides construction is needed
+ * POSTCONDITIONS:
+ * The cache is updated to fully reflect all changes in source.
+ * The function then returns the number of files changed in cache
+ * (counting deletions).
+ */
+ size_t crunch(CacheUpdater* cu, bool forceOverwrite=false);
+
+private:
+ /** loadFiles is a wrapper to the FileFinder that places matching
+ * files into mSourceFiles and mDestFiles.
+ *
+ * POSTCONDITIONS
+ * mDestFiles and mSourceFiles are refreshed to reflect the current
+ * state of the files in the source and dest directories.
+ * Any previous contents of mSourceFiles and mDestFiles are cleared.
+ */
+ void loadFiles();
+
+ /** needsUpdating takes a file path
+ * and returns true if the file represented by this path is newer in the
+ * sourceFiles than in the cache (mDestFiles).
+ *
+ * PRECONDITIONS:
+ * mSourceFiles and mDestFiles must be initialized and filled.
+ * POSTCONDITIONS:
+ * returns true if and only if source file's modification time
+ * is greater than the cached file's mod-time. Otherwise returns false.
+ *
+ * USAGE:
+ * Should be used something like the following:
+ * if (needsUpdating(filePath))
+ * // Recrunch sourceFile out to destFile.
+ *
+ */
+ bool needsUpdating(String8 relativePath) const;
+
+ // DATA MEMBERS ====================================================
+
+ String8 mSourcePath;
+ String8 mDestPath;
+
+ Vector<String8> mExtensions;
+
+ // Each vector of paths contains one entry per PNG file encountered.
+ // Each entry consists of a path pointing to that PNG.
+ DefaultKeyedVector<String8,time_t> mSourceFiles;
+ DefaultKeyedVector<String8,time_t> mDestFiles;
+
+ // Pointer to a FileFinder to use
+ FileFinder* mFileFinder;
+};
+
+#endif // CRUNCHCACHE_H
diff --git a/tools/aapt/DirectoryWalker.h b/tools/aapt/DirectoryWalker.h
new file mode 100644
index 000000000000..88031d04b2df
--- /dev/null
+++ b/tools/aapt/DirectoryWalker.h
@@ -0,0 +1,98 @@
+//
+// Copyright 2011 The Android Open Source Project
+//
+// Defines an abstraction for opening a directory on the filesystem and
+// iterating through it.
+
+#ifndef DIRECTORYWALKER_H
+#define DIRECTORYWALKER_H
+
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <utils/String8.h>
+
+#include <stdio.h>
+
+using namespace android;
+
+// Directory Walker
+// This is an abstraction for walking through a directory and getting files
+// and descriptions.
+
+class DirectoryWalker {
+public:
+ virtual ~DirectoryWalker() {};
+ virtual bool openDir(String8 path) = 0;
+ virtual bool openDir(const char* path) = 0;
+ // Advance to next directory entry
+ virtual struct dirent* nextEntry() = 0;
+ // Get the stats for the current entry
+ virtual struct stat* entryStats() = 0;
+ // Clean Up
+ virtual void closeDir() = 0;
+ // This class is able to replicate itself on the heap
+ virtual DirectoryWalker* clone() = 0;
+
+ // DATA MEMBERS
+ // Current directory entry
+ struct dirent mEntry;
+ // Stats for that directory entry
+ struct stat mStats;
+ // Base path
+ String8 mBasePath;
+};
+
+// System Directory Walker
+// This is an implementation of the above abstraction that calls
+// real system calls and is fully functional.
+// functions are inlined since they're very short and simple
+
+class SystemDirectoryWalker : public DirectoryWalker {
+
+ // Default constructor, copy constructor, and destructor are fine
+public:
+ virtual bool openDir(String8 path) {
+ mBasePath = path;
+ dir = NULL;
+ dir = opendir(mBasePath.string() );
+
+ if (dir == NULL)
+ return false;
+
+ return true;
+ };
+ virtual bool openDir(const char* path) {
+ String8 p(path);
+ openDir(p);
+ return true;
+ };
+ // Advance to next directory entry
+ virtual struct dirent* nextEntry() {
+ struct dirent* entryPtr = readdir(dir);
+ if (entryPtr == NULL)
+ return NULL;
+
+ mEntry = *entryPtr;
+ // Get stats
+ String8 fullPath = mBasePath.appendPathCopy(mEntry.d_name);
+ stat(fullPath.string(),&mStats);
+ return &mEntry;
+ };
+ // Get the stats for the current entry
+ virtual struct stat* entryStats() {
+ return &mStats;
+ };
+ virtual void closeDir() {
+ closedir(dir);
+ };
+ virtual DirectoryWalker* clone() {
+ return new SystemDirectoryWalker(*this);
+ };
+private:
+ DIR* dir;
+};
+
+#endif // DIRECTORYWALKER_H
diff --git a/tools/aapt/FileFinder.cpp b/tools/aapt/FileFinder.cpp
new file mode 100644
index 000000000000..580528d29a82
--- /dev/null
+++ b/tools/aapt/FileFinder.cpp
@@ -0,0 +1,113 @@
+//
+// Copyright 2011 The Android Open Source Project
+//
+
+// File Finder implementation.
+// Implementation for the functions declared and documented in FileFinder.h
+
+#include <utils/Vector.h>
+#include <utils/String8.h>
+#include <utils/KeyedVector.h>
+
+#include <iostream>
+#include <dirent.h>
+#include <sys/stat.h>
+
+#include "DirectoryWalker.h"
+#include "FileFinder.h"
+
+//#define DEBUG
+
+using android::String8;
+using std::cout;
+using std::endl;
+
+// Private function to check whether a file is a directory or not
+bool isDirectory(const char* filename) {
+ struct stat fileStat;
+ if (stat(filename, &fileStat) == -1) {
+ return false;
+ }
+ return(S_ISDIR(fileStat.st_mode));
+}
+
+
+// Private function to check whether a file is a regular file or not
+bool isFile(const char* filename) {
+ struct stat fileStat;
+ if (stat(filename, &fileStat) == -1) {
+ return false;
+ }
+ return(S_ISREG(fileStat.st_mode));
+}
+
+bool SystemFileFinder::findFiles(String8 basePath, Vector<String8>& extensions,
+ KeyedVector<String8,time_t>& fileStore,
+ DirectoryWalker* dw)
+{
+ // Scan the directory pointed to by basePath
+ // check files and recurse into subdirectories.
+ if (!dw->openDir(basePath)) {
+ return false;
+ }
+#ifdef DEBUG
+ cout << "FileFinder looking in " << basePath << endl;
+#endif // DEBUG
+ /*
+ * Go through all directory entries. Check each file using checkAndAddFile
+ * and recurse into sub-directories.
+ */
+ struct dirent* entry;
+ while ((entry = dw->nextEntry()) != NULL) {
+ String8 entryName(entry->d_name);
+ if (entry->d_name[0] == '.') // Skip hidden files and directories
+ continue;
+
+ String8 fullPath = basePath.appendPathCopy(entryName);
+ // If this entry is a directory we'll recurse into it
+ if (isDirectory(fullPath.string()) ) {
+ DirectoryWalker* copy = dw->clone();
+ findFiles(fullPath, extensions, fileStore,copy);
+ delete copy;
+ }
+
+ // If this entry is a file, we'll pass it over to checkAndAddFile
+ if (isFile(fullPath.string()) ) {
+ checkAndAddFile(fullPath,dw->entryStats(),extensions,fileStore);
+ }
+ }
+
+ // Clean up
+ dw->closeDir();
+
+ return true;
+}
+
+void SystemFileFinder::checkAndAddFile(String8 path, const struct stat* stats,
+ Vector<String8>& extensions,
+ KeyedVector<String8,time_t>& fileStore)
+{
+#ifdef DEBUG
+ cout << "Checking file " << path << "...";
+#endif // DEBUG
+ // Loop over the extensions, checking for a match
+ bool done = false;
+ String8 ext(path.getPathExtension());
+ ext.toLower();
+ for (size_t i = 0; i < extensions.size() && !done; ++i) {
+ String8 ext2 = extensions[i].getPathExtension();
+ ext2.toLower();
+ // Compare the extensions. If a match is found, add to storage.
+ if (ext == ext2) {
+#ifdef DEBUG
+ cout << "Match";
+#endif // DEBUG
+ done = true;
+ fileStore.add(path,stats->st_mtime);
+ }
+ }
+#ifdef DEBUG
+ cout << endl;
+#endif //DEBUG
+}
+
diff --git a/tools/aapt/FileFinder.h b/tools/aapt/FileFinder.h
new file mode 100644
index 000000000000..6974aee033a8
--- /dev/null
+++ b/tools/aapt/FileFinder.h
@@ -0,0 +1,80 @@
+//
+// Copyright 2011 The Android Open Source Project
+//
+
+// File Finder.
+// This is a collection of useful functions for finding paths and modification
+// times of files that match an extension pattern in a directory tree.
+// and finding files in it.
+
+#ifndef FILEFINDER_H
+#define FILEFINDER_H
+
+#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+#include "DirectoryWalker.h"
+
+using namespace android;
+
+// Abstraction to allow for dependency injection. See MockFileFinder.h
+// for the testing implementation.
+class FileFinder {
+public:
+ virtual bool findFiles(String8 basePath, Vector<String8>& extensions,
+ KeyedVector<String8,time_t>& fileStore,
+ DirectoryWalker* dw) = 0;
+
+ virtual ~FileFinder() {};
+};
+
+class SystemFileFinder : public FileFinder {
+public:
+
+ /* findFiles takes a path, a Vector of extensions, and a destination KeyedVector
+ * and places path/modification date key/values pointing to
+ * all files with matching extensions found into the KeyedVector
+ * PRECONDITIONS
+ * path is a valid system path
+ * extensions should include leading "."
+ * This is not necessary, but the comparison directly
+ * compares the end of the path string so if the "."
+ * is excluded there is a small chance you could have
+ * a false positive match. (For example: extension "png"
+ * would match a file called "blahblahpng")
+ *
+ * POSTCONDITIONS
+ * fileStore contains (in no guaranteed order) paths to all
+ * matching files encountered in subdirectories of path
+ * as keys in the KeyedVector. Each key has the modification time
+ * of the file as its value.
+ *
+ * Calls checkAndAddFile on each file encountered in the directory tree
+ * Recursively descends into subdirectories.
+ */
+ virtual bool findFiles(String8 basePath, Vector<String8>& extensions,
+ KeyedVector<String8,time_t>& fileStore,
+ DirectoryWalker* dw);
+
+private:
+ /**
+ * checkAndAddFile looks at a single file path and stat combo
+ * to determine whether it is a matching file (by looking at
+ * the extension)
+ *
+ * PRECONDITIONS
+ * no setup is needed
+ *
+ * POSTCONDITIONS
+ * If the given file has a matching extension then a new entry
+ * is added to the KeyedVector with the path as the key and the modification
+ * time as the value.
+ *
+ */
+ static void checkAndAddFile(String8 path, const struct stat* stats,
+ Vector<String8>& extensions,
+ KeyedVector<String8,time_t>& fileStore);
+
+};
+#endif // FILEFINDER_H
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index 3c471ca76107..311ceea660c5 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -1080,7 +1080,128 @@ bail:
return error;
}
+status_t preProcessImageToCache(Bundle* bundle, String8 source, String8 dest)
+{
+ png_structp read_ptr = NULL;
+ png_infop read_info = NULL;
+
+ FILE* fp;
+
+ image_info imageInfo;
+
+ png_structp write_ptr = NULL;
+ png_infop write_info = NULL;
+
+ status_t error = UNKNOWN_ERROR;
+
+ // Get a file handler to read from
+ fp = fopen(source.string(),"rb");
+ if (fp == NULL) {
+ fprintf(stderr, "%s ERROR: Unable to open PNG file\n", source.string());
+ return error;
+ }
+
+ // Call libpng to get a struct to read image data into
+ read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!read_ptr) {
+ fclose(fp);
+ png_destroy_read_struct(&read_ptr, &read_info,NULL);
+ return error;
+ }
+
+ // Call libpng to get a struct to read image info into
+ read_info = png_create_info_struct(read_ptr);
+ if (!read_info) {
+ fclose(fp);
+ png_destroy_read_struct(&read_ptr, &read_info,NULL);
+ return error;
+ }
+
+ // Set a jump point for libpng to long jump back to on error
+ if (setjmp(png_jmpbuf(read_ptr))) {
+ fclose(fp);
+ png_destroy_read_struct(&read_ptr, &read_info,NULL);
+ return error;
+ }
+
+ // Set up libpng to read from our file.
+ png_init_io(read_ptr,fp);
+
+ // Actually read data from the file
+ read_png(source.string(), read_ptr, read_info, &imageInfo);
+ // We're done reading so we can clean up
+ // Find old file size before releasing handle
+ fseek(fp, 0, SEEK_END);
+ size_t oldSize = (size_t)ftell(fp);
+ fclose(fp);
+ png_destroy_read_struct(&read_ptr, &read_info,NULL);
+
+ // Check to see if we're dealing with a 9-patch
+ // If we are, process appropriately
+ if (source.getBasePath().getPathExtension() == ".9") {
+ if (do_9patch(source.string(), &imageInfo) != NO_ERROR) {
+ return error;
+ }
+ }
+
+ // Call libpng to create a structure to hold the processed image data
+ // that can be written to disk
+ write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!write_ptr) {
+ png_destroy_write_struct(&write_ptr, &write_info);
+ return error;
+ }
+
+ // Call libpng to create a structure to hold processed image info that can
+ // be written to disk
+ write_info = png_create_info_struct(write_ptr);
+ if (!write_info) {
+ png_destroy_write_struct(&write_ptr, &write_info);
+ return error;
+ }
+
+ // Open up our destination file for writing
+ fp = fopen(dest.string(), "wb");
+ if (!fp) {
+ fprintf(stderr, "%s ERROR: Unable to open PNG file\n", dest.string());
+ png_destroy_write_struct(&write_ptr, &write_info);
+ return error;
+ }
+
+ // Set up libpng to write to our file
+ png_init_io(write_ptr, fp);
+
+ // Set up a jump for libpng to long jump back on on errors
+ if (setjmp(png_jmpbuf(write_ptr))) {
+ fclose(fp);
+ png_destroy_write_struct(&write_ptr, &write_info);
+ return error;
+ }
+
+ // Actually write out to the new png
+ write_png(dest.string(), write_ptr, write_info, imageInfo,
+ bundle->getGrayscaleTolerance());
+
+ if (bundle->getVerbose()) {
+ // Find the size of our new file
+ FILE* reader = fopen(dest.string(), "rb");
+ fseek(reader, 0, SEEK_END);
+ size_t newSize = (size_t)ftell(reader);
+ fclose(reader);
+
+ float factor = ((float)newSize)/oldSize;
+ int percent = (int)(factor*100);
+ printf(" (processed image to cache entry %s: %d%% size of source)\n",
+ dest.string(), percent);
+ }
+
+ //Clean up
+ fclose(fp);
+ png_destroy_write_struct(&write_ptr, &write_info);
+
+ return NO_ERROR;
+}
status_t postProcessImage(const sp<AaptAssets>& assets,
ResourceTable* table, const sp<AaptFile>& file)
diff --git a/tools/aapt/Images.h b/tools/aapt/Images.h
index 168e22ff8b53..4816905572c9 100644
--- a/tools/aapt/Images.h
+++ b/tools/aapt/Images.h
@@ -8,11 +8,19 @@
#define IMAGES_H
#include "ResourceTable.h"
+#include "Bundle.h"
+
+#include <utils/String8.h>
+#include <utils/RefBase.h>
+
+using android::String8;
status_t preProcessImage(Bundle* bundle, const sp<AaptAssets>& assets,
const sp<AaptFile>& file, String8* outNewLeafName);
+status_t preProcessImageToCache(Bundle* bundle, String8 source, String8 dest);
+
status_t postProcessImage(const sp<AaptAssets>& assets,
- ResourceTable* table, const sp<AaptFile>& file);
+ ResourceTable* table, const sp<AaptFile>& file);
#endif
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 8edb5b53b194..5135787050f9 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -83,6 +83,9 @@ void usage(void)
" %s a[dd] [-v] file.{zip,jar,apk} file1 [file2 ...]\n"
" Add specified files to Zip-compatible archive.\n\n", gProgName);
fprintf(stderr,
+ " %s c[runch] [-v] -S resource-sources ... -C output-folder ...\n"
+ " Do PNG preprocessing and store the results in output folder.\n\n", gProgName);
+ fprintf(stderr,
" %s v[ersion]\n"
" Print program version.\n\n", gProgName);
fprintf(stderr,
@@ -148,7 +151,7 @@ void usage(void)
" --extra-packages\n"
" generate R.java for libraries. Separate libraries with ':'.\n"
" --generate-dependencies\n"
- " generate a dependency file for R.java.\n"
+ " generate dependency files in the same directories for R.java and resource package\n"
" --auto-add-overlay\n"
" Automatically add resources that are only in overlays.\n"
" --rename-manifest-package\n"
@@ -190,6 +193,7 @@ int handleCommand(Bundle* bundle)
case kCommandAdd: return doAdd(bundle);
case kCommandRemove: return doRemove(bundle);
case kCommandPackage: return doPackage(bundle);
+ case kCommandCrunch: return doCrunch(bundle);
default:
fprintf(stderr, "%s: requested command not yet supported\n", gProgName);
return 1;
@@ -227,6 +231,8 @@ int main(int argc, char* const argv[])
bundle.setCommand(kCommandRemove);
else if (argv[1][0] == 'p')
bundle.setCommand(kCommandPackage);
+ else if (argv[1][0] == 'c')
+ bundle.setCommand(kCommandCrunch);
else {
fprintf(stderr, "ERROR: Unknown command '%s'\n", argv[1]);
wantUsage = true;
@@ -397,6 +403,17 @@ int main(int argc, char* const argv[])
convertPath(argv[0]);
bundle.addResourceSourceDir(argv[0]);
break;
+ case 'C':
+ argc--;
+ argv++;
+ if (!argc) {
+ fprintf(stderr, "ERROR: No argument supplied for '-C' option\n");
+ wantUsage = true;
+ goto bail;
+ }
+ convertPath(argv[0]);
+ bundle.setCrunchedOutputDir(argv[0]);
+ break;
case '0':
argc--;
argv++;
@@ -523,7 +540,9 @@ int main(int argc, char* const argv[])
bundle.setProduct(argv[0]);
} else if (strcmp(cp, "-non-constant-id") == 0) {
bundle.setNonConstantId(true);
- } else {
+ } else if (strcmp(cp, "-no-crunch") == 0) {
+ bundle.setUseCrunchCache(true);
+ }else {
fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp);
wantUsage = true;
goto bail;
diff --git a/tools/aapt/Main.h b/tools/aapt/Main.h
index 1df114430fd3..d20c601a0c77 100644
--- a/tools/aapt/Main.h
+++ b/tools/aapt/Main.h
@@ -14,12 +14,21 @@
#include "AaptAssets.h"
#include "ZipFile.h"
+
+/* Benchmarking Flag */
+//#define BENCHMARK 1
+
+#if BENCHMARK
+ #include <time.h>
+#endif /* BENCHMARK */
+
extern int doVersion(Bundle* bundle);
extern int doList(Bundle* bundle);
extern int doDump(Bundle* bundle);
extern int doAdd(Bundle* bundle);
extern int doRemove(Bundle* bundle);
extern int doPackage(Bundle* bundle);
+extern int doCrunch(Bundle* bundle);
extern int calcPercent(long uncompressedLen, long compressedLen);
@@ -27,6 +36,8 @@ extern android::status_t writeAPK(Bundle* bundle,
const sp<AaptAssets>& assets,
const android::String8& outputFile);
+extern android::status_t updatePreProcessedCache(Bundle* bundle);
+
extern android::status_t buildResources(Bundle* bundle,
const sp<AaptAssets>& assets);
@@ -46,5 +57,6 @@ int dumpResources(Bundle* bundle);
String8 getAttribute(const ResXMLTree& tree, const char* ns,
const char* attr, String8* outError);
-status_t writeDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets, FILE* fp);
+status_t writeDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets,
+ FILE* fp, bool includeRaw);
#endif // __MAIN_H
diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp
index ab71f34b3c8f..c9f687088b4f 100644
--- a/tools/aapt/Package.cpp
+++ b/tools/aapt/Package.cpp
@@ -50,6 +50,11 @@ ssize_t processJarFiles(Bundle* bundle, ZipFile* zip);
status_t writeAPK(Bundle* bundle, const sp<AaptAssets>& assets,
const String8& outputFile)
{
+ #if BENCHMARK
+ fprintf(stdout, "BENCHMARK: Starting APK Bundling \n");
+ long startAPKTime = clock();
+ #endif /* BENCHMARK */
+
status_t result = NO_ERROR;
ZipFile* zip = NULL;
int count;
@@ -172,6 +177,16 @@ status_t writeAPK(Bundle* bundle, const sp<AaptAssets>& assets,
}
}
+ if (bundle->getGenDependencies()) {
+ // Add this file to the dependency file
+ String8 dependencyFile = outputFile.getBasePath();
+ dependencyFile.append(".d");
+
+ FILE* fp = fopen(dependencyFile.string(), "a");
+ fprintf(fp, "%s \\\n", outputFile.string());
+ fclose(fp);
+ }
+
assert(result == NO_ERROR);
bail:
@@ -187,6 +202,10 @@ bail:
if (result == NO_ERROR && bundle->getVerbose())
printf("Done!\n");
+
+ #if BENCHMARK
+ fprintf(stdout, "BENCHMARK: End APK Bundling. Time Elapsed: %f ms \n",(clock() - startAPKTime)/1000.0);
+ #endif /* BENCHMARK */
return result;
}
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 99e781dc5a52..cb6484fcf2af 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -10,6 +10,10 @@
#include "ResourceTable.h"
#include "Images.h"
+#include "CrunchCache.h"
+#include "FileFinder.h"
+#include "CacheUpdater.h"
+
#define NOISY(x) // x
// ==========================================================================
@@ -293,18 +297,19 @@ static status_t makeFileResources(Bundle* bundle, const sp<AaptAssets>& assets,
static status_t preProcessImages(Bundle* bundle, const sp<AaptAssets>& assets,
const sp<ResourceTypeSet>& set, const char* type)
{
- ResourceDirIterator it(set, String8(type));
- Vector<sp<AaptFile> > newNameFiles;
- Vector<String8> newNamePaths;
bool hasErrors = false;
- ssize_t res;
- while ((res=it.next()) == NO_ERROR) {
- res = preProcessImage(bundle, assets, it.getFile(), NULL);
- if (res < NO_ERROR) {
- hasErrors = true;
+ ssize_t res = NO_ERROR;
+ if (bundle->getUseCrunchCache() == false) {
+ ResourceDirIterator it(set, String8(type));
+ Vector<sp<AaptFile> > newNameFiles;
+ Vector<String8> newNamePaths;
+ while ((res=it.next()) == NO_ERROR) {
+ res = preProcessImage(bundle, assets, it.getFile(), NULL);
+ if (res < NO_ERROR) {
+ hasErrors = true;
+ }
}
}
-
return (hasErrors || (res < NO_ERROR)) ? UNKNOWN_ERROR : NO_ERROR;
}
@@ -754,6 +759,35 @@ status_t massageManifest(Bundle* bundle, sp<XMLNode> root)
} \
} while (0)
+status_t updatePreProcessedCache(Bundle* bundle)
+{
+ #if BENCHMARK
+ fprintf(stdout, "BENCHMARK: Starting PNG PreProcessing \n");
+ long startPNGTime = clock();
+ #endif /* BENCHMARK */
+
+ String8 source(bundle->getResourceSourceDirs()[0]);
+ String8 dest(bundle->getCrunchedOutputDir());
+
+ FileFinder* ff = new SystemFileFinder();
+ CrunchCache cc(source,dest,ff);
+
+ CacheUpdater* cu = new SystemCacheUpdater(bundle);
+ size_t numFiles = cc.crunch(cu);
+
+ if (bundle->getVerbose())
+ fprintf(stdout, "Crunched %d PNG files to update cache\n", (int)numFiles);
+
+ delete ff;
+ delete cu;
+
+ #if BENCHMARK
+ fprintf(stdout, "BENCHMARK: End PNG PreProcessing. Time Elapsed: %f ms \n"
+ ,(clock() - startPNGTime)/1000.0);
+ #endif /* BENCHMARK */
+ return 0;
+}
+
status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets)
{
// First, look for a package file to parse. This is required to
@@ -2261,11 +2295,11 @@ writeProguardFile(Bundle* bundle, const sp<AaptAssets>& assets)
return err;
}
-status_t
-writeDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets, FILE* fp)
+// Loops through the string paths and writes them to the file pointer
+// Each file path is written on its own line with a terminating backslash.
+status_t writePathsToFile(const sp<FilePathStore>& files, FILE* fp)
{
status_t deps = -1;
- sp<FilePathStore> files = assets->getFullResPaths();
for (size_t file_i = 0; file_i < files->size(); ++file_i) {
// Add the full file path to the dependency file
fprintf(fp, "%s \\\n", files->itemAt(file_i).string());
@@ -2273,3 +2307,14 @@ writeDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets, FILE* fp)
}
return deps;
}
+
+status_t
+writeDependencyPreReqs(Bundle* bundle, const sp<AaptAssets>& assets, FILE* fp, bool includeRaw)
+{
+ status_t deps = -1;
+ deps += writePathsToFile(assets->getFullResPaths(), fp);
+ if (includeRaw) {
+ deps += writePathsToFile(assets->getFullAssetPaths(), fp);
+ }
+ return deps;
+}
diff --git a/tools/aapt/ZipFile.h b/tools/aapt/ZipFile.h
index 78775502884b..dbbd072d1692 100644
--- a/tools/aapt/ZipFile.h
+++ b/tools/aapt/ZipFile.h
@@ -57,7 +57,7 @@ public:
/*
* Open a new or existing archive.
*/
- enum {
+ typedef enum {
kOpenReadOnly = 0x01,
kOpenReadWrite = 0x02,
kOpenCreate = 0x04, // create if it doesn't exist
diff --git a/tools/aapt/tests/CrunchCache_test.cpp b/tools/aapt/tests/CrunchCache_test.cpp
new file mode 100644
index 000000000000..20b5022b5257
--- /dev/null
+++ b/tools/aapt/tests/CrunchCache_test.cpp
@@ -0,0 +1,97 @@
+//
+// Copyright 2011 The Android Open Source Project
+//
+#include <utils/String8.h>
+#include <iostream>
+#include <errno.h>
+
+#include "CrunchCache.h"
+#include "FileFinder.h"
+#include "MockFileFinder.h"
+#include "CacheUpdater.h"
+#include "MockCacheUpdater.h"
+
+using namespace android;
+using std::cout;
+using std::endl;
+
+void expectEqual(int got, int expected, const char* desc) {
+ cout << "Checking " << desc << ": ";
+ cout << "Got " << got << ", expected " << expected << "...";
+ cout << ( (got == expected) ? "PASSED" : "FAILED") << endl;
+ errno += ((got == expected) ? 0 : 1);
+}
+
+int main() {
+
+ errno = 0;
+
+ String8 source("res");
+ String8 dest("res2");
+
+ // Create data for MockFileFinder to feed to the cache
+ KeyedVector<String8, time_t> sourceData;
+ // This shouldn't be updated
+ sourceData.add(String8("res/drawable/hello.png"),3);
+ // This should be updated
+ sourceData.add(String8("res/drawable/world.png"),5);
+ // This should cause make directory to be called
+ sourceData.add(String8("res/drawable-cool/hello.png"),3);
+
+ KeyedVector<String8, time_t> destData;
+ destData.add(String8("res2/drawable/hello.png"),3);
+ destData.add(String8("res2/drawable/world.png"),3);
+ // this should call delete
+ destData.add(String8("res2/drawable/dead.png"),3);
+
+ // Package up data and create mock file finder
+ KeyedVector<String8, KeyedVector<String8,time_t> > data;
+ data.add(source,sourceData);
+ data.add(dest,destData);
+ FileFinder* ff = new MockFileFinder(data);
+ CrunchCache cc(source,dest,ff);
+
+ MockCacheUpdater* mcu = new MockCacheUpdater();
+ CacheUpdater* cu(mcu);
+
+ cout << "Running Crunch...";
+ int result = cc.crunch(cu);
+ cout << ((result > 0) ? "PASSED" : "FAILED") << endl;
+ errno += ((result > 0) ? 0 : 1);
+
+ const int EXPECTED_RESULT = 2;
+ expectEqual(result, EXPECTED_RESULT, "number of files touched");
+
+ cout << "Checking calls to deleteFile and processImage:" << endl;
+ const int EXPECTED_DELETES = 1;
+ const int EXPECTED_PROCESSED = 2;
+ // Deletes
+ expectEqual(mcu->deleteCount, EXPECTED_DELETES, "deleteFile");
+ // processImage
+ expectEqual(mcu->processCount, EXPECTED_PROCESSED, "processImage");
+
+ const int EXPECTED_OVERWRITES = 3;
+ result = cc.crunch(cu, true);
+ expectEqual(result, EXPECTED_OVERWRITES, "number of files touched with overwrite");
+ \
+
+ if (errno == 0)
+ cout << "ALL TESTS PASSED!" << endl;
+ else
+ cout << errno << " TESTS FAILED" << endl;
+
+ delete ff;
+ delete cu;
+
+ // TESTS BELOW WILL GO AWAY SOON
+
+ String8 source2("ApiDemos/res");
+ String8 dest2("ApiDemos/res2");
+
+ FileFinder* sff = new SystemFileFinder();
+ CacheUpdater* scu = new SystemCacheUpdater();
+
+ CrunchCache scc(source2,dest2,sff);
+
+ scc.crunch(scu);
+} \ No newline at end of file
diff --git a/tools/aapt/tests/FileFinder_test.cpp b/tools/aapt/tests/FileFinder_test.cpp
new file mode 100644
index 000000000000..07bd665bcdb5
--- /dev/null
+++ b/tools/aapt/tests/FileFinder_test.cpp
@@ -0,0 +1,101 @@
+//
+// Copyright 2011 The Android Open Source Project
+//
+#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+#include <iostream>
+#include <cassert>
+#include <utils/String8.h>
+#include <utility>
+
+#include "DirectoryWalker.h"
+#include "MockDirectoryWalker.h"
+#include "FileFinder.h"
+
+using namespace android;
+
+using std::pair;
+using std::cout;
+using std::endl;
+
+
+
+int main()
+{
+
+ cout << "\n\n STARTING FILE FINDER TESTS" << endl;
+ String8 path("ApiDemos");
+
+ // Storage to pass to findFiles()
+ KeyedVector<String8,time_t> testStorage;
+
+ // Mock Directory Walker initialization. First data, then sdw
+ Vector< pair<String8,time_t> > data;
+ data.push( pair<String8,time_t>(String8("hello.png"),3) );
+ data.push( pair<String8,time_t>(String8("world.PNG"),3) );
+ data.push( pair<String8,time_t>(String8("foo.pNg"),3) );
+ // Neither of these should be found
+ data.push( pair<String8,time_t>(String8("hello.jpg"),3) );
+ data.push( pair<String8,time_t>(String8(".hidden.png"),3));
+
+ DirectoryWalker* sdw = new StringDirectoryWalker(path,data);
+
+ // Extensions to look for
+ Vector<String8> exts;
+ exts.push(String8(".png"));
+
+ errno = 0;
+
+ // Make sure we get a valid mock directory walker
+ // Make sure we finish without errors
+ cout << "Checking DirectoryWalker...";
+ assert(sdw != NULL);
+ cout << "PASSED" << endl;
+
+ // Make sure we finish without errors
+ cout << "Running findFiles()...";
+ bool findStatus = FileFinder::findFiles(path,exts, testStorage, sdw);
+ assert(findStatus);
+ cout << "PASSED" << endl;
+
+ const size_t SIZE_EXPECTED = 3;
+ // Check to make sure we have the right number of things in our storage
+ cout << "Running size comparison: Size is " << testStorage.size() << ", ";
+ cout << "Expected " << SIZE_EXPECTED << "...";
+ if(testStorage.size() == SIZE_EXPECTED)
+ cout << "PASSED" << endl;
+ else {
+ cout << "FAILED" << endl;
+ errno++;
+ }
+
+ // Check to make sure that each of our found items has the right extension
+ cout << "Checking Returned Extensions...";
+ bool extsOkay = true;
+ String8 wrongExts;
+ for (size_t i = 0; i < SIZE_EXPECTED; ++i) {
+ String8 testExt(testStorage.keyAt(i).getPathExtension());
+ testExt.toLower();
+ if (testExt != ".png") {
+ wrongExts += testStorage.keyAt(i);
+ wrongExts += "\n";
+ extsOkay = false;
+ }
+ }
+ if (extsOkay)
+ cout << "PASSED" << endl;
+ else {
+ cout << "FAILED" << endl;
+ cout << "The following extensions didn't check out" << endl << wrongExts;
+ }
+
+ // Clean up
+ delete sdw;
+
+ if(errno == 0) {
+ cout << "ALL TESTS PASSED" << endl;
+ } else {
+ cout << errno << " TESTS FAILED" << endl;
+ }
+ return errno;
+} \ No newline at end of file
diff --git a/tools/aapt/tests/MockCacheUpdater.h b/tools/aapt/tests/MockCacheUpdater.h
new file mode 100644
index 000000000000..c7f4bd7359a1
--- /dev/null
+++ b/tools/aapt/tests/MockCacheUpdater.h
@@ -0,0 +1,40 @@
+//
+// Copyright 2011 The Android Open Source Project
+//
+#ifndef MOCKCACHEUPDATER_H
+#define MOCKCACHEUPDATER_H
+
+#include <utils/String8.h>
+#include "CacheUpdater.h"
+
+using namespace android;
+
+class MockCacheUpdater : public CacheUpdater {
+public:
+
+ MockCacheUpdater()
+ : deleteCount(0), processCount(0) { };
+
+ // Make sure all the directories along this path exist
+ virtual void ensureDirectoriesExist(String8 path)
+ {
+ // Nothing to do
+ };
+
+ // Delete a file
+ virtual void deleteFile(String8 path) {
+ deleteCount++;
+ };
+
+ // Process an image from source out to dest
+ virtual void processImage(String8 source, String8 dest) {
+ processCount++;
+ };
+
+ // DATA MEMBERS
+ int deleteCount;
+ int processCount;
+private:
+};
+
+#endif // MOCKCACHEUPDATER_H \ No newline at end of file
diff --git a/tools/aapt/tests/MockDirectoryWalker.h b/tools/aapt/tests/MockDirectoryWalker.h
new file mode 100644
index 000000000000..5900cf3d8b0a
--- /dev/null
+++ b/tools/aapt/tests/MockDirectoryWalker.h
@@ -0,0 +1,85 @@
+//
+// Copyright 2011 The Android Open Source Project
+//
+#ifndef MOCKDIRECTORYWALKER_H
+#define MOCKDIRECTORYWALKER_H
+
+#include <utils/Vector.h>
+#include <utils/String8.h>
+#include <utility>
+#include "DirectoryWalker.h"
+
+using namespace android;
+using std::pair;
+
+// String8 Directory Walker
+// This is an implementation of the Directory Walker abstraction that is built
+// for testing.
+// Instead of system calls it queries a private data structure for the directory
+// entries. It takes a path and a map of filenames and their modification times.
+// functions are inlined since they are short and simple
+
+class StringDirectoryWalker : public DirectoryWalker {
+public:
+ StringDirectoryWalker(String8& path, Vector< pair<String8,time_t> >& data)
+ : mPos(0), mBasePath(path), mData(data) {
+ //fprintf(stdout,"StringDW built to mimic %s with %d files\n",
+ // mBasePath.string());
+ };
+ // Default copy constructor, and destructor are fine
+
+ virtual bool openDir(String8 path) {
+ // If the user is trying to query the "directory" that this
+ // walker was initialized with, then return success. Else fail.
+ return path == mBasePath;
+ };
+ virtual bool openDir(const char* path) {
+ String8 p(path);
+ openDir(p);
+ return true;
+ };
+ // Advance to next entry in the Vector
+ virtual struct dirent* nextEntry() {
+ // Advance position and check to see if we're done
+ if (mPos >= mData.size())
+ return NULL;
+
+ // Place data in the entry descriptor. This class only returns files.
+ mEntry.d_type = DT_REG;
+ mEntry.d_ino = mPos;
+ // Copy chars from the string name to the entry name
+ size_t i = 0;
+ for (i; i < mData[mPos].first.size(); ++i)
+ mEntry.d_name[i] = mData[mPos].first[i];
+ mEntry.d_name[i] = '\0';
+
+ // Place data in stats
+ mStats.st_ino = mPos;
+ mStats.st_mtime = mData[mPos].second;
+
+ // Get ready to move to the next entry
+ mPos++;
+
+ return &mEntry;
+ };
+ // Get the stats for the current entry
+ virtual struct stat* entryStats() {
+ return &mStats;
+ };
+ // Nothing to do in clean up
+ virtual void closeDir() {
+ // Nothing to do
+ };
+ virtual DirectoryWalker* clone() {
+ return new StringDirectoryWalker(*this);
+ };
+private:
+ // Current position in the Vector
+ size_t mPos;
+ // Base path
+ String8 mBasePath;
+ // Data to simulate a directory full of files.
+ Vector< pair<String8,time_t> > mData;
+};
+
+#endif // MOCKDIRECTORYWALKER_H \ No newline at end of file
diff --git a/tools/aapt/tests/MockFileFinder.h b/tools/aapt/tests/MockFileFinder.h
new file mode 100644
index 000000000000..da5ea4fcd3a2
--- /dev/null
+++ b/tools/aapt/tests/MockFileFinder.h
@@ -0,0 +1,55 @@
+//
+// Copyright 2011 The Android Open Source Project
+//
+
+#ifndef MOCKFILEFINDER_H
+#define MOCKFILEFINDER_H
+
+#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+#include "DirectoryWalker.h"
+
+using namespace android;
+
+class MockFileFinder : public FileFinder {
+public:
+ MockFileFinder (KeyedVector<String8, KeyedVector<String8,time_t> >& files)
+ : mFiles(files)
+ {
+ // Nothing left to do
+ };
+
+ /**
+ * findFiles implementation for the abstraction.
+ * PRECONDITIONS:
+ * No checking is done, so there MUST be an entry in mFiles with
+ * path matching basePath.
+ *
+ * POSTCONDITIONS:
+ * fileStore is filled with a copy of the data in mFiles corresponding
+ * to the basePath.
+ */
+
+ virtual bool findFiles(String8 basePath, Vector<String8>& extensions,
+ KeyedVector<String8,time_t>& fileStore,
+ DirectoryWalker* dw)
+ {
+ const KeyedVector<String8,time_t>* payload(&mFiles.valueFor(basePath));
+ // Since KeyedVector doesn't implement swap
+ // (who doesn't use swap??) we loop and add one at a time.
+ for (size_t i = 0; i < payload->size(); ++i) {
+ fileStore.add(payload->keyAt(i),payload->valueAt(i));
+ }
+ return true;
+ }
+
+private:
+ // Virtual mapping between "directories" and the "files" contained
+ // in them
+ KeyedVector<String8, KeyedVector<String8,time_t> > mFiles;
+};
+
+
+#endif // MOCKFILEFINDER_H \ No newline at end of file
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 6e13d0fb349c..f1f0fcc6ac9f 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -104,18 +104,30 @@ public class WifiNative {
public native static boolean stopDriverCommand();
+
+ /**
+ * Start filtering out Multicast V4 packets
+ * @return {@code true} if the operation succeeded, {@code false} otherwise
+ */
+ public native static boolean startFilteringMulticastV4Packets();
+
+ /**
+ * Stop filtering out Multicast V4 packets.
+ * @return {@code true} if the operation succeeded, {@code false} otherwise
+ */
+ public native static boolean stopFilteringMulticastV4Packets();
+
/**
- * Start filtering out multicast packets, to reduce battery consumption
- * that would result from processing them, only to discard them.
+ * Start filtering out Multicast V6 packets
* @return {@code true} if the operation succeeded, {@code false} otherwise
*/
- public native static boolean startPacketFiltering();
+ public native static boolean startFilteringMulticastV6Packets();
/**
- * Stop filtering out multicast packets.
+ * Stop filtering out Multicast V6 packets.
* @return {@code true} if the operation succeeded, {@code false} otherwise
*/
- public native static boolean stopPacketFiltering();
+ public native static boolean stopFilteringMulticastV6Packets();
public native static boolean setPowerModeCommand(int mode);
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 12efeb1e59f1..1e3afbdf7f18 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -82,6 +82,7 @@ import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;
/**
@@ -96,7 +97,7 @@ public class WifiStateMachine extends StateMachine {
private static final String NETWORKTYPE = "WIFI";
private static final boolean DBG = false;
- /* TODO: fetch a configurable interface */
+ /* TODO: This is no more used with the hostapd code. Clean up */
private static final String SOFTAP_IFACE = "wl0.1";
private WifiMonitor mWifiMonitor;
@@ -160,6 +161,9 @@ public class WifiStateMachine extends StateMachine {
/* Tracks current frequency mode */
private AtomicInteger mFrequencyBand = new AtomicInteger(WifiManager.WIFI_FREQUENCY_BAND_AUTO);
+ /* Tracks if we are filtering Multicast v4 packets. Default is to filter. */
+ private AtomicBoolean mFilteringMulticastV4Packets = new AtomicBoolean(true);
+
// Channel for sending replies.
private AsyncChannel mReplyChannel = new AsyncChannel();
@@ -204,8 +208,10 @@ public class WifiStateMachine extends StateMachine {
static final int CMD_SET_AP_CONFIG = BASE + 23;
/* Get the soft access point configuration */
static final int CMD_GET_AP_CONFIG = BASE + 24;
+ /* Set configuration on tether interface */
+ static final int CMD_TETHER_INTERFACE = BASE + 25;
- static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE = BASE + 25;
+ static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE = BASE + 26;
/* Supplicant events */
/* Connection to supplicant established */
@@ -285,6 +291,11 @@ public class WifiStateMachine extends StateMachine {
static final int CMD_START_PACKET_FILTERING = BASE + 84;
/* Clear packet filter */
static final int CMD_STOP_PACKET_FILTERING = BASE + 85;
+
+ /* arg1 values to CMD_STOP_PACKET_FILTERING and CMD_START_PACKET_FILTERING */
+ static final int MULTICAST_V6 = 1;
+ static final int MULTICAST_V4 = 0;
+
/* Connect to a specified network (network id
* or WifiConfiguration) This involves increasing
* the priority of the network, enabling the network
@@ -412,8 +423,10 @@ public class WifiStateMachine extends StateMachine {
/* Waiting for WPS to be completed*/
private State mWaitForWpsCompletionState = new WaitForWpsCompletionState();
- /* Soft Ap is running */
+ /* Soft ap is running */
private State mSoftApStartedState = new SoftApStartedState();
+ /* Soft ap is running and we are tethered through connectivity service */
+ private State mTetheredState = new TetheredState();
/**
@@ -504,13 +517,9 @@ public class WifiStateMachine extends StateMachine {
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
-
ArrayList<String> available = intent.getStringArrayListExtra(
ConnectivityManager.EXTRA_AVAILABLE_TETHER);
- ArrayList<String> active = intent.getStringArrayListExtra(
- ConnectivityManager.EXTRA_ACTIVE_TETHER);
- updateTetherState(available, active);
-
+ sendMessage(CMD_TETHER_INTERFACE, available);
}
},new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
@@ -550,6 +559,7 @@ public class WifiStateMachine extends StateMachine {
addState(mDriverStoppedState, mSupplicantStartedState);
addState(mSupplicantStoppingState, mDefaultState);
addState(mSoftApStartedState, mDefaultState);
+ addState(mTetheredState, mSoftApStartedState);
setInitialState(mInitialState);
@@ -868,17 +878,33 @@ public class WifiStateMachine extends StateMachine {
}
/**
- * Start packet filtering
+ * Start filtering Multicast v4 packets
+ */
+ public void startFilteringMulticastV4Packets() {
+ mFilteringMulticastV4Packets.set(true);
+ sendMessage(obtainMessage(CMD_START_PACKET_FILTERING, MULTICAST_V4, 0));
+ }
+
+ /**
+ * Stop filtering Multicast v4 packets
+ */
+ public void stopFilteringMulticastV4Packets() {
+ mFilteringMulticastV4Packets.set(false);
+ sendMessage(obtainMessage(CMD_STOP_PACKET_FILTERING, MULTICAST_V4, 0));
+ }
+
+ /**
+ * Start filtering Multicast v4 packets
*/
- public void startPacketFiltering() {
- sendMessage(CMD_START_PACKET_FILTERING);
+ public void startFilteringMulticastV6Packets() {
+ sendMessage(obtainMessage(CMD_START_PACKET_FILTERING, MULTICAST_V6, 0));
}
/**
- * Stop packet filtering
+ * Stop filtering Multicast v4 packets
*/
- public void stopPacketFiltering() {
- sendMessage(CMD_STOP_PACKET_FILTERING);
+ public void stopFilteringMulticastV6Packets() {
+ sendMessage(obtainMessage(CMD_STOP_PACKET_FILTERING, MULTICAST_V6, 0));
}
/**
@@ -1023,14 +1049,17 @@ public class WifiStateMachine extends StateMachine {
* Internal private functions
********************************************************/
- private void updateTetherState(ArrayList<String> available, ArrayList<String> tethered) {
-
- boolean wifiTethered = false;
- boolean wifiAvailable = false;
-
+ private void checkAndSetConnectivityInstance() {
if (mCm == null) {
mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
}
+ }
+
+ private void startTethering(ArrayList<String> available) {
+
+ boolean wifiAvailable = false;
+
+ checkAndSetConnectivityInstance();
String[] wifiRegexs = mCm.getTetherableWifiRegexs();
@@ -1066,6 +1095,29 @@ public class WifiStateMachine extends StateMachine {
}
}
+ private void stopTethering() {
+
+ checkAndSetConnectivityInstance();
+
+ /* Clear the interface config to allow dhcp correctly configure new
+ ip settings */
+ InterfaceConfiguration ifcg = null;
+ try {
+ ifcg = nwService.getInterfaceConfig(mInterfaceName);
+ if (ifcg != null) {
+ ifcg.addr = new LinkAddress(NetworkUtils.numericToInetAddress(
+ "0.0.0.0"), 0);
+ nwService.setInterfaceConfig(mInterfaceName, ifcg);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Error resetting interface " + mInterfaceName + ", :" + e);
+ }
+
+ if (mCm.untether(mInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+ Log.e(TAG, "Untether initiate failed!");
+ }
+ }
+
/**
* Set the country code from the system setting value, if any.
*/
@@ -1591,12 +1643,15 @@ public class WifiStateMachine extends StateMachine {
if (currentStatus == SOFT_AP_STOPPED) {
nwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE);
} else if (currentStatus == SOFT_AP_RUNNING) {
- nwService.setAccessPoint(config, mInterfaceName, SOFTAP_IFACE);
+ //nwService.setAccessPoint(config, mInterfaceName, SOFTAP_IFACE);
+ //TODO: when we have a control channel to hostapd, we should not need to do this
+ nwService.stopAccessPoint(mInterfaceName);
+ nwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE);
}
} catch (Exception e) {
Log.e(TAG, "Exception in softap start " + e);
try {
- nwService.stopAccessPoint();
+ nwService.stopAccessPoint(mInterfaceName);
nwService.startAccessPoint(config, mInterfaceName, SOFTAP_IFACE);
} catch (Exception ee) {
Log.e(TAG, "Exception during softap restart : " + ee);
@@ -1749,6 +1804,7 @@ public class WifiStateMachine extends StateMachine {
case CMD_STOP_DRIVER:
case CMD_START_AP:
case CMD_STOP_AP:
+ case CMD_TETHER_INTERFACE:
case CMD_START_SCAN:
case CMD_DISCONNECT:
case CMD_RECONNECT:
@@ -2074,9 +2130,6 @@ public class WifiStateMachine extends StateMachine {
WifiConfigStore.initialize(mContext);
- //TODO: initialize and fix multicast filtering
- //mWM.initializeMulticastFiltering();
-
sendSupplicantConnectionChangedBroadcast(true);
transitionTo(mDriverStartedState);
break;
@@ -2359,6 +2412,16 @@ public class WifiStateMachine extends StateMachine {
/* initialize network state */
setNetworkDetailedState(DetailedState.DISCONNECTED);
+ /* Remove any filtering on Multicast v6 at start */
+ WifiNative.stopFilteringMulticastV6Packets();
+
+ /* Reset Multicast v4 filtering state */
+ if (mFilteringMulticastV4Packets.get()) {
+ WifiNative.startFilteringMulticastV4Packets();
+ } else {
+ WifiNative.stopFilteringMulticastV4Packets();
+ }
+
if (mIsScanMode) {
WifiNative.setScanResultHandlingCommand(SCAN_ONLY_MODE);
WifiNative.disconnectCommand();
@@ -2419,10 +2482,22 @@ public class WifiStateMachine extends StateMachine {
mWakeLock.release();
break;
case CMD_START_PACKET_FILTERING:
- WifiNative.startPacketFiltering();
+ if (message.arg1 == MULTICAST_V6) {
+ WifiNative.startFilteringMulticastV6Packets();
+ } else if (message.arg1 == MULTICAST_V4) {
+ WifiNative.startFilteringMulticastV4Packets();
+ } else {
+ Log.e(TAG, "Illegal arugments to CMD_START_PACKET_FILTERING");
+ }
break;
case CMD_STOP_PACKET_FILTERING:
- WifiNative.stopPacketFiltering();
+ if (message.arg1 == MULTICAST_V6) {
+ WifiNative.stopFilteringMulticastV6Packets();
+ } else if (message.arg1 == MULTICAST_V4) {
+ WifiNative.stopFilteringMulticastV4Packets();
+ } else {
+ Log.e(TAG, "Illegal arugments to CMD_STOP_PACKET_FILTERING");
+ }
break;
default:
return NOT_HANDLED;
@@ -2784,10 +2859,7 @@ public class WifiStateMachine extends StateMachine {
deferMessage(message);
break;
case CMD_REQUEST_CM_WAKELOCK:
- if (mCm == null) {
- mCm = (ConnectivityManager)mContext.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- }
+ checkAndSetConnectivityInstance();
mCm.requestNetworkTransitionWakelock(TAG);
break;
case CMD_SET_SCAN_MODE:
@@ -3065,16 +3137,9 @@ public class WifiStateMachine extends StateMachine {
case CMD_STOP_AP:
Log.d(TAG,"Stopping Soft AP");
setWifiApState(WIFI_AP_STATE_DISABLING);
-
- if (mCm == null) {
- mCm = (ConnectivityManager) mContext.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- }
- if (mCm.untether(SOFTAP_IFACE) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
- Log.e(TAG, "Untether initiate failed!");
- }
+ stopTethering();
try {
- nwService.stopAccessPoint();
+ nwService.stopAccessPoint(mInterfaceName);
} catch(Exception e) {
Log.e(TAG, "Exception in stopAccessPoint()");
}
@@ -3096,6 +3161,11 @@ public class WifiStateMachine extends StateMachine {
Log.e(TAG,"Cannot start supplicant with a running soft AP");
setWifiState(WIFI_STATE_UNKNOWN);
break;
+ case CMD_TETHER_INTERFACE:
+ ArrayList<String> available = (ArrayList<String>) message.obj;
+ startTethering(available);
+ transitionTo(mTetheredState);
+ break;
default:
return NOT_HANDLED;
}
@@ -3103,4 +3173,24 @@ public class WifiStateMachine extends StateMachine {
return HANDLED;
}
}
+
+ class TetheredState extends State {
+ @Override
+ public void enter() {
+ if (DBG) Log.d(TAG, getName() + "\n");
+ EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
+ }
+ @Override
+ public boolean processMessage(Message message) {
+ if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
+ switch(message.what) {
+ case CMD_TETHER_INTERFACE:
+ // Ignore any duplicate interface available notifications
+ // when in tethered state
+ return HANDLED;
+ default:
+ return NOT_HANDLED;
+ }
+ }
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index 0eb73b7e8a95..fa7cf21627bf 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -16,11 +16,15 @@
package android.net.wifi;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.DnsPinger;
@@ -29,7 +33,7 @@ import android.net.Uri;
import android.os.Message;
import android.os.SystemClock;
import android.provider.Settings;
-import android.text.TextUtils;
+import android.provider.Settings.Secure;
import android.util.Slog;
import com.android.internal.util.Protocol;
@@ -45,6 +49,7 @@ import java.net.URL;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
+import java.util.regex.Pattern;
/**
* {@link WifiWatchdogStateMachine} monitors the initial connection to a Wi-Fi
@@ -62,6 +67,7 @@ import java.util.Scanner;
*/
public class WifiWatchdogStateMachine extends StateMachine {
+
private static final boolean VDBG = false;
private static final boolean DBG = true;
private static final String WWSM_TAG = "WifiWatchdogStateMachine";
@@ -72,18 +78,22 @@ public class WifiWatchdogStateMachine extends StateMachine {
*/
private static final int LOW_SIGNAL_CUTOFF = 1;
- private static final long MIN_LOW_SIGNAL_CHECK_INTERVAL_MS = 2 * 60 * 1000;
- private static final long MIN_SINGLE_DNS_CHECK_INTERVAL_MS = 10 * 60 * 1000;
- private static final long MIN_WALLED_GARDEN_INTERVAL_MS = 30 * 60 * 1000;
-
- private static final int MAX_CHECKS_PER_SSID = 7;
- private static final int NUM_DNS_PINGS = 5;
- private static final double MIN_DNS_RESPONSE_RATE = 0.50;
+ private static final long DEFAULT_DNS_CHECK_SHORT_INTERVAL_MS = 2 * 60 * 1000;
+ private static final long DEFAULT_DNS_CHECK_LONG_INTERVAL_MS = 10 * 60 * 1000;
+ private static final long DEFAULT_WALLED_GARDEN_INTERVAL_MS = 30 * 60 * 1000;
- private static final int DNS_PING_TIMEOUT_MS = 800;
+ private static final int DEFAULT_MAX_SSID_BLACKLISTS = 7;
+ private static final int DEFAULT_NUM_DNS_PINGS = 5;
+ private static final int DEFAULT_MIN_DNS_RESPONSES = 3;
private static final long DNS_PING_INTERVAL_MS = 100;
- private static final long BLACKLIST_FOLLOWUP_INTERVAL_MS = 15 * 1000;
+ private static final int DEFAULT_DNS_PING_TIMEOUT_MS = 1500;
+
+ private static final long DEFAULT_BLACKLIST_FOLLOWUP_INTERVAL_MS = 15 * 1000;
+
+ private static final String DEFAULT_WALLED_GARDEN_URL = "http://www.google.com/";
+ private static final String DEFAULT_WALLED_GARDEN_PATTERN = "<title>.*Google.*</title>";
+
private static final int BASE = Protocol.BASE_WIFI_WATCHDOG;
@@ -104,6 +114,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
private static final int EVENT_RSSI_CHANGE = BASE + 3;
private static final int EVENT_SCAN_RESULTS_AVAILABLE = BASE + 4;
private static final int EVENT_WIFI_RADIO_STATE_CHANGE = BASE + 5;
+ private static final int EVENT_WATCHDOG_SETTINGS_CHANGE = BASE + 6;
private static final int MESSAGE_CHECK_STEP = BASE + 100;
private static final int MESSAGE_HANDLE_WALLED_GARDEN = BASE + 101;
@@ -132,6 +143,19 @@ public class WifiWatchdogStateMachine extends StateMachine {
private WalledGardenState mWalledGardenState = new WalledGardenState();
private BlacklistedApState mBlacklistedApState = new BlacklistedApState();
+ private long mDnsCheckShortIntervalMs;
+ private long mDnsCheckLongIntervalMs;
+ private long mWalledGardenIntervalMs;
+ private int mMaxSsidBlacklists;
+ private int mNumDnsPings;
+ private int mMinDnsResponses;
+ private int mDnsPingTimeoutMs;
+ private long mBlacklistFollowupIntervalMs;
+ private boolean mWalledGardenTestEnabled;
+ private String mWalledGardenUrl;
+ private Pattern mWalledGardenPattern;
+
+ private boolean mShowDisabledNotification;
/**
* The {@link WifiInfo} object passed to WWSM on network broadcasts
*/
@@ -142,7 +166,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
* Currently maintained but not used, TODO
*/
private HashSet<String> mBssids = new HashSet<String>();
- private int mNumFullDNSchecks = 0;
+ private int mNumCheckFailures = 0;
private Long mLastWalledGardenCheckTime = null;
@@ -158,7 +182,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
* / \
* Disabled Enabled
* / \
- * Disconnected Connected
+ * NotConnected Connected
* /---------\
* (all other states)
*/
@@ -174,6 +198,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
// The content observer to listen needs a handler
registerForSettingsChanges();
+ registerForWatchdogToggle();
addState(mDefaultState);
addState(mWatchdogDisabledState, mDefaultState);
addState(mWatchdogEnabledState, mDefaultState);
@@ -186,6 +211,9 @@ public class WifiWatchdogStateMachine extends StateMachine {
addState(mOnlineWatchState, mConnectedState);
setInitialState(mWatchdogDisabledState);
+ updateSettings();
+ mShowDisabledNotification = getSettingsBoolean(mContentResolver,
+ Settings.Secure.WIFI_WATCHDOG_SHOW_DISABLED_NETWORK_POPUP, true);
}
public static WifiWatchdogStateMachine makeWifiWatchdogStateMachine(Context context) {
@@ -228,7 +256,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
/**
* Observes the watchdog on/off setting, and takes action when changed.
*/
- private void registerForSettingsChanges() {
+ private void registerForWatchdogToggle() {
ContentObserver contentObserver = new ContentObserver(this.getHandler()) {
@Override
public void onChange(boolean selfChange) {
@@ -242,6 +270,54 @@ public class WifiWatchdogStateMachine extends StateMachine {
}
/**
+ * Observes watchdogs secure setting changes.
+ */
+ private void registerForSettingsChanges() {
+ ContentObserver contentObserver = new ContentObserver(this.getHandler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ sendMessage(EVENT_WATCHDOG_SETTINGS_CHANGE);
+ }
+ };
+
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(
+ Settings.Secure.WIFI_WATCHDOG_DNS_CHECK_SHORT_INTERVAL_MS),
+ false, contentObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_DNS_CHECK_LONG_INTERVAL_MS),
+ false, contentObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_INTERVAL_MS),
+ false, contentObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_MAX_SSID_BLACKLISTS),
+ false, contentObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_NUM_DNS_PINGS),
+ false, contentObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_MIN_DNS_RESPONSES),
+ false, contentObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_DNS_PING_TIMEOUT_MS),
+ false, contentObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(
+ Settings.Secure.WIFI_WATCHDOG_BLACKLIST_FOLLOWUP_INTERVAL_MS),
+ false, contentObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_TEST_ENABLED),
+ false, contentObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_URL),
+ false, contentObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_PATTERN),
+ false, contentObserver);
+ }
+
+ /**
* DNS based detection techniques do not work at all hotspots. The one sure
* way to check a walled garden is to see if a URL fetch on a known address
* fetches the data we expect
@@ -250,11 +326,11 @@ public class WifiWatchdogStateMachine extends StateMachine {
InputStream in = null;
HttpURLConnection urlConnection = null;
try {
- URL url = new URL(getWalledGardenUrl());
+ URL url = new URL(mWalledGardenUrl);
urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream());
Scanner scanner = new Scanner(in);
- if (scanner.findInLine(getWalledGardenPattern()) != null) {
+ if (scanner.findInLine(mWalledGardenPattern) != null) {
return false;
} else {
return true;
@@ -281,49 +357,49 @@ public class WifiWatchdogStateMachine extends StateMachine {
pw.print("WatchdogStatus: ");
pw.print("State " + getCurrentState());
pw.println(", network [" + mInitialConnInfo + "]");
- pw.print("checkCount " + mNumFullDNSchecks);
+ pw.print("checkFailures " + mNumCheckFailures);
pw.println(", bssids: " + mBssids);
pw.println("lastSingleCheck: " + mOnlineWatchState.lastCheckTime);
}
- /**
- * @see android.provider.Settings.Secure#WIFI_WATCHDOG_WALLED_GARDEN_TEST_ENABLED
- */
- private Boolean isWalledGardenTestEnabled() {
- return Settings.Secure.getInt(mContentResolver,
- Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_TEST_ENABLED, 1) == 1;
- }
-
- /**
- * @see android.provider.Settings.Secure#WIFI_WATCHDOG_WALLED_GARDEN_URL
- */
- private String getWalledGardenUrl() {
- String url = Settings.Secure.getString(mContentResolver,
- Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_URL);
- if (TextUtils.isEmpty(url))
- return "http://www.google.com/";
- return url;
- }
-
- /**
- * @see android.provider.Settings.Secure#WIFI_WATCHDOG_WALLED_GARDEN_PATTERN
- */
- private String getWalledGardenPattern() {
- String pattern = Settings.Secure.getString(mContentResolver,
- Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_PATTERN);
- if (TextUtils.isEmpty(pattern))
- return "<title>.*Google.*</title>";
- return pattern;
- }
-
- /**
- * @see android.provider.Settings.Secure#WIFI_WATCHDOG_ON
- */
private boolean isWatchdogEnabled() {
- return Settings.Secure.getInt(mContentResolver,
- Settings.Secure.WIFI_WATCHDOG_ON, 1) == 1;
+ return getSettingsBoolean(mContentResolver, Settings.Secure.WIFI_WATCHDOG_ON, true);
}
+ private void updateSettings() {
+ mDnsCheckShortIntervalMs = Secure.getLong(mContentResolver,
+ Secure.WIFI_WATCHDOG_DNS_CHECK_SHORT_INTERVAL_MS,
+ DEFAULT_DNS_CHECK_SHORT_INTERVAL_MS);
+ mDnsCheckLongIntervalMs = Secure.getLong(mContentResolver,
+ Secure.WIFI_WATCHDOG_DNS_CHECK_LONG_INTERVAL_MS,
+ DEFAULT_DNS_CHECK_LONG_INTERVAL_MS);
+ mMaxSsidBlacklists = Secure.getInt(mContentResolver,
+ Secure.WIFI_WATCHDOG_MAX_SSID_BLACKLISTS,
+ DEFAULT_MAX_SSID_BLACKLISTS);
+ mNumDnsPings = Secure.getInt(mContentResolver,
+ Secure.WIFI_WATCHDOG_NUM_DNS_PINGS,
+ DEFAULT_NUM_DNS_PINGS);
+ mMinDnsResponses = Secure.getInt(mContentResolver,
+ Secure.WIFI_WATCHDOG_MIN_DNS_RESPONSES,
+ DEFAULT_MIN_DNS_RESPONSES);
+ mDnsPingTimeoutMs = Secure.getInt(mContentResolver,
+ Secure.WIFI_WATCHDOG_DNS_PING_TIMEOUT_MS,
+ DEFAULT_DNS_PING_TIMEOUT_MS);
+ mBlacklistFollowupIntervalMs = Secure.getLong(mContentResolver,
+ Settings.Secure.WIFI_WATCHDOG_BLACKLIST_FOLLOWUP_INTERVAL_MS,
+ DEFAULT_BLACKLIST_FOLLOWUP_INTERVAL_MS);
+ mWalledGardenTestEnabled = getSettingsBoolean(mContentResolver,
+ Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_TEST_ENABLED, true);
+ mWalledGardenUrl = getSettingsStr(mContentResolver,
+ Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_URL,
+ DEFAULT_WALLED_GARDEN_URL);
+ mWalledGardenPattern = Pattern.compile(getSettingsStr(mContentResolver,
+ Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_PATTERN,
+ DEFAULT_WALLED_GARDEN_PATTERN));
+ mWalledGardenIntervalMs = Secure.getLong(mContentResolver,
+ Secure.WIFI_WATCHDOG_WALLED_GARDEN_INTERVAL_MS,
+ DEFAULT_WALLED_GARDEN_INTERVAL_MS);
+ }
/**
* Helper to return wait time left given a min interval and last run
@@ -353,7 +429,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
mInitialConnInfo = null;
mDisableAPNextFailure = false;
mLastWalledGardenCheckTime = null;
- mNumFullDNSchecks = 0;
+ mNumCheckFailures = 0;
mBssids.clear();
}
@@ -365,13 +441,43 @@ public class WifiWatchdogStateMachine extends StateMachine {
mContext.startActivity(intent);
}
- private void sendCheckStepMessage(long delay) {
- sendMessageDelayed(obtainMessage(MESSAGE_CHECK_STEP, mNetEventCounter, 0), delay);
+ private void displayDisabledNetworkNotification() {
+ Resources r = Resources.getSystem();
+ CharSequence title =
+ r.getText(com.android.internal.R.string.wifi_watchdog_network_disabled);
+ CharSequence msg =
+ r.getText(com.android.internal.R.string.wifi_watchdog_network_disabled_detailed);
+
+ Notification wifiDisabledWarning = new Notification.Builder(mContext)
+ .setSmallIcon(com.android.internal.R.drawable.stat_sys_warning)
+ .setDefaults(Notification.DEFAULT_ALL)
+ .setTicker(title)
+ .setContentTitle(title)
+ .setContentText(msg)
+ .setContentIntent(PendingIntent.getActivity(mContext, 0,
+ new Intent(Settings.ACTION_WIFI_IP_SETTINGS)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0))
+ .setWhen(System.currentTimeMillis())
+ .setAutoCancel(true)
+ .getNotification();
+
+ NotificationManager notificationManager = (NotificationManager) mContext
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+
+ notificationManager.notify("WifiWatchdog", wifiDisabledWarning.icon, wifiDisabledWarning);
}
class DefaultState extends State {
@Override
public boolean processMessage(Message msg) {
+ switch (msg.what) {
+ case EVENT_WATCHDOG_SETTINGS_CHANGE:
+ updateSettings();
+ if (VDBG) {
+ Slog.d(WWSM_TAG, "Updating wifi-watchdog secure settings");
+ }
+ return HANDLED;
+ }
if (VDBG) {
Slog.v(WWSM_TAG, "Caught message " + msg.what + " in state " +
getCurrentState().getName());
@@ -509,6 +615,10 @@ public class WifiWatchdogStateMachine extends StateMachine {
mBssids.add(result.BSSID);
}
return HANDLED;
+ case EVENT_WATCHDOG_SETTINGS_CHANGE:
+ // Stop current checks, but let state update
+ transitionTo(mOnlineWatchState);
+ return NOT_HANDLED;
}
return NOT_HANDLED;
}
@@ -522,13 +632,12 @@ public class WifiWatchdogStateMachine extends StateMachine {
@Override
public void enter() {
- mNumFullDNSchecks++;
dnsCheckSuccesses = 0;
dnsCheckTries = 0;
if (DBG) {
Slog.d(WWSM_TAG, "Starting DNS pings at " + SystemClock.elapsedRealtime());
- dnsCheckLogStr = String.format("Dns Check %d. Pinging %s on ssid [%s]: ",
- mNumFullDNSchecks, mDnsPinger.getDns(), mInitialConnInfo.getSSID());
+ dnsCheckLogStr = String.format("Pinging %s on ssid [%s]: ",
+ mDnsPinger.getDns(), mInitialConnInfo.getSSID());
}
sendCheckStepMessage(0);
@@ -545,7 +654,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
}
long pingResponseTime = mDnsPinger.pingDns(mDnsPinger.getDns(),
- DNS_PING_TIMEOUT_MS);
+ mDnsPingTimeoutMs);
dnsCheckTries++;
if (pingResponseTime >= 0)
@@ -567,14 +676,12 @@ public class WifiWatchdogStateMachine extends StateMachine {
* After a full ping count, if we have more responses than this
* cutoff, the outcome is success; else it is 'failure'.
*/
- double pingResponseCutoff = MIN_DNS_RESPONSE_RATE * NUM_DNS_PINGS;
- int remainingChecks = NUM_DNS_PINGS - dnsCheckTries;
/**
* Our final success count will be at least this big, so we're
* guaranteed to succeed.
*/
- if (dnsCheckSuccesses >= pingResponseCutoff) {
+ if (dnsCheckSuccesses >= mMinDnsResponses) {
// DNS CHECKS OK, NOW WALLED GARDEN
if (DBG) {
Slog.d(WWSM_TAG, dnsCheckLogStr + "| SUCCESS");
@@ -603,7 +710,8 @@ public class WifiWatchdogStateMachine extends StateMachine {
* Our final count will be at most the current count plus the
* remaining pings - we're guaranteed to fail.
*/
- if (remainingChecks + dnsCheckSuccesses < pingResponseCutoff) {
+ int remainingChecks = mNumDnsPings - dnsCheckTries;
+ if (remainingChecks + dnsCheckSuccesses < mMinDnsResponses) {
if (DBG) {
Slog.d(WWSM_TAG, dnsCheckLogStr + "| FAILURE");
}
@@ -617,12 +725,12 @@ public class WifiWatchdogStateMachine extends StateMachine {
}
private boolean shouldCheckWalledGarden() {
- if (!isWalledGardenTestEnabled()) {
+ if (!mWalledGardenTestEnabled) {
if (VDBG)
Slog.v(WWSM_TAG, "Skipping walled garden check - disabled");
return false;
}
- long waitTime = waitTime(MIN_WALLED_GARDEN_INTERVAL_MS,
+ long waitTime = waitTime(mWalledGardenIntervalMs,
mLastWalledGardenCheckTime);
if (waitTime > 0) {
if (DBG) {
@@ -634,6 +742,10 @@ public class WifiWatchdogStateMachine extends StateMachine {
return true;
}
+ private void sendCheckStepMessage(long delay) {
+ sendMessageDelayed(obtainMessage(MESSAGE_CHECK_STEP, mNetEventCounter, 0), delay);
+ }
+
}
class OnlineWatchState extends State {
@@ -698,7 +810,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
}
lastCheckTime = SystemClock.elapsedRealtime();
long responseTime = mDnsPinger.pingDns(mDnsPinger.getDns(),
- DNS_PING_TIMEOUT_MS);
+ mDnsPingTimeoutMs);
if (responseTime >= 0) {
if (VDBG) {
Slog.v(WWSM_TAG, "Ran a single DNS ping. Response time: "
@@ -720,15 +832,15 @@ public class WifiWatchdogStateMachine extends StateMachine {
}
/**
- * Times a dns check with an interval based on {@link #curSignalStable}
+ * Times a dns check with an interval based on {@link #signalUnstable}
*/
private void triggerSingleDnsCheck() {
long waitInterval;
if (signalUnstable) {
- waitInterval = MIN_LOW_SIGNAL_CHECK_INTERVAL_MS;
+ waitInterval = mDnsCheckShortIntervalMs;
unstableSignalChecks = true;
} else {
- waitInterval = MIN_SINGLE_DNS_CHECK_INTERVAL_MS;
+ waitInterval = mDnsCheckLongIntervalMs;
}
sendMessageDelayed(obtainMessage(MESSAGE_SINGLE_DNS_CHECK, checkGuard, 0),
waitTime(waitInterval, lastCheckTime));
@@ -738,6 +850,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
class DnsCheckFailureState extends State {
@Override
public void enter() {
+ mNumCheckFailures++;
obtainMessage(MESSAGE_HANDLE_BAD_AP, mNetEventCounter, 0).sendToTarget();
}
@@ -754,16 +867,22 @@ public class WifiWatchdogStateMachine extends StateMachine {
return HANDLED;
}
- if (mDisableAPNextFailure || mNumFullDNSchecks >= MAX_CHECKS_PER_SSID) {
+ if (mDisableAPNextFailure || mNumCheckFailures >= mMaxSsidBlacklists) {
// TODO : Unban networks if they had low signal ?
Slog.i(WWSM_TAG, "Disabling current SSID " + wifiInfoToStr(mInitialConnInfo)
- + ". " +
- "numChecks " + mNumFullDNSchecks + ", numAPs " + mBssids.size());
+ + ". " + "numCheckFailures " + mNumCheckFailures
+ + ", numAPs " + mBssids.size());
mWifiManager.disableNetwork(mInitialConnInfo.getNetworkId());
+ if (mShowDisabledNotification) {
+ displayDisabledNetworkNotification();
+ mShowDisabledNotification = false;
+ putSettingsBoolean(mContentResolver,
+ Settings.Secure.WIFI_WATCHDOG_SHOW_DISABLED_NETWORK_POPUP, false);
+ }
transitionTo(mNotConnectedState);
} else {
- Slog.i(WWSM_TAG, "Blacklisting current BSSID. " + wifiInfoToStr(mInitialConnInfo) +
- "numChecks " + mNumFullDNSchecks + ", numAPs " + mBssids.size());
+ Slog.i(WWSM_TAG, "Blacklisting current BSSID. " + wifiInfoToStr(mInitialConnInfo)
+ + "numCheckFailures " + mNumCheckFailures + ", numAPs " + mBssids.size());
mWifiManager.addToBlacklist(mInitialConnInfo.getBSSID());
mWifiManager.reassociate();
@@ -802,7 +921,7 @@ public class WifiWatchdogStateMachine extends StateMachine {
public void enter() {
mDisableAPNextFailure = true;
sendMessageDelayed(obtainMessage(MESSAGE_NETWORK_FOLLOWUP, mNetEventCounter, 0),
- BLACKLIST_FOLLOWUP_INTERVAL_MS);
+ mBlacklistFollowupIntervalMs);
}
@Override
@@ -822,4 +941,57 @@ public class WifiWatchdogStateMachine extends StateMachine {
return HANDLED;
}
}
+
+
+ /**
+ * Convenience function for retrieving a single secure settings value
+ * as a string with a default value.
+ *
+ * @param cr The ContentResolver to access.
+ * @param name The name of the setting to retrieve.
+ * @param def Value to return if the setting is not defined.
+ *
+ * @return The setting's current value, or 'def' if it is not defined
+ */
+ private static String getSettingsStr(ContentResolver cr, String name, String def) {
+ String v = Settings.Secure.getString(cr, name);
+ return v != null ? v : def;
+ }
+
+ /**
+ * Convenience function for retrieving a single secure settings value
+ * as a boolean. Note that internally setting values are always
+ * stored as strings; this function converts the string to a boolean
+ * for you. The default value will be returned if the setting is
+ * not defined or not a valid boolean.
+ *
+ * @param cr The ContentResolver to access.
+ * @param name The name of the setting to retrieve.
+ * @param def Value to return if the setting is not defined.
+ *
+ * @return The setting's current value, or 'def' if it is not defined
+ * or not a valid boolean.
+ */
+ private static boolean getSettingsBoolean(ContentResolver cr, String name, boolean def) {
+ return Settings.Secure.getInt(cr, name, def ? 1 : 0) == 1;
+ }
+
+ /**
+ * Convenience function for updating a single settings value as an
+ * integer. This will either create a new entry in the table if the
+ * given name does not exist, or modify the value of the existing row
+ * with that name. Note that internally setting values are always
+ * stored as strings, so this function converts the given value to a
+ * string before storing it.
+ *
+ * @param cr The ContentResolver to access.
+ * @param name The name of the setting to modify.
+ * @param value The new value for the setting.
+ * @return true if the value was set, false on database errors
+ */
+ private static boolean putSettingsBoolean(ContentResolver cr, String name, boolean value) {
+ return Settings.Secure.putInt(cr, name, value ? 1 : 0);
+ }
+
+
}