summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk2
-rw-r--r--api/current.xml527
-rw-r--r--core/java/android/app/ActivityManager.java43
-rw-r--r--core/java/android/app/ActivityManagerNative.java29
-rw-r--r--core/java/android/app/FragmentBreadCrumbs.java44
-rw-r--r--core/java/android/app/IActivityManager.java3
-rw-r--r--core/java/android/app/KeyguardManager.java34
-rw-r--r--core/java/android/app/ListActivity.java6
-rw-r--r--core/java/android/app/backup/WallpaperBackupHelper.java12
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java3
-rw-r--r--core/java/android/bluetooth/BluetoothDeviceProfileState.java18
-rw-r--r--core/java/android/bluetooth/BluetoothInputDevice.java320
-rw-r--r--core/java/android/bluetooth/BluetoothProfile.java5
-rw-r--r--core/java/android/bluetooth/BluetoothProfileState.java10
-rw-r--r--core/java/android/bluetooth/IBluetooth.aidl3
-rwxr-xr-xcore/java/android/content/res/Resources.java2
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java91
-rw-r--r--core/java/android/net/DummyDataStateTracker.java21
-rw-r--r--core/java/android/net/MobileDataStateTracker.java69
-rw-r--r--core/java/android/net/NetworkStateTracker.java33
-rw-r--r--core/java/android/net/TrafficStats.java37
-rw-r--r--core/java/android/os/BatteryStats.java25
-rw-r--r--core/java/android/provider/Settings.java1
-rw-r--r--core/java/android/server/BluetoothEventLoop.java35
-rw-r--r--core/java/android/server/BluetoothInputProfileHandler.java19
-rw-r--r--core/java/android/server/BluetoothService.java82
-rw-r--r--core/java/android/text/Layout.java21
-rw-r--r--core/java/android/text/StaticLayout.java70
-rw-r--r--core/java/android/util/AttributeSet.java70
-rw-r--r--core/java/android/view/IWindowManager.aidl2
-rwxr-xr-xcore/java/android/view/InputDevice.java38
-rwxr-xr-xcore/java/android/view/KeyEvent.java497
-rw-r--r--core/java/android/view/MotionEvent.java707
-rw-r--r--core/java/android/view/View.java92
-rw-r--r--core/java/android/view/ViewGroup.java16
-rw-r--r--core/java/android/view/ViewRoot.java13
-rw-r--r--core/java/android/view/VolumePanel.java4
-rw-r--r--core/java/android/view/WindowManagerPolicy.java18
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java3
-rw-r--r--core/java/android/webkit/CookieSyncManager.java18
-rw-r--r--core/java/android/webkit/DebugFlags.java4
-rw-r--r--core/java/android/webkit/HTML5VideoViewProxy.java32
-rw-r--r--core/java/android/webkit/WebView.java55
-rw-r--r--core/java/android/webkit/WebViewCore.java71
-rw-r--r--core/java/android/webkit/ZoomManager.java8
-rw-r--r--core/java/android/widget/GridView.java34
-rw-r--r--core/java/android/widget/PopupWindow.java15
-rw-r--r--core/java/android/widget/TextView.java252
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java43
-rw-r--r--core/java/com/android/internal/view/menu/MenuPopupHelper.java51
-rw-r--r--core/java/com/android/internal/widget/PointerLocationView.java38
-rwxr-xr-xcore/jni/android_bluetooth_BluetoothAudioGateway.cpp64
-rw-r--r--core/jni/android_bluetooth_BluetoothSocket.cpp20
-rw-r--r--core/jni/android_bluetooth_HeadsetBase.cpp14
-rw-r--r--core/jni/android_net_TrafficStats.cpp31
-rw-r--r--core/jni/android_server_BluetoothA2dpService.cpp20
-rw-r--r--core/jni/android_server_BluetoothEventLoop.cpp22
-rw-r--r--core/jni/android_server_BluetoothService.cpp94
-rw-r--r--core/jni/android_view_MotionEvent.cpp85
-rwxr-xr-xcore/res/res/values/attrs.xml11
-rw-r--r--core/res/res/values/public.xml8
-rw-r--r--core/res/res/values/styles.xml2
-rw-r--r--core/res/res/values/themes.xml4
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java40
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java11
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java7
-rw-r--r--core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java4
-rw-r--r--core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java207
-rw-r--r--core/tests/coretests/src/android/database/sqlite/SQLiteCursorTest.java2
-rw-r--r--core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java7
-rw-r--r--data/keyboards/Android.mk18
-rw-r--r--data/keyboards/Generic.kcm126
-rw-r--r--data/keyboards/Generic.kl14
-rw-r--r--data/keyboards/Vendor_046d_Product_c216.kl37
-rw-r--r--data/keyboards/Vendor_054c_Product_0268.kl76
-rw-r--r--data/keyboards/common.mk2
-rw-r--r--docs/html/guide/appendix/api-levels.jd1
-rw-r--r--docs/html/guide/developing/tools/aidl.jd556
-rw-r--r--docs/html/guide/guide_toc.cs2
-rw-r--r--docs/html/guide/topics/advanced/aidl.jd389
-rw-r--r--docs/html/guide/topics/fundamentals/bound-services.jd4
-rw-r--r--docs/html/guide/topics/graphics/renderscript.jd156
-rw-r--r--docs/html/guide/topics/manifest/uses-library-element.jd115
-rw-r--r--docs/html/resources/resources-data.js10
-rw-r--r--docs/html/sdk/android-3.0-optimize.jd397
-rw-r--r--docs/html/sdk/android-3.0.jd6
-rw-r--r--docs/html/sdk/api_diff/11/changes.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/alldiffs_index_additions.html9
-rw-r--r--docs/html/sdk/api_diff/11/changes/alldiffs_index_all.html9
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.Manifest.permission.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.R.attr.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.R.dimen.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.R.drawable.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.R.id.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.R.layout.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.R.string.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.R.style.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.accounts.AccountManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.accounts.AuthenticatorDescription.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.Activity.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.RecentTaskInfo.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.Builder.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.DatePickerDialog.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.Dialog.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.Request.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.Notification.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.PendingIntent.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.ProgressDialog.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.SearchManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.Service.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.WallpaperManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminInfo.html9
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminReceiver.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.app.admin.DevicePolicyManager.html16
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetHost.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetProviderInfo.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.bluetooth.BluetoothAdapter.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.AbstractThreadedSyncAdapter.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.BroadcastReceiver.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.ContentProvider.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.ContentProviderClient.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.ContentResolver.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.ContentValues.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.Context.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.ContextWrapper.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.Intent.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.Editor.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.SyncAdapterType.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.SyncInfo.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.pm.ActivityInfo.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.pm.ApplicationInfo.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.pm.ComponentInfo.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.pm.PackageManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.pm.PackageStats.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.content.res.Configuration.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.database.AbstractCursor.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.database.AbstractWindowedCursor.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.database.Cursor.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.database.CursorWindow.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.database.CursorWrapper.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.database.DatabaseUtils.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteCursor.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteDatabase.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteOpenHelper.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteProgram.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteQueryBuilder.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteStatement.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.graphics.BitmapFactory.Options.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.graphics.Canvas.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.graphics.drawable.ColorDrawable.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.graphics.drawable.Drawable.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.DrawableContainerState.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.graphics.drawable.LayerDrawable.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.hardware.Camera.Parameters.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.hardware.Camera.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.hardware.SensorManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.InputMethodImpl.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.Insets.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.inputmethodservice.Keyboard.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.media.AudioManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.media.CamcorderProfile.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.media.ExifInterface.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.AudioSource.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.net.Proxy.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.net.Uri.Builder.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.net.Uri.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.opengl.GLSurfaceView.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.os.AsyncTask.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.os.BatteryManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.os.Build.VERSION_CODES.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.os.Bundle.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.os.Debug.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.os.DropBoxManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.os.Environment.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.os.StrictMode.ThreadPolicy.Builder.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.os.StrictMode.VmPolicy.Builder.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.os.StrictMode.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.os.Vibrator.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.preference.Preference.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.preference.PreferenceActivity.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.AlarmClock.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.Browser.SearchColumns.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Email.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Relation.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactStatusColumns.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.AggregationSuggestions.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.Photo.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactsColumns.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumns.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumnsWithJoins.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.GroupsColumns.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Intents.Insert.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContacts.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContactsColumns.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.StatusColumns.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.MediaStore.Audio.Genres.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.Settings.Secure.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.Settings.System.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.provider.Settings.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.speech.RecognizerIntent.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.speech.tts.TextToSpeech.Engine.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.telephony.TelephonyManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.test.mock.MockContext.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.test.mock.MockCursor.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.test.mock.MockPackageManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.text.ClipboardManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.text.InputType.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.text.SpannableStringBuilder.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.text.format.Time.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.text.method.ArrowKeyMovementMethod.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.text.method.BaseKeyListener.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.text.method.QwertyKeyListener.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.text.method.ScrollingMovementMethod.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.util.AndroidException.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.util.AndroidRuntimeException.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.util.Patterns.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.util.SparseArray.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.util.StateSet.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.KeyData.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.KeyEvent.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.LayoutInflater.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.MenuItem.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.MotionEvent.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.ScaleGestureDetector.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.Surface.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.SurfaceHolder.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.View.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.ViewGroup.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.ViewParent.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.Window.Callback.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.Window.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.WindowManager.LayoutParams.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.animation.Animation.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.animation.Interpolator.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.inputmethod.BaseInputConnection.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.inputmethod.EditorInfo.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnection.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnectionWrapper.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethod.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodInfo.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.CacheResult.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.webkit.WebSettings.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.webkit.WebView.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.webkit.WebViewClient.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.AbsListView.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.ArrayAdapter.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.CursorAdapter.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.DatePicker.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.GridView.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.ImageView.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.LinearLayout.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.ListView.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.OverScroller.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.PopupWindow.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.QuickContactBadge.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.RemoteViews.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.ResourceCursorAdapter.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.Scroller.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.SimpleCursorAdapter.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.Spinner.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.TabWidget.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/android.widget.TextView.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/changes-summary.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/dalvik.bytecode.Opcodes.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/fields_index_additions.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/fields_index_all.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/java.lang.Character.UnicodeBlock.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/java.lang.Object.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/java.util.Deque.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/java.util.Locale.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/java.util.NavigableMap.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/java.util.NavigableSet.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/java.util.Queue.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.Control.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/jdiff_statistics.html42
-rw-r--r--docs/html/sdk/api_diff/11/changes/methods_index_additions.html4
-rw-r--r--docs/html/sdk/api_diff/11/changes/methods_index_all.html4
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.accounts.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.app.admin.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.app.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.appwidget.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.bluetooth.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.content.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.content.pm.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.content.res.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.database.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.database.sqlite.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.graphics.drawable.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.graphics.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.hardware.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.inputmethodservice.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.media.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.net.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.opengl.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.os.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.preference.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.provider.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.speech.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.speech.tts.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.telephony.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.test.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.test.mock.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.text.format.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.text.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.text.method.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.util.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.view.animation.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.view.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.view.inputmethod.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.webkit.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_android.widget.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_dalvik.bytecode.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_java.lang.html2
-rw-r--r--docs/html/sdk/api_diff/11/changes/pkg_java.util.html2
-rw-r--r--docs/html/sdk/eclipse-adt.jd8
-rw-r--r--docs/html/sdk/index.jd24
-rw-r--r--docs/html/sdk/ndk/index.jd18
-rw-r--r--docs/html/sdk/preview/start.jd294
-rw-r--r--docs/html/sdk/sdk_toc.cs17
-rw-r--r--include/media/stagefright/AudioSource.h6
-rw-r--r--include/media/stagefright/foundation/ABitReader.h3
-rw-r--r--include/ui/Input.h85
-rw-r--r--include/ui/KeyLayoutMap.h12
-rw-r--r--include/ui/Keyboard.h12
-rwxr-xr-xinclude/ui/KeycodeLabels.h43
-rw-r--r--libs/hwui/FontRenderer.cpp16
-rw-r--r--libs/hwui/FontRenderer.h8
-rw-r--r--libs/hwui/OpenGLRenderer.cpp6
-rw-r--r--libs/rs/java/Balls/_index.html1
-rw-r--r--libs/rs/java/Fountain/_index.html5
-rw-r--r--libs/rs/java/HelloCompute/_index.html2
-rw-r--r--libs/rs/java/HelloWorld/_index.html1
-rw-r--r--libs/rs/java/ImageProcessing/res/layout/main.xml187
-rw-r--r--libs/rs/java/Samples/AndroidManifest.xml9
-rw-r--r--libs/rs/java/Samples/_index.html1
-rw-r--r--libs/rs/java/_index.html1
-rw-r--r--libs/ui/Input.cpp86
-rw-r--r--libs/ui/InputTransport.cpp3
-rw-r--r--libs/ui/KeyLayoutMap.cpp70
-rw-r--r--libs/ui/Keyboard.cpp24
-rw-r--r--libs/ui/tests/Android.mk7
-rw-r--r--libs/ui/tests/InputChannel_test.cpp18
-rw-r--r--libs/ui/tests/InputEvent_test.cpp582
-rw-r--r--libs/ui/tests/InputPublisherAndConsumer_test.cpp80
-rw-r--r--media/java/android/media/videoeditor/MediaArtistNativeHelper.java5
-rwxr-xr-xmedia/java/android/media/videoeditor/Transition.java1
-rw-r--r--media/java/android/mtp/MtpServer.java7
-rw-r--r--media/jni/android_mtp_MtpServer.cpp47
-rwxr-xr-xmedia/jni/mediaeditor/VideoEditorMain.cpp14
-rw-r--r--media/libmedia/mediarecorder.cpp11
-rw-r--r--media/libstagefright/Android.mk6
-rw-r--r--media/libstagefright/AudioSource.cpp15
-rw-r--r--media/libstagefright/AwesomePlayer.cpp3
-rw-r--r--media/libstagefright/CameraSource.cpp8
-rw-r--r--media/libstagefright/DataSource.cpp3
-rw-r--r--media/libstagefright/HTTPStream.cpp99
-rw-r--r--media/libstagefright/MPEG4Writer.cpp60
-rw-r--r--media/libstagefright/NuHTTPDataSource.cpp34
-rw-r--r--media/libstagefright/foundation/ABitReader.cpp4
-rw-r--r--media/libstagefright/httplive/LiveSession.cpp3
-rw-r--r--media/libstagefright/include/HTTPStream.h5
-rw-r--r--media/libstagefright/include/NuHTTPDataSource.h2
-rw-r--r--media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp83
-rw-r--r--media/libstagefright/rtsp/AMPEG4AudioAssembler.h1
-rw-r--r--media/mtp/MtpServer.cpp91
-rw-r--r--media/mtp/MtpServer.h18
-rw-r--r--media/mtp/MtpStorage.cpp4
-rw-r--r--media/mtp/MtpStorage.h5
-rw-r--r--media/mtp/mtp.h2
-rwxr-xr-xmedia/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java7
-rwxr-xr-xmedia/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java4
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java1
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/VideoEditorPreviewTest.java80
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java1086
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java16
-rwxr-xr-xmedia/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java1317
-rw-r--r--native/include/android/input.h88
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java29
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_notification_dnd.pngbin0 -> 1075 bytes
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml15
-rw-r--r--packages/SystemUI/res/values-xlarge/strings.xml7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java81
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java153
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java96
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java2
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java42
-rw-r--r--services/input/EventHub.cpp196
-rw-r--r--services/input/EventHub.h17
-rw-r--r--services/input/InputDispatcher.cpp209
-rw-r--r--services/input/InputDispatcher.h24
-rw-r--r--services/input/InputReader.cpp416
-rw-r--r--services/input/InputReader.h164
-rw-r--r--services/input/tests/InputReader_test.cpp49
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java2
-rw-r--r--services/java/com/android/server/NetworkManagementService.java22
-rw-r--r--services/java/com/android/server/PowerManagerService.java7
-rw-r--r--services/java/com/android/server/StatusBarManagerService.java1
-rw-r--r--services/java/com/android/server/SystemBackupAgent.java1
-rw-r--r--services/java/com/android/server/SystemServer.java1
-rw-r--r--services/java/com/android/server/UsbService.java169
-rw-r--r--services/java/com/android/server/WallpaperManagerService.java2
-rw-r--r--services/java/com/android/server/WifiService.java222
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java42
-rw-r--r--services/java/com/android/server/wm/AppWindowToken.java413
-rw-r--r--services/java/com/android/server/wm/DimAnimator.java187
-rw-r--r--services/java/com/android/server/wm/DragState.java368
-rw-r--r--services/java/com/android/server/wm/FadeInOutAnimation.java44
-rw-r--r--services/java/com/android/server/wm/InputApplication.java (renamed from services/java/com/android/server/InputApplication.java)3
-rw-r--r--services/java/com/android/server/wm/InputApplicationHandle.java (renamed from services/java/com/android/server/InputApplicationHandle.java)7
-rw-r--r--services/java/com/android/server/wm/InputManager.java (renamed from services/java/com/android/server/InputManager.java)2
-rw-r--r--services/java/com/android/server/wm/InputMonitor.java377
-rw-r--r--services/java/com/android/server/wm/InputWindow.java (renamed from services/java/com/android/server/InputWindow.java)2
-rw-r--r--services/java/com/android/server/wm/InputWindowHandle.java (renamed from services/java/com/android/server/InputWindowHandle.java)2
-rw-r--r--services/java/com/android/server/wm/InputWindowList.java (renamed from services/java/com/android/server/InputWindowList.java)2
-rw-r--r--services/java/com/android/server/wm/ScreenRotationAnimation.java (renamed from services/java/com/android/server/ScreenRotationAnimation.java)2
-rw-r--r--services/java/com/android/server/wm/Session.java419
-rw-r--r--services/java/com/android/server/wm/StartingData.java36
-rw-r--r--services/java/com/android/server/wm/StrictModeFlash.java (renamed from services/java/com/android/server/StrictModeFlash.java)4
-rw-r--r--services/java/com/android/server/wm/ViewServer.java (renamed from services/java/com/android/server/ViewServer.java)5
-rw-r--r--services/java/com/android/server/wm/Watermark.java177
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java (renamed from services/java/com/android/server/WindowManagerService.java)3498
-rw-r--r--services/java/com/android/server/wm/WindowState.java1623
-rw-r--r--services/java/com/android/server/wm/WindowToken.java110
-rw-r--r--services/jni/com_android_server_InputApplication.cpp4
-rw-r--r--services/jni/com_android_server_InputApplicationHandle.cpp4
-rw-r--r--services/jni/com_android_server_InputManager.cpp24
-rw-r--r--services/jni/com_android_server_InputWindow.cpp4
-rw-r--r--services/jni/com_android_server_InputWindowHandle.cpp6
-rw-r--r--telephony/java/android/telephony/SignalStrength.java425
-rw-r--r--telephony/java/com/android/internal/telephony/BaseCommands.java56
-rw-r--r--telephony/java/com/android/internal/telephony/CommandsInterface.java119
-rw-r--r--telephony/java/com/android/internal/telephony/DataCallState.java7
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnection.java43
-rw-r--r--telephony/java/com/android/internal/telephony/IccCardStatus.java18
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneBase.java2
-rw-r--r--telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java28
-rw-r--r--telephony/java/com/android/internal/telephony/RIL.java187
-rw-r--r--telephony/java/com/android/internal/telephony/RILConstants.java12
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java6
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java4
-rwxr-xr-xtelephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java15
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java4
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java45
-rw-r--r--telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java31
-rw-r--r--telephony/java/com/android/internal/telephony/test/SimulatedCommands.java37
-rw-r--r--tests/RenderScriptTests/Android.mk1
-rw-r--r--tests/RenderScriptTests/ImageProcessing/Android.mk (renamed from libs/rs/java/ImageProcessing/Android.mk)0
-rw-r--r--tests/RenderScriptTests/ImageProcessing/AndroidManifest.xml (renamed from libs/rs/java/ImageProcessing/AndroidManifest.xml)3
-rw-r--r--tests/RenderScriptTests/ImageProcessing/res/drawable-hdpi/data.jpg (renamed from libs/rs/java/ImageProcessing/res/drawable-hdpi/data.jpg)bin76367 -> 76367 bytes
-rw-r--r--tests/RenderScriptTests/ImageProcessing/res/drawable/data.jpg (renamed from libs/rs/java/ImageProcessing/res/drawable/data.jpg)bin76367 -> 76367 bytes
-rw-r--r--tests/RenderScriptTests/ImageProcessing/res/layout/main.xml153
-rw-r--r--tests/RenderScriptTests/ImageProcessing/res/values/strings.xml (renamed from libs/rs/java/ImageProcessing/res/values/strings.xml)0
-rw-r--r--tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java (renamed from libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java)4
-rw-r--r--tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs (renamed from libs/rs/java/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs)0
-rw-r--r--tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ip.rsh (renamed from libs/rs/java/ImageProcessing/src/com/android/rs/image/ip.rsh)0
-rw-r--r--tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/threshold.rs (renamed from libs/rs/java/ImageProcessing/src/com/android/rs/image/threshold.rs)0
-rw-r--r--tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vertical_blur.rs (renamed from libs/rs/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/Android.mk (renamed from libs/rs/java/ModelViewer/Android.mk)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/AndroidManifest.xml (renamed from libs/rs/java/ModelViewer/AndroidManifest.xml)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/res/drawable/robot.png (renamed from libs/rs/java/ModelViewer/res/drawable/robot.png)bin292580 -> 292580 bytes
-rw-r--r--tests/RenderScriptTests/ModelViewer/res/menu/loader_menu.xml (renamed from libs/rs/java/ModelViewer/res/menu/loader_menu.xml)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/res/raw/robot.a3d (renamed from libs/rs/java/ModelViewer/res/raw/robot.a3d)bin144528 -> 144528 bytes
-rw-r--r--tests/RenderScriptTests/ModelViewer/res/values/strings.xml (renamed from libs/rs/java/ModelViewer/res/values/strings.xml)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/A3DSelector.java (renamed from libs/rs/java/ModelViewer/src/com/android/modelviewer/A3DSelector.java)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SceneGraph.java (renamed from libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraph.java)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java (renamed from libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SceneGraphView.java (renamed from libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphView.java)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SgTransform.java (renamed from libs/rs/java/ModelViewer/src/com/android/modelviewer/SgTransform.java)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SimpleModel.java (renamed from libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModel.java)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java (renamed from libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SimpleModelView.java (renamed from libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelView.java)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/scenegraph.rs (renamed from libs/rs/java/ModelViewer/src/com/android/modelviewer/scenegraph.rs)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs (renamed from libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs)2
-rw-r--r--tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/transform.rs (renamed from libs/rs/java/ModelViewer/src/com/android/modelviewer/transform.rs)0
-rw-r--r--tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/transform_def.rsh (renamed from libs/rs/java/ModelViewer/src/com/android/modelviewer/transform_def.rsh)0
-rw-r--r--tests/RenderScriptTests/PerfTest/Android.mk31
-rw-r--r--tests/RenderScriptTests/PerfTest/AndroidManifest.xml16
-rw-r--r--tests/RenderScriptTests/PerfTest/res/drawable/checker.pngbin0 -> 3732 bytes
-rw-r--r--tests/RenderScriptTests/PerfTest/res/drawable/data.pngbin0 -> 97800 bytes
-rw-r--r--tests/RenderScriptTests/PerfTest/res/drawable/leaf.pngbin0 -> 18837 bytes
-rw-r--r--tests/RenderScriptTests/PerfTest/res/drawable/test_pattern.png (renamed from libs/rs/java/tests/res/drawable/test_pattern.png)bin307 -> 307 bytes
-rw-r--r--tests/RenderScriptTests/PerfTest/res/drawable/torusmap.pngbin0 -> 47127 bytes
-rw-r--r--tests/RenderScriptTests/PerfTest/res/raw/multitexf.glsl13
-rw-r--r--tests/RenderScriptTests/PerfTest/res/raw/shader2f.glsl29
-rw-r--r--tests/RenderScriptTests/PerfTest/res/raw/shader2movev.glsl21
-rw-r--r--tests/RenderScriptTests/PerfTest/res/raw/shader2v.glsl17
-rw-r--r--tests/RenderScriptTests/PerfTest/res/raw/shaderf.glsl16
-rw-r--r--tests/RenderScriptTests/PerfTest/res/raw/shaderv.glsl30
-rw-r--r--tests/RenderScriptTests/PerfTest/res/raw/torus.a3dbin0 -> 571248 bytes
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java (renamed from libs/rs/java/Samples/src/com/android/samples/RsBench.java)2
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java (renamed from libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java)24
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java (renamed from libs/rs/java/Samples/src/com/android/samples/RsBenchView.java)2
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs (renamed from libs/rs/java/Samples/src/com/android/samples/rsbench.rs)5
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/shader_def.rsh83
-rw-r--r--tests/RenderScriptTests/tests/Android.mk (renamed from libs/rs/java/tests/Android.mk)0
-rw-r--r--tests/RenderScriptTests/tests/AndroidManifest.xml (renamed from libs/rs/java/tests/AndroidManifest.xml)0
-rw-r--r--tests/RenderScriptTests/tests/res/drawable/test_pattern.pngbin0 -> 307 bytes
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/RSTest.java (renamed from libs/rs/java/tests/src/com/android/rs/test/RSTest.java)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java (renamed from libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestView.java (renamed from libs/rs/java/tests/src/com/android/rs/test/RSTestView.java)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_fp_mad.java (renamed from libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math.java (renamed from libs/rs/java/tests/src/com/android/rs/test/UT_math.java)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_primitives.java (renamed from libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_rsdebug.java (renamed from libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_rstime.java (renamed from libs/rs/java/tests/src/com/android/rs/test/UT_rstime.java)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_rstypes.java (renamed from libs/rs/java/tests/src/com/android/rs/test/UT_rstypes.java)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java (renamed from libs/rs/java/tests/src/com/android/rs/test/UnitTest.java)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/fp_mad.rs (renamed from libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/math.rs (renamed from libs/rs/java/tests/src/com/android/rs/test/math.rs)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/primitives.rs (renamed from libs/rs/java/tests/src/com/android/rs/test/primitives.rs)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/rsdebug.rs (renamed from libs/rs/java/tests/src/com/android/rs/test/rsdebug.rs)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/rslist.rs (renamed from libs/rs/java/tests/src/com/android/rs/test/rslist.rs)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/rstime.rs (renamed from libs/rs/java/tests/src/com/android/rs/test/rstime.rs)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/rstypes.rs (renamed from libs/rs/java/tests/src/com/android/rs/test/rstypes.rs)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh (renamed from libs/rs/java/tests/src/com/android/rs/test/shared.rsh)0
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/test_root.rs (renamed from libs/rs/java/tests/src/com/android/rs/test/test_root.rs)0
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java1
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java84
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java32
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java90
-rw-r--r--tools/validatekeymaps/Main.cpp21
-rw-r--r--voip/java/android/net/sip/SipProfile.java9
-rw-r--r--voip/java/com/android/server/sip/SipHelper.java7
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl19
-rw-r--r--wifi/java/android/net/wifi/WifiConfiguration.java23
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java72
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java4
-rw-r--r--wifi/java/android/net/wifi/WifiStateTracker.java42
544 files changed, 14645 insertions, 8079 deletions
diff --git a/Android.mk b/Android.mk
index 140763153ac3..08ee65effab1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -416,6 +416,8 @@ web_docs_sample_code_flags := \
resources/samples/NotePad "Note Pad" \
-samplecode $(sample_dir)/SampleSyncAdapter \
resources/samples/SampleSyncAdapter "Sample Sync Adapter" \
+ -samplecode frameworks/base/libs/rs/java \
+ resources/samples/Renderscript "Renderscript" \
-samplecode $(sample_dir)/SearchableDictionary \
resources/samples/SearchableDictionary "Searchable Dictionary v2" \
-samplecode $(sample_dir)/SipDemo \
diff --git a/api/current.xml b/api/current.xml
index 9a38459d50df..c4fc0e470c56 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -9937,6 +9937,17 @@
visibility="public"
>
</field>
+<field name="textCursorDrawable"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843618"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="textEditNoPasteWindowLayout"
type="int"
transient="false"
@@ -25064,6 +25075,17 @@
<parameter name="packageName" type="java.lang.String">
</parameter>
</method>
+<field name="MOVE_TASK_NO_USER_ACTION"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="MOVE_TASK_WITH_HOME"
type="int"
transient="false"
@@ -25495,6 +25517,16 @@
visibility="public"
>
</field>
+<field name="persistentId"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="ActivityManager.RunningAppProcessInfo"
extends="java.lang.Object"
@@ -30692,6 +30724,19 @@
<parameter name="visibleCrumbs" type="int">
</parameter>
</method>
+<method name="setOnBreadCrumbClickListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.app.FragmentBreadCrumbs.OnBreadCrumbClickListener">
+</parameter>
+</method>
<method name="setParentTitle"
return="void"
abstract="false"
@@ -30725,6 +30770,29 @@
</parameter>
</method>
</class>
+<interface name="FragmentBreadCrumbs.OnBreadCrumbClickListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onBreadCrumbClick"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="backStack" type="android.app.FragmentManager.BackStackEntry">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+</interface>
<class name="FragmentManager"
extends="java.lang.Object"
abstract="true"
@@ -118943,6 +119011,17 @@
visibility="public"
>
</method>
+<method name="getAuthUserName"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getAutoRegistration"
return="boolean"
abstract="false"
@@ -119145,6 +119224,19 @@
visibility="public"
>
</method>
+<method name="setAuthUserName"
+ return="android.net.sip.SipProfile.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+</method>
<method name="setAutoRegistration"
return="android.net.sip.SipProfile.Builder"
abstract="false"
@@ -210575,6 +210667,17 @@
visibility="public"
>
</method>
+<method name="getMotionAxes"
+ return="int[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getMotionRange"
return="android.view.InputDevice.MotionRange"
abstract="false"
@@ -212145,6 +212248,19 @@
visibility="public"
>
</method>
+<method name="isGamepadButton"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="keyCode" type="int">
+</parameter>
+</method>
<method name="isLongPress"
return="boolean"
abstract="false"
@@ -212257,6 +212373,32 @@
visibility="public"
>
</method>
+<method name="keyCodeFromString"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="symbolicName" type="java.lang.String">
+</parameter>
+</method>
+<method name="keyCodeToString"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="keyCode" type="int">
+</parameter>
+</method>
<method name="metaStateHasModifiers"
return="boolean"
abstract="false"
@@ -216521,6 +216663,32 @@
<parameter name="metaState" type="int">
</parameter>
</method>
+<method name="axisFromString"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="symbolicName" type="java.lang.String">
+</parameter>
+</method>
+<method name="axisToString"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="axis" type="int">
+</parameter>
+</method>
<method name="findPointerIndex"
return="int"
abstract="false"
@@ -217584,6 +217752,17 @@
visibility="public"
>
</field>
+<field name="ACTION_HOVER_MOVE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="7"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="ACTION_MASK"
type="int"
transient="false"
@@ -217760,6 +217939,226 @@
visibility="public"
>
</field>
+<field name="AXIS_GENERIC_1"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="32"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_10"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="41"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_11"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="42"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_12"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="43"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_13"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="44"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_14"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="45"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_15"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="46"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_16"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="47"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_2"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="33"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_3"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="34"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_4"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="35"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_5"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="36"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_6"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="37"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_7"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="38"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_8"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="39"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_GENERIC_9"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="40"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_HAT_X"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="15"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_HAT_Y"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_HSCROLL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="10"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_LTRIGGER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="17"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="AXIS_ORIENTATION"
type="int"
transient="false"
@@ -217782,6 +218181,50 @@
visibility="public"
>
</field>
+<field name="AXIS_RTRIGGER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="18"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_RX"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="12"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_RY"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="13"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AXIS_RZ"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="14"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="AXIS_SIZE"
type="int"
transient="false"
@@ -217837,6 +218280,17 @@
visibility="public"
>
</field>
+<field name="AXIS_VSCROLL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="9"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="AXIS_X"
type="int"
transient="false"
@@ -217859,6 +218313,17 @@
visibility="public"
>
</field>
+<field name="AXIS_Z"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="11"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="CREATOR"
type="android.os.Parcelable.Creator"
transient="false"
@@ -219989,6 +220454,19 @@
<parameter name="focusableMode" type="int">
</parameter>
</method>
+<method name="addOnAttachStateChangeListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.view.View.OnAttachStateChangeListener">
+</parameter>
+</method>
<method name="addOnLayoutChangeListener"
return="void"
abstract="false"
@@ -222992,6 +223470,19 @@
<parameter name="action" type="java.lang.Runnable">
</parameter>
</method>
+<method name="removeOnAttachStateChangeListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.view.View.OnAttachStateChangeListener">
+</parameter>
+</method>
<method name="removeOnLayoutChangeListener"
return="void"
abstract="false"
@@ -225313,6 +225804,40 @@
>
</field>
</class>
+<interface name="View.OnAttachStateChangeListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onViewAttachedToWindow"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="v" type="android.view.View">
+</parameter>
+</method>
+<method name="onViewDetachedFromWindow"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="v" type="android.view.View">
+</parameter>
+</method>
+</interface>
<interface name="View.OnClickListener"
abstract="true"
static="true"
@@ -266112,7 +266637,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="arg0" type="T">
+<parameter name="t" type="T">
</parameter>
</method>
</interface>
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index d76b67d3ef2a..a660076b4b03 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -112,6 +112,11 @@ public class ActivityManager {
public int id;
/**
+ * The true identifier of this task, valid even if it is not running.
+ */
+ public int persistentId;
+
+ /**
* The original Intent used to launch the task. You can use this
* Intent to re-launch the task (if it is no longer running) or bring
* the current task to the front.
@@ -127,14 +132,6 @@ public class ActivityManager {
public ComponentName origActivity;
/**
- * Thumbnail representation of the task's last state. Must
- * use {@link ActivityManager#TASKS_GET_THUMBNAILS} to have this set.
- * @hide -- this is not scalable, need to have a separate API to get
- * the bitmap.
- */
- public Bitmap thumbnail;
-
- /**
* Description of the task's last state.
*/
public CharSequence description;
@@ -148,6 +145,7 @@ public class ActivityManager {
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
+ dest.writeInt(persistentId);
if (baseIntent != null) {
dest.writeInt(1);
baseIntent.writeToParcel(dest, 0);
@@ -155,29 +153,19 @@ public class ActivityManager {
dest.writeInt(0);
}
ComponentName.writeToParcel(origActivity, dest);
- if (thumbnail != null) {
- dest.writeInt(1);
- thumbnail.writeToParcel(dest, 0);
- } else {
- dest.writeInt(0);
- }
TextUtils.writeToParcel(description, dest,
Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
public void readFromParcel(Parcel source) {
id = source.readInt();
+ persistentId = source.readInt();
if (source.readInt() != 0) {
baseIntent = Intent.CREATOR.createFromParcel(source);
} else {
baseIntent = null;
}
origActivity = ComponentName.readFromParcel(source);
- if (source.readInt() != 0) {
- thumbnail = Bitmap.CREATOR.createFromParcel(source);
- } else {
- thumbnail = null;
- }
description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
}
@@ -401,6 +389,16 @@ public class ActivityManager {
return getRunningTasks(maxNum, 0, null);
}
+ /** @hide */
+ public Bitmap getTaskThumbnail(int id) throws SecurityException {
+ try {
+ return ActivityManagerNative.getDefault().getTaskThumbnail(id);
+ } catch (RemoteException e) {
+ // System dead, we will be dead too soon!
+ return null;
+ }
+ }
+
/**
* Flag for {@link #moveTaskToFront(int, int)}: also move the "home"
* activity along with the task, so it is positioned immediately behind
@@ -409,6 +407,13 @@ public class ActivityManager {
public static final int MOVE_TASK_WITH_HOME = 0x00000001;
/**
+ * Flag for {@link #moveTaskToFront(int, int)}: don't count this as a
+ * user-instigated action, so the current activity will not receive a
+ * hint that the user is leaving.
+ */
+ public static final int MOVE_TASK_NO_USER_ACTION = 0x00000002;
+
+ /**
* Ask that the task associated with a given task ID be moved to the
* front of the stack, so it is now visible to the user. Requires that
* the caller hold permission {@link android.Manifest.permission#REORDER_TASKS}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index c095c069918b..d3d379294789 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -442,6 +442,20 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
+ case GET_TASK_THUMBNAIL_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int id = data.readInt();
+ Bitmap bm = getTaskThumbnail(id);
+ reply.writeNoException();
+ if (bm != null) {
+ reply.writeInt(1);
+ bm.writeToParcel(reply, 0);
+ } else {
+ reply.writeInt(0);
+ }
+ return true;
+ }
+
case GET_SERVICES_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
int maxNum = data.readInt();
@@ -1816,6 +1830,21 @@ class ActivityManagerProxy implements IActivityManager
reply.recycle();
return list;
}
+ public Bitmap getTaskThumbnail(int id) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(id);
+ mRemote.transact(GET_TASK_THUMBNAIL_TRANSACTION, data, reply, 0);
+ reply.readException();
+ Bitmap bm = null;
+ if (reply.readInt() != 0) {
+ bm = Bitmap.CREATOR.createFromParcel(reply);
+ }
+ data.recycle();
+ reply.recycle();
+ return bm;
+ }
public List getServices(int maxNum, int flags) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/FragmentBreadCrumbs.java b/core/java/android/app/FragmentBreadCrumbs.java
index 3f045ac288f9..df64035b4be9 100644
--- a/core/java/android/app/FragmentBreadCrumbs.java
+++ b/core/java/android/app/FragmentBreadCrumbs.java
@@ -50,6 +50,26 @@ public class FragmentBreadCrumbs extends ViewGroup
/** Listener to inform when a parent entry is clicked */
private OnClickListener mParentClickListener;
+ private OnBreadCrumbClickListener mOnBreadCrumbClickListener;
+
+ /**
+ * Interface to intercept clicks on the bread crumbs.
+ */
+ public interface OnBreadCrumbClickListener {
+ /**
+ * Called when a bread crumb is clicked.
+ *
+ * @param backStack The BackStackEntry whose bread crumb was clicked.
+ * May be null, if this bread crumb is for the root of the back stack.
+ * @param flags Additional information about the entry. Currently
+ * always 0.
+ *
+ * @return Return true to consume this click. Return to false to allow
+ * the default action (popping back stack to this entry) to occur.
+ */
+ public boolean onBreadCrumbClick(BackStackEntry backStack, int flags);
+ }
+
public FragmentBreadCrumbs(Context context) {
this(context, null);
}
@@ -107,6 +127,16 @@ public class FragmentBreadCrumbs extends ViewGroup
updateCrumbs();
}
+ /**
+ * Sets a listener for clicks on the bread crumbs. This will be called before
+ * the default click action is performed.
+ *
+ * @param listener The new listener to set. Replaces any existing listener.
+ */
+ public void setOnBreadCrumbClickListener(OnBreadCrumbClickListener listener) {
+ mOnBreadCrumbClickListener = listener;
+ }
+
private BackStackRecord createBackStackEntry(CharSequence title, CharSequence shortTitle) {
if (title == null) return null;
@@ -266,8 +296,18 @@ public class FragmentBreadCrumbs extends ViewGroup
mParentClickListener.onClick(v);
}
} else {
- mActivity.getFragmentManager().popBackStack(bse.getId(),
- bse == mTopEntry? FragmentManager.POP_BACK_STACK_INCLUSIVE : 0);
+ if (mOnBreadCrumbClickListener != null) {
+ if (mOnBreadCrumbClickListener.onBreadCrumbClick(
+ bse == mTopEntry ? null : bse, 0)) {
+ return;
+ }
+ }
+ if (bse == mTopEntry) {
+ // Pop everything off the back stack.
+ mActivity.getFragmentManager().popBackStack();
+ } else {
+ mActivity.getFragmentManager().popBackStack(bse.getId(), 0);
+ }
}
}
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 5d4380b3c18c..f42e8fb73e86 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -133,6 +133,7 @@ public interface IActivityManager extends IInterface {
IThumbnailReceiver receiver) throws RemoteException;
public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
int flags) throws RemoteException;
+ public Bitmap getTaskThumbnail(int taskId) throws RemoteException;
public List getServices(int maxNum, int flags) throws RemoteException;
public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState()
throws RemoteException;
@@ -514,7 +515,7 @@ public interface IActivityManager extends IInterface {
int FORCE_STOP_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+78;
int KILL_PIDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+79;
int GET_SERVICES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+80;
-
+ int GET_TASK_THUMBNAIL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+81;
int GET_RUNNING_APP_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+82;
int GET_DEVICE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+83;
int PEEK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+84;
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index e3d8e2047c96..1e8743cae68a 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -117,6 +117,40 @@ public class KeyguardManager {
}
/**
+ * isKeyguardLocked
+ *
+ * Return whether the keyguard is currently locked.
+ *
+ * @return true if in keyguard is locked.
+ *
+ * @hide
+ */
+ public boolean isKeyguardLocked() {
+ try {
+ return mWM.isKeyguardSecure();
+ } catch (RemoteException ex) {
+ return false;
+ }
+ }
+
+ /**
+ * isKeyguardSecure
+ *
+ * Return whether the keyguard requires a password to unlock.
+ *
+ * @return true if in keyguard is secure.
+ *
+ * @hide
+ */
+ public boolean isKeyguardSecure() {
+ try {
+ return mWM.isKeyguardSecure();
+ } catch (RemoteException ex) {
+ return false;
+ }
+ }
+
+ /**
* If keyguard screen is showing or in restricted key input mode (i.e. in
* keyguard password emergency screen). When in such mode, certain keys,
* such as the Home key and the right soft keys, don't work.
diff --git a/core/java/android/app/ListActivity.java b/core/java/android/app/ListActivity.java
index d49968f8bfcc..2162521edce1 100644
--- a/core/java/android/app/ListActivity.java
+++ b/core/java/android/app/ListActivity.java
@@ -43,7 +43,7 @@ import android.widget.ListView;
* <p>
* Optionally, your custom view can contain another view object of any type to
* display when the list view is empty. This "empty list" notifier must have an
- * id "android:empty". Note that when an empty view is present, the list view
+ * id "android:id/empty". Note that when an empty view is present, the list view
* will be hidden when there is no data to display.
* <p>
* The following code demonstrates an (ugly) custom screen layout. It has a list
@@ -59,14 +59,14 @@ import android.widget.ListView;
* android:paddingLeft=&quot;8dp&quot;
* android:paddingRight=&quot;8dp&quot;&gt;
*
- * &lt;ListView android:id=&quot;@id/android:list&quot;
+ * &lt;ListView android:id=&quot;@android:id/list&quot;
* android:layout_width=&quot;match_parent&quot;
* android:layout_height=&quot;match_parent&quot;
* android:background=&quot;#00FF00&quot;
* android:layout_weight=&quot;1&quot;
* android:drawSelectorOnTop=&quot;false&quot;/&gt;
*
- * &lt;TextView android:id=&quot;@id/android:empty&quot;
+ * &lt;TextView android:id=&quot;@android:id/empty&quot;
* android:layout_width=&quot;match_parent&quot;
* android:layout_height=&quot;match_parent&quot;
* android:background=&quot;#FF0000&quot;
diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java
index 98082006caef..d70b3d37ee8b 100644
--- a/core/java/android/app/backup/WallpaperBackupHelper.java
+++ b/core/java/android/app/backup/WallpaperBackupHelper.java
@@ -32,7 +32,7 @@ import java.io.File;
*/
public class WallpaperBackupHelper extends FileBackupHelperBase implements BackupHelper {
private static final String TAG = "WallpaperBackupHelper";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = true;
// This path must match what the WallpaperManagerService uses
private static final String WALLPAPER_IMAGE = "/data/data/com.android.settings/files/wallpaper";
@@ -64,6 +64,10 @@ public class WallpaperBackupHelper extends FileBackupHelperBase implements Backu
wpm = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
mDesiredMinWidth = (double) wpm.getDesiredMinimumWidth();
mDesiredMinHeight = (double) wpm.getDesiredMinimumHeight();
+
+ if (DEBUG) {
+ Slog.d(TAG, "dmW=" + mDesiredMinWidth + " dmH=" + mDesiredMinHeight);
+ }
}
/**
@@ -94,7 +98,7 @@ public class WallpaperBackupHelper extends FileBackupHelperBase implements Backu
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(STAGE_FILE, options);
- if (DEBUG) Slog.v(TAG, "Restoring wallpaper image w=" + options.outWidth
+ if (DEBUG) Slog.d(TAG, "Restoring wallpaper image w=" + options.outWidth
+ " h=" + options.outHeight);
// how much does the image differ from our preference?
@@ -103,13 +107,13 @@ public class WallpaperBackupHelper extends FileBackupHelperBase implements Backu
if (widthRatio > 0.8 && widthRatio < 1.25
&& heightRatio > 0.8 && heightRatio < 1.25) {
// sufficiently close to our resolution; go ahead and use it
- if (DEBUG) Slog.v(TAG, "wallpaper dimension match; using");
+ if (DEBUG) Slog.d(TAG, "wallpaper dimension match; using");
f.renameTo(new File(WALLPAPER_IMAGE));
// TODO: spin a service to copy the restored image to sd/usb storage,
// since it does not exist anywhere other than the private wallpaper
// file.
} else {
- if (DEBUG) Slog.v(TAG, "dimensions too far off: wr=" + widthRatio
+ if (DEBUG) Slog.d(TAG, "dimensions too far off: wr=" + widthRatio
+ " hr=" + heightRatio);
f.delete();
}
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 4656e153915d..1f4fe801e638 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1049,6 +1049,9 @@ public final class BluetoothAdapter {
} else if (profile == BluetoothProfile.A2DP) {
BluetoothA2dp a2dp = new BluetoothA2dp(context, listener);
return true;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ BluetoothInputDevice iDev = new BluetoothInputDevice(context, listener);
+ return true;
} else {
return false;
}
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index 6ec347f65b79..116a0687d5f4 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -136,17 +136,17 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
newState == BluetoothProfile.STATE_DISCONNECTED) {
sendMessage(TRANSITION_TO_STABLE);
}
- } else if (action.equals(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED)) {
- int newState = intent.getIntExtra(BluetoothInputDevice.EXTRA_INPUT_DEVICE_STATE, 0);
+ } else if (action.equals(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED)) {
+ int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
int oldState =
- intent.getIntExtra(BluetoothInputDevice.EXTRA_PREVIOUS_INPUT_DEVICE_STATE, 0);
+ intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0);
- if (oldState == BluetoothInputDevice.STATE_CONNECTED &&
- newState == BluetoothInputDevice.STATE_DISCONNECTED) {
+ if (oldState == BluetoothProfile.STATE_CONNECTED &&
+ newState == BluetoothProfile.STATE_DISCONNECTED) {
sendMessage(DISCONNECT_HID_INCOMING);
}
- if (newState == BluetoothInputDevice.STATE_CONNECTED ||
- newState == BluetoothInputDevice.STATE_DISCONNECTED) {
+ if (newState == BluetoothProfile.STATE_CONNECTED ||
+ newState == BluetoothProfile.STATE_DISCONNECTED) {
sendMessage(TRANSITION_TO_STABLE);
}
} else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
@@ -194,7 +194,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
- filter.addAction(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED);
+ filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
mContext.registerReceiver(mBroadcastReceiver, filter);
@@ -286,7 +286,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
sendMessage(DISCONNECT_A2DP_OUTGOING);
deferMessage(message);
break;
- } else if (mService.getInputDeviceState(mDevice) !=
+ } else if (mService.getInputDeviceConnectionState(mDevice) !=
BluetoothInputDevice.STATE_DISCONNECTED) {
sendMessage(DISCONNECT_HID_OUTGOING);
deferMessage(message);
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index a70de59a48f6..df212a82d4e6 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * 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.
@@ -27,91 +27,88 @@ import android.util.Log;
import java.util.ArrayList;
import java.util.List;
+
/**
- * Public API for controlling the Bluetooth HID (Input Device) Profile
- *
- * BluetoothInputDevice is a proxy object used to make calls to Bluetooth Service
- * which handles the HID profile.
+ * This class provides the public APIs to control the Bluetooth Input
+ * Device Profile.
*
- * Creating a BluetoothInputDevice object will initiate a binding with the
- * Bluetooth service. Users of this object should call close() when they
- * are finished, so that this proxy object can unbind from the service.
+ *<p>BluetoothInputDevice is a proxy object for controlling the Bluetooth
+ * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
+ * the BluetoothInputDevice proxy object.
*
- * Currently the Bluetooth service runs in the system server and this
- * proxy object will be immediately bound to the service on construction.
- *
- * @hide
+ *<p>Each method is protected with its appropriate permission.
+ *@hide
*/
-public final class BluetoothInputDevice {
+public final class BluetoothInputDevice implements BluetoothProfile {
private static final String TAG = "BluetoothInputDevice";
private static final boolean DBG = false;
- /** int extra for ACTION_INPUT_DEVICE_STATE_CHANGED */
- public static final String EXTRA_INPUT_DEVICE_STATE =
- "android.bluetooth.inputdevice.extra.INPUT_DEVICE_STATE";
- /** int extra for ACTION_INPUT_DEVICE_STATE_CHANGED */
- public static final String EXTRA_PREVIOUS_INPUT_DEVICE_STATE =
- "android.bluetooth.inputdevice.extra.PREVIOUS_INPUT_DEVICE_STATE";
-
- /** Indicates the state of an input device has changed.
- * This intent will always contain EXTRA_INPUT_DEVICE_STATE,
- * EXTRA_PREVIOUS_INPUT_DEVICE_STATE and BluetoothDevice.EXTRA_DEVICE
- * extras.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_INPUT_DEVICE_STATE_CHANGED =
- "android.bluetooth.inputdevice.action.INPUT_DEVICE_STATE_CHANGED";
-
- public static final int STATE_DISCONNECTED = 0;
- public static final int STATE_CONNECTING = 1;
- public static final int STATE_CONNECTED = 2;
- public static final int STATE_DISCONNECTING = 3;
-
- /**
- * Auto connection, incoming and outgoing connection are allowed at this
- * priority level.
- */
- public static final int PRIORITY_AUTO_CONNECT = 1000;
- /**
- * Incoming and outgoing connection are allowed at this priority level
- */
- public static final int PRIORITY_ON = 100;
- /**
- * Connections to the device are not allowed at this priority level.
- */
- public static final int PRIORITY_OFF = 0;
/**
- * Default priority level when the device is unpaired.
+ * Intent used to broadcast the change in connection state of the Input
+ * Device profile.
+ *
+ * <p>This intent will have 3 extras:
+ * <ul>
+ * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+ * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+ * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+ * </ul>
+ *
+ * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+ * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
+ * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+ * receive.
*/
- public static final int PRIORITY_UNDEFINED = -1;
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_CONNECTION_STATE_CHANGED =
+ "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
/**
* Return codes for the connect and disconnect Bluez / Dbus calls.
+ * @hide
*/
public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000;
+ /**
+ * @hide
+ */
public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001;
+ /**
+ * @hide
+ */
public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002;
+ /**
+ * @hide
+ */
public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003;
+ /**
+ * @hide
+ */
public static final int INPUT_OPERATION_SUCCESS = 5004;
- private final IBluetooth mService;
- private final Context mContext;
+ private ServiceListener mServiceListener;
+ private BluetoothAdapter mAdapter;
+ private IBluetooth mService;
/**
* Create a BluetoothInputDevice proxy object for interacting with the local
- * Bluetooth Service which handle the HID profile.
- * @param c Context
+ * Bluetooth Service which handles the InputDevice profile
+ *
*/
- public BluetoothInputDevice(Context c) {
- mContext = c;
-
+ /*package*/ BluetoothInputDevice(Context mContext, ServiceListener l) {
IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
+ mServiceListener = l;
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
if (b != null) {
mService = IBluetooth.Stub.asInterface(b);
+ if (mServiceListener != null) {
+ mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, this);
+ }
} else {
Log.w(TAG, "Bluetooth Service not available!");
@@ -121,130 +118,151 @@ public final class BluetoothInputDevice {
}
}
- /** Initiate a connection to an Input device.
- *
- * This function returns false on error and true if the connection
- * attempt is being made.
- *
- * Listen for INPUT_DEVICE_STATE_CHANGED_ACTION to find out when the
- * connection is completed.
- * @param device Remote BT device.
- * @return false on immediate error, true otherwise
- * @hide
+ /**
+ * {@inheritDoc}
+ * @hide
*/
- public boolean connectInputDevice(BluetoothDevice device) {
- if (DBG) log("connectInputDevice(" + device + ")");
- try {
- return mService.connectInputDevice(device);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return false;
+ public boolean connect(BluetoothDevice device) {
+ if (DBG) log("connect(" + device + ")");
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
+ try {
+ return mService.connectInputDevice(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
}
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
}
- /** Initiate disconnect from an Input Device.
- * This function return false on error and true if the disconnection
- * attempt is being made.
- *
- * Listen for INPUT_DEVICE_STATE_CHANGED_ACTION to find out when
- * disconnect is completed.
- *
- * @param device Remote BT device.
- * @return false on immediate error, true otherwise
- * @hide
+ /**
+ * {@inheritDoc}
+ * @hide
*/
- public boolean disconnectInputDevice(BluetoothDevice device) {
- if (DBG) log("disconnectInputDevice(" + device + ")");
- try {
- return mService.disconnectInputDevice(device);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return false;
+ public boolean disconnect(BluetoothDevice device) {
+ if (DBG) log("disconnect(" + device + ")");
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
+ try {
+ return mService.disconnectInputDevice(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
}
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
}
- /** Check if a specified InputDevice is connected.
- *
- * @param device Remote BT device.
- * @return True if connected , false otherwise and on error.
- * @hide
+ /**
+ * {@inheritDoc}
*/
- public boolean isInputDeviceConnected(BluetoothDevice device) {
- if (DBG) log("isInputDeviceConnected(" + device + ")");
- int state = getInputDeviceState(device);
- if (state == STATE_CONNECTED) return true;
- return false;
+ public List<BluetoothDevice> getConnectedDevices() {
+ if (DBG) log("getConnectedDevices()");
+ if (mService != null && isEnabled()) {
+ try {
+ return mService.getConnectedInputDevices();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return new ArrayList<BluetoothDevice>();
+ }
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return new ArrayList<BluetoothDevice>();
}
- /** Check if any Input Device is connected.
- *
- * @return List of devices, empty List on error.
- * @hide
+ /**
+ * {@inheritDoc}
*/
- public List<BluetoothDevice> getConnectedInputDevices() {
- if (DBG) log("getConnectedInputDevices()");
- try {
- return mService.getConnectedInputDevices();
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return new ArrayList<BluetoothDevice>();
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+ if (DBG) log("getDevicesMatchingStates()");
+ if (mService != null && isEnabled()) {
+ try {
+ return mService.getInputDevicesMatchingConnectionStates(states);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return new ArrayList<BluetoothDevice>();
+ }
}
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return new ArrayList<BluetoothDevice>();
}
- /** Get the state of an Input Device.
- *
- * @param device Remote BT device.
- * @return The current state of the Input Device
- * @hide
+ /**
+ * {@inheritDoc}
*/
- public int getInputDeviceState(BluetoothDevice device) {
- if (DBG) log("getInputDeviceState(" + device + ")");
- try {
- return mService.getInputDeviceState(device);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return STATE_DISCONNECTED;
+ public int getConnectionState(BluetoothDevice device) {
+ if (DBG) log("getState(" + device + ")");
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ try {
+ return mService.getInputDeviceConnectionState(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return BluetoothProfile.STATE_DISCONNECTED;
+ }
}
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return BluetoothProfile.STATE_DISCONNECTED;
}
/**
- * Set priority of an input device.
- *
- * Priority is a non-negative integer. Priority can take the following
- * values:
- * {@link PRIORITY_ON}, {@link PRIORITY_OFF}, {@link PRIORITY_AUTO_CONNECT}
- *
- * @param device Paired device.
- * @param priority Integer priority
- * @return true if priority is set, false on error
+ * {@inheritDoc}
+ * @hide
*/
- public boolean setInputDevicePriority(BluetoothDevice device, int priority) {
- if (DBG) log("setInputDevicePriority(" + device + ", " + priority + ")");
- try {
- return mService.setInputDevicePriority(device, priority);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return false;
+ public boolean setPriority(BluetoothDevice device, int priority) {
+ if (DBG) log("setPriority(" + device + ", " + priority + ")");
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ if (priority != BluetoothProfile.PRIORITY_OFF &&
+ priority != BluetoothProfile.PRIORITY_ON) {
+ return false;
+ }
+ try {
+ return mService.setInputDevicePriority(device, priority);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
}
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
}
/**
- * Get the priority associated with an Input Device.
- *
- * @param device Input Device
- * @return non-negative priority, or negative error code on error.
+ * {@inheritDoc}
+ * @hide
*/
- public int getInputDevicePriority(BluetoothDevice device) {
- if (DBG) log("getInputDevicePriority(" + device + ")");
- try {
- return mService.getInputDevicePriority(device);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return PRIORITY_OFF;
+ public int getPriority(BluetoothDevice device) {
+ if (DBG) log("getPriority(" + device + ")");
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ try {
+ return mService.getInputDevicePriority(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return BluetoothProfile.PRIORITY_OFF;
+ }
}
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return BluetoothProfile.PRIORITY_OFF;
+ }
+
+ private boolean isEnabled() {
+ if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
+ return false;
+ }
+
+ private boolean isValidDevice(BluetoothDevice device) {
+ if (device == null) return false;
+
+ if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
+ return false;
}
private static void log(String msg) {
- Log.d(TAG, msg);
+ Log.d(TAG, msg);
}
}
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index ef80195d935d..1ffee7205395 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -62,6 +62,11 @@ public interface BluetoothProfile {
* A2DP profile.
*/
public static final int A2DP = 2;
+ /**
+ * Input Device Profile
+ * @hide
+ */
+ public static final int INPUT_DEVICE = 3;
/**
* Default priority for devices that we try to auto-connect to and
diff --git a/core/java/android/bluetooth/BluetoothProfileState.java b/core/java/android/bluetooth/BluetoothProfileState.java
index 3f36926a9ea7..18060a0234d5 100644
--- a/core/java/android/bluetooth/BluetoothProfileState.java
+++ b/core/java/android/bluetooth/BluetoothProfileState.java
@@ -72,10 +72,10 @@ public class BluetoothProfileState extends HierarchicalStateMachine {
newState == BluetoothProfile.STATE_DISCONNECTED)) {
sendMessage(TRANSITION_TO_STABLE);
}
- } else if (action.equals(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED)) {
- int newState = intent.getIntExtra(BluetoothInputDevice.EXTRA_INPUT_DEVICE_STATE, 0);
- if (mProfile == HID && (newState == BluetoothInputDevice.STATE_CONNECTED ||
- newState == BluetoothInputDevice.STATE_DISCONNECTED)) {
+ } else if (action.equals(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED)) {
+ int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
+ if (mProfile == HID && (newState == BluetoothProfile.STATE_CONNECTED ||
+ newState == BluetoothProfile.STATE_DISCONNECTED)) {
sendMessage(TRANSITION_TO_STABLE);
}
} else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
@@ -96,7 +96,7 @@ public class BluetoothProfileState extends HierarchicalStateMachine {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
- filter.addAction(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED);
+ filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
context.registerReceiver(mBroadcastReceiver, filter);
}
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index f3e73cf5db2f..69fb06a0f7b0 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -85,7 +85,8 @@ interface IBluetooth
boolean connectInputDevice(in BluetoothDevice device);
boolean disconnectInputDevice(in BluetoothDevice device);
List<BluetoothDevice> getConnectedInputDevices();
- int getInputDeviceState(in BluetoothDevice device);
+ List<BluetoothDevice> getInputDevicesMatchingConnectionStates(in int[] states);
+ int getInputDeviceConnectionState(in BluetoothDevice device);
boolean setInputDevicePriority(in BluetoothDevice device, int priority);
int getInputDevicePriority(in BluetoothDevice device);
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 85f64d058bde..81eb09c1ad99 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -115,7 +115,7 @@ public class Resources {
private CompatibilityInfo mCompatibilityInfo;
private Display mDefaultDisplay;
- private static final LongSparseArray<Object> EMPTY_ARRAY = new LongSparseArray<Object>() {
+ private static final LongSparseArray<Object> EMPTY_ARRAY = new LongSparseArray<Object>(0) {
@Override
public void put(long k, Object o) {
throw new UnsupportedOperationException();
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 891a5d9d4601..2e43eef3c770 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -2354,39 +2354,37 @@ public class SQLiteDatabase extends SQLiteClosable {
* @return true if write-ahead-logging is set. false otherwise
*/
public boolean enableWriteAheadLogging() {
- // turn off WAL until lockingprotocolerror bug and diskIO bug are fixed
- return false;
-// // make sure the database is not READONLY. WAL doesn't make sense for readonly-databases.
-// if (isReadOnly()) {
-// return false;
-// }
-// // acquire lock - no that no other thread is enabling WAL at the same time
-// lock();
-// try {
-// if (mConnectionPool != null) {
-// // already enabled
-// return true;
-// }
-// if (mPath.equalsIgnoreCase(MEMORY_DB_PATH)) {
-// Log.i(TAG, "can't enable WAL for memory databases.");
-// return false;
-// }
-//
-// // make sure this database has NO attached databases because sqlite's write-ahead-logging
-// // doesn't work for databases with attached databases
-// if (mHasAttachedDbs) {
-// if (Log.isLoggable(TAG, Log.DEBUG)) {
-// Log.d(TAG,
-// "this database: " + mPath + " has attached databases. can't enable WAL.");
-// }
-// return false;
-// }
-// mConnectionPool = new DatabaseConnectionPool(this);
-// setJournalMode(mPath, "WAL");
-// return true;
-// } finally {
-// unlock();
-// }
+ // make sure the database is not READONLY. WAL doesn't make sense for readonly-databases.
+ if (isReadOnly()) {
+ return false;
+ }
+ // acquire lock - no that no other thread is enabling WAL at the same time
+ lock();
+ try {
+ if (mConnectionPool != null) {
+ // already enabled
+ return true;
+ }
+ if (mPath.equalsIgnoreCase(MEMORY_DB_PATH)) {
+ Log.i(TAG, "can't enable WAL for memory databases.");
+ return false;
+ }
+
+ // make sure this database has NO attached databases because sqlite's write-ahead-logging
+ // doesn't work for databases with attached databases
+ if (mHasAttachedDbs) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG,
+ "this database: " + mPath + " has attached databases. can't enable WAL.");
+ }
+ return false;
+ }
+ mConnectionPool = new DatabaseConnectionPool(this);
+ setJournalMode(mPath, "WAL");
+ return true;
+ } finally {
+ unlock();
+ }
}
/**
@@ -2394,20 +2392,19 @@ public class SQLiteDatabase extends SQLiteClosable {
* @hide
*/
public void disableWriteAheadLogging() {
- return;
-// // grab database lock so that writeAheadLogging is not disabled from 2 different threads
-// // at the same time
-// lock();
-// try {
-// if (mConnectionPool == null) {
-// return; // already disabled
-// }
-// mConnectionPool.close();
-// setJournalMode(mPath, "TRUNCATE");
-// mConnectionPool = null;
-// } finally {
-// unlock();
-// }
+ // grab database lock so that writeAheadLogging is not disabled from 2 different threads
+ // at the same time
+ lock();
+ try {
+ if (mConnectionPool == null) {
+ return; // already disabled
+ }
+ mConnectionPool.close();
+ setJournalMode(mPath, "TRUNCATE");
+ mConnectionPool = null;
+ } finally {
+ unlock();
+ }
}
/* package */ SQLiteDatabase getDatabaseHandle(String sql) {
diff --git a/core/java/android/net/DummyDataStateTracker.java b/core/java/android/net/DummyDataStateTracker.java
index daa1c0938f43..d0c77cf900c6 100644
--- a/core/java/android/net/DummyDataStateTracker.java
+++ b/core/java/android/net/DummyDataStateTracker.java
@@ -70,15 +70,6 @@ public class DummyDataStateTracker implements NetworkStateTracker {
mContext = context;
}
- /**
- * Return the IP addresses of the DNS servers available for the mobile data
- * network interface.
- * @return a list of DNS addresses, with no holes.
- */
- public String[] getDnsPropNames() {
- return new String[0];
- }
-
public boolean isPrivateDnsRouteSet() {
return mPrivateDnsRouteSet;
}
@@ -91,10 +82,6 @@ public class DummyDataStateTracker implements NetworkStateTracker {
return mNetworkInfo;
}
- public int getDefaultGatewayAddr() {
- return 0;
- }
-
public boolean isDefaultRouteSet() {
return mDefaultRouteSet;
}
@@ -181,14 +168,6 @@ public class DummyDataStateTracker implements NetworkStateTracker {
return true;
}
- public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- return -1;
- }
-
- public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- return -1;
- }
-
public void setDataEnable(boolean enabled) {
}
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 9ecd68cbef7f..e04964e53efc 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -59,7 +59,6 @@ public class MobileDataStateTracker implements NetworkStateTracker {
private ITelephony mPhoneService;
private String mApnType;
- private static String[] sDnsPropNames;
private NetworkInfo mNetworkInfo;
private boolean mTeardownRequested = false;
private Handler mTarget;
@@ -67,7 +66,6 @@ public class MobileDataStateTracker implements NetworkStateTracker {
private LinkProperties mLinkProperties;
private LinkCapabilities mLinkCapabilities;
private boolean mPrivateDnsRouteSet = false;
- private int mDefaultGatewayAddr = 0;
private boolean mDefaultRouteSet = false;
// DEFAULT and HIPRI are the same connection. If we're one of these we need to check if
@@ -94,18 +92,6 @@ public class MobileDataStateTracker implements NetworkStateTracker {
}
mPhoneService = null;
-
- sDnsPropNames = new String[] {
- "net.rmnet0.dns1",
- "net.rmnet0.dns2",
- "net.eth0.dns1",
- "net.eth0.dns2",
- "net.eth0.dns3",
- "net.eth0.dns4",
- "net.gprs.dns1",
- "net.gprs.dns2",
- "net.ppp0.dns1",
- "net.ppp0.dns2"};
}
/**
@@ -166,15 +152,6 @@ public class MobileDataStateTracker implements NetworkStateTracker {
}
}
- /**
- * Return the IP addresses of the DNS servers available for the mobile data
- * network interface.
- * @return a list of DNS addresses, with no holes.
- */
- public String[] getDnsPropNames() {
- return sDnsPropNames;
- }
-
public boolean isPrivateDnsRouteSet() {
return mPrivateDnsRouteSet;
}
@@ -187,10 +164,6 @@ public class MobileDataStateTracker implements NetworkStateTracker {
return mNetworkInfo;
}
- public int getDefaultGatewayAddr() {
- return mDefaultGatewayAddr;
- }
-
public boolean isDefaultRouteSet() {
return mDefaultRouteSet;
}
@@ -279,7 +252,6 @@ public class MobileDataStateTracker implements NetworkStateTracker {
//if (DBG) log("clearing mInterfaceName for "+ mApnType +
// " as it DISCONNECTED");
//mInterfaceName = null;
- //mDefaultGatewayAddr = 0;
break;
case CONNECTING:
setDetailedState(DetailedState.CONNECTING, reason, apnName);
@@ -507,47 +479,6 @@ public class MobileDataStateTracker implements NetworkStateTracker {
}
/**
- * Tells the phone sub-system that the caller wants to
- * begin using the named feature. The only supported features at
- * this time are {@code Phone.FEATURE_ENABLE_MMS}, which allows an application
- * to specify that it wants to send and/or receive MMS data, and
- * {@code Phone.FEATURE_ENABLE_SUPL}, which is used for Assisted GPS.
- * @param feature the name of the feature to be used
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is feature-specific.
- * specific, except that the value {@code -1}
- * always indicates failure. For {@code Phone.FEATURE_ENABLE_MMS},
- * the other possible return values are
- * <ul>
- * <li>{@code Phone.APN_ALREADY_ACTIVE}</li>
- * <li>{@code Phone.APN_REQUEST_STARTED}</li>
- * <li>{@code Phone.APN_TYPE_NOT_AVAILABLE}</li>
- * <li>{@code Phone.APN_REQUEST_FAILED}</li>
- * </ul>
- */
- public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- return -1;
- }
-
- /**
- * Tells the phone sub-system that the caller is finished
- * using the named feature. The only supported feature at
- * this time is {@code Phone.FEATURE_ENABLE_MMS}, which allows an application
- * to specify that it wants to send and/or receive MMS data.
- * @param feature the name of the feature that is no longer needed
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is feature-specific, except that
- * the value {@code -1} always indicates failure.
- */
- public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- return -1;
- }
-
- /**
* @param enabled
*/
public void setDataEnable(boolean enabled) {
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index e37850636405..eb97d77ba345 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -136,39 +136,6 @@ public interface NetworkStateTracker {
public boolean isAvailable();
/**
- * Fetch default gateway address for the network
- */
- public int getDefaultGatewayAddr();
-
- /**
- * Tells the underlying networking system that the caller wants to
- * begin using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- * @param feature the name of the feature to be used
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- */
- public int startUsingNetworkFeature(String feature, int callingPid, int callingUid);
-
- /**
- * Tells the underlying networking system that the caller is finished
- * using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- * @param feature the name of the feature that is no longer needed.
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- */
- public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid);
-
- /**
* @param enabled
*/
public void setDataEnable(boolean enabled);
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index d14324346964..eca06c50dd82 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -69,6 +69,43 @@ public class TrafficStats {
public static native long getMobileRxBytes();
/**
+ * Get the total number of packets transmitted through the specified interface.
+ *
+ * @return number of packets. If the statistics are not supported by this interface,
+ * {@link #UNSUPPORTED} will be returned.
+ * @hide
+ */
+ public static native long getTxPackets(String iface);
+
+ /**
+ * Get the total number of packets received through the specified interface.
+ *
+ * @return number of packets. If the statistics are not supported by this interface,
+ * {@link #UNSUPPORTED} will be returned.
+ * @hide
+ */
+ public static native long getRxPackets(String iface);
+
+ /**
+ * Get the total number of bytes transmitted through the specified interface.
+ *
+ * @return number of bytes. If the statistics are not supported by this interface,
+ * {@link #UNSUPPORTED} will be returned.
+ * @hide
+ */
+ public static native long getTxBytes(String iface);
+
+ /**
+ * Get the total number of bytes received through the specified interface.
+ *
+ * @return number of bytes. If the statistics are not supported by this interface,
+ * {@link #UNSUPPORTED} will be returned.
+ * @hide
+ */
+ public static native long getRxBytes(String iface);
+
+
+ /**
* Get the total number of packets sent through all network interfaces.
*
* @return the number of packets. If the statistics are not supported by this device,
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 6e6731e45506..90e2e797cbee 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -23,6 +23,7 @@ import java.util.List;
import java.util.Map;
import android.content.pm.ApplicationInfo;
+import android.telephony.SignalStrength;
import android.util.Log;
import android.util.Printer;
import android.util.SparseArray;
@@ -608,18 +609,6 @@ public abstract class BatteryStats implements Parcelable {
* {@hide}
*/
public abstract long getPhoneOnTime(long batteryRealtime, int which);
-
- public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
- public static final int SIGNAL_STRENGTH_POOR = 1;
- public static final int SIGNAL_STRENGTH_MODERATE = 2;
- public static final int SIGNAL_STRENGTH_GOOD = 3;
- public static final int SIGNAL_STRENGTH_GREAT = 4;
-
- static final String[] SIGNAL_STRENGTH_NAMES = {
- "none", "poor", "moderate", "good", "great"
- };
-
- public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
/**
* Returns the time in microseconds that the phone has been running with
@@ -710,7 +699,7 @@ public abstract class BatteryStats implements Parcelable {
SCREEN_BRIGHTNESS_NAMES),
new BitDescription(HistoryItem.STATE_SIGNAL_STRENGTH_MASK,
HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT, "signal_strength",
- SIGNAL_STRENGTH_NAMES),
+ SignalStrength.SIGNAL_STRENGTH_NAMES),
new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state",
new String[] {"in", "out", "emergency", "off"}),
@@ -1095,14 +1084,14 @@ public abstract class BatteryStats implements Parcelable {
dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
// Dump signal strength stats
- args = new Object[NUM_SIGNAL_STRENGTH_BINS];
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
}
dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
args[i] = getPhoneSignalStrengthCount(i, which);
}
dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
@@ -1408,14 +1397,14 @@ public abstract class BatteryStats implements Parcelable {
sb.append(prefix);
sb.append(" Signal levels: ");
didOne = false;
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
if (time == 0) {
continue;
}
if (didOne) sb.append(", ");
didOne = true;
- sb.append(SIGNAL_STRENGTH_NAMES[i]);
+ sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
sb.append(" ");
formatTimeMs(sb, time/1000);
sb.append("(");
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 257f275b2c1e..f5cf76e1a387 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3704,7 +3704,6 @@ public final class Settings {
TTS_ENABLED_PLUGINS,
WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
- WIFI_COUNTRY_CODE,
WIFI_NUM_OPEN_NETWORKS_KEPT,
MOUNT_PLAY_NOTIFICATION_SND,
MOUNT_UMS_AUTOSTART,
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 3316ea51f701..c0b3cc8fb523 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -57,6 +57,7 @@ class BluetoothEventLoop {
private final BluetoothService mBluetoothService;
private final BluetoothAdapter mAdapter;
private BluetoothA2dp mA2dp;
+ private BluetoothInputDevice mInputDevice;
private final Context mContext;
// The WakeLock is used for bringing up the LCD during a pairing request
// from remote device when Android is in Suspend state.
@@ -125,15 +126,24 @@ class BluetoothEventLoop {
/*package*/ void getProfileProxy() {
mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.A2DP);
+ mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.INPUT_DEVICE);
}
private BluetoothProfile.ServiceListener mProfileServiceListener =
new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
- mA2dp = (BluetoothA2dp) proxy;
+ if (profile == BluetoothProfile.A2DP) {
+ mA2dp = (BluetoothA2dp) proxy;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ mInputDevice = (BluetoothInputDevice) proxy;
+ }
}
public void onServiceDisconnected(int profile) {
- mA2dp = null;
+ if (profile == BluetoothProfile.A2DP) {
+ mA2dp = null;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ mInputDevice = null;
+ }
}
};
@@ -651,10 +661,9 @@ class BluetoothEventLoop {
} else {
Log.i(TAG, "Rejecting incoming A2DP / AVRCP connection from " + address);
}
- } else if (BluetoothUuid.isInputDevice(uuid) && !isOtherInputDeviceConnected(address)) {
- BluetoothInputDevice inputDevice = new BluetoothInputDevice(mContext);
- authorized = inputDevice.getInputDevicePriority(device) >
- BluetoothInputDevice.PRIORITY_OFF;
+ } else if (mInputDevice != null && BluetoothUuid.isInputDevice(uuid)) {
+ // We can have more than 1 input device connected.
+ authorized = mInputDevice.getPriority(device) > BluetoothInputDevice.PRIORITY_OFF;
if (authorized) {
Log.i(TAG, "Allowing incoming HID connection from " + address);
} else {
@@ -669,18 +678,6 @@ class BluetoothEventLoop {
return authorized;
}
- private boolean isOtherInputDeviceConnected(String address) {
- List<BluetoothDevice> devices =
- mBluetoothService.lookupInputDevicesMatchingStates(new int[] {
- BluetoothInputDevice.STATE_CONNECTING,
- BluetoothInputDevice.STATE_CONNECTED});
-
- for (BluetoothDevice device : devices) {
- if (!device.getAddress().equals(address)) return true;
- }
- return false;
- }
-
private boolean onAgentOutOfBandDataAvailable(String objectPath) {
if (!mBluetoothService.isEnabled()) return false;
@@ -758,7 +755,7 @@ class BluetoothEventLoop {
boolean connected = false;
BluetoothDevice device = mAdapter.getRemoteDevice(address);
- int state = mBluetoothService.getInputDeviceState(device);
+ int state = mBluetoothService.getInputDeviceConnectionState(device);
if (state == BluetoothInputDevice.STATE_CONNECTING) {
if (result == BluetoothInputDevice.INPUT_CONNECT_FAILED_ALREADY_CONNECTED) {
connected = true;
diff --git a/core/java/android/server/BluetoothInputProfileHandler.java b/core/java/android/server/BluetoothInputProfileHandler.java
index 7ffa5ae2c727..cdc0f2df5d17 100644
--- a/core/java/android/server/BluetoothInputProfileHandler.java
+++ b/core/java/android/server/BluetoothInputProfileHandler.java
@@ -64,7 +64,7 @@ final class BluetoothInputProfileHandler {
BluetoothDeviceProfileState state) {
String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
if (objectPath == null ||
- getInputDeviceState(device) != BluetoothInputDevice.STATE_DISCONNECTED ||
+ getInputDeviceConnectionState(device) != BluetoothInputDevice.STATE_DISCONNECTED ||
getInputDevicePriority(device) == BluetoothInputDevice.PRIORITY_OFF) {
return false;
}
@@ -92,7 +92,7 @@ final class BluetoothInputProfileHandler {
BluetoothDeviceProfileState state) {
String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
if (objectPath == null ||
- getInputDeviceState(device) == BluetoothInputDevice.STATE_DISCONNECTED) {
+ getInputDeviceConnectionState(device) == BluetoothInputDevice.STATE_DISCONNECTED) {
return false;
}
if (state != null) {
@@ -115,7 +115,7 @@ final class BluetoothInputProfileHandler {
return true;
}
- synchronized int getInputDeviceState(BluetoothDevice device) {
+ synchronized int getInputDeviceConnectionState(BluetoothDevice device) {
if (mInputDevices.get(device) == null) {
return BluetoothInputDevice.STATE_DISCONNECTED;
}
@@ -128,6 +128,11 @@ final class BluetoothInputProfileHandler {
return devices;
}
+ synchronized List<BluetoothDevice> getInputDevicesMatchingConnectionStates(int[] states) {
+ List<BluetoothDevice> devices = lookupInputDevicesMatchingStates(states);
+ return devices;
+ }
+
synchronized int getInputDevicePriority(BluetoothDevice device) {
return Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.getBluetoothInputDevicePriorityKey(device.getAddress()),
@@ -147,7 +152,7 @@ final class BluetoothInputProfileHandler {
List<BluetoothDevice> inputDevices = new ArrayList<BluetoothDevice>();
for (BluetoothDevice device: mInputDevices.keySet()) {
- int inputDeviceState = getInputDeviceState(device);
+ int inputDeviceState = getInputDeviceConnectionState(device);
for (int state : states) {
if (state == inputDeviceState) {
inputDevices.add(device);
@@ -178,10 +183,10 @@ final class BluetoothInputProfileHandler {
setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_AUTO_CONNECT);
}
- Intent intent = new Intent(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED);
+ Intent intent = new Intent(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothInputDevice.EXTRA_PREVIOUS_INPUT_DEVICE_STATE, prevState);
- intent.putExtra(BluetoothInputDevice.EXTRA_INPUT_DEVICE_STATE, state);
+ intent.putExtra(BluetoothInputDevice.EXTRA_PREVIOUS_STATE, prevState);
+ intent.putExtra(BluetoothInputDevice.EXTRA_STATE, state);
mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
debugLog("InputDevice state : device: " + device + " State:" + prevState + "->" + state);
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index a295de5660f6..70aaf0a009f1 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -31,6 +31,7 @@ import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDeviceProfileState;
import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothInputDevice;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfileState;
@@ -83,6 +84,7 @@ public class BluetoothService extends IBluetooth.Stub {
private int mNativeData;
private BluetoothEventLoop mEventLoop;
private BluetoothHeadset mBluetoothHeadset;
+ private BluetoothInputDevice mInputDevice;
private boolean mIsAirplaneSensitive;
private boolean mIsAirplaneToggleable;
private int mBluetoothState;
@@ -2078,6 +2080,8 @@ public class BluetoothService extends IBluetooth.Stub {
mAdapter.getProfileProxy(mContext,
mBluetoothProfileServiceListener, BluetoothProfile.HEADSET);
+ mAdapter.getProfileProxy(mContext,
+ mBluetoothProfileServiceListener, BluetoothProfile.INPUT_DEVICE);
pw.println("\n--Known devices--");
for (String address : mDeviceProperties.keySet()) {
@@ -2119,8 +2123,17 @@ public class BluetoothService extends IBluetooth.Stub {
}
}
- // Rather not do this from here, but no-where else and I need this
- // dump
+ dumpHeadsetProfile(pw);
+ dumpInputDeviceProfile(pw);
+
+ pw.println("\n--Application Service Records--");
+ for (Integer handle : mServiceRecordToPid.keySet()) {
+ Integer pid = mServiceRecordToPid.get(handle);
+ pw.println("\tpid " + pid + " handle " + Integer.toHexString(handle));
+ }
+ }
+
+ private void dumpHeadsetProfile(PrintWriter pw) {
pw.println("\n--Headset Service--");
if (mBluetoothHeadset != null) {
List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
@@ -2158,24 +2171,60 @@ public class BluetoothService extends IBluetooth.Stub {
pw.println("SCO audio connected to device:" + device);
}
}
-
- mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
}
+ mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
+ }
- pw.println("\n--Application Service Records--");
- for (Integer handle : mServiceRecordToPid.keySet()) {
- Integer pid = mServiceRecordToPid.get(handle);
- pw.println("\tpid " + pid + " handle " + Integer.toHexString(handle));
+ private void dumpInputDeviceProfile(PrintWriter pw) {
+ pw.println("\n--Bluetooth Service- Input Device Profile");
+ if (mInputDevice != null) {
+ List<BluetoothDevice> deviceList = mInputDevice.getConnectedDevices();
+ if (deviceList.size() == 0) {
+ pw.println("\nNo input devices connected--");
+ } else {
+ pw.println("\nNumber of connected devices:" + deviceList.size());
+ BluetoothDevice device = deviceList.get(0);
+ pw.println("getConnectedDevices[0] = " + device);
+ pw.println("Priority of Connected device = " + mInputDevice.getPriority(device));
+
+ switch (mInputDevice.getConnectionState(device)) {
+ case BluetoothInputDevice.STATE_CONNECTING:
+ pw.println("getConnectionState() = STATE_CONNECTING");
+ break;
+ case BluetoothInputDevice.STATE_CONNECTED:
+ pw.println("getConnectionState() = STATE_CONNECTED");
+ break;
+ case BluetoothInputDevice.STATE_DISCONNECTING:
+ pw.println("getConnectionState() = STATE_DISCONNECTING");
+ break;
+ }
+ }
+ deviceList.clear();
+ deviceList = mInputDevice.getDevicesMatchingConnectionStates(new int[] {
+ BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED});
+ pw.println("--Connected and Disconnected input devices");
+ for (BluetoothDevice device: deviceList) {
+ pw.println(device);
+ }
}
+ mAdapter.closeProfileProxy(BluetoothProfile.INPUT_DEVICE, mBluetoothHeadset);
}
private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
- mBluetoothHeadset = (BluetoothHeadset) proxy;
- }
+ if (profile == BluetoothProfile.HEADSET) {
+ mBluetoothHeadset = (BluetoothHeadset) proxy;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ mInputDevice = (BluetoothInputDevice) proxy;
+ }
+ }
public void onServiceDisconnected(int profile) {
- mBluetoothHeadset = null;
+ if (profile == BluetoothProfile.HEADSET) {
+ mBluetoothHeadset = null;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ mInputDevice = null;
+ }
}
};
@@ -2311,9 +2360,9 @@ public class BluetoothService extends IBluetooth.Stub {
return mBluetoothInputProfileHandler.disconnectInputDeviceInternal(device);
}
- public synchronized int getInputDeviceState(BluetoothDevice device) {
+ public synchronized int getInputDeviceConnectionState(BluetoothDevice device) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return mBluetoothInputProfileHandler.getInputDeviceState(device);
+ return mBluetoothInputProfileHandler.getInputDeviceConnectionState(device);
}
@@ -2322,6 +2371,13 @@ public class BluetoothService extends IBluetooth.Stub {
return mBluetoothInputProfileHandler.getConnectedInputDevices();
}
+ public synchronized List<BluetoothDevice> getInputDevicesMatchingConnectionStates(
+ int[] states) {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ return mBluetoothInputProfileHandler.getInputDevicesMatchingConnectionStates(states);
+ }
+
+
public synchronized int getInputDevicePriority(BluetoothDevice device) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
return mBluetoothInputProfileHandler.getInputDevicePriority(device);
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 97a216a8415d..1e4cca95ec9c 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1727,6 +1727,17 @@ public abstract class Layout {
}
}
+ /**
+ * Inform this layout that not all of its lines will be displayed, because a maximum number of
+ * lines has been set on the associated TextView.
+ *
+ * A non strictly positive value means that all lines are displayed.
+ *
+ * @param lineCount number of visible lines
+ * @hide
+ */
+ public void setMaximumVisibleLineCount(int lineCount) {}
+
private CharSequence mText;
private TextPaint mPaint;
/* package */ TextPaint mWorkPaint;
@@ -1765,14 +1776,4 @@ public abstract class Layout {
/* package */ static final Directions DIRS_ALL_RIGHT_TO_LEFT =
new Directions(new int[] { 0, RUN_LENGTH_MASK | RUN_RTL_FLAG });
- /**
- * Inform this layout that not all of its lines will be displayed, because a maximum number of
- * lines has been set on the associated TextView.
- *
- * A non positive value means that all lines are displayed.
- *
- * @param line line number of the last visible line (line numbers start at 1 for the first line)
- * @hide
- */
- public void setMaximumVisibleLineCount(int line) {}
}
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index a4546f0682b3..a826a97ff889 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -355,8 +355,6 @@ public class StaticLayout extends Layout {
okBottom = fitBottom;
}
} else {
- if (ellipsize != null) {
- // Break only at spaces using ok indexes.
if (ok != here) {
// Log.e("text", "output ok " + here + " to " +ok);
@@ -372,43 +370,7 @@ public class StaticLayout extends Layout {
chooseHtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
ok == bufEnd, includepad, trackpad,
- chs, widths, here - paraStart,
- ellipsize, ellipsizedWidth, okWidth,
- paint);
-
- here = ok;
- } else {
- // Act like it fit even though it didn't.
-
- fitWidth = w;
- here = fit = j + 1;
-
- if (fmTop < fitTop)
- fitTop = fmTop;
- if (fmAscent < fitAscent)
- fitAscent = fmAscent;
- if (fmDescent > fitDescent)
- fitDescent = fmDescent;
- if (fmBottom > fitBottom)
- fitBottom = fmBottom;
- }
- } else {
- if (ok != here) {
- // Log.e("text", "output ok " + here + " to " +ok);
-
- while (ok < spanEnd && chs[ok - paraStart] == CHAR_SPACE) {
- ok++;
- }
-
- v = out(source,
- here, ok,
- okAscent, okDescent, okTop, okBottom,
- v,
- spacingmult, spacingadd, chooseHt,
- chooseHtv, fm, hasTabOrEmoji,
- needMultiply, paraStart, chdirs, dir, easy,
- ok == bufEnd, includepad, trackpad,
- chs, widths, here - paraStart,
+ chs, widths, paraStart,
ellipsize, ellipsizedWidth, okWidth,
paint);
@@ -424,7 +386,7 @@ public class StaticLayout extends Layout {
chooseHtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
fit == bufEnd, includepad, trackpad,
- chs, widths, here - paraStart,
+ chs, widths, paraStart,
ellipsize, ellipsizedWidth, fitWidth,
paint);
@@ -446,13 +408,12 @@ public class StaticLayout extends Layout {
needMultiply, paraStart, chdirs, dir, easy,
here + 1 == bufEnd, includepad,
trackpad,
- chs, widths, here - paraStart,
+ chs, widths, paraStart,
ellipsize, ellipsizedWidth,
widths[here - paraStart], paint);
here = here + 1;
}
- }
if (here < spanStart) {
// didn't output all the text for this span
@@ -495,7 +456,7 @@ public class StaticLayout extends Layout {
chooseHtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
paraEnd == bufEnd, includepad, trackpad,
- chs, widths, here - paraStart,
+ chs, widths, paraStart,
ellipsize, ellipsizedWidth, w, paint);
}
@@ -614,19 +575,6 @@ public class StaticLayout extends Layout {
return false;
}
-/*
- private static void dump(byte[] data, int count, String label) {
- if (false) {
- System.out.print(label);
-
- for (int i = 0; i < count; i++)
- System.out.print(" " + data[i]);
-
- System.out.println();
- }
- }
-*/
-
private int out(CharSequence text, int start, int end,
int above, int below, int top, int bottom, int v,
float spacingmult, float spacingadd,
@@ -729,8 +677,8 @@ public class StaticLayout extends Layout {
if (easy) {
mLineDirections[j] = linedirs;
} else {
- mLineDirections[j] = AndroidBidi.directions(dir, chdirs, widthStart, chs,
- widthStart, end - start);
+ mLineDirections[j] = AndroidBidi.directions(dir, chdirs, start - widthStart, chs,
+ start - widthStart, end - start);
}
// If ellipsize is in marquee mode, do not apply ellipsis on the first line
@@ -869,7 +817,7 @@ public class StaticLayout extends Layout {
@Override
public int getLineDescent(int line) {
int descent = mLines[mColumns * line + DESCENT];
- if (mMaximumVisibleLineCount > 0 && line >= mMaximumVisibleLineCount - 1 &&
+ if (mMaximumVisibleLineCount > 0 && line >= mMaximumVisibleLineCount - 1 && // -1 intended
line != mLineCount) {
descent += getBottomPadding();
}
@@ -933,8 +881,8 @@ public class StaticLayout extends Layout {
* @hide
*/
@Override
- public void setMaximumVisibleLineCount(int line) {
- mMaximumVisibleLineCount = line;
+ public void setMaximumVisibleLineCount(int lineCount) {
+ mMaximumVisibleLineCount = lineCount;
}
private int mLineCount;
diff --git a/core/java/android/util/AttributeSet.java b/core/java/android/util/AttributeSet.java
index 82592b9f7e06..470526cf1bdd 100644
--- a/core/java/android/util/AttributeSet.java
+++ b/core/java/android/util/AttributeSet.java
@@ -56,10 +56,53 @@ package android.util;
* identifier associated with a particular XML attribute name.
*/
public interface AttributeSet {
+ /**
+ * Returns the number of attributes available in the set.
+ *
+ * @return A positive integer, or 0 if the set is empty.
+ */
public int getAttributeCount();
+
+ /**
+ * Returns the name of the specified attribute.
+ *
+ * @param index Index of the desired attribute, 0...count-1.
+ *
+ * @return A String containing the name of the attribute, or null if the
+ * attribute cannot be found.
+ */
public String getAttributeName(int index);
+
+ /**
+ * Returns the value of the specified attribute as a string representation.
+ *
+ * @param index Index of the desired attribute, 0...count-1.
+ *
+ * @return A String containing the value of the attribute, or null if the
+ * attribute cannot be found.
+ */
public String getAttributeValue(int index);
+
+ /**
+ * Returns the value of the specified attribute as a string representation.
+ * The lookup is performed using the attribute name.
+ *
+ * @param namespace The namespace of the attribute to get the value from.
+ * @param name The name of the attribute to get the value from.
+ *
+ * @return A String containing the value of the attribute, or null if the
+ * attribute cannot be found.
+ */
public String getAttributeValue(String namespace, String name);
+
+ /**
+ * Returns a description of the current position of the attribute set.
+ * For instance, if the attribute set is loaded from an XML document,
+ * the position description could indicate the current line number.
+ *
+ * @return A string representation of the current position in the set,
+ * may be null.
+ */
public String getPositionDescription();
/**
@@ -80,7 +123,8 @@ public interface AttributeSet {
/**
* Return the index of the value of 'attribute' in the list 'options'.
- *
+ *
+ * @param namespace Namespace of attribute to retrieve.
* @param attribute Name of attribute to retrieve.
* @param options List of strings whose values we are checking against.
* @param defaultValue Value returned if attribute doesn't exist or no
@@ -94,6 +138,7 @@ public interface AttributeSet {
/**
* Return the boolean value of 'attribute'.
*
+ * @param namespace Namespace of attribute to retrieve.
* @param attribute The attribute to retrieve.
* @param defaultValue What to return if the attribute isn't found.
*
@@ -111,6 +156,7 @@ public interface AttributeSet {
* "@package:type/resource"); the other method returns a resource
* identifier that identifies the name of the attribute.
*
+ * @param namespace Namespace of attribute to retrieve.
* @param attribute The attribute to retrieve.
* @param defaultValue What to return if the attribute isn't found.
*
@@ -122,6 +168,7 @@ public interface AttributeSet {
/**
* Return the integer value of 'attribute'.
*
+ * @param namespace Namespace of attribute to retrieve.
* @param attribute The attribute to retrieve.
* @param defaultValue What to return if the attribute isn't found.
*
@@ -135,6 +182,7 @@ public interface AttributeSet {
* unsigned value. In particular, the formats 0xn...n and #n...n are
* handled.
*
+ * @param namespace Namespace of attribute to retrieve.
* @param attribute The attribute to retrieve.
* @param defaultValue What to return if the attribute isn't found.
*
@@ -146,6 +194,7 @@ public interface AttributeSet {
/**
* Return the float value of 'attribute'.
*
+ * @param namespace Namespace of attribute to retrieve.
* @param attribute The attribute to retrieve.
* @param defaultValue What to return if the attribute isn't found.
*
@@ -165,8 +214,7 @@ public interface AttributeSet {
*
* @return Index in to 'options' or defaultValue.
*/
- public int getAttributeListValue(int index,
- String[] options, int defaultValue);
+ public int getAttributeListValue(int index, String[] options, int defaultValue);
/**
* Return the boolean value of attribute at 'index'.
@@ -176,8 +224,7 @@ public interface AttributeSet {
*
* @return Resulting value.
*/
- public boolean getAttributeBooleanValue(int index,
- boolean defaultValue);
+ public boolean getAttributeBooleanValue(int index, boolean defaultValue);
/**
* Return the value of attribute at 'index' as a resource identifier.
@@ -193,8 +240,7 @@ public interface AttributeSet {
*
* @return Resulting value.
*/
- public int getAttributeResourceValue(int index,
- int defaultValue);
+ public int getAttributeResourceValue(int index, int defaultValue);
/**
* Return the integer value of attribute at 'index'.
@@ -204,8 +250,7 @@ public interface AttributeSet {
*
* @return Resulting value.
*/
- public int getAttributeIntValue(int index,
- int defaultValue);
+ public int getAttributeIntValue(int index, int defaultValue);
/**
* Return the integer value of attribute at 'index' that is formatted as an
@@ -217,8 +262,7 @@ public interface AttributeSet {
*
* @return Resulting value.
*/
- public int getAttributeUnsignedIntValue(int index,
- int defaultValue);
+ public int getAttributeUnsignedIntValue(int index, int defaultValue);
/**
* Return the float value of attribute at 'index'.
@@ -228,8 +272,7 @@ public interface AttributeSet {
*
* @return Resulting value.
*/
- public float getAttributeFloatValue(int index,
- float defaultValue);
+ public float getAttributeFloatValue(int index, float defaultValue);
/**
* Return the value of the "id" attribute or null if there is not one.
@@ -266,4 +309,3 @@ public interface AttributeSet {
*/
public int getStyleAttribute();
}
-
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 51653df16d1c..dd8242a6fef1 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -100,6 +100,8 @@ interface IWindowManager
void disableKeyguard(IBinder token, String tag);
void reenableKeyguard(IBinder token);
void exitKeyguardSecurely(IOnKeyguardExitResult callback);
+ boolean isKeyguardLocked();
+ boolean isKeyguardSecure();
boolean inKeyguardRestrictedInputMode();
void closeSystemDialogs(String reason);
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 7abbce6269c5..def1161d05b4 100755
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -44,6 +44,7 @@ public final class InputDevice implements Parcelable {
private int mKeyboardType;
private final SparseArray<MotionRange> mMotionRanges = new SparseArray<MotionRange>();
+ private int[] mMotionAxes;
/**
* A mask for input source classes.
@@ -359,12 +360,31 @@ public final class InputDevice implements Parcelable {
*
* @see MotionEvent#AXIS_X
* @see MotionEvent#AXIS_Y
+ * @see #getSupportedAxes()
*/
public MotionRange getMotionRange(int axis) {
return mMotionRanges.get(axis);
}
- // Called by native code.
+ /**
+ * Gets the axis ids of all motion axes supported by this device.
+ * @return The axis ids of all motion axes supported by this device.
+ *
+ * @see #getMotionRange(int)
+ */
+ public int[] getMotionAxes() {
+ synchronized (this) {
+ if (mMotionAxes == null) {
+ final int count = mMotionRanges.size();
+ mMotionAxes = new int[count];
+ for (int i = 0; i < count; i++) {
+ mMotionAxes[i] = mMotionRanges.keyAt(i);
+ }
+ }
+ return mMotionAxes;
+ }
+ }
+
private void addMotionRange(int axis, float min, float max, float flat, float fuzz) {
mMotionRanges.append(axis, new MotionRange(min, max, flat, fuzz));
}
@@ -388,33 +408,35 @@ public final class InputDevice implements Parcelable {
}
/**
- * Gets the minimum value for the axis.
- * @return The (inclusive) minimum value.
+ * Gets the inclusive minimum value for the axis.
+ * @return The inclusive minimum value.
*/
public float getMin() {
return mMin;
}
/**
- * Gets the maximum value for the axis.
- * @return The (inclusive) maximum value.
+ * Gets the inclusive maximum value for the axis.
+ * @return The inclusive maximum value.
*/
public float getMax() {
return mMax;
}
/**
- * Gets the range of the axis (difference between maximum and minimum plus one).
+ * Gets the range of the axis (difference between maximum and minimum).
* @return The range of values.
*/
public float getRange() {
- return mMax - mMin + 1;
+ return mMax - mMin;
}
/**
* Gets the extent of the center flat position with respect to this axis.
+ * <p>
* For example, a flat value of 8 means that the center position is between -8 and +8.
* This value is mainly useful for calibrating self-centering devices.
+ * </p>
* @return The extent of the center flat position.
*/
public float getFlat() {
@@ -423,8 +445,10 @@ public final class InputDevice implements Parcelable {
/**
* Gets the error tolerance for input device measurements with respect to this axis.
+ * <p>
* For example, a value of 2 indicates that the measured value may be up to +/- 2 units
* away from the actual value due to noise and device sensitivity limitations.
+ * </p>
* @return The error tolerance.
*/
public float getFuzz() {
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 3f6a04b09baf..81d5a6e7f77d 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -21,6 +21,7 @@ import android.os.Parcelable;
import android.text.method.MetaKeyKeyListener;
import android.util.Log;
import android.util.Slog;
+import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.KeyCharacterMap;
import android.view.KeyCharacterMap.KeyData;
@@ -582,213 +583,214 @@ public class KeyEvent extends InputEvent implements Parcelable {
// those new codes. This is intended to maintain a consistent
// set of key code definitions across all Android devices.
- // Symbolic names of all keys indexed by keycode.
- // There should be exactly LAST_KEYCODE + 1 entries in this table.
- private static final String[] KEYCODE_SYMBOLIC_NAMES = new String[] {
- "KEYCODE_UNKNOWN",
- "KEYCODE_SOFT_LEFT",
- "KEYCODE_SOFT_RIGHT",
- "KEYCODE_HOME",
- "KEYCODE_BACK",
- "KEYCODE_CALL",
- "KEYCODE_ENDCALL",
- "KEYCODE_0",
- "KEYCODE_1",
- "KEYCODE_2",
- "KEYCODE_3",
- "KEYCODE_4",
- "KEYCODE_5",
- "KEYCODE_6",
- "KEYCODE_7",
- "KEYCODE_8",
- "KEYCODE_9",
- "KEYCODE_STAR",
- "KEYCODE_POUND",
- "KEYCODE_DPAD_UP",
- "KEYCODE_DPAD_DOWN",
- "KEYCODE_DPAD_LEFT",
- "KEYCODE_DPAD_RIGHT",
- "KEYCODE_DPAD_CENTER",
- "KEYCODE_VOLUME_UP",
- "KEYCODE_VOLUME_DOWN",
- "KEYCODE_POWER",
- "KEYCODE_CAMERA",
- "KEYCODE_CLEAR",
- "KEYCODE_A",
- "KEYCODE_B",
- "KEYCODE_C",
- "KEYCODE_D",
- "KEYCODE_E",
- "KEYCODE_F",
- "KEYCODE_G",
- "KEYCODE_H",
- "KEYCODE_I",
- "KEYCODE_J",
- "KEYCODE_K",
- "KEYCODE_L",
- "KEYCODE_M",
- "KEYCODE_N",
- "KEYCODE_O",
- "KEYCODE_P",
- "KEYCODE_Q",
- "KEYCODE_R",
- "KEYCODE_S",
- "KEYCODE_T",
- "KEYCODE_U",
- "KEYCODE_V",
- "KEYCODE_W",
- "KEYCODE_X",
- "KEYCODE_Y",
- "KEYCODE_Z",
- "KEYCODE_COMMA",
- "KEYCODE_PERIOD",
- "KEYCODE_ALT_LEFT",
- "KEYCODE_ALT_RIGHT",
- "KEYCODE_SHIFT_LEFT",
- "KEYCODE_SHIFT_RIGHT",
- "KEYCODE_TAB",
- "KEYCODE_SPACE",
- "KEYCODE_SYM",
- "KEYCODE_EXPLORER",
- "KEYCODE_ENVELOPE",
- "KEYCODE_ENTER",
- "KEYCODE_DEL",
- "KEYCODE_GRAVE",
- "KEYCODE_MINUS",
- "KEYCODE_EQUALS",
- "KEYCODE_LEFT_BRACKET",
- "KEYCODE_RIGHT_BRACKET",
- "KEYCODE_BACKSLASH",
- "KEYCODE_SEMICOLON",
- "KEYCODE_APOSTROPHE",
- "KEYCODE_SLASH",
- "KEYCODE_AT",
- "KEYCODE_NUM",
- "KEYCODE_HEADSETHOOK",
- "KEYCODE_FOCUS",
- "KEYCODE_PLUS",
- "KEYCODE_MENU",
- "KEYCODE_NOTIFICATION",
- "KEYCODE_SEARCH",
- "KEYCODE_MEDIA_PLAY_PAUSE",
- "KEYCODE_MEDIA_STOP",
- "KEYCODE_MEDIA_NEXT",
- "KEYCODE_MEDIA_PREVIOUS",
- "KEYCODE_MEDIA_REWIND",
- "KEYCODE_MEDIA_FAST_FORWARD",
- "KEYCODE_MUTE",
- "KEYCODE_PAGE_UP",
- "KEYCODE_PAGE_DOWN",
- "KEYCODE_PICTSYMBOLS",
- "KEYCODE_SWITCH_CHARSET",
- "KEYCODE_BUTTON_A",
- "KEYCODE_BUTTON_B",
- "KEYCODE_BUTTON_C",
- "KEYCODE_BUTTON_X",
- "KEYCODE_BUTTON_Y",
- "KEYCODE_BUTTON_Z",
- "KEYCODE_BUTTON_L1",
- "KEYCODE_BUTTON_R1",
- "KEYCODE_BUTTON_L2",
- "KEYCODE_BUTTON_R2",
- "KEYCODE_BUTTON_THUMBL",
- "KEYCODE_BUTTON_THUMBR",
- "KEYCODE_BUTTON_START",
- "KEYCODE_BUTTON_SELECT",
- "KEYCODE_BUTTON_MODE",
- "KEYCODE_ESCAPE",
- "KEYCODE_FORWARD_DEL",
- "KEYCODE_CTRL_LEFT",
- "KEYCODE_CTRL_RIGHT",
- "KEYCODE_CAPS_LOCK",
- "KEYCODE_SCROLL_LOCK",
- "KEYCODE_META_LEFT",
- "KEYCODE_META_RIGHT",
- "KEYCODE_FUNCTION",
- "KEYCODE_SYSRQ",
- "KEYCODE_BREAK",
- "KEYCODE_MOVE_HOME",
- "KEYCODE_MOVE_END",
- "KEYCODE_INSERT",
- "KEYCODE_FORWARD",
- "KEYCODE_MEDIA_PLAY",
- "KEYCODE_MEDIA_PAUSE",
- "KEYCODE_MEDIA_CLOSE",
- "KEYCODE_MEDIA_EJECT",
- "KEYCODE_MEDIA_RECORD",
- "KEYCODE_F1",
- "KEYCODE_F2",
- "KEYCODE_F3",
- "KEYCODE_F4",
- "KEYCODE_F5",
- "KEYCODE_F6",
- "KEYCODE_F7",
- "KEYCODE_F8",
- "KEYCODE_F9",
- "KEYCODE_F10",
- "KEYCODE_F11",
- "KEYCODE_F12",
- "KEYCODE_NUM_LOCK",
- "KEYCODE_NUMPAD_0",
- "KEYCODE_NUMPAD_1",
- "KEYCODE_NUMPAD_2",
- "KEYCODE_NUMPAD_3",
- "KEYCODE_NUMPAD_4",
- "KEYCODE_NUMPAD_5",
- "KEYCODE_NUMPAD_6",
- "KEYCODE_NUMPAD_7",
- "KEYCODE_NUMPAD_8",
- "KEYCODE_NUMPAD_9",
- "KEYCODE_NUMPAD_DIVIDE",
- "KEYCODE_NUMPAD_MULTIPLY",
- "KEYCODE_MUMPAD_SUBTRACT",
- "KEYCODE_NUMPAD_ADD",
- "KEYCODE_NUMPAD_DOT",
- "KEYCODE_NUMPAD_COMMA",
- "KEYCODE_NUMPAD_ENTER",
- "KEYCODE_NUMPAD_EQUALS",
- "KEYCODE_NUMPAD_LEFT_PAREN",
- "KEYCODE_NUMPAD_RIGHT_PAREN",
- "KEYCODE_VOLUME_MUTE",
- "KEYCODE_INFO",
- "KEYCODE_CHANNEL_UP",
- "KEYCODE_CHANNEL_DOWN",
- "KEYCODE_ZOOM_IN",
- "KEYCODE_ZOOM_OUT",
- "KEYCODE_TV",
- "KEYCODE_WINDOW",
- "KEYCODE_GUIDE",
- "KEYCODE_DVR",
- "KEYCODE_BOOKMARK",
- "KEYCODE_CAPTIONS",
- "KEYCODE_SETTINGS",
- "KEYCODE_TV_POWER",
- "KEYCODE_TV_INPUT",
- "KEYCODE_STB_INPUT",
- "KEYCODE_STB_POWER",
- "KEYCODE_AVR_POWER",
- "KEYCODE_AVR_INPUT",
- "KEYCODE_PROG_RED",
- "KEYCODE_PROG_GREEN",
- "KEYCODE_PROG_YELLOW",
- "KEYCODE_PROG_BLUE",
- "KEYCODE_APP_SWITCH",
- "KEYCODE_BUTTON_1",
- "KEYCODE_BUTTON_2",
- "KEYCODE_BUTTON_3",
- "KEYCODE_BUTTON_4",
- "KEYCODE_BUTTON_5",
- "KEYCODE_BUTTON_6",
- "KEYCODE_BUTTON_7",
- "KEYCODE_BUTTON_8",
- "KEYCODE_BUTTON_9",
- "KEYCODE_BUTTON_10",
- "KEYCODE_BUTTON_11",
- "KEYCODE_BUTTON_12",
- "KEYCODE_BUTTON_13",
- "KEYCODE_BUTTON_14",
- "KEYCODE_BUTTON_15",
- "KEYCODE_BUTTON_16",
+ // Symbolic names of all key codes.
+ private static final SparseArray<String> KEYCODE_SYMBOLIC_NAMES = new SparseArray<String>();
+ private static void populateKeycodeSymbolicNames() {
+ SparseArray<String> names = KEYCODE_SYMBOLIC_NAMES;
+ names.append(KEYCODE_UNKNOWN, "KEYCODE_UNKNOWN");
+ names.append(KEYCODE_SOFT_LEFT, "KEYCODE_SOFT_LEFT");
+ names.append(KEYCODE_SOFT_RIGHT, "KEYCODE_SOFT_RIGHT");
+ names.append(KEYCODE_HOME, "KEYCODE_HOME");
+ names.append(KEYCODE_BACK, "KEYCODE_BACK");
+ names.append(KEYCODE_CALL, "KEYCODE_CALL");
+ names.append(KEYCODE_ENDCALL, "KEYCODE_ENDCALL");
+ names.append(KEYCODE_0, "KEYCODE_0");
+ names.append(KEYCODE_1, "KEYCODE_1");
+ names.append(KEYCODE_2, "KEYCODE_2");
+ names.append(KEYCODE_3, "KEYCODE_3");
+ names.append(KEYCODE_4, "KEYCODE_4");
+ names.append(KEYCODE_5, "KEYCODE_5");
+ names.append(KEYCODE_6, "KEYCODE_6");
+ names.append(KEYCODE_7, "KEYCODE_7");
+ names.append(KEYCODE_8, "KEYCODE_8");
+ names.append(KEYCODE_9, "KEYCODE_9");
+ names.append(KEYCODE_STAR, "KEYCODE_STAR");
+ names.append(KEYCODE_POUND, "KEYCODE_POUND");
+ names.append(KEYCODE_DPAD_UP, "KEYCODE_DPAD_UP");
+ names.append(KEYCODE_DPAD_DOWN, "KEYCODE_DPAD_DOWN");
+ names.append(KEYCODE_DPAD_LEFT, "KEYCODE_DPAD_LEFT");
+ names.append(KEYCODE_DPAD_RIGHT, "KEYCODE_DPAD_RIGHT");
+ names.append(KEYCODE_DPAD_CENTER, "KEYCODE_DPAD_CENTER");
+ names.append(KEYCODE_VOLUME_UP, "KEYCODE_VOLUME_UP");
+ names.append(KEYCODE_VOLUME_DOWN, "KEYCODE_VOLUME_DOWN");
+ names.append(KEYCODE_POWER, "KEYCODE_POWER");
+ names.append(KEYCODE_CAMERA, "KEYCODE_CAMERA");
+ names.append(KEYCODE_CLEAR, "KEYCODE_CLEAR");
+ names.append(KEYCODE_A, "KEYCODE_A");
+ names.append(KEYCODE_B, "KEYCODE_B");
+ names.append(KEYCODE_C, "KEYCODE_C");
+ names.append(KEYCODE_D, "KEYCODE_D");
+ names.append(KEYCODE_E, "KEYCODE_E");
+ names.append(KEYCODE_F, "KEYCODE_F");
+ names.append(KEYCODE_G, "KEYCODE_G");
+ names.append(KEYCODE_H, "KEYCODE_H");
+ names.append(KEYCODE_I, "KEYCODE_I");
+ names.append(KEYCODE_J, "KEYCODE_J");
+ names.append(KEYCODE_K, "KEYCODE_K");
+ names.append(KEYCODE_L, "KEYCODE_L");
+ names.append(KEYCODE_M, "KEYCODE_M");
+ names.append(KEYCODE_N, "KEYCODE_N");
+ names.append(KEYCODE_O, "KEYCODE_O");
+ names.append(KEYCODE_P, "KEYCODE_P");
+ names.append(KEYCODE_Q, "KEYCODE_Q");
+ names.append(KEYCODE_R, "KEYCODE_R");
+ names.append(KEYCODE_S, "KEYCODE_S");
+ names.append(KEYCODE_T, "KEYCODE_T");
+ names.append(KEYCODE_U, "KEYCODE_U");
+ names.append(KEYCODE_V, "KEYCODE_V");
+ names.append(KEYCODE_W, "KEYCODE_W");
+ names.append(KEYCODE_X, "KEYCODE_X");
+ names.append(KEYCODE_Y, "KEYCODE_Y");
+ names.append(KEYCODE_Z, "KEYCODE_Z");
+ names.append(KEYCODE_COMMA, "KEYCODE_COMMA");
+ names.append(KEYCODE_PERIOD, "KEYCODE_PERIOD");
+ names.append(KEYCODE_ALT_LEFT, "KEYCODE_ALT_LEFT");
+ names.append(KEYCODE_ALT_RIGHT, "KEYCODE_ALT_RIGHT");
+ names.append(KEYCODE_SHIFT_LEFT, "KEYCODE_SHIFT_LEFT");
+ names.append(KEYCODE_SHIFT_RIGHT, "KEYCODE_SHIFT_RIGHT");
+ names.append(KEYCODE_TAB, "KEYCODE_TAB");
+ names.append(KEYCODE_SPACE, "KEYCODE_SPACE");
+ names.append(KEYCODE_SYM, "KEYCODE_SYM");
+ names.append(KEYCODE_EXPLORER, "KEYCODE_EXPLORER");
+ names.append(KEYCODE_ENVELOPE, "KEYCODE_ENVELOPE");
+ names.append(KEYCODE_ENTER, "KEYCODE_ENTER");
+ names.append(KEYCODE_DEL, "KEYCODE_DEL");
+ names.append(KEYCODE_GRAVE, "KEYCODE_GRAVE");
+ names.append(KEYCODE_MINUS, "KEYCODE_MINUS");
+ names.append(KEYCODE_EQUALS, "KEYCODE_EQUALS");
+ names.append(KEYCODE_LEFT_BRACKET, "KEYCODE_LEFT_BRACKET");
+ names.append(KEYCODE_RIGHT_BRACKET, "KEYCODE_RIGHT_BRACKET");
+ names.append(KEYCODE_BACKSLASH, "KEYCODE_BACKSLASH");
+ names.append(KEYCODE_SEMICOLON, "KEYCODE_SEMICOLON");
+ names.append(KEYCODE_APOSTROPHE, "KEYCODE_APOSTROPHE");
+ names.append(KEYCODE_SLASH, "KEYCODE_SLASH");
+ names.append(KEYCODE_AT, "KEYCODE_AT");
+ names.append(KEYCODE_NUM, "KEYCODE_NUM");
+ names.append(KEYCODE_HEADSETHOOK, "KEYCODE_HEADSETHOOK");
+ names.append(KEYCODE_FOCUS, "KEYCODE_FOCUS");
+ names.append(KEYCODE_PLUS, "KEYCODE_PLUS");
+ names.append(KEYCODE_MENU, "KEYCODE_MENU");
+ names.append(KEYCODE_NOTIFICATION, "KEYCODE_NOTIFICATION");
+ names.append(KEYCODE_SEARCH, "KEYCODE_SEARCH");
+ names.append(KEYCODE_MEDIA_PLAY_PAUSE, "KEYCODE_MEDIA_PLAY_PAUSE");
+ names.append(KEYCODE_MEDIA_STOP, "KEYCODE_MEDIA_STOP");
+ names.append(KEYCODE_MEDIA_NEXT, "KEYCODE_MEDIA_NEXT");
+ names.append(KEYCODE_MEDIA_PREVIOUS, "KEYCODE_MEDIA_PREVIOUS");
+ names.append(KEYCODE_MEDIA_REWIND, "KEYCODE_MEDIA_REWIND");
+ names.append(KEYCODE_MEDIA_FAST_FORWARD, "KEYCODE_MEDIA_FAST_FORWARD");
+ names.append(KEYCODE_MUTE, "KEYCODE_MUTE");
+ names.append(KEYCODE_PAGE_UP, "KEYCODE_PAGE_UP");
+ names.append(KEYCODE_PAGE_DOWN, "KEYCODE_PAGE_DOWN");
+ names.append(KEYCODE_PICTSYMBOLS, "KEYCODE_PICTSYMBOLS");
+ names.append(KEYCODE_SWITCH_CHARSET, "KEYCODE_SWITCH_CHARSET");
+ names.append(KEYCODE_BUTTON_A, "KEYCODE_BUTTON_A");
+ names.append(KEYCODE_BUTTON_B, "KEYCODE_BUTTON_B");
+ names.append(KEYCODE_BUTTON_C, "KEYCODE_BUTTON_C");
+ names.append(KEYCODE_BUTTON_X, "KEYCODE_BUTTON_X");
+ names.append(KEYCODE_BUTTON_Y, "KEYCODE_BUTTON_Y");
+ names.append(KEYCODE_BUTTON_Z, "KEYCODE_BUTTON_Z");
+ names.append(KEYCODE_BUTTON_L1, "KEYCODE_BUTTON_L1");
+ names.append(KEYCODE_BUTTON_R1, "KEYCODE_BUTTON_R1");
+ names.append(KEYCODE_BUTTON_L2, "KEYCODE_BUTTON_L2");
+ names.append(KEYCODE_BUTTON_R2, "KEYCODE_BUTTON_R2");
+ names.append(KEYCODE_BUTTON_THUMBL, "KEYCODE_BUTTON_THUMBL");
+ names.append(KEYCODE_BUTTON_THUMBR, "KEYCODE_BUTTON_THUMBR");
+ names.append(KEYCODE_BUTTON_START, "KEYCODE_BUTTON_START");
+ names.append(KEYCODE_BUTTON_SELECT, "KEYCODE_BUTTON_SELECT");
+ names.append(KEYCODE_BUTTON_MODE, "KEYCODE_BUTTON_MODE");
+ names.append(KEYCODE_ESCAPE, "KEYCODE_ESCAPE");
+ names.append(KEYCODE_FORWARD_DEL, "KEYCODE_FORWARD_DEL");
+ names.append(KEYCODE_CTRL_LEFT, "KEYCODE_CTRL_LEFT");
+ names.append(KEYCODE_CTRL_RIGHT, "KEYCODE_CTRL_RIGHT");
+ names.append(KEYCODE_CAPS_LOCK, "KEYCODE_CAPS_LOCK");
+ names.append(KEYCODE_SCROLL_LOCK, "KEYCODE_SCROLL_LOCK");
+ names.append(KEYCODE_META_LEFT, "KEYCODE_META_LEFT");
+ names.append(KEYCODE_META_RIGHT, "KEYCODE_META_RIGHT");
+ names.append(KEYCODE_FUNCTION, "KEYCODE_FUNCTION");
+ names.append(KEYCODE_SYSRQ, "KEYCODE_SYSRQ");
+ names.append(KEYCODE_BREAK, "KEYCODE_BREAK");
+ names.append(KEYCODE_MOVE_HOME, "KEYCODE_MOVE_HOME");
+ names.append(KEYCODE_MOVE_END, "KEYCODE_MOVE_END");
+ names.append(KEYCODE_INSERT, "KEYCODE_INSERT");
+ names.append(KEYCODE_FORWARD, "KEYCODE_FORWARD");
+ names.append(KEYCODE_MEDIA_PLAY, "KEYCODE_MEDIA_PLAY");
+ names.append(KEYCODE_MEDIA_PAUSE, "KEYCODE_MEDIA_PAUSE");
+ names.append(KEYCODE_MEDIA_CLOSE, "KEYCODE_MEDIA_CLOSE");
+ names.append(KEYCODE_MEDIA_EJECT, "KEYCODE_MEDIA_EJECT");
+ names.append(KEYCODE_MEDIA_RECORD, "KEYCODE_MEDIA_RECORD");
+ names.append(KEYCODE_F1, "KEYCODE_F1");
+ names.append(KEYCODE_F2, "KEYCODE_F2");
+ names.append(KEYCODE_F3, "KEYCODE_F3");
+ names.append(KEYCODE_F4, "KEYCODE_F4");
+ names.append(KEYCODE_F5, "KEYCODE_F5");
+ names.append(KEYCODE_F6, "KEYCODE_F6");
+ names.append(KEYCODE_F7, "KEYCODE_F7");
+ names.append(KEYCODE_F8, "KEYCODE_F8");
+ names.append(KEYCODE_F9, "KEYCODE_F9");
+ names.append(KEYCODE_F10, "KEYCODE_F10");
+ names.append(KEYCODE_F11, "KEYCODE_F11");
+ names.append(KEYCODE_F12, "KEYCODE_F12");
+ names.append(KEYCODE_NUM_LOCK, "KEYCODE_NUM_LOCK");
+ names.append(KEYCODE_NUMPAD_0, "KEYCODE_NUMPAD_0");
+ names.append(KEYCODE_NUMPAD_1, "KEYCODE_NUMPAD_1");
+ names.append(KEYCODE_NUMPAD_2, "KEYCODE_NUMPAD_2");
+ names.append(KEYCODE_NUMPAD_3, "KEYCODE_NUMPAD_3");
+ names.append(KEYCODE_NUMPAD_4, "KEYCODE_NUMPAD_4");
+ names.append(KEYCODE_NUMPAD_5, "KEYCODE_NUMPAD_5");
+ names.append(KEYCODE_NUMPAD_6, "KEYCODE_NUMPAD_6");
+ names.append(KEYCODE_NUMPAD_7, "KEYCODE_NUMPAD_7");
+ names.append(KEYCODE_NUMPAD_8, "KEYCODE_NUMPAD_8");
+ names.append(KEYCODE_NUMPAD_9, "KEYCODE_NUMPAD_9");
+ names.append(KEYCODE_NUMPAD_DIVIDE, "KEYCODE_NUMPAD_DIVIDE");
+ names.append(KEYCODE_NUMPAD_MULTIPLY, "KEYCODE_NUMPAD_MULTIPLY");
+ names.append(KEYCODE_NUMPAD_SUBTRACT, "KEYCODE_NUMPAD_SUBTRACT");
+ names.append(KEYCODE_NUMPAD_ADD, "KEYCODE_NUMPAD_ADD");
+ names.append(KEYCODE_NUMPAD_DOT, "KEYCODE_NUMPAD_DOT");
+ names.append(KEYCODE_NUMPAD_COMMA, "KEYCODE_NUMPAD_COMMA");
+ names.append(KEYCODE_NUMPAD_ENTER, "KEYCODE_NUMPAD_ENTER");
+ names.append(KEYCODE_NUMPAD_EQUALS, "KEYCODE_NUMPAD_EQUALS");
+ names.append(KEYCODE_NUMPAD_LEFT_PAREN, "KEYCODE_NUMPAD_LEFT_PAREN");
+ names.append(KEYCODE_NUMPAD_RIGHT_PAREN, "KEYCODE_NUMPAD_RIGHT_PAREN");
+ names.append(KEYCODE_VOLUME_MUTE, "KEYCODE_VOLUME_MUTE");
+ names.append(KEYCODE_INFO, "KEYCODE_INFO");
+ names.append(KEYCODE_CHANNEL_UP, "KEYCODE_CHANNEL_UP");
+ names.append(KEYCODE_CHANNEL_DOWN, "KEYCODE_CHANNEL_DOWN");
+ names.append(KEYCODE_ZOOM_IN, "KEYCODE_ZOOM_IN");
+ names.append(KEYCODE_ZOOM_OUT, "KEYCODE_ZOOM_OUT");
+ names.append(KEYCODE_TV, "KEYCODE_TV");
+ names.append(KEYCODE_WINDOW, "KEYCODE_WINDOW");
+ names.append(KEYCODE_GUIDE, "KEYCODE_GUIDE");
+ names.append(KEYCODE_DVR, "KEYCODE_DVR");
+ names.append(KEYCODE_BOOKMARK, "KEYCODE_BOOKMARK");
+ names.append(KEYCODE_CAPTIONS, "KEYCODE_CAPTIONS");
+ names.append(KEYCODE_SETTINGS, "KEYCODE_SETTINGS");
+ names.append(KEYCODE_TV_POWER, "KEYCODE_TV_POWER");
+ names.append(KEYCODE_TV_INPUT, "KEYCODE_TV_INPUT");
+ names.append(KEYCODE_STB_INPUT, "KEYCODE_STB_INPUT");
+ names.append(KEYCODE_STB_POWER, "KEYCODE_STB_POWER");
+ names.append(KEYCODE_AVR_POWER, "KEYCODE_AVR_POWER");
+ names.append(KEYCODE_AVR_INPUT, "KEYCODE_AVR_INPUT");
+ names.append(KEYCODE_PROG_RED, "KEYCODE_PROG_RED");
+ names.append(KEYCODE_PROG_GREEN, "KEYCODE_PROG_GREEN");
+ names.append(KEYCODE_PROG_YELLOW, "KEYCODE_PROG_YELLOW");
+ names.append(KEYCODE_PROG_BLUE, "KEYCODE_PROG_BLUE");
+ names.append(KEYCODE_APP_SWITCH, "KEYCODE_APP_SWITCH");
+ names.append(KEYCODE_BUTTON_1, "KEYCODE_BUTTON_1");
+ names.append(KEYCODE_BUTTON_2, "KEYCODE_BUTTON_2");
+ names.append(KEYCODE_BUTTON_3, "KEYCODE_BUTTON_3");
+ names.append(KEYCODE_BUTTON_4, "KEYCODE_BUTTON_4");
+ names.append(KEYCODE_BUTTON_5, "KEYCODE_BUTTON_5");
+ names.append(KEYCODE_BUTTON_6, "KEYCODE_BUTTON_6");
+ names.append(KEYCODE_BUTTON_7, "KEYCODE_BUTTON_7");
+ names.append(KEYCODE_BUTTON_8, "KEYCODE_BUTTON_8");
+ names.append(KEYCODE_BUTTON_9, "KEYCODE_BUTTON_9");
+ names.append(KEYCODE_BUTTON_10, "KEYCODE_BUTTON_10");
+ names.append(KEYCODE_BUTTON_11, "KEYCODE_BUTTON_11");
+ names.append(KEYCODE_BUTTON_12, "KEYCODE_BUTTON_12");
+ names.append(KEYCODE_BUTTON_13, "KEYCODE_BUTTON_13");
+ names.append(KEYCODE_BUTTON_14, "KEYCODE_BUTTON_14");
+ names.append(KEYCODE_BUTTON_15, "KEYCODE_BUTTON_15");
+ names.append(KEYCODE_BUTTON_16, "KEYCODE_BUTTON_16");
};
// Symbolic names of all metakeys in bit order from least significant to most significant.
@@ -1250,14 +1252,7 @@ public class KeyEvent extends InputEvent implements Parcelable {
}
static {
- if (META_SYMBOLIC_NAMES.length != 32) {
- throw new IllegalStateException(
- "META_SYMBOLIC_NAMES array should contain exactly 32 entries.");
- }
- if (KEYCODE_SYMBOLIC_NAMES.length != LAST_KEYCODE + 1) {
- throw new IllegalStateException(
- "KEYCODE_SYMBOLIC_NAMES array is out of sync with the keycode constants.");
- }
+ populateKeycodeSymbolicNames();
}
private KeyEvent() {
@@ -1653,6 +1648,49 @@ public class KeyEvent extends InputEvent implements Parcelable {
return native_hasDefaultAction(mKeyCode);
}
+ /**
+ * Returns true if the specified keycode is a gamepad button.
+ * @return True if the keycode is a gamepad button, such as {@link #KEYCODE_BUTTON_A}.
+ */
+ public static final boolean isGamepadButton(int keyCode) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_BUTTON_A:
+ case KeyEvent.KEYCODE_BUTTON_B:
+ case KeyEvent.KEYCODE_BUTTON_C:
+ case KeyEvent.KEYCODE_BUTTON_X:
+ case KeyEvent.KEYCODE_BUTTON_Y:
+ case KeyEvent.KEYCODE_BUTTON_Z:
+ case KeyEvent.KEYCODE_BUTTON_L1:
+ case KeyEvent.KEYCODE_BUTTON_R1:
+ case KeyEvent.KEYCODE_BUTTON_L2:
+ case KeyEvent.KEYCODE_BUTTON_R2:
+ case KeyEvent.KEYCODE_BUTTON_THUMBL:
+ case KeyEvent.KEYCODE_BUTTON_THUMBR:
+ case KeyEvent.KEYCODE_BUTTON_START:
+ case KeyEvent.KEYCODE_BUTTON_SELECT:
+ case KeyEvent.KEYCODE_BUTTON_MODE:
+ case KeyEvent.KEYCODE_BUTTON_1:
+ case KeyEvent.KEYCODE_BUTTON_2:
+ case KeyEvent.KEYCODE_BUTTON_3:
+ case KeyEvent.KEYCODE_BUTTON_4:
+ case KeyEvent.KEYCODE_BUTTON_5:
+ case KeyEvent.KEYCODE_BUTTON_6:
+ case KeyEvent.KEYCODE_BUTTON_7:
+ case KeyEvent.KEYCODE_BUTTON_8:
+ case KeyEvent.KEYCODE_BUTTON_9:
+ case KeyEvent.KEYCODE_BUTTON_10:
+ case KeyEvent.KEYCODE_BUTTON_11:
+ case KeyEvent.KEYCODE_BUTTON_12:
+ case KeyEvent.KEYCODE_BUTTON_13:
+ case KeyEvent.KEYCODE_BUTTON_14:
+ case KeyEvent.KEYCODE_BUTTON_15:
+ case KeyEvent.KEYCODE_BUTTON_16:
+ return true;
+ default:
+ return false;
+ }
+ }
+
/** {@inheritDoc} */
@Override
public final int getDeviceId() {
@@ -2554,7 +2592,7 @@ public class KeyEvent extends InputEvent implements Parcelable {
/**
* Returns a string that represents the symbolic name of the specified action
- * such as "ACTION_DOWN", or "35" (if unknown).
+ * such as "ACTION_DOWN", or an equivalent numeric constant such as "35" if unknown.
*
* @param action The action.
* @return The symbolic name of the specified action.
@@ -2575,52 +2613,51 @@ public class KeyEvent extends InputEvent implements Parcelable {
/**
* Returns a string that represents the symbolic name of the specified keycode
- * such as "KEYCODE_A", "KEYCODE_DPAD_UP", or "1001" (if unknown).
+ * such as "KEYCODE_A", "KEYCODE_DPAD_UP", or an equivalent numeric constant
+ * such as "1001" if unknown.
*
* @param keyCode The key code.
* @return The symbolic name of the specified keycode.
*
* @see KeyCharacterMap#getDisplayLabel
- * @hide
*/
public static String keyCodeToString(int keyCode) {
- if (keyCode >= 0 && keyCode < KEYCODE_SYMBOLIC_NAMES.length) {
- return KEYCODE_SYMBOLIC_NAMES[keyCode];
- }
- return Integer.toString(keyCode);
+ String symbolicName = KEYCODE_SYMBOLIC_NAMES.get(keyCode);
+ return symbolicName != null ? symbolicName : Integer.toString(keyCode);
}
/**
- * Gets a keycode by its symbolic name such as "KEYCODE_A" or "1001" (if unknown).
+ * Gets a keycode by its symbolic name such as "KEYCODE_A" or an equivalent
+ * numeric constant such as "1001".
*
* @param symbolicName The symbolic name of the keycode.
- * @return The keycode or -1 if not found.
+ * @return The keycode or {@link #KEYCODE_UNKNOWN} if not found.
* @see #keycodeToString
- * @hide
*/
public static int keyCodeFromString(String symbolicName) {
if (symbolicName == null) {
throw new IllegalArgumentException("symbolicName must not be null");
}
- final int count = KEYCODE_SYMBOLIC_NAMES.length;
+ final int count = KEYCODE_SYMBOLIC_NAMES.size();
for (int i = 0; i < count; i++) {
- if (symbolicName.equals(KEYCODE_SYMBOLIC_NAMES[i])) {
+ if (symbolicName.equals(KEYCODE_SYMBOLIC_NAMES.valueAt(i))) {
return i;
}
}
try {
- return Integer.parseInt(symbolicName,10);
+ return Integer.parseInt(symbolicName, 10);
} catch (NumberFormatException ex) {
- return -1;
+ return KEYCODE_UNKNOWN;
}
}
/**
* Returns a string that represents the symbolic name of the specified combined meta
* key modifier state flags such as "0", "META_SHIFT_ON",
- * "META_ALT_ON|META_SHIFT_ON" or "0x10000000" (if unknown).
+ * "META_ALT_ON|META_SHIFT_ON" or an equivalent numeric constant such as "0x10000000"
+ * if unknown.
*
* @param metaState The meta state.
* @return The symbolic name of the specified combined meta state flags.
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 6673be2bbd3c..cc37a28f62cd 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -20,6 +20,7 @@ import android.graphics.Matrix;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
+import android.util.SparseArray;
/**
* Object used to report movement (mouse, pen, finger, trackball) events. This
@@ -156,7 +157,15 @@ public final class MotionEvent extends InputEvent implements Parcelable {
* {@link #ACTION_POINTER_ID_MASK} indicate which pointer changed.
*/
public static final int ACTION_POINTER_UP = 6;
-
+
+ /**
+ * Constant for {@link #getAction}: A change happened but the pointer
+ * is not down (unlike {@link #ACTION_MOVE}). The motion contains the most
+ * recent point, as well as any intermediate points since the last
+ * hover move event.
+ */
+ public static final int ACTION_HOVER_MOVE = 7;
+
/**
* Bits in the action code that represent a pointer index, used with
* {@link #ACTION_POINTER_DOWN} and {@link #ACTION_POINTER_UP}. Shifting
@@ -263,10 +272,21 @@ public final class MotionEvent extends InputEvent implements Parcelable {
/**
* Constant used to identify the X axis of a motion event.
- *
- * The interpretation of the X axis varies by input source.
- * It may represent the X position of the center of the touch contact area,
- * a relative horizontal displacement of a trackball or joystick, or something else.
+ * <p>
+ * <ul>
+ * <li>For a touch screen, reports the absolute X screen position of the center of
+ * the touch contact area. The units are display pixels.
+ * <li>For a touch pad, reports the absolute X surface position of the center of the touch
+ * contact area. The units are device-dependent; use {@link InputDevice#getMotionRange(int)}
+ * to query the effective range of values.
+ * <li>For a mouse, reports the absolute X screen position of the mouse pointer.
+ * The units are display pixels.
+ * <li>For a trackball, reports the relative horizontal displacement of the trackball.
+ * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+ * <li>For a joystick, reports the absolute X position of the joystick.
+ * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+ * </ul>
+ * </p>
*
* @see #getX(int)
* @see #getHistoricalX(int, int)
@@ -277,10 +297,21 @@ public final class MotionEvent extends InputEvent implements Parcelable {
/**
* Constant used to identify the Y axis of a motion event.
- *
- * The interpretation of the Y axis varies by input source.
- * It may represent the Y position of the center of the touch contact area,
- * a relative vertical displacement of a trackball or joystick, or something else.
+ * <p>
+ * <ul>
+ * <li>For a touch screen, reports the absolute Y screen position of the center of
+ * the touch contact area. The units are display pixels.
+ * <li>For a touch pad, reports the absolute Y surface position of the center of the touch
+ * contact area. The units are device-dependent; use {@link InputDevice#getMotionRange(int)}
+ * to query the effective range of values.
+ * <li>For a mouse, reports the absolute Y screen position of the mouse pointer.
+ * The units are display pixels.
+ * <li>For a trackball, reports the relative vertical displacement of the trackball.
+ * The value is normalized to a range from -1.0 (up) to 1.0 (down).
+ * <li>For a joystick, reports the absolute Y position of the joystick.
+ * The value is normalized to a range from -1.0 (up or far) to 1.0 (down or near).
+ * </ul>
+ * </p>
*
* @see #getY(int)
* @see #getHistoricalY(int, int)
@@ -291,12 +322,18 @@ public final class MotionEvent extends InputEvent implements Parcelable {
/**
* Constant used to identify the Pressure axis of a motion event.
- *
- * The pressure axis specifies a normalized value that describes the approximate
- * pressure applied to the device by a finger or other tool.
- * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
- * although values higher than 1 may be generated depending on the calibration of
- * the input device.
+ * <p>
+ * <ul>
+ * <li>For a touch screen or touch pad, reports the approximate pressure applied to the surface
+ * by a finger or other tool. The value is normalized to a range from
+ * 0 (no pressure at all) to 1 (normal pressure), although values higher than 1
+ * may be generated depending on the calibration of the input device.
+ * <li>For a trackball, the value is set to 1 if the trackball button is pressed
+ * or 0 otherwise.
+ * <li>For a mouse, the value is set to 1 if the primary mouse button is pressed
+ * or 0 otherwise.
+ * </ul>
+ * </p>
*
* @see #getPressure(int)
* @see #getHistoricalPressure(int, int)
@@ -307,17 +344,16 @@ public final class MotionEvent extends InputEvent implements Parcelable {
/**
* Constant used to identify the Size axis of a motion event.
- *
- * The size axis specifies a normalized value that describes the approximate size
- * of the pointer touch area in relation to the maximum detectable size for the device.
- * It represents some approximation of the area of the screen being
- * pressed; the actual value in pixels corresponding to the
- * touch is normalized with the device specific range of values
- * and scaled to a value between 0 and 1. The value of size can be used to
- * determine fat touch events.
- *
- * To obtain calibrated size information in terms of pixels, use
- * {@link #AXIS_TOUCH_MAJOR} or {@link #AXIS_TOOL_MAJOR} instead.
+ * <p>
+ * <ul>
+ * <li>For a touch screen or touch pad, reports the approximate size of the contact area in
+ * relation to the maximum detectable size for the device. The value is normalized
+ * to a range from 0 (smallest detectable size) to 1 (largest detectable size),
+ * although it is not a linear scale. This value is of limited use.
+ * To obtain calibrated size information, use
+ * {@link #AXIS_TOUCH_MAJOR} or {@link #AXIS_TOOL_MAJOR}.
+ * </ul>
+ * </p>
*
* @see #getSize(int)
* @see #getHistoricalSize(int, int)
@@ -328,11 +364,17 @@ public final class MotionEvent extends InputEvent implements Parcelable {
/**
* Constant used to identify the TouchMajor axis of a motion event.
- *
- * The touch major axis specifies the length of the major axis of an ellipse that
- * describes the touch area at the point of contact.
- * If the device is a touch screen, the length is reported in pixels, otherwise it is
- * reported in device-specific units.
+ * <p>
+ * <ul>
+ * <li>For a touch screen, reports the length of the major axis of an ellipse that
+ * represents the touch area at the point of contact.
+ * The units are display pixels.
+ * <li>For a touch pad, reports the length of the major axis of an ellipse that
+ * represents the touch area at the point of contact.
+ * The units are device-dependent; use {@link InputDevice#getMotionRange(int)}
+ * to query the effective range of values.
+ * </ul>
+ * </p>
*
* @see #getTouchMajor(int)
* @see #getHistoricalTouchMajor(int, int)
@@ -343,11 +385,19 @@ public final class MotionEvent extends InputEvent implements Parcelable {
/**
* Constant used to identify the TouchMinor axis of a motion event.
- *
- * The touch major axis specifies the length of the minor axis of an ellipse that
- * describes the touch area at the point of contact.
- * If the device is a touch screen, the length is reported in pixels, otherwise it is
- * reported in device-specific units.
+ * <p>
+ * <ul>
+ * <li>For a touch screen, reports the length of the minor axis of an ellipse that
+ * represents the touch area at the point of contact.
+ * The units are display pixels.
+ * <li>For a touch pad, reports the length of the minor axis of an ellipse that
+ * represents the touch area at the point of contact.
+ * The units are device-dependent; use {@link InputDevice#getMotionRange(int)}
+ * to query the effective range of values.
+ * </ul>
+ * </p><p>
+ * When the touch is circular, the major and minor axis lengths will be equal to one another.
+ * </p>
*
* @see #getTouchMinor(int)
* @see #getHistoricalTouchMinor(int, int)
@@ -358,13 +408,21 @@ public final class MotionEvent extends InputEvent implements Parcelable {
/**
* Constant used to identify the ToolMajor axis of a motion event.
- *
- * The tool major axis specifies the length of the major axis of an ellipse that
- * describes the size of the approaching tool.
- * The tool area represents the estimated size of the finger or pen that is
- * touching the device independent of its actual touch area at the point of contact.
- * If the device is a touch screen, the length is reported in pixels, otherwise it is
- * reported in device-specific units.
+ * <p>
+ * <ul>
+ * <li>For a touch screen, reports the length of the major axis of an ellipse that
+ * represents the size of the approaching finger or tool used to make contact.
+ * <li>For a touch pad, reports the length of the major axis of an ellipse that
+ * represents the size of the approaching finger or tool used to make contact.
+ * The units are device-dependent; use {@link InputDevice#getMotionRange(int)}
+ * to query the effective range of values.
+ * </ul>
+ * </p><p>
+ * When the touch is circular, the major and minor axis lengths will be equal to one another.
+ * </p><p>
+ * The tool size may be larger than the touch size since the tool may not be fully
+ * in contact with the touch sensor.
+ * </p>
*
* @see #getToolMajor(int)
* @see #getHistoricalToolMajor(int, int)
@@ -375,13 +433,21 @@ public final class MotionEvent extends InputEvent implements Parcelable {
/**
* Constant used to identify the ToolMinor axis of a motion event.
- *
- * The tool minor axis specifies the length of the major axis of an ellipse that
- * describes the size of the approaching tool.
- * The tool area represents the estimated size of the finger or pen that is
- * touching the device independent of its actual touch area at the point of contact.
- * If the device is a touch screen, the length is reported in pixels, otherwise it is
- * reported in device-specific units.
+ * <p>
+ * <ul>
+ * <li>For a touch screen, reports the length of the minor axis of an ellipse that
+ * represents the size of the approaching finger or tool used to make contact.
+ * <li>For a touch pad, reports the length of the minor axis of an ellipse that
+ * represents the size of the approaching finger or tool used to make contact.
+ * The units are device-dependent; use {@link InputDevice#getMotionRange(int)}
+ * to query the effective range of values.
+ * </ul>
+ * </p><p>
+ * When the touch is circular, the major and minor axis lengths will be equal to one another.
+ * </p><p>
+ * The tool size may be larger than the touch size since the tool may not be fully
+ * in contact with the touch sensor.
+ * </p>
*
* @see #getToolMinor(int)
* @see #getHistoricalToolMinor(int, int)
@@ -392,15 +458,18 @@ public final class MotionEvent extends InputEvent implements Parcelable {
/**
* Constant used to identify the Orientation axis of a motion event.
- *
- * The orientation axis specifies the orientation of the touch area and tool area in
- * radians clockwise from vertical relative to the vertical plane of the device.
- * An angle of 0 degrees indicates that the major axis of contact is oriented
+ * <p>
+ * <ul>
+ * <li>For a touch screen or touch pad, reports the orientation of the finger
+ * or tool in radians relative to the vertical plane of the device.
+ * An angle of 0 radians indicates that the major axis of contact is oriented
* upwards, is perfectly circular or is of unknown orientation. A positive angle
* indicates that the major axis of contact is oriented to the right. A negative angle
* indicates that the major axis of contact is oriented to the left.
* The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
* (finger pointing fully right).
+ * </ul>
+ * </p>
*
* @see #getOrientation(int)
* @see #getHistoricalOrientation(int, int)
@@ -409,6 +478,399 @@ public final class MotionEvent extends InputEvent implements Parcelable {
*/
public static final int AXIS_ORIENTATION = 8;
+ /**
+ * Constant used to identify the Vertical Scroll axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a mouse, reports the relative movement of the vertical scroll wheel.
+ * The value is normalized to a range from -1.0 (up) to 1.0 (down).
+ * </ul>
+ * </p><p>
+ * This axis should be used to scroll views vertically.
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_VSCROLL = 9;
+
+ /**
+ * Constant used to identify the Horizontal Scroll axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a mouse, reports the relative movement of the horizontal scroll wheel.
+ * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+ * </ul>
+ * </p><p>
+ * This axis should be used to scroll views horizontally.
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_HSCROLL = 10;
+
+ /**
+ * Constant used to identify the Z axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute Z position of the joystick.
+ * The value is normalized to a range from -1.0 (high) to 1.0 (low).
+ * <em>On game pads with two analog joysticks, this axis is often reinterpreted
+ * to report the absolute X position of the second joystick instead.</em>
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_Z = 11;
+
+ /**
+ * Constant used to identify the X Rotation axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute rotation angle about the X axis.
+ * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_RX = 12;
+
+ /**
+ * Constant used to identify the Y Rotation axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute rotation angle about the Y axis.
+ * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_RY = 13;
+
+ /**
+ * Constant used to identify the Z Rotation axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute rotation angle about the Z axis.
+ * The value is normalized to a range from -1.0 (counter-clockwise) to 1.0 (clockwise).
+ * <em>On game pads with two analog joysticks, this axis is often reinterpreted
+ * to report the absolute Y position of the second joystick instead.</em>
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_RZ = 14;
+
+ /**
+ * Constant used to identify the Hat X axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute X position of the directional hat control.
+ * The value is normalized to a range from -1.0 (left) to 1.0 (right).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_HAT_X = 15;
+
+ /**
+ * Constant used to identify the Hat Y axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute Y position of the directional hat control.
+ * The value is normalized to a range from -1.0 (up) to 1.0 (down).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_HAT_Y = 16;
+
+ /**
+ * Constant used to identify the Left Trigger axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute position of the left trigger control.
+ * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_LTRIGGER = 17;
+
+ /**
+ * Constant used to identify the Right Trigger axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>For a joystick, reports the absolute position of the right trigger control.
+ * The value is normalized to a range from 0.0 (released) to 1.0 (fully pressed).
+ * </ul>
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_RTRIGGER = 18;
+
+ /**
+ * Constant used to identify the Generic 1 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_1 = 32;
+
+ /**
+ * Constant used to identify the Generic 2 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_2 = 33;
+
+ /**
+ * Constant used to identify the Generic 3 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_3 = 34;
+
+ /**
+ * Constant used to identify the Generic 4 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_4 = 35;
+
+ /**
+ * Constant used to identify the Generic 5 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_5 = 36;
+
+ /**
+ * Constant used to identify the Generic 6 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_6 = 37;
+
+ /**
+ * Constant used to identify the Generic 7 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_7 = 38;
+
+ /**
+ * Constant used to identify the Generic 8 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_8 = 39;
+
+ /**
+ * Constant used to identify the Generic 9 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_9 = 40;
+
+ /**
+ * Constant used to identify the Generic 10 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_10 = 41;
+
+ /**
+ * Constant used to identify the Generic 11 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_11 = 42;
+
+ /**
+ * Constant used to identify the Generic 12 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_12 = 43;
+
+ /**
+ * Constant used to identify the Generic 13 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_13 = 44;
+
+ /**
+ * Constant used to identify the Generic 14 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_14 = 45;
+
+ /**
+ * Constant used to identify the Generic 15 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_15 = 46;
+
+ /**
+ * Constant used to identify the Generic 16 axis of a motion event.
+ * The interpretation of a generic axis is device-specific.
+ *
+ * @see #getAxisValue(int, int)
+ * @see #getHistoricalAxisValue(int, int, int)
+ * @see MotionEvent.PointerCoords#getAxisValue(int)
+ * @see InputDevice#getMotionRange
+ */
+ public static final int AXIS_GENERIC_16 = 47;
+
+ // NOTE: If you add a new axis here you must also add it to:
+ // native/include/android/input.h
+ // frameworks/base/include/ui/KeycodeLabels.h
+
+ // Symbolic names of all axes.
+ private static final SparseArray<String> AXIS_SYMBOLIC_NAMES = new SparseArray<String>();
+ private static void populateAxisSymbolicNames() {
+ SparseArray<String> names = AXIS_SYMBOLIC_NAMES;
+ names.append(AXIS_X, "AXIS_X");
+ names.append(AXIS_Y, "AXIS_Y");
+ names.append(AXIS_PRESSURE, "AXIS_PRESSURE");
+ names.append(AXIS_SIZE, "AXIS_SIZE");
+ names.append(AXIS_TOUCH_MAJOR, "AXIS_TOUCH_MAJOR");
+ names.append(AXIS_TOUCH_MINOR, "AXIS_TOUCH_MINOR");
+ names.append(AXIS_TOOL_MAJOR, "AXIS_TOOL_MAJOR");
+ names.append(AXIS_TOOL_MINOR, "AXIS_TOOL_MINOR");
+ names.append(AXIS_ORIENTATION, "AXIS_ORIENTATION");
+ names.append(AXIS_VSCROLL, "AXIS_VSCROLL");
+ names.append(AXIS_HSCROLL, "AXIS_HSCROLL");
+ names.append(AXIS_Z, "AXIS_Z");
+ names.append(AXIS_RX, "AXIS_RX");
+ names.append(AXIS_RY, "AXIS_RY");
+ names.append(AXIS_RZ, "AXIS_RZ");
+ names.append(AXIS_HAT_X, "AXIS_HAT_X");
+ names.append(AXIS_HAT_Y, "AXIS_HAT_Y");
+ names.append(AXIS_LTRIGGER, "AXIS_LTRIGGER");
+ names.append(AXIS_RTRIGGER, "AXIS_RTRIGGER");
+ names.append(AXIS_GENERIC_1, "AXIS_GENERIC_1");
+ names.append(AXIS_GENERIC_2, "AXIS_GENERIC_2");
+ names.append(AXIS_GENERIC_3, "AXIS_GENERIC_3");
+ names.append(AXIS_GENERIC_4, "AXIS_GENERIC_4");
+ names.append(AXIS_GENERIC_5, "AXIS_GENERIC_5");
+ names.append(AXIS_GENERIC_6, "AXIS_GENERIC_6");
+ names.append(AXIS_GENERIC_7, "AXIS_GENERIC_7");
+ names.append(AXIS_GENERIC_8, "AXIS_GENERIC_8");
+ names.append(AXIS_GENERIC_9, "AXIS_GENERIC_9");
+ names.append(AXIS_GENERIC_10, "AXIS_GENERIC_10");
+ names.append(AXIS_GENERIC_11, "AXIS_GENERIC_11");
+ names.append(AXIS_GENERIC_12, "AXIS_GENERIC_12");
+ names.append(AXIS_GENERIC_13, "AXIS_GENERIC_13");
+ names.append(AXIS_GENERIC_14, "AXIS_GENERIC_14");
+ names.append(AXIS_GENERIC_15, "AXIS_GENERIC_15");
+ names.append(AXIS_GENERIC_16, "AXIS_GENERIC_16");
+ }
+
+ static {
+ populateAxisSymbolicNames();
+ }
+
// Private value for history pos that obtains the current sample.
private static final int HISTORY_CURRENT = -0x80000000;
@@ -514,9 +976,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
* a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
* @param eventTime The the time (in ms) when this specific event was generated. This
* must be obtained from {@link SystemClock#uptimeMillis()}.
- * @param action The kind of action being performed -- one of either
- * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
- * {@link #ACTION_CANCEL}.
+ * @param action The kind of action being performed, such as {@link #ACTION_DOWN}.
* @param pointers The number of points that will be in this event.
* @param pointerIds An array of <em>pointers</em> values providing
* an identifier for each pointer.
@@ -555,9 +1015,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
* a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
* @param eventTime The the time (in ms) when this specific event was generated. This
* must be obtained from {@link SystemClock#uptimeMillis()}.
- * @param action The kind of action being performed -- one of either
- * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
- * {@link #ACTION_CANCEL}.
+ * @param action The kind of action being performed, such as {@link #ACTION_DOWN}.
* @param x The X coordinate of this event.
* @param y The Y coordinate of this event.
* @param pressure The current pressure of this event. The pressure generally
@@ -607,9 +1065,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
* a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
* @param eventTime The the time (in ms) when this specific event was generated. This
* must be obtained from {@link SystemClock#uptimeMillis()}.
- * @param action The kind of action being performed -- one of either
- * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
- * {@link #ACTION_CANCEL}.
+ * @param action The kind of action being performed, such as {@link #ACTION_DOWN}.
* @param pointers The number of pointers that are active in this event.
* @param x The X coordinate of this event.
* @param y The Y coordinate of this event.
@@ -651,9 +1107,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
* a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
* @param eventTime The the time (in ms) when this specific event was generated. This
* must be obtained from {@link SystemClock#uptimeMillis()}.
- * @param action The kind of action being performed -- one of either
- * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
- * {@link #ACTION_CANCEL}.
+ * @param action The kind of action being performed, such as {@link #ACTION_DOWN}.
* @param x The X coordinate of this event.
* @param y The Y coordinate of this event.
* @param metaState The state of any meta / modifier keys that were in effect when
@@ -748,23 +1202,20 @@ public final class MotionEvent extends InputEvent implements Parcelable {
}
/**
- * Return the kind of action being performed -- one of either
- * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
- * {@link #ACTION_CANCEL}. Consider using {@link #getActionMasked}
- * and {@link #getActionIndex} to retrieve the separate masked action
- * and pointer index.
+ * Return the kind of action being performed.
+ * Consider using {@link #getActionMasked} and {@link #getActionIndex} to retrieve
+ * the separate masked action and pointer index.
+ * @return The action, such as {@link #ACTION_DOWN} or
+ * the combination of {@link #ACTION_POINTER_DOWN} with a shifted pointer index.
*/
public final int getAction() {
return nativeGetAction(mNativePtr);
}
/**
- * Return the masked action being performed, without pointer index
- * information. May be any of the actions: {@link #ACTION_DOWN},
- * {@link #ACTION_MOVE}, {@link #ACTION_UP}, {@link #ACTION_CANCEL},
- * {@link #ACTION_POINTER_DOWN}, or {@link #ACTION_POINTER_UP}.
- * Use {@link #getActionIndex} to return the index associated with
- * pointer actions.
+ * Return the masked action being performed, without pointer index information.
+ * Use {@link #getActionIndex} to return the index associated with pointer actions.
+ * @return The action, such as {@link #ACTION_DOWN} or {@link #ACTION_POINTER_DOWN}.
*/
public final int getActionMasked() {
return nativeGetAction(mNativePtr) & ACTION_MASK;
@@ -773,10 +1224,12 @@ public final class MotionEvent extends InputEvent implements Parcelable {
/**
* For {@link #ACTION_POINTER_DOWN} or {@link #ACTION_POINTER_UP}
* as returned by {@link #getActionMasked}, this returns the associated
- * pointer index. The index may be used with {@link #getPointerId(int)},
+ * pointer index.
+ * The index may be used with {@link #getPointerId(int)},
* {@link #getX(int)}, {@link #getY(int)}, {@link #getPressure(int)},
* and {@link #getSize(int)} to get information about the pointer that has
* gone down or up.
+ * @return The index associated with the action.
*/
public final int getActionIndex() {
return (nativeGetAction(mNativePtr) & ACTION_POINTER_INDEX_MASK)
@@ -1081,7 +1534,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
* Returns the orientation of the touch area and tool area in radians clockwise from vertical
* for the given pointer <em>index</em> (use {@link #getPointerId(int)} to find the pointer
* identifier for this index).
- * An angle of 0 degrees indicates that the major axis of contact is oriented
+ * An angle of 0 radians indicates that the major axis of contact is oriented
* upwards, is perfectly circular or is of unknown orientation. A positive angle
* indicates that the major axis of contact is oriented to the right. A negative angle
* indicates that the major axis of contact is oriented to the left.
@@ -1641,7 +2094,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
* current location, position and size is updated to the new values.
* The current values in the event are added to a list of historical values.
*
- * Only applies to {@link #ACTION_MOVE} events.
+ * Only applies to {@link #ACTION_MOVE} or {@link #ACTION_HOVER_MOVE} events.
*
* @param eventTime The time stamp (in ms) for this data.
* @param x The new X position.
@@ -1668,7 +2121,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
* current location, position and size is updated to the new values.
* The current values in the event are added to a list of historical values.
*
- * Only applies to {@link #ACTION_MOVE} events.
+ * Only applies to {@link #ACTION_MOVE} or {@link #ACTION_HOVER_MOVE} events.
*
* @param eventTime The time stamp (in ms) for this data.
* @param pointerCoords The new pointer coordinates.
@@ -1723,6 +2176,8 @@ public final class MotionEvent extends InputEvent implements Parcelable {
return "ACTION_CANCEL";
case ACTION_MOVE:
return "ACTION_MOVE";
+ case ACTION_HOVER_MOVE:
+ return "ACTION_HOVER_MOVE";
}
int index = (action & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT;
switch (action & ACTION_MASK) {
@@ -1737,34 +2192,40 @@ public final class MotionEvent extends InputEvent implements Parcelable {
/**
* Returns a string that represents the symbolic name of the specified axis
- * such as "AXIS_X" or an equivalent numeric constants such as "42" if unknown.
+ * such as "AXIS_X" or an equivalent numeric constant such as "42" if unknown.
*
* @param axis The axis
* @return The symbolic name of the specified axis.
- * @hide
*/
public static String axisToString(int axis) {
- switch (axis) {
- case AXIS_X:
- return "AXIS_X";
- case AXIS_Y:
- return "AXIS_Y";
- case AXIS_PRESSURE:
- return "AXIS_PRESSURE";
- case AXIS_SIZE:
- return "AXIS_SIZE";
- case AXIS_TOUCH_MAJOR:
- return "AXIS_TOUCH_MAJOR";
- case AXIS_TOUCH_MINOR:
- return "AXIS_TOUCH_MINOR";
- case AXIS_TOOL_MAJOR:
- return "AXIS_TOOL_MAJOR";
- case AXIS_TOOL_MINOR:
- return "AXIS_TOOL_MINOR";
- case AXIS_ORIENTATION:
- return "AXIS_ORIENTATION";
- default:
- return Integer.toString(axis);
+ String symbolicName = AXIS_SYMBOLIC_NAMES.get(axis);
+ return symbolicName != null ? symbolicName : Integer.toString(axis);
+ }
+
+ /**
+ * Gets an axis by its symbolic name such as "AXIS_X" or an
+ * equivalent numeric constant such as "42".
+ *
+ * @param symbolicName The symbolic name of the axis.
+ * @return The axis or -1 if not found.
+ * @see #keycodeToString
+ */
+ public static int axisFromString(String symbolicName) {
+ if (symbolicName == null) {
+ throw new IllegalArgumentException("symbolicName must not be null");
+ }
+
+ final int count = AXIS_SYMBOLIC_NAMES.size();
+ for (int i = 0; i < count; i++) {
+ if (symbolicName.equals(AXIS_SYMBOLIC_NAMES.valueAt(i))) {
+ return i;
+ }
+ }
+
+ try {
+ return Integer.parseInt(symbolicName, 10);
+ } catch (NumberFormatException ex) {
+ return -1;
}
}
@@ -1803,7 +2264,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
*/
public static final class PointerCoords {
private static final int INITIAL_PACKED_AXIS_VALUES = 8;
- private int mPackedAxisBits; // 32bits are enough for now, can raise to 64bit when needed
+ private long mPackedAxisBits;
private float[] mPackedAxisValues;
/**
@@ -1823,20 +2284,14 @@ public final class MotionEvent extends InputEvent implements Parcelable {
}
/**
- * The X coordinate of the pointer movement.
- * The interpretation of the X axis varies by input source.
- * It may represent the X position of the center of the touch contact area,
- * a relative horizontal displacement of a trackball or joystick, or something else.
+ * The X component of the pointer movement.
*
* @see MotionEvent#AXIS_X
*/
public float x;
/**
- * The Y coordinate of the pointer movement.
- * The interpretation of the Y axis varies by input source.
- * It may represent the Y position of the center of the touch contact area,
- * a relative vertical displacement of a trackball or joystick, or something else.
+ * The Y component of the pointer movement.
*
* @see MotionEvent#AXIS_Y
*/
@@ -1912,7 +2367,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
/**
* The orientation of the touch area and tool area in radians clockwise from vertical.
- * An angle of 0 degrees indicates that the major axis of contact is oriented
+ * An angle of 0 radians indicates that the major axis of contact is oriented
* upwards, is perfectly circular or is of unknown orientation. A positive angle
* indicates that the major axis of contact is oriented to the right. A negative angle
* indicates that the major axis of contact is oriented to the left.
@@ -1947,11 +2402,11 @@ public final class MotionEvent extends InputEvent implements Parcelable {
* @param other The pointer coords object to copy.
*/
public void copyFrom(PointerCoords other) {
- final int bits = other.mPackedAxisBits;
+ final long bits = other.mPackedAxisBits;
mPackedAxisBits = bits;
if (bits != 0) {
final float[] otherValues = other.mPackedAxisValues;
- final int count = Integer.bitCount(bits);
+ final int count = Long.bitCount(bits);
float[] values = mPackedAxisValues;
if (values == null || count > values.length) {
values = new float[otherValues.length];
@@ -2001,12 +2456,15 @@ public final class MotionEvent extends InputEvent implements Parcelable {
case AXIS_ORIENTATION:
return orientation;
default: {
- final int bits = mPackedAxisBits;
- final int axisBit = 1 << axis;
+ if (axis < 0 || axis > 63) {
+ throw new IllegalArgumentException("Axis out of range.");
+ }
+ final long bits = mPackedAxisBits;
+ final long axisBit = 1L << axis;
if ((bits & axisBit) == 0) {
return 0;
}
- final int index = Integer.bitCount(bits & (axisBit - 1));
+ final int index = Long.bitCount(bits & (axisBit - 1L));
return mPackedAxisValues[index];
}
}
@@ -2051,16 +2509,19 @@ public final class MotionEvent extends InputEvent implements Parcelable {
orientation = value;
break;
default: {
- final int bits = mPackedAxisBits;
- final int axisBit = 1 << axis;
- final int index = Integer.bitCount(bits & (axisBit - 1));
+ if (axis < 0 || axis > 63) {
+ throw new IllegalArgumentException("Axis out of range.");
+ }
+ final long bits = mPackedAxisBits;
+ final long axisBit = 1L << axis;
+ final int index = Long.bitCount(bits & (axisBit - 1L));
float[] values = mPackedAxisValues;
if ((bits & axisBit) == 0) {
if (values == null) {
values = new float[INITIAL_PACKED_AXIS_VALUES];
mPackedAxisValues = values;
} else {
- final int count = Integer.bitCount(bits);
+ final int count = Long.bitCount(bits);
if (count < values.length) {
if (index != count) {
System.arraycopy(values, index, values, index + 1,
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 48451bad5736..ae06888addc1 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -74,6 +74,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.WeakHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* <p>
@@ -2099,6 +2100,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
private ArrayList<OnLayoutChangeListener> mOnLayoutChangeListeners;
/**
+ * Listeners for attach events.
+ */
+ private CopyOnWriteArrayList<OnAttachStateChangeListener> mOnAttachStateChangeListeners;
+
+ /**
* Listener used to dispatch click events.
* This field should be made private, so it is hidden from the SDK.
* {@hide}
@@ -2996,6 +3002,37 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
}
/**
+ * Add a listener for attach state changes.
+ *
+ * This listener will be called whenever this view is attached or detached
+ * from a window. Remove the listener using
+ * {@link #removeOnAttachStateChangeListener(OnAttachStateChangeListener)}.
+ *
+ * @param listener Listener to attach
+ * @see #removeOnAttachStateChangeListener(OnAttachStateChangeListener)
+ */
+ public void addOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
+ if (mOnAttachStateChangeListeners == null) {
+ mOnAttachStateChangeListeners = new CopyOnWriteArrayList<OnAttachStateChangeListener>();
+ }
+ mOnAttachStateChangeListeners.add(listener);
+ }
+
+ /**
+ * Remove a listener for attach state changes. The listener will receive no further
+ * notification of window attach/detach events.
+ *
+ * @param listener Listener to remove
+ * @see #addOnAttachStateChangeListener(OnAttachStateChangeListener)
+ */
+ public void removeOnAttachStateChangeListener(OnAttachStateChangeListener listener) {
+ if (mOnAttachStateChangeListeners == null) {
+ return;
+ }
+ mOnAttachStateChangeListeners.remove(listener);
+ }
+
+ /**
* Returns the focus-change callback registered for this view.
*
* @return The callback, or null if one is not registered.
@@ -6628,7 +6665,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
* view specifying how it should be arranged. There are many subclasses of
* ViewGroup.LayoutParams, and these correspond to the different subclasses
* of ViewGroup that are responsible for arranging their children.
- * @return The LayoutParams associated with this view
+ *
+ * This method may return null if this View is not attached to a parent
+ * ViewGroup or {@link #setLayoutParams(android.view.ViewGroup.LayoutParams)}
+ * was not invoked successfully. When a View is attached to a parent
+ * ViewGroup, this method must not return null.
+ *
+ * @return The LayoutParams associated with this view, or null if no
+ * parameters have been set yet
*/
@ViewDebug.ExportedProperty(deepExport = true, prefix = "layout_")
public ViewGroup.LayoutParams getLayoutParams() {
@@ -6642,11 +6686,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
* correspond to the different subclasses of ViewGroup that are responsible
* for arranging their children.
*
- * @param params the layout parameters for this view
+ * @param params The layout parameters for this view, cannot be null
*/
public void setLayoutParams(ViewGroup.LayoutParams params) {
if (params == null) {
- throw new NullPointerException("params == null");
+ throw new NullPointerException("Layout parameters cannot be null");
}
mLayoutParams = params;
requestLayout();
@@ -7953,6 +7997,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
}
performCollectViewAttributes(visibility);
onAttachedToWindow();
+
+ final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
+ mOnAttachStateChangeListeners;
+ if (listeners != null && listeners.size() > 0) {
+ // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
+ // perform the dispatching. The iterator is a safe guard against listeners that
+ // could mutate the list by calling the various add/remove methods. This prevents
+ // the array from being modified while we iterate it.
+ for (OnAttachStateChangeListener listener : listeners) {
+ listener.onViewAttachedToWindow(this);
+ }
+ }
+
int vis = info.mWindowVisibility;
if (vis != GONE) {
onWindowVisibilityChanged(vis);
@@ -7974,6 +8031,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
onDetachedFromWindow();
+ final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
+ mOnAttachStateChangeListeners;
+ if (listeners != null && listeners.size() > 0) {
+ // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
+ // perform the dispatching. The iterator is a safe guard against listeners that
+ // could mutate the list by calling the various add/remove methods. This prevents
+ // the array from being modified while we iterate it.
+ for (OnAttachStateChangeListener listener : listeners) {
+ listener.onViewDetachedFromWindow(this);
+ }
+ }
+
if ((mPrivateFlags & SCROLL_CONTAINER_ADDED) != 0) {
mAttachInfo.mScrollContainers.remove(this);
mPrivateFlags &= ~SCROLL_CONTAINER_ADDED;
@@ -11767,6 +11836,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
public void onSystemUiVisibilityChange(int visibility);
}
+ /**
+ * Interface definition for a callback to be invoked when this view is attached
+ * or detached from its window.
+ */
+ public interface OnAttachStateChangeListener {
+ /**
+ * Called when the view is attached to a window.
+ * @param v The view that was attached
+ */
+ public void onViewAttachedToWindow(View v);
+ /**
+ * Called when the view is detached from a window.
+ * @param v The view that was detached
+ */
+ public void onViewDetachedFromWindow(View v);
+ }
+
private final class UnsetPressedState implements Runnable {
public void run() {
setPressed(false);
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index b5a255892208..a0d4263e58ff 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1166,7 +1166,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final int actionMasked = action & MotionEvent.ACTION_MASK;
// Handle an initial down.
- if (actionMasked == MotionEvent.ACTION_DOWN) {
+ if (actionMasked == MotionEvent.ACTION_DOWN
+ || actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
// Throw away all previous state when starting a new touch gesture.
// The framework may have dropped the up or cancel event for the previous gesture
// due to an app switch, ANR, or some other state change.
@@ -1176,7 +1177,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
// Check for interception.
final boolean intercepted;
- if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) {
+ if (actionMasked == MotionEvent.ACTION_DOWN
+ || actionMasked == MotionEvent.ACTION_HOVER_MOVE
+ || mFirstTouchTarget != null) {
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
@@ -1198,7 +1201,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
boolean alreadyDispatchedToNewTouchTarget = false;
if (!canceled && !intercepted) {
if (actionMasked == MotionEvent.ACTION_DOWN
- || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)) {
+ || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)
+ || actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
final int actionIndex = ev.getActionIndex(); // always 0 for down
final int idBitsToAssign = split ? 1 << ev.getPointerId(actionIndex)
: TouchTarget.ALL_POINTER_IDS;
@@ -1299,7 +1303,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
// Update list of touch targets for pointer up or cancel, if needed.
- if (canceled || actionMasked == MotionEvent.ACTION_UP) {
+ if (canceled
+ || actionMasked == MotionEvent.ACTION_UP
+ || actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
resetTouchState();
} else if (split && actionMasked == MotionEvent.ACTION_POINTER_UP) {
final int actionIndex = ev.getActionIndex();
@@ -1542,6 +1548,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final int newAction;
if (cancel) {
newAction = MotionEvent.ACTION_CANCEL;
+ } else if (oldAction == MotionEvent.ACTION_HOVER_MOVE) {
+ newAction = MotionEvent.ACTION_HOVER_MOVE;
} else {
final int oldMaskedAction = oldAction & MotionEvent.ACTION_MASK;
if (oldMaskedAction == MotionEvent.ACTION_POINTER_DOWN
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index ec1a373397ae..39f99b8c8412 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -2496,7 +2496,6 @@ public final class ViewRoot extends Handler implements ViewParent,
// Deliver the event to the view.
if (mView.dispatchGenericMotionEvent(event)) {
- ensureTouchMode(false);
if (isJoystick) {
updateJoystickDirection(event, false);
}
@@ -2525,8 +2524,16 @@ public final class ViewRoot extends Handler implements ViewParent,
final int metaState = event.getMetaState();
final int deviceId = event.getDeviceId();
final int source = event.getSource();
- final int xDirection = joystickAxisValueToDirection(event.getX());
- final int yDirection = joystickAxisValueToDirection(event.getY());
+
+ int xDirection = joystickAxisValueToDirection(event.getAxisValue(MotionEvent.AXIS_HAT_X));
+ if (xDirection == 0) {
+ xDirection = joystickAxisValueToDirection(event.getX());
+ }
+
+ int yDirection = joystickAxisValueToDirection(event.getAxisValue(MotionEvent.AXIS_HAT_Y));
+ if (yDirection == 0) {
+ yDirection = joystickAxisValueToDirection(event.getY());
+ }
if (xDirection != mLastJoystickXDirection) {
if (mLastJoystickXKeyCode != 0) {
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index 89b7aaadd2d8..9e9f46fb7418 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -129,6 +129,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
// List of stream types and their order
// RING and VOICE_CALL are hidden unless explicitly requested
private static final int [] STREAM_TYPES = {
+ AudioManager.STREAM_BLUETOOTH_SCO,
AudioManager.STREAM_RING,
AudioManager.STREAM_VOICE_CALL,
AudioManager.STREAM_MUSIC,
@@ -137,6 +138,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
// These icons need to correspond to the ones above.
private static final int [] STREAM_ICONS_NORMAL = {
+ R.drawable.ic_audio_bt,
R.drawable.ic_audio_phone,
R.drawable.ic_audio_phone,
R.drawable.ic_audio_vol,
@@ -145,6 +147,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
// These icons need to correspond to the ones above.
private static final int [] STREAM_ICONS_MUTED = {
+ R.drawable.ic_audio_bt,
R.drawable.ic_audio_phone,
R.drawable.ic_audio_phone,
R.drawable.ic_audio_vol_mute,
@@ -277,6 +280,7 @@ public class VolumePanel extends Handler implements OnSeekBarChangeListener, Vie
final int streamType = STREAM_TYPES[i];
if (streamType == AudioManager.STREAM_RING
|| streamType == AudioManager.STREAM_VOICE_CALL
+ || streamType == AudioManager.STREAM_BLUETOOTH_SCO
|| streamType == activeStreamType) {
continue;
}
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index ad069029eabe..be68cb9e4a44 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -754,6 +754,24 @@ public interface WindowManagerPolicy {
void exitKeyguardSecurely(OnKeyguardExitResult callback);
/**
+ * isKeyguardLocked
+ *
+ * Return whether the keyguard is currently locked.
+ *
+ * @return true if in keyguard is locked.
+ */
+ public boolean isKeyguardLocked();
+
+ /**
+ * isKeyguardSecure
+ *
+ * Return whether the keyguard requires a password to unlock.
+ *
+ * @return true if in keyguard is secure.
+ */
+ public boolean isKeyguardSecure();
+
+ /**
* inKeyguardRestrictedKeyInputMode
*
* if keyguard screen is showing or in restricted key input mode (i.e. in
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index cb67b78b8e98..a39c7c70042d 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -762,8 +762,7 @@ public final class InputMethodManager {
* {@link #RESULT_UNCHANGED_HIDDEN}, {@link #RESULT_SHOWN}, or
* {@link #RESULT_HIDDEN}.
*/
- public boolean showSoftInput(View view, int flags,
- ResultReceiver resultReceiver) {
+ public boolean showSoftInput(View view, int flags, ResultReceiver resultReceiver) {
checkFocus();
synchronized (mH) {
if (mServedView != view && (mServedView == null
diff --git a/core/java/android/webkit/CookieSyncManager.java b/core/java/android/webkit/CookieSyncManager.java
index 8393980433a0..313f7558bfe7 100644
--- a/core/java/android/webkit/CookieSyncManager.java
+++ b/core/java/android/webkit/CookieSyncManager.java
@@ -178,14 +178,16 @@ public final class CookieSyncManager extends WebSyncManager {
return;
}
- manager.flushCookieStore();
-
- ArrayList<Cookie> cookieList = manager.getUpdatedCookiesSince(mLastUpdate);
- mLastUpdate = System.currentTimeMillis();
- syncFromRamToFlash(cookieList);
-
- ArrayList<Cookie> lruList = manager.deleteLRUDomain();
- syncFromRamToFlash(lruList);
+ if (JniUtil.useChromiumHttpStack()) {
+ manager.flushCookieStore();
+ } else {
+ ArrayList<Cookie> cookieList = manager.getUpdatedCookiesSince(mLastUpdate);
+ mLastUpdate = System.currentTimeMillis();
+ syncFromRamToFlash(cookieList);
+
+ ArrayList<Cookie> lruList = manager.deleteLRUDomain();
+ syncFromRamToFlash(lruList);
+ }
if (DebugFlags.COOKIE_SYNC_MANAGER) {
Log.v(LOGTAG, "CookieSyncManager::syncFromRamToFlash DONE");
diff --git a/core/java/android/webkit/DebugFlags.java b/core/java/android/webkit/DebugFlags.java
index 3cb5e24ec26c..2dac7e91151a 100644
--- a/core/java/android/webkit/DebugFlags.java
+++ b/core/java/android/webkit/DebugFlags.java
@@ -31,7 +31,7 @@ class DebugFlags {
public static final boolean CACHE_MANAGER = false;
public static final boolean CALLBACK_PROXY = false;
public static final boolean COOKIE_MANAGER = false;
- public static final boolean COOKIE_SYNC_MANAGER = false;
+ public static final boolean COOKIE_SYNC_MANAGER = true;
public static final boolean FRAME_LOADER = false;
public static final boolean J_WEB_CORE_JAVA_BRIDGE = false;// HIGHLY VERBOSE
public static final boolean LOAD_LISTENER = false;
@@ -41,7 +41,7 @@ class DebugFlags {
public static final boolean URL_UTIL = false;
public static final boolean WEB_BACK_FORWARD_LIST = false;
public static final boolean WEB_SETTINGS = false;
- public static final boolean WEB_SYNC_MANAGER = false;
+ public static final boolean WEB_SYNC_MANAGER = true;
public static final boolean WEB_TEXT_VIEW = false;
public static final boolean WEB_VIEW = false;
public static final boolean WEB_VIEW_CORE = false;
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index d8f34e05d2fe..3caf3452822b 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -46,6 +46,8 @@ import android.widget.VideoView;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
@@ -344,7 +346,7 @@ class HTML5VideoViewProxy extends Handler
private static RequestQueue mRequestQueue;
private static int mQueueRefCount = 0;
// The poster URL
- private String mUrl;
+ private URL mUrl;
// The proxy we're doing this for.
private final HTML5VideoViewProxy mProxy;
// The poster bytes. We only touch this on the network thread.
@@ -359,14 +361,30 @@ class HTML5VideoViewProxy extends Handler
private Handler mHandler;
public PosterDownloader(String url, HTML5VideoViewProxy proxy) {
- mUrl = url;
+ try {
+ mUrl = new URL(url);
+ } catch (MalformedURLException e) {
+ mUrl = null;
+ }
mProxy = proxy;
mHandler = new Handler();
}
// Start the download. Called on WebCore thread.
public void start() {
retainQueue();
- mRequestHandle = mRequestQueue.queueRequest(mUrl, "GET", null, this, null, 0);
+
+ if (mUrl == null) {
+ return;
+ }
+
+ // Only support downloading posters over http/https.
+ // FIXME: Add support for other schemes. WebKit seems able to load
+ // posters over other schemes e.g. file://, but gets the dimensions wrong.
+ String protocol = mUrl.getProtocol();
+ if ("http".equals(protocol) || "https".equals(protocol)) {
+ mRequestHandle = mRequestQueue.queueRequest(mUrl.toString(), "GET", null,
+ this, null, 0);
+ }
}
// Cancel the download if active and release the queue. Called on WebCore thread.
public void cancelAndReleaseQueue() {
@@ -405,12 +423,16 @@ class HTML5VideoViewProxy extends Handler
cleanup();
} else if (mStatusCode >= 300 && mStatusCode < 400) {
// We have a redirect.
- mUrl = mHeaders.getLocation();
+ try {
+ mUrl = new URL(mHeaders.getLocation());
+ } catch (MalformedURLException e) {
+ mUrl = null;
+ }
if (mUrl != null) {
mHandler.post(new Runnable() {
public void run() {
if (mRequestHandle != null) {
- mRequestHandle.setupRedirect(mUrl, mStatusCode,
+ mRequestHandle.setupRedirect(mUrl.toString(), mStatusCode,
new HashMap<String, String>());
}
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index b374fbdd25ed..d9f050b34fe1 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -5275,7 +5275,6 @@ public class WebView extends AbsoluteLayout
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- boolean dispatch = true;
switch (event.getAction()) {
case KeyEvent.ACTION_DOWN:
mKeysPressed.add(Integer.valueOf(event.getKeyCode()));
@@ -5288,7 +5287,7 @@ public class WebView extends AbsoluteLayout
if (location == -1) {
// We did not receive the key down for this key, so do not
// handle the key up.
- dispatch = false;
+ return false;
} else {
// We did receive the key down. Handle the key up, and
// remove it from our pressed keys.
@@ -5300,17 +5299,12 @@ public class WebView extends AbsoluteLayout
// action is added to KeyEvent.
break;
}
- if (dispatch) {
- if (inEditingMode()) {
- // Ensure that the WebTextView gets the event, even if it does
- // not currently have a bounds.
- return mWebTextView.dispatchKeyEvent(event);
- } else {
- return super.dispatchKeyEvent(event);
- }
+ if (inEditingMode() && mWebTextView.isFocused()) {
+ // Ensure that the WebTextView gets the event, even if it does
+ // not currently have a bounds.
+ return mWebTextView.dispatchKeyEvent(event);
} else {
- // We didn't dispatch, so let something else handle the key
- return false;
+ return super.dispatchKeyEvent(event);
}
}
@@ -5514,8 +5508,8 @@ public class WebView extends AbsoluteLayout
}
}
// Trigger the link
- if (mTouchMode == TOUCH_INIT_MODE
- || mTouchMode == TOUCH_DOUBLE_TAP_MODE) {
+ if (!mSelectingText && (mTouchMode == TOUCH_INIT_MODE
+ || mTouchMode == TOUCH_DOUBLE_TAP_MODE)) {
mPrivateHandler.sendEmptyMessageDelayed(
SWITCH_TO_SHORTPRESS, TAP_TIMEOUT);
mPrivateHandler.sendEmptyMessageDelayed(
@@ -5537,6 +5531,8 @@ public class WebView extends AbsoluteLayout
ted.mPoints[0] = new Point(contentX, contentY);
ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = nativeScrollableLayer(
+ contentX, contentY, ted.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
if (mDeferTouchProcess) {
// still needs to set them for compute deltaX/Y
@@ -5581,6 +5577,8 @@ public class WebView extends AbsoluteLayout
ted.mPoints[0] = new Point(contentX, contentY);
ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = mScrollingLayer;
+ ted.mNativeLayerRect.set(mScrollingLayerRect);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
mLastSentTouchTime = eventTime;
if (mDeferTouchProcess) {
@@ -5760,6 +5758,8 @@ public class WebView extends AbsoluteLayout
ted.mPoints[0] = new Point(contentX, contentY);
ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = mScrollingLayer;
+ ted.mNativeLayerRect.set(mScrollingLayerRect);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
}
mLastTouchUpTime = eventTime;
@@ -5779,6 +5779,9 @@ public class WebView extends AbsoluteLayout
ted.mPoints[0] = new Point(contentX, contentY);
ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = nativeScrollableLayer(
+ contentX, contentY,
+ ted.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
} else if (mPreventDefault != PREVENT_DEFAULT_YES){
mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
@@ -6010,6 +6013,8 @@ public class WebView extends AbsoluteLayout
ted.mPoints = new Point[1];
ted.mPoints[0] = new Point(x, y);
ted.mAction = MotionEvent.ACTION_CANCEL;
+ ted.mNativeLayer = nativeScrollableLayer(
+ x, y, ted.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
mPreventDefault = PREVENT_DEFAULT_IGNORE;
}
@@ -6649,8 +6654,9 @@ public class WebView extends AbsoluteLayout
// mLastTouchX and mLastTouchY are the point in the current viewport
int contentX = viewToContentX(mLastTouchX + mScrollX);
int contentY = viewToContentY(mLastTouchY + mScrollY);
- Rect rect = new Rect(contentX - mNavSlop, contentY - mNavSlop,
- contentX + mNavSlop, contentY + mNavSlop);
+ int slop = viewToContentDimension(mNavSlop);
+ Rect rect = new Rect(contentX - slop, contentY - slop,
+ contentX + slop, contentY + slop);
nativeSelectBestAt(rect);
mInitialHitTestResult = hitTestResult(null);
}
@@ -6724,7 +6730,8 @@ public class WebView extends AbsoluteLayout
}
int x = viewToContentX((int) event.getX() + mWebTextView.getLeft());
int y = viewToContentY((int) event.getY() + mWebTextView.getTop());
- nativeMotionUp(x, y, mNavSlop);
+ int slop = viewToContentDimension(mNavSlop);
+ nativeMotionUp(x, y, slop);
}
/**
@@ -6747,6 +6754,7 @@ public class WebView extends AbsoluteLayout
// mLastTouchX and mLastTouchY are the point in the current viewport
int contentX = viewToContentX(mLastTouchX + mScrollX);
int contentY = viewToContentY(mLastTouchY + mScrollY);
+ int slop = viewToContentDimension(mNavSlop);
if (getSettings().supportTouchOnly()) {
removeTouchHighlight(false);
WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData();
@@ -6754,7 +6762,7 @@ public class WebView extends AbsoluteLayout
// it used when processing GET_TOUCH_HIGHLIGHT_RECTS
touchUpData.mMoveGeneration = 0;
mWebViewCore.sendMessage(EventHub.TOUCH_UP, touchUpData);
- } else if (nativePointInNavCache(contentX, contentY, mNavSlop)) {
+ } else if (nativePointInNavCache(contentX, contentY, slop)) {
WebViewCore.MotionUpData motionUpData = new WebViewCore
.MotionUpData();
motionUpData.mFrame = nativeCacheHitFramePointer();
@@ -6770,7 +6778,8 @@ public class WebView extends AbsoluteLayout
}
private void doMotionUp(int contentX, int contentY) {
- if (nativeMotionUp(contentX, contentY, mNavSlop) && mLogEvent) {
+ int slop = viewToContentDimension(mNavSlop);
+ if (nativeMotionUp(contentX, contentY, slop) && mLogEvent) {
EventLog.writeEvent(EventLogTags.BROWSER_SNAP_CENTER);
}
if (nativeHasCursorNode() && !nativeCursorIsTextInput()) {
@@ -6783,7 +6792,8 @@ public class WebView extends AbsoluteLayout
* plugin. Otherwise a NULL rectangle is returned.
*/
Rect getPluginBounds(int x, int y) {
- if (nativePointInNavCache(x, y, mNavSlop) && nativeCacheHitIsPlugin()) {
+ int slop = viewToContentDimension(mNavSlop);
+ if (nativePointInNavCache(x, y, slop) && nativeCacheHitIsPlugin()) {
return nativeCacheHitNodeBounds();
} else {
return null;
@@ -7167,6 +7177,9 @@ public class WebView extends AbsoluteLayout
// simplicity for now, we don't set it.
ted.mMetaState = 0;
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = nativeScrollableLayer(
+ ted.mPoints[0].x, ted.mPoints[0].y,
+ ted.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
} else if (mPreventDefault != PREVENT_DEFAULT_YES) {
mTouchMode = TOUCH_DONE_MODE;
@@ -8039,6 +8052,8 @@ public class WebView extends AbsoluteLayout
touchUpData.mNode = node;
touchUpData.mX = x;
touchUpData.mY = y;
+ touchUpData.mNativeLayer = nativeScrollableLayer(
+ x, y, touchUpData.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_UP, touchUpData);
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 42889cbf81ab..fb0f61ce595e 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -778,6 +778,8 @@ final class WebViewCore {
int mNode;
int mX;
int mY;
+ int mNativeLayer;
+ Rect mNativeLayerRect = new Rect();
}
static class TouchHighlightData {
@@ -821,6 +823,8 @@ final class WebViewCore {
int mMetaState;
boolean mReprocess;
MotionEvent mMotionEvent;
+ int mNativeLayer;
+ Rect mNativeLayerRect = new Rect();
}
static class GeolocationPermissionsData {
@@ -1304,6 +1308,10 @@ final class WebViewCore {
case TOUCH_UP:
TouchUpData touchUpData = (TouchUpData) msg.obj;
+ if (touchUpData.mNativeLayer != 0) {
+ nativeScrollLayer(touchUpData.mNativeLayer,
+ touchUpData.mNativeLayerRect);
+ }
nativeTouchUp(touchUpData.mMoveGeneration,
touchUpData.mFrame, touchUpData.mNode,
touchUpData.mX, touchUpData.mY);
@@ -1318,6 +1326,10 @@ final class WebViewCore {
xArray[c] = ted.mPoints[c].x;
yArray[c] = ted.mPoints[c].y;
}
+ if (ted.mNativeLayer != 0) {
+ nativeScrollLayer(ted.mNativeLayer,
+ ted.mNativeLayerRect);
+ }
Message.obtain(
mWebView.mPrivateHandler,
WebView.PREVENT_TOUCH_ID,
@@ -1814,7 +1826,34 @@ final class WebViewCore {
Log.w(LOGTAG, "skip viewSizeChanged as w is 0");
return;
}
- int width = w;
+ int width = calculateWindowWidth(w, textwrapWidth);
+ int height = h;
+ if (width != w) {
+ float heightWidthRatio = data.mHeightWidthRatio;
+ float ratio = (heightWidthRatio > 0) ? heightWidthRatio : (float) h / w;
+ height = Math.round(ratio * width);
+ }
+ nativeSetSize(width, height, textwrapWidth, scale, w,
+ data.mActualViewHeight > 0 ? data.mActualViewHeight : h,
+ data.mAnchorX, data.mAnchorY, data.mIgnoreHeight);
+ // Remember the current width and height
+ boolean needInvalidate = (mCurrentViewWidth == 0);
+ mCurrentViewWidth = w;
+ mCurrentViewHeight = h;
+ mCurrentViewScale = scale;
+ if (needInvalidate) {
+ // ensure {@link #webkitDraw} is called as we were blocking in
+ // {@link #contentDraw} when mCurrentViewWidth is 0
+ if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "viewSizeChanged");
+ contentDraw();
+ }
+ mEventHub.sendMessage(Message.obtain(null,
+ EventHub.UPDATE_CACHE_AND_TEXT_ENTRY));
+ }
+
+ // Calculate width to be used in webkit window.
+ private int calculateWindowWidth(int viewWidth, int textwrapWidth) {
+ int width = viewWidth;
if (mSettings.getUseWideViewPort()) {
if (mViewportWidth == -1) {
if (mSettings.getLayoutAlgorithm() ==
@@ -1833,7 +1872,7 @@ final class WebViewCore {
* In the worse case, the native width will be adjusted when
* next zoom or screen orientation change happens.
*/
- width = Math.min(WebView.sMaxViewportWidth, Math.max(w,
+ width = Math.min(WebView.sMaxViewportWidth, Math.max(viewWidth,
Math.max(WebView.DEFAULT_VIEWPORT_WIDTH,
nativeGetContentMinPrefWidth())));
}
@@ -1842,7 +1881,7 @@ final class WebViewCore {
// Use website specified or desired fixed viewport width.
width = mViewportWidth;
} else {
- width = Math.max(w, mViewportWidth);
+ width = Math.max(viewWidth, mViewportWidth);
}
} else if (mSettings.getUseFixedViewport()) {
width = mWebView.getViewWidth();
@@ -1850,28 +1889,7 @@ final class WebViewCore {
width = textwrapWidth;
}
}
- int height = h;
- if (width != w) {
- float heightWidthRatio = data.mHeightWidthRatio;
- float ratio = (heightWidthRatio > 0) ? heightWidthRatio : (float) h / w;
- height = Math.round(ratio * width);
- }
- nativeSetSize(width, height, textwrapWidth, scale, w,
- data.mActualViewHeight > 0 ? data.mActualViewHeight : h,
- data.mAnchorX, data.mAnchorY, data.mIgnoreHeight);
- // Remember the current width and height
- boolean needInvalidate = (mCurrentViewWidth == 0);
- mCurrentViewWidth = w;
- mCurrentViewHeight = h;
- mCurrentViewScale = scale;
- if (needInvalidate) {
- // ensure {@link #webkitDraw} is called as we were blocking in
- // {@link #contentDraw} when mCurrentViewWidth is 0
- if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "viewSizeChanged");
- contentDraw();
- }
- mEventHub.sendMessage(Message.obtain(null,
- EventHub.UPDATE_CACHE_AND_TEXT_ENTRY));
+ return width;
}
private void sendUpdateTextEntry() {
@@ -2370,7 +2388,7 @@ final class WebViewCore {
// to syncing an incorrect height.
data.mHeight = mCurrentViewHeight == 0 ?
Math.round(mWebView.getViewHeight() / data.mScale)
- : mCurrentViewHeight * data.mWidth / viewportWidth;
+ : Math.round((float) mCurrentViewHeight * data.mWidth / viewportWidth);
data.mTextWrapWidth = Math.round(webViewWidth
/ mInitialViewState.mTextWrapScale);
data.mIgnoreHeight = false;
@@ -2696,4 +2714,5 @@ final class WebViewCore {
int slop);
private native void nativeAutoFillForm(int queryId);
+ private native void nativeScrollLayer(int layer, Rect rect);
}
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 9d472e02ae46..86aef4c3d2cc 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -361,6 +361,7 @@ class ZoomManager {
// returns TRUE if zoom out succeeds and FALSE if no zoom changes.
private boolean zoom(float zoomMultiplier) {
+ mInitialZoomOverview = false;
// TODO: alternatively we can disallow this during draw history mode
mWebView.switchOutDrawHistory();
// Center zooming to the center of the screen.
@@ -378,6 +379,7 @@ class ZoomManager {
* @return true if the new scale triggered an animation and false otherwise.
*/
public boolean startZoomAnimation(float scale, boolean reflowText) {
+ mInitialZoomOverview = false;
float oldScale = mActualScale;
mInitialScrollX = mWebView.getScrollX();
mInitialScrollY = mWebView.getScrollY();
@@ -421,6 +423,7 @@ class ZoomManager {
* in progress by calling isFixedLengthAnimationInProgress().
*/
public void animateZoom(Canvas canvas) {
+ mInitialZoomOverview = false;
if (mZoomScale == 0) {
Log.w(LOGTAG, "A WebView is attempting to perform a fixed length "
+ "zoom animation when no zoom is in progress");
@@ -568,6 +571,8 @@ class ZoomManager {
* C. If the page is in overmode then change to the default scale.
*/
public void handleDoubleTap(float lastTouchX, float lastTouchY) {
+ // User takes action, set initial zoom overview to false.
+ mInitialZoomOverview = false;
WebSettings settings = mWebView.getSettings();
if (!isDoubleTapEnabled()) {
return;
@@ -706,6 +711,7 @@ class ZoomManager {
private class ScaleDetectorListener implements ScaleGestureDetector.OnScaleGestureListener {
public boolean onScaleBegin(ScaleGestureDetector detector) {
+ mInitialZoomOverview = false;
dismissZoomPicker();
mWebView.mViewManager.startZoom();
mWebView.onPinchToZoomAnimationStart();
@@ -884,7 +890,7 @@ class ZoomManager {
!exceedsMinScaleIncrement(newZoomOverviewScale, 1.0f);
if (!mWebView.drawHistory() &&
(mInitialZoomOverview || scaleLessThanOverview || mobileSiteInOverview) &&
- scaleHasDiff) {
+ scaleHasDiff && zoomOverviewWidthChanged) {
mInitialZoomOverview = false;
setZoomScale(newZoomOverviewScale, !willScaleTriggerZoom(mTextWrapScale) &&
!mWebView.getSettings().getUseFixedViewport());
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index a84df16d2d59..0383b5c8c0cd 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -37,14 +37,46 @@ import android.widget.RemoteViews.RemoteView;
*
* <p>See the <a href="{@docRoot}resources/tutorials/views/hello-gridview.html">Grid
* View tutorial</a>.</p>
+ *
+ * @attr ref android.R.styleable#GridView_horizontalSpacing
+ * @attr ref android.R.styleable#GridView_verticalSpacing
+ * @attr ref android.R.styleable#GridView_stretchMode
+ * @attr ref android.R.styleable#GridView_columnWidth
+ * @attr ref android.R.styleable#GridView_numColumns
+ * @attr ref android.R.styleable#GridView_gravity
*/
@RemoteView
public class GridView extends AbsListView {
+ /**
+ * Disables stretching.
+ *
+ * @see #setStretchMode(int)
+ */
public static final int NO_STRETCH = 0;
+ /**
+ * Stretches the spacing between columns.
+ *
+ * @see #setStretchMode(int)
+ */
public static final int STRETCH_SPACING = 1;
+ /**
+ * Stretches columns.
+ *
+ * @see #setStretchMode(int)
+ */
public static final int STRETCH_COLUMN_WIDTH = 2;
+ /**
+ * Stretches the spacing between columns. The spacing is uniform.
+ *
+ * @see #setStretchMode(int)
+ */
public static final int STRETCH_SPACING_UNIFORM = 3;
-
+
+ /**
+ * Creates as many columns as can fit on screen.
+ *
+ * @see #setNumColumns(int)
+ */
public static final int AUTO_FIT = -1;
private int mNumColumns = AUTO_FIT;
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 53932af65404..4b858d0dd154 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -1056,16 +1056,17 @@ public class PopupWindow {
anchor.getWindowVisibleDisplayFrame(displayFrame);
final View root = anchor.getRootView();
- if (mAllowScrollingAnchorParent && (p.y + mPopupHeight > displayFrame.bottom ||
- p.x + mPopupWidth - root.getWidth() > 0)) {
+ if (p.y + mPopupHeight > displayFrame.bottom || p.x + mPopupWidth - root.getWidth() > 0) {
// if the drop down disappears at the bottom of the screen. we try to
// scroll a parent scrollview or move the drop down back up on top of
// the edit box
- int scrollX = anchor.getScrollX();
- int scrollY = anchor.getScrollY();
- Rect r = new Rect(scrollX, scrollY, scrollX + mPopupWidth + xoff,
- scrollY + mPopupHeight + anchor.getHeight() + yoff);
- anchor.requestRectangleOnScreen(r, true);
+ if (mAllowScrollingAnchorParent) {
+ int scrollX = anchor.getScrollX();
+ int scrollY = anchor.getScrollY();
+ Rect r = new Rect(scrollX, scrollY, scrollX + mPopupWidth + xoff,
+ scrollY + mPopupHeight + anchor.getHeight() + yoff);
+ anchor.requestRectangleOnScreen(r, true);
+ }
// now we re-evaluate the space available, and decide from that
// whether the pop-up will go above or below the anchor.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 993af31c31cd..c4d95b26c9ea 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -46,7 +46,6 @@ import android.os.Handler;
import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.ResultReceiver;
import android.os.SystemClock;
import android.text.BoringLayout;
import android.text.DynamicLayout;
@@ -3998,7 +3997,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if (mBlink != null) {
- mBlink.cancel();
+ mBlink.removeCallbacks(mBlink);
}
if (mInsertionPointCursorController != null) {
@@ -4403,12 +4402,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
(mCurrentAlpha * Color.alpha(cursorcolor)) / 255);
}
mHighlightPaint.setStyle(Paint.Style.STROKE);
-
- if (mCursorCount > 0) {
- drawCursor = true;
- } else {
- highlight = mHighlightPath;
- }
+ highlight = mHighlightPath;
+ drawCursor = true;
}
} else {
if (mHighlightPathBogus) {
@@ -4491,7 +4486,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mCorrectionHighlighter.draw(canvas, cursorOffsetVertical);
}
- if (drawCursor) drawCursor(canvas, cursorOffsetVertical);
+ if (drawCursor) {
+ drawCursor(canvas, cursorOffsetVertical);
+ // Rely on the drawable entirely, do not draw the cursor line.
+ // Has to be done after the IMM related code above which relies on the highlight.
+ highlight = null;
+ }
layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
@@ -5421,18 +5421,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
invalidate();
int curs = getSelectionStart();
- if (curs >= 0 || (mGravity & Gravity.VERTICAL_GRAVITY_MASK) ==
- Gravity.BOTTOM) {
+ if (curs >= 0 || (mGravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
registerForPreDraw();
}
if (curs >= 0) {
mHighlightPathBogus = true;
-
- if (isFocused()) {
- mShowCursor = SystemClock.uptimeMillis();
- makeBlink();
- }
+ makeBlink();
}
checkForResize();
@@ -6589,13 +6584,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
@android.view.RemotableViewMethod
public void setCursorVisible(boolean visible) {
- mCursorVisible = visible;
- invalidate();
+ if (mCursorVisible != visible) {
+ mCursorVisible = visible;
+ invalidate();
- makeBlink();
+ makeBlink();
- // InsertionPointCursorController depends on mCursorVisible
- prepareCursorControllers();
+ // InsertionPointCursorController depends on mCursorVisible
+ prepareCursorControllers();
+ }
}
private boolean isCursorVisible() {
@@ -6934,11 +6931,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (oldStart >= 0 || newStart >= 0) {
invalidateCursor(Selection.getSelectionStart(buf), oldStart, newStart);
registerForPreDraw();
-
- if (isFocused()) {
- mShowCursor = SystemClock.uptimeMillis();
- makeBlink();
- }
+ makeBlink();
}
}
@@ -7089,22 +7082,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- private void makeBlink() {
- if (!isCursorVisible()) {
- if (mBlink != null) {
- mBlink.removeCallbacks(mBlink);
- }
-
- return;
- }
-
- if (mBlink == null)
- mBlink = new Blink(this);
-
- mBlink.removeCallbacks(mBlink);
- mBlink.postAtTime(mBlink, mShowCursor + BLINK);
- }
-
/**
* @hide
*/
@@ -7242,7 +7219,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// does not happen in that case (using the arrows on a bluetooth keyboard).
if (focused && isTextEditable()) {
final InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null) imm.showSoftInput(this, 0, null);
+ if (imm != null) imm.showSoftInput(this, 0);
}
}
@@ -7271,11 +7248,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (hasWindowFocus) {
if (mBlink != null) {
mBlink.uncancel();
-
- if (isFocused()) {
- mShowCursor = SystemClock.uptimeMillis();
- makeBlink();
- }
+ makeBlink();
}
} else {
if (mBlink != null) {
@@ -7326,33 +7299,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- class CommitSelectionReceiver extends ResultReceiver {
- private final int mPrevStart, mPrevEnd;
-
- public CommitSelectionReceiver(int prevStart, int prevEnd) {
- super(getHandler());
- mPrevStart = prevStart;
- mPrevEnd = prevEnd;
- }
-
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- // If this tap was actually used to show the IMM, leave cursor or selection unchanged
- // by restoring its previous position.
- if (resultCode == InputMethodManager.RESULT_SHOWN) {
- final int len = mText.length();
- int start = Math.min(len, mPrevStart);
- int end = Math.min(len, mPrevEnd);
- Selection.setSelection((Spannable)mText, start, end);
-
- boolean selectAllGotFocus = mSelectAllOnFocus && mTouchFocusSelected;
- if (hasSelection() && !selectAllGotFocus) {
- startSelectionActionMode();
- }
- }
- }
- }
-
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
@@ -7393,10 +7339,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
&& mText instanceof Spannable && mLayout != null) {
boolean handled = false;
- // Save previous selection, in case this event is used to show the IME.
- int oldSelStart = getSelectionStart();
- int oldSelEnd = getSelectionEnd();
-
final int oldScrollX = mScrollX;
final int oldScrollY = mScrollY;
@@ -7428,22 +7370,21 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if (touchIsFinished) {
- CommitSelectionReceiver csr = null;
- if (getSelectionStart() != oldSelStart || getSelectionEnd() != oldSelEnd ||
- didTouchFocusSelect()) {
- csr = new CommitSelectionReceiver(oldSelStart, oldSelEnd);
- }
-
// Show the IME, except when selecting in read-only text.
if (!mTextIsSelectable) {
final InputMethodManager imm = InputMethodManager.peekInstance();
- handled |= imm != null && imm.showSoftInput(this, 0, csr) && (csr != null);
+ handled |= imm != null && imm.showSoftInput(this, 0);
}
- stopSelectionActionMode();
- boolean selectAllGotFocus = mSelectAllOnFocus && mTouchFocusSelected;
- if (hasInsertionController() && !selectAllGotFocus && mText.length() > 0) {
- getInsertionController().show();
+
+ boolean selectAllGotFocus = mSelectAllOnFocus && didTouchFocusSelect();
+ if (!selectAllGotFocus && hasSelection()) {
+ startSelectionActionMode();
+ } else {
+ stopSelectionActionMode();
+ if (hasInsertionController() && !selectAllGotFocus && mText.length() > 0) {
+ getInsertionController().show();
+ }
}
}
}
@@ -7544,17 +7485,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
TextView tv = mView.get();
- if (tv != null && tv.isFocused()) {
- int st = tv.getSelectionStart();
- int en = tv.getSelectionEnd();
-
- if (st == en && st >= 0 && en >= 0) {
- if (tv.mLayout != null) {
- tv.invalidateCursorPath();
- }
-
- postAtTime(this, SystemClock.uptimeMillis() + BLINK);
+ if (tv != null && tv.shouldBlink()) {
+ if (tv.mLayout != null) {
+ tv.invalidateCursorPath();
}
+
+ postAtTime(this, SystemClock.uptimeMillis() + BLINK);
}
}
@@ -7570,6 +7506,34 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
+ /**
+ * @return True when the TextView isFocused and has a valid zero-length selection (cursor).
+ */
+ private boolean shouldBlink() {
+ if (!isFocused()) return false;
+
+ final int start = getSelectionStart();
+ if (start < 0) return false;
+
+ final int end = getSelectionEnd();
+ if (end < 0) return false;
+
+ return start == end;
+ }
+
+ private void makeBlink() {
+ if (isCursorVisible()) {
+ if (shouldBlink()) {
+ mShowCursor = SystemClock.uptimeMillis();
+ if (mBlink == null) mBlink = new Blink(this);
+ mBlink.removeCallbacks(mBlink);
+ mBlink.postAtTime(mBlink, mShowCursor + BLINK);
+ }
+ } else {
+ if (mBlink != null) mBlink.removeCallbacks(mBlink);
+ }
+ }
+
@Override
protected float getLeftFadingEdgeStrength() {
if (mCurrentAlpha <= ViewConfiguration.ALPHA_THRESHOLD_INT) return 0.0f;
@@ -8714,7 +8678,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Touch-up filter: number of previous positions remembered
private static final int HISTORY_SIZE = 5;
- private static final int TOUCH_UP_FILTER_DELAY = 150;
+ private static final int TOUCH_UP_FILTER_DELAY_AFTER = 150;
+ private static final int TOUCH_UP_FILTER_DELAY_BEFORE = 350;
private final long[] mPreviousOffsetsTimes = new long[HISTORY_SIZE];
private final int[] mPreviousOffsets = new int[HISTORY_SIZE];
private int mPreviousOffsetIndex = 0;
@@ -8741,15 +8706,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public void filterOnTouchUp() {
final long now = SystemClock.uptimeMillis();
int i = 0;
- int index = 0;
+ int index = mPreviousOffsetIndex;
final int iMax = Math.min(mNumberPreviousOffsets, HISTORY_SIZE);
- while (i < iMax) {
- index = (mPreviousOffsetIndex - i + HISTORY_SIZE) % HISTORY_SIZE;
- if ((now - mPreviousOffsetsTimes[index]) >= TOUCH_UP_FILTER_DELAY) break;
+ while (i < iMax && (now - mPreviousOffsetsTimes[index]) < TOUCH_UP_FILTER_DELAY_AFTER) {
i++;
+ index = (mPreviousOffsetIndex - i + HISTORY_SIZE) % HISTORY_SIZE;
}
- mController.updateOffset(this, mPreviousOffsets[index]);
+ if (i > 0 && i < iMax &&
+ (now - mPreviousOffsetsTimes[index]) > TOUCH_UP_FILTER_DELAY_BEFORE) {
+ mController.updateOffset(this, mPreviousOffsets[index]);
+ }
}
public static final int LEFT = 0;
@@ -8771,40 +8738,40 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public void setOrientation(int pos) {
int handleWidth;
switch (pos) {
- case LEFT: {
- if (mSelectHandleLeft == null) {
- mSelectHandleLeft = mContext.getResources().getDrawable(
- mTextSelectHandleLeftRes);
+ case LEFT: {
+ if (mSelectHandleLeft == null) {
+ mSelectHandleLeft = mContext.getResources().getDrawable(
+ mTextSelectHandleLeftRes);
+ }
+ mDrawable = mSelectHandleLeft;
+ handleWidth = mDrawable.getIntrinsicWidth();
+ mHotspotX = handleWidth * 3.0f / 4.0f;
+ break;
}
- mDrawable = mSelectHandleLeft;
- handleWidth = mDrawable.getIntrinsicWidth();
- mHotspotX = handleWidth * 3.0f / 4.0f;
- break;
- }
- case RIGHT: {
- if (mSelectHandleRight == null) {
- mSelectHandleRight = mContext.getResources().getDrawable(
- mTextSelectHandleRightRes);
+ case RIGHT: {
+ if (mSelectHandleRight == null) {
+ mSelectHandleRight = mContext.getResources().getDrawable(
+ mTextSelectHandleRightRes);
+ }
+ mDrawable = mSelectHandleRight;
+ handleWidth = mDrawable.getIntrinsicWidth();
+ mHotspotX = handleWidth / 4.0f;
+ break;
}
- mDrawable = mSelectHandleRight;
- handleWidth = mDrawable.getIntrinsicWidth();
- mHotspotX = handleWidth / 4.0f;
- break;
- }
- case CENTER:
- default: {
- if (mSelectHandleCenter == null) {
- mSelectHandleCenter = mContext.getResources().getDrawable(
- mTextSelectHandleRes);
+ case CENTER:
+ default: {
+ if (mSelectHandleCenter == null) {
+ mSelectHandleCenter = mContext.getResources().getDrawable(
+ mTextSelectHandleRes);
+ }
+ mDrawable = mSelectHandleCenter;
+ handleWidth = mDrawable.getIntrinsicWidth();
+ mHotspotX = handleWidth / 2.0f;
+ mIsInsertionHandle = true;
+ break;
}
- mDrawable = mSelectHandleCenter;
- handleWidth = mDrawable.getIntrinsicWidth();
- mHotspotX = handleWidth / 2.0f;
- mIsInsertionHandle = true;
- break;
- }
}
final int handleHeight = mDrawable.getIntrinsicHeight();
@@ -8984,11 +8951,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mIsInsertionHandle) {
long delay = SystemClock.uptimeMillis() - mTouchTimer;
if (delay < ViewConfiguration.getTapTimeout()) {
- if (mPastePopupWindow != null && mPastePopupWindow.isShowing()) {
- // Tapping on the handle dismisses the displayed paste view,
- mPastePopupWindow.hide();
- } else {
- ((InsertionPointCursorController) mController).show(0);
+ final float deltaX = mDownPositionX - ev.getRawX();
+ final float deltaY = mDownPositionY - ev.getRawY();
+ final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
+ if (distanceSquared < mSquaredTouchSlopDistance) {
+ if (mPastePopupWindow != null && mPastePopupWindow.isShowing()) {
+ // Tapping on the handle dismisses the displayed paste view,
+ mPastePopupWindow.hide();
+ } else {
+ ((InsertionPointCursorController) mController).show(0);
+ }
}
}
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index b3b80f66838f..1cca21d79922 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -194,7 +194,7 @@ public final class BatteryStatsImpl extends BatteryStats {
int mPhoneSignalStrengthBin = -1;
int mPhoneSignalStrengthBinRaw = -1;
final StopwatchTimer[] mPhoneSignalStrengthsTimer =
- new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS];
+ new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
StopwatchTimer mPhoneSignalScanningTimer;
@@ -1659,7 +1659,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
void stopAllSignalStrengthTimersLocked(int except) {
- for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
if (i == except) {
continue;
}
@@ -1674,7 +1674,7 @@ public final class BatteryStatsImpl extends BatteryStats {
// In this case we will always be STATE_OUT_OF_SERVICE, so need
// to infer that we are scanning from other data.
if (state == ServiceState.STATE_OUT_OF_SERVICE
- && signalBin > SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
state = ServiceState.STATE_IN_SERVICE;
}
}
@@ -1694,7 +1694,7 @@ public final class BatteryStatsImpl extends BatteryStats {
// In this case we will always be STATE_OUT_OF_SERVICE, so need
// to infer that we are scanning from other data.
if (state == ServiceState.STATE_OUT_OF_SERVICE
- && bin > SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ && bin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
state = ServiceState.STATE_IN_SERVICE;
}
}
@@ -1711,7 +1711,7 @@ public final class BatteryStatsImpl extends BatteryStats {
// bin and have the scanning bit set.
} else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
scanning = true;
- bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ bin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
if (!mPhoneSignalScanningTimer.isRunningLocked()) {
mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
newHistory = true;
@@ -1775,24 +1775,7 @@ public final class BatteryStatsImpl extends BatteryStats {
public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
// Bin the strength.
- int bin;
-
- if (!signalStrength.isGsm()) {
- int dBm = signalStrength.getCdmaDbm();
- if (dBm >= -75) bin = SIGNAL_STRENGTH_GREAT;
- else if (dBm >= -85) bin = SIGNAL_STRENGTH_GOOD;
- else if (dBm >= -95) bin = SIGNAL_STRENGTH_MODERATE;
- else if (dBm >= -100) bin = SIGNAL_STRENGTH_POOR;
- else bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- } else {
- int asu = signalStrength.getGsmSignalStrength();
- if (asu < 0 || asu >= 99) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- else if (asu >= 16) bin = SIGNAL_STRENGTH_GREAT;
- else if (asu >= 8) bin = SIGNAL_STRENGTH_GOOD;
- else if (asu >= 4) bin = SIGNAL_STRENGTH_MODERATE;
- else bin = SIGNAL_STRENGTH_POOR;
- }
-
+ int bin = signalStrength.getLevel();
updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
}
@@ -3903,7 +3886,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mInputEventCounter = new Counter(mUnpluggables);
mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables);
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables);
}
mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables);
@@ -4017,7 +4000,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mPhoneOnTimer.reset(this, false);
mAudioOnTimer.reset(this, false);
mVideoOnTimer.reset(this, false);
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].reset(this, false);
}
mPhoneSignalScanningTimer.reset(this, false);
@@ -4780,7 +4763,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mInputEventCounter.readSummaryFromParcelLocked(in);
mPhoneOn = false;
mPhoneOnTimer.readSummaryFromParcelLocked(in);
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
}
mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
@@ -4973,7 +4956,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mInputEventCounter.writeSummaryFromParcelLocked(out);
mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
}
mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
@@ -5172,7 +5155,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mInputEventCounter = new Counter(mUnpluggables, in);
mPhoneOn = false;
mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
null, mUnpluggables, in);
}
@@ -5285,7 +5268,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mInputEventCounter.writeToParcel(out);
mPhoneOnTimer.writeToParcel(out, batteryRealtime);
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
}
mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
@@ -5382,7 +5365,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mInputEventCounter.logState(pr, " ");
pr.println("*** Phone timer:");
mPhoneOnTimer.logState(pr, " ");
- for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
+ for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
pr.println("*** Signal strength #" + i + ":");
mPhoneSignalStrengthsTimer[i].logState(pr, " ");
}
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 6c9e7bb02dd9..04a059e720e8 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -36,14 +36,15 @@ import java.lang.ref.WeakReference;
* @hide
*/
public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.OnKeyListener,
- ViewTreeObserver.OnGlobalLayoutListener, PopupWindow.OnDismissListener {
+ ViewTreeObserver.OnGlobalLayoutListener, PopupWindow.OnDismissListener,
+ View.OnAttachStateChangeListener {
private static final String TAG = "MenuPopupHelper";
private Context mContext;
private ListPopupWindow mPopup;
private MenuBuilder mMenu;
private int mPopupMaxWidth;
- private WeakReference<View> mAnchorView;
+ private View mAnchorView;
private boolean mOverflowOnly;
private ViewTreeObserver mTreeObserver;
@@ -66,13 +67,11 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
mPopupMaxWidth = metrics.widthPixels / 2;
- if (anchorView != null) {
- mAnchorView = new WeakReference<View>(anchorView);
- }
+ mAnchorView = anchorView;
}
public void setAnchorView(View anchor) {
- mAnchorView = new WeakReference<View>(anchor);
+ mAnchorView = anchor;
}
public void show() {
@@ -92,19 +91,19 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
mPopup.setAdapter(adapter);
mPopup.setModal(true);
- View anchor = mAnchorView != null ? mAnchorView.get() : null;
+ View anchor = mAnchorView;
if (anchor == null && mMenu instanceof SubMenuBuilder) {
SubMenuBuilder subMenu = (SubMenuBuilder) mMenu;
final MenuItemImpl itemImpl = (MenuItemImpl) subMenu.getItem();
anchor = itemImpl.getItemView(MenuBuilder.TYPE_ACTION_BUTTON, null);
- mAnchorView = new WeakReference<View>(anchor);
+ mAnchorView = anchor;
}
if (anchor != null) {
- if (mTreeObserver == null) {
- mTreeObserver = anchor.getViewTreeObserver();
- mTreeObserver.addOnGlobalLayoutListener(this);
- }
+ final boolean addGlobalListener = mTreeObserver == null;
+ mTreeObserver = anchor.getViewTreeObserver(); // Refresh to latest
+ if (addGlobalListener) mTreeObserver.addOnGlobalLayoutListener(this);
+ anchor.addOnAttachStateChangeListener(this);
mPopup.setAnchorView(anchor);
} else {
return false;
@@ -125,10 +124,12 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
public void onDismiss() {
mPopup = null;
- if (mTreeObserver != null && mTreeObserver.isAlive()) {
+ if (mTreeObserver != null) {
+ if (!mTreeObserver.isAlive()) mTreeObserver = mAnchorView.getViewTreeObserver();
mTreeObserver.removeGlobalOnLayoutListener(this);
+ mTreeObserver = null;
}
- mTreeObserver = null;
+ mAnchorView.removeOnAttachStateChangeListener(this);
}
public boolean isShowing() {
@@ -187,13 +188,8 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
@Override
public void onGlobalLayout() {
- if (!isShowing()) {
- if (mTreeObserver.isAlive()) {
- mTreeObserver.removeGlobalOnLayoutListener(this);
- }
- mTreeObserver = null;
- } else {
- final View anchor = mAnchorView != null ? mAnchorView.get() : null;
+ if (isShowing()) {
+ final View anchor = mAnchorView;
if (anchor == null || !anchor.isShown()) {
dismiss();
} else if (isShowing()) {
@@ -202,4 +198,17 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
}
}
}
+
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ if (mTreeObserver != null) {
+ if (!mTreeObserver.isAlive()) mTreeObserver = v.getViewTreeObserver();
+ mTreeObserver.removeGlobalOnLayoutListener(this);
+ }
+ v.removeOnAttachStateChangeListener(this);
+ }
}
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index 0b765fdfab27..c72d0e82c8bc 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -27,6 +27,7 @@ import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
+import android.view.MotionEvent.PointerCoords;
import java.util.ArrayList;
@@ -43,7 +44,7 @@ public class PointerLocationView extends View {
private boolean mCurDown;
// Most recent coordinates.
- private MotionEvent.PointerCoords mCoords = new MotionEvent.PointerCoords();
+ private PointerCoords mCoords = new PointerCoords();
// Most recent velocity.
private float mXVelocity;
@@ -86,6 +87,7 @@ public class PointerLocationView extends View {
private int mMaxNumPointers;
private int mActivePointerId;
private final ArrayList<PointerState> mPointers = new ArrayList<PointerState>();
+ private final PointerCoords mHoverCoords = new PointerCoords();
private final VelocityTracker mVelocity;
@@ -327,7 +329,10 @@ public class PointerLocationView extends View {
.append(" ToolMajor=").append(coords.toolMajor, 3)
.append(" ToolMinor=").append(coords.toolMinor, 3)
.append(" Orientation=").append((float)(coords.orientation * 180 / Math.PI), 1)
- .append("deg").toString());
+ .append("deg")
+ .append(" VScroll=").append(coords.getAxisValue(MotionEvent.AXIS_VSCROLL), 1)
+ .append(" HScroll=").append(coords.getAxisValue(MotionEvent.AXIS_HSCROLL), 1)
+ .toString());
}
public void addTouchEvent(MotionEvent event) {
@@ -383,9 +388,11 @@ public class PointerLocationView extends View {
}
final int NI = event.getPointerCount();
-
+
+ final boolean hover = (action == MotionEvent.ACTION_HOVER_MOVE);
mCurDown = action != MotionEvent.ACTION_UP
- && action != MotionEvent.ACTION_CANCEL;
+ && action != MotionEvent.ACTION_CANCEL
+ && !hover;
mCurNumPointers = mCurDown ? NI : 0;
if (mMaxNumPointers < mCurNumPointers) {
mMaxNumPointers = mCurNumPointers;
@@ -396,22 +403,27 @@ public class PointerLocationView extends View {
for (int i=0; i<NI; i++) {
final int id = event.getPointerId(i);
- final PointerState ps = mPointers.get(id);
+ final PointerState ps = hover ? null : mPointers.get(id);
+ final PointerCoords coords = ps != null ? ps.mCoords : mHoverCoords;
final int N = event.getHistorySize();
for (int j=0; j<N; j++) {
- event.getHistoricalPointerCoords(i, j, ps.mCoords);
+ event.getHistoricalPointerCoords(i, j, coords);
if (mPrintCoords) {
- logPointerCoords(ps.mCoords, id);
+ logPointerCoords(coords, id);
+ }
+ if (ps != null) {
+ ps.addTrace(event.getHistoricalX(i, j), event.getHistoricalY(i, j));
}
- ps.addTrace(event.getHistoricalX(i, j), event.getHistoricalY(i, j));
}
- event.getPointerCoords(i, ps.mCoords);
+ event.getPointerCoords(i, coords);
if (mPrintCoords) {
- logPointerCoords(ps.mCoords, id);
+ logPointerCoords(coords, id);
+ }
+ if (ps != null) {
+ ps.addTrace(coords.x, coords.y);
+ ps.mXVelocity = mVelocity.getXVelocity(id);
+ ps.mYVelocity = mVelocity.getYVelocity(id);
}
- ps.addTrace(ps.mCoords.x, ps.mCoords.y);
- ps.mXVelocity = mVelocity.getXVelocity(id);
- ps.mYVelocity = mVelocity.getYVelocity(id);
}
if (action == MotionEvent.ACTION_UP
diff --git a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
index bf2365094917..acf858aff440 100755
--- a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
+++ b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
@@ -89,40 +89,40 @@ static int setup_listening_socket(int dev, int channel);
#endif
static void classInitNative(JNIEnv* env, jclass clazz) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
/* in */
field_mNativeData = get_field(env, clazz, "mNativeData", "I");
- field_mHandsfreeAgRfcommChannel =
+ field_mHandsfreeAgRfcommChannel =
get_field(env, clazz, "mHandsfreeAgRfcommChannel", "I");
- field_mHeadsetAgRfcommChannel =
+ field_mHeadsetAgRfcommChannel =
get_field(env, clazz, "mHeadsetAgRfcommChannel", "I");
/* out */
- field_mConnectingHeadsetAddress =
- get_field(env, clazz,
+ field_mConnectingHeadsetAddress =
+ get_field(env, clazz,
"mConnectingHeadsetAddress", "Ljava/lang/String;");
- field_mConnectingHeadsetRfcommChannel =
+ field_mConnectingHeadsetRfcommChannel =
get_field(env, clazz, "mConnectingHeadsetRfcommChannel", "I");
- field_mConnectingHeadsetSocketFd =
+ field_mConnectingHeadsetSocketFd =
get_field(env, clazz, "mConnectingHeadsetSocketFd", "I");
- field_mConnectingHandsfreeAddress =
- get_field(env, clazz,
+ field_mConnectingHandsfreeAddress =
+ get_field(env, clazz,
"mConnectingHandsfreeAddress", "Ljava/lang/String;");
- field_mConnectingHandsfreeRfcommChannel =
+ field_mConnectingHandsfreeRfcommChannel =
get_field(env, clazz, "mConnectingHandsfreeRfcommChannel", "I");
- field_mConnectingHandsfreeSocketFd =
+ field_mConnectingHandsfreeSocketFd =
get_field(env, clazz, "mConnectingHandsfreeSocketFd", "I");
- field_mTimeoutRemainingMs =
+ field_mTimeoutRemainingMs =
get_field(env, clazz, "mTimeoutRemainingMs", "I");
#endif
}
static void initializeNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -150,7 +150,7 @@ static void initializeNativeDataNative(JNIEnv* env, jobject object) {
}
static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -165,7 +165,7 @@ static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
static int set_nb(int sk, bool nb) {
int flags = fcntl(sk, F_GETFL);
if (flags < 0) {
- LOGE("Can't get socket flags with fcntl(): %s (%d)",
+ LOGE("Can't get socket flags with fcntl(): %s (%d)",
strerror(errno), errno);
close(sk);
return -1;
@@ -255,7 +255,7 @@ static inline int on_accept_set_fields(JNIEnv* env, jobject object,
static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
jint timeout_ms) {
-// LOGV(__FUNCTION__);
+// LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
env->SetIntField(object, field_mTimeoutRemainingMs, timeout_ms);
@@ -264,11 +264,11 @@ static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
native_data_t *nat = get_native_data(env, object);
#if USE_ACCEPT_DIRECTLY
if (nat->hf_ag_rfcomm_channel > 0) {
- LOGI("Setting HF AG server socket to RFCOMM port %d!",
+ LOGI("Setting HF AG server socket to RFCOMM port %d!",
nat->hf_ag_rfcomm_channel);
struct timeval tv;
int len = sizeof(tv);
- if (getsockopt(nat->hf_ag_rfcomm_channel,
+ if (getsockopt(nat->hf_ag_rfcomm_channel,
SOL_SOCKET, SO_RCVTIMEO, &tv, &len) < 0) {
LOGE("getsockopt(%d, SOL_SOCKET, SO_RCVTIMEO): %s (%d)",
nat->hf_ag_rfcomm_channel,
@@ -276,12 +276,12 @@ static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
errno);
return JNI_FALSE;
}
- LOGI("Current HF AG server socket RCVTIMEO is (%d(s), %d(us))!",
+ LOGI("Current HF AG server socket RCVTIMEO is (%d(s), %d(us))!",
(int)tv.tv_sec, (int)tv.tv_usec);
if (timeout_ms >= 0) {
tv.tv_sec = timeout_ms / 1000;
tv.tv_usec = 1000 * (timeout_ms % 1000);
- if (setsockopt(nat->hf_ag_rfcomm_channel,
+ if (setsockopt(nat->hf_ag_rfcomm_channel,
SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
LOGE("setsockopt(%d, SOL_SOCKET, SO_RCVTIMEO): %s (%d)",
nat->hf_ag_rfcomm_channel,
@@ -289,11 +289,11 @@ static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
errno);
return JNI_FALSE;
}
- LOGI("Changed HF AG server socket RCVTIMEO to (%d(s), %d(us))!",
+ LOGI("Changed HF AG server socket RCVTIMEO to (%d(s), %d(us))!",
(int)tv.tv_sec, (int)tv.tv_usec);
}
- if (!do_accept(env, object, nat->hf_ag_rfcomm_sock,
+ if (!do_accept(env, object, nat->hf_ag_rfcomm_sock,
field_mConnectingHandsfreeSocketFd,
field_mConnectingHandsfreeAddress,
field_mConnectingHandsfreeRfcommChannel))
@@ -309,13 +309,13 @@ static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
FD_ZERO(&rset);
int cnt = 0;
if (nat->hf_ag_rfcomm_channel > 0) {
- LOGI("Setting HF AG server socket to RFCOMM port %d!",
+ LOGI("Setting HF AG server socket to RFCOMM port %d!",
nat->hf_ag_rfcomm_channel);
cnt++;
FD_SET(nat->hf_ag_rfcomm_sock, &rset);
}
if (nat->hs_ag_rfcomm_channel > 0) {
- LOGI("Setting HS AG server socket to RFCOMM port %d!",
+ LOGI("Setting HS AG server socket to RFCOMM port %d!",
nat->hs_ag_rfcomm_channel);
cnt++;
FD_SET(nat->hs_ag_rfcomm_sock, &rset);
@@ -330,7 +330,7 @@ static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
to.tv_sec = timeout_ms / 1000;
to.tv_usec = 1000 * (timeout_ms % 1000);
}
- n = select(MAX(nat->hf_ag_rfcomm_sock,
+ n = select(MAX(nat->hf_ag_rfcomm_sock,
nat->hs_ag_rfcomm_sock) + 1,
&rset,
NULL,
@@ -354,7 +354,7 @@ static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
return JNI_FALSE;
}
- n = on_accept_set_fields(env, object,
+ n = on_accept_set_fields(env, object,
&rset, nat->hf_ag_rfcomm_sock,
field_mConnectingHandsfreeSocketFd,
field_mConnectingHandsfreeAddress,
@@ -371,7 +371,7 @@ static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
struct pollfd fds[2];
int cnt = 0;
if (nat->hf_ag_rfcomm_channel > 0) {
-// LOGI("Setting HF AG server socket %d to RFCOMM port %d!",
+// LOGI("Setting HF AG server socket %d to RFCOMM port %d!",
// nat->hf_ag_rfcomm_sock,
// nat->hf_ag_rfcomm_channel);
fds[cnt].fd = nat->hf_ag_rfcomm_sock;
@@ -379,7 +379,7 @@ static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
cnt++;
}
if (nat->hs_ag_rfcomm_channel > 0) {
-// LOGI("Setting HS AG server socket %d to RFCOMM port %d!",
+// LOGI("Setting HS AG server socket %d to RFCOMM port %d!",
// nat->hs_ag_rfcomm_sock,
// nat->hs_ag_rfcomm_channel);
fds[cnt].fd = nat->hs_ag_rfcomm_sock;
@@ -411,7 +411,7 @@ static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
if (fds[cnt].fd == nat->hf_ag_rfcomm_sock) {
if (fds[cnt].revents & (POLLIN | POLLPRI | POLLOUT)) {
LOGI("Accepting HF connection.\n");
- err += do_accept(env, object, fds[cnt].fd,
+ err += do_accept(env, object, fds[cnt].fd,
field_mConnectingHandsfreeSocketFd,
field_mConnectingHandsfreeAddress,
field_mConnectingHandsfreeRfcommChannel);
@@ -421,7 +421,7 @@ static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
else if (fds[cnt].fd == nat->hs_ag_rfcomm_sock) {
if (fds[cnt].revents & (POLLIN | POLLPRI | POLLOUT)) {
LOGI("Accepting HS connection.\n");
- err += do_accept(env, object, fds[cnt].fd,
+ err += do_accept(env, object, fds[cnt].fd,
field_mConnectingHeadsetSocketFd,
field_mConnectingHeadsetAddress,
field_mConnectingHeadsetRfcommChannel);
@@ -444,7 +444,7 @@ static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
}
static jboolean setUpListeningSocketsNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
@@ -509,7 +509,7 @@ static int setup_listening_socket(int dev, int channel) {
private native void tearDownListeningSocketsNative();
*/
static void tearDownListeningSocketsNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
diff --git a/core/jni/android_bluetooth_BluetoothSocket.cpp b/core/jni/android_bluetooth_BluetoothSocket.cpp
index 31ebf8ca58cc..b87f7c4a62c0 100644
--- a/core/jni/android_bluetooth_BluetoothSocket.cpp
+++ b/core/jni/android_bluetooth_BluetoothSocket.cpp
@@ -66,7 +66,7 @@ static struct asocket *get_socketData(JNIEnv *env, jobject obj) {
static void initSocketFromFdNative(JNIEnv *env, jobject obj, jint fd) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
struct asocket *s = asocket_init(fd);
@@ -85,7 +85,7 @@ static void initSocketFromFdNative(JNIEnv *env, jobject obj, jint fd) {
static void initSocketNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int fd;
int lm = 0;
@@ -161,7 +161,7 @@ static void initSocketNative(JNIEnv *env, jobject obj) {
static void connectNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int ret;
jint type;
@@ -240,7 +240,7 @@ static void connectNative(JNIEnv *env, jobject obj) {
/* Returns errno instead of throwing, so java can check errno */
static int bindListenNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
jint type;
socklen_t addr_sz;
@@ -307,7 +307,7 @@ static int bindListenNative(JNIEnv *env, jobject obj) {
static jobject acceptNative(JNIEnv *env, jobject obj, int timeout) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int fd;
jint type;
@@ -380,7 +380,7 @@ static jobject acceptNative(JNIEnv *env, jobject obj, int timeout) {
static jint availableNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int available;
struct asocket *s = get_socketData(env, obj);
@@ -403,7 +403,7 @@ static jint availableNative(JNIEnv *env, jobject obj) {
static jint readNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
jint length) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int ret;
jbyte *b;
@@ -446,7 +446,7 @@ static jint readNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
static jint writeNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
jint length) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int ret;
jbyte *b;
@@ -488,7 +488,7 @@ static jint writeNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
static void abortNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
struct asocket *s = get_socketData(env, obj);
if (!s)
@@ -504,7 +504,7 @@ static void abortNative(JNIEnv *env, jobject obj) {
static void destroyNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
struct asocket *s = get_socketData(env, obj);
int fd = s->fd;
diff --git a/core/jni/android_bluetooth_HeadsetBase.cpp b/core/jni/android_bluetooth_HeadsetBase.cpp
index 4e9fbaf1bd62..bbf1ae5f8e41 100644
--- a/core/jni/android_bluetooth_HeadsetBase.cpp
+++ b/core/jni/android_bluetooth_HeadsetBase.cpp
@@ -180,7 +180,7 @@ again:
#endif
static void classInitNative(JNIEnv* env, jclass clazz) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
field_mNativeData = get_field(env, clazz, "mNativeData", "I");
field_mAddress = get_field(env, clazz, "mAddress", "Ljava/lang/String;");
@@ -191,7 +191,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
static void initializeNativeDataNative(JNIEnv* env, jobject object,
jint socketFd) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -213,7 +213,7 @@ static void initializeNativeDataNative(JNIEnv* env, jobject object,
}
static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -226,7 +226,7 @@ static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
static jboolean connectNative(JNIEnv *env, jobject obj)
{
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
int lm;
struct sockaddr_rc addr;
@@ -278,7 +278,7 @@ static jboolean connectNative(JNIEnv *env, jobject obj)
}
static jint connectAsyncNative(JNIEnv *env, jobject obj) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
struct sockaddr_rc addr;
native_data_t *nat = get_native_data(env, obj);
@@ -357,7 +357,7 @@ static jint connectAsyncNative(JNIEnv *env, jobject obj) {
static jint waitForAsyncConnectNative(JNIEnv *env, jobject obj,
jint timeout_ms) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
struct sockaddr_rc addr;
native_data_t *nat = get_native_data(env, obj);
@@ -463,7 +463,7 @@ static jint waitForAsyncConnectNative(JNIEnv *env, jobject obj,
}
static void disconnectNative(JNIEnv *env, jobject obj) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, obj);
if (nat->rfcomm_sock >= 0) {
diff --git a/core/jni/android_net_TrafficStats.cpp b/core/jni/android_net_TrafficStats.cpp
index dfa36cee8176..0c84f1138e7c 100644
--- a/core/jni/android_net_TrafficStats.cpp
+++ b/core/jni/android_net_TrafficStats.cpp
@@ -130,6 +130,33 @@ static jlong getMobileRxBytes(JNIEnv* env, jobject clazz) {
"/sys/class/net/ppp0/statistics/rx_bytes");
}
+static jlong getData(JNIEnv* env, char *what, jstring interface) {
+ char filename[80];
+ jboolean isCopy;
+
+ const char *interfaceStr = env->GetStringUTFChars(interface, &isCopy);
+ snprintf(filename, sizeof(filename), "/sys/class/net/%s/statistics/%s", interfaceStr, what);
+
+ return readNumber(filename);
+}
+
+static jlong getTxPackets(JNIEnv* env, jobject clazz, jstring interface) {
+ return getData(env, "tx_packets", interface);
+}
+
+static jlong getRxPackets(JNIEnv* env, jobject clazz, jstring interface) {
+ return getData(env, "rx_packets", interface);
+}
+
+static jlong getTxBytes(JNIEnv* env, jobject clazz, jstring interface) {
+ return getData(env, "tx_bytes", interface);
+}
+
+static jlong getRxBytes(JNIEnv* env, jobject clazz, jstring interface) {
+ return getData(env, "rx_bytes", interface);
+}
+
+
// Total stats are read less often, so we're willing to put up
// with listing the directory and concatenating filenames.
@@ -288,6 +315,10 @@ static JNINativeMethod gMethods[] = {
{"getMobileRxPackets", "()J", (void*) getMobileRxPackets},
{"getMobileTxBytes", "()J", (void*) getMobileTxBytes},
{"getMobileRxBytes", "()J", (void*) getMobileRxBytes},
+ {"getTxPackets", "(Ljava/lang/String;)J", (void*) getTxPackets},
+ {"getRxPackets", "(Ljava/lang/String;)J", (void*) getRxPackets},
+ {"getTxBytes", "(Ljava/lang/String;)J", (void*) getTxBytes},
+ {"getRxBytes", "(Ljava/lang/String;)J", (void*) getRxBytes},
{"getTotalTxPackets", "()J", (void*) getTotalTxPackets},
{"getTotalRxPackets", "()J", (void*) getTotalRxPackets},
{"getTotalTxBytes", "()J", (void*) getTotalTxBytes},
diff --git a/core/jni/android_server_BluetoothA2dpService.cpp b/core/jni/android_server_BluetoothA2dpService.cpp
index 8c795afe3ee4..1851ad69fc8b 100644
--- a/core/jni/android_server_BluetoothA2dpService.cpp
+++ b/core/jni/android_server_BluetoothA2dpService.cpp
@@ -61,7 +61,7 @@ static Properties sink_properties[] = {
* Return false if dbus is down, or another serious error (out of memory)
*/
static bool initNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -88,7 +88,7 @@ static bool initNative(JNIEnv* env, jobject object) {
static void cleanupNative(JNIEnv* env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
dbus_connection_close(nat->conn);
env->DeleteGlobalRef(nat->me);
@@ -101,7 +101,7 @@ static void cleanupNative(JNIEnv* env, jobject object) {
static jobjectArray getSinkPropertiesNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
DBusMessage *msg, *reply;
DBusError err;
@@ -132,7 +132,7 @@ static jobjectArray getSinkPropertiesNative(JNIEnv *env, jobject object,
static jboolean connectSinkNative(JNIEnv *env, jobject object, jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
int len = env->GetStringLength(path) + 1;
@@ -153,7 +153,7 @@ static jboolean connectSinkNative(JNIEnv *env, jobject object, jstring path) {
static jboolean disconnectSinkNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
@@ -171,7 +171,7 @@ static jboolean disconnectSinkNative(JNIEnv *env, jobject object,
static jboolean suspendSinkNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
@@ -187,7 +187,7 @@ static jboolean suspendSinkNative(JNIEnv *env, jobject object,
static jboolean resumeSinkNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
@@ -203,7 +203,7 @@ static jboolean resumeSinkNative(JNIEnv *env, jobject object,
static jboolean avrcpVolumeUpNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
@@ -219,7 +219,7 @@ static jboolean avrcpVolumeUpNative(JNIEnv *env, jobject object,
static jboolean avrcpVolumeDownNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
@@ -278,7 +278,7 @@ DBusHandlerResult a2dp_event_filter(DBusMessage *msg, JNIEnv *env) {
}
void onConnectSinkResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *path = (const char *)user;
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index fd12c2d736f8..afaade8b21ee 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -88,7 +88,7 @@ native_data_t *get_EventLoop_native_data(JNIEnv *env, jobject object) {
#endif
static void classInitNative(JNIEnv* env, jclass clazz) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
method_onPropertyChanged = env->GetMethodID(clazz, "onPropertyChanged",
@@ -147,7 +147,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
}
static void initializeNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -175,7 +175,7 @@ static void initializeNativeDataNative(JNIEnv* env, jobject object) {
}
static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -216,7 +216,7 @@ static short dbus_flags_to_unix_events(unsigned int flags) {
}
static jboolean setUpEventLoop(native_data_t *nat) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat != NULL && nat->conn != NULL) {
dbus_threads_init_default();
@@ -395,7 +395,7 @@ static int register_agent(native_data_t *nat,
}
static void tearDownEventLoop(native_data_t *nat) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat != NULL && nat->conn != NULL) {
DBusMessage *msg, *reply;
@@ -1229,7 +1229,7 @@ success:
#ifdef HAVE_BLUETOOTH
void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *address = (const char *)user;
@@ -1298,7 +1298,7 @@ done:
}
void onCreateDeviceResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *address= (const char *)user;
@@ -1328,7 +1328,7 @@ void onCreateDeviceResult(DBusMessage *msg, void *user, void *n) {
}
void onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *path = (const char *)user;
@@ -1354,7 +1354,7 @@ void onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) {
}
void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
const char *address = (const char *) user;
native_data_t *nat = (native_data_t *) n;
@@ -1387,7 +1387,7 @@ done:
}
void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *path = (const char *)user;
@@ -1426,7 +1426,7 @@ void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
}
void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *path = (const char *)user;
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index bf0504f7c8cc..158e47573c52 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -1,16 +1,16 @@
/*
** Copyright 2006, The Android Open Source Project
**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
**
-** http://www.apache.org/licenses/LICENSE-2.0
+** http://www.apache.org/licenses/LICENSE-2.0
**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
** limitations under the License.
*/
@@ -93,7 +93,7 @@ static inline native_data_t * get_native_data(JNIEnv *env, jobject object) {
#endif
static void classInitNative(JNIEnv* env, jclass clazz) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
field_mNativeData = get_field(env, clazz, "mNativeData", "I");
field_mEventLoop = get_field(env, clazz, "mEventLoop",
@@ -105,7 +105,7 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
* Return false if dbus is down, or another serious error (out of memory)
*/
static bool initializeNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -144,7 +144,7 @@ static const char *get_adapter_path(JNIEnv* env, jobject object) {
// This function is called when the adapter is enabled.
static jboolean setupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -167,7 +167,7 @@ static jboolean setupNativeDataNative(JNIEnv* env, jobject object) {
}
static jboolean tearDownNativeDataNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -181,7 +181,7 @@ static jboolean tearDownNativeDataNative(JNIEnv *env, jobject object) {
}
static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -193,7 +193,7 @@ static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
}
static jstring getAdapterPathNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -205,7 +205,7 @@ static jstring getAdapterPathNative(JNIEnv *env, jobject object) {
static jboolean startDiscoveryNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
DBusMessage *msg = NULL;
DBusMessage *reply = NULL;
@@ -251,7 +251,7 @@ done:
}
static void stopDiscoveryNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
DBusMessage *msg = NULL;
DBusMessage *reply = NULL;
@@ -297,7 +297,7 @@ done:
}
static jbyteArray readAdapterOutOfBandDataNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
DBusError err;
@@ -338,7 +338,7 @@ static jbyteArray readAdapterOutOfBandDataNative(JNIEnv *env, jobject object) {
static jboolean createPairedDeviceNative(JNIEnv *env, jobject object,
jstring address, jint timeout_ms) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -374,7 +374,7 @@ static jboolean createPairedDeviceNative(JNIEnv *env, jobject object,
static jboolean createPairedDeviceOutOfBandNative(JNIEnv *env, jobject object,
jstring address, jint timeout_ms) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -411,7 +411,7 @@ static jint getDeviceServiceChannelNative(JNIEnv *env, jobject object,
jstring path,
jstring pattern, jint attr_id) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
struct event_loop_native_data_t *eventLoopNat =
@@ -437,7 +437,7 @@ static jint getDeviceServiceChannelNative(JNIEnv *env, jobject object,
static jboolean cancelDeviceCreationNative(JNIEnv *env, jobject object,
jstring address) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
jboolean result = JNI_FALSE;
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
@@ -469,7 +469,7 @@ static jboolean cancelDeviceCreationNative(JNIEnv *env, jobject object,
}
static jboolean removeDeviceNative(JNIEnv *env, jobject object, jstring object_path) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -492,7 +492,7 @@ static jboolean removeDeviceNative(JNIEnv *env, jobject object, jstring object_p
static jint enableNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
return bt_enable();
#endif
return -1;
@@ -500,7 +500,7 @@ static jint enableNative(JNIEnv *env, jobject object) {
static jint disableNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
return bt_disable();
#endif
return -1;
@@ -508,7 +508,7 @@ static jint disableNative(JNIEnv *env, jobject object) {
static jint isEnabledNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
return bt_is_enabled();
#endif
return -1;
@@ -518,7 +518,7 @@ static jboolean setPairingConfirmationNative(JNIEnv *env, jobject object,
jstring address, bool confirm,
int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -549,7 +549,7 @@ static jboolean setPairingConfirmationNative(JNIEnv *env, jobject object,
static jboolean setPasskeyNative(JNIEnv *env, jobject object, jstring address,
int passkey, int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -576,7 +576,7 @@ static jboolean setPasskeyNative(JNIEnv *env, jobject object, jstring address,
static jboolean setRemoteOutOfBandDataNative(JNIEnv *env, jobject object, jstring address,
jbyteArray hash, jbyteArray randomizer, int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -610,7 +610,7 @@ static jboolean setRemoteOutOfBandDataNative(JNIEnv *env, jobject object, jstrin
static jboolean setPinNative(JNIEnv *env, jobject object, jstring address,
jstring pin, int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -640,7 +640,7 @@ static jboolean setPinNative(JNIEnv *env, jobject object, jstring address,
static jboolean cancelPairingUserInputNative(JNIEnv *env, jobject object,
jstring address, int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -666,7 +666,7 @@ static jobjectArray getDevicePropertiesNative(JNIEnv *env, jobject object,
jstring path)
{
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg, *reply;
@@ -705,7 +705,7 @@ static jobjectArray getDevicePropertiesNative(JNIEnv *env, jobject object,
static jobjectArray getAdapterPropertiesNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg, *reply;
@@ -741,7 +741,7 @@ static jobjectArray getAdapterPropertiesNative(JNIEnv *env, jobject object) {
static jboolean setAdapterPropertyNative(JNIEnv *env, jobject object, jstring key,
void *value, jint type) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg;
@@ -808,7 +808,7 @@ static jboolean setAdapterPropertyBooleanNative(JNIEnv *env, jobject object, jst
static jboolean setDevicePropertyNative(JNIEnv *env, jobject object, jstring path,
jstring key, void *value, jint type) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *reply, *msg;
@@ -863,7 +863,7 @@ static jboolean setDevicePropertyBooleanNative(JNIEnv *env, jobject object,
static jboolean createDeviceNative(JNIEnv *env, jobject object,
jstring address) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -894,7 +894,7 @@ static jboolean createDeviceNative(JNIEnv *env, jobject object,
static jboolean discoverServicesNative(JNIEnv *env, jobject object,
jstring path, jstring pattern) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -955,7 +955,7 @@ static jintArray extract_handles(JNIEnv *env, DBusMessage *reply) {
static jintArray addReservedServiceRecordsNative(JNIEnv *env, jobject object,
jintArray uuids) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
DBusMessage *reply = NULL;
@@ -979,7 +979,7 @@ static jintArray addReservedServiceRecordsNative(JNIEnv *env, jobject object,
static jboolean removeReservedServiceRecordsNative(JNIEnv *env, jobject object,
jintArray handles) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jint *values = env->GetIntArrayElements(handles, NULL);
@@ -1002,7 +1002,7 @@ static jboolean removeReservedServiceRecordsNative(JNIEnv *env, jobject object,
static jint addRfcommServiceRecordNative(JNIEnv *env, jobject object,
jstring name, jlong uuidMsb, jlong uuidLsb, jshort channel) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -1027,7 +1027,7 @@ static jint addRfcommServiceRecordNative(JNIEnv *env, jobject object,
}
static jboolean removeServiceRecordNative(JNIEnv *env, jobject object, jint handle) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -1045,7 +1045,7 @@ static jboolean removeServiceRecordNative(JNIEnv *env, jobject object, jint hand
static jboolean setLinkTimeoutNative(JNIEnv *env, jobject object, jstring object_path,
jint num_slots) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -1064,7 +1064,7 @@ static jboolean setLinkTimeoutNative(JNIEnv *env, jobject object, jstring object
}
static jboolean connectInputDeviceNative(JNIEnv *env, jobject object, jstring path) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -1092,7 +1092,7 @@ static jboolean connectInputDeviceNative(JNIEnv *env, jobject object, jstring pa
static jboolean disconnectInputDeviceNative(JNIEnv *env, jobject object,
jstring path) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -1120,7 +1120,7 @@ static jboolean disconnectInputDeviceNative(JNIEnv *env, jobject object,
static jboolean setBluetoothTetheringNative(JNIEnv *env, jobject object, jboolean value,
jstring src_role, jstring bridge) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -1155,7 +1155,7 @@ static jboolean setBluetoothTetheringNative(JNIEnv *env, jobject object, jboolea
static jboolean connectPanDeviceNative(JNIEnv *env, jobject object, jstring path,
jstring dstRole) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
LOGE("connectPanDeviceNative");
native_data_t *nat = get_native_data(env, object);
@@ -1187,7 +1187,7 @@ static jboolean connectPanDeviceNative(JNIEnv *env, jobject object, jstring path
static jboolean disconnectPanDeviceNative(JNIEnv *env, jobject object,
jstring path) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
LOGE("disconnectPanDeviceNative");
native_data_t *nat = get_native_data(env, object);
@@ -1217,7 +1217,7 @@ static jboolean disconnectPanDeviceNative(JNIEnv *env, jobject object,
static jboolean disconnectPanServerDeviceNative(JNIEnv *env, jobject object,
jstring path, jstring address,
jstring iface) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
LOGE("disconnectPanServerDeviceNative");
native_data_t *nat = get_native_data(env, object);
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index 99fbbe979298..b01400628f19 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -188,27 +188,26 @@ static bool validatePointerCoords(JNIEnv* env, jobject pointerCoordsObj) {
static void pointerCoordsToNative(JNIEnv* env, jobject pointerCoordsObj,
float xOffset, float yOffset, PointerCoords* outRawPointerCoords) {
outRawPointerCoords->clear();
- outRawPointerCoords->setAxisValue(AINPUT_MOTION_AXIS_X,
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_X,
env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.x) - xOffset);
- outRawPointerCoords->setAxisValue(AINPUT_MOTION_AXIS_Y,
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_Y,
env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.y) - yOffset);
- outRawPointerCoords->setAxisValue(AINPUT_MOTION_AXIS_PRESSURE,
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.pressure));
- outRawPointerCoords->setAxisValue(AINPUT_MOTION_AXIS_SIZE,
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_SIZE,
env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.size));
- outRawPointerCoords->setAxisValue(AINPUT_MOTION_AXIS_TOUCH_MAJOR,
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR,
env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMajor));
- outRawPointerCoords->setAxisValue(AINPUT_MOTION_AXIS_TOUCH_MINOR,
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR,
env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.touchMinor));
- outRawPointerCoords->setAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR,
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR,
env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMajor));
- outRawPointerCoords->setAxisValue(AINPUT_MOTION_AXIS_TOOL_MINOR,
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR,
env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.toolMinor));
- outRawPointerCoords->setAxisValue(AINPUT_MOTION_AXIS_ORIENTATION,
+ outRawPointerCoords->setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
env->GetFloatField(pointerCoordsObj, gPointerCoordsClassInfo.orientation));
- uint32_t bits = env->GetIntField(pointerCoordsObj,
- gPointerCoordsClassInfo.mPackedAxisBits);
+ uint64_t bits = env->GetLongField(pointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits);
if (bits) {
jfloatArray valuesArray = jfloatArray(env->GetObjectField(pointerCoordsObj,
gPointerCoordsClassInfo.mPackedAxisValues));
@@ -218,8 +217,8 @@ static void pointerCoordsToNative(JNIEnv* env, jobject pointerCoordsObj,
uint32_t index = 0;
do {
- uint32_t axis = __builtin_ctz(bits);
- uint32_t axisBit = 1 << axis;
+ uint32_t axis = __builtin_ctzll(bits);
+ uint64_t axisBit = 1LL << axis;
bits &= ~axisBit;
outRawPointerCoords->setAxisValue(axis, values[index++]);
} while (bits);
@@ -254,39 +253,39 @@ static jfloatArray obtainPackedAxisValuesArray(JNIEnv* env, uint32_t minSize,
static void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointerCoords,
float xOffset, float yOffset, jobject outPointerCoordsObj) {
env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.x,
- rawPointerCoords->getAxisValue(AINPUT_MOTION_AXIS_X) + xOffset);
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset);
env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.y,
- rawPointerCoords->getAxisValue(AINPUT_MOTION_AXIS_Y) + yOffset);
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset);
env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.pressure,
- rawPointerCoords->getAxisValue(AINPUT_MOTION_AXIS_PRESSURE));
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.size,
- rawPointerCoords->getAxisValue(AINPUT_MOTION_AXIS_SIZE));
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_SIZE));
env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMajor,
- rawPointerCoords->getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MAJOR));
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR));
env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.touchMinor,
- rawPointerCoords->getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MINOR));
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR));
env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMajor,
- rawPointerCoords->getAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR));
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR));
env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.toolMinor,
- rawPointerCoords->getAxisValue(AINPUT_MOTION_AXIS_TOOL_MINOR));
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR));
env->SetFloatField(outPointerCoordsObj, gPointerCoordsClassInfo.orientation,
- rawPointerCoords->getAxisValue(AINPUT_MOTION_AXIS_ORIENTATION));
-
- const uint32_t unpackedAxisBits = 0
- | (1 << AINPUT_MOTION_AXIS_X)
- | (1 << AINPUT_MOTION_AXIS_Y)
- | (1 << AINPUT_MOTION_AXIS_PRESSURE)
- | (1 << AINPUT_MOTION_AXIS_SIZE)
- | (1 << AINPUT_MOTION_AXIS_TOUCH_MAJOR)
- | (1 << AINPUT_MOTION_AXIS_TOUCH_MINOR)
- | (1 << AINPUT_MOTION_AXIS_TOOL_MAJOR)
- | (1 << AINPUT_MOTION_AXIS_TOOL_MINOR)
- | (1 << AINPUT_MOTION_AXIS_ORIENTATION);
-
- uint32_t outBits = 0;
- uint32_t remainingBits = rawPointerCoords->bits & ~unpackedAxisBits;
+ rawPointerCoords->getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
+
+ const uint64_t unpackedAxisBits = 0
+ | (1LL << AMOTION_EVENT_AXIS_X)
+ | (1LL << AMOTION_EVENT_AXIS_Y)
+ | (1LL << AMOTION_EVENT_AXIS_PRESSURE)
+ | (1LL << AMOTION_EVENT_AXIS_SIZE)
+ | (1LL << AMOTION_EVENT_AXIS_TOUCH_MAJOR)
+ | (1LL << AMOTION_EVENT_AXIS_TOUCH_MINOR)
+ | (1LL << AMOTION_EVENT_AXIS_TOOL_MAJOR)
+ | (1LL << AMOTION_EVENT_AXIS_TOOL_MINOR)
+ | (1LL << AMOTION_EVENT_AXIS_ORIENTATION);
+
+ uint64_t outBits = 0;
+ uint64_t remainingBits = rawPointerCoords->bits & ~unpackedAxisBits;
if (remainingBits) {
- uint32_t packedAxesCount = __builtin_popcount(remainingBits);
+ uint32_t packedAxesCount = __builtin_popcountll(remainingBits);
jfloatArray outValuesArray = obtainPackedAxisValuesArray(env, packedAxesCount,
outPointerCoordsObj);
if (!outValuesArray) {
@@ -299,8 +298,8 @@ static void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointer
const float* values = rawPointerCoords->values;
uint32_t index = 0;
do {
- uint32_t axis = __builtin_ctz(remainingBits);
- uint32_t axisBit = 1 << axis;
+ uint32_t axis = __builtin_ctzll(remainingBits);
+ uint64_t axisBit = 1LL << axis;
remainingBits &= ~axisBit;
outBits |= axisBit;
outValues[index++] = rawPointerCoords->getAxisValue(axis);
@@ -309,7 +308,7 @@ static void pointerCoordsFromNative(JNIEnv* env, const PointerCoords* rawPointer
env->ReleasePrimitiveArrayCritical(outValuesArray, outValues, 0);
env->DeleteLocalRef(outValuesArray);
}
- env->SetIntField(outPointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits, outBits);
+ env->SetLongField(outPointerCoordsObj, gPointerCoordsClassInfo.mPackedAxisBits, outBits);
}
@@ -610,7 +609,7 @@ static jint android_view_MotionEvent_nativeReadFromParcel(JNIEnv* env, jclass cl
Parcel* parcel = parcelForJavaObject(env, parcelObj);
status_t status = event->readFromParcel(parcel);
- if (!status) {
+ if (status) {
if (!nativePtr) {
delete event;
}
@@ -626,7 +625,7 @@ static void android_view_MotionEvent_nativeWriteToParcel(JNIEnv* env, jclass cla
Parcel* parcel = parcelForJavaObject(env, parcelObj);
status_t status = event->writeToParcel(parcel);
- if (!status) {
+ if (status) {
jniThrowRuntimeException(env, "Failed to write MotionEvent parcel.");
}
}
@@ -758,7 +757,7 @@ int register_android_view_MotionEvent(JNIEnv* env) {
FIND_CLASS(gPointerCoordsClassInfo.clazz, "android/view/MotionEvent$PointerCoords");
GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisBits, gPointerCoordsClassInfo.clazz,
- "mPackedAxisBits", "I");
+ "mPackedAxisBits", "J");
GET_FIELD_ID(gPointerCoordsClassInfo.mPackedAxisValues, gPointerCoordsClassInfo.clazz,
"mPackedAxisValues", "[F");
GET_FIELD_ID(gPointerCoordsClassInfo.x, gPointerCoordsClassInfo.clazz,
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 6f37dc097010..d9eccd6f2729 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2256,18 +2256,29 @@
<attr name="unselectedAlpha" format="float" />
</declare-styleable>
<declare-styleable name="GridView">
+ <!-- Defines the default horizontal spacing between columns. -->
<attr name="horizontalSpacing" format="dimension" />
+ <!-- Defines the default vertical spacing between rows. -->
<attr name="verticalSpacing" format="dimension" />
+ <!-- Defines how columns should stretch to fill the available empty space, if any. -->
<attr name="stretchMode">
+ <!-- Stretching is disabled. -->
<enum name="none" value="0"/>
+ <!-- The spacing between each column is stretched. -->
<enum name="spacingWidth" value="1" />
+ <!-- Each column is stretched equally. -->
<enum name="columnWidth" value="2" />
+ <!-- The spacing between each column is uniformly stretched.. -->
<enum name="spacingWidthUniform" value="3" />
</attr>
+ <!-- Specifies the fixed width for each column. -->
<attr name="columnWidth" format="dimension" />
+ <!-- Defines how many columns to show. -->
<attr name="numColumns" format="integer" min="0">
+ <!-- Display as many columns as possible to fill the available space. -->
<enum name="auto_fit" value="-1" />
</attr>
+ <!-- Specifies the gravity within each cell. -->
<attr name="gravity" />
</declare-styleable>
<declare-styleable name="ImageSwitcher">
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 454257522a09..c7f082b451b1 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1642,7 +1642,9 @@
<!-- Default icon for applications that don't specify an icon. -->
<public type="mipmap" name="sym_def_app_icon" id="0x010d0000" />
- <!-- Theme attribute used to customize the text insertion cursor -->
- <!-- Commented out for HC MR1 to prevent an API change -->
- <!-- <public type="attr" name="textCursorDrawable" id="0x01010362" /> -->
+<!-- ===============================================================
+ Resources added in version 12 of the platform (Honeycomb / 3.1)
+ =============================================================== -->
+ <eat-comment />
+ <public type="attr" name="textCursorDrawable" id="0x01010362" />
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 8cc5944dc058..72f1801831e9 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -589,7 +589,7 @@
</style>
<style name="Widget.ListView.White" parent="Widget.AbsListView">
- <item name="android:listSelector">@android:drawable/list_selector_background_light</item>
+ <item name="android:listSelector">@android:drawable/list_selector_background</item>
<item name="android:cacheColorHint">?android:attr/colorBackgroundCacheHint</item>
<item name="android:divider">@android:drawable/divider_horizontal_bright_opaque</item>
</style>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 927a668ac857..82164e5ae742 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -105,7 +105,7 @@
<item name="listChoiceIndicatorSingle">@android:drawable/btn_radio</item>
<item name="listChoiceIndicatorMultiple">@android:drawable/btn_check</item>
- <item name="listChoiceBackgroundIndicator">@android:drawable/list_selected_background</item>
+ <item name="listChoiceBackgroundIndicator">@android:drawable/list_selector_background</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background</item>
@@ -358,7 +358,7 @@
<item name="textColorLinkInverse">@android:color/link_text_dark</item>
<item name="editTextColor">?android:attr/textColorPrimary</item>
- <item name="listChoiceBackgroundIndicator">@android:drawable/list_selected_background_light</item>
+ <item name="listChoiceBackgroundIndicator">@android:drawable/list_selector_background</item>
<item name="activatedBackgroundIndicator">@android:drawable/activated_background_light</item>
<item name="quickContactBadgeOverlay">@android:drawable/quickcontact_badge_overlay_light</item>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index fb8b5ce2b916..775613504aaf 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -30,7 +30,9 @@ import android.provider.Settings;
import android.util.Log;
import android.view.KeyEvent;
+import java.io.IOException;
import java.io.InputStream;
+import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import android.widget.LinearLayout;
@@ -485,6 +487,44 @@ public class ConnectivityManagerTestActivity extends Activity {
}
/**
+ * @param pingServerList a list of servers that can be used for ping test, can be null
+ * @return true if the ping test is successful, false otherwise.
+ */
+ public boolean pingTest(String[] pingServerList) {
+ boolean result = false;
+ String[] hostList = {"www.google.com", "www.yahoo.com",
+ "www.bing.com", "www.facebook.com", "www.ask.com"};
+ if (pingServerList != null) {
+ hostList = pingServerList;
+ }
+ try {
+ // assume the chance that all servers are down is very small
+ for (int i = 0; i < hostList.length; i++ ) {
+ String host = hostList[i];
+ log("Start ping test, ping " + host);
+ Process p = Runtime.getRuntime().exec("ping -c 10 -w 100 " + host);
+ int status = p.waitFor();
+ if (status == 0) {
+ // if any of the ping test is successful, return true
+ result = true;
+ break;
+ } else {
+ result = false;
+ log("ping " + host + " failed.");
+ }
+ }
+ } catch (UnknownHostException e) {
+ log("Ping test Fail: Unknown Host");
+ } catch (IOException e) {
+ log("Ping test Fail: IOException");
+ } catch (InterruptedException e) {
+ log("Ping test Fail: InterruptedException");
+ }
+ log("return");
+ return result;
+ }
+
+ /**
* Associate the device to given SSID
* If the device is already associated with a WiFi, disconnect and forget it,
* We don't verify whether the connection is successful or not, leave this to the test
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
index 4457de9d3d0e..1374e7f8afef 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java
@@ -107,6 +107,17 @@ public class WifiApStress
} catch (Exception e) {
fail("thread in sleep is interrupted");
}
+ assertTrue("no uplink data connection after Wi-Fi tethering", mAct.pingTest(null));
+ // Wait for 5 minutes, and verify the data connection again.
+ // bug id: 3400027
+ try {
+ Thread.sleep(5 * 60 * 1000);
+ } catch (Exception e) {
+ fail("thread in sleep is interrupted");
+ }
+ // Verify the uplink data connection
+ assertTrue("no uplink data connection", mAct.pingTest(null));
+ // Disable soft AP
assertTrue(mAct.mWifiManager.setWifiApEnabled(config, false));
// Wait for 30 seconds until Wi-Fi tethering is stopped
try {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index ae009ca62460..2f2a28302dca 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -243,6 +243,9 @@ public class WifiStressTest
ConnectivityManagerTestActivity.SHORT_TIMEOUT));
assertTrue(mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ // Run ping test to verify the data connection
+ assertTrue("Wi-Fi is connected, but no data connection.", mAct.pingTest(null));
+
int i;
for (i = 0; i < mReconnectIterations; i++) {
// 1. Put device into sleep mode
@@ -271,6 +274,9 @@ public class WifiStressTest
mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState());
assertEquals("Cellular connection is down", State.CONNECTED,
mAct.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState());
+
+ assertTrue("Mobile is connected, but no data connection.", mAct.pingTest(null));
+
// Turn screen on again
mAct.turnScreenOn();
assertTrue("Wait for Wi-Fi enable timeout after wake up",
@@ -279,6 +285,7 @@ public class WifiStressTest
assertTrue("Wait for Wi-Fi connection timeout after wake up",
mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
ConnectivityManagerTestActivity.LONG_TIMEOUT));
+ assertTrue("Reconnect to Wi-Fi network, but no data connection.", mAct.pingTest(null));
}
if (i == mReconnectIterations) {
writeOutput(String.format("iteration %d out of %d",
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
index 96b028a02360..672f252388fd 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
@@ -250,8 +250,8 @@ public class BluetoothStressTest extends InstrumentationTestCase {
for (int i = 0; i < iterations; i++) {
mTestUtils.writeOutput("connectInput iteration " + (i + 1) + " of " + iterations);
- mTestUtils.connectInput(adapter, device);
- mTestUtils.disconnectInput(adapter, device);
+ mTestUtils.connectProfile(adapter, device, BluetoothProfile.INPUT_DEVICE);
+ mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.INPUT_DEVICE);
}
mTestUtils.unpair(adapter, device);
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
index effed7676487..35210e5c7b3d 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
@@ -238,6 +238,9 @@ public class BluetoothTestUtils extends Assert {
case BluetoothProfile.HEADSET:
mConnectionAction = BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED;
break;
+ case BluetoothProfile.INPUT_DEVICE:
+ mConnectionAction = BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED;
+ break;
default:
mConnectionAction = null;
}
@@ -270,47 +273,6 @@ public class BluetoothTestUtils extends Assert {
}
}
- private class ConnectInputReceiver extends FlagReceiver {
- private static final int STATE_DISCONNECTED_FLAG = 1;
- private static final int STATE_CONNECTING_FLAG = 1 << 1;
- private static final int STATE_CONNECTED_FLAG = 1 << 2;
- private static final int STATE_DISCONNECTING_FLAG = 1 << 3;
-
- private BluetoothDevice mDevice;
-
- public ConnectInputReceiver(BluetoothDevice device, int expectedFlags) {
- super(expectedFlags);
-
- mDevice = device;
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!mDevice.equals(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE))) {
- return;
- }
-
- if (BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED.equals(intent.getAction())) {
- int state = intent.getIntExtra(BluetoothInputDevice.EXTRA_INPUT_DEVICE_STATE, -1);
- assertNotSame(-1, state);
- switch (state) {
- case BluetoothInputDevice.STATE_DISCONNECTED:
- setFiredFlag(STATE_DISCONNECTED_FLAG);
- break;
- case BluetoothInputDevice.STATE_CONNECTING:
- setFiredFlag(STATE_CONNECTING_FLAG);
- break;
- case BluetoothInputDevice.STATE_CONNECTED:
- setFiredFlag(STATE_CONNECTED_FLAG);
- break;
- case BluetoothInputDevice.STATE_DISCONNECTING:
- setFiredFlag(STATE_DISCONNECTING_FLAG);
- break;
- }
- }
- }
- }
-
private class ConnectPanReceiver extends FlagReceiver {
private static final int STATE_DISCONNECTED_FLAG = 1;
private static final int STATE_CONNECTING_FLAG = 1 << 1;
@@ -366,6 +328,9 @@ public class BluetoothTestUtils extends Assert {
case BluetoothProfile.HEADSET:
mHeadset = (BluetoothHeadset) proxy;
break;
+ case BluetoothProfile.INPUT_DEVICE:
+ mInput = (BluetoothInputDevice) proxy;
+ break;
}
}
}
@@ -379,6 +344,9 @@ public class BluetoothTestUtils extends Assert {
case BluetoothProfile.HEADSET:
mHeadset = null;
break;
+ case BluetoothProfile.INPUT_DEVICE:
+ mInput = null;
+ break;
}
}
}
@@ -393,6 +361,7 @@ public class BluetoothTestUtils extends Assert {
private Context mContext;
private BluetoothA2dp mA2dp;
private BluetoothHeadset mHeadset;
+ private BluetoothInputDevice mInput;
/**
* Creates a utility instance for testing Bluetooth.
@@ -1078,142 +1047,6 @@ public class BluetoothTestUtils extends Assert {
}
/**
- * Connects the local device with a remote HID device and checks to make sure that the profile
- * is connected and that the correct actions were broadcast.
- *
- * @param adapter The BT adapter.
- * @param device The remote device.
- */
- public void connectInput(BluetoothAdapter adapter, BluetoothDevice device) {
- int mask = (ConnectInputReceiver.STATE_CONNECTING_FLAG
- | ConnectInputReceiver.STATE_CONNECTED_FLAG);
- long start = -1;
-
- if (!adapter.isEnabled()) {
- fail(String.format("connectInput() bluetooth not enabled: device=%s", device));
- }
-
- if (!adapter.getBondedDevices().contains(device)) {
- fail(String.format("connectInput() device not paired: device=%s", device));
- }
-
- BluetoothInputDevice inputDevice = new BluetoothInputDevice(mContext);
- assertNotNull(inputDevice);
- ConnectInputReceiver receiver = getConnectInputReceiver(device, mask);
-
- int state = inputDevice.getInputDeviceState(device);
- switch (state) {
- case BluetoothInputDevice.STATE_CONNECTED:
- removeReceiver(receiver);
- return;
- case BluetoothInputDevice.STATE_CONNECTING:
- mask = 0; // Don't check for received intents since we might have missed them.
- break;
- case BluetoothInputDevice.STATE_DISCONNECTED:
- case BluetoothInputDevice.STATE_DISCONNECTING:
- start = System.currentTimeMillis();
- assertTrue(inputDevice.connectInputDevice(device));
- break;
- default:
- removeReceiver(receiver);
- fail(String.format("connectInput() invalid state: device=%s, state=%d", device,
- state));
- }
-
- long s = System.currentTimeMillis();
- while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
- state = inputDevice.getInputDeviceState(device);
- if (state == BluetoothInputDevice.STATE_CONNECTED
- && (receiver.getFiredFlags() & mask) == mask) {
- long finish = receiver.getCompletedTime();
- if (start != -1 && finish != -1) {
- writeOutput(String.format("connectInput() completed in %d ms: device=%s",
- (finish - start), device));
- } else {
- writeOutput(String.format("connectInput() completed: device=%s", device));
- }
- removeReceiver(receiver);
- return;
- }
- sleep(POLL_TIME);
- }
-
- int firedFlags = receiver.getFiredFlags();
- removeReceiver(receiver);
- fail(String.format("connectInput() timeout: device=%s, state=%d (expected %d), "
- + "flags=0x%x (expected 0x%s)", device, state, BluetoothInputDevice.STATE_CONNECTED,
- firedFlags, mask));
- }
-
- /**
- * Disconnects the local device with a remote HID device and checks to make sure that the
- * profile is connected and that the correct actions were broadcast.
- *
- * @param adapter The BT adapter.
- * @param device The remote device.
- */
- public void disconnectInput(BluetoothAdapter adapter, BluetoothDevice device) {
- int mask = (ConnectInputReceiver.STATE_DISCONNECTING_FLAG
- | ConnectInputReceiver.STATE_DISCONNECTED_FLAG);
- long start = -1;
-
- if (!adapter.isEnabled()) {
- fail(String.format("disconnectInput() bluetooth not enabled: device=%s", device));
- }
-
- if (!adapter.getBondedDevices().contains(device)) {
- fail(String.format("disconnectInput() device not paired: device=%s", device));
- }
-
- BluetoothInputDevice inputDevice = new BluetoothInputDevice(mContext);
- assertNotNull(inputDevice);
- ConnectInputReceiver receiver = getConnectInputReceiver(device, mask);
-
- int state = inputDevice.getInputDeviceState(device);
- switch (state) {
- case BluetoothInputDevice.STATE_CONNECTED:
- case BluetoothInputDevice.STATE_CONNECTING:
- start = System.currentTimeMillis();
- assertTrue(inputDevice.disconnectInputDevice(device));
- break;
- case BluetoothInputDevice.STATE_DISCONNECTED:
- removeReceiver(receiver);
- return;
- case BluetoothInputDevice.STATE_DISCONNECTING:
- mask = 0; // Don't check for received intents since we might have missed them.
- break;
- default:
- removeReceiver(receiver);
- fail(String.format("disconnectInput() invalid state: device=%s, state=%d", device,
- state));
- }
-
- long s = System.currentTimeMillis();
- while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
- state = inputDevice.getInputDeviceState(device);
- if (state == BluetoothInputDevice.STATE_DISCONNECTED
- && (receiver.getFiredFlags() & mask) == mask) {
- long finish = receiver.getCompletedTime();
- if (start != -1 && finish != -1) {
- writeOutput(String.format("disconnectInput() completed in %d ms: device=%s",
- (finish - start), device));
- } else {
- writeOutput(String.format("disconnectInput() completed: device=%s", device));
- }
- removeReceiver(receiver);
- return;
- }
- sleep(POLL_TIME);
- }
-
- int firedFlags = receiver.getFiredFlags();
- removeReceiver(receiver);
- fail(String.format("disconnectInput() timeout: device=%s, state=%d (expected %d), "
- + "flags=0x%x (expected 0x%s)", device, state,
- BluetoothInputDevice.STATE_DISCONNECTED, firedFlags, mask));
- }
-
- /**
* Connects the PANU to a remote NAP and checks to make sure that the PANU is connected and that
* the correct actions were broadcast.
*
@@ -1478,21 +1311,14 @@ public class BluetoothTestUtils extends Assert {
int expectedFlags) {
String[] actions = {
BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED,
- BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED};
+ BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED,
+ BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED};
ConnectProfileReceiver receiver = new ConnectProfileReceiver(device, profile,
expectedFlags);
addReceiver(receiver, actions);
return receiver;
}
- private ConnectInputReceiver getConnectInputReceiver(BluetoothDevice device,
- int expectedFlags) {
- String[] actions = {BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED};
- ConnectInputReceiver receiver = new ConnectInputReceiver(device, expectedFlags);
- addReceiver(receiver, actions);
- return receiver;
- }
-
private ConnectPanReceiver getConnectPanReceiver(BluetoothDevice device, int role,
int expectedFlags) {
String[] actions = {BluetoothPan.ACTION_PAN_STATE_CHANGED};
@@ -1511,15 +1337,20 @@ public class BluetoothTestUtils extends Assert {
long s = System.currentTimeMillis();
switch (profile) {
case BluetoothProfile.A2DP:
- while (mA2dp != null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
+ while (mA2dp == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
sleep(POLL_TIME);
}
return mA2dp;
case BluetoothProfile.HEADSET:
- while (mHeadset != null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
+ while (mHeadset == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
sleep(POLL_TIME);
}
return mHeadset;
+ case BluetoothProfile.INPUT_DEVICE:
+ while (mInput == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
+ sleep(POLL_TIME);
+ }
+ return mInput;
default:
return null;
}
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteCursorTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteCursorTest.java
index 963c8ed52322..f6b1d04c8487 100644
--- a/core/tests/coretests/src/android/database/sqlite/SQLiteCursorTest.java
+++ b/core/tests/coretests/src/android/database/sqlite/SQLiteCursorTest.java
@@ -22,7 +22,6 @@ import android.database.Cursor;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
import java.io.File;
@@ -55,7 +54,6 @@ public class SQLiteCursorTest extends AndroidTestCase {
super.tearDown();
}
- @Suppress
@SmallTest
public void testQueryObjReassignment() {
mDatabase.enableWriteAheadLogging();
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java
index 45165107b59e..39258ae473ee 100644
--- a/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java
+++ b/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java
@@ -74,7 +74,6 @@ public class SQLiteDatabaseTest extends AndroidTestCase {
mDatabase.setVersion(CURRENT_DATABASE_VERSION);
}
- @Suppress
@SmallTest
public void testEnableWriteAheadLogging() {
mDatabase.disableWriteAheadLogging();
@@ -87,7 +86,6 @@ public class SQLiteDatabaseTest extends AndroidTestCase {
assertEquals(pool, mDatabase.mConnectionPool);
}
- @Suppress
@SmallTest
public void testDisableWriteAheadLogging() {
mDatabase.execSQL("create table test (i int);");
@@ -104,7 +102,6 @@ public class SQLiteDatabaseTest extends AndroidTestCase {
assertFalse(db.isOpen());
}
- @Suppress
@SmallTest
public void testCursorsWithClosedDbConnAfterDisableWriteAheadLogging() {
mDatabase.disableWriteAheadLogging();
@@ -141,7 +138,6 @@ public class SQLiteDatabaseTest extends AndroidTestCase {
/**
* a transaction should be started before a standalone-update/insert/delete statement
*/
- @Suppress
@SmallTest
public void testStartXactBeforeUpdateSql() throws InterruptedException {
runTestForStartXactBeforeUpdateSql(INSERT);
@@ -753,7 +749,6 @@ public class SQLiteDatabaseTest extends AndroidTestCase {
*
* @throws InterruptedException
*/
- @Suppress
@SmallTest
public void testTransactionAndWalInterplay1() throws InterruptedException {
createTableAndClearCache();
@@ -812,7 +807,6 @@ public class SQLiteDatabaseTest extends AndroidTestCase {
* instead of mDatabase.beginTransactionNonExclusive(), use execSQL("BEGIN transaction")
* and instead of mDatabase.endTransaction(), use execSQL("END");
*/
- @Suppress
@SmallTest
public void testTransactionAndWalInterplay2() throws InterruptedException {
createTableAndClearCache();
@@ -869,7 +863,6 @@ public class SQLiteDatabaseTest extends AndroidTestCase {
* instead of committing the data, do rollback and make sure the data seen by the query
* within the transaction is now gone.
*/
- @Suppress
@SmallTest
public void testTransactionAndWalInterplay3() {
createTableAndClearCache();
diff --git a/data/keyboards/Android.mk b/data/keyboards/Android.mk
index 8cba52d047b0..a66a884f6a63 100644
--- a/data/keyboards/Android.mk
+++ b/data/keyboards/Android.mk
@@ -17,3 +17,21 @@
LOCAL_PATH := $(call my-dir)
include $(LOCAL_PATH)/common.mk
+
+# Validate all key maps.
+include $(CLEAR_VARS)
+
+validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
+files := \
+ $(foreach file,$(keylayouts),frameworks/base/data/keyboards/$(file)) \
+ $(foreach file,$(keycharmaps),frameworks/base/data/keyboards/$(file)) \
+ $(foreach file,$(keyconfigs),frameworks/base/data/keyboards/$(file))
+
+LOCAL_MODULE := validate_framework_keymaps
+LOCAL_MODULE_TAGS := optional
+LOCAL_REQUIRED_MODULES := validatekeymaps
+
+validate_framework_keymaps: $(files)
+ $(hide) $(validatekeymaps) $(files)
+
+include $(BUILD_PHONY_PACKAGE)
diff --git a/data/keyboards/Generic.kcm b/data/keyboards/Generic.kcm
index 14d7c80ecb0c..51a8b27bc877 100644
--- a/data/keyboards/Generic.kcm
+++ b/data/keyboards/Generic.kcm
@@ -545,3 +545,129 @@ key ESCAPE {
meta: fallback HOME
alt: fallback MENU
}
+
+### Gamepad buttons ###
+
+key BUTTON_A {
+ base: fallback BACK
+}
+
+key BUTTON_B {
+ base: fallback BACK
+}
+
+key BUTTON_C {
+ base: fallback BACK
+}
+
+key BUTTON_X {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_Y {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_Z {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_L1 {
+ base: none
+}
+
+key BUTTON_R1 {
+ base: none
+}
+
+key BUTTON_L2 {
+ base: none
+}
+
+key BUTTON_R2 {
+ base: none
+}
+
+key BUTTON_THUMBL {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_THUMBR {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_START {
+ base: fallback HOME
+}
+
+key BUTTON_SELECT {
+ base: fallback MENU
+}
+
+key BUTTON_MODE {
+ base: fallback MENU
+}
+
+key BUTTON_1 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_2 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_3 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_4 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_5 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_6 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_7 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_8 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_9 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_10 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_11 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_12 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_13 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_14 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_15 {
+ base: fallback DPAD_CENTER
+}
+
+key BUTTON_16 {
+ base: fallback DPAD_CENTER
+}
diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl
index 0aefc3114679..6d925d67f989 100644
--- a/data/keyboards/Generic.kl
+++ b/data/keyboards/Generic.kl
@@ -261,7 +261,6 @@ key 233 HEADSETHOOK
# key 239 "KEY_KBDILLUMUP"
# key 240 "KEY_UNKNOWN"
-
key 288 BUTTON_1
key 289 BUTTON_2
key 290 BUTTON_3
@@ -400,3 +399,16 @@ key 484 B FUNCTION
# key 502 KEY_BRL_DOT6
# key 503 KEY_BRL_DOT7
# key 504 KEY_BRL_DOT8
+
+
+# Joystick and game controller axes.
+# Axes that are not mapped will be assigned generic axis numbers by the input subsystem.
+axis 0x00 X
+axis 0x01 Y
+axis 0x02 Z
+axis 0x03 RX
+axis 0x04 RY
+axis 0x05 RZ
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+ \ No newline at end of file
diff --git a/data/keyboards/Vendor_046d_Product_c216.kl b/data/keyboards/Vendor_046d_Product_c216.kl
new file mode 100644
index 000000000000..6743323d7db8
--- /dev/null
+++ b/data/keyboards/Vendor_046d_Product_c216.kl
@@ -0,0 +1,37 @@
+# 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.
+
+#
+# Logitech Dual Action Controller
+#
+
+key 0x120 BUTTON_A
+key 0x123 BUTTON_B
+key 0x121 BUTTON_X
+key 0x122 BUTTON_Y
+key 0x124 BUTTON_L1
+key 0x125 BUTTON_R1
+key 0x126 BUTTON_L2
+key 0x127 BUTTON_R2
+key 0x128 BUTTON_SELECT
+key 0x129 BUTTON_START
+key 0x12a BUTTON_THUMBL
+key 0x12b BUTTON_THUMBR
+
+axis 0x00 X
+axis 0x01 Y
+axis 0x02 Z
+axis 0x05 RZ
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
diff --git a/data/keyboards/Vendor_054c_Product_0268.kl b/data/keyboards/Vendor_054c_Product_0268.kl
new file mode 100644
index 000000000000..f8ac6a358753
--- /dev/null
+++ b/data/keyboards/Vendor_054c_Product_0268.kl
@@ -0,0 +1,76 @@
+# 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.
+
+#
+# Sony Playstation(R)3 Controller
+#
+
+key 0x124 DPAD_UP
+key 0x125 DPAD_RIGHT
+key 0x126 DPAD_DOWN
+key 0x127 DPAD_LEFT
+
+key 0x120 BUTTON_SELECT
+key 0x123 BUTTON_START
+key 0x12f BUTTON_A
+key 0x12c BUTTON_B
+key 0x12e BUTTON_X
+key 0x12d BUTTON_Y
+key 0x12a BUTTON_L1
+key 0x12b BUTTON_R1
+key 0x128 BUTTON_L2
+key 0x129 BUTTON_R2
+key 0x121 BUTTON_THUMBL
+key 0x122 BUTTON_THUMBR
+
+# PS key
+key 0x2d0 BUTTON_1
+
+# Left Analog Stick
+axis 0x00 X
+axis 0x01 Y
+
+# Right Analog Stick
+axis 0x02 Z
+axis 0x05 RZ
+
+# DPAD
+# axis 0x2c -HAT_Y
+# axis 0x2d +HAT_X
+# axis 0x2e +HAT_Y
+# axis 0x2f -HAT_X
+
+# L2 trigger
+axis 0x30 LTRIGGER
+
+# R2 trigger
+axis 0x31 RTRIGGER
+
+# L1 trigger
+# axis 0x32
+
+# R1 trigger
+# axis 0x33
+
+# Triangle
+# axis 0x34
+
+# Circle
+# axis 0x35
+
+# Cross
+# axis 0x36
+
+# Square
+# axis 0x37
diff --git a/data/keyboards/common.mk b/data/keyboards/common.mk
index 56c287a5be6b..5b367b91f114 100644
--- a/data/keyboards/common.mk
+++ b/data/keyboards/common.mk
@@ -19,7 +19,9 @@ keylayouts := \
Generic.kl \
AVRCP.kl \
qwerty.kl \
+ Vendor_046d_Product_c216.kl \
Vendor_046d_Product_c532.kl \
+ Vendor_054c_Product_0268.kl \
Vendor_05ac_Product_0239.kl \
Vendor_22b8_Product_093d.kl
diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd
index cbe3bf4c2981..013cc94dbcf8 100644
--- a/docs/html/guide/appendix/api-levels.jd
+++ b/docs/html/guide/appendix/api-levels.jd
@@ -83,6 +83,7 @@ Android platform.</p>
<table>
<tr><th>Platform Version</th><th>API Level</th></tr>
+ <tr><td>Android 3.0</td><td>11</td></tr>
<tr><td>Android 2.3.3</td><td>10</td></tr>
<tr><td>Android 2.3</td><td>9</td></tr>
<tr><td>Android 2.2</td><td>8</td></tr>
diff --git a/docs/html/guide/developing/tools/aidl.jd b/docs/html/guide/developing/tools/aidl.jd
index d3da2852bdf3..731aef7e7751 100644
--- a/docs/html/guide/developing/tools/aidl.jd
+++ b/docs/html/guide/developing/tools/aidl.jd
@@ -1,4 +1,4 @@
-page.title=Designing a Remote Interface Using AIDL
+page.title=Android Interface Definition Language (AIDL)
@jd:body
@@ -6,209 +6,367 @@ page.title=Designing a Remote Interface Using AIDL
<div id="qv">
<h2>In this document</h2>
<ol>
- <li><a href="#implementing">Implementing IPC Using AIDL</a>
+ <li><a href="#Defining">Defining an AIDL Interface</a>
<ol>
- <li><a href="#aidlsyntax">Create an .aidl File</a></li>
- <li><a href="#implementtheinterface">Implementing the Interface</a></li>
- <li><a href="#exposingtheinterface">Exposing Your Interface to Clients</a></li>
- <li><a href="#parcelable">Pass by value Parameters using Parcelables</a></li>
+ <li><a href="#Create">Create the .aidl file</a></li>
+ <li><a href="#Implement">Implement the interface</a></li>
+ <li><a href="#Expose">Expose the interface to clients</a></li>
</ol>
</li>
- <li><a href="#calling">Calling an IPC Method</a></li>
+ <li><a href="#PassingObjects">Passing Objects over IPC</a></li>
+ <li><a href="#Calling">Calling an IPC Method</a></li>
</ol>
+
+<h2>See also</h2>
+<ol>
+ <li><a href="{@docRoot}guide/topics/fundamentals/bound-services.html">Bound Services</a></li>
+</ol>
+
</div>
</div>
-<p>Since each application runs in its own process, and you can write a service that
-runs in a different process from your Application's UI, sometimes you need to pass objects
-between processes. On the Android platform, one process can not normally access the memory
-of another process. So to talk, they need to decompose their objects into primitives that
-the operating system can understand, and "marshall" the object across that boundary for you.</p>
+<p>AIDL (Android Interface Definition Language) is similar to other IDLs you might have
+worked with. It allows you to define the programming interface that both
+the client and service agree upon in order to communicate with each other using
+interprocess communication (IPC). On Android, one process cannot normally access the
+memory of another process. So to talk, they need to decompose their objects into primitives that the
+operating system can understand, and marshall the objects across that boundary for you. The code to
+do that marshalling is tedious to write, so Android handles it for you with AIDL.</p>
+
+<p class="note"><strong>Note:</strong> Using AIDL is necessary only if you allow clients from
+different applications to access your service for IPC and want to handle multithreading in your
+service. If you do not need to perform concurrent IPC across
+different applications, you should create your interface by <a
+href="{@docRoot}guide/topics/fundamentals/bound-services.html#Binder">implementing a
+Binder</a> or, if you want to perform IPC, but do <em>not</em> need to handle multithreading,
+implement your interface <a
+href="{@docRoot}guide/topics/fundamentals/bound-services.html#Messenger">using a Messenger</a>.
+Regardless, be sure that you understand <a
+href="{@docRoot}guide/topics/fundamentals/bound-services.html">Bound Services</a> before
+implementing an AIDL.</p>
+
+<p>Before you begin designing your AIDL interface, be aware that calls to an AIDL interface are
+direct function calls. You should not make assumptions about the thread in which the call
+occurs. What happens is different depending on whether the call is from a thread in the
+local process or a remote process. Specifically:</p>
-<p>The code to do that marshalling is tedious to write, so we provide the AIDL tool to do it
-for you.</p>
+<ul>
+<li>Calls made from the local process are executed in the same thread that is making the call. If
+this is your main UI thread, that thread continues to execute in the AIDL interface. If it is
+another thread, that is the one that executes your code in the service. Thus, if only local
+threads are accessing the service, you can completely control which threads are executing in it (but
+if that is the case, then you shouldn't be using AIDL at all, but should instead create the
+interface by <a href="{@docRoot}guide/topics/fundamentals/bound-services.html#Binder">implementing a
+Binder</a>).</li>
+
+<li>Calls from a remote process are dispatched from a thread pool the platform maintains inside of
+your own process. You must be prepared for incoming calls from unknown threads, with multiple calls
+happening at the same time. In other words, an implementation of an AIDL interface must be
+completely thread-safe.</li>
+
+<li>The {@code oneway} keyword modifies the behavior of remote calls. When used, a remote call does
+not block; it simply sends the transaction data and immediately returns.
+The implementation of the interface eventually receives this as a regular call from the {@link
+android.os.Binder} thread pool as a normal remote call. If {@code oneway} is used with a local call,
+there is no impact and the call is still synchronous.</li>
+</ul>
-<p>AIDL (Android Interface Definition Language) is an <a
-href="http://en.wikipedia.org/wiki/Interface_description_language">IDL</a>
-language used to generate code that enables two processes on an Android-powered device
-to talk using interprocess communication (IPC). If you have code
-in one process (for example, in an Activity) that needs to call methods on an
-object in another process (for example, a Service), you would use AIDL to
-generate code to marshall the parameters.</p>
-<p>The AIDL IPC mechanism
- is interface-based, similar to COM or Corba, but lighter weight. It uses a proxy
- class to pass values between the client and the implementation. </p>
+<h2 id="Defining">Defining an AIDL Interface</h2>
-<h2 id="implementing">Implementing IPC Using AIDL</h2>
-<p>Follow these steps to implement an IPC service using AIDL.</p>
+<p>You must define your AIDL interface in an {@code .aidl} file using the Java
+programming language syntax, then save it in the source code (in the {@code src/} directory) of both
+the application hosting the service and any other application that binds to the service.</p>
+
+<p>When you build each application that contains the {@code .aidl} file, the Android SDK tools
+generate an {@link android.os.IBinder} interface based on the {@code .aidl} file and save it in
+the project's {@code gen/} directory. The service must implement the {@link android.os.IBinder}
+interface as appropriate. The client applications can then bind to the service and call methods from
+the {@link android.os.IBinder} to perform IPC.</p>
+
+<p>To create a bounded service using AIDL, follow these steps:</p>
<ol>
- <li><strong><a href="#aidlsyntax">Create your .aidl file</a> </strong>- This
- file defines an interface (<em>YourInterface</em>.aidl) that defines the
- methods and fields available to a client. </li>
- <li><strong>Add the .aidl file to your makefile</strong> - (the ADT Plugin for Eclipse
- manages this for you). Android includes the compiler, called
- AIDL, in the <code>tools/</code> directory. </li>
- <li><strong><a href="#implementtheinterface">Implement your interface methods</a></strong> -
- The AIDL compiler creates an interface in the Java programming language from your AIDL interface.
- This interface has an inner abstract class named Stub that inherits the
- interface (and implements a few additional methods necessary for the IPC
- call). You must create a class that extends <em>YourInterface</em>.Stub
- and implements the methods you declared in your .aidl file. </li>
- <li><strong><a href="#exposingtheinterface">Expose your interface to clients</a></strong> -
- If you're writing a service, you should extend {@link
- android.app.Service Service} and override {@link android.app.Service#onBind
- Service.onBind(Intent)} to return an instance of your class that implements your
- interface. </li>
+ <li><a href="#CreateAidl">Create the .aidl file</a>
+ <p>This file defines the programming interface with method signatures.</p>
+ </li>
+ <li><a href="#ImplementTheInterface">Implement the interface</a>
+ <p>The Android SDK tools generate an interface in the Java programming language, based on your
+{@code .aidl} file. This interface has an inner abstract class named {@code Stub} that extends
+{@link android.os.Binder} and implements methods from your AIDL interface. You must extend the
+{@code Stub} class and implement the methods.</p>
+ </li>
+ <li><a href="#ExposeTheInterface">Expose the interface to clients</a>
+ <p>Implement a {@link android.app.Service Service} and override {@link
+android.app.Service#onBind onBind()} to return your implementation of the {@code Stub}
+class.</p>
+ </li>
</ol>
-<h3 id="aidlsyntax">Create an .aidl File</h3>
-<p>AIDL is a simple syntax that lets you declare an interface with one or more
- methods, that can take parameters and return values. These parameters and return
- values can be of any type, even other AIDL-generated interfaces. <em>However, it
- is important to note</em> that you <em>must</em> import all non-built-in types,
- <em>even if they are defined in the same package as your interface</em>.
- Here are the data types that AIDL can support: </p>
+<p class="caution"><strong>Caution:</strong> Any changes that you make to your AIDL interface after
+your first release must remain backward compatible in order to avoid breaking other applications
+that use your service. That is, because your {@code .aidl} file must be copied to other applications
+in order for them to access your service's interface, you must maintain support for the original
+interface.</p>
+
+
+<h3 id="Create">1. Create the .aidl file</h3>
+
+<p>AIDL uses a simple syntax that lets you declare an interface with one or more methods that can
+take parameters and return values. The parameters and return values can be of any type, even other
+AIDL-generated interfaces.</p>
+
+<p>You must construct the {@code .aidl} file using the Java programming language. Each {@code .aidl}
+file must define a single interface and requires only the interface declaration and method
+signatures.</p>
+
+<p>By default, AIDL supports the following data types:</p>
+
<ul>
- <li>Primitive Java programming language types (int, boolean, etc)
- &mdash; No <code>import</code> statement is needed. </li>
- <li>One of the following classes (no <code>import</code> statements needed):
- <ul>
- <li><strong>String</strong></li>
- <li><strong>List</strong> - All elements in the List must be one of the types
- in this list, including other AIDL-generated interfaces and
- parcelables. List may optionally be used as a "generic" class (e.g.
- List&lt;String&gt;).
- The actual concrete class that the other side will receive
- will always be an ArrayList, although the method will be generated
- to use the List interface. </li>
- <li><strong>Map</strong> - All elements in the Map must be of one of the
- types in this list, including other AIDL-generated interfaces and
- parcelables. Generic maps, (e.g. of the form Map&lt;String,Integer&gt;
- are not supported.
- The actual concrete class that the other side will receive
- will always be a HashMap, although the method will be generated
- to use the Map interface.</li>
- <li><strong>CharSequence</strong> - This is useful for the CharSequence
- types used by {@link android.widget.TextView TextView} and other
- widget objects. </li>
- </ul>
- </li>
- <li>Other AIDL-generated interfaces, which are always passed by reference.
- An <code>import</code> statement is always needed for these.</li>
- <li>Custom classes that implement the <a href="#parcelable">Parcelable
- protocol</a> and are passed by value.
- An <code>import</code> statement is always needed for these.</li>
+ <li>All primitive types in the Java programming language (such as {@code int}, {@code long},
+{@code char}, {@code boolean}, and so on)</li>
+ <li>{@link java.lang.String}</li>
+ <li>{@link java.lang.CharSequence}</li>
+ <li>{@link java.util.List}
+ <p>All elements in the {@link java.util.List} must be one of the supported data types in this
+list or one of the other AIDL-generated interfaces or parcelables you've declared. A {@link
+java.util.List} may optionally be used as a "generic" class (for example,
+<code>List&lt;String&gt;</code>).
+The actual concrete class that the other side receives is always an {@link
+java.util.ArrayList}, although the method is generated to use the {@link
+java.util.List} interface.</p>
+ </li>
+ <li>{@link java.util.Map}
+ <p>All elements in the {@link java.util.Map} must be one of the supported data types in this
+list or one of the other AIDL-generated interfaces or parcelables you've declared. Generic maps,
+(such as those of the form
+{@code Map&lt;String,Integer&gt;} are not supported. The actual concrete class that the other side
+receives is always a {@link java.util.HashMap}, although the method is generated to
+use the {@link java.util.Map} interface.</p>
+ </li>
</ul>
-<p>Here is the basic AIDL syntax:</p>
-<pre>// My AIDL file, named <em>SomeClass</em>.aidl
-// Note that standard comment syntax is respected.
-// Comments before the import or package statements are not bubbled up
-// to the generated interface, but comments above interface/method/field
-// declarations are added to the generated interface.
-
-// Include your fully-qualified package statement.
-package com.android.sample;
-
-// See the list above for which classes need
-// import statements (hint--most of them)
-import com.android.sample.IAtmService;
-
-// Declare the interface.
-interface IBankAccountService {
-
- // Methods can take 0 or more parameters, and
- // return a value or void.
- int getAccountBalance();
- void setOwnerNames(in List&lt;String&gt; names);
-
- // Methods can even take other AIDL-defined parameters.
- BankAccount createAccount(in String name, int startingDeposit, in IAtmService atmService);
-
- // All non-Java primitive parameters (e.g., int, bool, etc) require
- // a directional tag indicating which way the data will go. Available
- // values are in, out, inout. (Primitives are in by default, and cannot be otherwise).
- // Limit the direction to what is truly needed, because marshalling parameters
- // is expensive.
- int getCustomerList(in String branch, out String[] customerList);
-}</pre>
-
-<h3 id="implementtheinterface">Implementing the Interface</h3>
-<p>AIDL generates an interface file for you with the same name as your .aidl
- file. If you are using the Eclipse plugin, AIDL will automatically be run as part of
- the build process (you don't need to run AIDL first and then build your project).
- If you are not using the plugin, you should run AIDL first. </p>
-<p>The generated interface
- includes an abstract inner class named Stub that declares all the methods
- that you declared in your .aidl file. Stub also defines a few helper methods,
- most notably asInterface(), which takes an IBinder (passed to a client's onServiceConnected()
- implementation when applicationContext.bindService() succeeds), and returns an
- instance of the interface used to call the IPC methods. See the section
- <a href="#calling">Calling an IPC Method</a> for more details on how to make this cast.</p>
-<p>To implement your interface, extend <em>YourInterface</em>.Stub,
- and implement the methods. (You can create the .aidl file and implement the stub
- methods without building between--the Android build process will process .aidl
-files before .java files.) </p>
-<p>Here is an example of implementing an interface called IRemoteService, which exposes
- a single method, getPid(), using an anonymous instance:</p>
-<pre>// No need to import IRemoteService if it's in the same project.
-private final IRemoteService.Stub mBinder = new IRemoteService.Stub(){
+
+<p>You must include an {@code import} statement for each additional type not listed above, even if
+they are defined in the same package as your interface.</p>
+
+<p>When defining your service interface, be aware that:</p>
+<ul>
+ <li>Methods can take zero or more parameters, and return a value or void.</li>
+ <li>All non-primitive parameters require a directional tag indicating which way the data goes.
+Either <code>in</code>, <code>out</code>, or <code>inout</code> (see the example below).
+ <p>Primitives are <code>in</code> by default, and cannot be otherwise.</p>
+ <p class="caution"><strong>Caution:</strong> You should limit the direction to what is truly
+needed, because marshalling parameters is expensive.</p></li>
+ <li>All code comments included in the {@code .aidl} file are included in the generated {@link
+android.os.IBinder} interface (except for comments before the import and package
+statements).</li>
+ <li>Only methods are supported; you cannot expose static fields in AIDL.</li>
+</ul>
+
+<p>Here is an example {@code .aidl} file:</p>
+
+<pre>
+// IRemoteService.aidl
+package com.example.android;
+
+// Declare any non-default types here with import statements
+
+/** Example service interface */
+interface IRemoteService {
+ /** Request the process ID of this service, to do evil things with it. */
+ int getPid();
+
+ /** Demonstrates some basic types that you can use as parameters
+ * and return values in AIDL.
+ */
+ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
+ double aDouble, String aString);
+}
+</pre>
+
+<p>Simply save your {@code .aidl} file in your project's {@code src/} directory and when you
+build your application, the SDK tools generate the {@link android.os.IBinder} interface file in your
+project's {@code gen/} directory. The generated file name matches the {@code .aidl} file name, but
+with a {@code .java} extension (for example, {@code IRemoteService.aidl} results in {@code
+IRemoteService.java}).</p>
+
+<p>If you use Eclipse, the incremental build generates the binder class almost immediately. If you
+do not use Eclipse, then the Ant tool generates the binder class next time you build your
+application&mdash;you should build your project with <code>ant debug</code> (or <code>ant
+release</code>) as soon as you're finished writing the {@code .aidl} file, so that your code can
+link against the generated class.</p>
+
+
+<h3 id="Implement">2. Implement the interface</h3>
+
+<p>When you build your application, the Android SDK tools generate a {@code .java} interface file
+named after your {@code .aidl} file. The generated interface includes a subclass named {@code Stub}
+that is an abstract implementation of its parent interface (for example, {@code
+YourInterface.Stub}) and declares all the methods from the {@code .aidl} file.</p>
+
+<p class="note"><strong>Note:</strong> {@code Stub} also
+defines a few helper methods, most notably {@code asInterface()}, which takes an {@link
+android.os.IBinder} (usually the one passed to a client's {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback method) and
+returns an instance of the stub interface. See the section <a href="#calling">Calling an IPC
+Method</a> for more details on how to make this cast.</p>
+
+<p>To implement the interface generated from the {@code .aidl}, extend the generated {@link
+android.os.Binder} interface (for example, {@code YourInterface.Stub}) and implement the methods
+inherited from the {@code .aidl} file.</p>
+
+<p>Here is an example implementation of an interface called {@code IRemoteService} (defined by the
+{@code IRemoteService.aidl} example, above) using an anonymous instance:</p>
+
+<pre>
+private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
public int getPid(){
return Process.myPid();
}
-}</pre>
-<p>A few rules about implementing your interface: </p>
+ public void basicTypes(int anInt, long aLong, boolean aBoolean,
+ float aFloat, double aDouble, String aString) {
+ // Does nothing
+ }
+};
+</pre>
+
+<p>Now the {@code mBinder} is an instance of the {@code Stub} class (a {@link android.os.Binder}),
+which defines the RPC interface for the service. In the next step, this instance is exposed to
+clients so they can interact with the service.</p>
+
+<p>There are a few rules you should be aware of when implementing your AIDL interface: </p>
<ul>
- <li>No exceptions that you throw will be sent back to the caller.</li>
- <li>By default, IPC calls are synchronous. If you know that an IPC service takes more than
- a few milliseconds to complete, you should not call it in the Activity/View thread,
- because it might hang the application (Android might display an &quot;Application
- is Not Responding&quot; dialog).
- Try to call them in a separate thread. </li>
- <li>Only methods are supported; you cannot declare static fields in an AIDL interface.</li>
+ <li>Incoming calls are not guaranteed to be executed on the main thread, so you need to think
+about multithreading from the start and properly build your service to be thread-safe.</li>
+ <li>By default, RPC calls are synchronous. If you know that the service takes more than a few
+milliseconds to complete a request, you should not call it from the activity's main thread, because
+it might hang the application (Android might display an &quot;Application is Not Responding&quot;
+dialog)&mdash;you should usually call them from a separate thread in the client. </li>
+ <li>No exceptions that you throw are sent back to the caller.</li>
</ul>
-<h3 id="exposingtheinterface">Exposing Your Interface to Clients</h3>
-<p>Now that you've got your interface implementation, you need to expose it to clients.
- This is known as &quot;publishing your service.&quot; To publish a service,
- inherit {@link android.app.Service Service} and implement {@link android.app.Service#onBind
- Service.onBind(Intent)} to return an instance of the class that implements your interface.
- Here's a code snippet of a service that exposes the IRemoteService
- interface to clients. </p>
-<pre>public class RemoteService extends Service {
-...
-{@include development/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
- exposing_a_service}
-}</pre>
+<h3 id="Expose">3. Expose the interface to clients</h3>
+
+<p>Once you've implemented the interface for your service, you need to expose it to
+clients so they can bind to it. To expose the interface
+for your service, extend {@link android.app.Service Service} and implement {@link
+android.app.Service#onBind onBind()} to return an instance of your class that implements
+the generated {@code Stub} (as discussed in the previous section). Here's an example
+service that exposes the {@code IRemoteService} example interface to clients. </p>
+
+<pre>
+public class RemoteService extends Service {
+ &#64;Override
+ public void onCreate() {
+ super.onCreate();
+ }
+
+ &#64;Override
+ public IBinder onBind(Intent intent) {
+ // Return the interface
+ return mBinder;
+ }
+
+ private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
+ public int getPid(){
+ return Process.myPid();
+ }
+ public void basicTypes(int anInt, long aLong, boolean aBoolean,
+ float aFloat, double aDouble, String aString) {
+ // Does nothing
+ }
+ };
+}
+</pre>
+
+<p>Now, when a client (such as an activity) calls {@link android.content.Context#bindService
+bindService()} to connect to this service, the client's {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback receives the
+{@code mBinder} instance returned by the service's {@link android.app.Service#onBind onBind()}
+method.</p>
+
+<p>The client must also have access to the interface class, so if the client and service are in
+separate applications, then the client's application must have a copy of the {@code .aidl} file
+in its {@code src/} directory (which generates the {@code android.os.Binder}
+interface&mdash;providing the client access to the AIDL methods).</p>
+
+<p>When the client receives the {@link android.os.IBinder} in the {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback, it must call
+<code><em>YourServiceInterface</em>.Stub.asInterface(service)</code> to cast the returned
+parameter to <code><em>YourServiceInterface</em></code> type. For example:</p>
+
+<pre>
+IRemoteService mIRemoteService;
+private ServiceConnection mConnection = new ServiceConnection() {
+ // Called when the connection with the service is established
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ // Following the example above for an AIDL interface,
+ // this gets an instance of the IRemoteInterface, which we can use to call on the service
+ mIRemoteService = IRemoteService.Stub.asInterface(service);
+ }
+
+ // Called when the connection with the service disconnects unexpectedly
+ public void onServiceDisconnected(ComponentName className) {
+ Log.e(TAG, "Service has unexpectedly disconnected");
+ mIRemoteService = null;
+ }
+};
+</pre>
-<h3 id="parcelable">Pass by value Parameters using Parcelables</h3>
+<p>For more sample code, see the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
+RemoteService.java}</a> class in <a
+href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p>
+
+
+
+
+
+
+
+
+<h2 id="PassingObjects">Passing Objects over IPC</h2>
<p>If you have a class that you would like to send from one process to another through
-an AIDL interface, you can do that. You must ensure that the code for your class is available
-to the other side of the IPC. Generally, that means that you're talking to a service that you
-started.</p>
-<p>There are five parts to making a class support the Parcelable protocol:</b>
+an IPC interface, you can do that. However, you must ensure that the code for your class is
+available to the other side of the IPC channel and your class must support the {@link
+android.os.Parcelable} interface. Supporting the {@link android.os.Parcelable} interface is
+important because it allows the Android system to decompose objects into primitives that can be
+marshalled across processes.</p>
+
+<p>To create a class that supports the {@link android.os.Parcelable} protocol, you must do the
+following:</b>
<ol>
<li>Make your class implement the {@link android.os.Parcelable} interface.</li>
-<li>Implement the method <code>public void writeToParcel(Parcel out)</code> that takes the
-current state of the object and writes it to a parcel.</li>
-value in a parcel into your object.</li>
+<li>Implement {@link android.os.Parcelable#writeToParcel writeToParcel}, which takes the
+current state of the object and writes it to a {@link android.os.Parcel}.</li>
<li>Add a static field called <code>CREATOR</code> to your class which is an object implementing
the {@link android.os.Parcelable.Creator Parcelable.Creator} interface.</li>
-<li>Last but not least, create an aidl file
-that declares your parcelable class (as shown below). If you are using a custom build process,
-do not add the aidl file to your build. Similar to a header file in C, the aidl file isn't
-compiled.</li>
+<li>Finally, create an {@code .aidl} file that declares your parcelable class (as shown for the
+{@code Rect.aidl} file, below).
+ <p>If you are using a custom build process, do <em>not</em> add the {@code .aidl} file to your
+build. Similar to a header file in the C language, this {@code .aidl} file isn't compiled.</p></li>
</ol>
-<p>AIDL will use these methods and fields in the code it generates to marshall and unmarshall
+<p>AIDL uses these methods and fields in the code it generates to marshall and unmarshall
your objects.</p>
-<p>Here is an example of how the {@link android.graphics.Rect} class implements the
-Parcelable protocol.</p>
-<pre class="prettyprint">
+<p>For example, here is a {@code Rect.aidl} file to create a {@code Rect} class that's
+parcelable:</p>
+
+<pre>
+package android.graphics;
+
+// Declare Rect so AIDL can find it and knows that it implements
+// the parcelable protocol.
+parcelable Rect;
+</pre>
+
+<p>And here is an example of how the {@link android.graphics.Rect} class implements the
+{@link android.os.Parcelable} protocol.</p>
+
+<pre>
import android.os.Parcel;
import android.os.Parcelable;
@@ -218,7 +376,8 @@ public final class Rect implements Parcelable {
public int right;
public int bottom;
- public static final Parcelable.Creator&lt;Rect&gt; CREATOR = new Parcelable.Creator&lt;Rect&gt;() {
+ public static final Parcelable.Creator&lt;Rect&gt; CREATOR = new
+Parcelable.Creator&lt;Rect&gt;() {
public Rect createFromParcel(Parcel in) {
return new Rect(in);
}
@@ -251,43 +410,42 @@ public final class Rect implements Parcelable {
}
</pre>
-<p>Here is Rect.aidl for this example</p>
+<p>The marshalling in the {@code Rect} class is pretty simple. Take a look at the other
+methods on {@link android.os.Parcel} to see the other kinds of values you can write
+to a Parcel.</p>
-<pre class="prettyprint">
-package android.graphics;
+<p class="warning"><strong>Warning:</strong> Don't forget the security implications of receiving
+data from other processes. In this case, the {@code Rect} reads four numbers from the {@link
+android.os.Parcel}, but it is up to you to ensure that these are within the acceptable range of
+values for whatever the caller is trying to do. See <a
+href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> for more
+information about how to keep your application secure from malware.</p>
-// Declare Rect so AIDL can find it and knows that it implements
-// the parcelable protocol.
-parcelable Rect;
-</pre>
-<p>The marshalling in the Rect class is pretty simple. Take a look at the other
-methods on {@link android.os.Parcel} to see the other kinds of values you can write
-to a Parcel.</p>
-<p class="warning"><b>Warning:</b> Don't forget the security implications of receiving data from
-other processes. In this case, the rect will read four numbers from the parcel,
-but it is up to you to ensure that these are within the acceptable range of
-values for whatever the caller is trying to do. See
-<a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> for more
-on how to keep your application secure from malware.</p>
+<h2 id="Calling">Calling an IPC Method</h2>
-<h2 id="calling">Calling an IPC Method</h2>
-<p>Here are the steps a calling class should make to call your remote interface: </p>
+<p>Here are the steps a calling class must take to call a remote interface defined with AIDL: </p>
<ol>
- <li>Declare a variable of the interface type that your .aidl file defined. </li>
+ <li>Include the {@code .aidl} file in the project {@code src/} directory.</li>
+ <li>Declare an instance of the {@link android.os.IBinder} interface (generated based on the
+AIDL). </li>
<li>Implement {@link android.content.ServiceConnection ServiceConnection}. </li>
- <li>Call {@link android.content.Context#bindService(android.content.Intent,android.content.ServiceConnection,int)
- Context.bindService()}, passing in your ServiceConnection implementation. </li>
- <li>In your implementation of {@link android.content.ServiceConnection#onServiceConnected(android.content.ComponentName,android.os.IBinder)
- ServiceConnection.onServiceConnected()}, you will receive an {@link android.os.IBinder
- IBinder} instance (called <em>service</em>). Call <code><em>YourInterfaceName</em>.Stub.asInterface((IBinder)<em>service</em>)</code> to
+ <li>Call {@link
+android.content.Context#bindService(android.content.Intent,android.content.ServiceConnection,int)
+ Context.bindService()}, passing in your {@link
+android.content.ServiceConnection} implementation. </li>
+ <li>In your implementation of {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()},
+you will receive an {@link android.os.IBinder} instance (called <code>service</code>). Call
+<code><em>YourInterfaceName</em>.Stub.asInterface((IBinder)<em>service</em>)</code> to
cast the returned parameter to <em>YourInterface</em> type.</li>
<li>Call the methods that you defined on your interface. You should always trap
{@link android.os.DeadObjectException} exceptions, which are thrown when
the connection has broken; this will be the only exception thrown by remote
methods.</li>
- <li>To disconnect, call {@link android.content.Context#unbindService(android.content.ServiceConnection)
+ <li>To disconnect, call {@link
+android.content.Context#unbindService(android.content.ServiceConnection)
Context.unbindService()} with the instance of your interface. </li>
</ol>
<p>A few comments on calling an IPC service:</p>
@@ -296,10 +454,12 @@ on how to keep your application secure from malware.</p>
<li>You can send anonymous objects
as method arguments. </li>
</ul>
+
+<p>For more information about binding to a service, read the <a
+href="{@docRoot}guide/topics/fundamentals/bound-services.html#Binding">Bound Services</a>
+document.</p>
+
<p>Here is some sample code demonstrating calling an AIDL-created service, taken
from the Remote Service sample in the ApiDemos project.</p>
<p>{@sample development/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
calling_a_service}</p>
-
-
-
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 92230a954774..d81b41670924 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -554,7 +554,6 @@
<ul>
<li><a href="<?cs var:toroot ?>guide/developing/tools/adb.html">adb</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/android.html">android</a></li>
- <li><a href="<?cs var:toroot ?>guide/developing/tools/aidl.html">aidl</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/bmgr.html">bmgr</a>
<li><a href="<?cs var:toroot ?>guide/developing/tools/dmtracedump.html">dmtracedump</a></li>
<li><a href="<?cs var:toroot ?>guide/developing/tools/draw9patch.html" >Draw 9-Patch</a></li>
@@ -754,6 +753,7 @@
<li><a href="<?cs var:toroot ?>guide/appendix/g-app-intents.html">
<span class="en">Intents List: Google Apps</span>
</a></li>
+ <li><a href="<?cs var:toroot ?>guide/developing/tools/aidl.html">AIDL</a></li>
<li><a href="<?cs var:toroot ?>guide/appendix/glossary.html">
<span class="en">Glossary</span>
</a></li>
diff --git a/docs/html/guide/topics/advanced/aidl.jd b/docs/html/guide/topics/advanced/aidl.jd
deleted file mode 100644
index 419048a083d0..000000000000
--- a/docs/html/guide/topics/advanced/aidl.jd
+++ /dev/null
@@ -1,389 +0,0 @@
-page.title=Android Interface Definition Language (AIDL)
-@jd:body
-
-
-
-<p>AIDL (Android Interface Definition Language) is similar to other IDLs you might have
-worked with. It allows you to define the programming interface that both
-the client and service agree upon in order to communicate with each other and allows for
-interprocess communication (IPC). On Android, one process can not normally access the
-memory of another process. So to talk, they need to decompose their objects into primitives that the
-operating system can understand, and "marshall" the object across that boundary for you. The code to
-do that marshalling is tedious to write, so Android handles it for you with AIDL.</p>
-
-<p class="note"><strong>Note:</strong> Using AIDL is necessary only if you allow clients from
-different applications to access your service for IPC and want to handle multithreading in your
-service. If you do not need to perform IPC across
-different applications, you should create your interface <a
-href="{@docRoot}guide/topics/fundamentals/bound-services.html#Binder">implementing a
-Binder</a> or, if you want to perform IPC, but do not need to handle multithreading, then you
-should implement your interface <a
-href="{@docRoot}guide/topics/fundamentals/bound-services.html#Messenger">using a Messenger</a>.</p>
-
-<p>Before you begin designing your AIDL interface, be aware that calls on to an AIDL interface are
-direct function calls. You can not generally make assumptions about the thread in which the call
-will happen. What happens is different depending on whether the call is from a thread in the
-local process, or coming from a remote process. Specifically:</p>
-
-<ul>
-<li>Calls from the local process are executed in the same thread that is making the call. If this is
-your main UI thread, that thread will continue executing into the aidl interface. If it is another
-thread, that is one that will be executing your code. Thus if only local threads are accessing the
-interface, you can completely control which threads are executing in it (but if that is the case,
-why are you defining an aidl interface at all?).</li>
-
-<li>Calls from a remote process are dispatched from a thread pool the platform maintains inside of
-your own process. You must be prepared for incoming calls from unknown threads, with multiple calls
-happening at the same time. In other words, an implementation of an aidl interface must be
-completely thread-safe.</li>
-
-<li>The "oneway" keyword modifies the behavior of remote calls. When used, a remote call will not
-block until its call completes; it simply sends the transaction data and immediately returns. The
-implementation of the interface will eventually receive this as a regular call from the {@link
-android.os.Binder} thread pool as a normal remote call. If "oneway" is used with a local call,
-there is no impact and the call is still synchronous.</li>
-</ul>
-
-
-<h2 id="Defining">Defining an AIDL Interface</h2>
-
-<p>You must define your AIDL interface in an {@code .aidl} file using the Java
-programming language syntax, then save it in the source code (in the {@code src/} directory) of both
-the application hosting the service and any other application that will bind to the service.</p>
-
-<p>When you build the projects containing the {@code .aidl} file, the Android SDK tools generate an
-{@link android.os.IBinder} class based on your AIDL interface (and saves the file in the {@code
-gen/} directory). This class defines the APIs you can call to perform RPC as an interface&mdash;you
-must implement the interface in your service.</p>
-
-<p>To create a bounded service using AIDL, follow these steps:</p>
-<ol>
- <li><a href="#CreateAidl">Create the .aidl file</a>
- <p>This file defines the programming interface with method signatures.</p>
- </li>
- <li><a href="#ImplementTheInterface">Implement the interface</a>
- <p>The Android SDK tools generate an interface in the Java programming language, based on your
-{@code .aidl} file. This interface has an inner abstract class named {@code Stub} that extends
-{@link android.os.Binder} and implements methods from your AIDL interface. You must extend the
-{@code Stub} class and implement the methods.</p>
- </li>
- <li><a href="#ExposeTheInterface">Expose the interface to clients</a>
- <p>Implement a {@link android.app.Service Service} and override {@link
-android.app.Service#onBind onBind()} to return your implementation of the {@code Stub}
-class.</p>
- </li>
-</ol>
-
-<p class="caution"><strong>Caution:</strong> Any changes that you make to your AIDL interface after
-your first release must remain backward compatible in order to avoid breaking other applications
-that use your service. That is, because your {@code .aidl} file must be copied to other applications
-in order for them to access your service's interface, you must maintain support for the original
-interface.</p>
-
-
-<h3 id="CreateAidl">1. Create the .aidl file</h3>
-
-<p>AIDL uses a simple syntax that lets you declare an interface with one or more methods that can
-take parameters and return values. The parameters and return values can be of any type, even other
-AIDL-generated interfaces.</p>
-
-<p>The syntax for the {@code .aidl} file uses the Java programming language. The file defines a
-single interface and requires only the interface declaration and method signatures.</p>
-
-<p>By default, AIDL supports the following data types:</p>
-
-<ul>
- <li>All primitive types in the Java programming language ({@code int}, {@code long}, {@code
-char}, {@code boolean}, etc.)</li>
- <li>{@link java.lang.String}</li>
- <li>{@link java.lang.CharSequence}</li>
- <li>{@link java.util.List}
- <p>All elements in the {@link java.util.List} must be one of the supported data types in this
-list or one of the other AIDL-generated interfaces or parcelables you've declared. A {@link
-java.util.List} may optionally be used as a "generic" class (e.g. <code>List&lt;String&gt;</code>).
-The actual concrete class that the other side will receive will always be an {@link
-java.util.ArrayList}, although the method will be generated to use the {@link
-java.util.List} interface.</p>
- </li>
- <li>{@link java.util.Map}
- <p>All elements in the {@link java.util.Map} must be one of the supported data types in this
-list or one of the other AIDL-generated interfaces or parcelables you've declared. Generic maps,
-(such as those of the form
-{@code Map&lt;String,Integer&gt;} are not supported. The actual concrete class that the other side
-will receive will always be a {@link java.util.HashMap}, although the method will be generated to
-use the {@link java.util.Map} interface.</p>
- </li>
-</ul>
-
-<p>You must include an {@code import} statement for each additional type not listed above, even if
-they are defined in the same package as your interface.</p>
-
-<p>When defining methods for your service interface, be aware that:</p>
-<ul>
- <li>Methods can take zero or more parameters, and return a value or void.</li>
- <li>All non-primitive parameters require a directional tag indicating which way the data will go.
-Either <code>in</code>, <code>out</code>, or <code>inout</code> (see the example below).
- <p>Primitives are <code>in</code> by default, and cannot be otherwise.</p>
- <p class="caution"><strong>Caution:</strong> You should limit the direction to what is truly
-needed, because marshalling parameters is expensive.</p></li>
- <li>All code comments included in the {@code .aidl} file are included in the generated {@link
-android.os.IBinder} interface (except for comments before the import and package
-statements).</li>
-</ul>
-
-<p>Here is an example {@code .aidl} file:</p>
-
-<pre>
-// IRemoteService.aidl
-package com.example.android;
-
-// Declare any non-default types here with import statements
-
-/** Example service interface */
-interface IRemoteService {
- /** Request the process ID of this service, to do evil things with it. */
- int getPid();
-
- /** Demonstrates some basic types that you can use as parameters
- * and return values in AIDL.
- */
- void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
- double aDouble, String aString);
-}
-</pre>
-
-<p>Simply save your {@code .aidl} file in your project's {@code src/} directory and when you
-build your application, the SDK tools will generate the binder class file in your project's
-{@code gen/} directory. The generated file name matches the {@code .aidl} file name, but with a
-{@code .java} extension (for example, {@code IRemoteService.aidl} results in {@code
-IRemoteService.java}).</p>
-
-<p>If you use Eclipse, the incremental build generates the binder class almost immediately. If you
-do not use Eclipse, then the Ant tool generates the binder class next time you build your
-application&mdash;you should build your project with <code>ant debug</code> (or <code>ant
-release</code>) as soon as you're finished writing the {@code .aidl} file, so that your code can
-link against the generated class.</p>
-
-
-<h3 id="ImplementTheInterface">2. Implement the interface</h3>
-
-<p>When you build your application, the Android SDK tools generate a {@code .java} interface file
-named after your {@code .aidl} file. The generated interface includes a subclass named {@code Stub}
-that is an abstract implementation of its parent interface (for example, {@code
-YourInterface.Stub}) and declares all the methods from the {@code .aidl} file.</p>
-
-<p class="note"><strong>Note:</strong> {@code Stub} also
-defines a few helper methods, most notably {@code asInterface()}, which takes an {@link
-android.os.IBinder} (usually the one passed to a client's {@link
-android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback method) and
-returns an instance of the stub interface. See the section <a href="#calling">Calling an IPC
-Method</a> for more details on how to make this cast.</p></p>
-
-<p>To implement the interface generated from the {@code .aidl}, extend the generated {@link
-android.os.Binder} interface (for example, {@code YourInterface.Stub}) and implement the methods
-inherited from the {@code .aidl} file.</p>
-
-<p>Here is an example implementation of an interface called {@code IRemoteService} (defined by the
-{@code IRemoteService.aidl} example, above) using an anonymous instance:</p>
-
-<pre>
-private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
- public int getPid(){
- return Process.myPid();
- }
- public void basicTypes(int anInt, long aLong, boolean aBoolean,
- float aFloat, double aDouble, String aString) {
- // Does nothing
- }
-};
-</pre>
-
-<p>Now the {@code mBinder} is an instance of the {@code Stub} class (a {@link android.os.Binder}),
-which defines the RPC interface for the service. In the next step, this instance is exposed to
-clients so they can interact with the service.</p>
-
-<p>There are a few rules you should be aware of when implementing your AIDL interface: </p>
-<ul>
- <li>Incoming calls are not guaranteed to be executed on the main thread, so you need to think
-about multithreading from the start and properly build your service to be thread-safe.</li>
- <li>By default, RPC calls are synchronous. If you know that the service takes more than a few
-milliseconds to complete a request, you should not call it from the activity's main thread, because
-it might hang the application (Android might display an &quot;Application is Not Responding&quot;
-dialog)&mdash;you should usually call them from a separate thread in the client. </li>
- <li>No exceptions that you throw are sent back to the caller.</li>
- <li>Only methods are supported; you cannot expose static fields in AIDL.</li>
-</ul>
-
-
-<h3 id="ExposeTheInterface">3. Expose the interface to clients</h3>
-
-<p>Once you've implemented the interface for your service, you need to expose it to
-clients so they can bind to it. To expose the interface
-for your service, extend {@link android.app.Service Service} and implement {@link
-android.app.Service#onBind onBind()} to return an instance of your class that implements
-the generated {@code Stub} (as discussed in the previous section). Here's an example
-service that exposes the {@code IRemoteService} example interface to clients. </p>
-
-<pre>
-public class RemoteService extends Service {
- &#64;Override
- public void onCreate() {
- super.onCreate();
- }
-
- &#64;Override
- public IBinder onBind(Intent intent) {
- // Return the interface
- return mBinder;
- }
-
- private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
- public int getPid(){
- return Process.myPid();
- }
- public void basicTypes(int anInt, long aLong, boolean aBoolean,
- float aFloat, double aDouble, String aString) {
- // Does nothing
- }
- };
-}
-</pre>
-
-<p>Now, when a client (such as an activity) calls {@link android.content.Context#bindService
-bindService()} to connect to this service, the client's {@link
-android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback receives the
-{@code mBinder} instance returned by the service's {@link android.app.Service#onBind onBind()}
-method.</p>
-
-<p>The client must also have access to the interface class, so if the client and service are in
-separate applications, then the client's application must have a copy of the {@code .aidl} file
-in its {@code src/} directory (which generates the {@code android.os.Binder}
-interface&mdash;providing the client access to the AIDL methods).</p>
-
-<p>When the client receives the {@link android.os.IBinder} in the {@link
-android.content.ServiceConnection#onServiceConnected onServiceConnected()} callback, it must call
-<code><em>YourServiceInterface</em>.Stub.asInterface(service)</code> to cast the returned
-parameter to <code><em>YourServiceInterface</em></code> type. For example:</p>
-
-<pre>
-IRemoteService mIRemoteService;
-private ServiceConnection mConnection = new ServiceConnection() {
- // Called when the connection with the service is established
- public void onServiceConnected(ComponentName className, IBinder service) {
- // Following the example above for an AIDL interface,
- // this gets an instance of the IRemoteInterface, which we can use to call on the service
- mIRemoteService = IRemoteService.Stub.asInterface(service);
- }
-
- // Called when the connection with the service disconnects unexpectedly
- public void onServiceDisconnected(ComponentName className) {
- Log.e(TAG, "onServiceDisconnected");
- }
-};
-</pre>
-
-<p>For more sample code, see the <a
-href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
-RemoteService.java}</a> class in <a
-href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p>
-
-
-
-
-
-
-
-
-<h2 id="PassingObjects">Passing Objects over IPC</h2>
-
-<p>If you have a class that you would like to send from one process to another through
-an IPC interface, you can do that. However, you must ensure that the code for your class is
-available to the other side of the IPC and the class must support the {@link
-android.os.Parcelable} interface, in order for the objects to be decomposed into primitives and
-marshalled across processes by the Android system.</p>
-
-<p>There are five parts to making a class support the {@link android.os.Parcelable} protocol:</b>
-<ol>
-<li>Make your class implement the {@link android.os.Parcelable} interface.</li>
-<li>Implement {@link android.os.Parcelable#writeToParcel writeToParcel}, which takes the
-current state of the object and writes it to a {@link android.os.Parcel}.</li>
-<li>Add a static field called <code>CREATOR</code> to your class which is an object implementing
-the {@link android.os.Parcelable.Creator Parcelable.Creator} interface.</li>
-<li>Finally, create an {@code .aidl} file that declares your parcelable class (as shown for the
-{@code Rect.aidl} file, below).
- <p>If you are using a custom build process, do <em>not</em> add the {@code .aidl} file to your
-build. Similar to a header file in the C language, this {@code .aidl} file isn't compiled.</p></li>
-</ol>
-
-<p>AIDL will use these methods and fields in the code it generates to marshall and unmarshall
-your objects.</p>
-
-<p>For example, here is a {@code Rect.aidl} file to create a {@code Rect} class that's
-parcelable:</p>
-
-<pre>
-package android.graphics;
-
-// Declare Rect so AIDL can find it and knows that it implements
-// the parcelable protocol.
-parcelable Rect;
-</pre>
-
-<p>And here is an example of how the {@link android.graphics.Rect} class implements the
-{@link android.os.Parcelable} protocol.</p>
-
-<pre>
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public final class Rect implements Parcelable {
- public int left;
- public int top;
- public int right;
- public int bottom;
-
- public static final Parcelable.Creator&lt;Rect&gt; CREATOR = new
-Parcelable.Creator&lt;Rect&gt;() {
- public Rect createFromParcel(Parcel in) {
- return new Rect(in);
- }
-
- public Rect[] newArray(int size) {
- return new Rect[size];
- }
- };
-
- public Rect() {
- }
-
- private Rect(Parcel in) {
- readFromParcel(in);
- }
-
- public void writeToParcel(Parcel out) {
- out.writeInt(left);
- out.writeInt(top);
- out.writeInt(right);
- out.writeInt(bottom);
- }
-
- public void readFromParcel(Parcel in) {
- left = in.readInt();
- top = in.readInt();
- right = in.readInt();
- bottom = in.readInt();
- }
-}
-</pre>
-
-<p>The marshalling in the {@code Rect} class is pretty simple. Take a look at the other
-methods on {@link android.os.Parcel} to see the other kinds of values you can write
-to a Parcel.</p>
-
-<p class="warning"><strong>Warning:</strong> Don't forget the security implications of receiving
-data from other processes. In this case, the {@code Rect} will read four numbers from the {@link
-android.os.Parcel}, but it is up to you to ensure that these are within the acceptable range of
-values for whatever the caller is trying to do. See <a
-href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> for more
-information about how to keep your application secure from malware.</p>
-
diff --git a/docs/html/guide/topics/fundamentals/bound-services.jd b/docs/html/guide/topics/fundamentals/bound-services.jd
index e5d626c0799c..ec7d7230d90e 100644
--- a/docs/html/guide/topics/fundamentals/bound-services.jd
+++ b/docs/html/guide/topics/fundamentals/bound-services.jd
@@ -170,7 +170,7 @@ can then extend within your service.</p>
create a bound service, because it may require multithreading capabilities and
can result in a more complicated implementation. As such, AIDL is not suitable for most applications
and this document does not discuss how to use it for your service. If you're certain that you need
-to use AIDL directly, see the <a href="{@docRoot}guide/topics/advanced/aidl.html">AIDL</a>
+to use AIDL directly, see the <a href="{@docRoot}guide/developing/tools/aidl.html">AIDL</a>
document.</p>
@@ -341,7 +341,7 @@ service, which must then handle multi-threading.</p>
<p>For most applications, the service doesn't need to perform multi-threading, so using a {@link
android.os.Messenger} allows the service to handle one call at a time. If it's important
that your service be multi-threaded, then you should use <a
-href="{@docRoot}guide/topics/advanced/aidl.html">AIDL</a> to define your interface.</p>
+href="{@docRoot}guide/developing/tools/aidl.html">AIDL</a> to define your interface.</p>
</div>
</div>
diff --git a/docs/html/guide/topics/graphics/renderscript.jd b/docs/html/guide/topics/graphics/renderscript.jd
index 54737ad71804..0e64c786ab11 100644
--- a/docs/html/guide/topics/graphics/renderscript.jd
+++ b/docs/html/guide/topics/graphics/renderscript.jd
@@ -16,7 +16,7 @@ parent.link=index.html
<ol>
<li><a href="#native-api">Native Renderscript APIs</a></li>
- <li><a href="#reflective-api">Reflective layer APIs</a></li>
+ <li><a href="#reflective-api">Reflected layer APIs</a></li>
<li><a href="#graphics-api">Graphics APIs</a></li>
</ol>
@@ -30,10 +30,18 @@ parent.link=index.html
</ol>
</li>
</ol>
+ <h2>Related Samples</h2>
+ <ol>
+ <li><a href="{@docRoot}resources/samples/Renderscript/Balls/index.html">Balls</a></li>
+ <li><a href="{@docRoot}resources/samples/Renderscript/Fountain/index.html">Fountain</a></li>
+ <li><a href="{@docRoot}resources/samples/Renderscript/HelloCompute/index.html">Hello Compute</a></li>
+ <li><a href="{@docRoot}resources/samples/Renderscript/HelloWorld/index.html">Hello World</a></li>
+ <li><a href="{@docRoot}resources/samples/Renderscript/Samples/index.html">Samples</a></li>
+ </ol>
</div>
</div>
- <p>The Renderscript system offers high performance 3D rendering and mathematical computations at
+ <p>The Renderscript system offers high performance 3D rendering and mathematical computation at
the native level. The Renderscript APIs are intended for developers who are comfortable with
developing in C (C99 standard) and want to maximize performance in their applications. The
Renderscript system improves performance by running as native code on the device, but it also
@@ -46,47 +54,46 @@ parent.link=index.html
intermediate code.</p>
<p>The disadvantage of the Renderscript system is that it adds complexity to the development and
- debugging processes and is not a substitute for the Android system APIs. It is a portable native
- language with pointers and explicit resource management. The target use is for performance
- critical code where the existing Android APIs are not sufficient. If what you are rendering or
- computing is very simple and does not require much processing power, you should still use the
- Android APIs for ease of development. Debugging visibility can be limited, because the
+ debugging processes. Debugging visibility can be limited, because the
Renderscript system can execute on processors other than the main CPU (such as the GPU), so if
- this occurs, debugging becomes more difficult. Remember the tradeoffs between development and
- debugging complexity versus performance when deciding to use Renderscript.</p>
+ this occurs, debugging becomes more difficult. The target use is for performance
+ critical code where the traditional framework APIs (such as using {@link android.opengl}) are not sufficient.
+ If what you are rendering or computing is very simple and does not require much processing power, you should still use the
+ traditional framework APIs for ease of development. Remember the tradeoffs between development and
+ debugging complexity versus performance when deciding to use Renderscript. </p>
<p>For an example of Renderscript in action, see the 3D carousel view in the Android 3.0 versions
of Google Books and YouTube or install the Renderscript sample applications that are shipped with
- the SDK in <code>&lt;sdk_root&gt;/platforms/android-3.0/samples</code>.</p>
+ the SDK in <code>&lt;sdk_root&gt;/samples/android-11/Renderscript</code>.</p>
<h2 id="overview">Renderscript System Overview</h2>
<p>The Renderscript system adopts a control and slave architecture where the low-level native
code is controlled by the higher level Android system that runs in the virtual machine (VM). When
- you use the Renderscript system, there are three layers of APIs that exist:</p>
+ you use the Renderscript system, there are three layers that exist:</p>
<ul>
- <li>The native Renderscript layer consists of the native Renderscript <code>.rs</code> files
- that you write to compute mathematical operations, render graphics, or both. This layer does
- the intensive computation or graphics rendering and returns the result back to the Android VM
- through the reflected layer.</li>
+ <li>The native Renderscript layer consists of native libraries that are packaged with the SDK.
+ The native Renderscript <code>.rs</code> files compute mathematical operations, render graphics,
+ or both. This layer does the intensive computation or graphics rendering and returns the result
+ back to the Android VM through the reflected layer.</li>
- <li>The reflected layer is a set of generated Android system classes (through reflection) based
- on the native layer interface that you define. This layer acts as a bridge between the native
+ <li>The reflected layer is a set of generated Android framework classes reflected from
+ the native Renderscript code that you wrote. This layer acts as a bridge between the native
Renderscript layer and the Android system layer. The Android build tools automatically generate
- the APIs for this layer during the build process.</li>
+ the classes for this layer during the build process. This layer also includes a set of Android
+ framework APIs that provide the memory and resource allocation classes to support this layer.</li>
- <li>The Android system layer consists of your normal Android APIs along with the Renderscript
+ <li>The Android system layer consists of the traditional framework APIs, which include the Renderscript
APIs in {@link android.renderscript}. This layer handles things such as the Activity lifecycle
- management of your application and calls the native Renderscript layer through the reflected
- layer.</li>
+ management of your application and calls the reflected layer to communicate with the native Renderscript code.</li>
</ul>
<p>To fully understand how the Renderscript system works, you must understand how the reflected
layer is generated and how it interacts with the native Renderscript layer and Android system
layer. The reflected layer provides the entry points into the native code, enabling the Android
- system code to give high level commands like, "rotate the view" or "filter the bitmap." It
- delegates all the heavy lifting to the native layer. To accomplish this, you need to create logic
+ system to give high level commands like, "rotate the view" or "filter the bitmap" to the
+ native layer, which does the heavy lifting. To accomplish this, you need to create logic
to hook together all of these layers so that they can correctly communicate.</p>
<p>At the root of everything is your Renderscript, which is the actual C code that you write and
@@ -94,11 +101,10 @@ parent.link=index.html
and graphics. A compute Renderscript does not do any graphics rendering while a graphics
Renderscript does.</p>
- <p>When you create a Renderscript <code>.rs</code> file, an equivalent, reflective layer class,
- {@link android.renderscript.ScriptC}, is generated by the build tools and exposes the native
- functions to the Android system. This class is named
- <code><em>ScriptC_renderscript_filename</em></code>. The following list describes the major
- components of your native Renderscript code that is reflected:</p>
+ <p>When you create Renderscript <code>.rs</code> files, equivalent, reflected classes
+ are generated by the build tools and expose the native functions and data types and structures
+ to the Android system. The following list describes the major components of your native Renderscript
+ code that is reflected:</p>
<ul>
<li>The non-static functions in your Renderscript (<code>.rs</code> file) are reflected into
@@ -108,12 +114,12 @@ parent.link=index.html
<li>Any non-static, global Renderscript variables are reflected into
<code><em>ScriptC_renderscript_filename</em></code>.
Accessor methods are generated, so the Android system layer can access the values.
- The <code>get()</code> method comes with a one-way communication restriction.
- The Android system layer always caches the last value that is set and returns that during a call to get.
- If the native Renderscript code has changed the value, the change does propagate back to the Android system layer
- for efficiency. If the global variables are initialized in the native Renderscript code, those values are used
- to initialize the Android system versions. If global variables are marked as <code>const</code>,
- then a <code>set()</code> method is not generated.
+ The <code>get</code> method comes with a one-way communication restriction.
+ The Android system layer always caches the last value that is set and returns that during a call to a <code>get<code> method.
+ If the native Renderscript code changes the value, the change does not propagate back to the Android system layer.
+ If the global variables are initialized in the native Renderscript code, those values are used
+ to initialize the corresponding values in the Android system. If global variables are marked as <code>const</code>,
+ then a <code>set</code> method is not generated.
</li>
<li>Structs are reflected into their own classes, one for each struct, into a class named
@@ -128,15 +134,14 @@ parent.link=index.html
Renderscripts should not directly set the exported global pointers.</li>
</ul>
- <p>The Android system also has a corresponding Renderscript context object, {@link
+ <p>The Android framework API also has a corresponding Renderscript context object, {@link
android.renderscript.RenderScript} (for a compute Renderscript) or {@link
android.renderscript.RenderScriptGL} (for a graphics Renderscript). This context object allows
you to bind to the reflected Renderscript class, so that the Renderscript context knows what its
corresponding native Renderscript is. If you have a graphics Renderscript context, you can also
specify a variety of Programs (stages in the graphics pipeline) to tweek how your graphics are
rendered. A graphics Renderscript context also needs a surface to render on, {@link
- android.renderscript.RSSurfaceView}, which gets passed into its constructor. When all three of
- the layers are connected, the Renderscript system can compute or render graphics.</p>
+ android.renderscript.RSSurfaceView}, which gets passed into its constructor.</p>
<h2 id="api">API overview</h2>
@@ -145,15 +150,15 @@ parent.link=index.html
because these functions are assumed to be running on a standard CPU. The Renderscript runtime
chooses the best processor to execute the code, which may not be the CPU, so it cannot guarantee
support for standard C libraries. What Renderscript does offer is an API that supports intensive
- computation with an extensive collection of math APIs. Some key features of the Renderscript APIs
- are:</p>
+ computation with an extensive collection of math APIs. The following sections group the APIs
+ into three distinct categories.</p>
<h3 id="native-api">Native Renderscript APIs</h3>
<p>The Renderscript headers are located in the <code>include</code> and
<code>clang-include</code> directories in the
- <code>&lt;sdk_root&gt;/platforms/android-3.0/renderscript</code> directory of the Android SDK.
+ <code>&lt;sdk_root&gt;/platforms/android-11/renderscript</code> directory of the Android SDK.
The headers are automatically included for you, except for the graphics specific header,
which you can define as follows:</p>
@@ -170,16 +175,14 @@ parent.link=index.html
<li>Graphics rendering functions</li>
<li>Memory allocation request features</li>
<li>Data types and structures to support the Renderscript system such as
- Vector types for defining two-, three-, or four-vectors.</li></li>
- </ul>
+ Vector types for defining two-, three-, or four-vectors.</li>
</ul>
- <h3 id="reflective-api">Reflective layer APIs</h3>
+ <h3 id="reflective-api">Reflected layer APIs</h3>
- <p>These classes are not generated by the reflection process, and are actually part of the
- Android system APIs, but they are mainly used by the reflective layer classes to handle memory
- allocation and management for your Renderscript. You normally do not need to be call these classes
- directly.</p>
+ <p>These classes are mainly used by the reflected classes that are generated from your native Renderscript
+ code. They allocate and manage memory for your Renderscript on the Android system side.
+ You normally do not need to call these classes directly.</p>
<p>Because of the constraints of the Renderscript native layer, you cannot do any dynamic
memory allocation in your Renderscript <code>.rs</code> file.
@@ -195,7 +198,7 @@ parent.link=index.html
The Android system object, which at this point is just an empty shell, is eventually garbage collected.
</p>
- <p>The following classes are mainly used by the reflective layer classes:</p>
+ <p>The following classes are mainly used by the reflected layer classes:</p>
<table>
<tr>
@@ -214,9 +217,9 @@ parent.link=index.html
<td>
An {@link android.renderscript.Element} is the most basic element of a memory type. An
element represents one cell of a memory allocation. An element can have two forms: Basic or
- Complex. They are typically created from C structures that are used within Renderscript
- code and cannot contain pointers or nested arrays. The other common source of elements is
- bitmap formats.
+ Complex. They are typically created from C structures in your Renderscript
+ code during the reflection process. Elements cannot contain pointers or nested arrays.
+ The other common source of elements is bitmap formats.
<p>A basic element contains a single component of data of any valid Renderscript data type.
Examples of basic element data types include a single float value, a float4 vector, or a
@@ -253,12 +256,11 @@ parent.link=index.html
<td>rs_allocation</td>
<td>
- An {@link android.renderscript.Allocation} provides the memory for applications. An {@link
+ <p>An {@link android.renderscript.Allocation} provides the memory for applications. An {@link
android.renderscript.Allocation} allocates memory based on a description of the memory that
- is represented by a {@link android.renderscript.Type}. The {@link
- android.renderscript.Type} describes an array of {@link android.renderscript.Element}s that
+ is represented by a {@link android.renderscript.Type}. The type describes an array of elements that
represent the memory to be allocated. Allocations are the primary way data moves into and
- out of scripts.
+ out of scripts.</p>
<p>Memory is user-synchronized and it's possible for allocations to exist in multiple
memory spaces concurrently. For example, if you make a call to the graphics card to load a
@@ -270,9 +272,9 @@ parent.link=index.html
<p>Allocation data is uploaded in one of two primary ways: type checked and type unchecked.
For simple arrays there are <code>copyFrom()</code> functions that take an array from the
- Android system code and copy it to the native layer memory store. Both type checked and
+ Android system and copy it to the native layer memory store. Both type checked and
unchecked copies are provided. The unchecked variants allow the Android system to copy over
- arrays of structures because it not support inherently support structures. For example, if
+ arrays of structures because it does not support structures. For example, if
there is an allocation that is an array n floats, you can copy the data contained in a
float[n] array or a byte[n*4] array.</p>
</td>
@@ -331,7 +333,7 @@ parent.link=index.html
state is taken from the bind points as set in the {@link android.renderscript.RenderScriptGL}
bind methods in the control environment (VM environment).</p>
- <p>For example, you can define this at the top of your native Renderscript code:</p>
+ <p>For example, you can define this at the top of your native graphics Renderscript code:</p>
<pre>
#pragma stateVertex(parent)
#pragma stateStore(parent)
@@ -354,9 +356,9 @@ parent.link=index.html
<td>rs_program_vertex</td>
<td>
- The Renderscript vertex program, also known as a vertex shader, describes the stage in the
+ <p>The Renderscript vertex program, also known as a vertex shader, describes the stage in the
graphics pipeline responsible for manipulating geometric data in a user-defined way. The
- object is constructed by providing Renderscript with the following data:
+ object is constructed by providing Renderscript with the following data:</p>
<ul>
<li>An Element describing its varying inputs or attributes</li>
@@ -367,7 +369,9 @@ parent.link=index.html
inputs</li>
</ul>
- <p>Once the program is created, bind it to the graphics context. It is then used for all
+ <p>Once the program is created, bind it to the {@link android.renderscript.RenderScriptGL}
+ graphics context by calling
+ {@link android.renderscript.RenderScriptGL#bindProgramVertex bindProgramVertex()}. It is then used for all
subsequent draw calls until you bind a new program. If the program has constant inputs, the
user needs to bind an allocation containing those inputs. The allocation’s type must match
the one provided during creation. The Renderscript library then does all the necessary
@@ -391,7 +395,7 @@ parent.link=index.html
<td>rs_program_fragment</td>
- <td>The Renderscript fragment program, also known as the fragment shader, is responsible for
+ <td><p>The Renderscript fragment program, also known as the fragment shader, is responsible for
manipulating pixel data in a user-defined way. It’s constructed from a GLSL shader string
containing the program body, textures inputs, and a Type object describing the constants used
by the program. Like the vertex programs, when an allocation with constant input values is
@@ -401,7 +405,7 @@ parent.link=index.html
rsgAllocationSyncAll so it could send the new values to hardware. Communication between the
vertex and fragment programs is handled internally in the GLSL code. For example, if the
fragment program is expecting a varying input called varTex0, the GLSL code inside the
- program vertex must provide it.
+ program vertex must provide it.</p>
<p> To bind shader constructs to the this Program, declare a struct containing the necessary shader constants in your native Renderscript code.
This struct is generated into a reflected class that you can use as a constant input element
during the Program's creation. It is an easy way to create an instance of this struct as an allocation.
@@ -416,7 +420,7 @@ parent.link=index.html
<td>rs_program_store</td>
<td>The Renderscript ProgramStore contains a set of parameters that control how the graphics
- hardware writes to the framebuffer. It could be used to enable/disable depth writes and
+ hardware writes to the framebuffer. It could be used to enable and disable depth writes and
testing, setup various blending modes for effects like transparency and define write masks
for color components.</td>
</tr>
@@ -493,19 +497,19 @@ parent.link=index.html
<ol>
<li>Analyze your application's requirements and figure out what you want to develop with
- Renderscript. To take full advantage of Renderscript, you want to use it when the computation
- or graphics performance you're getting with the normal Android system APIs is
+ Renderscript. To take full advantage of the Renderscript system, you want to use it when the computation
+ or graphics performance you're getting with the traditional framework APIs is
insufficient.</li>
<li>Design the interface of your Renderscript code and implement it using the native
Renderscript APIs that are included in the Android SDK in
- <code>&lt;sdk_root&gt;/platforms/android-3.0/renderscript</code>.</li>
+ <code>&lt;sdk_root&gt;/platforms/android-11/renderscript</code>.</li>
<li>Create an Android project as you would normally, in Eclipse or with the
<code>android</code> tool.</li>
<li>Place your Renderscript files in <code>src</code> folder of the Android project so that the
- build tools can generate the reflective layer classes.</li>
+ build tools can generate the reflected layer classes.</li>
<li>Create your application, calling the Renderscript through the reflected class layer when
you need to.</li>
@@ -513,16 +517,16 @@ parent.link=index.html
<li>Build, install, and run your application as you would normally.</li>
</ol>
- <p>To see how a simple Renderscript application is put together, see <a href="#hello-world">The
- Hello World Renderscript Graphics Application</a>. The SDK also ships with many Renderscript
- samples in the<code>&lt;sdk_root&gt;/samples/android-3.0/</code> directory.</p>
+ <p>To see how a simple Renderscript application is put together, see the
+ <a href="{@docRoot}resources/samples/Renderscript/index.html">Renderscript samples</a>
+ and <a href="#hello-graphics">The Hello Graphics Application</a> section of the documentation.</p>
<h3 id="hello-graphics">The Hello Graphics Application</h3>
<p>This small application demonstrates the structure of a simple Renderscript application. You
can model your Renderscript application after the basic structure of this application. You can
find the complete source in the SDK in the
- <code>&lt;android-sdk&gt;/platforms/android-3.0/samples/HelloWorldRS directory</code>. The
+ <code>&lt;android-sdk&gt;/samples/android-11/HelloWorldRS directory</code>. The
application uses Renderscript to draw the string, "Hello World!" to the screen and redraws the
text whenever the user touches the screen at the location of the touch. This application is only
a demonstration and you should not use the Renderscript system to do something this trivial. The
@@ -544,7 +548,7 @@ parent.link=index.html
screen.</li>
<li>
- <p>The <code>&lt;project_root&gt;/gen</code> directory contains the reflective layer classes
+ <p>The <code>&lt;project_root&gt;/gen</code> directory contains the reflected layer classes
that are generated by the Android build tools. You will notice a
<code>ScriptC_helloworld</code> class, which is the reflective version of the Renderscript
and contains the entry points into the <code>helloworld.rs</code> native code. This file does
@@ -552,8 +556,8 @@ parent.link=index.html
</li>
</ul>
- <p>Each file has its own distinct use. The following section demonstrates in detail how the
- sample works:</p>
+ <p>Each file has its own distinct use. The following files comprise the main parts of the sample and
+ demonstrate in detail how the sample works:</p>
<dl>
<dt><code>helloworld.rs</code></dt>
@@ -628,7 +632,7 @@ int root(int launchID) {
<dd>This class is generated by the Android build tools and is the reflected version of the
<code>helloworld.rs</code> Renderscript. It provides a a high level entry point into the
<code>helloworld.rs</code> native code by defining the corresponding methods that you can call
- from Android system APIs.</dd>
+ from the traditional framework APIs.</dd>
<dt><code>helloworld.bc</code> bytecode</dt>
diff --git a/docs/html/guide/topics/manifest/uses-library-element.jd b/docs/html/guide/topics/manifest/uses-library-element.jd
index f1b5e70ff7ec..1d38c1afee0a 100644
--- a/docs/html/guide/topics/manifest/uses-library-element.jd
+++ b/docs/html/guide/topics/manifest/uses-library-element.jd
@@ -3,34 +3,101 @@ page.title=&lt;uses-library&gt;
<dl class="xml">
<dt>syntax:</dt>
-<dd><pre>&lt;uses-library android:<a href="#nm">name</a>="<i>string</i>" /&gt;</pre></dd>
-
+<dd>
+<pre class="stx">
+&lt;uses-library android:<a href="#nm">name</a>="<var>string</var>"
+ android:<a href="#rq">required</a>=["true" | "false"] /&gt;
+</pre>
+</dd>
<dt>contained in:</dt>
-<dd><code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code></dd>
-
+<dd>
+ <code>
+ <a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a>
+ </code>
+</dd>
<dt>description:</dt>
-<dd>Specifies a shared library that the application must be linked against.
-This element tells the system to include the library's code in the class
-loader for the package.
-
-<p>
-All of the {@code android} packages (such as {@link android.app},
-{@link android.content}, {@link android.view}, and {@link android.widget})
-are in the default library that all applications are automatically linked
-against. However, some packages (such as {@code maps} and {@code awt} are
-in separate libraries that are not automatically linked. Consult the
-documentation for the packages you're using to determine which library
-contains the package code.
-</p></dd>
-
+<dd>
+ Specifies a shared library that the application must be linked against.
+ This element tells the system to include the library's code in the class
+ loader for the package.
+ <p>
+ All of the {@code android} packages (such as {@link android.app},
+ {@link android.content}, {@link android.view}, and {@link android.widget})
+ are in the default library that all applications are automatically linked
+ against. However, some packages (such as {@code maps}) are
+ in separate libraries that are not automatically linked. Consult the
+ documentation for the packages you're using to determine which library
+ contains the package code.
+ </p>
+ <p>
+ This element also affects the installation of the application on a particular device and
+ the availability of the application in Android Market:
+ </p>
+ <dl>
+ <dt><em>Installation</em></dt>
+ <dd>
+ If this element is present and its {@code android:required} attribute is set to
+ {@code true}, the {@link android.content.pm.PackageManager} framework won't let the user
+ install the application unless the library is present on the user's device.
+ </dd>
+ <dt><em>Market</em></dt>
+ <dd>
+ Android Market filters applications based on the libraries installed on the
+ user's device. For more information about filtering, see the topic
+ <a href="{@docRoot}/guide/appendix/market-filters.html">Market Filters</a>.
+ </dd>
+ </dl>
+ <p>
+ The {@code android:required} attribute is described in detail in the following section.
+ </p>
+</dd>
<dt>attributes:</dt>
-<dd><dl class="attr">
-<dt><a name="nm"></a>{@code android:name}</dt>
-<dd>The name of the library.</dd>
-</dl></dd>
-
+<dd>
+ <dl class="attr">
+ <dt><a name="nm"></a>{@code android:name}</dt>
+ <dd>
+ The name of the library. The name is provided by the
+ documentation for the package you are using. An example of this is
+ &quot;<code>android.test.runner</code>&quot;, a package that contains Android test
+ classes.
+ </dd>
+ <dt><a name="rq"></a>{@code android:required}</dt>
+ <dd>
+ Boolean value that indicates whether the application requires the
+ library specified by {@code android:name}:
+ <ul>
+ <li>
+ <code>&quot;true&quot;</code>: The application does not function without this
+ library. The system will not allow the application on a device that does not
+ have the library.
+ </li>
+ <li>
+ <code>&quot;false&quot;</code>: The application can use the
+ library if present, but is designed to function without it if necessary.
+ The system will allow the application to be installed, even if the library is
+ not present. If you use <code>&quot;false&quot;</code>, you are responsible for
+ checking at runtime that the library is available.
+ <p>
+ To check for a library, you can use reflection to determine
+ if a particular class is available.
+ </p>
+ </li>
+ </ul>
+ <p>
+ The default is <code>&quot;true&quot;</code>.
+ </p>
+ <p>Introduced in: API Level 7.</p>
+ </dd>
+ </dl>
+</dd>
<!-- ##api level indication## -->
<dt>introduced in:</dt>
<dd>API Level 1</dd>
-</dl>
+<dt>see also:</dt>
+<dd>
+ <ul>
+ <li>{@link android.content.pm.PackageManager}</li>
+ </ul>
+</dd>
+</dl> \ No newline at end of file
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 5839064b32a6..b80e59a556b0 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -496,6 +496,16 @@ var ANDROID_RESOURCES = [
}
},
{
+ tags: ['sample', 'new'],
+ path: 'samples/Renderscript/index.html',
+ title: {
+ en: 'Renderscript'
+ },
+ description: {
+ en: 'A set of samples that demonstrate how to use various features of the Renderscript APIs.'
+ }
+ },
+ {
tags: ['sample', 'accountsync'],
path: 'samples/SampleSyncAdapter/index.html',
title: {
diff --git a/docs/html/sdk/android-3.0-optimize.jd b/docs/html/sdk/android-3.0-optimize.jd
new file mode 100644
index 000000000000..a22e69af2076
--- /dev/null
+++ b/docs/html/sdk/android-3.0-optimize.jd
@@ -0,0 +1,397 @@
+page.title=Optimizing Apps for Android 3.0
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>In this document</h2>
+<ol>
+<li><a href="#Setup">Set Up Your SDK with Android 3.0</a></li>
+<li><a href="#SearchableConfiguration">Optimize Your App for Tablets and Similar Devices</a></li>
+<li><a href="#SearchableActivity">Upgrade or Develop a New App for Tablets and Similar
+Devices</a></li>
+</ol>
+
+</div>
+</div>
+
+<p>If you're developing an Android application, Android 3.0 introduces several features that allow
+you to enhance your user's experience on tablets and similar devices. Any application you've already
+published is compatible with devices running Android 3.0, by default, because Android applications
+are forward-compatible. However, there are some simple changes you should make to optimize your
+application for tablet-type devices.</p>
+
+<p>This document shows how you can optimize your existing application for Android 3.0 and
+maintain compatibility with older versions or upgrade your application completely with new APIs.</p>
+
+
+<p><b>To get started:</b></p>
+
+<ol>
+ <li><a href="#Setup">Set up your SDK with Android 3.0</a>.</li>
+ <li>Then choose to either optimize or upgrade:
+ <ol type="a">
+ <li><a href="#Optimize">Optimize Your App for Tablets and Similar Devices</a>.
+ <p>When you have an existing application and want to maintain compatibility with
+older versions of Android.</p>
+ </li>
+ <li><a href="#Upgrade">Upgrade or Develop a New App for Tablets and Similar Devices</a>.
+ <p>When you want to upgrade your application to use APIs introduced in Android 3.0 or
+ create a new application targeted to tablets and similar devices.</p></li>
+ </ol>
+ </li>
+</ol>
+
+
+<h2 id="Setup">Set Up Your SDK with Android 3.0</h2>
+
+<p>To start testing and developing your application on Android 3.0, set up your existing Android
+SDK with the new platform:</p>
+
+<p>(If you don't have an existing Android SDK, <a href="{@docRoot}sdk/index.html">download the
+SDK starter package now</a>.)</p>
+
+<ol>
+ <li><a href="{@docRoot}sdk/adding-components.html#launching">Launch the Android SDK and AVD
+Manager</a> and install the following:
+ <ul>
+ <li>SDK Platform Android 3.0</li>
+ <li>Android SDK Tools, revision 10</li>
+ <li>Android SDK Platform-tools, revision 3</li>
+ <li>Documentation for Android SDK, API 11</li>
+ <li>Samples for SDK API 11</li>
+ </ul>
+ </li>
+ <li><a href="{@docRoot}guide/developing/other-ide.html#AVD">Create an AVD</a> for a tablet-type
+device:
+ <p>Set the target to "Android 3.0" and the skin to "WXGA" (the default skin).</p></li>
+</ol>
+
+
+<h3>About emulator performance</h3>
+
+<p>Because the Android emulator must simulate the ARM instruction set on your computer
+and the WXGA screen is significantly larger than a typical virtual device, emulator performance is
+much slower than a real device.</p>
+
+<p>In particular, initializing the emulator can be slow and can take several minutes, depending on
+your hardware. When the emulator is booting, there is limited user feedback, so please be patient
+and wait until you see the home screen (or lock screen) appear. </p>
+
+<p>However, you don't need to boot the emulator each time you rebuild your
+application&mdash;typically you only need to boot at the start of a session and keep it running.
+Also see the tip below for information about using a snapshot to drastically reduce startup time
+after the first initialization. </p>
+
+<p>We're working hard to resolve the performance issues and it will improve in future tools
+releases. For the time being, the emulator is still best way to evaluate your application's
+appearance and functionality on Android 3.0 without a real device.</p>
+
+<p class="note"><strong>Tip:</strong> To improve the startup time for the emulator, enable snapshots
+for the AVD when you create it with the SDK and AVD Manager (there's a checkbox in the AVD creator
+to <strong>Enable</strong> snapshots). Then, start the AVD from the AVD manager and check <b>Launch
+from snapshot</b> and <b>Save to snapshot</b>. This way, when you close the emulator, a snapshot of
+the AVD state is saved and used to quickly relaunch the AVD next time. However, when you choose to
+save a snapshot, the emulator will be slow to close, so you might want to disable <b>Save to
+snapshot</b> after you've acquired an initial snapshot (after you close the AVD for the first
+time).</p>
+
+
+
+<h2 id="Optimize">Optimize Your Application for Tablets and Similar Devices</h2>
+
+<p>If you've already developed an application for an earlier version of Android, there are a few
+things you can do to optimize it for a tablet-style experience on Android 3.0 without changing the
+minimum version required (you don't need to change your manifest's <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+android:minSdkVersion}</a>).</p>
+
+<p class="note"><strong>Note:</strong> All Android applications are forward-compatible, so
+there's nothing you <em>have to</em> do&mdash;if your application is a good citizen of the Android
+APIs, your app should work fine on devices running Android 3.0. However, in order to provide users
+a better experience when using your app on an Android 3.0 tablet or similar-size device, you
+should update your application to inherit the new system theme and provide some optimizations for
+larger screens.</p>
+
+<p>Here are a few things you can do to optimize your application for devices running Android
+3.0:</p>
+
+<ol>
+ <li><b>Test your current application on Android 3.0</b>
+ <ol>
+ <li>Build your application as-is and install it on your Android 3.0 AVD (created above during
+<a href="#Setup">setup</a>).</li>
+ <li>Perform your usual tests to be sure everything works and looks as expected.</li>
+ </ol>
+ </li>
+
+ <li><b>Apply the new "holographic" theme to your application</b>
+ <ol>
+ <li>Open your manifest file and update the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code &lt;uses-sdk&gt;}</a> element to
+set <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+android:targetSdkVersion}</a> to {@code "11"}. For example:
+<pre>
+&lt;manifest ... >
+ &lt;uses-sdk android:minSdkVersion="4"
+ android:targetSdkVersion="11" /&gt;
+ &lt;application ... >
+ ...
+ &lt;application>
+&lt;/manifest>
+</pre>
+ <p>By targeting the Android 3.0 platform, the system automatically applies the holographic theme
+to each activity when your application runs on an Android 3.0 device. The holographic theme
+provides a new design for widgets, such as buttons and text boxes, and restyles other
+visual elements. This is the standard theme in applications built for Android 3.0, so your
+application will look more at home by enabling the theme.</p>
+ <p>Additionally, the holographic theme enables the <a
+href="{@docRoot}guide/topics/ui/actionbar.html">Action Bar</a> in your activities when running on an
+Android 3.0 device. The Action Bar replaces the traditional title bar at the top of the activity
+window and provides the user access to the activity's Options Menu.</p>
+ </li>
+ <li>Continue to build your application against the minimum version specified by <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code android:minSdkVersion}</a>,
+but install it on the Android 3.0 AVD. Repeat your tests to be sure that your user interface works
+well with the holographic theme.
+ <p class="note"><strong>Note:</strong> If you have applied other themes directly to your
+activities, they will override the inherited holographic theme. To resolve this, you can use
+the <a href="{@docRoot}guide/topics/resources/providing-resources.html#VersionQualifier">system
+version qualifier</a> to provide an alternative theme for Android 3.0 devices that's based on the
+holographic theme. For more information, read how to <a
+href="{@docRoot}guide/topics/ui/themes.html#SelectATheme">select a theme based on platform
+version</a>.</p>
+ </ol>
+ </li>
+
+ <li><b>Supply alternative layout resources for xlarge screens</b>
+ <p>By providing <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">alternative
+resources</a> when running on extra large screens (using the <code>xlarge</code> resource
+qualifier), you can improve the user experience of your application on tablet-type devices without
+using new APIs.</p>
+ <p>For example, here are some things to consider when creating a new layout for extra large
+screens:</p>
+ <ul>
+ <li>Landscape layout: The "normal" orientation for tablet-type devices is usually landscape
+(wide), so you should be sure that your activities offer a layout that's optimized for a wide
+viewing area. <p>You can specify landscape resources with the <code>land</code> resource
+qualifier, but if you want alternative resources for an extra large landscape screen, you
+should use both <code>xlarge</code> and <code>land</code> qualifiers. For example, {@code
+res/layout-xlarge-land/}. The order of the qualifier names is important; see <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">
+Providing Alternative Resources</a> for more information.</p></li>
+ <li>Button position: Consider whether the position of the most common buttons in your UI are
+easily accessible while holding a tablet with two hands.</li>
+ <li>Font sizes: Be sure your application uses {@code sp} units when setting font
+sizes. This alone should ensure a readable experience on tablet-style devices. In some cases,
+however, you might want to consider larger font sizes for <code>xlarge</code> configurations.</li>
+ </ul>
+ <p>In general, always be sure that your application follows the <a
+href="{@docRoot}guide/practices/screens_support.html#screen-independence">Best Practices
+for Screen Independence</a>.</p>
+ </li>
+</ol>
+
+
+
+
+
+<h2 id="Upgrade">Upgrade or Develop a New App for Tablets and Similar Devices</h2>
+
+<p>If you want to develop an application that's fully enhanced for tablet-type devices running
+Android 3.0, then you need to use new APIs in Android 3.0. This section introduces some of
+the new features you should use.</p>
+
+
+<h3>Declare the minimum system version</h3>
+
+<p>The first thing to do when you create a project for Android 3.0 is set your manifest's <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code android:minSdkVersion}</a>
+to {@code "11"}. For example:</p>
+
+<pre>
+&lt;manifest ... >
+ &lt;uses-sdk android:minSdkVersion="11" /&gt;
+ &lt;application ... >
+ ...
+ &lt;application>
+&lt;/manifest>
+</pre>
+
+<p>By targeting the Android 3.0 platform, the system automatically applies the new holographic theme
+to each of your activities.</p>
+
+<p>Additionally, the holographic theme enables the Action Bar for each activity.</p>
+
+
+<h3>Use the Action Bar</h3>
+
+<p>The Action Bar is a widget for activities that replaces the traditional title bar at the top of
+the screen. By default, the Action Bar includes the application logo on the left side, followed by
+the activity title, and any available items from the Options Menu on the right side.</p>
+
+<p>You can enable items from your activity's Options Menu to appear directly in the Action Bar as
+"action items" by adding {@code showAsAction="ifRoom"} to specific items in your <a
+href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>. You can also add
+navigation features to the Action Bar, such as tabs, and use the application icon to navigate to
+your application's "home" activity or "up" the activity hierarchy.</p>
+
+<p>For more information, read <a href="{@docRoot}guide/topics/ui/actionbar.html">Using the
+Action Bar</a>.</p>
+
+
+
+<h3>Divide your activities into fragments</h3>
+
+<p>A fragment represents a behavior or a portion of user interface in an activity. You can combine
+multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple
+activities. You can think of a fragment as a modular section of an activity, which has its own
+lifecycle, receives its own input events, and which you can add or remove while the activity is
+running.</p>
+
+<p>For example, a news application can use one fragment to show a list of articles on the left and
+another fragment to display an article on the right&mdash;both fragments appear in one activity,
+side by side, and each fragment has its own set of lifecycle callback methods and handles its own
+input events. Thus, instead of using one activity to select an article and another activity to
+read the article, the user can select an article and read it all within the same activity.</p>
+
+<p>For more information, read the <a
+href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> document.</p>
+
+
+<h3>Use new animation APIs for transitions</h3>
+
+<p>An all new flexible animation framework allows you to animate arbitrary properties of any object
+(View, Drawable, Fragment, Object, or anything else). You can define several animation aspects
+(such as duration, repeat, interpolation, and more) for an object's int, float, and hexadecimal
+color values, by default. That is, when an object has a property field for one of these types, you
+can change its value over time to affect an animation.</p>
+
+<p>The {@link android.view.View} class also provides new APIs that leverage the new animation
+framework, allowing you to easily apply 2D and 3D transformations to views in your activity layout.
+New transformations are made possible with a set of object properties that define the view's layout
+position, orientation, transparency and more.</p>
+
+<p>For more information, read the <a
+href="{@docRoot}guide/topics/graphics/animation.html">Property Animation</a> document.</p>
+
+
+<h3>Enable hardware acceleration</h3>
+
+<p>You can now enable the OpenGL renderer for your application by setting {@code
+android:hardwareAccelerated="true"} in your manifest's <a
+href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
+element or for individual <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a> elements. Hardware acceleration results in smoother animations, smoother
+scrolling, and overall better performance and response to user interaction. When enabled, be sure
+that you thoroughly test your application on a device that supports hardware acceleration.</p>
+
+
+<h3>Enhance your app widgets</h3>
+
+<p>App widgets allow users to access information from your application directly from the Home
+screen and interact with ongoing services (such as preview their email and control music playback).
+Android 3.0 enhances these capabilities by enabling collections, created with widgets such as
+{@link android.widget.ListView}, {@link android.widget.GridView}, and the new {@link
+android.widget.StackView}. These widgets allow you to create more interactive app
+widgets, such as one with a scrolling list, and can automatically update their data through a {@link
+android.widget.RemoteViewsService}.</p>
+
+<p>Additionally, you should create a preview image of your app widget using the Widget Preview
+application (pre-installed in an Android 3.0 AVD) and reference it with the {@link
+android.appwidget.AppWidgetProviderInfo#previewImage android:previewImage} attribute, so that users
+can see what the app widget looks like before adding it to their Home screen.</p>
+
+
+<h3>Add other new features</h3>
+
+<p>Android 3.0 introduces many more APIs that you might find valuable for your
+application, such as drag and drop APIs, new Bluetooth APIs, a system-wide clipboard framework, a
+new graphics engine called Renderscript, and more.</p>
+
+<p>To learn more about the APIs mentioned above and more, see the <a
+href="{@docRoot}sdk/android-3.0.html">Android 3.0 Platform</a> document.</p>
+
+
+<h3>Publish your app for extra large screens</h3>
+
+<p>You should also decide whether your application is <em>only</em> for
+tablet-type devices (specifically, <em>xlarge</em> devices) or for all types of screen sizes.</p>
+
+<p>If you want your application to be available to all screen sizes (for example, for all
+phones and tablets), there's nothing you need to do. By default, an application with <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+android:minSdkVersion}</a> set to {@code "4"} or higher will resize to fit any screen size.</p>
+
+<p>If your application is <em>only</em> for <em>xlarge</em> screens, include the <a
+href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
+&lt;supports-screens&gt;}</a> element in your manifest and declare that the application supports
+only <em>xlarge</em> screens, by declaring all other sizes {@code "false"}. For example:</p>
+
+<pre>
+&lt;manifest ... >
+ ...
+ &lt;supports-screens android:smallScreens="false"
+ android:normalScreens="false"
+ android:largeScreens="false"
+ android:xlargeScreens="true" /&gt;
+ &lt;application ... >
+ ...
+ &lt;application>
+&lt;/manifest>
+</pre>
+
+<p>With this declaration, you indicate that your application does not support any screen size except
+extra large. External services such as Android Market may then use this information to filter your
+application from devices that do not have an extra large screen.</p>
+
+
+
+<h3>Look at some samples</h3>
+
+<p>Many of the new features and APIs that are described in the <a
+href="{@docRoot}sdk/android-3.0.html#api">Android 3.0 Platform Preview</a> also have accompanying
+samples that can help you understand how to use them. To get the samples, download them from the SDK
+repository using the Android SDK Manager. After downloading the samples ("Samples for SDK API 11"),
+you can find them in <code>&lt;sdk_root&gt;/samples/android-11/</code>. The links below can help you
+find samples for the features you are interested in:</p>
+
+<ul>
+ <li><a href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a>:
+Demonstrates many new APIs in Android 3.0, including fragments, the action bar, drag and drop, and
+animations.</li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#Fragment">
+Fragments</a>: Various samples that demonstrate fragment layouts, back stack, restoring state, and
+more.</li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ActionBarMechanics.html"
+>Action Bar</a>: Samples that demonstrate various Action Bar features, such as tabs, logos, and
+action items.</li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/content/ClipboardSample.
+html">Clipboard</a>: An example of how to use the clipboard for copy and paste operations.</li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/DragAndDropDemo.html">
+Drag and Drop</a>: An example of how to perform drag and drop with new View events.</li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List15.html">
+Multi-choice List</a>: An example of how to provide multiple-choice selection for ListView and
+GridView.</li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html">
+Content Loaders</a>: An example using new Loader APIs to asynchronously load data.</li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">
+Property Animation</a>: Several samples using the new animation APIs to animate object
+properties.</li>
+ <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.
+html">Search View Widget</a>: Example using the new search widget in the Action Bar (as an
+"action view").</li>
+ <li><a
+href="{@docRoot}resources/samples/Renderscript/index.html">Renderscript</a>: Contains several
+different applications that demonstrate using renderscript APIs for computations and 3D
+graphics.</li>
+</ul>
+
diff --git a/docs/html/sdk/android-3.0.jd b/docs/html/sdk/android-3.0.jd
index 8088e32e3227..6c88146d7c84 100644
--- a/docs/html/sdk/android-3.0.jd
+++ b/docs/html/sdk/android-3.0.jd
@@ -25,7 +25,7 @@ Differences Report &raquo;</a> </li>
<h2>See Also</h2>
<ol>
- <li><a href="{@docRoot}sdk/preview/start.html">Getting Started</a></li>
+ <li><a href="{@docRoot}sdk/android-3.0-optimize.html">Optimizing Apps for Android 3.0</a></li>
</ol>
</div>
@@ -48,6 +48,10 @@ href="{@docRoot}sdk/index.html">download the SDK Starter Package</a> first.</p>
href="{@docRoot}sdk/android-{@sdkPlatformVersion}-highlights.html">Platform
Highlights</a>.</p>
+<p>Also see the <a href="{@docRoot}sdk/android-3.0-optimize.html">Optimizing Apps for Android
+3.0</a> document for information about how to optimize your existing applications for Android 3.0
+devices, even if you want to remain compatible with previous versions.</p>
+
<h2 id="relnotes">Revisions</h2>
diff --git a/docs/html/sdk/api_diff/11/changes.html b/docs/html/sdk/api_diff/11/changes.html
index 5166a8f29bb8..508ed163fa3a 100644
--- a/docs/html/sdk/api_diff/11/changes.html
+++ b/docs/html/sdk/api_diff/11/changes.html
@@ -4,7 +4,7 @@
<meta name="generator" content="JDiff v1.1.0">
<!-- Generated by the JDiff Javadoc doclet -->
<!-- (http://www.jdiff.org) -->
-<!-- on Tue Feb 08 11:41:20 PST 2011 -->
+<!-- on Sat Feb 19 17:19:55 PST 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>
diff --git a/docs/html/sdk/api_diff/11/changes/alldiffs_index_additions.html b/docs/html/sdk/api_diff/11/changes/alldiffs_index_additions.html
index 1be3b833613f..454d0d807151 100644
--- a/docs/html/sdk/api_diff/11/changes/alldiffs_index_additions.html
+++ b/docs/html/sdk/api_diff/11/changes/alldiffs_index_additions.html
@@ -1117,9 +1117,6 @@ Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style=
<!-- Method getFragmentManager -->
<nobr><A HREF="android.app.Activity.html#android.app.Activity.getFragmentManager_added()" class="hiddenlink" target="rightframe"><b>getFragmentManager</b>
()</A></nobr><br>
-<!-- Method getGlobalProxyAdmin -->
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.getGlobalProxyAdmin_added()" class="hiddenlink" target="rightframe"><b>getGlobalProxyAdmin</b>
-()</A></nobr><br>
<!-- Method getIcon -->
<nobr><A HREF="android.preference.Preference.html#android.preference.Preference.getIcon_added()" class="hiddenlink" target="rightframe"><b>getIcon</b>
()</A></nobr><br>
@@ -3058,9 +3055,6 @@ Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style=
&nbsp;&nbsp;<nobr><A HREF="android.widget.Scroller.html#android.widget.Scroller.setFriction_added(float)" class="hiddenlink" target="rightframe">type&nbsp;<b>
(<code>float</code>)</b>&nbsp;in&nbsp;android.widget.Scroller
</A></nobr><br>
-<!-- Method setGlobalProxy -->
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.setGlobalProxy_added(android.content.ComponentName, java.net.Proxy, java.util.List<java.lang.String>)" class="hiddenlink" target="rightframe"><b>setGlobalProxy</b>
-(<code>ComponentName, Proxy, List&lt;String&gt;</code>)</A></nobr><br>
<!-- Method setGravity -->
<nobr><A HREF="android.widget.Spinner.html#android.widget.Spinner.setGravity_added(int)" class="hiddenlink" target="rightframe"><b>setGravity</b>
(<code>int</code>)</A></nobr><br>
@@ -3810,9 +3804,6 @@ Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style=
<!-- Field USES_POLICY_EXPIRE_PASSWORD -->
<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD" class="hiddenlink" target="rightframe">USES_POLICY_EXPIRE_PASSWORD</A>
</nobr><br>
-<!-- Field USES_POLICY_SETS_GLOBAL_PROXY -->
-<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY" class="hiddenlink" target="rightframe">USES_POLICY_SETS_GLOBAL_PROXY</A>
-</nobr><br>
<!-- Field valueFrom -->
<A NAME="V"></A>
<br><font size="+2">V</font>&nbsp;
diff --git a/docs/html/sdk/api_diff/11/changes/alldiffs_index_all.html b/docs/html/sdk/api_diff/11/changes/alldiffs_index_all.html
index d62c2dcdcf7a..c36382a25973 100644
--- a/docs/html/sdk/api_diff/11/changes/alldiffs_index_all.html
+++ b/docs/html/sdk/api_diff/11/changes/alldiffs_index_all.html
@@ -1520,9 +1520,6 @@ Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style=
<!-- Method getGlobalExternalFreedSize -->
<nobr><A HREF="android.os.Debug.html#android.os.Debug.getGlobalExternalFreedSize_changed()" class="hiddenlink" target="rightframe">getGlobalExternalFreedSize
()</A></nobr><br>
-<!-- Method getGlobalProxyAdmin -->
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.getGlobalProxyAdmin_added()" class="hiddenlink" target="rightframe"><b>getGlobalProxyAdmin</b>
-()</A></nobr><br>
<!-- Method getHost -->
<nobr><A HREF="android.net.Proxy.html#android.net.Proxy.getHost_changed(android.content.Context)" class="hiddenlink" target="rightframe">getHost
(<code>Context</code>)</A></nobr><br>
@@ -3923,9 +3920,6 @@ Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style=
<!-- Method setGlobalAllocationLimit -->
<nobr><A HREF="android.os.Debug.html#android.os.Debug.setGlobalAllocationLimit_changed(int)" class="hiddenlink" target="rightframe">setGlobalAllocationLimit
(<code>int</code>)</A></nobr><br>
-<!-- Method setGlobalProxy -->
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.setGlobalProxy_added(android.content.ComponentName, java.net.Proxy, java.util.List<java.lang.String>)" class="hiddenlink" target="rightframe"><b>setGlobalProxy</b>
-(<code>ComponentName, Proxy, List&lt;String&gt;</code>)</A></nobr><br>
<!-- Method setGravity -->
<nobr><A HREF="android.widget.Spinner.html#android.widget.Spinner.setGravity_added(int)" class="hiddenlink" target="rightframe"><b>setGravity</b>
(<code>int</code>)</A></nobr><br>
@@ -4826,9 +4820,6 @@ Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style=
<!-- Field USES_POLICY_EXPIRE_PASSWORD -->
<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD" class="hiddenlink" target="rightframe">USES_POLICY_EXPIRE_PASSWORD</A>
</nobr><br>
-<!-- Field USES_POLICY_SETS_GLOBAL_PROXY -->
-<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY" class="hiddenlink" target="rightframe">USES_POLICY_SETS_GLOBAL_PROXY</A>
-</nobr><br>
<!-- Field valueFrom -->
<A NAME="V"></A>
<br><font size="+2">V</font>&nbsp;
diff --git a/docs/html/sdk/api_diff/11/changes/android.Manifest.permission.html b/docs/html/sdk/api_diff/11/changes/android.Manifest.permission.html
index 0de6f00feb5d..79aaf1043bc6 100644
--- a/docs/html/sdk/api_diff/11/changes/android.Manifest.permission.html
+++ b/docs/html/sdk/api_diff/11/changes/android.Manifest.permission.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.R.attr.html b/docs/html/sdk/api_diff/11/changes/android.R.attr.html
index 3d896e1bc52e..b6cac99ecf0f 100644
--- a/docs/html/sdk/api_diff/11/changes/android.R.attr.html
+++ b/docs/html/sdk/api_diff/11/changes/android.R.attr.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.R.dimen.html b/docs/html/sdk/api_diff/11/changes/android.R.dimen.html
index ba8688fb229e..205f3fc22626 100644
--- a/docs/html/sdk/api_diff/11/changes/android.R.dimen.html
+++ b/docs/html/sdk/api_diff/11/changes/android.R.dimen.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.R.drawable.html b/docs/html/sdk/api_diff/11/changes/android.R.drawable.html
index ddce2d313a34..8172aed147de 100644
--- a/docs/html/sdk/api_diff/11/changes/android.R.drawable.html
+++ b/docs/html/sdk/api_diff/11/changes/android.R.drawable.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.R.id.html b/docs/html/sdk/api_diff/11/changes/android.R.id.html
index 1ac126d2a7ae..163425d74747 100644
--- a/docs/html/sdk/api_diff/11/changes/android.R.id.html
+++ b/docs/html/sdk/api_diff/11/changes/android.R.id.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.R.layout.html b/docs/html/sdk/api_diff/11/changes/android.R.layout.html
index 85ae20e063fb..a596cfd84275 100644
--- a/docs/html/sdk/api_diff/11/changes/android.R.layout.html
+++ b/docs/html/sdk/api_diff/11/changes/android.R.layout.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.R.string.html b/docs/html/sdk/api_diff/11/changes/android.R.string.html
index c28dc593b8a2..0e0f1057fdb4 100644
--- a/docs/html/sdk/api_diff/11/changes/android.R.string.html
+++ b/docs/html/sdk/api_diff/11/changes/android.R.string.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.R.style.html b/docs/html/sdk/api_diff/11/changes/android.R.style.html
index 832221eed583..74ff759a071b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.R.style.html
+++ b/docs/html/sdk/api_diff/11/changes/android.R.style.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.accounts.AccountManager.html b/docs/html/sdk/api_diff/11/changes/android.accounts.AccountManager.html
index 5d39a5810e47..f3c662621fce 100644
--- a/docs/html/sdk/api_diff/11/changes/android.accounts.AccountManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.accounts.AccountManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.accounts.AuthenticatorDescription.html b/docs/html/sdk/api_diff/11/changes/android.accounts.AuthenticatorDescription.html
index 354ded01f922..58c532a59723 100644
--- a/docs/html/sdk/api_diff/11/changes/android.accounts.AuthenticatorDescription.html
+++ b/docs/html/sdk/api_diff/11/changes/android.accounts.AuthenticatorDescription.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.Activity.html b/docs/html/sdk/api_diff/11/changes/android.app.Activity.html
index 24ee0f84a613..96d728a5ecb2 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.Activity.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.Activity.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.RecentTaskInfo.html b/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.RecentTaskInfo.html
index c14fb270a511..282362992521 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.RecentTaskInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.RecentTaskInfo.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.html b/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.html
index 416348085991..6c46ba7b3924 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.ActivityManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.Builder.html b/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.Builder.html
index 2bbac02a7614..532eb6b34f6e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.Builder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.Builder.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.html b/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.html
index 0382b73f25e6..cb5c2f26dca4 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.AlertDialog.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.DatePickerDialog.html b/docs/html/sdk/api_diff/11/changes/android.app.DatePickerDialog.html
index e5cb692afd80..d6b69c0e8ea7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.DatePickerDialog.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.DatePickerDialog.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.Dialog.html b/docs/html/sdk/api_diff/11/changes/android.app.Dialog.html
index a514fcb30d58..fe83a770c8bc 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.Dialog.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.Dialog.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.Request.html b/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.Request.html
index 24049ec2d997..f85ec189c26c 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.Request.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.Request.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.html b/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.html
index f6de68cac880..3c138ad713e6 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.DownloadManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.Notification.html b/docs/html/sdk/api_diff/11/changes/android.app.Notification.html
index 1d0948fce4e6..19086f5207d0 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.Notification.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.Notification.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.PendingIntent.html b/docs/html/sdk/api_diff/11/changes/android.app.PendingIntent.html
index a66438b67e25..fed6b615724a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.PendingIntent.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.PendingIntent.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.ProgressDialog.html b/docs/html/sdk/api_diff/11/changes/android.app.ProgressDialog.html
index bf32ac5d581c..7437921153ea 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.ProgressDialog.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.ProgressDialog.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.SearchManager.html b/docs/html/sdk/api_diff/11/changes/android.app.SearchManager.html
index 9be408e01b24..4621bf0a9895 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.SearchManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.SearchManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.Service.html b/docs/html/sdk/api_diff/11/changes/android.app.Service.html
index bc2ce973435f..0bf322d8f2f0 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.Service.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.Service.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.WallpaperManager.html b/docs/html/sdk/api_diff/11/changes/android.app.WallpaperManager.html
index 308a0552a6a2..42c6f8b7064b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.WallpaperManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.WallpaperManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminInfo.html b/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminInfo.html
index 8801ac5e6d3a..1bb82b33e86d 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminInfo.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
@@ -96,13 +96,6 @@ Class android.app.admin.<A HREF="../../../../reference/android/app/admin/DeviceA
</TD>
<TD>&nbsp;</TD>
</TR>
-<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
- <TD VALIGN="TOP" WIDTH="25%">
- <A NAME="android.app.admin.DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY"></A>
- <nobr><code>int</code>&nbsp;<A HREF="../../../../reference/android/app/admin/DeviceAdminInfo.html#USES_POLICY_SETS_GLOBAL_PROXY" target="_top"><code>USES_POLICY_SETS_GLOBAL_PROXY</code></A></nobr>
- </TD>
- <TD>&nbsp;</TD>
-</TR>
</TABLE>
&nbsp;
</div>
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminReceiver.html b/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminReceiver.html
index aebcd6f6f75c..28691bc52640 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminReceiver.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.admin.DeviceAdminReceiver.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.app.admin.DevicePolicyManager.html b/docs/html/sdk/api_diff/11/changes/android.app.admin.DevicePolicyManager.html
index b54a22d906f0..9527bda1c52d 100644
--- a/docs/html/sdk/api_diff/11/changes/android.app.admin.DevicePolicyManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.app.admin.DevicePolicyManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
@@ -83,13 +83,6 @@ Class android.app.admin.<A HREF="../../../../reference/android/app/admin/DeviceP
</TH>
<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
<TD VALIGN="TOP" WIDTH="25%">
- <A NAME="android.app.admin.DevicePolicyManager.getGlobalProxyAdmin_added()"></A>
- <nobr><code>ComponentName</code>&nbsp;<A HREF="../../../../reference/android/app/admin/DevicePolicyManager.html#getGlobalProxyAdmin()" target="_top"><code>getGlobalProxyAdmin</code></A>()</nobr>
- </TD>
- <TD>&nbsp;</TD>
-</TR>
-<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
- <TD VALIGN="TOP" WIDTH="25%">
<A NAME="android.app.admin.DevicePolicyManager.getPasswordExpiration_added(android.content.ComponentName)"></A>
<nobr><code>long</code>&nbsp;<A HREF="../../../../reference/android/app/admin/DevicePolicyManager.html#getPasswordExpiration(android.content.ComponentName)" target="_top"><code>getPasswordExpiration</code></A>(<code>ComponentName</code>)</nobr>
</TD>
@@ -174,13 +167,6 @@ Class android.app.admin.<A HREF="../../../../reference/android/app/admin/DeviceP
</TR>
<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
<TD VALIGN="TOP" WIDTH="25%">
- <A NAME="android.app.admin.DevicePolicyManager.setGlobalProxy_added(android.content.ComponentName, java.net.Proxy, java.util.List<java.lang.String>)"></A>
- <nobr><code>ComponentName</code>&nbsp;<A HREF="../../../../reference/android/app/admin/DevicePolicyManager.html#setGlobalProxy(android.content.ComponentName, java.net.Proxy, java.util.List<java.lang.String>)" target="_top"><code>setGlobalProxy</code></A>(<code>ComponentName,</nobr> Proxy<nobr>,</nobr> List&lt;String&gt;<nobr><nobr></code>)</nobr>
- </TD>
- <TD>&nbsp;</TD>
-</TR>
-<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
- <TD VALIGN="TOP" WIDTH="25%">
<A NAME="android.app.admin.DevicePolicyManager.setPasswordExpirationTimeout_added(android.content.ComponentName, long)"></A>
<nobr><code>void</code>&nbsp;<A HREF="../../../../reference/android/app/admin/DevicePolicyManager.html#setPasswordExpirationTimeout(android.content.ComponentName, long)" target="_top"><code>setPasswordExpirationTimeout</code></A>(<code>ComponentName,</nobr> long<nobr><nobr></code>)</nobr>
</TD>
diff --git a/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetHost.html b/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetHost.html
index 4f1a5b8655f7..ec97611875a8 100644
--- a/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetHost.html
+++ b/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetHost.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetManager.html b/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetManager.html
index 88afafeb7ee7..81585ba00b27 100644
--- a/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetProviderInfo.html b/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetProviderInfo.html
index 36a3ce3f32d0..dbcbce258005 100644
--- a/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetProviderInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.appwidget.AppWidgetProviderInfo.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.bluetooth.BluetoothAdapter.html b/docs/html/sdk/api_diff/11/changes/android.bluetooth.BluetoothAdapter.html
index 3ca03e3cb44d..e71af0f90ca6 100644
--- a/docs/html/sdk/api_diff/11/changes/android.bluetooth.BluetoothAdapter.html
+++ b/docs/html/sdk/api_diff/11/changes/android.bluetooth.BluetoothAdapter.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.AbstractThreadedSyncAdapter.html b/docs/html/sdk/api_diff/11/changes/android.content.AbstractThreadedSyncAdapter.html
index 37e96ab6dbb8..0c3d6157cbef 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.AbstractThreadedSyncAdapter.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.AbstractThreadedSyncAdapter.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.BroadcastReceiver.html b/docs/html/sdk/api_diff/11/changes/android.content.BroadcastReceiver.html
index eefe15da1524..526c9231981a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.BroadcastReceiver.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.BroadcastReceiver.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.ContentProvider.html b/docs/html/sdk/api_diff/11/changes/android.content.ContentProvider.html
index 1c6064184a5d..a1c2be1b0fa5 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.ContentProvider.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.ContentProvider.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.ContentProviderClient.html b/docs/html/sdk/api_diff/11/changes/android.content.ContentProviderClient.html
index 24de46c5252c..569e158145f2 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.ContentProviderClient.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.ContentProviderClient.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.ContentResolver.html b/docs/html/sdk/api_diff/11/changes/android.content.ContentResolver.html
index 0cbeea015a48..33c85fc603aa 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.ContentResolver.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.ContentResolver.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.ContentValues.html b/docs/html/sdk/api_diff/11/changes/android.content.ContentValues.html
index 98b3e0fb7860..c5348d30c215 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.ContentValues.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.ContentValues.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.Context.html b/docs/html/sdk/api_diff/11/changes/android.content.Context.html
index 4c6b4ebc4e1e..ae902c027fb7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.Context.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.Context.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.ContextWrapper.html b/docs/html/sdk/api_diff/11/changes/android.content.ContextWrapper.html
index f3ac2cc242d7..e7c38ce97d84 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.ContextWrapper.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.ContextWrapper.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.Intent.html b/docs/html/sdk/api_diff/11/changes/android.content.Intent.html
index f5abec5dc7de..20f5cf9c2a38 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.Intent.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.Intent.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.Editor.html b/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.Editor.html
index ff6a71d05f36..b36c5173b18b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.Editor.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.Editor.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.html b/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.html
index c46e257aea3b..7d77e1bfb8eb 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.SharedPreferences.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.SyncAdapterType.html b/docs/html/sdk/api_diff/11/changes/android.content.SyncAdapterType.html
index 7fe598db096c..4b810a5b71a8 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.SyncAdapterType.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.SyncAdapterType.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.SyncInfo.html b/docs/html/sdk/api_diff/11/changes/android.content.SyncInfo.html
index c00e677f2c1f..d8b75aa2b35b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.SyncInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.SyncInfo.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.pm.ActivityInfo.html b/docs/html/sdk/api_diff/11/changes/android.content.pm.ActivityInfo.html
index 0514240584d0..32c8de7a3308 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.pm.ActivityInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.pm.ActivityInfo.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.pm.ApplicationInfo.html b/docs/html/sdk/api_diff/11/changes/android.content.pm.ApplicationInfo.html
index c79d5f9482e5..cb1994ed255a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.pm.ApplicationInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.pm.ApplicationInfo.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.pm.ComponentInfo.html b/docs/html/sdk/api_diff/11/changes/android.content.pm.ComponentInfo.html
index 58341f9d0cf9..f1a5385c7491 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.pm.ComponentInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.pm.ComponentInfo.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageManager.html b/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageManager.html
index 5a6f4bf95401..42e668aea519 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageStats.html b/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageStats.html
index 14708d05de1f..11536cb8cd8d 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageStats.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.pm.PackageStats.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.content.res.Configuration.html b/docs/html/sdk/api_diff/11/changes/android.content.res.Configuration.html
index 5eaf4c84adda..a2c3198647a7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.content.res.Configuration.html
+++ b/docs/html/sdk/api_diff/11/changes/android.content.res.Configuration.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.AbstractCursor.html b/docs/html/sdk/api_diff/11/changes/android.database.AbstractCursor.html
index e8cf9e855b0d..12811eda1068 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.AbstractCursor.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.AbstractCursor.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.AbstractWindowedCursor.html b/docs/html/sdk/api_diff/11/changes/android.database.AbstractWindowedCursor.html
index 4511dc16ba6b..242592415fc9 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.AbstractWindowedCursor.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.AbstractWindowedCursor.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.Cursor.html b/docs/html/sdk/api_diff/11/changes/android.database.Cursor.html
index 1c4bda4cc006..5df763465a01 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.Cursor.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.Cursor.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.CursorWindow.html b/docs/html/sdk/api_diff/11/changes/android.database.CursorWindow.html
index 0a1ed459d0f4..50284fba1bf7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.CursorWindow.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.CursorWindow.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.CursorWrapper.html b/docs/html/sdk/api_diff/11/changes/android.database.CursorWrapper.html
index d9fdceca3bcc..d5152d1a04ce 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.CursorWrapper.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.CursorWrapper.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.DatabaseUtils.html b/docs/html/sdk/api_diff/11/changes/android.database.DatabaseUtils.html
index 628ce54a4698..97436a20f380 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.DatabaseUtils.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.DatabaseUtils.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteCursor.html b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteCursor.html
index 705a8cff92c3..324912ca0a5b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteCursor.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteCursor.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteDatabase.html b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteDatabase.html
index 259192db5502..779678d2bd79 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteDatabase.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteDatabase.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteOpenHelper.html b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteOpenHelper.html
index c38367ba5b0a..b782814d30ef 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteOpenHelper.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteOpenHelper.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteProgram.html b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteProgram.html
index e61a06637d5a..20aab2063120 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteProgram.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteProgram.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteQueryBuilder.html b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteQueryBuilder.html
index aae81942a5c5..aa6bc15b262a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteQueryBuilder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteQueryBuilder.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteStatement.html b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteStatement.html
index 7bedb5da86c4..ee6c8fbb6458 100644
--- a/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteStatement.html
+++ b/docs/html/sdk/api_diff/11/changes/android.database.sqlite.SQLiteStatement.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.graphics.BitmapFactory.Options.html b/docs/html/sdk/api_diff/11/changes/android.graphics.BitmapFactory.Options.html
index 53d3fdb0621a..68aa8723c27e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.graphics.BitmapFactory.Options.html
+++ b/docs/html/sdk/api_diff/11/changes/android.graphics.BitmapFactory.Options.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.graphics.Canvas.html b/docs/html/sdk/api_diff/11/changes/android.graphics.Canvas.html
index bf254368b97c..a4cf3e6c7155 100644
--- a/docs/html/sdk/api_diff/11/changes/android.graphics.Canvas.html
+++ b/docs/html/sdk/api_diff/11/changes/android.graphics.Canvas.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.ColorDrawable.html b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.ColorDrawable.html
index 2977fb33ad15..b2dd30846539 100644
--- a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.ColorDrawable.html
+++ b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.ColorDrawable.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.Drawable.html b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.Drawable.html
index 09f7e5dec91a..0b28b32a4708 100644
--- a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.Drawable.html
+++ b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.Drawable.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.DrawableContainerState.html b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.DrawableContainerState.html
index 55990327f3c0..603d4e72279c 100644
--- a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.DrawableContainerState.html
+++ b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.DrawableContainerState.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.html b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.html
index 6f5a1e6baabc..7c69ecdf6d47 100644
--- a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.html
+++ b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.DrawableContainer.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.LayerDrawable.html b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.LayerDrawable.html
index 688fb5451c7f..d93342151767 100644
--- a/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.LayerDrawable.html
+++ b/docs/html/sdk/api_diff/11/changes/android.graphics.drawable.LayerDrawable.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.Parameters.html b/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.Parameters.html
index fa67596502c7..f2edcf9f89fc 100644
--- a/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.Parameters.html
+++ b/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.Parameters.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.html b/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.html
index a8f2f5611dcf..32dfdde38771 100644
--- a/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.html
+++ b/docs/html/sdk/api_diff/11/changes/android.hardware.Camera.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.hardware.SensorManager.html b/docs/html/sdk/api_diff/11/changes/android.hardware.SensorManager.html
index 6973a6407e19..14d24adb6181 100644
--- a/docs/html/sdk/api_diff/11/changes/android.hardware.SensorManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.hardware.SensorManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.InputMethodImpl.html b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.InputMethodImpl.html
index 3cc8fcb393d8..9769634b539e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.InputMethodImpl.html
+++ b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.InputMethodImpl.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.Insets.html b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.Insets.html
index f4bb8416b716..83d5e9eb18f1 100644
--- a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.Insets.html
+++ b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.Insets.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.html b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.html
index c025fc07e644..c6e749a71ae2 100644
--- a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.html
+++ b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.InputMethodService.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.Keyboard.html b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.Keyboard.html
index 5ce6d479eae5..58490d846bfd 100644
--- a/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.Keyboard.html
+++ b/docs/html/sdk/api_diff/11/changes/android.inputmethodservice.Keyboard.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.media.AudioManager.html b/docs/html/sdk/api_diff/11/changes/android.media.AudioManager.html
index 6a201aee82f1..d946c6844911 100644
--- a/docs/html/sdk/api_diff/11/changes/android.media.AudioManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.media.AudioManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.media.CamcorderProfile.html b/docs/html/sdk/api_diff/11/changes/android.media.CamcorderProfile.html
index 0cda7efeda80..94a07842f886 100644
--- a/docs/html/sdk/api_diff/11/changes/android.media.CamcorderProfile.html
+++ b/docs/html/sdk/api_diff/11/changes/android.media.CamcorderProfile.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.media.ExifInterface.html b/docs/html/sdk/api_diff/11/changes/android.media.ExifInterface.html
index 53630fcce6c7..e99c6de615f5 100644
--- a/docs/html/sdk/api_diff/11/changes/android.media.ExifInterface.html
+++ b/docs/html/sdk/api_diff/11/changes/android.media.ExifInterface.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.AudioSource.html b/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.AudioSource.html
index 3bcc1971b58e..1035e58e559d 100644
--- a/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.AudioSource.html
+++ b/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.AudioSource.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.html b/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.html
index d4fb6cbfba08..57241e2d0cb6 100644
--- a/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.media.MediaRecorder.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.net.Proxy.html b/docs/html/sdk/api_diff/11/changes/android.net.Proxy.html
index c4053de0bbb9..90d43f23942a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.net.Proxy.html
+++ b/docs/html/sdk/api_diff/11/changes/android.net.Proxy.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.net.Uri.Builder.html b/docs/html/sdk/api_diff/11/changes/android.net.Uri.Builder.html
index 14e94d065836..3261b0300899 100644
--- a/docs/html/sdk/api_diff/11/changes/android.net.Uri.Builder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.net.Uri.Builder.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.net.Uri.html b/docs/html/sdk/api_diff/11/changes/android.net.Uri.html
index 7bb8b183f091..c0afdd22d802 100644
--- a/docs/html/sdk/api_diff/11/changes/android.net.Uri.html
+++ b/docs/html/sdk/api_diff/11/changes/android.net.Uri.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.opengl.GLSurfaceView.html b/docs/html/sdk/api_diff/11/changes/android.opengl.GLSurfaceView.html
index ba9366c4b29a..d49cd6504953 100644
--- a/docs/html/sdk/api_diff/11/changes/android.opengl.GLSurfaceView.html
+++ b/docs/html/sdk/api_diff/11/changes/android.opengl.GLSurfaceView.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.AsyncTask.html b/docs/html/sdk/api_diff/11/changes/android.os.AsyncTask.html
index 3b6cacafc354..6655d8add51a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.AsyncTask.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.AsyncTask.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.BatteryManager.html b/docs/html/sdk/api_diff/11/changes/android.os.BatteryManager.html
index 7c43f4c5fa3c..832a5f0892da 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.BatteryManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.BatteryManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.Build.VERSION_CODES.html b/docs/html/sdk/api_diff/11/changes/android.os.Build.VERSION_CODES.html
index 5c7e9be33cf1..14357aaf7dce 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.Build.VERSION_CODES.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.Build.VERSION_CODES.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.Bundle.html b/docs/html/sdk/api_diff/11/changes/android.os.Bundle.html
index a10c6eeb9f5a..14964de3bb8d 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.Bundle.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.Bundle.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.Debug.html b/docs/html/sdk/api_diff/11/changes/android.os.Debug.html
index e246dab2c1ab..768895910d33 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.Debug.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.Debug.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.DropBoxManager.html b/docs/html/sdk/api_diff/11/changes/android.os.DropBoxManager.html
index c52aa3e1c6f0..06153282372e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.DropBoxManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.DropBoxManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.Environment.html b/docs/html/sdk/api_diff/11/changes/android.os.Environment.html
index d442c3c0f14a..4c9554abd9d6 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.Environment.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.Environment.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.ThreadPolicy.Builder.html b/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.ThreadPolicy.Builder.html
index 11d58cbffd6c..3413c079090e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.ThreadPolicy.Builder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.ThreadPolicy.Builder.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.VmPolicy.Builder.html b/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.VmPolicy.Builder.html
index 2a2d2a12a91a..89cc5460ce85 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.VmPolicy.Builder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.VmPolicy.Builder.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.html b/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.html
index f6f67bc3313e..91cacad9a18c 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.StrictMode.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.os.Vibrator.html b/docs/html/sdk/api_diff/11/changes/android.os.Vibrator.html
index 33e97afc6162..eb400c09d2da 100644
--- a/docs/html/sdk/api_diff/11/changes/android.os.Vibrator.html
+++ b/docs/html/sdk/api_diff/11/changes/android.os.Vibrator.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.preference.Preference.html b/docs/html/sdk/api_diff/11/changes/android.preference.Preference.html
index 769be1fb83d3..68b1829bd119 100644
--- a/docs/html/sdk/api_diff/11/changes/android.preference.Preference.html
+++ b/docs/html/sdk/api_diff/11/changes/android.preference.Preference.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.preference.PreferenceActivity.html b/docs/html/sdk/api_diff/11/changes/android.preference.PreferenceActivity.html
index 4818c3b4ec52..f4c2b9793371 100644
--- a/docs/html/sdk/api_diff/11/changes/android.preference.PreferenceActivity.html
+++ b/docs/html/sdk/api_diff/11/changes/android.preference.PreferenceActivity.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.AlarmClock.html b/docs/html/sdk/api_diff/11/changes/android.provider.AlarmClock.html
index 378b739efb62..56e510fb2429 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.AlarmClock.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.AlarmClock.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.Browser.SearchColumns.html b/docs/html/sdk/api_diff/11/changes/android.provider.Browser.SearchColumns.html
index 8310d79d84f1..229704959aca 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.Browser.SearchColumns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.Browser.SearchColumns.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Email.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Email.html
index 79a10ef07df7..ee96c98c2bf8 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Email.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Email.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Relation.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Relation.html
index 977cb167a6b0..584d98bc94ad 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Relation.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.CommonDataKinds.Relation.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactStatusColumns.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactStatusColumns.html
index 5dd50faa0db1..023a1dc6987e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactStatusColumns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactStatusColumns.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.AggregationSuggestions.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.AggregationSuggestions.html
index 245ccd6f552e..4fe9e1248539 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.AggregationSuggestions.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.AggregationSuggestions.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.Photo.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.Photo.html
index 83cdcad6c9c4..f4bf4d8440de 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.Photo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.Photo.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.html
index 8cd4f79a4db3..7071f671c844 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Contacts.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactsColumns.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactsColumns.html
index 93ecc6b5ee0e..5817b98e48c7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactsColumns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.ContactsColumns.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumns.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumns.html
index a4b9a6145fe4..5c838183ad16 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumns.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumnsWithJoins.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumnsWithJoins.html
index 9c1624c730ae..2988b8b2977c 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumnsWithJoins.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.DataColumnsWithJoins.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.GroupsColumns.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.GroupsColumns.html
index 8164d5b9c4e2..986064ebb358 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.GroupsColumns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.GroupsColumns.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Intents.Insert.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Intents.Insert.html
index a39f75f6822a..7f2786a6eaee 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Intents.Insert.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.Intents.Insert.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContacts.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContacts.html
index e47425736de8..e3b69753d6f9 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContacts.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContacts.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContactsColumns.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContactsColumns.html
index 4dc36046c5e1..795461f46236 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContactsColumns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.RawContactsColumns.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.StatusColumns.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.StatusColumns.html
index cc8991cf0ab8..fb3a818b8424 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.StatusColumns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.StatusColumns.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.html b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.html
index c46e2474e686..91f1cc9cbaa4 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.ContactsContract.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.MediaStore.Audio.Genres.html b/docs/html/sdk/api_diff/11/changes/android.provider.MediaStore.Audio.Genres.html
index 027b99f6fdb1..f0b24584d672 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.MediaStore.Audio.Genres.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.MediaStore.Audio.Genres.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.Settings.Secure.html b/docs/html/sdk/api_diff/11/changes/android.provider.Settings.Secure.html
index 8a7dfac48f62..017b8b710e23 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.Settings.Secure.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.Settings.Secure.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.Settings.System.html b/docs/html/sdk/api_diff/11/changes/android.provider.Settings.System.html
index 1069d4fe365b..546a8a1ed6bb 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.Settings.System.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.Settings.System.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.provider.Settings.html b/docs/html/sdk/api_diff/11/changes/android.provider.Settings.html
index ed4c14cb30e2..d01ded842965 100644
--- a/docs/html/sdk/api_diff/11/changes/android.provider.Settings.html
+++ b/docs/html/sdk/api_diff/11/changes/android.provider.Settings.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.speech.RecognizerIntent.html b/docs/html/sdk/api_diff/11/changes/android.speech.RecognizerIntent.html
index b8d0f2de8dde..528ba3e67417 100644
--- a/docs/html/sdk/api_diff/11/changes/android.speech.RecognizerIntent.html
+++ b/docs/html/sdk/api_diff/11/changes/android.speech.RecognizerIntent.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.speech.tts.TextToSpeech.Engine.html b/docs/html/sdk/api_diff/11/changes/android.speech.tts.TextToSpeech.Engine.html
index abb12f2474b5..ecd4ae2d40b1 100644
--- a/docs/html/sdk/api_diff/11/changes/android.speech.tts.TextToSpeech.Engine.html
+++ b/docs/html/sdk/api_diff/11/changes/android.speech.tts.TextToSpeech.Engine.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.telephony.TelephonyManager.html b/docs/html/sdk/api_diff/11/changes/android.telephony.TelephonyManager.html
index d052e33f1118..13258f9f6643 100644
--- a/docs/html/sdk/api_diff/11/changes/android.telephony.TelephonyManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.telephony.TelephonyManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.test.mock.MockContext.html b/docs/html/sdk/api_diff/11/changes/android.test.mock.MockContext.html
index d29faf5adad5..80b70711576c 100644
--- a/docs/html/sdk/api_diff/11/changes/android.test.mock.MockContext.html
+++ b/docs/html/sdk/api_diff/11/changes/android.test.mock.MockContext.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.test.mock.MockCursor.html b/docs/html/sdk/api_diff/11/changes/android.test.mock.MockCursor.html
index fa78a3df73cc..44479f27216b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.test.mock.MockCursor.html
+++ b/docs/html/sdk/api_diff/11/changes/android.test.mock.MockCursor.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.test.mock.MockPackageManager.html b/docs/html/sdk/api_diff/11/changes/android.test.mock.MockPackageManager.html
index 242543a21935..ba731baf60fb 100644
--- a/docs/html/sdk/api_diff/11/changes/android.test.mock.MockPackageManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.test.mock.MockPackageManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.ClipboardManager.html b/docs/html/sdk/api_diff/11/changes/android.text.ClipboardManager.html
index cfa9b822026f..58d40812fdc1 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.ClipboardManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.ClipboardManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.InputType.html b/docs/html/sdk/api_diff/11/changes/android.text.InputType.html
index e1c90c775d10..0bc07838e677 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.InputType.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.InputType.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.SpannableStringBuilder.html b/docs/html/sdk/api_diff/11/changes/android.text.SpannableStringBuilder.html
index e5142ad9358c..2b3020536945 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.SpannableStringBuilder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.SpannableStringBuilder.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.format.Time.html b/docs/html/sdk/api_diff/11/changes/android.text.format.Time.html
index 04481b596ac7..733ae3263448 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.format.Time.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.format.Time.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.method.ArrowKeyMovementMethod.html b/docs/html/sdk/api_diff/11/changes/android.text.method.ArrowKeyMovementMethod.html
index 874bc56db2fd..e8018ffbfa5a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.method.ArrowKeyMovementMethod.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.method.ArrowKeyMovementMethod.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.method.BaseKeyListener.html b/docs/html/sdk/api_diff/11/changes/android.text.method.BaseKeyListener.html
index 0a9d7d2cfd4d..f8476bcf735a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.method.BaseKeyListener.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.method.BaseKeyListener.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.method.QwertyKeyListener.html b/docs/html/sdk/api_diff/11/changes/android.text.method.QwertyKeyListener.html
index 6ce55bf86c7e..326579db4ca5 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.method.QwertyKeyListener.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.method.QwertyKeyListener.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.text.method.ScrollingMovementMethod.html b/docs/html/sdk/api_diff/11/changes/android.text.method.ScrollingMovementMethod.html
index f7a04af2894f..4c2a5afcf348 100644
--- a/docs/html/sdk/api_diff/11/changes/android.text.method.ScrollingMovementMethod.html
+++ b/docs/html/sdk/api_diff/11/changes/android.text.method.ScrollingMovementMethod.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.util.AndroidException.html b/docs/html/sdk/api_diff/11/changes/android.util.AndroidException.html
index df81a2c52479..4e5829af7a19 100644
--- a/docs/html/sdk/api_diff/11/changes/android.util.AndroidException.html
+++ b/docs/html/sdk/api_diff/11/changes/android.util.AndroidException.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.util.AndroidRuntimeException.html b/docs/html/sdk/api_diff/11/changes/android.util.AndroidRuntimeException.html
index f33dc973eef3..e4d37357bcaa 100644
--- a/docs/html/sdk/api_diff/11/changes/android.util.AndroidRuntimeException.html
+++ b/docs/html/sdk/api_diff/11/changes/android.util.AndroidRuntimeException.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.util.Patterns.html b/docs/html/sdk/api_diff/11/changes/android.util.Patterns.html
index 31db636d3d6f..8985ccbcd5c2 100644
--- a/docs/html/sdk/api_diff/11/changes/android.util.Patterns.html
+++ b/docs/html/sdk/api_diff/11/changes/android.util.Patterns.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.util.SparseArray.html b/docs/html/sdk/api_diff/11/changes/android.util.SparseArray.html
index da2d4218bb12..3dd7be2fc8d3 100644
--- a/docs/html/sdk/api_diff/11/changes/android.util.SparseArray.html
+++ b/docs/html/sdk/api_diff/11/changes/android.util.SparseArray.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.util.StateSet.html b/docs/html/sdk/api_diff/11/changes/android.util.StateSet.html
index 0bf93e3b5c83..c40f95489ab5 100644
--- a/docs/html/sdk/api_diff/11/changes/android.util.StateSet.html
+++ b/docs/html/sdk/api_diff/11/changes/android.util.StateSet.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.KeyData.html b/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.KeyData.html
index 9adcb310661d..945bee75144e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.KeyData.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.KeyData.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.html b/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.html
index d46a5f7dff71..07150bc3a564 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.KeyCharacterMap.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.KeyEvent.html b/docs/html/sdk/api_diff/11/changes/android.view.KeyEvent.html
index a8cb83ac78a8..7eab63e8770e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.KeyEvent.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.KeyEvent.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.LayoutInflater.html b/docs/html/sdk/api_diff/11/changes/android.view.LayoutInflater.html
index 44fee2e0bcfc..384f01e6be7e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.LayoutInflater.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.LayoutInflater.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.MenuItem.html b/docs/html/sdk/api_diff/11/changes/android.view.MenuItem.html
index 4fa11b902c70..ae27c1d297ff 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.MenuItem.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.MenuItem.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.MotionEvent.html b/docs/html/sdk/api_diff/11/changes/android.view.MotionEvent.html
index 9a2994eed0f7..d5cb34120326 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.MotionEvent.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.MotionEvent.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.ScaleGestureDetector.html b/docs/html/sdk/api_diff/11/changes/android.view.ScaleGestureDetector.html
index 952c6f172293..bc9da1113cc0 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.ScaleGestureDetector.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.ScaleGestureDetector.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.Surface.html b/docs/html/sdk/api_diff/11/changes/android.view.Surface.html
index 95daf0e28402..dfbfde363a78 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.Surface.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.Surface.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.SurfaceHolder.html b/docs/html/sdk/api_diff/11/changes/android.view.SurfaceHolder.html
index d97f6eb73325..409e3101aa35 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.SurfaceHolder.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.SurfaceHolder.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.View.html b/docs/html/sdk/api_diff/11/changes/android.view.View.html
index 97a38dc7350d..6de1ad78fc30 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.View.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.View.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.ViewGroup.html b/docs/html/sdk/api_diff/11/changes/android.view.ViewGroup.html
index c014d5cb8318..c14d36ff9206 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.ViewGroup.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.ViewGroup.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.ViewParent.html b/docs/html/sdk/api_diff/11/changes/android.view.ViewParent.html
index 79646cd82a29..9caa391d591d 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.ViewParent.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.ViewParent.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.Window.Callback.html b/docs/html/sdk/api_diff/11/changes/android.view.Window.Callback.html
index 9bc54f5975b4..73aa43640bb4 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.Window.Callback.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.Window.Callback.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.Window.html b/docs/html/sdk/api_diff/11/changes/android.view.Window.html
index 62c3bb93063d..c55a2074206d 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.Window.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.Window.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.WindowManager.LayoutParams.html b/docs/html/sdk/api_diff/11/changes/android.view.WindowManager.LayoutParams.html
index 15cf4ee38d0b..c68dce778972 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.WindowManager.LayoutParams.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.WindowManager.LayoutParams.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.animation.Animation.html b/docs/html/sdk/api_diff/11/changes/android.view.animation.Animation.html
index d2a593bb0602..8bf383bc4e3b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.animation.Animation.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.animation.Animation.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.animation.Interpolator.html b/docs/html/sdk/api_diff/11/changes/android.view.animation.Interpolator.html
index de6170c37785..c292c2486450 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.animation.Interpolator.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.animation.Interpolator.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.BaseInputConnection.html b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.BaseInputConnection.html
index 10a1b5190fbc..610400713f24 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.BaseInputConnection.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.BaseInputConnection.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.EditorInfo.html b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.EditorInfo.html
index 8dd751e37e2d..bd0e91392a38 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.EditorInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.EditorInfo.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnection.html b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnection.html
index 14a56f4fa9f5..3a21f567f490 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnection.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnection.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnectionWrapper.html b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnectionWrapper.html
index 21c20539b623..1f8cd1e82db1 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnectionWrapper.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputConnectionWrapper.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethod.html b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethod.html
index c8e7c24472f7..faa103b5d0eb 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethod.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethod.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodInfo.html b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodInfo.html
index 680e2fe59d58..5e8ef7f2a3d6 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodInfo.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodInfo.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodManager.html b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodManager.html
index ae7396bac623..68a58d34a896 100644
--- a/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.view.inputmethod.InputMethodManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.CacheResult.html b/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.CacheResult.html
index 2924189ad7df..9ba6fb25cec8 100644
--- a/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.CacheResult.html
+++ b/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.CacheResult.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.html b/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.html
index f85b0d205801..0330d94c358a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.html
+++ b/docs/html/sdk/api_diff/11/changes/android.webkit.CacheManager.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.webkit.WebSettings.html b/docs/html/sdk/api_diff/11/changes/android.webkit.WebSettings.html
index 6a59505950bf..d5dd2ca1731b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.webkit.WebSettings.html
+++ b/docs/html/sdk/api_diff/11/changes/android.webkit.WebSettings.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.webkit.WebView.html b/docs/html/sdk/api_diff/11/changes/android.webkit.WebView.html
index 023f085c49e8..dbd3c125121d 100644
--- a/docs/html/sdk/api_diff/11/changes/android.webkit.WebView.html
+++ b/docs/html/sdk/api_diff/11/changes/android.webkit.WebView.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.webkit.WebViewClient.html b/docs/html/sdk/api_diff/11/changes/android.webkit.WebViewClient.html
index 5f1bb1aa6c84..65172a01eb50 100644
--- a/docs/html/sdk/api_diff/11/changes/android.webkit.WebViewClient.html
+++ b/docs/html/sdk/api_diff/11/changes/android.webkit.WebViewClient.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.AbsListView.html b/docs/html/sdk/api_diff/11/changes/android.widget.AbsListView.html
index 294126e01d0e..03dc6a1e2450 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.AbsListView.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.AbsListView.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.ArrayAdapter.html b/docs/html/sdk/api_diff/11/changes/android.widget.ArrayAdapter.html
index 4480a6c4e37a..4dbdc6e5c5c7 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.ArrayAdapter.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.ArrayAdapter.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.CursorAdapter.html b/docs/html/sdk/api_diff/11/changes/android.widget.CursorAdapter.html
index 4a58279af634..537dd79edcbb 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.CursorAdapter.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.CursorAdapter.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.DatePicker.html b/docs/html/sdk/api_diff/11/changes/android.widget.DatePicker.html
index 64f70b560587..2309fed502e6 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.DatePicker.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.DatePicker.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.GridView.html b/docs/html/sdk/api_diff/11/changes/android.widget.GridView.html
index 4ad372079ac2..73b9dbc75273 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.GridView.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.GridView.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.ImageView.html b/docs/html/sdk/api_diff/11/changes/android.widget.ImageView.html
index 7eb3d5d90fec..2658d25381e0 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.ImageView.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.ImageView.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.LinearLayout.html b/docs/html/sdk/api_diff/11/changes/android.widget.LinearLayout.html
index 29324a70fdca..acdd2b733c35 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.LinearLayout.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.LinearLayout.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.ListView.html b/docs/html/sdk/api_diff/11/changes/android.widget.ListView.html
index 1f82834b5005..922cbd7e1ebd 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.ListView.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.ListView.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.OverScroller.html b/docs/html/sdk/api_diff/11/changes/android.widget.OverScroller.html
index 58c06775cf69..9cc2fa87df8e 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.OverScroller.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.OverScroller.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.PopupWindow.html b/docs/html/sdk/api_diff/11/changes/android.widget.PopupWindow.html
index 4aad339c1e47..f3aebe0a6f64 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.PopupWindow.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.PopupWindow.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.QuickContactBadge.html b/docs/html/sdk/api_diff/11/changes/android.widget.QuickContactBadge.html
index 1d6d6b706997..de5f6ebdb596 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.QuickContactBadge.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.QuickContactBadge.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.RemoteViews.html b/docs/html/sdk/api_diff/11/changes/android.widget.RemoteViews.html
index be2a0e20eed8..53eef9148340 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.RemoteViews.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.RemoteViews.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.ResourceCursorAdapter.html b/docs/html/sdk/api_diff/11/changes/android.widget.ResourceCursorAdapter.html
index 169abdd13300..a41e9dfb4ea9 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.ResourceCursorAdapter.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.ResourceCursorAdapter.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.Scroller.html b/docs/html/sdk/api_diff/11/changes/android.widget.Scroller.html
index 340fbd033b4e..b6e77bef5949 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.Scroller.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.Scroller.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.SimpleCursorAdapter.html b/docs/html/sdk/api_diff/11/changes/android.widget.SimpleCursorAdapter.html
index ba62dd3bdff4..602482b5fcfa 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.SimpleCursorAdapter.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.SimpleCursorAdapter.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.Spinner.html b/docs/html/sdk/api_diff/11/changes/android.widget.Spinner.html
index 23773e8be1d7..e2ee047cd447 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.Spinner.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.Spinner.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.TabWidget.html b/docs/html/sdk/api_diff/11/changes/android.widget.TabWidget.html
index e63bee44db40..45488a7afa5b 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.TabWidget.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.TabWidget.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/android.widget.TextView.html b/docs/html/sdk/api_diff/11/changes/android.widget.TextView.html
index 48e551eeff44..780259e0284a 100644
--- a/docs/html/sdk/api_diff/11/changes/android.widget.TextView.html
+++ b/docs/html/sdk/api_diff/11/changes/android.widget.TextView.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/changes-summary.html b/docs/html/sdk/api_diff/11/changes/changes-summary.html
index a0422838599a..b6af9ae7a321 100644
--- a/docs/html/sdk/api_diff/11/changes/changes-summary.html
+++ b/docs/html/sdk/api_diff/11/changes/changes-summary.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/dalvik.bytecode.Opcodes.html b/docs/html/sdk/api_diff/11/changes/dalvik.bytecode.Opcodes.html
index e91f26694f7c..5bbc2a85360f 100644
--- a/docs/html/sdk/api_diff/11/changes/dalvik.bytecode.Opcodes.html
+++ b/docs/html/sdk/api_diff/11/changes/dalvik.bytecode.Opcodes.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/fields_index_additions.html b/docs/html/sdk/api_diff/11/changes/fields_index_additions.html
index 856253898d8b..12ecd4f70738 100644
--- a/docs/html/sdk/api_diff/11/changes/fields_index_additions.html
+++ b/docs/html/sdk/api_diff/11/changes/fields_index_additions.html
@@ -1552,8 +1552,6 @@ Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style=
</nobr><br>
<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD" class="hiddenlink" target="rightframe">USES_POLICY_EXPIRE_PASSWORD</A>
</nobr><br>
-<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY" class="hiddenlink" target="rightframe">USES_POLICY_SETS_GLOBAL_PROXY</A>
-</nobr><br>
<A NAME="V"></A>
<br><font size="+2">V</font>&nbsp;
<a href="#A"><font size="-2">A</font></a>
diff --git a/docs/html/sdk/api_diff/11/changes/fields_index_all.html b/docs/html/sdk/api_diff/11/changes/fields_index_all.html
index a218b9c26215..52705a53e121 100644
--- a/docs/html/sdk/api_diff/11/changes/fields_index_all.html
+++ b/docs/html/sdk/api_diff/11/changes/fields_index_all.html
@@ -1633,8 +1633,6 @@ Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style=
</nobr><br>
<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD" class="hiddenlink" target="rightframe">USES_POLICY_EXPIRE_PASSWORD</A>
</nobr><br>
-<nobr><A HREF="android.app.admin.DeviceAdminInfo.html#android.app.admin.DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY" class="hiddenlink" target="rightframe">USES_POLICY_SETS_GLOBAL_PROXY</A>
-</nobr><br>
<A NAME="V"></A>
<br><font size="+2">V</font>&nbsp;
<a href="#A"><font size="-2">A</font></a>
diff --git a/docs/html/sdk/api_diff/11/changes/java.lang.Character.UnicodeBlock.html b/docs/html/sdk/api_diff/11/changes/java.lang.Character.UnicodeBlock.html
index 911563e68acb..4ba7af54ce74 100644
--- a/docs/html/sdk/api_diff/11/changes/java.lang.Character.UnicodeBlock.html
+++ b/docs/html/sdk/api_diff/11/changes/java.lang.Character.UnicodeBlock.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.lang.Object.html b/docs/html/sdk/api_diff/11/changes/java.lang.Object.html
index 724f0e8b186d..c894b076b241 100644
--- a/docs/html/sdk/api_diff/11/changes/java.lang.Object.html
+++ b/docs/html/sdk/api_diff/11/changes/java.lang.Object.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.util.Deque.html b/docs/html/sdk/api_diff/11/changes/java.util.Deque.html
index 221750fe99d4..103909365829 100644
--- a/docs/html/sdk/api_diff/11/changes/java.util.Deque.html
+++ b/docs/html/sdk/api_diff/11/changes/java.util.Deque.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.util.Locale.html b/docs/html/sdk/api_diff/11/changes/java.util.Locale.html
index 8967c69a3cca..c27208e976b3 100644
--- a/docs/html/sdk/api_diff/11/changes/java.util.Locale.html
+++ b/docs/html/sdk/api_diff/11/changes/java.util.Locale.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.util.NavigableMap.html b/docs/html/sdk/api_diff/11/changes/java.util.NavigableMap.html
index 74f15ba14ab4..e611d879b85f 100644
--- a/docs/html/sdk/api_diff/11/changes/java.util.NavigableMap.html
+++ b/docs/html/sdk/api_diff/11/changes/java.util.NavigableMap.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.util.NavigableSet.html b/docs/html/sdk/api_diff/11/changes/java.util.NavigableSet.html
index e441b9d1deb2..7fbc133028f5 100644
--- a/docs/html/sdk/api_diff/11/changes/java.util.NavigableSet.html
+++ b/docs/html/sdk/api_diff/11/changes/java.util.NavigableSet.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.util.Queue.html b/docs/html/sdk/api_diff/11/changes/java.util.Queue.html
index 29a125657000..0595cfad0172 100644
--- a/docs/html/sdk/api_diff/11/changes/java.util.Queue.html
+++ b/docs/html/sdk/api_diff/11/changes/java.util.Queue.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.Control.html b/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.Control.html
index a1e371a14f9a..a0f3777cbec3 100644
--- a/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.Control.html
+++ b/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.Control.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.html b/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.html
index 232c8c0ad95f..3cf915b2a94f 100644
--- a/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.html
+++ b/docs/html/sdk/api_diff/11/changes/java.util.ResourceBundle.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/jdiff_statistics.html b/docs/html/sdk/api_diff/11/changes/jdiff_statistics.html
index db430c423c7e..044e5cae5bb2 100644
--- a/docs/html/sdk/api_diff/11/changes/jdiff_statistics.html
+++ b/docs/html/sdk/api_diff/11/changes/jdiff_statistics.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
@@ -71,7 +71,7 @@ body{overflow:auto;}
<div id="doc-content" style="position:relative;">
<div id="mainBodyFluid">
<h1>API&nbsp;Change&nbsp;Statistics</h1>
-<p>The overall difference between API Levels 10 and 11 is approximately <span style="color:222;font-weight:bold;">2.57%</span>.
+<p>The overall difference between API Levels 10 and 11 is approximately <span style="color:222;font-weight:bold;">2.56%</span>.
</p>
<br>
<a name="numbers"></a>
@@ -110,24 +110,24 @@ The table below lists the numbers of program elements (packages, classes, constr
</TR>
<TR>
<TD>Methods</TD>
- <TD ALIGN="right">433</TD>
+ <TD ALIGN="right">431</TD>
<TD ALIGN="right">100</TD>
<TD ALIGN="right">26</TD>
- <TD ALIGN="right">559</TD>
+ <TD ALIGN="right">557</TD>
</TR>
<TR>
<TD>Fields</TD>
- <TD ALIGN="right">620</TD>
+ <TD ALIGN="right">619</TD>
<TD ALIGN="right">36</TD>
<TD ALIGN="right">0</TD>
- <TD ALIGN="right">656</TD>
+ <TD ALIGN="right">655</TD>
</TR>
<TR>
<TD style="background-color:#FAFAFA"><b>Total</b></TD>
- <TD style="background-color:#FAFAFA" ALIGN="right"><strong>1185</strong></TD>
+ <TD style="background-color:#FAFAFA" ALIGN="right"><strong>1182</strong></TD>
<TD style="background-color:#FAFAFA" ALIGN="right"><strong>375</strong></TD>
<TD style="background-color:#FAFAFA" ALIGN="right"><strong>27</strong></TD>
- <TD style="background-color:#FAFAFA" ALIGN="right"><strong>1587</strong></TD>
+ <TD style="background-color:#FAFAFA" ALIGN="right"><strong>1584</strong></TD>
</TR>
</TABLE>
<br>
@@ -159,12 +159,12 @@ The table below lists the numbers of program elements (packages, classes, constr
<TD><A HREF="pkg_android.html">android</A></TD>
</TR>
<TR>
- <TD ALIGN="center">15</TD>
- <TD><A HREF="pkg_android.app.admin.html">android.app.admin</A></TD>
+ <TD ALIGN="center">14</TD>
+ <TD><A HREF="pkg_android.preference.html">android.preference</A></TD>
</TR>
<TR>
<TD ALIGN="center">14</TD>
- <TD><A HREF="pkg_android.preference.html">android.preference</A></TD>
+ <TD><A HREF="pkg_android.app.admin.html">android.app.admin</A></TD>
</TR>
<TR>
<TD ALIGN="center">11</TD>
@@ -336,11 +336,6 @@ android.provider.ContactsContract.Contacts.AggregationSuggestions</A></TD>
android.R.style</A></TD>
</TR>
<TR>
- <TD ALIGN="center">34</TD>
- <TD><A HREF="android.app.admin.DevicePolicyManager.html">
-android.app.admin.DevicePolicyManager</A></TD>
-</TR>
-<TR>
<TD ALIGN="center">33</TD>
<TD><A HREF="android.R.dimen.html">
android.R.dimen</A></TD>
@@ -361,6 +356,11 @@ android.provider.ContactsContract.Contacts.Photo</A></TD>
android.widget.DatePicker</A></TD>
</TR>
<TR>
+ <TD ALIGN="center">32</TD>
+ <TD><A HREF="android.app.admin.DevicePolicyManager.html">
+android.app.admin.DevicePolicyManager</A></TD>
+</TR>
+<TR>
<TD ALIGN="center">30</TD>
<TD><A HREF="android.media.CamcorderProfile.html">
android.media.CamcorderProfile</A></TD>
@@ -762,11 +762,6 @@ android.app.Activity</A></TD>
</TR>
<TR>
<TD ALIGN="center">6</TD>
- <TD><A HREF="android.app.admin.DeviceAdminInfo.html">
-android.app.admin.DeviceAdminInfo</A></TD>
-</TR>
-<TR>
- <TD ALIGN="center">6</TD>
<TD><A HREF="android.media.MediaRecorder.AudioSource.html">
android.media.MediaRecorder.AudioSource</A></TD>
</TR>
@@ -867,6 +862,11 @@ android.app.WallpaperManager</A></TD>
</TR>
<TR>
<TD ALIGN="center">4</TD>
+ <TD><A HREF="android.app.admin.DeviceAdminInfo.html">
+android.app.admin.DeviceAdminInfo</A></TD>
+</TR>
+<TR>
+ <TD ALIGN="center">4</TD>
<TD><A HREF="android.appwidget.AppWidgetHost.html">
android.appwidget.AppWidgetHost</A></TD>
</TR>
diff --git a/docs/html/sdk/api_diff/11/changes/methods_index_additions.html b/docs/html/sdk/api_diff/11/changes/methods_index_additions.html
index ba2131731fea..b3a67abc77a4 100644
--- a/docs/html/sdk/api_diff/11/changes/methods_index_additions.html
+++ b/docs/html/sdk/api_diff/11/changes/methods_index_additions.html
@@ -430,8 +430,6 @@ Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style=
()</A></nobr><br>
<nobr><A HREF="android.app.Activity.html#android.app.Activity.getFragmentManager_added()" class="hiddenlink" target="rightframe"><b>getFragmentManager</b>
()</A></nobr><br>
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.getGlobalProxyAdmin_added()" class="hiddenlink" target="rightframe"><b>getGlobalProxyAdmin</b>
-()</A></nobr><br>
<nobr><A HREF="android.preference.Preference.html#android.preference.Preference.getIcon_added()" class="hiddenlink" target="rightframe"><b>getIcon</b>
()</A></nobr><br>
<nobr><A HREF="android.text.method.QwertyKeyListener.html#android.text.method.QwertyKeyListener.getInstanceForFullKeyboard_added()" class="hiddenlink" target="rightframe"><b>getInstanceForFullKeyboard</b>
@@ -1273,8 +1271,6 @@ Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style=
&nbsp;&nbsp;<nobr><A HREF="android.widget.Scroller.html#android.widget.Scroller.setFriction_added(float)" class="hiddenlink" target="rightframe">type&nbsp;<b>
(<code>float</code>)</b>&nbsp;in&nbsp;android.widget.Scroller
</A></nobr><br>
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.setGlobalProxy_added(android.content.ComponentName, java.net.Proxy, java.util.List<java.lang.String>)" class="hiddenlink" target="rightframe"><b>setGlobalProxy</b>
-(<code>ComponentName, Proxy, List&lt;String&gt;</code>)</A></nobr><br>
<nobr><A HREF="android.widget.Spinner.html#android.widget.Spinner.setGravity_added(int)" class="hiddenlink" target="rightframe"><b>setGravity</b>
(<code>int</code>)</A></nobr><br>
<i>setIcon</i><br>
diff --git a/docs/html/sdk/api_diff/11/changes/methods_index_all.html b/docs/html/sdk/api_diff/11/changes/methods_index_all.html
index 79ac20acabba..2f1d8651b956 100644
--- a/docs/html/sdk/api_diff/11/changes/methods_index_all.html
+++ b/docs/html/sdk/api_diff/11/changes/methods_index_all.html
@@ -544,8 +544,6 @@ Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style=
()</A></nobr><br>
<nobr><A HREF="android.os.Debug.html#android.os.Debug.getGlobalExternalFreedSize_changed()" class="hiddenlink" target="rightframe">getGlobalExternalFreedSize
()</A></nobr><br>
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.getGlobalProxyAdmin_added()" class="hiddenlink" target="rightframe"><b>getGlobalProxyAdmin</b>
-()</A></nobr><br>
<nobr><A HREF="android.net.Proxy.html#android.net.Proxy.getHost_changed(android.content.Context)" class="hiddenlink" target="rightframe">getHost
(<code>Context</code>)</A></nobr><br>
<nobr><A HREF="android.preference.Preference.html#android.preference.Preference.getIcon_added()" class="hiddenlink" target="rightframe"><b>getIcon</b>
@@ -1590,8 +1588,6 @@ Listed as: <span style="color:#069"><strong>Added</strong></span>, <span style=
</A></nobr><br>
<nobr><A HREF="android.os.Debug.html#android.os.Debug.setGlobalAllocationLimit_changed(int)" class="hiddenlink" target="rightframe">setGlobalAllocationLimit
(<code>int</code>)</A></nobr><br>
-<nobr><A HREF="android.app.admin.DevicePolicyManager.html#android.app.admin.DevicePolicyManager.setGlobalProxy_added(android.content.ComponentName, java.net.Proxy, java.util.List<java.lang.String>)" class="hiddenlink" target="rightframe"><b>setGlobalProxy</b>
-(<code>ComponentName, Proxy, List&lt;String&gt;</code>)</A></nobr><br>
<nobr><A HREF="android.widget.Spinner.html#android.widget.Spinner.setGravity_added(int)" class="hiddenlink" target="rightframe"><b>setGravity</b>
(<code>int</code>)</A></nobr><br>
<i>setIcon</i><br>
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.accounts.html b/docs/html/sdk/api_diff/11/changes/pkg_android.accounts.html
index f52f77db3907..b2a2812346f4 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.accounts.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.accounts.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.app.admin.html b/docs/html/sdk/api_diff/11/changes/pkg_android.app.admin.html
index ab6c604fa59b..54220b196c89 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.app.admin.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.app.admin.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.app.html b/docs/html/sdk/api_diff/11/changes/pkg_android.app.html
index d251b5c66224..da5df6ff21d2 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.app.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.app.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.appwidget.html b/docs/html/sdk/api_diff/11/changes/pkg_android.appwidget.html
index 4ca6abc7872e..d3df6f32eac9 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.appwidget.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.appwidget.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.bluetooth.html b/docs/html/sdk/api_diff/11/changes/pkg_android.bluetooth.html
index 95550d76ca4f..286de69ec307 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.bluetooth.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.bluetooth.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.content.html b/docs/html/sdk/api_diff/11/changes/pkg_android.content.html
index b409999d4df7..814b57c10d8d 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.content.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.content.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.content.pm.html b/docs/html/sdk/api_diff/11/changes/pkg_android.content.pm.html
index 5e599e6b32e5..e791cbc414ab 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.content.pm.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.content.pm.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.content.res.html b/docs/html/sdk/api_diff/11/changes/pkg_android.content.res.html
index 6801657a75d8..196615152a5d 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.content.res.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.content.res.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.database.html b/docs/html/sdk/api_diff/11/changes/pkg_android.database.html
index fe1f8d403280..94564d370391 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.database.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.database.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.database.sqlite.html b/docs/html/sdk/api_diff/11/changes/pkg_android.database.sqlite.html
index bc66f4ba4674..7200032a114d 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.database.sqlite.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.database.sqlite.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.drawable.html b/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.drawable.html
index afe6b4a6d8b6..18d15cc57c8f 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.drawable.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.drawable.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.html b/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.html
index 74c158e1f08b..4f1c440eb503 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.graphics.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.hardware.html b/docs/html/sdk/api_diff/11/changes/pkg_android.hardware.html
index f542030aaeec..ea84a38a7559 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.hardware.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.hardware.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.html b/docs/html/sdk/api_diff/11/changes/pkg_android.html
index 5e25eb4dcd93..29df82c173bd 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.inputmethodservice.html b/docs/html/sdk/api_diff/11/changes/pkg_android.inputmethodservice.html
index 699635bc68c5..d2c4e275e1f6 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.inputmethodservice.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.inputmethodservice.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.media.html b/docs/html/sdk/api_diff/11/changes/pkg_android.media.html
index b7352581042e..2cd99a5cc07f 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.media.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.media.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.net.html b/docs/html/sdk/api_diff/11/changes/pkg_android.net.html
index 8c89b3598bd3..e1e2bf52ea7e 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.net.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.net.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.opengl.html b/docs/html/sdk/api_diff/11/changes/pkg_android.opengl.html
index 4cbf960f88c3..f871db5df88a 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.opengl.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.opengl.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.os.html b/docs/html/sdk/api_diff/11/changes/pkg_android.os.html
index a76e62c6df3a..eedacd394278 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.os.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.os.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.preference.html b/docs/html/sdk/api_diff/11/changes/pkg_android.preference.html
index c7e1fe978229..35ef0bc772d5 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.preference.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.preference.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.provider.html b/docs/html/sdk/api_diff/11/changes/pkg_android.provider.html
index c273c1c3b8e4..842355ef29a7 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.provider.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.provider.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.speech.html b/docs/html/sdk/api_diff/11/changes/pkg_android.speech.html
index dfcd56fa2c92..e981387adda9 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.speech.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.speech.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.speech.tts.html b/docs/html/sdk/api_diff/11/changes/pkg_android.speech.tts.html
index d9cec6bf91c1..f0bde9f43086 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.speech.tts.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.speech.tts.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.telephony.html b/docs/html/sdk/api_diff/11/changes/pkg_android.telephony.html
index c6263c4188d3..8a2d08b158ea 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.telephony.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.telephony.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.test.html b/docs/html/sdk/api_diff/11/changes/pkg_android.test.html
index 9d746cbbee0a..39db204dddfc 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.test.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.test.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.test.mock.html b/docs/html/sdk/api_diff/11/changes/pkg_android.test.mock.html
index 105c032461df..45914ea3177b 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.test.mock.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.test.mock.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.text.format.html b/docs/html/sdk/api_diff/11/changes/pkg_android.text.format.html
index 48429bed0039..cc395caa3c4e 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.text.format.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.text.format.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.text.html b/docs/html/sdk/api_diff/11/changes/pkg_android.text.html
index 7be792588df4..0d47282e6a0e 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.text.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.text.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.text.method.html b/docs/html/sdk/api_diff/11/changes/pkg_android.text.method.html
index 9bf1ec4904cb..eefed4b0ebe9 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.text.method.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.text.method.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.util.html b/docs/html/sdk/api_diff/11/changes/pkg_android.util.html
index 99e977b79392..b6444bab9fe6 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.util.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.util.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.view.animation.html b/docs/html/sdk/api_diff/11/changes/pkg_android.view.animation.html
index b12ffa3a86fa..3fd23d1580c2 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.view.animation.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.view.animation.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.view.html b/docs/html/sdk/api_diff/11/changes/pkg_android.view.html
index 6f31108f45d1..2ec022d5b6bd 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.view.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.view.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.view.inputmethod.html b/docs/html/sdk/api_diff/11/changes/pkg_android.view.inputmethod.html
index 44d337175b55..d7f85e005a2e 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.view.inputmethod.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.view.inputmethod.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.webkit.html b/docs/html/sdk/api_diff/11/changes/pkg_android.webkit.html
index efbfcaa0b0a6..0fd65d3a553d 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.webkit.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.webkit.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_android.widget.html b/docs/html/sdk/api_diff/11/changes/pkg_android.widget.html
index 6ba274e3a85e..64f2bc2269a0 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_android.widget.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_android.widget.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_dalvik.bytecode.html b/docs/html/sdk/api_diff/11/changes/pkg_dalvik.bytecode.html
index 18325d7f5ad3..6479d334b501 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_dalvik.bytecode.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_dalvik.bytecode.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_java.lang.html b/docs/html/sdk/api_diff/11/changes/pkg_java.lang.html
index 075dadca55f2..9415d76a9903 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_java.lang.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_java.lang.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/11/changes/pkg_java.util.html b/docs/html/sdk/api_diff/11/changes/pkg_java.util.html
index 4f6d8a0025bb..461d0ace9fe6 100644
--- a/docs/html/sdk/api_diff/11/changes/pkg_java.util.html
+++ b/docs/html/sdk/api_diff/11/changes/pkg_java.util.html
@@ -54,7 +54,7 @@ body{overflow:auto;}
</tr>
<tr>
<td class="diffspec">Generated</td>
- <td class="diffvalue">2011.02.08 11:41</td>
+ <td class="diffvalue">2011.02.19 17:19</td>
</tr>
</table>
</div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 355465b54e7d..3a7b39fbac3e 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -1,8 +1,8 @@
page.title=ADT Plugin for Eclipse
-adt.zip.version=9.0.0
-adt.zip.download=ADT_9.0.0.zip
-adt.zip.bytes=4433536
-adt.zip.checksum=bc2757f2a5a11d131390ce547bae154b
+adt.zip.version=10.0.0
+adt.zip.download=ADT-10.0.0.zip
+adt.zip.bytes=4243777
+adt.zip.checksum=bf88bff62bc45c3b6d062e2beed67765
@jd:body
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 1b4a33639712..df8869e4b854 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -1,21 +1,21 @@
page.title=Android SDK
sdk.redirect=0
-sdk.win_installer=installer_r09-windows.exe
-sdk.win_installer_bytes=32828818
-sdk.win_installer_checksum=ef92e643731f820360e036eb11658656
+sdk.win_installer=installer_r10-windows.exe
+sdk.win_installer_bytes=32845713
+sdk.win_installer_checksum=4e4356c472a6271ac9c062df0219dcb3
-sdk.win_download=android-sdk_r09-windows.zip
-sdk.win_bytes=32779808
-sdk.win_checksum=1a1bb8fad80bcc2dfbd00443b9a13e6b
+sdk.win_download=android-sdk_r10-windows.zip
+sdk.win_bytes=30112516
+sdk.win_checksum=643a75d99f5d4ca39dcf743fe894d599
-sdk.mac_download=android-sdk_r09-mac_x86.zip
-sdk.mac_bytes=28829553
-sdk.mac_checksum=ef3102fdbbbbd9bf4d9b572624aa9dc1
+sdk.mac_download=android-sdk_r10-mac_x86.zip
+sdk.mac_bytes=28224540
+sdk.mac_checksum=4d0a99a458e4f4bde65a01f8545f27e9
-sdk.linux_download=android-sdk_r09-linux_x86.tgz
-sdk.linux_bytes=26917824
-sdk.linux_checksum=9fefac5ff85d329836439f6e77a78cae
+sdk.linux_download=android-sdk_r10-linux_x86.tgz
+sdk.linux_bytes=26556013
+sdk.linux_checksum=10cafdd44771bfe2ba9d4440886389e7
@jd:body
diff --git a/docs/html/sdk/ndk/index.jd b/docs/html/sdk/ndk/index.jd
index 10887c66a068..40231a315e5d 100644
--- a/docs/html/sdk/ndk/index.jd
+++ b/docs/html/sdk/ndk/index.jd
@@ -1,16 +1,16 @@
ndk=true
-ndk.win_download=android-ndk-r5b-windows.zip
-ndk.win_bytes=61299831
-ndk.win_checksum=87745ada305ab639399161ab4faf684c
+ndk.win_download=android-ndk-r6-windows.zip
+ndk.win_bytes=64147764
+ndk.win_checksum=771b56328b7fc7751aa8040fb9dd09f0
-ndk.mac_download=android-ndk-r5b-darwin-x86.tar.bz2
-ndk.mac_bytes=50210863
-ndk.mac_checksum=019a14622a377b3727ec789af6707037
+ndk.mac_download=android-ndk-r6-darwin-x86.tar.bz2
+ndk.mac_bytes=50244722
+ndk.mac_checksum=d107f6d63478b73e09ed2eecd4c62bd3
-ndk.linux_download=android-ndk-r5b-linux-x86.tar.bz2
-ndk.linux_bytes=44138539
-ndk.linux_checksum=4c0045ddc2bfd657be9d5177d0e0b7e7
+ndk.linux_download=android-ndk-r6-linux-x86.tar.bz2
+ndk.linux_bytes=44088689
+ndk.linux_checksum=c83c3ab5a5e5a3b3fe7b907735ce77d4
page.title=Android NDK
@jd:body
diff --git a/docs/html/sdk/preview/start.jd b/docs/html/sdk/preview/start.jd
deleted file mode 100644
index d6e442e46bd9..000000000000
--- a/docs/html/sdk/preview/start.jd
+++ /dev/null
@@ -1,294 +0,0 @@
-page.title=Getting Started with the Android 3.0 Preview
-@jd:body
-
-<p>Welcome to Android 3.0!</p>
-
-<p>Android 3.0 is the next major release of the Android platform and is optimized for larger screen
-devices, particularly tablets. We're offering a preview SDK so you can get a head-start developing
-applications for it or simply test and optimize your existing application for upcoming devices.</p>
-
-<p><strong>Be aware that:</strong></p>
-<ul>
- <li>The APIs in the preview SDK are <strong>not final</strong>. Some APIs may change in behavior
-or availability when the final SDK is made available.</li>
- <li>You <strong>cannot</strong> publish an application that's built against the preview
-SDK&mdash;you can only run an application built against the preview SDK on the Android
-emulator.</li>
- <li>The documentation on <a href="http://developer.android.com">developer.android.com</a>
-does <strong>not</strong> include the Android 3.0 documentation&mdash;to read the API reference and
-developer guides for Android 3.0, you must install the Android 3.0 preview documentation from
-the AVD and SDK Manager.</li>
-</ul>
-
-
-
-<h3>How do I start?</h3>
-
-<ol>
- <li><a href="#Setup">Set up the preview SDK</a></li>
- <li>Then choose your app adventure:
- <ol type="a">
- <li><a href="#Optimize">Optimize Your App for Tablets and Similar Devices</a>
- <p>When you have an existing application and you want to maintain compatibility with
-older versions of Android.</p>
- </li>
- <li><a href="#Upgrade">Upgrade or Develop a New App for Tablets and Similar Devices</a>
- <p>When you want to upgrade your application to use APIs introduced in Android 3.0 or
- create a new application targeted to tablets and similar devices.</p></li>
- </ol>
- </li>
-</ol>
-
-<h3>Code samples</h3>
-<p>Many of the new features and APIs that are described in the <a href="{@docRoot}sdk/android-3.0.html#api">
-Android 3.0 Platform Preview</a> also have accompanying samples that help you understand how to use them.
-To get the samples, download them from the SDK repository using the Android SDK Manager. After download
-the samples are located in <code>&lt;sdk_root&gt;/samples/android-Honeycomb</code>. The list of links
-below helps you find samples for the features you are interested in:</p>
-<ul>
- <li><a href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a> -
- A demo application highlighting how to use some of the new APIs in Honeycomb, including fragments, the action bar,
- drag and drop, transition animations, and a stack widget.</li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#Fragment">Fragments</a>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ActionBarMechanics.html">Action Bar</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/content/ClipboardSample.html">Clipboard</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/DragAndDropDemo.html">Drag and Drop</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List15.html">
- Multiple-choice selection for ListView and GridView</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html">Content Loaders</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">Property Animation</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.html">Search View Widget</a></li>
- <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/PopupMenu1.html">Popup Menu Widget</a></li>
-</ul>
-
-
-<h2 id="Setup">Set Up the Preview SDK</h2>
-
-<p>To start using the Android 3.0 preview SDK, set up your existing Android SDK with the new
-platform:</p>
-<p>(If you don't have an existing SDK, <a href="{@docRoot}sdk/index.html">download it
-now</a>.)</p>
-<ol>
- <li><a href="{@docRoot}sdk/adding-components.html#launching">Launch the Android SDK and AVD
-Manager</a> and install the following:
- <ul>
- <li>SDK Platform Android 3.0 Preview</li>
- <li>Android SDK Tools, revision 9</li>
- <li>Documentation for Android 'Honeycomb' Preview</li>
- <li>Samples for SDK API Honeycomb Preview</li>
- </ul>
- </li>
- <li><a href="{@docRoot}guide/developing/other-ide.html#AVD">Create an AVD</a> for tablets: set
-the target to "Android 3.0 (Preview)" and the skin to "WXGA".</li>
-</ol>
-
-
-<h3>About emulator performance</h3>
-
-<p>Because the Android emulator must simulate the ARM instruction set architecture on your
-computer and the WXGA screen is significantly larger than what the emulator
-normally handles, emulator performance is much slower than usual.</p>
-
-<p>In particular, initializing the emulator can be slow and can take several
-minutes, depending on your hardware. When the emulator is booting there is
-limited user feedback, so please be patient and continue waiting until you see
-the home screen appear. </p>
-
-<p>Note that you do not need to do a full boot of your emulator each time you
-rebuild your application &mdash; typically you only need to boot at the start of
-a session. See the Tips section below for information about using Snapshots to
-cut startup time after first initialization. </p>
-
-<p>We're working hard to resolve the performance issues and it will improve in future releases.
-Unfortunately, the emulator will perform slowly during your trial with the preview SDK. For the time
-being, the emulator is still best way to evaluate your application's appearance and functionality on
-Android 3.0.</p>
-
-<p class="note"><strong>Tip:</strong> To improve the startup time for the emulator, enable
-snapshots for the AVD when you create it with the SDK and AVD Manager (there's a checkbox in
-the GUI). Then, start the AVD from the manager and check <b>Launch from snapshot</b> and <b>Save to
-snapshot</b>. This way, when you close the emulator, a snapshot of the AVD state is saved and
-used to quickly relaunch the AVD next time. However, when you choose to save a snapshot, the
-emulator will be slow to close, so you might want to enable <b>Save to
-snapshot</b> only for the first time you launch the AVD.</p>
-
-
-<h3>Known issues</h3>
-
-<p>The following known issues occur for Android 3.0 AVDs that are loaded in the emulator:</p>
- <ul>
- <li>You cannot take screenshots of an emulator screen. The Device Screen
- Capture window displays <strong>Screen not available</strong>.</li>
- <li>The emulator cannot receive incoming SMS messages.</li>
- <li>GPS emulation is currently not supported.</li>
- <li>When rotating the emulator screen by pressing Ctrl-F11, the screen turns green momentarily,
-then displays the normal interface.</li>
- <li>In some circumstances, the emulator displays a rotated portrait screen while in landscape
-mode. To view the screen correctly, rotate the emulator to portrait mode by pressing Ctrl-F11 or
-turn off the auto-rotate setting in <strong>Settings > Screen > Auto-rotate screen</strong>.</li>
- <li>The Dev Tools application sometimes crashes when trying to use the Package Browser
-feature.</li>
- <li>On Ubuntu 10.04 64-bit machines, you cannot create an AVD that has an SD card.</li>
- </ul>
-
-
-
-<h2 id="Optimize">Optimize Your Application for Tablets and Similar Devices</h2>
-
-<p>If you've already developed an application for Android, there are a few things you can do
-to optimize it for a tablet-style experience, without changing the minimum platform version required
-(you don't need to change the manifest {@code minSdkVersion}).</p>
-
-<p class="note"><strong>Note:</strong> All Android applications are forward-compatible, so
-there's nothing you <em>have to</em> do&mdash;if your application is a good citizen of the Android
-APIs, your app should work fine on devices running Android 3.0. However, in order to provide users
-a better experience when running your app on an Android 3.0 tablet or similar-size device, we
-recommend that you update your application to adapt to the new system theme and optimize your
-application for larger screens.</p>
-
-<p>Here's what you can do to optimize your application for tablets running Android
-3.0:</p>
-
-<ol>
- <li><b>Test your current application on Android 3.0</b>
- <ol>
- <li>Build your application as-is and install it on your WXGA AVD (created above).</li>
- <li>Perform your usual tests to be sure everything works and looks as expected.</li>
- </ol>
- </li>
-
- <li><b>Apply the new "holographic" theme to your application</b>
- <ol>
- <li>Open your manifest file and update the <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code &lt;uses-sdk&gt;}</a> element to
-set {@code android:targetSdkVersion} to {@code "Honeycomb"}. For example:
-<pre>
-&lt;manifest ... >
- &lt;uses-sdk android:minSdkVersion="4"
- android:targetSdkVersion="Honeycomb" /&gt;
- &lt;application ... >
- ...
- &lt;application>
-&lt;/manifest>
-</pre>
- <p class="note"><strong>Note:</strong> The API Level value "Honeycomb" is a provisional API
-Level that is valid only while testing against the preview SDK. You
-<strong>should not</strong> publish your application using this API Level. When the final version of
-the Android 3.0 SDK is made available, you must change this value to the real API Level that will be
-specified for Android 3.0. For more information, read about <a
-href="{@docRoot}guide/appendix/api-levels.html">Android API Levels</a>.</p>
- <p>By targeting the Android 3.0 platform, the system automatically applies the Holographic theme
-to each of your activities, when running on an Android 3.0 device.</p>
- </li>
- <li>Continue to build against your application's {@code minSdkVersion}, but install it
-on the Android 3.0 AVD. Perform more testing on your application to be sure that your user interface
-works well with the Holographic theme.
- <p class="note"><strong>Note:</strong> If you've applied themes to your activities already,
-they will override the Holographic theme that the system applies when you set the {@code
-android:targetSdkVersion} to {@code "Honeycomb"}.
-Once the Android 3.0 APIs are finalized and an official API Level is assigned, you can use
-the <a href="{@docRoot}guide/topics/resources/providing-resources.html#VersionQualifier">system
-version qualifier</a> to provide an alternative theme that's based on the Holographic theme when
-your application is running on Android 3.0.</p>
- </ol>
- </li>
-
- <li><b>Supply alternative layout resources for xlarge screens</b>
- <p>As discussed in the guide to <a
-href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>, Android
-2.3 and above support the <code>xlarge</code> resource qualifier, which you should use to supply
-alternative layouts for extra large screens.</p>
- <p>By providing alternative layouts for some of your activities when running on extra large
-screens, you can improve the user experience of your application on a tablet without using any
-new APIs.</p>
- <p>For example, here are some things to consider when creating a new layout for tables:</p>
- <ul>
- <li>Landscape layout: The "normal" orientation for tablets is usually landscape (wide), so
-you should be sure that your activities offer an appropriate layout for such a wide viewing
-area.</li>
- <li>Button position: Consider whether the position of the most common buttons in your UI are
-easily accessible while holding a tablet with two hands.</li>
- </ul>
- </li>
-</ol>
-
- <p>In general, always be sure that your application follows the <a
-href="{@docRoot}guide/practices/screens_support.html#screen-independence">Best Practices
-for Screen Independence</a>.</p>
-
-
-<h2 id="Upgrade">Upgrade or Develop a New App for Tablets and Similar Devices</h2>
-
-<p>If you want to develop something truly for tablet-type devices running Android 3.0, then you need
-to use new APIs available in Android 3.0. This section introduces some of the new features that you
-should use.</p>
-
-<p>The first thing to do when you create a project with the Android 3.0 preview is set the <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code &lt;uses-sdk&gt;}</a> element to
-use {@code "Honeycomb"} for the {@code android:minSdkVersion}. For example:</p>
-
-<pre>
-&lt;manifest ... >
- &lt;uses-sdk android:minSdkVersion="Honeycomb" /&gt;
- &lt;application ... >
- ...
- &lt;application>
-&lt;/manifest>
-</pre>
-
-<p class="note"><strong>Note:</strong> The API Level value "Honeycomb" is a provisional API
-Level that is valid only while building and testing against the preview SDK. You
-<strong>cannot</strong> publish your application using this API Level. When the final version of the
-Android 3.0 SDK is made available, you must change this value to the real API Level that is
-specified for Android 3.0. For more information, read about <a
-href="{@docRoot}guide/appendix/api-levels.html">Android API Levels</a>.</p>
-
-<p>Be sure that the <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code
-&lt;uses-sdk&gt;}</a> element appears <strong>before</strong> the <a
-href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
-element.</p>
-
-<p>By targeting the Android 3.0 platform (and declaring it before <a
-href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>),
-the system automatically applies the new Holographic theme to each of your
-activities.</p>
-
-
-
-<h3>Publishing your app for tablet-type devices only</h3>
-
-<p>Additionally, you should decide whether your application is for <em>only</em> tablet devices
-(specifically, <em>xlarge</em> devices) or for devices of all sizes that may run Android 3.0.</p>
-
-<p>If your application is <em>only</em> for tablets (<em>xlarge</em> screens; not for mobile
-devices/phones), then you should include the <a
-href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
-&lt;supports-screens&gt;}</a> element in your manifest with all sizes except for xlarge declared
-false. For example:</p>
-
-<pre>
-&lt;manifest ... >
- &lt;uses-sdk android:minSdkVersion="Honeycomb" /&gt;
- &lt;supports-screens android:smallScreens="false"
- android:normalScreens="false"
- android:largeScreens="false"
- android:xlargeScreens="true" /&gt;
- &lt;application ... >
- ...
- &lt;application>
-&lt;/manifest>
-</pre>
-
-<p>With this declaration, you indicate that your application does not support any screen size except
-extra large. External services such as Android Market may use this to filter your application
-from devices that do not have an extra large screen.</p>
-
-<p>Otherwise, if you want your application to be available to both small devices (phones) and large
-devices (tablets), do <em>not</em> include the <a
-href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
-&lt;supports-screens&gt;}</a> element.</p>
-
-<div class="special">
-<p>To learn more about some of the new APIs,
-see the <a href="{@docRoot}sdk/android-3.0.html">Android 3.0 Platform Preview</a> document.</p>
-</div>
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 1b94b2cc4d59..c1894d89c393 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -80,6 +80,7 @@ class="new">new!</span></li>
<div><a href="<?cs var:toroot ?>sdk/android-3.0.html">
<span class="en">Android 3.0 Platform</span></a> <span class="new">new!</span></div>
<ul>
+ <li><a href="<?cs var:toroot ?>sdk/android-3.0-optimize.html">Optimizing Apps for 3.0</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-3.0-highlights.html">Platform Highlights</a></li>
<li><a href="<?cs var:toroot ?>sdk/api_diff/11/changes.html">API Differences Report &raquo;</a></li>
</ul>
@@ -88,10 +89,17 @@ class="new">new!</span></li>
<div><a href="<?cs var:toroot ?>sdk/android-2.3.3.html">
<span class="en">Android 2.3.3 Platform</span></a> <span class="new">new!</span></div>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/android-2.3-highlights.html">Platform Highlights</a></li>
<li><a href="<?cs var:toroot ?>sdk/api_diff/10/changes.html">API Differences Report &raquo;</a></li>
</ul>
</li>
+ <li class="toggle-list">
+ <div><a href="<?cs var:toroot ?>sdk/android-2.3.html">
+ <span class="en">Android 2.3 Platform</span></a></div>
+ <ul>
+ <li><a href="<?cs var:toroot ?>sdk/android-2.3-highlights.html">Platform Highlights</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/api_diff/9/changes.html">API Differences Report &raquo;</a></li>
+ </ul>
+ </li>
<li><a href="<?cs var:toroot ?>sdk/android-2.2.html">Android 2.2 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-2.1.html">Android 2.1 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-1.6.html">Android 1.6 Platform</a></li>
@@ -99,13 +107,6 @@ class="new">new!</span></li>
<li class="toggle-list">
<div><a href="#" onclick="toggle(this.parentNode.parentNode,true); return false;">Older Platforms</a></div>
<ul>
- <li class="toggle-list">
- <div><a href="<?cs var:toroot ?>sdk/android-2.3.html">
- <span class="en">Android 2.3 Platform</span></a></div>
- <ul>
- <li><a href="<?cs var:toroot ?>sdk/api_diff/9/changes.html">API Differences Report &raquo;</a></li>
- </ul>
- </li>
<li><a href="<?cs var:toroot ?>sdk/android-2.0.1.html">Android 2.0.1 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-2.0.html">Android 2.0 Platform</a></li>
<li><a href="<?cs var:toroot ?>sdk/android-1.1.html">Android 1.1 Platform</a></li>
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index b35a6e6159c1..9e6f0e227792 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -59,12 +59,12 @@ private:
// After the initial mute, we raise the volume linearly
// over kAutoRampDurationUs.
- kAutoRampDurationUs = 700000,
+ kAutoRampDurationUs = 300000,
// This is the initial mute duration to suppress
// the video recording signal tone
- kAutoRampStartUs = 1000000,
- };
+ kAutoRampStartUs = 0,
+ };
Mutex mLock;
Condition mFrameAvailableCondition;
diff --git a/include/media/stagefright/foundation/ABitReader.h b/include/media/stagefright/foundation/ABitReader.h
index 513521106536..5510b12aee8c 100644
--- a/include/media/stagefright/foundation/ABitReader.h
+++ b/include/media/stagefright/foundation/ABitReader.h
@@ -31,6 +31,8 @@ struct ABitReader {
uint32_t getBits(size_t n);
void skipBits(size_t n);
+ void putBits(uint32_t x, size_t n);
+
size_t numBitsLeft() const;
const uint8_t *data() const;
@@ -43,7 +45,6 @@ private:
size_t mNumBitsLeft;
void fillReservoir();
- void putBits(uint32_t x, size_t n);
DISALLOW_EVIL_CONSTRUCTORS(ABitReader);
};
diff --git a/include/ui/Input.h b/include/ui/Input.h
index b7b5a8d93113..86ce09835f63 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -170,10 +170,10 @@ struct InputConfiguration {
* Pointer coordinate data.
*/
struct PointerCoords {
- static const size_t MAX_AXES = 15; // 15 so that sizeof(PointerCoords) == 16 * 4 == 64
+ enum { MAX_AXES = 14 }; // 14 so that sizeof(PointerCoords) == 64
// Bitfield of axes that are present in this structure.
- uint32_t bits; // 32bits are enough for now, can raise to 64bit when needed
+ uint64_t bits;
// Values of axes that are stored in this structure packed in order by axis id
// for each axis that is present in the structure according to 'bits'.
@@ -183,40 +183,9 @@ struct PointerCoords {
bits = 0;
}
- inline float getAxisValue(int32_t axis) const {
- uint32_t axisBit = 1 << axis;
- if (!(bits & axisBit)) {
- return 0;
- }
- uint32_t index = __builtin_popcount(bits & (axisBit - 1));
- return values[index];
- }
-
- inline void setAxisValue(int32_t axis, float value) {
- uint32_t axisBit = 1 << axis;
- uint32_t index = __builtin_popcount(bits & (axisBit - 1));
- if (!(bits & axisBit)) {
- uint32_t count = __builtin_popcount(bits);
- if (count >= MAX_AXES) {
- tooManyAxes(axis);
- return;
- }
- bits |= axisBit;
- for (uint32_t i = count; i > index; i--) {
- values[i] = values[i - 1];
- }
- }
- values[index] = value;
- }
-
- inline float* editAxisValue(int32_t axis) {
- uint32_t axisBit = 1 << axis;
- if (!(bits & axisBit)) {
- return NULL;
- }
- uint32_t index = __builtin_popcount(bits & (axisBit - 1));
- return &values[index];
- }
+ float getAxisValue(int32_t axis) const;
+ status_t setAxisValue(int32_t axis, float value);
+ float* editAxisValue(int32_t axis);
#ifdef HAVE_ANDROID_OS
status_t readFromParcel(Parcel* parcel);
@@ -351,49 +320,49 @@ public:
float getRawAxisValue(int32_t axis, size_t pointerIndex) const;
inline float getRawX(size_t pointerIndex) const {
- return getRawAxisValue(AINPUT_MOTION_AXIS_X, pointerIndex);
+ return getRawAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
}
inline float getRawY(size_t pointerIndex) const {
- return getRawAxisValue(AINPUT_MOTION_AXIS_Y, pointerIndex);
+ return getRawAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
}
float getAxisValue(int32_t axis, size_t pointerIndex) const;
inline float getX(size_t pointerIndex) const {
- return getAxisValue(AINPUT_MOTION_AXIS_X, pointerIndex);
+ return getAxisValue(AMOTION_EVENT_AXIS_X, pointerIndex);
}
inline float getY(size_t pointerIndex) const {
- return getAxisValue(AINPUT_MOTION_AXIS_Y, pointerIndex);
+ return getAxisValue(AMOTION_EVENT_AXIS_Y, pointerIndex);
}
inline float getPressure(size_t pointerIndex) const {
- return getAxisValue(AINPUT_MOTION_AXIS_PRESSURE, pointerIndex);
+ return getAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pointerIndex);
}
inline float getSize(size_t pointerIndex) const {
- return getAxisValue(AINPUT_MOTION_AXIS_SIZE, pointerIndex);
+ return getAxisValue(AMOTION_EVENT_AXIS_SIZE, pointerIndex);
}
inline float getTouchMajor(size_t pointerIndex) const {
- return getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MAJOR, pointerIndex);
+ return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex);
}
inline float getTouchMinor(size_t pointerIndex) const {
- return getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MINOR, pointerIndex);
+ return getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex);
}
inline float getToolMajor(size_t pointerIndex) const {
- return getAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR, pointerIndex);
+ return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex);
}
inline float getToolMinor(size_t pointerIndex) const {
- return getAxisValue(AINPUT_MOTION_AXIS_TOOL_MINOR, pointerIndex);
+ return getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex);
}
inline float getOrientation(size_t pointerIndex) const {
- return getAxisValue(AINPUT_MOTION_AXIS_ORIENTATION, pointerIndex);
+ return getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex);
}
inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; }
@@ -410,59 +379,59 @@ public:
inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const {
return getHistoricalRawAxisValue(
- AINPUT_MOTION_AXIS_X, pointerIndex, historicalIndex);
+ AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
}
inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const {
return getHistoricalRawAxisValue(
- AINPUT_MOTION_AXIS_Y, pointerIndex, historicalIndex);
+ AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
}
float getHistoricalAxisValue(int32_t axis, size_t pointerIndex, size_t historicalIndex) const;
inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const {
return getHistoricalAxisValue(
- AINPUT_MOTION_AXIS_X, pointerIndex, historicalIndex);
+ AMOTION_EVENT_AXIS_X, pointerIndex, historicalIndex);
}
inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const {
return getHistoricalAxisValue(
- AINPUT_MOTION_AXIS_Y, pointerIndex, historicalIndex);
+ AMOTION_EVENT_AXIS_Y, pointerIndex, historicalIndex);
}
inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const {
return getHistoricalAxisValue(
- AINPUT_MOTION_AXIS_PRESSURE, pointerIndex, historicalIndex);
+ AMOTION_EVENT_AXIS_PRESSURE, pointerIndex, historicalIndex);
}
inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const {
return getHistoricalAxisValue(
- AINPUT_MOTION_AXIS_SIZE, pointerIndex, historicalIndex);
+ AMOTION_EVENT_AXIS_SIZE, pointerIndex, historicalIndex);
}
inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const {
return getHistoricalAxisValue(
- AINPUT_MOTION_AXIS_TOUCH_MAJOR, pointerIndex, historicalIndex);
+ AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex, historicalIndex);
}
inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const {
return getHistoricalAxisValue(
- AINPUT_MOTION_AXIS_TOUCH_MINOR, pointerIndex, historicalIndex);
+ AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex, historicalIndex);
}
inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const {
return getHistoricalAxisValue(
- AINPUT_MOTION_AXIS_TOOL_MAJOR, pointerIndex, historicalIndex);
+ AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex, historicalIndex);
}
inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const {
return getHistoricalAxisValue(
- AINPUT_MOTION_AXIS_TOOL_MINOR, pointerIndex, historicalIndex);
+ AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex, historicalIndex);
}
inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const {
return getHistoricalAxisValue(
- AINPUT_MOTION_AXIS_ORIENTATION, pointerIndex, historicalIndex);
+ AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historicalIndex);
}
void initialize(
diff --git a/include/ui/KeyLayoutMap.h b/include/ui/KeyLayoutMap.h
index f0a6d001f2c8..904c8f305fc7 100644
--- a/include/ui/KeyLayoutMap.h
+++ b/include/ui/KeyLayoutMap.h
@@ -25,7 +25,7 @@
namespace android {
/**
- * Describes a mapping from keyboard scan codes to Android key codes.
+ * Describes a mapping from keyboard scan codes and joystick axes to Android key codes and axes.
*/
class KeyLayoutMap {
public:
@@ -33,8 +33,10 @@ public:
static status_t load(const String8& filename, KeyLayoutMap** outMap);
- status_t map(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const;
- status_t findScanCodes(int32_t keyCode, Vector<int32_t>* outScanCodes) const;
+ status_t mapKey(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const;
+ status_t findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const;
+
+ status_t mapAxis(int32_t scanCode, int32_t* axis) const;
private:
struct Key {
@@ -42,7 +44,8 @@ private:
uint32_t flags;
};
- KeyedVector<int32_t,Key> mKeys;
+ KeyedVector<int32_t, Key> mKeys;
+ KeyedVector<int32_t, int32_t> mAxes;
KeyLayoutMap();
@@ -57,6 +60,7 @@ private:
private:
status_t parseKey();
+ status_t parseAxis();
};
};
diff --git a/include/ui/Keyboard.h b/include/ui/Keyboard.h
index 50296e29baa8..54bc968e3c63 100644
--- a/include/ui/Keyboard.h
+++ b/include/ui/Keyboard.h
@@ -111,6 +111,18 @@ extern int32_t getKeyCodeByLabel(const char* label);
extern uint32_t getKeyFlagByLabel(const char* label);
/**
+ * Gets a axis by its short form label, eg. "X".
+ * Returns -1 if unknown.
+ */
+extern int32_t getAxisByLabel(const char* label);
+
+/**
+ * Gets a axis label by its id.
+ * Returns NULL if unknown.
+ */
+extern const char* getAxisLabel(int32_t axisId);
+
+/**
* Updates a meta state field when a key is pressed or released.
*/
extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState);
diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h
index dbccf29b110e..bdfbf7cace72 100755
--- a/include/ui/KeycodeLabels.h
+++ b/include/ui/KeycodeLabels.h
@@ -250,4 +250,47 @@ static const KeycodeLabel FLAGS[] = {
{ NULL, 0 }
};
+static const KeycodeLabel AXES[] = {
+ { "X", 0 },
+ { "Y", 1 },
+ { "PRESSURE", 2 },
+ { "SIZE", 3 },
+ { "TOUCH_MAJOR", 4 },
+ { "TOUCH_MINOR", 5 },
+ { "TOOL_MAJOR", 6 },
+ { "TOOL_MINOR", 7 },
+ { "ORIENTATION", 8 },
+ { "VSCROLL", 9 },
+ { "HSCROLL", 10 },
+ { "Z", 11 },
+ { "RX", 12 },
+ { "RY", 13 },
+ { "RZ", 14 },
+ { "HAT_X", 15 },
+ { "HAT_Y", 16 },
+ { "LTRIGGER", 17 },
+ { "RTRIGGER", 18 },
+ { "GENERIC_1", 32 },
+ { "GENERIC_2", 33 },
+ { "GENERIC_3", 34 },
+ { "GENERIC_4", 35 },
+ { "GENERIC_5", 36 },
+ { "GENERIC_6", 37 },
+ { "GENERIC_7", 38 },
+ { "GENERIC_8", 39 },
+ { "GENERIC_9", 40 },
+ { "GENERIC_10", 41 },
+ { "GENERIC_11", 42 },
+ { "GENERIC_12", 43 },
+ { "GENERIC_13", 44 },
+ { "GENERIC_14", 45 },
+ { "GENERIC_15", 46 },
+ { "GENERIC_16", 47 },
+
+ // NOTE: If you add a new axis here you must also add it to several other files.
+ // Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
+
+ { NULL, -1 }
+};
+
#endif // _UI_KEYCODE_LABELS_H
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 0042f496fac4..8bae684f18e6 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -316,6 +316,8 @@ FontRenderer::FontRenderer() {
mTextTexture = NULL;
mIndexBufferID = 0;
+ mPositionAttrSlot = -1;
+ mTexcoordAttrSlot = -1;
mCacheWidth = DEFAULT_TEXT_CACHE_WIDTH;
mCacheHeight = DEFAULT_TEXT_CACHE_HEIGHT;
@@ -565,13 +567,8 @@ void FontRenderer::issueDrawCommand() {
float* vtx = mTextMeshPtr;
float* tex = vtx + 3;
- // position is slot 0
- uint32_t slot = 0;
- glVertexAttribPointer(slot, 3, GL_FLOAT, false, 20, vtx);
-
- // texture0 is slot 1
- slot = 1;
- glVertexAttribPointer(slot, 2, GL_FLOAT, false, 20, tex);
+ glVertexAttribPointer(mPositionAttrSlot, 3, GL_FLOAT, false, 20, vtx);
+ glVertexAttribPointer(mTexcoordAttrSlot, 2, GL_FLOAT, false, 20, tex);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBufferID);
glDrawElements(GL_TRIANGLES, mCurrentQuadIndex * 6, GL_UNSIGNED_SHORT, NULL);
@@ -718,6 +715,11 @@ bool FontRenderer::renderText(SkPaint* paint, const Rect* clip, const char *text
return false;
}
+ if (mPositionAttrSlot < 0 || mTexcoordAttrSlot < 0) {
+ LOGE("Font renderer unable to draw, attribute slots undefined");
+ return false;
+ }
+
mDrawn = false;
mBounds = bounds;
mClip = clip;
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 10058125a8e1..46f332e54ee1 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -138,6 +138,11 @@ public:
mGammaTable = gammaTable;
}
+ void setAttributeBindingSlots(int positionSlot, int texCoordSlot) {
+ mPositionAttrSlot = positionSlot;
+ mTexcoordAttrSlot = texCoordSlot;
+ }
+
void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
bool renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
uint32_t len, int numGlyphs, int x, int y, Rect* bounds);
@@ -263,6 +268,9 @@ protected:
uint32_t mIndexBufferID;
+ int32_t mPositionAttrSlot;
+ int32_t mTexcoordAttrSlot;
+
const Rect* mClip;
Rect* mBounds;
bool mDrawn;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 68b54febf956..4a08f533df6f 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1585,8 +1585,12 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
#else
bool hasActiveLayer = false;
#endif
-
mCaches.unbindMeshBuffer();
+
+ // Tell font renderer the locations of position and texture coord
+ // attributes so it can bind its data properly
+ int positionSlot = mCaches.currentProgram->position;
+ fontRenderer.setAttributeBindingSlots(positionSlot, mTexCoordsSlot);
if (fontRenderer.renderText(paint, clip, text, 0, bytesCount, count, x, y,
hasActiveLayer ? &bounds : NULL)) {
#if RENDER_LAYERS_AS_REGIONS
diff --git a/libs/rs/java/Balls/_index.html b/libs/rs/java/Balls/_index.html
new file mode 100644
index 000000000000..87604854d3d1
--- /dev/null
+++ b/libs/rs/java/Balls/_index.html
@@ -0,0 +1 @@
+<p>A brute force physics simulation that renders many balls onto the screen and moves them according to user touch and gravity.</p> \ No newline at end of file
diff --git a/libs/rs/java/Fountain/_index.html b/libs/rs/java/Fountain/_index.html
new file mode 100644
index 000000000000..223242f73bc7
--- /dev/null
+++ b/libs/rs/java/Fountain/_index.html
@@ -0,0 +1,5 @@
+<p>An example that renders many dots on the screen that follow a user's touch. The dots fall
+to the bottom of the screen when the user releases the finger.</p>
+
+
+
diff --git a/libs/rs/java/HelloCompute/_index.html b/libs/rs/java/HelloCompute/_index.html
new file mode 100644
index 000000000000..abfd9784a958
--- /dev/null
+++ b/libs/rs/java/HelloCompute/_index.html
@@ -0,0 +1,2 @@
+<p>A Renderscript compute sample that filters a bitmap. No Renderscript graphics APIs are used
+in this sample.</p> \ No newline at end of file
diff --git a/libs/rs/java/HelloWorld/_index.html b/libs/rs/java/HelloWorld/_index.html
new file mode 100644
index 000000000000..4cab73817684
--- /dev/null
+++ b/libs/rs/java/HelloWorld/_index.html
@@ -0,0 +1 @@
+<p>A Renderscript graphics application that draws the text "Hello, World!" where the user touches.</p> \ No newline at end of file
diff --git a/libs/rs/java/ImageProcessing/res/layout/main.xml b/libs/rs/java/ImageProcessing/res/layout/main.xml
deleted file mode 100644
index c6ec729652aa..000000000000
--- a/libs/rs/java/ImageProcessing/res/layout/main.xml
+++ /dev/null
@@ -1,187 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-
- <SurfaceView
- android:id="@+id/surface"
- android:layout_width="1dip"
- android:layout_height="1dip" />
-
- <ImageView
- android:id="@+id/display"
- android:layout_width="320dip"
- android:layout_height="266dip" />
-
- <Button
- android:layout_marginBottom="170dip"
- android:layout_width="wrap_content"
- android:layout_height="40dip"
- android:text="@string/benchmark"
- android:onClick="benchmark"
- android:layout_gravity="bottom"/>
-
- <TextView
- android:id="@+id/benchmarkText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="100dip"
- android:layout_marginBottom="175dip"
- android:layout_gravity="bottom"
- android:text="@string/saturation"/>
-
- <SeekBar
- android:id="@+id/inSaturation"
- android:layout_marginBottom="140dip"
- android:layout_marginLeft="10dip"
- android:layout_marginRight="10dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <TextView
- android:id="@+id/inSaturationText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="50dip"
- android:layout_marginBottom="142dip"
- android:textColor="#000"
- android:layout_gravity="bottom"
- android:text="@string/saturation"/>
-
- <SeekBar
- android:id="@+id/inGamma"
- android:layout_marginBottom="110dip"
- android:layout_marginLeft="10dip"
- android:layout_marginRight="10dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <TextView
- android:id="@+id/inGammaText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="50dip"
- android:layout_marginBottom="112dip"
- android:textColor="#000"
- android:layout_gravity="bottom"
- android:text="@string/gamma"/>
-
- <SeekBar
- android:id="@+id/outWhite"
- android:layout_marginBottom="80dip"
- android:layout_marginLeft="170dip"
- android:layout_marginRight="10dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <TextView
- android:id="@+id/outWhiteText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="220dip"
- android:layout_marginBottom="82dip"
- android:textColor="#000"
- android:layout_gravity="bottom"
- android:text="@string/out_white"/>
-
- <SeekBar
- android:id="@+id/inWhite"
- android:layout_marginBottom="80dip"
- android:layout_marginLeft="10dip"
- android:layout_marginRight="170dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <TextView
- android:id="@+id/inWhiteText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="50dip"
- android:layout_marginBottom="82dip"
- android:textColor="#000"
- android:layout_gravity="bottom"
- android:text="@string/in_white"/>
-
- <SeekBar
- android:id="@+id/outBlack"
- android:layout_marginBottom="50dip"
- android:layout_marginLeft="170dip"
- android:layout_marginRight="10dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <TextView
- android:id="@+id/outBlackText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="220dip"
- android:layout_marginBottom="52dip"
- android:textColor="#000"
- android:layout_gravity="bottom"
- android:text="@string/out_black"/>
-
- <SeekBar
- android:id="@+id/inBlack"
- android:layout_marginBottom="50dip"
- android:layout_marginLeft="10dip"
- android:layout_marginRight="170dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <TextView
- android:id="@+id/inBlackText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="50dip"
- android:layout_marginBottom="52dip"
- android:textColor="#000"
- android:layout_gravity="bottom"
- android:text="@string/in_black"/>
-
- <SeekBar
- android:id="@+id/radius"
- android:layout_marginBottom="10dip"
- android:layout_marginLeft="10dip"
- android:layout_marginRight="10dip"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <TextView
- android:id="@+id/blurText"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="18sp"
- android:layout_marginLeft="50dip"
- android:layout_marginBottom="12dip"
- android:textColor="#000"
- android:layout_gravity="bottom"
- android:text="@string/blur_description"/>
-
-</merge> \ No newline at end of file
diff --git a/libs/rs/java/Samples/AndroidManifest.xml b/libs/rs/java/Samples/AndroidManifest.xml
index 8dad1612e163..c08a264de070 100644
--- a/libs/rs/java/Samples/AndroidManifest.xml
+++ b/libs/rs/java/Samples/AndroidManifest.xml
@@ -21,14 +21,5 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
-
- <activity android:name="RsBench"
- android:label="RsBenchmark"
- android:theme="@android:style/Theme.Black.NoTitleBar">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
</application>
</manifest>
diff --git a/libs/rs/java/Samples/_index.html b/libs/rs/java/Samples/_index.html
new file mode 100644
index 000000000000..5872431420e6
--- /dev/null
+++ b/libs/rs/java/Samples/_index.html
@@ -0,0 +1 @@
+<p>A set of samples that demonstrate how to use various features of the Renderscript APIs.</p> \ No newline at end of file
diff --git a/libs/rs/java/_index.html b/libs/rs/java/_index.html
new file mode 100644
index 000000000000..5872431420e6
--- /dev/null
+++ b/libs/rs/java/_index.html
@@ -0,0 +1 @@
+<p>A set of samples that demonstrate how to use various features of the Renderscript APIs.</p> \ No newline at end of file
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index 90b954e03762..a80320e475eb 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -250,11 +250,59 @@ void KeyEvent::initialize(const KeyEvent& from) {
// --- PointerCoords ---
+float PointerCoords::getAxisValue(int32_t axis) const {
+ if (axis < 0 || axis > 63) {
+ return 0;
+ }
+
+ uint64_t axisBit = 1LL << axis;
+ if (!(bits & axisBit)) {
+ return 0;
+ }
+ uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
+ return values[index];
+}
+
+status_t PointerCoords::setAxisValue(int32_t axis, float value) {
+ if (axis < 0 || axis > 63) {
+ return NAME_NOT_FOUND;
+ }
+
+ uint64_t axisBit = 1LL << axis;
+ uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
+ if (!(bits & axisBit)) {
+ uint32_t count = __builtin_popcountll(bits);
+ if (count >= MAX_AXES) {
+ tooManyAxes(axis);
+ return NO_MEMORY;
+ }
+ bits |= axisBit;
+ for (uint32_t i = count; i > index; i--) {
+ values[i] = values[i - 1];
+ }
+ }
+ values[index] = value;
+ return OK;
+}
+
+float* PointerCoords::editAxisValue(int32_t axis) {
+ if (axis < 0 || axis > 63) {
+ return NULL;
+ }
+
+ uint64_t axisBit = 1LL << axis;
+ if (!(bits & axisBit)) {
+ return NULL;
+ }
+ uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
+ return &values[index];
+}
+
#ifdef HAVE_ANDROID_OS
status_t PointerCoords::readFromParcel(Parcel* parcel) {
- bits = parcel->readInt32();
+ bits = parcel->readInt64();
- uint32_t count = __builtin_popcount(bits);
+ uint32_t count = __builtin_popcountll(bits);
if (count > MAX_AXES) {
return BAD_VALUE;
}
@@ -266,9 +314,9 @@ status_t PointerCoords::readFromParcel(Parcel* parcel) {
}
status_t PointerCoords::writeToParcel(Parcel* parcel) const {
- parcel->writeInt32(bits);
+ parcel->writeInt64(bits);
- uint32_t count = __builtin_popcount(bits);
+ uint32_t count = __builtin_popcountll(bits);
for (uint32_t i = 0; i < count; i++) {
parcel->writeInt32(values[i]);
}
@@ -362,10 +410,10 @@ float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
switch (axis) {
- case AINPUT_MOTION_AXIS_X:
+ case AMOTION_EVENT_AXIS_X:
value += mXOffset;
break;
- case AINPUT_MOTION_AXIS_Y:
+ case AMOTION_EVENT_AXIS_Y:
value += mYOffset;
break;
}
@@ -386,10 +434,10 @@ float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
size_t historicalIndex) const {
float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
switch (axis) {
- case AINPUT_MOTION_AXIS_X:
+ case AMOTION_EVENT_AXIS_X:
value += mXOffset;
break;
- case AINPUT_MOTION_AXIS_Y:
+ case AMOTION_EVENT_AXIS_Y:
value += mYOffset;
break;
}
@@ -419,12 +467,12 @@ void MotionEvent::scale(float scaleFactor) {
PointerCoords& c = mSamplePointerCoords.editItemAt(i);
// No need to scale pressure or size since they are normalized.
// No need to scale orientation since it is meaningless to do so.
- scaleAxisValue(c, AINPUT_MOTION_AXIS_X, scaleFactor);
- scaleAxisValue(c, AINPUT_MOTION_AXIS_Y, scaleFactor);
- scaleAxisValue(c, AINPUT_MOTION_AXIS_TOUCH_MAJOR, scaleFactor);
- scaleAxisValue(c, AINPUT_MOTION_AXIS_TOUCH_MINOR, scaleFactor);
- scaleAxisValue(c, AINPUT_MOTION_AXIS_TOOL_MAJOR, scaleFactor);
- scaleAxisValue(c, AINPUT_MOTION_AXIS_TOOL_MINOR, scaleFactor);
+ scaleAxisValue(c, AMOTION_EVENT_AXIS_X, scaleFactor);
+ scaleAxisValue(c, AMOTION_EVENT_AXIS_Y, scaleFactor);
+ scaleAxisValue(c, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
+ scaleAxisValue(c, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
+ scaleAxisValue(c, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
+ scaleAxisValue(c, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
}
}
@@ -471,8 +519,8 @@ void MotionEvent::transform(const SkMatrix* matrix) {
size_t numSamples = mSamplePointerCoords.size();
for (size_t i = 0; i < numSamples; i++) {
PointerCoords& c = mSamplePointerCoords.editItemAt(i);
- float* xPtr = c.editAxisValue(AINPUT_MOTION_AXIS_X);
- float* yPtr = c.editAxisValue(AINPUT_MOTION_AXIS_Y);
+ float* xPtr = c.editAxisValue(AMOTION_EVENT_AXIS_X);
+ float* yPtr = c.editAxisValue(AMOTION_EVENT_AXIS_Y);
if (xPtr && yPtr) {
float x = *xPtr + oldXOffset;
float y = *yPtr + oldYOffset;
@@ -481,7 +529,7 @@ void MotionEvent::transform(const SkMatrix* matrix) {
*yPtr = SkScalarToFloat(point.fY) - newYOffset;
}
- float* orientationPtr = c.editAxisValue(AINPUT_MOTION_AXIS_ORIENTATION);
+ float* orientationPtr = c.editAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
if (orientationPtr) {
*orientationPtr = transformAngle(matrix, *orientationPtr);
}
@@ -523,7 +571,7 @@ status_t MotionEvent::readFromParcel(Parcel* parcel) {
for (size_t i = 0; i < pointerCount; i++) {
mSamplePointerCoords.push();
status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
- if (!status) {
+ if (status) {
return status;
}
}
@@ -559,7 +607,7 @@ status_t MotionEvent::writeToParcel(Parcel* parcel) const {
parcel->writeInt64(mSampleEventTimes.itemAt(h));
for (size_t i = 0; i < pointerCount; i++) {
status_t status = (pc++)->writeToParcel(parcel);
- if (!status) {
+ if (status) {
return status;
}
}
diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp
index 83d955682ad6..5c57a76f40f4 100644
--- a/libs/ui/InputTransport.cpp
+++ b/libs/ui/InputTransport.cpp
@@ -412,7 +412,8 @@ status_t InputPublisher::publishMotionEvent(
// Cache essential information about the motion event to ensure that a malicious consumer
// cannot confuse the publisher by modifying the contents of the shared memory buffer while
// it is being updated.
- if (action == AMOTION_EVENT_ACTION_MOVE) {
+ if (action == AMOTION_EVENT_ACTION_MOVE
+ || action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
mMotionEventPointerCount = pointerCount;
mMotionEventSampleDataStride = InputMessage::sampleDataStride(pointerCount);
mMotionEventSampleDataTail = InputMessage::sampleDataPtrIncrement(
diff --git a/libs/ui/KeyLayoutMap.cpp b/libs/ui/KeyLayoutMap.cpp
index 56bc26fd6d73..2ed0e66e1c1c 100644
--- a/libs/ui/KeyLayoutMap.cpp
+++ b/libs/ui/KeyLayoutMap.cpp
@@ -82,11 +82,11 @@ status_t KeyLayoutMap::load(const String8& filename, KeyLayoutMap** outMap) {
return status;
}
-status_t KeyLayoutMap::map(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const {
+status_t KeyLayoutMap::mapKey(int32_t scanCode, int32_t* keyCode, uint32_t* flags) const {
ssize_t index = mKeys.indexOfKey(scanCode);
if (index < 0) {
#if DEBUG_MAPPING
- LOGD("map: scanCode=%d ~ Failed.", scanCode);
+ LOGD("mapKey: scanCode=%d ~ Failed.", scanCode);
#endif
*keyCode = AKEYCODE_UNKNOWN;
*flags = 0;
@@ -98,12 +98,12 @@ status_t KeyLayoutMap::map(int32_t scanCode, int32_t* keyCode, uint32_t* flags)
*flags = k.flags;
#if DEBUG_MAPPING
- LOGD("map: scanCode=%d ~ Result keyCode=%d, flags=0x%08x.", scanCode, *keyCode, *flags);
+ LOGD("mapKey: scanCode=%d ~ Result keyCode=%d, flags=0x%08x.", scanCode, *keyCode, *flags);
#endif
return NO_ERROR;
}
-status_t KeyLayoutMap::findScanCodes(int32_t keyCode, Vector<int32_t>* outScanCodes) const {
+status_t KeyLayoutMap::findScanCodesForKey(int32_t keyCode, Vector<int32_t>* outScanCodes) const {
const size_t N = mKeys.size();
for (size_t i=0; i<N; i++) {
if (mKeys.valueAt(i).keyCode == keyCode) {
@@ -113,6 +113,25 @@ status_t KeyLayoutMap::findScanCodes(int32_t keyCode, Vector<int32_t>* outScanCo
return NO_ERROR;
}
+status_t KeyLayoutMap::mapAxis(int32_t scanCode, int32_t* axis) const {
+ ssize_t index = mAxes.indexOfKey(scanCode);
+ if (index < 0) {
+#if DEBUG_MAPPING
+ LOGD("mapAxis: scanCode=%d ~ Failed.", scanCode);
+#endif
+ *axis = -1;
+ return NAME_NOT_FOUND;
+ }
+
+ *axis = mAxes.valueAt(index);
+
+#if DEBUG_MAPPING
+ LOGD("mapAxis: scanCode=%d ~ Result axis=%d.", scanCode, *axis);
+#endif
+ return NO_ERROR;
+}
+
+
// --- KeyLayoutMap::Parser ---
KeyLayoutMap::Parser::Parser(KeyLayoutMap* map, Tokenizer* tokenizer) :
@@ -137,6 +156,10 @@ status_t KeyLayoutMap::Parser::parse() {
mTokenizer->skipDelimiters(WHITESPACE);
status_t status = parseKey();
if (status) return status;
+ } else if (keywordToken == "axis") {
+ mTokenizer->skipDelimiters(WHITESPACE);
+ status_t status = parseAxis();
+ if (status) return status;
} else {
LOGE("%s: Expected keyword, got '%s'.", mTokenizer->getLocation().string(),
keywordToken.string());
@@ -162,12 +185,12 @@ status_t KeyLayoutMap::Parser::parseKey() {
char* end;
int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
if (*end) {
- LOGE("%s: Expected scan code number, got '%s'.", mTokenizer->getLocation().string(),
+ LOGE("%s: Expected key scan code number, got '%s'.", mTokenizer->getLocation().string(),
scanCodeToken.string());
return BAD_VALUE;
}
if (mMap->mKeys.indexOfKey(scanCode) >= 0) {
- LOGE("%s: Duplicate entry for scan code '%s'.", mTokenizer->getLocation().string(),
+ LOGE("%s: Duplicate entry for key scan code '%s'.", mTokenizer->getLocation().string(),
scanCodeToken.string());
return BAD_VALUE;
}
@@ -189,12 +212,12 @@ status_t KeyLayoutMap::Parser::parseKey() {
String8 flagToken = mTokenizer->nextToken(WHITESPACE);
uint32_t flag = getKeyFlagByLabel(flagToken.string());
if (!flag) {
- LOGE("%s: Expected flag label, got '%s'.", mTokenizer->getLocation().string(),
+ LOGE("%s: Expected key flag label, got '%s'.", mTokenizer->getLocation().string(),
flagToken.string());
return BAD_VALUE;
}
if (flags & flag) {
- LOGE("%s: Duplicate flag '%s'.", mTokenizer->getLocation().string(),
+ LOGE("%s: Duplicate key flag '%s'.", mTokenizer->getLocation().string(),
flagToken.string());
return BAD_VALUE;
}
@@ -211,4 +234,35 @@ status_t KeyLayoutMap::Parser::parseKey() {
return NO_ERROR;
}
+status_t KeyLayoutMap::Parser::parseAxis() {
+ String8 scanCodeToken = mTokenizer->nextToken(WHITESPACE);
+ char* end;
+ int32_t scanCode = int32_t(strtol(scanCodeToken.string(), &end, 0));
+ if (*end) {
+ LOGE("%s: Expected axis scan code number, got '%s'.", mTokenizer->getLocation().string(),
+ scanCodeToken.string());
+ return BAD_VALUE;
+ }
+ if (mMap->mAxes.indexOfKey(scanCode) >= 0) {
+ LOGE("%s: Duplicate entry for axis scan code '%s'.", mTokenizer->getLocation().string(),
+ scanCodeToken.string());
+ return BAD_VALUE;
+ }
+
+ mTokenizer->skipDelimiters(WHITESPACE);
+ String8 axisToken = mTokenizer->nextToken(WHITESPACE);
+ int32_t axis = getAxisByLabel(axisToken.string());
+ if (axis < 0) {
+ LOGE("%s: Expected axis label, got '%s'.", mTokenizer->getLocation().string(),
+ axisToken.string());
+ return BAD_VALUE;
+ }
+
+#if DEBUG_PARSER
+ LOGD("Parsed axis: scanCode=%d, axis=%d.", scanCode, axis);
+#endif
+ mMap->mAxes.add(scanCode, axis);
+ return NO_ERROR;
+}
+
};
diff --git a/libs/ui/Keyboard.cpp b/libs/ui/Keyboard.cpp
index 6faa600e6e3a..8b6300a1ee70 100644
--- a/libs/ui/Keyboard.cpp
+++ b/libs/ui/Keyboard.cpp
@@ -217,7 +217,7 @@ status_t getKeyCharacterMapFile(int32_t deviceId, String8& outKeyCharacterMapFil
return NAME_NOT_FOUND;
}
-static int lookupLabel(const char* literal, const KeycodeLabel *list) {
+static int lookupValueByLabel(const char* literal, const KeycodeLabel *list) {
while (list->literal) {
if (strcmp(literal, list->literal) == 0) {
return list->value;
@@ -227,12 +227,30 @@ static int lookupLabel(const char* literal, const KeycodeLabel *list) {
return list->value;
}
+static const char* lookupLabelByValue(int value, const KeycodeLabel *list) {
+ while (list->literal) {
+ if (list->value == value) {
+ return list->literal;
+ }
+ list++;
+ }
+ return NULL;
+}
+
int32_t getKeyCodeByLabel(const char* label) {
- return int32_t(lookupLabel(label, KEYCODES));
+ return int32_t(lookupValueByLabel(label, KEYCODES));
}
uint32_t getKeyFlagByLabel(const char* label) {
- return uint32_t(lookupLabel(label, FLAGS));
+ return uint32_t(lookupValueByLabel(label, FLAGS));
+}
+
+int32_t getAxisByLabel(const char* label) {
+ return int32_t(lookupValueByLabel(label, AXES));
+}
+
+const char* getAxisLabel(int32_t axisId) {
+ return lookupLabelByValue(axisId, AXES);
}
static int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaState) {
diff --git a/libs/ui/tests/Android.mk b/libs/ui/tests/Android.mk
index 580d73cf384c..e23197185c85 100644
--- a/libs/ui/tests/Android.mk
+++ b/libs/ui/tests/Android.mk
@@ -7,6 +7,7 @@ ifneq ($(TARGET_SIMULATOR),true)
# Build the unit tests.
test_src_files := \
InputChannel_test.cpp \
+ InputEvent_test.cpp \
InputPublisherAndConsumer_test.cpp
shared_libraries := \
@@ -18,7 +19,8 @@ shared_libraries := \
libhardware \
libhardware_legacy \
libui \
- libstlport
+ libstlport \
+ libskia
static_libraries := \
libgtest \
@@ -28,7 +30,8 @@ c_includes := \
bionic \
bionic/libstdc++/include \
external/gtest/include \
- external/stlport/stlport
+ external/stlport/stlport \
+ external/skia/include/core
module_tags := eng tests
diff --git a/libs/ui/tests/InputChannel_test.cpp b/libs/ui/tests/InputChannel_test.cpp
index 6cec1c02ea95..eff22ee5f0eb 100644
--- a/libs/ui/tests/InputChannel_test.cpp
+++ b/libs/ui/tests/InputChannel_test.cpp
@@ -1,6 +1,18 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
+/*
+ * 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.
+ */
#include <ui/InputTransport.h>
#include <utils/Timers.h>
diff --git a/libs/ui/tests/InputEvent_test.cpp b/libs/ui/tests/InputEvent_test.cpp
new file mode 100644
index 000000000000..b77489e1586f
--- /dev/null
+++ b/libs/ui/tests/InputEvent_test.cpp
@@ -0,0 +1,582 @@
+/*
+ * 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.
+ */
+
+#include <ui/Input.h>
+#include <gtest/gtest.h>
+#include <binder/Parcel.h>
+
+#include <math.h>
+#include <SkMatrix.h>
+
+namespace android {
+
+class BaseTest : public testing::Test {
+protected:
+ virtual void SetUp() { }
+ virtual void TearDown() { }
+};
+
+// --- PointerCoordsTest ---
+
+class PointerCoordsTest : public BaseTest {
+};
+
+TEST_F(PointerCoordsTest, ClearSetsBitsToZero) {
+ PointerCoords coords;
+ coords.clear();
+
+ ASSERT_EQ(0ULL, coords.bits);
+}
+
+TEST_F(PointerCoordsTest, AxisValues) {
+ float* valuePtr;
+ PointerCoords coords;
+ coords.clear();
+
+ // Check invariants when no axes are present.
+ ASSERT_EQ(0, coords.getAxisValue(0))
+ << "getAxisValue should return zero because axis is not present";
+ ASSERT_EQ(0, coords.getAxisValue(1))
+ << "getAxisValue should return zero because axis is not present";
+
+ ASSERT_EQ(NULL, coords.editAxisValue(0))
+ << "editAxisValue should return null because axis is not present";
+
+ // Set first axis.
+ ASSERT_EQ(OK, coords.setAxisValue(1, 5));
+ ASSERT_EQ(0x00000002ULL, coords.bits);
+ ASSERT_EQ(5, coords.values[0]);
+
+ ASSERT_EQ(0, coords.getAxisValue(0))
+ << "getAxisValue should return zero because axis is not present";
+ ASSERT_EQ(5, coords.getAxisValue(1))
+ << "getAxisValue should return value of axis";
+
+ // Set an axis with a higher id than all others. (appending value at the end)
+ ASSERT_EQ(OK, coords.setAxisValue(3, 2));
+ ASSERT_EQ(0x0000000aULL, coords.bits);
+ ASSERT_EQ(5, coords.values[0]);
+ ASSERT_EQ(2, coords.values[1]);
+
+ ASSERT_EQ(0, coords.getAxisValue(0))
+ << "getAxisValue should return zero because axis is not present";
+ ASSERT_EQ(5, coords.getAxisValue(1))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(0, coords.getAxisValue(2))
+ << "getAxisValue should return zero because axis is not present";
+ ASSERT_EQ(2, coords.getAxisValue(3))
+ << "getAxisValue should return value of axis";
+
+ // Set an axis with an id lower than all others. (prepending value at beginning)
+ ASSERT_EQ(OK, coords.setAxisValue(0, 4));
+ ASSERT_EQ(0x0000000bULL, coords.bits);
+ ASSERT_EQ(4, coords.values[0]);
+ ASSERT_EQ(5, coords.values[1]);
+ ASSERT_EQ(2, coords.values[2]);
+
+ ASSERT_EQ(4, coords.getAxisValue(0))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(5, coords.getAxisValue(1))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(0, coords.getAxisValue(2))
+ << "getAxisValue should return zero because axis is not present";
+ ASSERT_EQ(2, coords.getAxisValue(3))
+ << "getAxisValue should return value of axis";
+
+ // Edit an existing axis value in place.
+ valuePtr = coords.editAxisValue(1);
+ ASSERT_EQ(5, *valuePtr)
+ << "editAxisValue should return pointer to axis value";
+
+ *valuePtr = 7;
+ ASSERT_EQ(7, coords.getAxisValue(1))
+ << "getAxisValue should return value of axis";
+
+ // Set an axis with an id between the others. (inserting value in the middle)
+ ASSERT_EQ(OK, coords.setAxisValue(2, 1));
+ ASSERT_EQ(0x0000000fULL, coords.bits);
+ ASSERT_EQ(4, coords.values[0]);
+ ASSERT_EQ(7, coords.values[1]);
+ ASSERT_EQ(1, coords.values[2]);
+ ASSERT_EQ(2, coords.values[3]);
+
+ ASSERT_EQ(4, coords.getAxisValue(0))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(7, coords.getAxisValue(1))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(1, coords.getAxisValue(2))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(2, coords.getAxisValue(3))
+ << "getAxisValue should return value of axis";
+
+ // Set an existing axis value in place.
+ ASSERT_EQ(OK, coords.setAxisValue(1, 6));
+ ASSERT_EQ(0x0000000fULL, coords.bits);
+ ASSERT_EQ(4, coords.values[0]);
+ ASSERT_EQ(6, coords.values[1]);
+ ASSERT_EQ(1, coords.values[2]);
+ ASSERT_EQ(2, coords.values[3]);
+
+ ASSERT_EQ(4, coords.getAxisValue(0))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(6, coords.getAxisValue(1))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(1, coords.getAxisValue(2))
+ << "getAxisValue should return value of axis";
+ ASSERT_EQ(2, coords.getAxisValue(3))
+ << "getAxisValue should return value of axis";
+
+ // Set maximum number of axes.
+ for (size_t axis = 4; axis < PointerCoords::MAX_AXES; axis++) {
+ ASSERT_EQ(OK, coords.setAxisValue(axis, axis));
+ }
+ ASSERT_EQ(PointerCoords::MAX_AXES, __builtin_popcountll(coords.bits));
+
+ // Try to set one more axis beyond maximum number.
+ // Ensure bits are unchanged.
+ ASSERT_EQ(NO_MEMORY, coords.setAxisValue(PointerCoords::MAX_AXES, 100));
+ ASSERT_EQ(PointerCoords::MAX_AXES, __builtin_popcountll(coords.bits));
+}
+
+TEST_F(PointerCoordsTest, Parcel) {
+ Parcel parcel;
+
+ PointerCoords inCoords;
+ inCoords.clear();
+ PointerCoords outCoords;
+
+ // Round trip with empty coords.
+ inCoords.writeToParcel(&parcel);
+ parcel.setDataPosition(0);
+ outCoords.readFromParcel(&parcel);
+
+ ASSERT_EQ(0ULL, outCoords.bits);
+
+ // Round trip with some values.
+ parcel.freeData();
+ inCoords.setAxisValue(2, 5);
+ inCoords.setAxisValue(5, 8);
+
+ inCoords.writeToParcel(&parcel);
+ parcel.setDataPosition(0);
+ outCoords.readFromParcel(&parcel);
+
+ ASSERT_EQ(outCoords.bits, inCoords.bits);
+ ASSERT_EQ(outCoords.values[0], inCoords.values[0]);
+ ASSERT_EQ(outCoords.values[1], inCoords.values[1]);
+}
+
+
+// --- KeyEventTest ---
+
+class KeyEventTest : public BaseTest {
+};
+
+TEST_F(KeyEventTest, Properties) {
+ KeyEvent event;
+
+ // Initialize and get properties.
+ const nsecs_t ARBITRARY_DOWN_TIME = 1;
+ const nsecs_t ARBITRARY_EVENT_TIME = 2;
+ event.initialize(2, AINPUT_SOURCE_GAMEPAD, AKEY_EVENT_ACTION_DOWN,
+ AKEY_EVENT_FLAG_FROM_SYSTEM, AKEYCODE_BUTTON_X, 121,
+ AMETA_ALT_ON, 1, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME);
+
+ ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event.getType());
+ ASSERT_EQ(2, event.getDeviceId());
+ ASSERT_EQ(AINPUT_SOURCE_GAMEPAD, event.getSource());
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, event.getAction());
+ ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, event.getFlags());
+ ASSERT_EQ(AKEYCODE_BUTTON_X, event.getKeyCode());
+ ASSERT_EQ(121, event.getScanCode());
+ ASSERT_EQ(AMETA_ALT_ON, event.getMetaState());
+ ASSERT_EQ(1, event.getRepeatCount());
+ ASSERT_EQ(ARBITRARY_DOWN_TIME, event.getDownTime());
+ ASSERT_EQ(ARBITRARY_EVENT_TIME, event.getEventTime());
+
+ // Set source.
+ event.setSource(AINPUT_SOURCE_JOYSTICK);
+ ASSERT_EQ(AINPUT_SOURCE_JOYSTICK, event.getSource());
+}
+
+
+// --- MotionEventTest ---
+
+class MotionEventTest : public BaseTest {
+protected:
+ static const nsecs_t ARBITRARY_DOWN_TIME;
+ static const nsecs_t ARBITRARY_EVENT_TIME;
+ static const float X_OFFSET;
+ static const float Y_OFFSET;
+
+ void initializeEventWithHistory(MotionEvent* event);
+ void assertEqualsEventWithHistory(const MotionEvent* event);
+};
+
+const nsecs_t MotionEventTest::ARBITRARY_DOWN_TIME = 1;
+const nsecs_t MotionEventTest::ARBITRARY_EVENT_TIME = 2;
+const float MotionEventTest::X_OFFSET = 1.0f;
+const float MotionEventTest::Y_OFFSET = 1.1f;
+
+void MotionEventTest::initializeEventWithHistory(MotionEvent* event) {
+ int32_t pointerIds[] = { 1, 2 };
+ PointerCoords pointerCoords[2];
+ pointerCoords[0].clear();
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 10);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 11);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 12);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 13);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 14);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 15);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 16);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 17);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 18);
+ pointerCoords[1].clear();
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 20);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 21);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 22);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 23);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 24);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 25);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 26);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 27);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 28);
+ event->initialize(2, AINPUT_SOURCE_TOUCHSCREEN, AMOTION_EVENT_ACTION_MOVE,
+ AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED,
+ AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON,
+ X_OFFSET, Y_OFFSET, 2.0f, 2.1f,
+ ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME,
+ 2, pointerIds, pointerCoords);
+
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 110);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 111);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 112);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 113);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 114);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 115);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 116);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 117);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 118);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 120);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 121);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 122);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 123);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 124);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 125);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 126);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 127);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 128);
+ event->addSample(ARBITRARY_EVENT_TIME + 1, pointerCoords);
+
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 210);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 211);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 212);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 213);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 214);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 215);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 216);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 217);
+ pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 218);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_X, 220);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_Y, 221);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 222);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_SIZE, 223);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 224);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 225);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 226);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, 227);
+ pointerCoords[1].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 228);
+ event->addSample(ARBITRARY_EVENT_TIME + 2, pointerCoords);
+}
+
+void MotionEventTest::assertEqualsEventWithHistory(const MotionEvent* event) {
+ // Check properties.
+ ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType());
+ ASSERT_EQ(2, event->getDeviceId());
+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, event->getSource());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, event->getAction());
+ ASSERT_EQ(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED, event->getFlags());
+ ASSERT_EQ(AMOTION_EVENT_EDGE_FLAG_TOP, event->getEdgeFlags());
+ ASSERT_EQ(AMETA_ALT_ON, event->getMetaState());
+ ASSERT_EQ(X_OFFSET, event->getXOffset());
+ ASSERT_EQ(Y_OFFSET, event->getYOffset());
+ ASSERT_EQ(2.0f, event->getXPrecision());
+ ASSERT_EQ(2.1f, event->getYPrecision());
+ ASSERT_EQ(ARBITRARY_DOWN_TIME, event->getDownTime());
+
+ ASSERT_EQ(2U, event->getPointerCount());
+ ASSERT_EQ(1, event->getPointerId(0));
+ ASSERT_EQ(2, event->getPointerId(1));
+
+ ASSERT_EQ(2U, event->getHistorySize());
+
+ // Check data.
+ ASSERT_EQ(ARBITRARY_EVENT_TIME, event->getHistoricalEventTime(0));
+ ASSERT_EQ(ARBITRARY_EVENT_TIME + 1, event->getHistoricalEventTime(1));
+ ASSERT_EQ(ARBITRARY_EVENT_TIME + 2, event->getEventTime());
+
+ ASSERT_EQ(11, event->getHistoricalRawPointerCoords(0, 0)->
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
+ ASSERT_EQ(21, event->getHistoricalRawPointerCoords(1, 0)->
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
+ ASSERT_EQ(111, event->getHistoricalRawPointerCoords(0, 1)->
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
+ ASSERT_EQ(121, event->getHistoricalRawPointerCoords(1, 1)->
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
+ ASSERT_EQ(211, event->getRawPointerCoords(0)->
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
+ ASSERT_EQ(221, event->getRawPointerCoords(1)->
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
+
+ ASSERT_EQ(11, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 0));
+ ASSERT_EQ(21, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 0));
+ ASSERT_EQ(111, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 0, 1));
+ ASSERT_EQ(121, event->getHistoricalRawAxisValue(AMOTION_EVENT_AXIS_Y, 1, 1));
+ ASSERT_EQ(211, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 0));
+ ASSERT_EQ(221, event->getRawAxisValue(AMOTION_EVENT_AXIS_Y, 1));
+
+ ASSERT_EQ(10, event->getHistoricalRawX(0, 0));
+ ASSERT_EQ(20, event->getHistoricalRawX(1, 0));
+ ASSERT_EQ(110, event->getHistoricalRawX(0, 1));
+ ASSERT_EQ(120, event->getHistoricalRawX(1, 1));
+ ASSERT_EQ(210, event->getRawX(0));
+ ASSERT_EQ(220, event->getRawX(1));
+
+ ASSERT_EQ(11, event->getHistoricalRawY(0, 0));
+ ASSERT_EQ(21, event->getHistoricalRawY(1, 0));
+ ASSERT_EQ(111, event->getHistoricalRawY(0, 1));
+ ASSERT_EQ(121, event->getHistoricalRawY(1, 1));
+ ASSERT_EQ(211, event->getRawY(0));
+ ASSERT_EQ(221, event->getRawY(1));
+
+ ASSERT_EQ(X_OFFSET + 10, event->getHistoricalX(0, 0));
+ ASSERT_EQ(X_OFFSET + 20, event->getHistoricalX(1, 0));
+ ASSERT_EQ(X_OFFSET + 110, event->getHistoricalX(0, 1));
+ ASSERT_EQ(X_OFFSET + 120, event->getHistoricalX(1, 1));
+ ASSERT_EQ(X_OFFSET + 210, event->getX(0));
+ ASSERT_EQ(X_OFFSET + 220, event->getX(1));
+
+ ASSERT_EQ(Y_OFFSET + 11, event->getHistoricalY(0, 0));
+ ASSERT_EQ(Y_OFFSET + 21, event->getHistoricalY(1, 0));
+ ASSERT_EQ(Y_OFFSET + 111, event->getHistoricalY(0, 1));
+ ASSERT_EQ(Y_OFFSET + 121, event->getHistoricalY(1, 1));
+ ASSERT_EQ(Y_OFFSET + 211, event->getY(0));
+ ASSERT_EQ(Y_OFFSET + 221, event->getY(1));
+
+ ASSERT_EQ(12, event->getHistoricalPressure(0, 0));
+ ASSERT_EQ(22, event->getHistoricalPressure(1, 0));
+ ASSERT_EQ(112, event->getHistoricalPressure(0, 1));
+ ASSERT_EQ(122, event->getHistoricalPressure(1, 1));
+ ASSERT_EQ(212, event->getPressure(0));
+ ASSERT_EQ(222, event->getPressure(1));
+
+ ASSERT_EQ(13, event->getHistoricalSize(0, 0));
+ ASSERT_EQ(23, event->getHistoricalSize(1, 0));
+ ASSERT_EQ(113, event->getHistoricalSize(0, 1));
+ ASSERT_EQ(123, event->getHistoricalSize(1, 1));
+ ASSERT_EQ(213, event->getSize(0));
+ ASSERT_EQ(223, event->getSize(1));
+
+ ASSERT_EQ(14, event->getHistoricalTouchMajor(0, 0));
+ ASSERT_EQ(24, event->getHistoricalTouchMajor(1, 0));
+ ASSERT_EQ(114, event->getHistoricalTouchMajor(0, 1));
+ ASSERT_EQ(124, event->getHistoricalTouchMajor(1, 1));
+ ASSERT_EQ(214, event->getTouchMajor(0));
+ ASSERT_EQ(224, event->getTouchMajor(1));
+
+ ASSERT_EQ(15, event->getHistoricalTouchMinor(0, 0));
+ ASSERT_EQ(25, event->getHistoricalTouchMinor(1, 0));
+ ASSERT_EQ(115, event->getHistoricalTouchMinor(0, 1));
+ ASSERT_EQ(125, event->getHistoricalTouchMinor(1, 1));
+ ASSERT_EQ(215, event->getTouchMinor(0));
+ ASSERT_EQ(225, event->getTouchMinor(1));
+
+ ASSERT_EQ(16, event->getHistoricalToolMajor(0, 0));
+ ASSERT_EQ(26, event->getHistoricalToolMajor(1, 0));
+ ASSERT_EQ(116, event->getHistoricalToolMajor(0, 1));
+ ASSERT_EQ(126, event->getHistoricalToolMajor(1, 1));
+ ASSERT_EQ(216, event->getToolMajor(0));
+ ASSERT_EQ(226, event->getToolMajor(1));
+
+ ASSERT_EQ(17, event->getHistoricalToolMinor(0, 0));
+ ASSERT_EQ(27, event->getHistoricalToolMinor(1, 0));
+ ASSERT_EQ(117, event->getHistoricalToolMinor(0, 1));
+ ASSERT_EQ(127, event->getHistoricalToolMinor(1, 1));
+ ASSERT_EQ(217, event->getToolMinor(0));
+ ASSERT_EQ(227, event->getToolMinor(1));
+
+ ASSERT_EQ(18, event->getHistoricalOrientation(0, 0));
+ ASSERT_EQ(28, event->getHistoricalOrientation(1, 0));
+ ASSERT_EQ(118, event->getHistoricalOrientation(0, 1));
+ ASSERT_EQ(128, event->getHistoricalOrientation(1, 1));
+ ASSERT_EQ(218, event->getOrientation(0));
+ ASSERT_EQ(228, event->getOrientation(1));
+}
+
+TEST_F(MotionEventTest, Properties) {
+ MotionEvent event;
+
+ // Initialize, add samples and check properties.
+ initializeEventWithHistory(&event);
+ ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&event));
+
+ // Set source.
+ event.setSource(AINPUT_SOURCE_JOYSTICK);
+ ASSERT_EQ(AINPUT_SOURCE_JOYSTICK, event.getSource());
+
+ // Set action.
+ event.setAction(AMOTION_EVENT_ACTION_CANCEL);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, event.getAction());
+
+ // Set meta state.
+ event.setMetaState(AMETA_CTRL_ON);
+ ASSERT_EQ(AMETA_CTRL_ON, event.getMetaState());
+}
+
+TEST_F(MotionEventTest, CopyFrom_KeepHistory) {
+ MotionEvent event;
+ initializeEventWithHistory(&event);
+
+ MotionEvent copy;
+ copy.copyFrom(&event, true /*keepHistory*/);
+
+ ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&event));
+}
+
+TEST_F(MotionEventTest, CopyFrom_DoNotKeepHistory) {
+ MotionEvent event;
+ initializeEventWithHistory(&event);
+
+ MotionEvent copy;
+ copy.copyFrom(&event, false /*keepHistory*/);
+
+ ASSERT_EQ(event.getPointerCount(), copy.getPointerCount());
+ ASSERT_EQ(0U, copy.getHistorySize());
+
+ ASSERT_EQ(event.getPointerId(0), copy.getPointerId(0));
+ ASSERT_EQ(event.getPointerId(1), copy.getPointerId(1));
+
+ ASSERT_EQ(event.getEventTime(), copy.getEventTime());
+
+ ASSERT_EQ(event.getX(0), copy.getX(0));
+}
+
+TEST_F(MotionEventTest, OffsetLocation) {
+ MotionEvent event;
+ initializeEventWithHistory(&event);
+
+ event.offsetLocation(5.0f, -2.0f);
+
+ ASSERT_EQ(X_OFFSET + 5.0f, event.getXOffset());
+ ASSERT_EQ(Y_OFFSET - 2.0f, event.getYOffset());
+}
+
+TEST_F(MotionEventTest, Scale) {
+ MotionEvent event;
+ initializeEventWithHistory(&event);
+
+ event.scale(2.0f);
+
+ ASSERT_EQ(X_OFFSET * 2, event.getXOffset());
+ ASSERT_EQ(Y_OFFSET * 2, event.getYOffset());
+
+ ASSERT_EQ(210 * 2, event.getRawX(0));
+ ASSERT_EQ(211 * 2, event.getRawY(0));
+ ASSERT_EQ((X_OFFSET + 210) * 2, event.getX(0));
+ ASSERT_EQ((Y_OFFSET + 211) * 2, event.getY(0));
+ ASSERT_EQ(212, event.getPressure(0));
+ ASSERT_EQ(213, event.getSize(0));
+ ASSERT_EQ(214 * 2, event.getTouchMajor(0));
+ ASSERT_EQ(215 * 2, event.getTouchMinor(0));
+ ASSERT_EQ(216 * 2, event.getToolMajor(0));
+ ASSERT_EQ(217 * 2, event.getToolMinor(0));
+ ASSERT_EQ(218, event.getOrientation(0));
+}
+
+TEST_F(MotionEventTest, Parcel) {
+ Parcel parcel;
+
+ MotionEvent inEvent;
+ initializeEventWithHistory(&inEvent);
+ MotionEvent outEvent;
+
+ // Round trip.
+ inEvent.writeToParcel(&parcel);
+ parcel.setDataPosition(0);
+ outEvent.readFromParcel(&parcel);
+
+ ASSERT_NO_FATAL_FAILURE(assertEqualsEventWithHistory(&outEvent));
+}
+
+TEST_F(MotionEventTest, Transform) {
+ // Generate some points on a circle.
+ // Each point 'i' is a point on a circle of radius ROTATION centered at (3,2) at an angle
+ // of ARC * i degrees clockwise relative to the Y axis.
+ // The geometrical representation is irrelevant to the test, it's just easy to generate
+ // and check rotation. We set the orientation to the same angle.
+ // Coordinate system: down is increasing Y, right is increasing X.
+ const float PI_180 = float(M_PI / 180);
+ const float RADIUS = 10;
+ const float ARC = 36;
+ const float ROTATION = ARC * 2;
+
+ const size_t pointerCount = 11;
+ int pointerIds[pointerCount];
+ PointerCoords pointerCoords[pointerCount];
+ for (size_t i = 0; i < pointerCount; i++) {
+ float angle = float(i * ARC * PI_180);
+ pointerIds[i] = i;
+ pointerCoords[i].clear();
+ pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, sinf(angle) * RADIUS + 3);
+ pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, -cosf(angle) * RADIUS + 2);
+ pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, angle);
+ }
+ MotionEvent event;
+ event.initialize(0, 0, AMOTION_EVENT_ACTION_MOVE, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords);
+ float originalRawX = 0 + 3;
+ float originalRawY = -RADIUS + 2;
+
+ // Check original raw X and Y assumption.
+ ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
+ ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
+
+ // Now translate the motion event so the circle's origin is at (0,0).
+ event.offsetLocation(-3, -2);
+
+ // Offsetting the location should preserve the raw X and Y of the first point.
+ ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
+ ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
+
+ // Apply a rotation about the origin by ROTATION degrees clockwise.
+ SkMatrix matrix;
+ matrix.setRotate(ROTATION);
+ event.transform(&matrix);
+
+ // Check the points.
+ for (size_t i = 0; i < pointerCount; i++) {
+ float angle = float((i * ARC + ROTATION) * PI_180);
+ ASSERT_NEAR(sinf(angle) * RADIUS, event.getX(i), 0.001);
+ ASSERT_NEAR(-cosf(angle) * RADIUS, event.getY(i), 0.001);
+ ASSERT_NEAR(tanf(angle), tanf(event.getOrientation(i)), 0.1);
+ }
+
+ // Applying the transformation should preserve the raw X and Y of the first point.
+ ASSERT_NEAR(originalRawX, event.getRawX(0), 0.001);
+ ASSERT_NEAR(originalRawY, event.getRawY(0), 0.001);
+}
+
+} // namespace android
diff --git a/libs/ui/tests/InputPublisherAndConsumer_test.cpp b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
index 1819a8be1698..6e18a4f1abb6 100644
--- a/libs/ui/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
@@ -1,6 +1,18 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
+/*
+ * 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.
+ */
#include <ui/InputTransport.h>
#include <utils/Timers.h>
@@ -161,15 +173,15 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent(
samplePointerCoords.push();
PointerCoords& pc = samplePointerCoords.editTop();
pc.clear();
- pc.setAxisValue(AINPUT_MOTION_AXIS_X, 100 * i + j);
- pc.setAxisValue(AINPUT_MOTION_AXIS_Y, 200 * i + j);
- pc.setAxisValue(AINPUT_MOTION_AXIS_PRESSURE, 0.5 * i + j);
- pc.setAxisValue(AINPUT_MOTION_AXIS_SIZE, 0.7 * i + j);
- pc.setAxisValue(AINPUT_MOTION_AXIS_TOUCH_MAJOR, 1.5 * i + j);
- pc.setAxisValue(AINPUT_MOTION_AXIS_TOUCH_MINOR, 1.7 * i + j);
- pc.setAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR, 2.5 * i + j);
- pc.setAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR, 2.7 * i + j);
- pc.setAxisValue(AINPUT_MOTION_AXIS_ORIENTATION, 3.5 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_X, 100 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_Y, 200 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.5 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_SIZE, 0.7 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 1.5 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, 1.7 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.5 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, 2.7 * i + j);
+ pc.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 3.5 * i + j);
}
}
@@ -241,27 +253,27 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent(
for (size_t i = 0; i < pointerCount; i++) {
SCOPED_TRACE(i);
size_t offset = sampleIndex * pointerCount + i;
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_X),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_X),
motionEvent->getHistoricalRawX(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_Y),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_Y),
motionEvent->getHistoricalRawY(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_X) + xOffset,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset,
motionEvent->getHistoricalX(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_Y) + yOffset,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset,
motionEvent->getHistoricalY(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_PRESSURE),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
motionEvent->getHistoricalPressure(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_SIZE),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
motionEvent->getHistoricalSize(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MAJOR),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
motionEvent->getHistoricalTouchMajor(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MINOR),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
motionEvent->getHistoricalTouchMinor(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
motionEvent->getHistoricalToolMajor(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOOL_MINOR),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
motionEvent->getHistoricalToolMinor(i, sampleIndex));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_ORIENTATION),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
motionEvent->getHistoricalOrientation(i, sampleIndex));
}
}
@@ -271,27 +283,27 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent(
for (size_t i = 0; i < pointerCount; i++) {
SCOPED_TRACE(i);
size_t offset = lastSampleIndex * pointerCount + i;
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_X),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_X),
motionEvent->getRawX(i));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_Y),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_Y),
motionEvent->getRawY(i));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_X) + xOffset,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_X) + xOffset,
motionEvent->getX(i));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_Y) + yOffset,
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_Y) + yOffset,
motionEvent->getY(i));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_PRESSURE),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
motionEvent->getPressure(i));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_SIZE),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
motionEvent->getSize(i));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MAJOR),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
motionEvent->getTouchMajor(i));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MINOR),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
motionEvent->getTouchMinor(i));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
motionEvent->getToolMajor(i));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOOL_MINOR),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
motionEvent->getToolMinor(i));
- EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_ORIENTATION),
+ EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
motionEvent->getOrientation(i));
}
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index 8c78d6044d4a..ad2bf954543e 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -3065,8 +3065,7 @@ class MediaArtistNativeHelper {
* This function is responsible for stopping the preview
*/
long stopPreview() {
- nativeStopPreview();
- return mPreviewProgress;
+ return nativeStopPreview();
}
/**
@@ -3999,7 +3998,7 @@ class MediaArtistNativeHelper {
int framewidth, int frameheight, int surfacewidth, int surfaceheight, long timeMs)
throws IllegalArgumentException, IllegalStateException, RuntimeException;
- private native void nativeStopPreview();
+ private native int nativeStopPreview();
private native int nativeGenerateAudioGraph(String pcmFilePath, String outGraphPath,
int frameDuration, int channels, int sampleCount);
diff --git a/media/java/android/media/videoeditor/Transition.java b/media/java/android/media/videoeditor/Transition.java
index 95f002c442f2..3e8fe9412830 100755
--- a/media/java/android/media/videoeditor/Transition.java
+++ b/media/java/android/media/videoeditor/Transition.java
@@ -173,6 +173,7 @@ public abstract class Transition {
mDurationMs = durationMs;
invalidate();
+ mNativeHelper.setGeneratePreview(true);
}
/**
diff --git a/media/java/android/mtp/MtpServer.java b/media/java/android/mtp/MtpServer.java
index d433887cf9f2..fe734e141cbc 100644
--- a/media/java/android/mtp/MtpServer.java
+++ b/media/java/android/mtp/MtpServer.java
@@ -54,6 +54,12 @@ public class MtpServer {
native_set_ptp_mode(usePtp);
}
+ // Used to disable MTP by removing all storage units.
+ // This is done to disable access to file transfer when the device is locked.
+ public void setLocked(boolean locked) {
+ native_set_locked(locked);
+ }
+
private native final void native_setup(MtpDatabase database, String storagePath,
long reserveSpace);
private native final void native_start();
@@ -61,4 +67,5 @@ public class MtpServer {
private native final void native_send_object_added(int handle);
private native final void native_send_object_removed(int handle);
private native final void native_set_ptp_mode(boolean usePtp);
+ private native final void native_set_locked(boolean locked);
}
diff --git a/media/jni/android_mtp_MtpServer.cpp b/media/jni/android_mtp_MtpServer.cpp
index 3883fb2dcd7a..e025ef1acff8 100644
--- a/media/jni/android_mtp_MtpServer.cpp
+++ b/media/jni/android_mtp_MtpServer.cpp
@@ -35,6 +35,7 @@
#include "private/android_filesystem_config.h"
#include "MtpServer.h"
+#include "MtpStorage.h"
using namespace android;
@@ -56,28 +57,47 @@ class MtpThread : public Thread {
private:
MtpDatabase* mDatabase;
MtpServer* mServer;
- String8 mStoragePath;
- uint64_t mReserveSpace;
+ MtpStorage* mStorage;
Mutex mMutex;
bool mUsePtp;
+ bool mLocked;
int mFd;
public:
- MtpThread(MtpDatabase* database, const char* storagePath, uint64_t reserveSpace)
+ MtpThread(MtpDatabase* database, MtpStorage* storage)
: mDatabase(database),
mServer(NULL),
- mStoragePath(storagePath),
- mReserveSpace(reserveSpace),
+ mStorage(storage),
+ mUsePtp(false),
+ mLocked(false),
mFd(-1)
{
}
+ virtual ~MtpThread() {
+ delete mStorage;
+ }
+
void setPtpMode(bool usePtp) {
mMutex.lock();
mUsePtp = usePtp;
mMutex.unlock();
}
+ void setLocked(bool locked) {
+ mMutex.lock();
+ if (locked != mLocked) {
+ if (mServer) {
+ if (locked)
+ mServer->removeStorage(mStorage);
+ else
+ mServer->addStorage(mStorage);
+ }
+ mLocked = locked;
+ }
+ mMutex.unlock();
+ }
+
virtual bool threadLoop() {
mMutex.lock();
mFd = open("/dev/mtp_usb", O_RDWR);
@@ -86,7 +106,8 @@ public:
(mUsePtp ? MTP_INTERFACE_MODE_PTP : MTP_INTERFACE_MODE_MTP));
mServer = new MtpServer(mFd, mDatabase, AID_MEDIA_RW, 0664, 0775);
- mServer->addStorage(mStoragePath, mReserveSpace);
+ if (!mLocked)
+ mServer->addStorage(mStorage);
mMutex.unlock();
mServer->run();
@@ -137,7 +158,8 @@ android_mtp_MtpServer_setup(JNIEnv *env, jobject thiz, jobject javaDatabase,
const char *storagePathStr = env->GetStringUTFChars(storagePath, NULL);
// create the thread and assign it to the smart pointer
- sThread = new MtpThread(database, storagePathStr, reserveSpace);
+ MtpStorage* storage = new MtpStorage(MTP_FIRST_STORAGE_ID, storagePathStr, reserveSpace);
+ sThread = new MtpThread(database, storage);
env->ReleaseStringUTFChars(storagePath, storagePathStr);
#endif
@@ -195,6 +217,16 @@ android_mtp_MtpServer_set_ptp_mode(JNIEnv *env, jobject thiz, jboolean usePtp)
#endif
}
+static void
+android_mtp_MtpServer_set_locked(JNIEnv *env, jobject thiz, jboolean locked)
+{
+#ifdef HAVE_ANDROID_OS
+ MtpThread *thread = sThread.get();
+ if (thread)
+ thread->setLocked(locked);
+#endif
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gMethods[] = {
@@ -205,6 +237,7 @@ static JNINativeMethod gMethods[] = {
{"native_send_object_added", "(I)V", (void *)android_mtp_MtpServer_send_object_added},
{"native_send_object_removed", "(I)V", (void *)android_mtp_MtpServer_send_object_removed},
{"native_set_ptp_mode", "(Z)V", (void *)android_mtp_MtpServer_set_ptp_mode},
+ {"native_set_locked", "(Z)V", (void *)android_mtp_MtpServer_set_locked},
};
static const char* const kClassPathName = "android/mtp/MtpServer";
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index 1ba5beb34843..23081f868fcb 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -208,7 +208,7 @@ videoEditor_populateSettings(
jobject object,
jobject audioSettingObject);
-static void videoEditor_stopPreview(JNIEnv* pEnv,
+static int videoEditor_stopPreview(JNIEnv* pEnv,
jobject thiz);
static jobject
@@ -283,8 +283,8 @@ static JNINativeMethod gManualEditMethods[] = {
{"nativeRenderMediaItemPreviewFrame",
"(Landroid/view/Surface;Ljava/lang/String;IIIIJ)I",
(int *)videoEditor_renderMediaItemPreviewFrame },
- {"nativeStopPreview", "()V",
- (void *)videoEditor_stopPreview },
+ {"nativeStopPreview", "()I",
+ (int *)videoEditor_stopPreview },
{"stopEncoding", "()V",
(void *)videoEditor_stopEncoding },
{"release", "()V",
@@ -482,11 +482,13 @@ static void jniPreviewProgressCallback (void* cookie, M4OSA_UInt32 msgType,
pContext->pVM->DetachCurrentThread();
}
-static void videoEditor_stopPreview(JNIEnv* pEnv,
+static int videoEditor_stopPreview(JNIEnv* pEnv,
jobject thiz)
{
ManualEditContext* pContext = M4OSA_NULL;
bool needToBeLoaded = true;
+ M4OSA_UInt32 lastProgressTimeMs = 0;
+
// Get the context.
pContext =
(ManualEditContext*)videoEditClasses_getContext(&needToBeLoaded, pEnv, thiz);
@@ -495,12 +497,14 @@ static void videoEditor_stopPreview(JNIEnv* pEnv,
videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv,
(M4OSA_NULL == pContext),
"not initialized");
- pContext->mPreviewController->stopPreview();
+ lastProgressTimeMs = pContext->mPreviewController->stopPreview();
if (pContext->mOverlayFileName != NULL) {
M4OSA_free((M4OSA_MemAddr32)pContext->mOverlayFileName);
pContext->mOverlayFileName = NULL;
}
+
+ return lastProgressTimeMs;
}
static void videoEditor_clearSurface(JNIEnv* pEnv,
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index fd575fef3b28..0100a1755327 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -298,6 +298,17 @@ status_t MediaRecorder::setOutputFile(int fd, int64_t offset, int64_t length)
return INVALID_OPERATION;
}
+ // It appears that if an invalid file descriptor is passed through
+ // binder calls, the server-side of the inter-process function call
+ // is skipped. As a result, the check at the server-side to catch
+ // the invalid file descritpor never gets invoked. This is to workaround
+ // this issue by checking the file descriptor first before passing
+ // it through binder call.
+ if (fd < 0) {
+ LOGE("Invalid file descriptor: %d", fd);
+ return BAD_VALUE;
+ }
+
status_t ret = mMediaRecorder->setOutputFile(fd, offset, length);
if (OK != ret) {
LOGV("setOutputFile failed: %d", ret);
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 53435f8378ed..80eb59ffc06e 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -58,7 +58,8 @@ LOCAL_C_INCLUDES:= \
$(TOP)/frameworks/base/include/media/stagefright/openmax \
$(TOP)/external/flac/include \
$(TOP)/external/tremolo \
- $(TOP)/frameworks/base/media/libstagefright/rtsp
+ $(TOP)/frameworks/base/media/libstagefright/rtsp \
+ $(TOP)/external/openssl/include \
LOCAL_SHARED_LIBRARIES := \
libbinder \
@@ -72,7 +73,8 @@ LOCAL_SHARED_LIBRARIES := \
libstagefright_yuv \
libcamera_client \
libdrmframework \
- libcrypto
+ libcrypto \
+ libssl
LOCAL_STATIC_LIBRARIES := \
libstagefright_color_conversion \
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index cd0e021441fc..bbdec024b148 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -263,6 +263,13 @@ status_t AudioSource::dataCallbackTimestamp(
return OK;
}
+ // Drop retrieved and previously lost audio data.
+ if (mNumFramesReceived == 0 && timeUs < mStartTimeUs) {
+ mRecord->getInputFramesLost();
+ LOGV("Drop audio data at %lld/%lld us", timeUs, mStartTimeUs);
+ return OK;
+ }
+
if (mNumFramesReceived == 0 && mPrevSampleTimeUs == 0) {
mInitialReadTimeUs = timeUs;
// Initial delay
@@ -277,7 +284,13 @@ status_t AudioSource::dataCallbackTimestamp(
int64_t timestampUs = mPrevSampleTimeUs;
- size_t numLostBytes = mRecord->getInputFramesLost();
+ size_t numLostBytes = 0;
+ if (mNumFramesReceived > 0) { // Ignore earlier frame lost
+ // getInputFramesLost() returns the number of lost frames.
+ // Convert number of frames lost to number of bytes lost.
+ numLostBytes = mRecord->getInputFramesLost() * mRecord->frameSize();
+ }
+
CHECK_EQ(numLostBytes & 1, 0u);
CHECK_EQ(audioBuffer.size & 1, 0u);
size_t bufferSize = numLostBytes + audioBuffer.size;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 8866750ff4f8..b1d3630c67df 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -1481,7 +1481,8 @@ status_t AwesomePlayer::prepareAsync_l() {
status_t AwesomePlayer::finishSetDataSource_l() {
sp<DataSource> dataSource;
- if (!strncasecmp("http://", mUri.string(), 7)) {
+ if (!strncasecmp("http://", mUri.string(), 7)
+ || !strncasecmp("https://", mUri.string(), 8)) {
mConnectingDataSource = new NuHTTPDataSource;
mLock.unlock();
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 66e0657b7b67..8a24bc45b62a 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -598,8 +598,7 @@ status_t CameraSource::stop() {
}
if (mNumGlitches > 0) {
- LOGW("%d long delays between neighboring video frames during",
- mNumGlitches);
+ LOGW("%d long delays between neighboring video frames", mNumGlitches);
}
CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped);
@@ -696,10 +695,9 @@ void CameraSource::dataCallbackTimestamp(int64_t timestampUs,
int32_t msgType, const sp<IMemory> &data) {
LOGV("dataCallbackTimestamp: timestamp %lld us", timestampUs);
Mutex::Autolock autoLock(mLock);
- if (!mStarted) {
+ if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) {
+ LOGV("Drop frame at %lld/%lld us", timestampUs, mStartTimeUs);
releaseOneRecordingFrame(data);
- ++mNumFramesReceived;
- ++mNumFramesDropped;
return;
}
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 8f9c150be626..3b382085bd80 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -125,7 +125,8 @@ sp<DataSource> DataSource::CreateFromURI(
sp<DataSource> source;
if (!strncasecmp("file://", uri, 7)) {
source = new FileSource(uri + 7);
- } else if (!strncasecmp("http://", uri, 7)) {
+ } else if (!strncasecmp("http://", uri, 7)
+ || !strncasecmp("https://", uri, 8)) {
sp<NuHTTPDataSource> httpSource = new NuHTTPDataSource;
if (httpSource->connect(uri, headers) != OK) {
return NULL;
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index 77a61a577c00..498c7b885e63 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -34,6 +34,8 @@
#include <media/stagefright/foundation/ADebug.h>
+#include <openssl/ssl.h>
+
namespace android {
// static
@@ -41,11 +43,18 @@ const char *HTTPStream::kStatusKey = ":status:"; // MUST be lowercase.
HTTPStream::HTTPStream()
: mState(READY),
- mSocket(-1) {
+ mSocket(-1),
+ mSSLContext(NULL),
+ mSSL(NULL) {
}
HTTPStream::~HTTPStream() {
disconnect();
+
+ if (mSSLContext != NULL) {
+ SSL_CTX_free((SSL_CTX *)mSSLContext);
+ mSSLContext = NULL;
+ }
}
static bool MakeSocketBlocking(int s, bool blocking) {
@@ -198,7 +207,11 @@ static ssize_t MyReceive(int s, void *data, size_t size, int flags) {
return MySendReceive(s, data, size, flags, false /* sendData */);
}
-status_t HTTPStream::connect(const char *server, int port) {
+status_t HTTPStream::connect(const char *server, int port, bool https) {
+ if (port < 0) {
+ port = https ? 443 : 80;
+ }
+
Mutex::Autolock autoLock(mLock);
status_t err = OK;
@@ -249,6 +262,47 @@ status_t HTTPStream::connect(const char *server, int port) {
return res;
}
+ if (https) {
+ CHECK(mSSL == NULL);
+
+ if (mSSLContext == NULL) {
+ SSL_library_init();
+
+ mSSLContext = SSL_CTX_new(TLSv1_client_method());
+
+ if (mSSLContext == NULL) {
+ LOGE("failed to create SSL context");
+ mState = READY;
+ return ERROR_IO;
+ }
+ }
+
+ mSSL = SSL_new((SSL_CTX *)mSSLContext);
+
+ if (mSSL == NULL) {
+ LOGE("failed to create SSL session");
+
+ mState = READY;
+ return ERROR_IO;
+ }
+
+ int res = SSL_set_fd((SSL *)mSSL, mSocket);
+
+ if (res == 1) {
+ res = SSL_connect((SSL *)mSSL);
+ }
+
+ if (res != 1) {
+ SSL_free((SSL *)mSSL);
+ mSSL = NULL;
+
+ LOGE("failed to connect over SSL");
+ mState = READY;
+
+ return ERROR_IO;
+ }
+ }
+
mState = CONNECTED;
return OK;
@@ -261,6 +315,13 @@ status_t HTTPStream::disconnect() {
return ERROR_NOT_CONNECTED;
}
+ if (mSSL != NULL) {
+ SSL_shutdown((SSL *)mSSL);
+
+ SSL_free((SSL *)mSSL);
+ mSSL = NULL;
+ }
+
CHECK(mSocket >= 0);
close(mSocket);
mSocket = -1;
@@ -276,7 +337,16 @@ status_t HTTPStream::send(const char *data, size_t size) {
}
while (size > 0) {
- ssize_t n = MySend(mSocket, data, size, 0);
+ ssize_t n;
+ if (mSSL != NULL) {
+ n = SSL_write((SSL *)mSSL, data, size);
+
+ if (n < 0) {
+ n = -SSL_get_error((SSL *)mSSL, n);
+ }
+ } else {
+ n = MySend(mSocket, data, size, 0);
+ }
if (n < 0) {
disconnect();
@@ -317,7 +387,17 @@ status_t HTTPStream::receive_line(char *line, size_t size) {
for (;;) {
char c;
- ssize_t n = MyReceive(mSocket, &c, 1, 0);
+ ssize_t n;
+ if (mSSL != NULL) {
+ n = SSL_read((SSL *)mSSL, &c, 1);
+
+ if (n < 0) {
+ n = -SSL_get_error((SSL *)mSSL, n);
+ }
+ } else {
+ n = MyReceive(mSocket, &c, 1, 0);
+ }
+
if (n < 0) {
disconnect();
@@ -437,7 +517,16 @@ status_t HTTPStream::receive_header(int *http_status) {
ssize_t HTTPStream::receive(void *data, size_t size) {
size_t total = 0;
while (total < size) {
- ssize_t n = MyReceive(mSocket, (char *)data + total, size - total, 0);
+ ssize_t n;
+ if (mSSL != NULL) {
+ n = SSL_read((SSL *)mSSL, (char *)data + total, size - total);
+
+ if (n < 0) {
+ n = -SSL_get_error((SSL *)mSSL, n);
+ }
+ } else {
+ n = MyReceive(mSocket, (char *)data + total, size - total, 0);
+ }
if (n < 0) {
LOGE("recv failed, errno = %d (%s)", (int)n, strerror(-n));
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index b11789dc9e25..5d6ea7cddc8a 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -1281,7 +1281,21 @@ status_t MPEG4Writer::Track::start(MetaData *params) {
initTrackingProgressStatus(params);
sp<MetaData> meta = new MetaData;
+ if (mIsRealTimeRecording && mOwner->numTracks() > 1) {
+ /*
+ * This extra delay of accepting incoming audio/video signals
+ * helps to align a/v start time at the beginning of a recording
+ * session, and it also helps eliminate the "recording" sound for
+ * camcorder applications.
+ *
+ * Ideally, this platform-specific value should be defined
+ * in media_profiles.xml file
+ */
+ startTimeUs += 700000;
+ }
+
meta->setInt64(kKeyTime, startTimeUs);
+
status_t err = mSource->start(meta.get());
if (err != OK) {
mDone = mReachedEOS = true;
@@ -1944,7 +1958,11 @@ status_t MPEG4Writer::Track::threadEntry() {
((timestampUs * mTimeScale + 500000LL) / 1000000LL -
(lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
- if (currDurationTicks != lastDurationTicks) {
+ // Force the first sample to have its own stts entry so that
+ // we can adjust its value later to maintain the A/V sync.
+ if (mNumSamples == 3 || currDurationTicks != lastDurationTicks) {
+ LOGV("%s lastDurationUs: %lld us, currDurationTicks: %lld us",
+ mIsAudio? "Audio": "Video", lastDurationUs, currDurationTicks);
addOneSttsTableEntry(sampleCount, lastDurationUs);
sampleCount = 1;
} else {
@@ -1957,6 +1975,8 @@ status_t MPEG4Writer::Track::threadEntry() {
}
previousSampleSize = sampleSize;
}
+ LOGV("%s timestampUs/lastTimestampUs: %lld/%lld",
+ mIsAudio? "Audio": "Video", timestampUs, lastTimestampUs);
lastDurationUs = timestampUs - lastTimestampUs;
lastDurationTicks = currDurationTicks;
lastTimestampUs = timestampUs;
@@ -2028,7 +2048,16 @@ status_t MPEG4Writer::Track::threadEntry() {
} else {
++sampleCount; // Count for the last sample
}
- addOneSttsTableEntry(sampleCount, lastDurationUs);
+
+ if (mNumSamples <= 2) {
+ addOneSttsTableEntry(1, lastDurationUs);
+ if (sampleCount - 1 > 0) {
+ addOneSttsTableEntry(sampleCount - 1, lastDurationUs);
+ }
+ } else {
+ addOneSttsTableEntry(sampleCount, lastDurationUs);
+ }
+
mTrackDurationUs += lastDurationUs;
mReachedEOS = true;
LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s",
@@ -2153,6 +2182,9 @@ void MPEG4Writer::Track::writeTrackHeader(
int32_t mvhdTimeScale = mOwner->getTimeScale();
int64_t trakDurationUs = getDurationUs();
+ // Compensate for small start time difference from different media tracks
+ int64_t trackStartTimeOffsetUs = 0;
+
mOwner->beginBox("trak");
mOwner->beginBox("tkhd");
@@ -2191,26 +2223,8 @@ void MPEG4Writer::Track::writeTrackHeader(
int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
if (mStartTimestampUs != moovStartTimeUs) {
- mOwner->beginBox("edts");
- mOwner->beginBox("elst");
- mOwner->writeInt32(0); // version=0, flags=0: 32-bit time
- mOwner->writeInt32(2); // never ends with an empty list
-
- // First elst entry: specify the starting time offset
- int64_t offsetUs = mStartTimestampUs - moovStartTimeUs;
- LOGV("OffsetUs: %lld", offsetUs);
- int32_t seg = (offsetUs * mvhdTimeScale + 5E5) / 1E6;
- mOwner->writeInt32(seg); // in mvhd timecale
- mOwner->writeInt32(-1); // starting time offset
- mOwner->writeInt32(1 << 16); // rate = 1.0
-
- // Second elst entry: specify the track duration
- seg = (trakDurationUs * mvhdTimeScale + 5E5) / 1E6;
- mOwner->writeInt32(seg); // in mvhd timescale
- mOwner->writeInt32(0);
- mOwner->writeInt32(1 << 16);
- mOwner->endBox();
- mOwner->endBox();
+ CHECK(mStartTimestampUs > moovStartTimeUs);
+ trackStartTimeOffsetUs = mStartTimestampUs - moovStartTimeUs;
}
mOwner->beginBox("mdia");
@@ -2466,7 +2480,7 @@ void MPEG4Writer::Track::writeTrackHeader(
mOwner->beginBox("stts");
mOwner->writeInt32(0); // version=0, flags=0
mOwner->writeInt32(mNumSttsTableEntries);
- int64_t prevTimestampUs = 0;
+ int64_t prevTimestampUs = trackStartTimeOffsetUs;
for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin();
it != mSttsTableEntries.end(); ++it) {
mOwner->writeInt32(it->sampleCount);
diff --git a/media/libstagefright/NuHTTPDataSource.cpp b/media/libstagefright/NuHTTPDataSource.cpp
index 0376e1c36646..e39fab3bcf9c 100644
--- a/media/libstagefright/NuHTTPDataSource.cpp
+++ b/media/libstagefright/NuHTTPDataSource.cpp
@@ -24,22 +24,30 @@ static bool ParseSingleUnsignedLong(
}
static bool ParseURL(
- const char *url, String8 *host, unsigned *port, String8 *path) {
+ const char *url, String8 *host, unsigned *port,
+ String8 *path, bool *https) {
host->setTo("");
*port = 0;
path->setTo("");
- if (strncasecmp("http://", url, 7)) {
+ size_t hostStart;
+ if (!strncasecmp("http://", url, 7)) {
+ hostStart = 7;
+ *https = false;
+ } else if (!strncasecmp("https://", url, 8)) {
+ hostStart = 8;
+ *https = true;
+ } else {
return false;
}
- const char *slashPos = strchr(&url[7], '/');
+ const char *slashPos = strchr(&url[hostStart], '/');
if (slashPos == NULL) {
- host->setTo(&url[7]);
+ host->setTo(&url[hostStart]);
path->setTo("/");
} else {
- host->setTo(&url[7], slashPos - &url[7]);
+ host->setTo(&url[hostStart], slashPos - &url[hostStart]);
path->setTo(slashPos);
}
@@ -57,7 +65,7 @@ static bool ParseURL(
String8 tmp(host->string(), colonOffset);
*host = tmp;
} else {
- *port = 80;
+ *port = (*https) ? 443 : 80;
}
return true;
@@ -66,6 +74,7 @@ static bool ParseURL(
NuHTTPDataSource::NuHTTPDataSource()
: mState(DISCONNECTED),
mPort(0),
+ mHTTPS(false),
mOffset(0),
mContentLength(0),
mContentLengthValid(false),
@@ -111,11 +120,12 @@ status_t NuHTTPDataSource::connect(
mUri = uri;
- if (!ParseURL(uri, &host, &port, &path)) {
+ bool https;
+ if (!ParseURL(uri, &host, &port, &path, &https)) {
return ERROR_MALFORMED;
}
- return connect(host, port, path, headers, offset);
+ return connect(host, port, path, https, headers, offset);
}
static bool IsRedirectStatusCode(int httpStatus) {
@@ -125,6 +135,7 @@ static bool IsRedirectStatusCode(int httpStatus) {
status_t NuHTTPDataSource::connect(
const char *host, unsigned port, const char *path,
+ bool https,
const String8 &headers,
off64_t offset) {
LOGI("connect to %s:%u%s @%lld", host, port, path, offset);
@@ -132,7 +143,7 @@ status_t NuHTTPDataSource::connect(
bool needsToReconnect = true;
if (mState == CONNECTED && host == mHost && port == mPort
- && offset == mOffset) {
+ && https == mHTTPS && offset == mOffset) {
if (mContentLengthValid && mOffset == mContentLength) {
LOGI("Didn't have to reconnect, old one's still good.");
needsToReconnect = false;
@@ -142,6 +153,7 @@ status_t NuHTTPDataSource::connect(
mHost = host;
mPort = port;
mPath = path;
+ mHTTPS = https;
mHeaders = headers;
status_t err = OK;
@@ -150,7 +162,7 @@ status_t NuHTTPDataSource::connect(
if (needsToReconnect) {
mHTTP.disconnect();
- err = mHTTP.connect(host, port);
+ err = mHTTP.connect(host, port, https);
}
if (err != OK) {
@@ -353,7 +365,7 @@ ssize_t NuHTTPDataSource::readAt(off64_t offset, void *data, size_t size) {
String8 host = mHost;
String8 path = mPath;
String8 headers = mHeaders;
- status_t err = connect(host, mPort, path, headers, offset);
+ status_t err = connect(host, mPort, path, mHTTPS, headers, offset);
if (err != OK) {
return err;
diff --git a/media/libstagefright/foundation/ABitReader.cpp b/media/libstagefright/foundation/ABitReader.cpp
index 24c8df89cec2..f07dd4f7fa90 100644
--- a/media/libstagefright/foundation/ABitReader.cpp
+++ b/media/libstagefright/foundation/ABitReader.cpp
@@ -90,9 +90,7 @@ size_t ABitReader::numBitsLeft() const {
}
const uint8_t *ABitReader::data() const {
- CHECK_EQ(mNumBitsLeft % 8, 0u);
-
- return mData - mNumBitsLeft / 8;
+ return mData - (mNumBitsLeft + 7) / 8;
}
} // namespace android
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index f7a908583695..ee845a3cc91d 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -189,7 +189,8 @@ status_t LiveSession::fetchFile(const char *url, sp<ABuffer> *out) {
if (!strncasecmp(url, "file://", 7)) {
source = new FileSource(url + 7);
- } else if (strncasecmp(url, "http://", 7)) {
+ } else if (strncasecmp(url, "http://", 7)
+ && strncasecmp(url, "https://", 8)) {
return ERROR_UNSUPPORTED;
} else {
{
diff --git a/media/libstagefright/include/HTTPStream.h b/media/libstagefright/include/HTTPStream.h
index 545cd0c431ed..09e6a5fbdf52 100644
--- a/media/libstagefright/include/HTTPStream.h
+++ b/media/libstagefright/include/HTTPStream.h
@@ -32,7 +32,7 @@ public:
HTTPStream();
~HTTPStream();
- status_t connect(const char *server, int port = 80);
+ status_t connect(const char *server, int port = -1, bool https = false);
status_t disconnect();
status_t send(const char *data, size_t size);
@@ -71,6 +71,9 @@ private:
KeyedVector<AString, AString> mHeaders;
+ void *mSSLContext;
+ void *mSSL;
+
HTTPStream(const HTTPStream &);
HTTPStream &operator=(const HTTPStream &);
};
diff --git a/media/libstagefright/include/NuHTTPDataSource.h b/media/libstagefright/include/NuHTTPDataSource.h
index a99e84a466a2..3918434e3709 100644
--- a/media/libstagefright/include/NuHTTPDataSource.h
+++ b/media/libstagefright/include/NuHTTPDataSource.h
@@ -57,6 +57,7 @@ private:
String8 mHost;
unsigned mPort;
String8 mPath;
+ bool mHTTPS;
String8 mHeaders;
String8 mUri;
@@ -83,6 +84,7 @@ private:
status_t connect(
const char *host, unsigned port, const char *path,
+ bool https,
const String8 &headers,
off64_t offset);
diff --git a/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp b/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
index 8bfe2852f17d..11d9c220959c 100644
--- a/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AMPEG4AudioAssembler"
+
#include "AMPEG4AudioAssembler.h"
#include "ARTPSource.h"
@@ -139,7 +142,10 @@ static status_t parseGASpecificConfig(
return OK;
}
-static status_t parseAudioSpecificConfig(ABitReader *bits) {
+static status_t parseAudioSpecificConfig(ABitReader *bits, sp<ABuffer> *asc) {
+ const uint8_t *dataStart = bits->data();
+ size_t totalNumBits = bits->numBitsLeft();
+
unsigned audioObjectType;
CHECK_EQ(parseAudioObjectType(bits, &audioObjectType), (status_t)OK);
@@ -185,13 +191,13 @@ static status_t parseAudioSpecificConfig(ABitReader *bits) {
}
}
-#if 0
- // This is not supported here as the upper layers did not explicitly
- // signal the length of AudioSpecificConfig.
-
if (extensionAudioObjectType != 5 && bits->numBitsLeft() >= 16) {
+ size_t numBitsLeftAtStart = bits->numBitsLeft();
+
unsigned syncExtensionType = bits->getBits(11);
if (syncExtensionType == 0x2b7) {
+ LOGI("found syncExtension");
+
CHECK_EQ(parseAudioObjectType(bits, &extensionAudioObjectType),
(status_t)OK);
@@ -203,9 +209,45 @@ static status_t parseAudioSpecificConfig(ABitReader *bits) {
/* unsigned extensionSamplingFrequency = */bits->getBits(24);
}
}
+
+ size_t numBitsInExtension =
+ numBitsLeftAtStart - bits->numBitsLeft();
+
+ if (numBitsInExtension & 7) {
+ // Apparently an extension is always considered an even
+ // multiple of 8 bits long.
+
+ LOGI("Skipping %d bits after sync extension",
+ 8 - (numBitsInExtension & 7));
+
+ bits->skipBits(8 - (numBitsInExtension & 7));
+ }
+ } else {
+ bits->putBits(syncExtensionType, 11);
+ }
+ }
+
+ if (asc != NULL) {
+ size_t bitpos = totalNumBits & 7;
+
+ ABitReader bs(dataStart, (totalNumBits + 7) / 8);
+
+ totalNumBits -= bits->numBitsLeft();
+
+ size_t numBytes = (totalNumBits + 7) / 8;
+
+ *asc = new ABuffer(numBytes);
+
+ if (bitpos & 7) {
+ bs.skipBits(8 - (bitpos & 7));
+ }
+
+ uint8_t *dstPtr = (*asc)->data();
+ while (numBytes > 0) {
+ *dstPtr++ = bs.getBits(8);
+ --numBytes;
}
}
-#endif
return OK;
}
@@ -214,6 +256,7 @@ static status_t parseStreamMuxConfig(
ABitReader *bits,
unsigned *numSubFrames,
unsigned *frameLengthType,
+ ssize_t *fixedFrameLength,
bool *otherDataPresent,
unsigned *otherDataLenBits) {
unsigned audioMuxVersion = bits->getBits(1);
@@ -242,12 +285,14 @@ static status_t parseStreamMuxConfig(
if (audioMuxVersion == 0) {
// AudioSpecificConfig
- CHECK_EQ(parseAudioSpecificConfig(bits), (status_t)OK);
+ CHECK_EQ(parseAudioSpecificConfig(bits, NULL /* asc */), (status_t)OK);
} else {
TRESPASS(); // XXX to be implemented
}
*frameLengthType = bits->getBits(3);
+ *fixedFrameLength = -1;
+
switch (*frameLengthType) {
case 0:
{
@@ -260,7 +305,14 @@ static status_t parseStreamMuxConfig(
case 1:
{
- /* unsigned frameLength = */bits->getBits(9);
+ *fixedFrameLength = bits->getBits(9);
+ break;
+ }
+
+ case 2:
+ {
+ // reserved
+ TRESPASS();
break;
}
@@ -338,9 +390,21 @@ sp<ABuffer> AMPEG4AudioAssembler::removeLATMFraming(const sp<ABuffer> &buffer) {
break;
}
+ case 2:
+ {
+ // reserved
+
+ TRESPASS();
+ break;
+ }
+
default:
- TRESPASS(); // XXX to be implemented
+ {
+ CHECK_GE(mFixedFrameLength, 0);
+
+ payloadLength = mFixedFrameLength;
break;
+ }
}
CHECK_LE(offset + payloadLength, buffer->size());
@@ -393,6 +457,7 @@ AMPEG4AudioAssembler::AMPEG4AudioAssembler(
ABitReader bits(config->data(), config->size());
status_t err = parseStreamMuxConfig(
&bits, &mNumSubFrames, &mFrameLengthType,
+ &mFixedFrameLength,
&mOtherDataPresent, &mOtherDataLenBits);
CHECK_EQ(err, (status_t)NO_ERROR);
diff --git a/media/libstagefright/rtsp/AMPEG4AudioAssembler.h b/media/libstagefright/rtsp/AMPEG4AudioAssembler.h
index 9cef94c6591c..1361cd2db701 100644
--- a/media/libstagefright/rtsp/AMPEG4AudioAssembler.h
+++ b/media/libstagefright/rtsp/AMPEG4AudioAssembler.h
@@ -46,6 +46,7 @@ private:
bool mMuxConfigPresent;
unsigned mNumSubFrames;
unsigned mFrameLengthType;
+ ssize_t mFixedFrameLength;
bool mOtherDataPresent;
unsigned mOtherDataLenBits;
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 853a5af864f7..37e02a3f6529 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -84,6 +84,8 @@ static const MtpOperationCode kSupportedOperationCodes[] = {
static const MtpEventCode kSupportedEventCodes[] = {
MTP_EVENT_OBJECT_ADDED,
MTP_EVENT_OBJECT_REMOVED,
+ MTP_EVENT_STORE_ADDED,
+ MTP_EVENT_STORE_REMOVED,
};
MtpServer::MtpServer(int fd, MtpDatabase* database,
@@ -104,11 +106,23 @@ MtpServer::MtpServer(int fd, MtpDatabase* database,
MtpServer::~MtpServer() {
}
-void MtpServer::addStorage(const char* filePath, uint64_t reserveSpace) {
- int index = mStorages.size() + 1;
- index |= index << 16; // set high and low part to our index
- MtpStorage* storage = new MtpStorage(index, filePath, reserveSpace);
- addStorage(storage);
+void MtpServer::addStorage(MtpStorage* storage) {
+ Mutex::Autolock autoLock(mMutex);
+
+ mStorages.push(storage);
+ sendStoreAdded(storage->getStorageID());
+}
+
+void MtpServer::removeStorage(MtpStorage* storage) {
+ Mutex::Autolock autoLock(mMutex);
+
+ for (int i = 0; i < mStorages.size(); i++) {
+ if (mStorages[i] == storage) {
+ mStorages.removeAt(i);
+ sendStoreRemoved(storage->getStorageID());
+ break;
+ }
+ }
}
MtpStorage* MtpServer::getStorage(MtpStorageID id) {
@@ -122,6 +136,12 @@ MtpStorage* MtpServer::getStorage(MtpStorageID id) {
return NULL;
}
+bool MtpServer::hasStorage(MtpStorageID id) {
+ if (id == 0 || id == 0xFFFFFFFF)
+ return mStorages.size() > 0;
+ return (getStorage(id) != NULL);
+}
+
void MtpServer::run() {
int fd = mFD;
@@ -203,28 +223,38 @@ void MtpServer::run() {
}
void MtpServer::sendObjectAdded(MtpObjectHandle handle) {
- if (mSessionOpen) {
- LOGV("sendObjectAdded %d\n", handle);
- mEvent.setEventCode(MTP_EVENT_OBJECT_ADDED);
- mEvent.setTransactionID(mRequest.getTransactionID());
- mEvent.setParameter(1, handle);
- int ret = mEvent.write(mFD);
- LOGV("mEvent.write returned %d\n", ret);
- }
+ LOGV("sendObjectAdded %d\n", handle);
+ sendEvent(MTP_EVENT_OBJECT_ADDED, handle);
}
void MtpServer::sendObjectRemoved(MtpObjectHandle handle) {
+ LOGV("sendObjectRemoved %d\n", handle);
+ sendEvent(MTP_EVENT_OBJECT_REMOVED, handle);
+}
+
+void MtpServer::sendStoreAdded(MtpStorageID id) {
+ LOGV("sendStoreAdded %08X\n", id);
+ sendEvent(MTP_EVENT_STORE_ADDED, id);
+}
+
+void MtpServer::sendStoreRemoved(MtpStorageID id) {
+ LOGV("sendStoreRemoved %08X\n", id);
+ sendEvent(MTP_EVENT_STORE_REMOVED, id);
+}
+
+void MtpServer::sendEvent(MtpEventCode code, uint32_t param1) {
if (mSessionOpen) {
- LOGV("sendObjectRemoved %d\n", handle);
- mEvent.setEventCode(MTP_EVENT_OBJECT_REMOVED);
+ mEvent.setEventCode(code);
mEvent.setTransactionID(mRequest.getTransactionID());
- mEvent.setParameter(1, handle);
+ mEvent.setParameter(1, param1);
int ret = mEvent.write(mFD);
LOGV("mEvent.write returned %d\n", ret);
}
}
bool MtpServer::handleRequest() {
+ Mutex::Autolock autoLock(mMutex);
+
MtpOperationCode operation = mRequest.getOperationCode();
MtpResponseCode response;
@@ -439,6 +469,9 @@ MtpResponseCode MtpServer::doGetObjectHandles() {
MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats
MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent
// 0x00000000 for all objects?
+
+ if (!hasStorage(storageID))
+ return MTP_RESPONSE_INVALID_STORAGE_ID;
if (parent == 0xFFFFFFFF)
parent = 0;
@@ -455,6 +488,8 @@ MtpResponseCode MtpServer::doGetNumObjects() {
MtpObjectFormat format = mRequest.getParameter(2); // 0 for all formats
MtpObjectHandle parent = mRequest.getParameter(3); // 0xFFFFFFFF for objects with no parent
// 0x00000000 for all objects?
+ if (!hasStorage(storageID))
+ return MTP_RESPONSE_INVALID_STORAGE_ID;
if (parent == 0xFFFFFFFF)
parent = 0;
@@ -471,7 +506,9 @@ MtpResponseCode MtpServer::doGetNumObjects() {
MtpResponseCode MtpServer::doGetObjectReferences() {
if (!mSessionOpen)
return MTP_RESPONSE_SESSION_NOT_OPEN;
- MtpStorageID handle = mRequest.getParameter(1);
+ if (!hasStorage())
+ return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
+ MtpObjectHandle handle = mRequest.getParameter(1);
// FIXME - check for invalid object handle
MtpObjectHandleList* handles = mDatabase->getObjectReferences(handle);
@@ -487,7 +524,10 @@ MtpResponseCode MtpServer::doGetObjectReferences() {
MtpResponseCode MtpServer::doSetObjectReferences() {
if (!mSessionOpen)
return MTP_RESPONSE_SESSION_NOT_OPEN;
+ if (!hasStorage())
+ return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
MtpStorageID handle = mRequest.getParameter(1);
+
MtpObjectHandleList* references = mData.getAUInt32();
MtpResponseCode result = mDatabase->setObjectReferences(handle, references);
delete references;
@@ -495,6 +535,8 @@ MtpResponseCode MtpServer::doSetObjectReferences() {
}
MtpResponseCode MtpServer::doGetObjectPropValue() {
+ if (!hasStorage())
+ return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
MtpObjectHandle handle = mRequest.getParameter(1);
MtpObjectProperty property = mRequest.getParameter(2);
LOGV("GetObjectPropValue %d %s\n", handle,
@@ -504,6 +546,8 @@ MtpResponseCode MtpServer::doGetObjectPropValue() {
}
MtpResponseCode MtpServer::doSetObjectPropValue() {
+ if (!hasStorage())
+ return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
MtpObjectHandle handle = mRequest.getParameter(1);
MtpObjectProperty property = mRequest.getParameter(2);
LOGV("SetObjectPropValue %d %s\n", handle,
@@ -537,6 +581,8 @@ MtpResponseCode MtpServer::doResetDevicePropValue() {
}
MtpResponseCode MtpServer::doGetObjectPropList() {
+ if (!hasStorage())
+ return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
MtpObjectHandle handle = mRequest.getParameter(1);
// use uint32_t so we can support 0xFFFFFFFF
@@ -552,11 +598,15 @@ MtpResponseCode MtpServer::doGetObjectPropList() {
}
MtpResponseCode MtpServer::doGetObjectInfo() {
+ if (!hasStorage())
+ return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
MtpObjectHandle handle = mRequest.getParameter(1);
return mDatabase->getObjectInfo(handle, mData);
}
MtpResponseCode MtpServer::doGetObject() {
+ if (!hasStorage())
+ return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
MtpObjectHandle handle = mRequest.getParameter(1);
MtpString pathBuf;
int64_t fileLength;
@@ -592,6 +642,8 @@ MtpResponseCode MtpServer::doGetObject() {
}
MtpResponseCode MtpServer::doGetPartialObject() {
+ if (!hasStorage())
+ return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
MtpObjectHandle handle = mRequest.getParameter(1);
uint32_t offset = mRequest.getParameter(2);
uint32_t length = mRequest.getParameter(3);
@@ -688,6 +740,7 @@ MtpResponseCode MtpServer::doSendObjectInfo() {
if (mSendObjectFileSize > storage->getFreeSpace())
return MTP_RESPONSE_STORAGE_FULL;
+LOGD("path: %s parent: %d storageID: %08X", (const char*)path, parent, storageID);
MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path,
format, parent, storageID, mSendObjectFileSize, modifiedTime);
if (handle == kInvalidObjectHandle) {
@@ -719,6 +772,8 @@ MtpResponseCode MtpServer::doSendObjectInfo() {
}
MtpResponseCode MtpServer::doSendObject() {
+ if (!hasStorage())
+ return MTP_RESPONSE_GENERAL_ERROR;
MtpResponseCode result = MTP_RESPONSE_OK;
mode_t mask;
int ret;
@@ -835,6 +890,8 @@ static void deletePath(const char* path) {
}
MtpResponseCode MtpServer::doDeleteObject() {
+ if (!hasStorage())
+ return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
MtpObjectHandle handle = mRequest.getParameter(1);
MtpObjectFormat format = mRequest.getParameter(2);
// FIXME - support deleting all objects if handle is 0xFFFFFFFF
diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h
index 605d5a2e0d4d..1efa7158baa6 100644
--- a/media/mtp/MtpServer.h
+++ b/media/mtp/MtpServer.h
@@ -22,9 +22,10 @@
#include "MtpResponsePacket.h"
#include "MtpEventPacket.h"
#include "mtp.h"
-
#include "MtpUtils.h"
+#include <utils/threads.h>
+
namespace android {
class MtpDatabase;
@@ -62,20 +63,29 @@ private:
MtpString mSendObjectFilePath;
size_t mSendObjectFileSize;
+ Mutex mMutex;
+
public:
MtpServer(int fd, MtpDatabase* database,
int fileGroup, int filePerm, int directoryPerm);
virtual ~MtpServer();
- void addStorage(const char* filePath, uint64_t reserveSpace);
- inline void addStorage(MtpStorage* storage) { mStorages.push(storage); }
- MtpStorage* getStorage(MtpStorageID id);
+ void addStorage(MtpStorage* storage);
+ void removeStorage(MtpStorage* storage);
+
void run();
void sendObjectAdded(MtpObjectHandle handle);
void sendObjectRemoved(MtpObjectHandle handle);
private:
+ MtpStorage* getStorage(MtpStorageID id);
+ inline bool hasStorage() { return mStorages.size() > 0; }
+ bool hasStorage(MtpStorageID id);
+ void sendStoreAdded(MtpStorageID id);
+ void sendStoreRemoved(MtpStorageID id);
+ void sendEvent(MtpEventCode code, uint32_t param1);
+
bool handleRequest();
MtpResponseCode doGetDeviceInfo();
diff --git a/media/mtp/MtpStorage.cpp b/media/mtp/MtpStorage.cpp
index 2fbbc512d1e2..6cb88b33551f 100644
--- a/media/mtp/MtpStorage.cpp
+++ b/media/mtp/MtpStorage.cpp
@@ -59,7 +59,7 @@ int MtpStorage::getAccessCapability() const {
uint64_t MtpStorage::getMaxCapacity() {
if (mMaxCapacity == 0) {
struct statfs stat;
- if (statfs(mFilePath, &stat))
+ if (statfs(getPath(), &stat))
return -1;
mMaxCapacity = (uint64_t)stat.f_blocks * (uint64_t)stat.f_bsize;
}
@@ -68,7 +68,7 @@ uint64_t MtpStorage::getMaxCapacity() {
uint64_t MtpStorage::getFreeSpace() {
struct statfs stat;
- if (statfs(mFilePath, &stat))
+ if (statfs(getPath(), &stat))
return -1;
uint64_t freeSpace = (uint64_t)stat.f_bavail * (uint64_t)stat.f_bsize;
return (freeSpace > mReserveSpace ? freeSpace - mReserveSpace : 0);
diff --git a/media/mtp/MtpStorage.h b/media/mtp/MtpStorage.h
index ace720b9f511..858c9d38a3f6 100644
--- a/media/mtp/MtpStorage.h
+++ b/media/mtp/MtpStorage.h
@@ -17,6 +17,7 @@
#ifndef _MTP_STORAGE_H
#define _MTP_STORAGE_H
+#include "MtpTypes.h"
#include "mtp.h"
namespace android {
@@ -27,7 +28,7 @@ class MtpStorage {
private:
MtpStorageID mStorageID;
- const char* mFilePath;
+ MtpString mFilePath;
uint64_t mMaxCapacity;
// amount of free space to leave unallocated
uint64_t mReserveSpace;
@@ -44,7 +45,7 @@ public:
uint64_t getMaxCapacity();
uint64_t getFreeSpace();
const char* getDescription() const;
- inline const char* getPath() const { return mFilePath; }
+ inline const char* getPath() const { return (const char *)mFilePath; }
};
}; // namespace android
diff --git a/media/mtp/mtp.h b/media/mtp/mtp.h
index 8bc2e22c31d8..6fedc161b9c1 100644
--- a/media/mtp/mtp.h
+++ b/media/mtp/mtp.h
@@ -22,6 +22,8 @@
#define MTP_STANDARD_VERSION 100
+#define MTP_FIRST_STORAGE_ID 0x00010001
+
// Container Types
#define MTP_CONTAINER_TYPE_UNDEFINED 0
#define MTP_CONTAINER_TYPE_COMMAND 1
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
index eaaa798166ec..988b229474b6 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
@@ -17,7 +17,8 @@
package com.android.mediaframeworktest;
import com.android.mediaframeworktest.performance.MediaPlayerPerformance;
-
+/*Video Editor performance Test cases*/
+import com.android.mediaframeworktest.performance.VideoEditorPerformance;
import junit.framework.TestSuite;
import android.test.InstrumentationTestRunner;
@@ -26,7 +27,7 @@ import android.test.InstrumentationTestSuite;
/**
* Instrumentation Test Runner for all MediaPlayer tests.
- *
+ *
* Running all tests:
*
* adb shell am instrument \
@@ -40,6 +41,8 @@ public class MediaFrameworkPerfTestRunner extends InstrumentationTestRunner {
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
suite.addTestSuite(MediaPlayerPerformance.class);
+ /*Video Editor performance Test cases*/
+ suite.addTestSuite(VideoEditorPerformance.class);
return suite;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java
index 543806135f26..0cd784cbce77 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java
@@ -19,6 +19,8 @@ package com.android.mediaframeworktest;
import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
import com.android.mediaframeworktest.stress.MediaPlayerStressTest;
+/** Import for Video Editor Stress Test cases*/
+import com.android.mediaframeworktest.stress.VideoEditorStressTest;
import junit.framework.TestSuite;
@@ -28,6 +30,8 @@ public class MediaPlayerStressTestRunner extends InstrumentationTestRunner {
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
suite.addTestSuite(MediaPlayerStressTest.class);
+ /** Video Editor Stress Test cases*/
+ suite.addTestSuite(VideoEditorStressTest.class);
return suite;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
index 4470740134fd..e84f762d9a9b 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
@@ -811,6 +811,7 @@ public class CodecTest {
try {
mMediaPlayer.setOnCompletionListener(mCompletionListener);
mMediaPlayer.setOnErrorListener(mOnErrorListener);
+ mMediaPlayer.setOnInfoListener(mInfoListener);
Log.v(TAG, "playMediaSamples: sample file name " + filePath);
mMediaPlayer.setDataSource(filePath);
mMediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/VideoEditorPreviewTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/VideoEditorPreviewTest.java
index bd0a83845777..9a7f4f2ee5c2 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/VideoEditorPreviewTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/VideoEditorPreviewTest.java
@@ -95,7 +95,7 @@ public class VideoEditorPreviewTest extends
private boolean previewStop;
/* Minimum waiting time for Semaphore to wait for release */
- private final long minWaitingTime = 1000;
+ private final long minWaitingTime = 3000;
// Declares the annotation for Preview Test Cases
public @interface Preview {
@@ -473,8 +473,8 @@ public class VideoEditorPreviewTest extends
mVideoEditorHelper.checkProgressCBValues(progressValues);
final SurfaceHolder surfaceHolder =
MediaFrameworkTest.mSurfaceView.getHolder();
-
- long waitingTime = minWaitingTime + 10000;
+ /* As transition takes more time buffer of 10 sec is added */
+ long waitingTime = minWaitingTime + 10000 + 10000;
blockTillPreviewCompletes.acquire();
try {
@@ -691,31 +691,34 @@ public class VideoEditorPreviewTest extends
long waitingTime = minWaitingTime + mVideoEditor.getDuration();
+
blockTillPreviewCompletes.acquire();
+ final String fileName = mVideoEditor.getPath() + "\test.3gp";
+ final int height = MediaProperties.HEIGHT_480;
+ final int bitrate = MediaProperties.BITRATE_512K;
+
+ try {
+ mVideoEditor.export(fileName, height, bitrate,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve,
+ String outFileName,int progress) {
+
+ }
+ });
+ } catch (IOException e) {
+ assertTrue("UnExpected Error in Export" +
+ e.toString(), false);
+ }
final SurfaceHolder surfaceHolder =
MediaFrameworkTest.mSurfaceView.getHolder();
try {
+
mVideoEditor.startPreview(surfaceHolder, 5000, -1, false, 1,
new PreviewProgressListener() {
- final String fileName = mVideoEditor.getPath() + "\test.3gp";
- final int height = MediaProperties.HEIGHT_360;
- final int bitrate = MediaProperties.BITRATE_512K;
+
public void onProgress(VideoEditor videoEditor, long timeMs,
OverlayData overlayData) {
- if (timeMs >= 10000)
- try {
- videoEditor.export(fileName, height, bitrate,
- new ExportProgressListener() {
- public void onProgress(VideoEditor ve,
- String outFileName,int progress) {
-
- }
- });
- } catch (IOException e) {
- assertTrue("UnExpected Error in Export" +
- e.toString(), false);
- }
}
public void onStart(VideoEditor videoEditor) {
setPreviewStart();
@@ -725,10 +728,10 @@ public class VideoEditorPreviewTest extends
blockTillPreviewCompletes.release();
}
});
+
} catch (Exception e) {
blockTillPreviewCompletes.release();
}
-
blockTillPreviewCompletes.tryAcquire(waitingTime, TimeUnit.MILLISECONDS);
mVideoEditor.stopPreview();
assertTrue("Preview Failed to start", previewStart);
@@ -837,31 +840,7 @@ public class VideoEditorPreviewTest extends
mVideoEditor.renderPreviewFrame(surfaceHolder, 7000,
overlayData1));
- long waitingTime = minWaitingTime + (mVideoEditor.getDuration() - 5000);
-
- blockTillPreviewCompletes.acquire();
- try {
- mVideoEditor.startPreview(surfaceHolder, 5000, -1, false, 1,
- new PreviewProgressListener() {
- public void onProgress(VideoEditor videoEditor, long timeMs,
- OverlayData overlayData) {
- }
- public void onStart(VideoEditor videoEditor) {
- setPreviewStart();
- }
- public void onStop(VideoEditor videoEditor) {
- setPreviewStop();
- blockTillPreviewCompletes.release();
- }
- });
- } catch (Exception e) {
- blockTillPreviewCompletes.release();
- }
- blockTillPreviewCompletes.tryAcquire(waitingTime, TimeUnit.MILLISECONDS);
- mVideoEditor.stopPreview();
- assertTrue("Preview Failed to start", previewStart);
- assertTrue("Preview Failed to stop", previewStop);
- blockTillPreviewCompletes.release();
+ validatePreviewProgress(5000, -1, false, mVideoEditor.getDuration());
}
/**
@@ -1142,20 +1121,19 @@ public class VideoEditorPreviewTest extends
duration = mVideoEditor.getDuration();
/* RenderPreviewFrame returns -1 to indicate last frame */
try {
- assertEquals("Render preview Frame at item duration", -1,
mVideoEditor.renderPreviewFrame(surfaceHolder, duration,
- overlayData1));
- } catch ( Exception e) {
- assertTrue (" Render Preview Frame without generate", false);
+ overlayData1);
+ } catch ( IllegalStateException e) {
+ flagForException = true;
}
+ assertTrue (" Render Preview Frame without generate", flagForException);
duration = mVideoEditor.getDuration() + 1000;
try {
mVideoEditor.renderPreviewFrame(surfaceHolder, duration,
overlayData1);
- } catch ( IllegalStateException e) {
+ } catch ( IllegalArgumentException e) {
flagForException = true;
}
assertTrue (" Preview time greater than duration", flagForException);
}
-
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java
new file mode 100644
index 000000000000..4481d0004156
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java
@@ -0,0 +1,1086 @@
+/*
+ * 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.mediaframeworktest.performance;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.Writer;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.media.videoeditor.AudioTrack;
+import android.media.videoeditor.EffectColor;
+import android.media.videoeditor.EffectKenBurns;
+import android.media.videoeditor.MediaImageItem;
+import android.media.videoeditor.MediaItem;
+import android.media.videoeditor.MediaProperties;
+import android.media.videoeditor.MediaVideoItem;
+import android.media.videoeditor.OverlayFrame;
+import android.media.videoeditor.Transition;
+import android.media.videoeditor.TransitionCrossfade;
+import android.media.videoeditor.TransitionAlpha;
+import android.media.videoeditor.TransitionFadeBlack;
+import android.media.videoeditor.TransitionSliding;
+import android.media.videoeditor.VideoEditor;
+import android.os.Environment;
+import android.test.ActivityInstrumentationTestCase;
+import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
+import android.os.Environment;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase;
+import android.media.videoeditor.VideoEditor.ExportProgressListener;
+
+import android.util.Log;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import com.android.mediaframeworktest.VideoEditorHelper;
+
+/**
+ * Junit / Instrumentation - performance measurement for media player and
+ * recorder
+ */
+public class VideoEditorPerformance extends
+ ActivityInstrumentationTestCase<MediaFrameworkTest> {
+
+ private final String TAG = "VideoEditorPerformance";
+
+ private final String PROJECT_LOCATION = VideoEditorHelper.PROJECT_LOCATION_COMMON;
+
+ private final String INPUT_FILE_PATH = VideoEditorHelper.INPUT_FILE_PATH_COMMON;
+
+ private final String VIDEOEDITOR_OUTPUT = PROJECT_LOCATION +
+ "VideoEditorPerformance.txt";
+
+ public VideoEditorPerformance() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ }
+
+ private final String PROJECT_CLASS_NAME =
+ "android.media.videoeditor.VideoEditorImpl";
+ private VideoEditor mVideoEditor;
+ private VideoEditorHelper mVideoEditorHelper;
+
+ @Override
+ protected void setUp() throws Exception {
+ // setup for each test case.
+ super.setUp();
+ mVideoEditorHelper = new VideoEditorHelper();
+ // Create a random String which will be used as project path, where all
+ // project related files will be stored.
+ final String projectPath =
+ mVideoEditorHelper.createRandomFile(PROJECT_LOCATION);
+ mVideoEditor = mVideoEditorHelper.createVideoEditor(projectPath);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mVideoEditorHelper.destroyVideoEditor(mVideoEditor);
+ // Clean the directory created as project path
+ mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
+ System.gc();
+ super.tearDown();
+ }
+
+ private void writeTimingInfo(String testCaseName, String[] information)
+ throws Exception {
+ File outFile = new File(VIDEOEDITOR_OUTPUT);
+ Writer output = new BufferedWriter(new FileWriter(outFile, true));
+ output.write(testCaseName + "\n\t");
+ for (int i = 0; i < information.length; i++) {
+ output.write(information[i]);
+ }
+ output.write("\n\n");
+ output.close();
+ }
+
+ private final int NUM_OF_ITERATIONS=20;
+
+ private float calculateTimeTaken(long beginTime, int numIterations)
+ throws Exception {
+ final long duration2 = SystemClock.uptimeMillis();
+ final long durationToCreateMediaItem = (duration2 - beginTime);
+ final float timeTaken1 = (float)durationToCreateMediaItem *
+ 1.0f/(float)numIterations;
+ return (timeTaken1);
+ }
+
+ private void createVideoItems(MediaVideoItem[] mediaVideoItem,
+ String videoItemFileName, int renderingMode, int startTime, int endTime) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mediaVideoItem[i] = new MediaVideoItem(mVideoEditor, "m" + i,
+ videoItemFileName, renderingMode);
+ mediaVideoItem[i].setExtractBoundaries(startTime, endTime);
+ } catch (Exception e1) {
+ assertTrue(
+ "Can not create an object of Video Item with file name = "
+ + videoItemFileName + "------ID:m" + i + " Issue = "
+ + e1.toString(), false);
+ }
+ }
+ }
+
+ private void addVideoItems(MediaVideoItem[] mediaVideoItem) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mVideoEditor.addMediaItem(mediaVideoItem[i]);
+ } catch (Exception e1) {
+ assertTrue(
+ "Can not add an object of Video Item with ID:m" + i +
+ " Issue = " + e1.toString(), false);
+ }
+ }
+ }
+
+ private void removeVideoItems(MediaVideoItem[] mediaVideoItem) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mVideoEditor.removeMediaItem(mediaVideoItem[i].getId());
+ } catch (Exception e1) {
+ assertTrue(
+ "Can not Remove an object of Video Item with ID:m" + i +
+ " Issue = " + e1.toString(), false);
+ }
+ }
+ }
+
+ private void createImageItems(MediaImageItem[] mIi,
+ String imageItemFileName, int renderingMode, int duration) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mIi[i] = new MediaImageItem(mVideoEditor, "m" + i,
+ imageItemFileName, duration, renderingMode);
+ } catch (Exception e1) {
+ assertTrue( " Cannot create Image Item", false);
+ }
+ }
+ }
+
+ private void addImageItems(MediaImageItem[] mIi) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mVideoEditor.addMediaItem(mIi[i]);
+ } catch (Exception e1) {
+ assertTrue("Cannot add Image item", false);
+ }
+ }
+ }
+
+ private void removeImageItems(MediaImageItem[] mIi) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mVideoEditor.removeMediaItem(mIi[i].getId());
+ } catch (Exception e1) {
+ assertTrue("Cannot remove image item", false);
+ }
+ }
+ }
+ /**
+ * To test the performance of adding and removing the video media item
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_001
+ @LargeTest
+ public void testPerformanceAddRemoveVideoItem() throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int videoItemStartTime = 0;
+ final int videoItemEndTime = 5000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[3];
+ final MediaVideoItem[] mediaVideoItem =
+ new MediaVideoItem[NUM_OF_ITERATIONS];
+ float timeTaken = 0.0f;
+ long startTime = 0;
+
+ /** Time Take for creation of Media Video Item */
+ startTime = SystemClock.uptimeMillis();
+ createVideoItems(mediaVideoItem, videoItemFileName, renderingMode,
+ videoItemStartTime, videoItemEndTime);
+
+ timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Time taken to Create Media Video Item\t" +
+ timeTaken;
+
+ /** Time Take for Addition of Media Video Item */
+ startTime = SystemClock.uptimeMillis();
+ addVideoItems(mediaVideoItem);
+ timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
+ loggingInfo[1] = "\n\tTime taken to Add Media Video Item\t"
+ + timeTaken;
+
+ /** Time Take for Removal of Media Video Item */
+ startTime = SystemClock.uptimeMillis();
+ removeVideoItems(mediaVideoItem);
+ timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
+ loggingInfo[2] = "\n\tTime taken to remove Media Video Item\t"
+ + timeTaken;
+
+ writeTimingInfo("testPerformanceAddRemoveVideoItem (in mSec)", loggingInfo);
+ }
+
+ /**
+ * To test the performance of adding and removing the image media item
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_002
+ @LargeTest
+ public void testPerformanceAddRemoveImageItem() throws Exception {
+ final String imageItemFileName = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
+ final int imageItemDuration = 0;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[3];
+ final MediaImageItem[] mediaImageItem =
+ new MediaImageItem[NUM_OF_ITERATIONS];
+ float timeTaken = 0.0f;
+
+ long beginTime = SystemClock.uptimeMillis();
+ createImageItems(mediaImageItem, imageItemFileName, renderingMode,
+ imageItemDuration);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Time taken to Create Media Image Item\t" +
+ timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ addImageItems(mediaImageItem);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[1] = "\n\tTime taken to add Media Image Item\t" +
+ timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ removeImageItems(mediaImageItem);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[2] = "\n\tTime taken to remove Media Image Item\t"
+ + timeTaken;
+
+ writeTimingInfo("testPerformanceAddRemoveImageItem (in mSec)",
+ loggingInfo);
+ }
+
+ /**
+ * To test the performance of adding and removing the transition
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_003
+ @LargeTest
+ public void testPerformanceAddRemoveTransition() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int videoItemStartTime1 = 0;
+ final int videoItemEndTime1 = 20000;
+ final String videoItemFileName2 = INPUT_FILE_PATH
+ + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int videoItemStartTime2 = 0;
+ final int videoItemEndTime2 = 20000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int transitionDuration = 5000;
+ final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
+ final String[] loggingInfo = new String[3];
+ float timeTaken = 0.0f;
+
+ final MediaVideoItem[] mediaVideoItem =
+ new MediaVideoItem[(NUM_OF_ITERATIONS *10) + 1];
+
+ for (int i = 0; i < (NUM_OF_ITERATIONS *10); i+=2) {
+ try {
+ mediaVideoItem[i] = new MediaVideoItem(mVideoEditor, "m" + i,
+ videoItemFileName1, renderingMode);
+ mediaVideoItem[i+1] = new MediaVideoItem(mVideoEditor,
+ "m" + (i+1), videoItemFileName2, renderingMode);
+ mediaVideoItem[i].setExtractBoundaries(videoItemStartTime1,
+ videoItemEndTime1);
+ mediaVideoItem[i+1].setExtractBoundaries(videoItemStartTime2,
+ videoItemEndTime2);
+ } catch (Exception e1) {
+ assertTrue("Can not create Video Object Item with file name = "
+ + e1.toString(), false);
+ }
+ mVideoEditor.addMediaItem(mediaVideoItem[i]);
+ mVideoEditor.addMediaItem(mediaVideoItem[i+1]);
+ }
+ mediaVideoItem[(NUM_OF_ITERATIONS *10)] = new MediaVideoItem(mVideoEditor,
+ "m" + (NUM_OF_ITERATIONS *10), videoItemFileName1, renderingMode);
+ mediaVideoItem[(NUM_OF_ITERATIONS *10)].setExtractBoundaries(
+ videoItemStartTime1, videoItemEndTime1);
+ mVideoEditor.addMediaItem(mediaVideoItem[(NUM_OF_ITERATIONS *10)]);
+ final TransitionCrossfade tranCrossfade[] =
+ new TransitionCrossfade[(NUM_OF_ITERATIONS *10)];
+
+ long beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < (NUM_OF_ITERATIONS *10); i++) {
+ tranCrossfade[i] = new TransitionCrossfade("transition" + i,
+ mediaVideoItem[i], mediaVideoItem[i+1], transitionDuration,
+ transitionBehavior);
+ }
+ timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
+ loggingInfo[0] = "Time taken to Create CrossFade Transition\t" +
+ timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < (NUM_OF_ITERATIONS *10); i++) {
+ mVideoEditor.addTransition(tranCrossfade[i]);
+ }
+ timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
+ loggingInfo[1] = "\n\tTime taken to add CrossFade Transition\t" +
+ timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < (NUM_OF_ITERATIONS *10); i++) {
+ assertEquals("Removing Transitions", tranCrossfade[i], mVideoEditor
+ .removeTransition(tranCrossfade[i].getId()));
+ }
+ timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
+ loggingInfo[2] = "\n\tTime taken to remove CrossFade Transition\t" +
+ timeTaken;
+
+ writeTimingInfo("testPerformanceAddRemoveTransition (in mSec)", loggingInfo);
+ }
+
+ /**
+ * To test performance of Export
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_004
+ @LargeTest
+ public void testPerformanceExport() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int outHeight = MediaProperties.HEIGHT_480;
+ final int outBitrate = MediaProperties.BITRATE_256K;
+ final int outVcodec = MediaProperties.VCODEC_H264BP;
+ final String[] loggingInfo = new String[1];
+ final String outFilename = mVideoEditorHelper
+ .createRandomFile(mVideoEditor.getPath() + "/") + ".3gp";
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_12Mbps_AACLC_44.1khz_64kbps_s_1_17.mp4";
+ final String imageItemFileName1 = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
+ final String videoItemFileName2 = INPUT_FILE_PATH +
+ "H264_BP_640x480_15fps_1200Kbps_AACLC_48KHz_32kbps_m_1_17.3gp";
+ final String imageItemFileName2 = INPUT_FILE_PATH + "IMG_176x144.jpg";
+ final String videoItemFileName3 = INPUT_FILE_PATH +
+ "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_161kbps_s_0_26.mp4";
+ final String overlayFile = INPUT_FILE_PATH + "IMG_640x480_Overlay1.png";
+ final String audioTrackFilename = INPUT_FILE_PATH +
+ "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
+ final String maskFilename = INPUT_FILE_PATH +
+ "TransitionSpiral_QVGA.jpg";
+
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFileName1, renderingMode);
+ mediaItem1.setExtractBoundaries(0, 20000);
+ mVideoEditor.addMediaItem(mediaItem1);
+
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2", imageItemFileName1, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3", videoItemFileName2, renderingMode);
+ mediaItem3.setExtractBoundaries(0, 20000);
+ mVideoEditor.addMediaItem(mediaItem3);
+
+ final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor,
+ "m4", imageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem4);
+
+ final MediaVideoItem mediaItem5 = new MediaVideoItem(mVideoEditor,
+ "m5", videoItemFileName3, renderingMode);
+ mediaItem5.setExtractBoundaries(0, 20000);
+ mVideoEditor.addMediaItem(mediaItem5);
+ /**
+ * 7.Add TransitionAlpha, Apply this Transition as Begin for Media Item 1
+ * with duration = 2 sec behavior = BEHAVIOR_LINEAR, mask file name =
+ * TransitionSpiral_QVGA.jpg , blending percent = 50%, invert = true;
+ * */
+ final TransitionAlpha transition1 =
+ mVideoEditorHelper.createTAlpha("transition1", null, mediaItem1,
+ 2000, Transition.BEHAVIOR_LINEAR, maskFilename, 50, true);
+ mVideoEditor.addTransition(transition1);
+
+ /**
+ * 8.Add Transition Sliding between MediaItem 2 and 3 ,
+ * Sliding Direction = DIRECTION_RIGHT_OUT_LEFT_IN,
+ * behavior = BEHAVIOR_MIDDLE_FAST and duration = 4sec
+ * */
+ final TransitionSliding transition2And3 =
+ mVideoEditorHelper.createTSliding("transition2", mediaItem2,
+ mediaItem3, 4000, Transition.BEHAVIOR_MIDDLE_FAST,
+ TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN);
+ mVideoEditor.addTransition(transition2And3);
+
+ /**
+ * 9.Add Transition Crossfade between Media Item 3 and 4,
+ * behavior = BEHAVIOR_MIDDLE_SLOW, duration = 3.5 sec
+ * */
+ final TransitionCrossfade transition3And4 =
+ mVideoEditorHelper.createTCrossFade("transition3", mediaItem3,
+ mediaItem4, 3500, Transition.BEHAVIOR_MIDDLE_SLOW);
+ mVideoEditor.addTransition(transition3And4);
+
+ /**
+ * 10.Add Transition Fadeblack between Media Item 4 and 5,
+ * behavior = BEHAVIOR_SPEED_DOWN, duration = 3.5 sec
+ * */
+ final TransitionFadeBlack transition4And5 =
+ mVideoEditorHelper.createTFadeBlack("transition4", mediaItem4,
+ mediaItem5, 3500, Transition.BEHAVIOR_SPEED_DOWN);
+ mVideoEditor.addTransition(transition4And5);
+
+ /**
+ * 11.Add Effect 1 type="TYPE_SEPIA" to the MediaItem 1,
+ * start time=1sec and duration =4secs
+ * */
+ final EffectColor effectColor1 = mVideoEditorHelper.createEffectItem(
+ mediaItem1, "effect1", 1000, 4000, EffectColor.TYPE_SEPIA, 0);
+ mediaItem1.addEffect(effectColor1);
+
+ /**
+ * 12.Add Overlay 1 to the MediaItem 3: Frame Overlay with start time = 1 sec
+ * duration = 4 sec with item = IMG_640x480_Overlay1.png
+ * */
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(overlayFile, 640,
+ 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem3, "overlay",
+ mBitmap, 1000, 4000);
+ mediaItem3.addOverlay(overlayFrame);
+ /**
+ * 13.Add Effect 2 type="TYPE_NEGATIVE" to the MediaItem 2,
+ * start time=8sec and duration =2secs
+ * */
+ final EffectColor effectColor2 = mVideoEditorHelper.createEffectItem(
+ mediaItem2, "effect2", 8000, 2000, EffectColor.TYPE_NEGATIVE, 0);
+ mediaItem2.addEffect(effectColor2);
+ /**
+ * 14.Add Effect 3 type="TYPE_COLOR" to the MediaItem 3, color param = "PINK",
+ * start time=5 sec and duration =3secs
+ * */
+ final EffectColor effectColor3 = mVideoEditorHelper.createEffectItem(
+ mediaItem3, "effect3", 5000, 3000, EffectColor.TYPE_COLOR,
+ EffectColor.PINK);
+ mediaItem3.addEffect(effectColor3);
+ /**
+ * 15.Add Effect 4 type="TYPE_FIFTIES" to the MediaItem 4,
+ * start time=2 sec and duration =1secs
+ * */
+ final EffectColor effectColor4 = mVideoEditorHelper.createEffectItem(
+ mediaItem4, "effect4", 2000, 1000, EffectColor.TYPE_FIFTIES, 0);
+ mediaItem4.addEffect(effectColor4);
+ /**
+ * 16.Add KenBurnsEffect for MediaItem 4 with
+ * duration = 3 sec and startTime = 4 sec
+ * StartRect
+ * left = org_height/3 ; top = org_width/3
+ * bottom = org_width/2 ; right = org_height/2
+ * EndRect
+ * left = 0 ; top = 0
+ * bottom = org_height; right = org_width
+ * */
+
+ final Rect startRect = new Rect((mediaItem4.getHeight() / 3),
+ (mediaItem4.getWidth() / 3), (mediaItem4.getHeight() / 2),
+ (mediaItem4.getWidth() / 2));
+ final Rect endRect = new Rect(0, 0, mediaItem4.getWidth(),
+ mediaItem4.getHeight());
+ final EffectKenBurns kbEffectOnMediaItem = new EffectKenBurns(
+ mediaItem4, "KBOnM2", startRect, endRect,4000 , 3000);
+ mediaItem4.addEffect(kbEffectOnMediaItem);
+
+ /** 17.Add Audio Track,Set extract boundaries o to 10 sec.
+ * */
+ final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
+ mVideoEditor, "audioTrack", audioTrackFilename);
+ mVideoEditor.addAudioTrack(audioTrack);
+ /** 18.Enable Looping for Audio Track.
+ * */
+ audioTrack.enableLoop();
+ float timeTaken = 0.0f;
+ final long beginTime = SystemClock.uptimeMillis();
+ try {
+ mVideoEditor.export(outFilename, outHeight, outBitrate,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve,
+ String outFileName, int progress) {
+ }
+ });
+ } catch (Exception e) {
+ assertTrue("Error in Export" + e.toString(), false);
+ }
+ mVideoEditorHelper.checkDeleteExistingFile(outFilename);
+
+ timeTaken = calculateTimeTaken(beginTime, 1);
+ loggingInfo[0] = "Time taken to do ONE export of storyboard duration\t"
+ + mVideoEditor.getDuration() + " is :\t" + timeTaken;
+
+ writeTimingInfo("testPerformanceExport (in mSec)", loggingInfo);
+ mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
+ }
+
+
+ /**
+ * To test the performance of thumbnail extraction
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_005
+ @LargeTest
+ public void testPerformanceThumbnailVideoItem() throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH
+ + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int videoItemStartTime = 0;
+ final int videoItemEndTime = 20000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFileName, renderingMode);
+ mediaVideoItem.setExtractBoundaries(videoItemStartTime,
+ videoItemEndTime);
+
+ float timeTaken = 0.0f;
+ long beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ mediaVideoItem.getThumbnail(mediaVideoItem.getWidth() / 2,
+ mediaVideoItem.getHeight() / 2, i);
+ }
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Duration taken to get Video Thumbnails\t" +
+ timeTaken;
+
+ writeTimingInfo("testPerformanceThumbnailVideoItem (in mSec)", loggingInfo);
+ }
+
+ /**
+ * To test the performance of adding and removing the overlay to media item
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_006
+ @LargeTest
+ public void testPerformanceOverlayVideoItem() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int videoItemStartTime1 = 0;
+ final int videoItemEndTime1 = 10000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String overlayFilename = INPUT_FILE_PATH
+ + "IMG_640x480_Overlay1.png";
+ final int overlayStartTime = 1000;
+ final int overlayDuration = 5000;
+
+ final String[] loggingInfo = new String[2];
+ MediaVideoItem mediaVideoItem = null;
+
+ try {
+ mediaVideoItem = new MediaVideoItem(mVideoEditor, "m0",
+ videoItemFileName1, renderingMode);
+ mediaVideoItem.setExtractBoundaries(videoItemStartTime1,
+ videoItemEndTime1);
+ } catch (Exception e1) {
+ assertTrue("Can not create Video Item with file name = "
+ + e1.toString(), false);
+ }
+ final OverlayFrame overlayFrame[] = new OverlayFrame[NUM_OF_ITERATIONS];
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(overlayFilename,
+ 640, 480);
+ float timeTaken = 0.0f;
+ long beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ overlayFrame[i] = new OverlayFrame(mediaVideoItem, "overlay" + i,
+ mBitmap, overlayStartTime, overlayDuration);
+ mediaVideoItem.addOverlay(overlayFrame[i]);
+ }
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Time taken to add & create Overlay\t" + timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ assertEquals("Removing Overlays", overlayFrame[i],
+ mediaVideoItem.removeOverlay((overlayFrame[i].getId())));
+ }
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[1] = "\n\tTime taken to remove Overlay\t" +
+ timeTaken;
+
+ writeTimingInfo("testPerformanceOverlayVideoItem (in mSec)", loggingInfo);
+ }
+
+ /**
+ * To test the performance of get properties of a Video media item
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_007
+ @LargeTest
+ public void testPerformanceVideoItemProperties() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int videoItemStartTime1 = 0;
+ final int videoItemEndTime1 = 10100;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_3_2;
+ final int fileType = MediaProperties.FILE_MP4;
+ final int videoCodecType = MediaProperties.VCODEC_H264BP;
+ final int duration = 77366;
+ final int videoBitrate = 3169971;
+ final int fps = 30;
+ final int videoProfile = MediaProperties.H264_PROFILE_0_LEVEL_1_3;
+ final int width = 1080;
+ final int height = MediaProperties.HEIGHT_720;
+ float timeTaken = 0.0f;
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m0", videoItemFileName1, renderingMode);
+ mediaVideoItem.setExtractBoundaries(videoItemStartTime1,
+ videoItemEndTime1);
+ long beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < (NUM_OF_ITERATIONS*10); i++) {
+ try {
+ assertEquals("Aspect Ratio Mismatch",
+ aspectRatio, mediaVideoItem.getAspectRatio());
+ assertEquals("File Type Mismatch",
+ fileType, mediaVideoItem.getFileType());
+ assertEquals("VideoCodec Mismatch",
+ videoCodecType, mediaVideoItem.getVideoType());
+ assertEquals("duration Mismatch",
+ duration, mediaVideoItem.getDuration());
+ assertEquals("Video Profile ",
+ videoProfile, mediaVideoItem.getVideoProfile());
+ assertEquals("Video height ",
+ height, mediaVideoItem.getHeight());
+ assertEquals("Video width ",
+ width, mediaVideoItem.getWidth());
+ } catch (Exception e1) {
+ assertTrue("Can not create Video Item with file name = "
+ + e1.toString(), false);
+ }
+ }
+ timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS*10));
+ loggingInfo[0] = "Time taken to get Media Properties\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceVideoItemProperties:", loggingInfo);
+ }
+
+ /**
+ * To test the performance of generatePreview : with Transitions
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_008
+ @LargeTest
+ public void testPerformanceGeneratePreviewWithTransitions()
+ throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String imageItemFileName = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
+ long averageTime = 0;
+ final String[] loggingInfo = new String[1];
+
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName, renderingMode);
+ mediaVideoItem.setExtractBoundaries(0, 10000);
+ mVideoEditor.addMediaItem(mediaVideoItem);
+
+ final MediaImageItem mediaImageItem = new MediaImageItem(mVideoEditor,
+ "mediaItem2", imageItemFileName, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaImageItem);
+
+ final TransitionCrossfade transitionCrossFade = new TransitionCrossfade(
+ "transitionCrossFade", mediaVideoItem, mediaImageItem,
+ 5000, transitionBehavior);
+ mVideoEditor.addTransition(transitionCrossFade);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ final long duration2 = SystemClock.uptimeMillis();
+ mVideoEditor.removeTransition(transitionCrossFade.getId());
+ mVideoEditor.addTransition(transitionCrossFade);
+ averageTime += (duration2 - duration1);
+ }
+ final long durationToAddObjects = averageTime;
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken to Generate Preview with transition\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceGeneratePreviewWithTransitions:",
+ loggingInfo);
+ }
+
+ /**
+ * To test the performance of generatePreview : with KenBurn
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_009
+ @LargeTest
+ public void testPerformanceWithKenBurn() throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String imageItemFileName = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ long averageTime = 0;
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName, renderingMode);
+ mediaVideoItem.setExtractBoundaries(0, 10000);
+ mVideoEditor.addMediaItem(mediaVideoItem);
+
+ final MediaImageItem mediaImageItem = new MediaImageItem(mVideoEditor,
+ "mediaItem2", imageItemFileName, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaImageItem);
+
+ final Rect startRect = new Rect((mediaImageItem.getHeight() / 3),
+ (mediaImageItem.getWidth() / 3), (mediaImageItem.getHeight() / 2),
+ (mediaImageItem.getWidth() / 2));
+ final Rect endRect = new Rect(0, 0, mediaImageItem.getWidth(),
+ mediaImageItem.getHeight());
+ final EffectKenBurns kbEffectOnMediaItem =
+ new EffectKenBurns(mediaImageItem, "KBOnM2", startRect, endRect,
+ 500, 3000);
+ mediaImageItem.addEffect(kbEffectOnMediaItem);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ final long duration2 = SystemClock.uptimeMillis();
+ mediaImageItem.removeEffect(kbEffectOnMediaItem.getId());
+ mediaImageItem.addEffect(kbEffectOnMediaItem);
+ averageTime += duration2 - duration1;
+ }
+
+ final long durationToAddObjects = (averageTime);
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken to Generate KenBurn Effect \t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceWithKenBurn", loggingInfo);
+ }
+
+ /**
+ * To test the performance of generatePreview : with Transitions and
+ * Effect,Overlapping scenario
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_010
+ @LargeTest
+ public void testPerformanceEffectOverlappingTransition() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String videoItemFileName2 = INPUT_FILE_PATH
+ + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int videoStartTime1 = 0;
+ final int videoEndTime1 = 10000;
+ final int videoStartTime2 = 0;
+ final int videoEndTime2 = 10000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int transitionDuration = 5000;
+ final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
+ final int effectItemStartTime = 5000;
+ final int effectItemDurationTime = 5000;
+ final int effectType = EffectColor.TYPE_COLOR;
+ final int effectColorType = EffectColor.GREEN;
+ long averageDuration = 0;
+
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaVideoItem1 = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName1, renderingMode);
+ mediaVideoItem1.setExtractBoundaries(videoStartTime1, videoEndTime1);
+ mVideoEditor.addMediaItem(mediaVideoItem1);
+
+ final MediaVideoItem mediaVideoItem2 = new MediaVideoItem(mVideoEditor,
+ "mediaItem2", videoItemFileName2, renderingMode);
+ mediaVideoItem2.setExtractBoundaries(videoStartTime2, videoEndTime2);
+ mVideoEditor.addMediaItem(mediaVideoItem2);
+
+ final TransitionCrossfade transitionCrossFade = new TransitionCrossfade(
+ "transitionCrossFade", mediaVideoItem1, mediaVideoItem2,
+ transitionDuration, transitionBehavior);
+ mVideoEditor.addTransition(transitionCrossFade);
+
+ final EffectColor effectColor = new EffectColor(mediaVideoItem1,
+ "effect", effectItemStartTime, effectItemDurationTime, effectType,
+ effectColorType);
+ mediaVideoItem1.addEffect(effectColor);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ final long duration2 = SystemClock.uptimeMillis();
+ mVideoEditor.removeTransition(transitionCrossFade.getId());
+ mVideoEditor.addTransition(transitionCrossFade);
+ averageDuration += (duration2 - duration1);
+ }
+ SystemClock.uptimeMillis();
+ final long durationToAddObjects = (averageDuration);
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] =
+ "Time taken to testPerformanceEffectOverlappingTransition\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceEffectOverlappingTransition:",
+ loggingInfo);
+ }
+
+ /**
+ * To test creation of story board with Transition and Two Effects, Effect
+ * overlapping transitions
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_011
+ @LargeTest
+ public void testPerformanceTransitionWithEffectOverlapping() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String videoItemFileName2 = INPUT_FILE_PATH
+ + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int transitionDuration = 5000;
+ final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
+ final int effectItemStartTime1 = 5000;
+ final int effectItemDurationTime1 = 5000;
+ final int effectType1 = EffectColor.TYPE_COLOR;
+ final int effectColorType1 = EffectColor.GREEN;
+ final int effectItemStartTime2 = 5000;
+ final int effectItemDurationTime2 = 5000;
+ final int effectType2 = EffectColor.TYPE_COLOR;
+ final int effectColorType2 = EffectColor.GREEN;
+ int averageTime = 0;
+ final String[] loggingInfo = new String[1];
+
+ final MediaVideoItem mediaVideoItem1 = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaVideoItem1);
+
+ final MediaVideoItem mediaVideoItem2 = new MediaVideoItem(mVideoEditor,
+ "mediaItem2", videoItemFileName2, renderingMode);
+ mVideoEditor.addMediaItem(mediaVideoItem2);
+
+ final TransitionCrossfade transitionCrossFade = new TransitionCrossfade(
+ "transitionCrossFade", mediaVideoItem1, mediaVideoItem2,
+ transitionDuration, transitionBehavior);
+ mVideoEditor.addTransition(transitionCrossFade);
+
+ final EffectColor effectColor1 = new EffectColor(mediaVideoItem1,
+ "effect1", effectItemStartTime1, effectItemDurationTime1,
+ effectType1, effectColorType1);
+ mediaVideoItem1.addEffect(effectColor1);
+
+ final EffectColor effectColor2 = new EffectColor(mediaVideoItem2,
+ "effect2", effectItemStartTime2, effectItemDurationTime2,
+ effectType2, effectColorType2);
+ mediaVideoItem2.addEffect(effectColor2);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ final long duration2 = SystemClock.uptimeMillis();
+ mVideoEditor.removeTransition(transitionCrossFade.getId());
+ mVideoEditor.addTransition(transitionCrossFade);
+ averageTime += duration2 - duration1;
+ }
+ final long durationToAddObjects = (averageTime);
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken to TransitionWithEffectOverlapping\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceTransitionWithEffectOverlapping",
+ loggingInfo);
+ }
+
+ /**
+ *To test ThumbnailList for H264
+ */
+ // TODO : TC_PRF_12
+ @LargeTest
+ public void testThumbnailH264NonIFrame() throws Exception {
+ final String videoItemFilename = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int outWidth = 1080;
+ final int outHeight = 720;
+ final int atTime = 2400;
+ long durationToAddObjects = 0;
+ int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFilename, renderingMode);
+ assertNotNull("MediaVideoItem", mediaVideoItem);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mediaVideoItem.getThumbnail(outWidth, outHeight, atTime + i);
+ final long duration2 = SystemClock.uptimeMillis();
+ durationToAddObjects += (duration2 - duration1);
+ }
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken for Thumbnail generation \t"
+ + timeTaken;
+ writeTimingInfo("testThumbnailH264NonIFrame", loggingInfo);
+ }
+
+ /**
+ *To test ThumbnailList for H264
+ */
+ // TODO : TC_PRF_13
+ @LargeTest
+ public void testThumbnailH264AnIFrame() throws Exception {
+ final String videoItemFilename = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int outWidth = 1080;
+ final int outHeight = 720;
+ final int atTime = 3000;
+ int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+ long durationToAddObjects = 0;
+
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFilename, renderingMode);
+ assertNotNull("MediaVideoItem", mediaVideoItem);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mediaVideoItem.getThumbnail(outWidth, outHeight, atTime + i);
+ final long duration2 = SystemClock.uptimeMillis();
+ durationToAddObjects += (duration2 - duration1);
+ }
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken Thumbnail generation \t"
+ + timeTaken;
+ writeTimingInfo("testThumbnailH264AnIFrame", loggingInfo);
+ }
+
+ /**
+ * To test the performance : With an audio track
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_014
+ @LargeTest
+ public void testPerformanceWithAudioTrack() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String audioFilename1 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ final String audioFilename2 = INPUT_FILE_PATH +
+ "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int audioVolume = 50;
+ final String[] loggingInfo = new String[2];
+ float timeTaken = 0.0f;
+
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaVideoItem);
+
+ final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
+ "Audio Track1", audioFilename1);
+ audioTrack1.disableDucking();
+ audioTrack1.setVolume(audioVolume);
+ mVideoEditor.addAudioTrack(audioTrack1);
+
+ long beginTime = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ timeTaken = calculateTimeTaken(beginTime, 1);
+ loggingInfo[0] = "Time taken for 1st Audio Track (AACLC)\t"
+ + timeTaken;
+
+ final AudioTrack audioTrack2 = new AudioTrack(mVideoEditor,
+ "Audio Track2", audioFilename2);
+ audioTrack2.enableLoop();
+
+ beginTime = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ timeTaken = calculateTimeTaken(beginTime, 1);
+ loggingInfo[1] = "\n\tTime taken for 2nd Audio Track(AMRNB)\t"
+ + timeTaken;
+
+ writeTimingInfo("testPerformanceWithAudioTrack", loggingInfo);
+ }
+
+ /**
+ * To test the performance of adding and removing the
+ * image media item with 640 x 480
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_015
+ @LargeTest
+ public void testPerformanceAddRemoveImageItem640x480() throws Exception {
+ final String imageItemFileName = INPUT_FILE_PATH + "IMG_640x480.jpg";
+ final int imageItemDuration = 0;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[3];
+
+ float timeTaken = 0.0f;
+
+ final MediaImageItem[] mediaImageItem =
+ new MediaImageItem[NUM_OF_ITERATIONS];
+ long beginTime = SystemClock.uptimeMillis();
+ createImageItems(mediaImageItem, imageItemFileName, renderingMode,
+ imageItemDuration);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Time taken to Create Media Image Item (640x480)\t"
+ + timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ addImageItems(mediaImageItem);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[1] = "\n\tTime taken to add Media Image Item (640x480)\t"
+ + timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ removeImageItems(mediaImageItem);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[2] = "\n\tTime taken to remove Media Image Item (640x480)\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceAddRemoveImageItem640x480 (in mSec)", loggingInfo);
+ }
+
+
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
index 20e29360e964..b2086d6d4e86 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
@@ -67,7 +67,7 @@ public class MediaPlayerStressTest extends InstrumentationTestCase {
output.write(" Error: " + CodecTest.mPlaybackError);
output.write(" Unknown Info: " + CodecTest.mMediaInfoUnknownCount);
output.write(" Track Lagging: " + CodecTest.mMediaInfoVideoTrackLaggingCount);
- output.write(" BadInterleaving: " + CodecTest.mMediaInfoBadInterleavingCount);
+ output.write(" Bad Interleaving: " + CodecTest.mMediaInfoBadInterleavingCount);
output.write(" Not Seekable: " + CodecTest.mMediaInfoNotSeekableCount);
output.write(" Info Meta data update: " + CodecTest.mMediaInfoMetdataUpdateCount);
output.write("\n");
@@ -75,13 +75,13 @@ public class MediaPlayerStressTest extends InstrumentationTestCase {
private void writeTestSummary(Writer output) throws Exception{
output.write("Total Result:\n");
- output.write(" Complete: " + mTotalComplete);
- output.write(" Error: " + mTotalPlaybackError);
- output.write(" Unknown Info: " + mTotalInfoUnknown);
- output.write(" Track Lagging: " + mTotalVideoTrackLagging );
- output.write(" BadInterleaving: " + mTotalBadInterleaving);
- output.write(" Not Seekable: " + mTotalNotSeekable);
- output.write(" Info Meta data update: " + mTotalMetaDataUpdate);
+ output.write("Total Complete: " + mTotalComplete + "\n");
+ output.write("Total Error: " + mTotalPlaybackError + "\n");
+ output.write("Total Unknown Info: " + mTotalInfoUnknown + "\n");
+ output.write("Total Track Lagging: " + mTotalVideoTrackLagging + "\n" );
+ output.write("Total Bad Interleaving: " + mTotalBadInterleaving + "\n");
+ output.write("Total Not Seekable: " + mTotalNotSeekable + "\n");
+ output.write("Total Info Meta data update: " + mTotalMetaDataUpdate + "\n");
output.write("\n");
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java
new file mode 100755
index 000000000000..0e70dd3fd368
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java
@@ -0,0 +1,1317 @@
+/*
+ * 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.mediaframeworktest.stress;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.Writer;
+import java.util.List;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.media.videoeditor.AudioTrack;
+import android.media.videoeditor.EffectColor;
+import android.media.videoeditor.EffectKenBurns;
+import android.media.videoeditor.MediaImageItem;
+import android.media.videoeditor.MediaItem;
+import android.media.videoeditor.MediaProperties;
+import android.media.videoeditor.MediaVideoItem;
+import android.media.videoeditor.OverlayFrame;
+import android.media.videoeditor.Transition;
+import android.media.videoeditor.TransitionCrossfade;
+import android.media.videoeditor.TransitionAlpha;
+import android.media.videoeditor.TransitionFadeBlack;
+import android.media.videoeditor.TransitionSliding;
+import android.media.videoeditor.VideoEditor;
+import android.os.Environment;
+import android.test.ActivityInstrumentationTestCase;
+import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
+import android.os.Environment;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase;
+import android.media.videoeditor.VideoEditor.ExportProgressListener;
+import android.media.videoeditor.VideoEditorFactory;
+import android.media.videoeditor.ExtractAudioWaveformProgressListener;
+
+import android.os.Debug;
+import android.util.Log;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import com.android.mediaframeworktest.VideoEditorHelper;
+
+/**
+ * Junit / Instrumentation - performance measurement for media player and
+ * recorder
+ */
+public class VideoEditorStressTest
+ extends ActivityInstrumentationTestCase<MediaFrameworkTest> {
+
+ private final String TAG = "VideoEditorPerformance";
+
+ private final String PROJECT_LOCATION = VideoEditorHelper.PROJECT_LOCATION_COMMON;
+
+ private final String INPUT_FILE_PATH = VideoEditorHelper.INPUT_FILE_PATH_COMMON;
+
+ private final String VIDEOEDITOR_OUTPUT = PROJECT_LOCATION +
+ "VideoEditorStressMemOutput.txt";
+
+ private long BeginJavaMemory;
+ private long AfterJavaMemory;
+
+ private long BeginNativeMemory;
+ private long AfterNativeMemory;
+
+ public VideoEditorStressTest() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ new File(VIDEOEDITOR_OUTPUT).delete();
+ }
+
+ private final String PROJECT_CLASS_NAME =
+ "android.media.videoeditor.VideoEditorImpl";
+ private VideoEditor mVideoEditor;
+ private VideoEditorHelper mVideoEditorHelper;
+
+ @Override
+ protected void setUp() throws Exception {
+ // setup for each test case.
+ super.setUp();
+ mVideoEditorHelper = new VideoEditorHelper();
+ // Create a random String which will be used as project path, where all
+ // project related files will be stored.
+ final String projectPath =
+ mVideoEditorHelper.createRandomFile(PROJECT_LOCATION);
+ mVideoEditor = mVideoEditorHelper.createVideoEditor(projectPath);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mVideoEditorHelper.destroyVideoEditor(mVideoEditor);
+ // Clean the directory created as project path
+ mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
+ System.gc();
+ super.tearDown();
+ }
+
+ private void writeTimingInfo(String[] information)
+ throws Exception {
+ File outFile = new File(VIDEOEDITOR_OUTPUT);
+ Writer output = new BufferedWriter(new FileWriter(outFile, true));
+ for (int i = 0; i < information.length; i++) {
+ output.write(information[i]);
+ }
+ output.close();
+ }
+
+ private void writeTestCaseHeader(String testCaseName)
+ throws Exception {
+ File outFile = new File(VIDEOEDITOR_OUTPUT);
+ Writer output = new BufferedWriter(new FileWriter(outFile, true));
+ output.write("\n\n" + testCaseName + "\n");
+ output.close();
+ }
+
+ private void getBeginMemory() throws Exception {
+ System.gc();
+ Thread.sleep(2500);
+ BeginNativeMemory = Debug.getNativeHeapAllocatedSize();
+ }
+ private void getAfterMemory_updateLog(String[] loggingInfo, boolean when,
+ int iteration)
+ throws Exception {
+ System.gc();
+ Thread.sleep(2500);
+ AfterNativeMemory = Debug.getNativeHeapAllocatedSize();
+ if(when == false){
+ loggingInfo[0] = "\n Before Remove: iteration No.= " + iteration +
+ "\t " + (AfterNativeMemory - BeginNativeMemory);
+ } else {
+ loggingInfo[0] = "\n After Remove: iteration No.= " + iteration +
+ "\t " + (AfterNativeMemory - BeginNativeMemory);
+ }
+ writeTimingInfo(loggingInfo);
+ }
+
+ /**
+ * To stress test MediaItem(Video Item) adding functionality
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_001
+ @LargeTest
+ public void testStressAddRemoveVideoItem() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_176x144_15fps_144kbps_AMRNB_8kHz_12.2kbps_m_1_17.3gp";
+ final String videoItemFileName2 = INPUT_FILE_PATH +
+ "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_96kbps_s_0_21.mp4";
+ final String videoItemFileName3 = INPUT_FILE_PATH +
+ "H263_profile0_176x144_15fps_128kbps_1_35.3gp";
+ final String videoItemFileName4 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
+ final String[] loggingInfo = new String[1];
+ writeTestCaseHeader("testStressAddRemoveVideoItem");
+ int i = 0;
+ getBeginMemory();
+
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1" + i, videoItemFileName1, renderingMode);
+ mediaItem1.setExtractBoundaries(0, 5000);
+ mVideoEditor.addMediaItem(mediaItem1);
+ }
+ if (i % 4 == 1) {
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
+ "m2" + i, videoItemFileName2, renderingMode);
+ mediaItem2.setExtractBoundaries(0, 10000);
+ mVideoEditor.addMediaItem(mediaItem2);
+ }
+ if (i % 4 == 2) {
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3" + i, videoItemFileName3, renderingMode);
+ mediaItem3.setExtractBoundaries(30000, 45000);
+ mVideoEditor.addMediaItem(mediaItem3);
+ }
+ if (i % 4 == 3) {
+ final MediaVideoItem mediaItem4 = new MediaVideoItem(mVideoEditor,
+ "m4" + i, videoItemFileName4, renderingMode);
+ mediaItem4.setExtractBoundaries(10000, 30000);
+ mVideoEditor.addMediaItem(mediaItem4);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ mVideoEditor.removeMediaItem("m1" + i);
+ }
+ if (i % 4 == 1) {
+ mVideoEditor.removeMediaItem("m2" + i);
+ }
+ if (i % 4 == 2) {
+ mVideoEditor.removeMediaItem("m3" + i);
+ }
+ if (i % 4 == 3) {
+ mVideoEditor.removeMediaItem("m4" + i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test MediaItem(Image Item) adding functionality
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_002
+ @LargeTest
+ public void testStressAddRemoveImageItem() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String ImageItemFileName1 = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String ImageItemFileName3 = INPUT_FILE_PATH +
+ "IMG_320x240.jpg";
+ final String ImageItemFileName4 = INPUT_FILE_PATH +
+ "IMG_176x144.jpg";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ writeTestCaseHeader("testStressAddRemoveImageItem");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final MediaImageItem mediaItem1 = new MediaImageItem(mVideoEditor,
+ "m1"+ i, ImageItemFileName1, 5000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ }
+ if (i % 4 == 1) {
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2"+ i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ }
+ if (i % 4 == 2) {
+ final MediaImageItem mediaItem3 = new MediaImageItem(mVideoEditor,
+ "m3"+ i, ImageItemFileName3, 15000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem3);
+ }
+ if (i % 4 == 3) {
+ final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor,
+ "m4"+ i, ImageItemFileName4, 20000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem4);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ mVideoEditor.removeMediaItem("m1"+i);
+ }
+ if (i % 4 == 1) {
+ mVideoEditor.removeMediaItem("m2"+i);
+ }
+ if (i % 4 == 2) {
+ mVideoEditor.removeMediaItem("m3"+i);
+ }
+ if (i % 4 == 3) {
+ mVideoEditor.removeMediaItem("m4"+i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test transition
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_003
+ @LargeTest
+ public void testStressAddRemoveTransition() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_800x480_15fps_512kbps_1_17.mp4";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final String VideoItemFileName3 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final String maskFilename = INPUT_FILE_PATH +
+ "TransitionSpiral_QVGA.jpg";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ writeTestCaseHeader("testStressAddRemoveTransition");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1"+i, VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+ final TransitionCrossfade tranCrossfade =
+ new TransitionCrossfade("transCF" + i, null,
+ mediaItem1, 5000, Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor.addTransition(tranCrossfade);
+ }
+ if (i % 4 == 1) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1"+i, VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2" +i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final TransitionAlpha transitionAlpha =
+ mVideoEditorHelper.createTAlpha("transAlpha" + i, mediaItem1,
+ mediaItem2, 5000, Transition.BEHAVIOR_SPEED_UP,
+ maskFilename, 10, false);
+ transitionAlpha.setDuration(4000);
+ mVideoEditor.addTransition(transitionAlpha);
+ }
+ if (i % 4 == 2) {
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2" + i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3" + i, VideoItemFileName3, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem3);
+
+ mediaItem3.setExtractBoundaries(0, 10000);
+ final TransitionAlpha transitionAlpha =
+ mVideoEditorHelper.createTAlpha("transAlpha" + i, mediaItem2,
+ mediaItem3, 5000, Transition.BEHAVIOR_SPEED_UP,
+ maskFilename, 10, false);
+ transitionAlpha.setDuration(4000);
+ mVideoEditor.addTransition(transitionAlpha);
+
+ mediaItem3.setExtractBoundaries(0, 6000);
+
+ final TransitionSliding transition2And3 =
+ mVideoEditorHelper.createTSliding("transSlide" +i, mediaItem2,
+ mediaItem3, 3000, Transition.BEHAVIOR_MIDDLE_FAST,
+ TransitionSliding.DIRECTION_LEFT_OUT_RIGHT_IN);
+ mVideoEditor.addTransition(transition2And3);
+ }
+ if (i % 4 == 3) {
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3" + i, VideoItemFileName3, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem3);
+ mediaItem3.setExtractBoundaries(0, 5000);
+
+ final TransitionFadeBlack transition3 =
+ mVideoEditorHelper.createTFadeBlack("transFB" +i, mediaItem3,
+ null, 2500, Transition.BEHAVIOR_SPEED_UP);
+ transition3.setDuration(500);
+ mVideoEditor.addTransition(transition3);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ mVideoEditor.removeTransition("transCF" + i);
+ mVideoEditor.removeMediaItem("m1" + i);
+ }
+ if (i % 4 == 1) {
+ mVideoEditor.removeTransition("transAlpha" + i);
+ mVideoEditor.removeMediaItem("m1" + i);
+ mVideoEditor.removeMediaItem("m2" + i);
+ }
+ if (i % 4 == 2) {
+ mVideoEditor.removeTransition("transSlide" +i);
+ mVideoEditor.removeMediaItem("m2" + i);
+ mVideoEditor.removeMediaItem("m3" + i);
+ }
+ if (i % 4 == 3) {
+ mVideoEditor.removeMediaItem("m3" + i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test overlay
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_004
+ @LargeTest
+ public void testStressAddRemoveOverlay() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String OverlayFile3 = INPUT_FILE_PATH +
+ "IMG_640x480_Overlay1.png";
+ final String OverlayFile4 = INPUT_FILE_PATH +
+ "IMG_640x480_Overlay2.png";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2", ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ writeTestCaseHeader("testStressAddRemoveOverlay");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 3 == 0) {
+ mediaItem1.setExtractBoundaries(0, 10000);
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(
+ OverlayFile3, 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem1, "overlay" + i,
+ mBitmap, 1000, 5000);
+ mediaItem1.addOverlay(overlayFrame);
+ mediaItem1.removeOverlay("overlay"+i);
+ }
+ if (i % 3 == 1) {
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(
+ OverlayFile4, 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem2, "overlay" + i,
+ mBitmap, 1000, 5000);
+ mediaItem2.addOverlay(overlayFrame);
+ mediaItem2.removeOverlay("overlay"+i);
+ }
+ if (i % 3 == 2) {
+ mediaItem1.setExtractBoundaries(0, 10000);
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(
+ OverlayFile4, 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem1, "overlay" + i,
+ mBitmap, 0, mediaItem1.getDuration());
+ mediaItem1.addOverlay(overlayFrame);
+ mediaItem1.removeOverlay("overlay"+i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+
+ /**
+ * To stress test Effects
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_005
+ @LargeTest
+ public void testStressAddRemoveEffects() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2", ImageItemFileName2, 10000, renderingMode);
+ int i = 0;
+ mVideoEditor.addMediaItem(mediaItem2);
+ writeTestCaseHeader("testStressAddRemoveEffects");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 5 == 0) {
+ mediaItem1.setExtractBoundaries(10000, 30000);
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem1, "effect1"+i,
+ 10000, (mediaItem1.getTimelineDuration()-1000),
+ EffectColor.TYPE_COLOR, EffectColor.GREEN);
+ mediaItem1.addEffect(effectColor1);
+ }
+ if (i % 5 == 1) {
+ mediaItem2.setDuration(20000);
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem2, "effect1"+i,
+ 0, 4000, EffectColor.TYPE_GRADIENT, EffectColor.GRAY);
+ mediaItem2.addEffect(effectColor1);
+ }
+ if (i % 5 == 2) {
+ mediaItem1.setExtractBoundaries(10000, 30000);
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem1, "effect1"+i,
+ (mediaItem1.getTimelineDuration() - 4000), 4000,
+ EffectColor.TYPE_SEPIA, 0);
+ mediaItem1.addEffect(effectColor1);
+ }
+ if (i % 5 == 3) {
+ mediaItem2.setDuration(20000);
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem2, "effect1"+i,
+ 10000, 4000, EffectColor.TYPE_NEGATIVE, 0);
+ mediaItem2.addEffect(effectColor1);
+ }
+ if (i % 5 == 4) {
+ mediaItem2.setDuration(20000);
+ final Rect startRect = new Rect((mediaItem2.getHeight() / 3),
+ (mediaItem2.getWidth() / 3), (mediaItem2.getHeight() / 2),
+ (mediaItem2.getWidth() / 2));
+ final Rect endRect = new Rect(0, 0, mediaItem2.getWidth(),
+ mediaItem2.getHeight());
+ final EffectKenBurns kbEffectOnMediaItem = new EffectKenBurns(
+ mediaItem2, "KBOnM2" + i, startRect, endRect, 500,
+ (mediaItem2.getDuration() - 500));
+ mediaItem2.addEffect(kbEffectOnMediaItem);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 5 == 0) {
+ mediaItem1.removeEffect("effect1"+i);
+ }
+ if (i % 5 == 1) {
+ mediaItem1.removeEffect("effect1"+i);
+ }
+ if (i % 5 == 2) {
+ mediaItem1.removeEffect("effect1"+i);
+ }
+ if (i % 5 == 3) {
+ mediaItem1.removeEffect("effect1"+i);
+ }
+ if (i % 5 == 4) {
+ mediaItem1.removeEffect("KBOnM2"+i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * This method will test thumbnail list extraction in a loop = 200 for Video
+ * Item
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_006
+ @LargeTest
+ public void testStressThumbnailVideoItem() throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH
+ + "H264_BP_640x480_15fps_1200Kbps_AACLC_48KHz_64kps_m_0_27.3gp";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFileName, renderingMode);
+ writeTestCaseHeader("testStressThumbnailVideoItem");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final Bitmap[] thumbNails =
+ mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth()*3,
+ mediaVideoItem.getHeight()*2, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 1) {
+ final Bitmap[] thumbNails =
+ mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth()/2,
+ mediaVideoItem.getHeight() * 3, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 2) {
+ final Bitmap[] thumbNails =
+ mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth()*2,
+ mediaVideoItem.getHeight() / 3, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 3) {
+ final Bitmap[] thumbNails =
+ mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth(),
+ mediaVideoItem.getHeight(), i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+
+ /**
+ * To stress test media properties
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_007
+ @LargeTest
+ public void testStressMediaProperties() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String AudioItemFileName3 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final int videoAspectRatio = MediaProperties.ASPECT_RATIO_3_2;
+ final int videoFileType = MediaProperties.FILE_MP4;
+ final int videoCodecType = MediaProperties.VCODEC_H264BP;
+ final int videoDuration = 77366;
+ final int videoProfile = MediaProperties.H264_PROFILE_0_LEVEL_1_3;
+ final int videoHeight = MediaProperties.HEIGHT_720;
+ final int videoWidth = 1080;
+
+ final int imageAspectRatio = MediaProperties.ASPECT_RATIO_4_3;
+ final int imageFileType = MediaProperties.FILE_JPEG;
+ final int imageWidth = 640;
+ final int imageHeight = MediaProperties.HEIGHT_480;
+
+ final int audioDuration = 77554;
+ final int audioCodecType = MediaProperties.ACODEC_AAC_LC;
+ final int audioSamplingFrequency = 44100;
+ final int audioChannel = 2;
+ writeTestCaseHeader("testStressMediaProperties");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 3 == 0) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1" + i, VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 20000);
+ assertEquals("Aspect Ratio Mismatch",
+ videoAspectRatio, mediaItem1.getAspectRatio());
+ assertEquals("File Type Mismatch",
+ videoFileType, mediaItem1.getFileType());
+ assertEquals("VideoCodec Mismatch",
+ videoCodecType, mediaItem1.getVideoType());
+ assertEquals("duration Mismatch",
+ videoDuration, mediaItem1.getDuration());
+ assertEquals("Video Profile ",
+ videoProfile, mediaItem1.getVideoProfile());
+ assertEquals("Video height ",
+ videoHeight, mediaItem1.getHeight());
+ assertEquals("Video width ",
+ videoWidth, mediaItem1.getWidth());
+ mVideoEditor.removeMediaItem("m1" + i);
+ }
+ if (i % 3 == 1) {
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2" + i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ assertEquals("Aspect Ratio Mismatch",
+ imageAspectRatio, mediaItem2.getAspectRatio());
+ assertEquals("File Type Mismatch",
+ imageFileType, mediaItem2.getFileType());
+ assertEquals("Image height",
+ imageHeight, mediaItem2.getHeight());
+ assertEquals("Image width",
+ imageWidth, mediaItem2.getWidth());
+ mVideoEditor.removeMediaItem("m2" + i);
+ }
+ if (i % 3 == 2) {
+ final AudioTrack mediaItem3 = new AudioTrack(mVideoEditor,
+ "m3" + i, AudioItemFileName3);
+ mVideoEditor.addAudioTrack(mediaItem3);
+ assertEquals("AudioType Mismatch", audioCodecType,
+ mediaItem3.getAudioType());
+ assertEquals("Audio Sampling", audioSamplingFrequency,
+ mediaItem3.getAudioSamplingFrequency());
+ assertEquals("Audio Channels",
+ audioChannel, mediaItem3.getAudioChannels());
+ assertEquals("duration Mismatch", audioDuration,
+ mediaItem3.getDuration());
+ mVideoEditor.removeAudioTrack("m3" + i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+
+ /**
+ * To stress test insert and move of mediaitems
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_008
+ @LargeTest
+ public void testStressInsertMovieItems() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String VideoItemFileName2 = INPUT_FILE_PATH +
+ "H264_BP_800x480_15fps_512kbps_1_17.mp4";
+ final String VideoItemFileName3 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ writeTestCaseHeader("testStressInsertMoveItems");
+
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
+ "m2", VideoItemFileName2, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ mediaItem2.setExtractBoundaries(0, 15000);
+
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3" + i, VideoItemFileName3, renderingMode);
+ mediaItem3.setExtractBoundaries(0, 15000);
+ mVideoEditor.insertMediaItem(mediaItem3, "m1");
+ mVideoEditor.moveMediaItem("m2", "m3" + i);
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ mVideoEditor.removeMediaItem("m3" + i);
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ mVideoEditor.removeMediaItem("m2");
+ mVideoEditor.removeMediaItem("m1");
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test : load and save
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_009
+ @LargeTest
+ public void testStressLoadAndSave() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String VideoItemFileName2 = INPUT_FILE_PATH +
+ "H264_BP_800x480_15fps_512kbps_1_17.mp4";
+ final String VideoItemFileName3 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
+ final String ImageItemFileName4 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String ImageItemFileName5 = INPUT_FILE_PATH +
+ "IMG_176x144.jpg";
+ final String OverlayFile6 = INPUT_FILE_PATH +
+ "IMG_640x480_Overlay1.png";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final String[] projectPath = new String[10];
+ writeTestCaseHeader("testStressLoadAndSave");
+ getBeginMemory();
+ for( i=0; i < 10; i++){
+
+ projectPath[i] =
+ mVideoEditorHelper.createRandomFile(PROJECT_LOCATION);
+ final VideoEditor mVideoEditor1 =
+ mVideoEditorHelper.createVideoEditor(projectPath[i]);
+
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor1,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor1,
+ "m2", VideoItemFileName2, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem2);
+ mediaItem2.setExtractBoundaries(mediaItem2.getDuration()/4,
+ mediaItem2.getDuration()/2);
+
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor1,
+ "m3", VideoItemFileName3, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem3);
+ mediaItem3.setExtractBoundaries(mediaItem3.getDuration()/2,
+ mediaItem3.getDuration());
+
+ final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor1,
+ "m4", ImageItemFileName4, 5000, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem4);
+
+ final MediaImageItem mediaItem5 = new MediaImageItem(mVideoEditor1,
+ "m5", ImageItemFileName5, 5000, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem5);
+
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem3, "effect1",
+ 10000, 2000, EffectColor.TYPE_COLOR, EffectColor.GREEN);
+ mediaItem3.addEffect(effectColor1);
+
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(OverlayFile6,
+ 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem4, "overlay",
+ mBitmap, 4000, 1000);
+ mediaItem4.addOverlay(overlayFrame);
+
+ final TransitionCrossfade tranCrossfade =
+ new TransitionCrossfade("transCF", mediaItem1,
+ mediaItem2, 5000, Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor1.addTransition(tranCrossfade);
+
+ final EffectColor effectColor2 =
+ mVideoEditorHelper.createEffectItem(mediaItem4, "effect2", 0,
+ mediaItem4.getDuration(), EffectColor.TYPE_COLOR,
+ EffectColor.PINK);
+ mediaItem4.addEffect(effectColor2);
+
+ mVideoEditor1.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+
+ mVideoEditor1.save();
+ mVideoEditor1.release();
+
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for( i=0; i<10; i++){
+ final VideoEditor mVideoEditor1b =
+ VideoEditorFactory.load(projectPath[i], true);
+ List<MediaItem> mediaList = mVideoEditor1b.getAllMediaItems();
+ assertEquals("Media Item List Size", 5, mediaList.size());
+
+ mediaList.get(3).removeEffect("effect1");
+ mediaList.get(3).removeEffect("effect2");
+ mediaList.get(2).removeOverlay("overlay");
+ mVideoEditor1b.removeTransition("transCF");
+ mVideoEditor1b.removeMediaItem("m5");
+ mVideoEditor1b.removeMediaItem("m4");
+ mVideoEditor1b.removeMediaItem("m3");
+ mVideoEditor1b.removeMediaItem("m2");
+ mVideoEditor1b.removeMediaItem("m1");
+ mVideoEditor1b.release();
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test : Multiple Export
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_010
+ @LargeTest
+ public void testStressMultipleExport() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String VideoItemFileName2 = INPUT_FILE_PATH +
+ "H264_BP_800x480_15fps_512kbps_1_17.mp4";
+ final String[] loggingInfo = new String[1];
+ final String outFilename = mVideoEditorHelper.createRandomFile(
+ mVideoEditor.getPath() + "/") + ".3gp";
+ int i = 0;
+ writeTestCaseHeader("testStressMultipleExport");
+ getBeginMemory();
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
+ "m2", VideoItemFileName2, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ mediaItem2.setExtractBoundaries(0, 15000);
+
+ for ( i = 0; i < 50; i++) {
+ if(i%4 ==0){
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_4_3;
+ mVideoEditor.setAspectRatio(aspectRatio);
+ mVideoEditor.export(outFilename, MediaProperties.HEIGHT_480,
+ MediaProperties.BITRATE_256K,MediaProperties.ACODEC_AAC_LC,
+ MediaProperties.VCODEC_H263,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve, String outFileName,
+ int progress) {
+ }
+ });
+ }
+ if(i%4 ==1){
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_5_3;
+ mVideoEditor.setAspectRatio(aspectRatio);
+ mVideoEditor.export(outFilename, MediaProperties.HEIGHT_144,
+ MediaProperties.BITRATE_384K,MediaProperties.ACODEC_AAC_LC,
+ MediaProperties.VCODEC_MPEG4,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve, String outFileName,
+ int progress) {
+ }
+ });
+ }
+ if(i%4 ==2){
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_11_9;
+ mVideoEditor.setAspectRatio(aspectRatio);
+ mVideoEditor.export(outFilename, MediaProperties.HEIGHT_144,
+ MediaProperties.BITRATE_512K,MediaProperties.ACODEC_AAC_LC,
+ MediaProperties.VCODEC_H264BP,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve, String outFileName,
+ int progress) {
+ }
+ });
+ }
+ if(i%4 ==3){
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_3_2;
+ mVideoEditor.setAspectRatio(aspectRatio);
+ mVideoEditor.export(outFilename, MediaProperties.HEIGHT_480,
+ MediaProperties.BITRATE_800K,MediaProperties.ACODEC_AAC_LC,
+ MediaProperties.VCODEC_H264BP,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve, String outFileName,
+ int progress) {
+ }
+ });
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ mVideoEditor.removeMediaItem("m2");
+ mVideoEditor.removeMediaItem("m1");
+
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test Media Item,Overlays,Transitions and Ken Burn
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_011
+ @LargeTest
+ public void testStressOverlayTransKenBurn() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_640x480_30fps_256kbps_1_17.mp4";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String OverlayFile3 = INPUT_FILE_PATH +
+ "IMG_640x480_Overlay1.png";
+ final String audioFilename4 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ int i = 0;
+ final String[] loggingInfo = new String[1];
+ writeTestCaseHeader("testStressOverlayTransKenBurn");
+ getBeginMemory();
+ for ( i = 0; i < 10; i++) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1" + i, VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2" + i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem1, "effect1"+i,
+ (mediaItem1.getDuration() - 4000), 4000,
+ EffectColor.TYPE_SEPIA, 0);
+ mediaItem1.addEffect(effectColor1);
+
+ final TransitionCrossfade tranCrossfade =
+ new TransitionCrossfade("transCF" + i, mediaItem1,
+ mediaItem2, 4000, Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor.addTransition(tranCrossfade);
+
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(OverlayFile3,
+ 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem1, "overlay" + i,
+ mBitmap, 1000, 5000);
+ mediaItem1.addOverlay(overlayFrame);
+
+ final Rect startRect = new Rect((mediaItem2.getHeight() / 3),
+ (mediaItem2.getWidth() / 3), (mediaItem2.getHeight() / 2),
+ (mediaItem2.getWidth() / 2));
+ final Rect endRect = new Rect(0, 0, mediaItem2.getWidth(),
+ mediaItem2.getHeight());
+
+ final EffectKenBurns kbEffectOnMediaItem = new EffectKenBurns(
+ mediaItem2, "KBOnM2" + i, startRect, endRect, 500,
+ (mediaItem2.getDuration()-500));
+ mediaItem2.addEffect(kbEffectOnMediaItem);
+
+ if(i == 5) {
+ final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
+ "Audio Track1", audioFilename4);
+ mVideoEditor.addAudioTrack(audioTrack1);
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 10; i++) {
+ MediaImageItem m2 = (MediaImageItem)mVideoEditor.getMediaItem("m2"+i);
+ MediaVideoItem m1 = (MediaVideoItem)mVideoEditor.getMediaItem("m1"+i);
+ m2.removeEffect("KBOnM2" + i);
+ m1.removeOverlay("overlay" + i);
+ mVideoEditor.removeTransition("transCF" + i);
+ m1.removeEffect("effect1" + i);
+ mVideoEditor.removeMediaItem("m2" + i);
+ mVideoEditor.removeMediaItem("m1" + i);
+ if(i == 5) {
+ mVideoEditor.removeAudioTrack("Audio Track1");
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To test the performance : With an audio track with Video
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_012
+ @LargeTest
+ public void testStressAudioTrackVideo() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String audioFilename1 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ final String audioFilename2 = INPUT_FILE_PATH +
+ "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int audioVolume = 50;
+ final String[] loggingInfo = new String[1];
+ int i = 1;
+ writeTestCaseHeader("testStressAudioTrackVideo");
+ getBeginMemory();
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaVideoItem);
+
+ final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
+ "Audio Track1", audioFilename1);
+ audioTrack1.disableDucking();
+ audioTrack1.setVolume(audioVolume);
+ mVideoEditor.addAudioTrack(audioTrack1);
+
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+
+ mVideoEditor.removeAudioTrack("Audio Track1");
+
+ final AudioTrack audioTrack2 = new AudioTrack(mVideoEditor,
+ "Audio Track2", audioFilename2);
+ audioTrack2.enableLoop();
+
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ mVideoEditor.removeMediaItem("mediaItem1");
+
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To Test Stress : Story Board creation with out preview or export
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_013
+ @LargeTest
+ public void testStressStoryBoard() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_161kbps_s_0_26.mp4";
+ final String videoItemFileName2 = INPUT_FILE_PATH +
+ "MPEG4_SP_854x480_15fps_256kbps_AACLC_16khz_48kbps_s_0_26.mp4";
+ final String videoItemFileName3= INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final String imageItemFileName4 = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final String imageItemFileName5 = INPUT_FILE_PATH +
+ "IMG_176x144.jpg";
+ final String audioFilename6 = INPUT_FILE_PATH +
+ "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
+ final String audioFilename7 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int audioVolume = 50;
+ final String[] loggingInfo = new String[1];
+ int i = 1;
+
+ writeTestCaseHeader("testStressStoryBoard");
+ getBeginMemory();
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFileName1, renderingMode);
+ mediaItem1.setExtractBoundaries(0, 10000);
+ mVideoEditor.addMediaItem(mediaItem1);
+
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
+ "m2", videoItemFileName2, renderingMode);
+ mediaItem2.setExtractBoundaries(mediaItem2.getDuration()/4,
+ mediaItem2.getDuration()/2);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3", videoItemFileName3, renderingMode);
+ mediaItem3.setExtractBoundaries(mediaItem3.getDuration()/2,
+ mediaItem3.getDuration());
+ mVideoEditor.addMediaItem(mediaItem3);
+
+ final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor,
+ "m4", imageItemFileName4, 5000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem4);
+
+ final MediaImageItem mediaItem5 = new MediaImageItem(mVideoEditor,
+ "m5", imageItemFileName5, 5000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem5);
+
+ final TransitionCrossfade tranCrossfade =
+ new TransitionCrossfade("transCF", mediaItem2, mediaItem3, 2500,
+ Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor.addTransition(tranCrossfade);
+
+ final TransitionCrossfade tranCrossfade1 =
+ new TransitionCrossfade("transCF1", mediaItem3, mediaItem4, 2500,
+ Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor.addTransition(tranCrossfade1);
+
+ final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
+ "Audio Track1", audioFilename6);
+ mVideoEditor.addAudioTrack(audioTrack1);
+
+ mVideoEditor.removeAudioTrack("Audio Track1");
+ final AudioTrack audioTrack2 = new AudioTrack(mVideoEditor,
+ "Audio Track2", audioFilename7);
+ mVideoEditor.addAudioTrack(audioTrack2);
+ audioTrack2.enableLoop();
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ mVideoEditor.removeAudioTrack("Audio Track2");
+ mVideoEditor.removeTransition("transCF");
+ mVideoEditor.removeTransition("transCF1");
+ mVideoEditor.removeMediaItem("m5");
+ mVideoEditor.removeMediaItem("m4");
+ mVideoEditor.removeMediaItem("m3");
+ mVideoEditor.removeMediaItem("m2");
+ mVideoEditor.removeMediaItem("m1");
+
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To test the performance : With an audio track Only
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_014
+ @LargeTest
+ public void testStressAudioTrackOnly() throws Exception {
+
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String AudioItemFileName1 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ writeTestCaseHeader("testStressAudioTrackOnly");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ final AudioTrack mediaItem1 = new AudioTrack(mVideoEditor,
+ "m1" + i, AudioItemFileName1);
+ mVideoEditor.addAudioTrack(mediaItem1);
+ mediaItem1.enableLoop();
+ mVideoEditor.removeAudioTrack("m1" + i);
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+
+ /**
+ * This method will test thumbnail list extraction in a loop = 200 for Image
+ * Item
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_016 -- New Test Case
+ @LargeTest
+ public void testStressThumbnailImageItem() throws Exception {
+ final String imageItemFileName = INPUT_FILE_PATH + "IMG_640x480.jpg";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final MediaImageItem mediaImageItem = new MediaImageItem(mVideoEditor,
+ "m1", imageItemFileName, 5000, renderingMode);
+ writeTestCaseHeader("testStressThumbnailImageItem");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
+ mediaImageItem.getWidth() / 2 ,
+ mediaImageItem.getHeight() / 2, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 1) {
+ final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
+ mediaImageItem.getWidth() / 2,
+ mediaImageItem.getHeight() * 3, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 2) {
+ final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
+ mediaImageItem.getWidth() * 2,
+ mediaImageItem.getHeight() / 3, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 3) {
+ final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
+ mediaImageItem.getWidth(),
+ mediaImageItem.getHeight(), i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+}
diff --git a/native/include/android/input.h b/native/include/android/input.h
index 0ffb8b5fb1ef..d5160378dbb0 100644
--- a/native/include/android/input.h
+++ b/native/include/android/input.h
@@ -281,7 +281,13 @@ enum {
/* A non-primary pointer has gone up.
* The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
*/
- AMOTION_EVENT_ACTION_POINTER_UP = 6
+ AMOTION_EVENT_ACTION_POINTER_UP = 6,
+
+ /* A change happened but the pointer is not down (unlike AMOTION_EVENT_ACTION_MOVE).
+ * The motion contains the most recent point, as well as any intermediate points since
+ * the last hover move event.
+ */
+ AMOTION_EVENT_ACTION_HOVER_MOVE = 7,
};
/*
@@ -321,6 +327,51 @@ enum {
};
/*
+ * Constants that identify each individual axis of a motion event.
+ * Refer to the documentation on the MotionEvent class for descriptions of each axis.
+ */
+enum {
+ AMOTION_EVENT_AXIS_X = 0,
+ AMOTION_EVENT_AXIS_Y = 1,
+ AMOTION_EVENT_AXIS_PRESSURE = 2,
+ AMOTION_EVENT_AXIS_SIZE = 3,
+ AMOTION_EVENT_AXIS_TOUCH_MAJOR = 4,
+ AMOTION_EVENT_AXIS_TOUCH_MINOR = 5,
+ AMOTION_EVENT_AXIS_TOOL_MAJOR = 6,
+ AMOTION_EVENT_AXIS_TOOL_MINOR = 7,
+ AMOTION_EVENT_AXIS_ORIENTATION = 8,
+ AMOTION_EVENT_AXIS_VSCROLL = 9,
+ AMOTION_EVENT_AXIS_HSCROLL = 10,
+ AMOTION_EVENT_AXIS_Z = 11,
+ AMOTION_EVENT_AXIS_RX = 12,
+ AMOTION_EVENT_AXIS_RY = 13,
+ AMOTION_EVENT_AXIS_RZ = 14,
+ AMOTION_EVENT_AXIS_HAT_X = 15,
+ AMOTION_EVENT_AXIS_HAT_Y = 16,
+ AMOTION_EVENT_AXIS_LTRIGGER = 17,
+ AMOTION_EVENT_AXIS_RTRIGGER = 18,
+ AMOTION_EVENT_AXIS_GENERIC_1 = 32,
+ AMOTION_EVENT_AXIS_GENERIC_2 = 33,
+ AMOTION_EVENT_AXIS_GENERIC_3 = 34,
+ AMOTION_EVENT_AXIS_GENERIC_4 = 35,
+ AMOTION_EVENT_AXIS_GENERIC_5 = 36,
+ AMOTION_EVENT_AXIS_GENERIC_6 = 37,
+ AMOTION_EVENT_AXIS_GENERIC_7 = 38,
+ AMOTION_EVENT_AXIS_GENERIC_8 = 39,
+ AMOTION_EVENT_AXIS_GENERIC_9 = 40,
+ AMOTION_EVENT_AXIS_GENERIC_10 = 41,
+ AMOTION_EVENT_AXIS_GENERIC_11 = 42,
+ AMOTION_EVENT_AXIS_GENERIC_12 = 43,
+ AMOTION_EVENT_AXIS_GENERIC_13 = 44,
+ AMOTION_EVENT_AXIS_GENERIC_14 = 45,
+ AMOTION_EVENT_AXIS_GENERIC_15 = 46,
+ AMOTION_EVENT_AXIS_GENERIC_16 = 47,
+
+ // NOTE: If you add a new axis here you must also add it to several other files.
+ // Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
+};
+
+/*
* Input sources.
*
* Refer to the documentation on android.view.InputDevice for more details about input sources
@@ -363,39 +414,24 @@ enum {
};
/*
- * Constants that identify each individual axis of a motion event.
- */
-enum {
- AINPUT_MOTION_AXIS_X = 0,
- AINPUT_MOTION_AXIS_Y = 1,
- AINPUT_MOTION_AXIS_PRESSURE = 2,
- AINPUT_MOTION_AXIS_SIZE = 3,
- AINPUT_MOTION_AXIS_TOUCH_MAJOR = 4,
- AINPUT_MOTION_AXIS_TOUCH_MINOR = 5,
- AINPUT_MOTION_AXIS_TOOL_MAJOR = 6,
- AINPUT_MOTION_AXIS_TOOL_MINOR = 7,
- AINPUT_MOTION_AXIS_ORIENTATION = 8,
-};
-
-/*
* Constants used to retrieve information about the range of motion for a particular
* coordinate of a motion event.
*
* Refer to the documentation on android.view.InputDevice for more details about input sources
* and their correct interpretation.
*
- * DEPRECATION NOTICE: These constants are deprecated. Use AINPUT_MOTION_AXIS_* constants instead.
+ * DEPRECATION NOTICE: These constants are deprecated. Use AMOTION_EVENT_AXIS_* constants instead.
*/
enum {
- AINPUT_MOTION_RANGE_X = AINPUT_MOTION_AXIS_X,
- AINPUT_MOTION_RANGE_Y = AINPUT_MOTION_AXIS_Y,
- AINPUT_MOTION_RANGE_PRESSURE = AINPUT_MOTION_AXIS_PRESSURE,
- AINPUT_MOTION_RANGE_SIZE = AINPUT_MOTION_AXIS_SIZE,
- AINPUT_MOTION_RANGE_TOUCH_MAJOR = AINPUT_MOTION_AXIS_TOUCH_MAJOR,
- AINPUT_MOTION_RANGE_TOUCH_MINOR = AINPUT_MOTION_AXIS_TOUCH_MINOR,
- AINPUT_MOTION_RANGE_TOOL_MAJOR = AINPUT_MOTION_AXIS_TOOL_MAJOR,
- AINPUT_MOTION_RANGE_TOOL_MINOR = AINPUT_MOTION_AXIS_TOOL_MINOR,
- AINPUT_MOTION_RANGE_ORIENTATION = AINPUT_MOTION_AXIS_ORIENTATION,
+ AINPUT_MOTION_RANGE_X = AMOTION_EVENT_AXIS_X,
+ AINPUT_MOTION_RANGE_Y = AMOTION_EVENT_AXIS_Y,
+ AINPUT_MOTION_RANGE_PRESSURE = AMOTION_EVENT_AXIS_PRESSURE,
+ AINPUT_MOTION_RANGE_SIZE = AMOTION_EVENT_AXIS_SIZE,
+ AINPUT_MOTION_RANGE_TOUCH_MAJOR = AMOTION_EVENT_AXIS_TOUCH_MAJOR,
+ AINPUT_MOTION_RANGE_TOUCH_MINOR = AMOTION_EVENT_AXIS_TOUCH_MINOR,
+ AINPUT_MOTION_RANGE_TOOL_MAJOR = AMOTION_EVENT_AXIS_TOOL_MAJOR,
+ AINPUT_MOTION_RANGE_TOOL_MINOR = AMOTION_EVENT_AXIS_TOOL_MINOR,
+ AINPUT_MOTION_RANGE_ORIENTATION = AMOTION_EVENT_AXIS_ORIENTATION,
} __attribute__ ((deprecated));
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index f8809d7421e0..9017ca3a831a 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -17,11 +17,7 @@
package com.android.providers.settings;
import java.io.FileNotFoundException;
-import java.io.UnsupportedEncodingException;
-import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
-import java.util.LinkedHashMap;
-import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -47,6 +43,7 @@ import android.provider.MediaStore;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import android.util.LruCache;
public class SettingsProvider extends ContentProvider {
private static final String TAG = "SettingsProvider";
@@ -293,7 +290,7 @@ public class SettingsProvider extends ContentProvider {
"" + (MAX_CACHE_ENTRIES + 1) /* limit */);
try {
synchronized (cache) {
- cache.clear();
+ cache.evictAll();
cache.setFullyMatchesDisk(true); // optimistic
int rows = 0;
while (c.moveToNext()) {
@@ -359,8 +356,8 @@ public class SettingsProvider extends ContentProvider {
// possibly with a null value, or null on failure.
private Bundle lookupValue(String table, SettingsCache cache, String key) {
synchronized (cache) {
- if (cache.containsKey(key)) {
- Bundle value = cache.get(key);
+ Bundle value = cache.get(key);
+ if (value != null) {
if (value != TOO_LARGE_TO_CACHE_MARKER) {
return value;
}
@@ -725,13 +722,13 @@ public class SettingsProvider extends ContentProvider {
* associated helper functions to keep cache coherent with the
* database.
*/
- private static final class SettingsCache extends LinkedHashMap<String, Bundle> {
+ private static final class SettingsCache extends LruCache<String, Bundle> {
private final String mCacheName;
private boolean mCacheFullyMatchesDisk = false; // has the whole database slurped.
public SettingsCache(String name) {
- super(MAX_CACHE_ENTRIES, 0.75f /* load factor */, true /* access ordered */);
+ super(MAX_CACHE_ENTRIES);
mCacheName = name;
}
@@ -751,14 +748,8 @@ public class SettingsProvider extends ContentProvider {
}
@Override
- protected boolean removeEldestEntry(Map.Entry eldest) {
- if (size() <= MAX_CACHE_ENTRIES) {
- return false;
- }
- synchronized (this) {
- mCacheFullyMatchesDisk = false;
- }
- return true;
+ protected synchronized void entryEvicted(String key, Bundle value) {
+ mCacheFullyMatchesDisk = false;
}
/**
@@ -772,7 +763,7 @@ public class SettingsProvider extends ContentProvider {
Bundle bundle = (value == null) ? NULL_SETTING : Bundle.forPair("value", value);
if (value == null || value.length() <= MAX_CACHE_ENTRY_SIZE) {
synchronized (this) {
- if (!containsKey(key)) {
+ if (get(key) == null) {
put(key, bundle);
}
}
@@ -826,7 +817,7 @@ public class SettingsProvider extends ContentProvider {
return;
}
synchronized (cache) {
- cache.clear();
+ cache.evictAll();
cache.mCacheFullyMatchesDisk = false;
}
}
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notification_dnd.png b/packages/SystemUI/res/drawable-mdpi/ic_notification_dnd.png
new file mode 100644
index 000000000000..6d4da7f1233d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notification_dnd.png
Binary files differ
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml b/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml
index c358e13c8f47..d7e16337d47f 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_recent_item.xml
@@ -58,26 +58,33 @@
/>
<TextView android:id="@+id/app_label"
- android:layout_width="113dip"
+ android:layout_width="97dip"
android:layout_height="wrap_content"
android:textSize="18dip"
- android:fadingEdge="none"
- android:fadingEdgeLength="0dp"
+ android:fadingEdge="horizontal"
+ android:fadingEdgeLength="10dip"
android:scrollHorizontally="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="16dip"
android:layout_marginTop="32dip"
+ android:singleLine="true"
+ android:ellipsize="marquee"
/>
<TextView android:id="@+id/app_description"
- android:layout_width="wrap_content"
+ android:layout_width="97dip"
android:layout_height="wrap_content"
android:textSize="18dip"
+ android:fadingEdge="horizontal"
+ android:fadingEdgeLength="10dip"
+ android:scrollHorizontally="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="16dip"
android:layout_marginTop="61dip"
+ android:singleLine="true"
+ android:ellipsize="marquee"
/>
</RelativeLayout>
diff --git a/packages/SystemUI/res/values-xlarge/strings.xml b/packages/SystemUI/res/values-xlarge/strings.xml
index dfd5851c6ae8..35be53208008 100644
--- a/packages/SystemUI/res/values-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-xlarge/strings.xml
@@ -43,4 +43,11 @@
<!-- Notification text: when GPS has found a fix [CHAR LIMIT=50] -->
<string name="gps_notification_found_text">Location set by GPS</string>
+
+ <!-- Title for the pseudo-notification shown when notifications are disabled (do-not-disturb
+ mode) -->
+ <string name="notifications_off_title">Notifications off</string>
+
+ <!-- Content text for do-not-disturb mode notification -->
+ <string name="notifications_off_text">Tap here to turn notifications back on.</string>
</resources>
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 dfe0262dd525..0273a4c70076 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -599,16 +599,6 @@ public class PhoneStatusBarPolicy {
return (mSignalStrength != null) && !mSignalStrength.isGsm();
}
- private boolean isEvdo() {
- return ( (mServiceState != null)
- && ((mServiceState.getRadioTechnology()
- == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
- || (mServiceState.getRadioTechnology()
- == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
- || (mServiceState.getRadioTechnology()
- == ServiceState.RADIO_TECHNOLOGY_EVDO_B)));
- }
-
private boolean hasService() {
if (mServiceState != null) {
switch (mServiceState.getState()) {
@@ -624,7 +614,6 @@ public class PhoneStatusBarPolicy {
}
private final void updateSignalStrength() {
- int iconLevel = -1;
int[] iconList;
// Display signal strength while in "emergency calls only" mode
@@ -641,18 +630,6 @@ public class PhoneStatusBarPolicy {
}
if (!isCdma()) {
- int asu = mSignalStrength.getGsmSignalStrength();
-
- // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
- // asu = 0 (-113dB or less) is very weak
- // signal, its better to show 0 bars to the user in such cases.
- // asu = 99 is a special case, where the signal strength is unknown.
- if (asu <= 2 || asu == 99) iconLevel = 0;
- else if (asu >= 12) iconLevel = 4;
- else if (asu >= 8) iconLevel = 3;
- else if (asu >= 5) iconLevel = 2;
- else iconLevel = 1;
-
// Though mPhone is a Manager, this call is not an IPC
if (mPhone.isNetworkRoaming()) {
iconList = sSignalImages_r[mInetCondition];
@@ -661,67 +638,11 @@ public class PhoneStatusBarPolicy {
}
} else {
iconList = sSignalImages[mInetCondition];
-
- // If 3G(EV) and 1x network are available than 3G should be
- // displayed, displayed RSSI should be from the EV side.
- // If a voice call is made then RSSI should switch to 1x.
- if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){
- iconLevel = getEvdoLevel();
- if (false) {
- Slog.d(TAG, "use Evdo level=" + iconLevel + " to replace Cdma Level="
- + getCdmaLevel());
- }
- } else {
- iconLevel = getCdmaLevel();
- }
}
- mPhoneSignalIconId = iconList[iconLevel];
+ mPhoneSignalIconId = iconList[mSignalStrength.getLevel()];
mService.setIcon("phone_signal", mPhoneSignalIconId, 0);
}
- private int getCdmaLevel() {
- final int cdmaDbm = mSignalStrength.getCdmaDbm();
- final int cdmaEcio = mSignalStrength.getCdmaEcio();
- int levelDbm = 0;
- int levelEcio = 0;
-
- if (cdmaDbm >= -75) levelDbm = 4;
- else if (cdmaDbm >= -85) levelDbm = 3;
- else if (cdmaDbm >= -95) levelDbm = 2;
- else if (cdmaDbm >= -100) levelDbm = 1;
- else levelDbm = 0;
-
- // Ec/Io are in dB*10
- if (cdmaEcio >= -90) levelEcio = 4;
- else if (cdmaEcio >= -110) levelEcio = 3;
- else if (cdmaEcio >= -130) levelEcio = 2;
- else if (cdmaEcio >= -150) levelEcio = 1;
- else levelEcio = 0;
-
- return (levelDbm < levelEcio) ? levelDbm : levelEcio;
- }
-
- private int getEvdoLevel() {
- int evdoDbm = mSignalStrength.getEvdoDbm();
- int evdoSnr = mSignalStrength.getEvdoSnr();
- int levelEvdoDbm = 0;
- int levelEvdoSnr = 0;
-
- if (evdoDbm >= -65) levelEvdoDbm = 4;
- else if (evdoDbm >= -75) levelEvdoDbm = 3;
- else if (evdoDbm >= -90) levelEvdoDbm = 2;
- else if (evdoDbm >= -105) levelEvdoDbm = 1;
- else levelEvdoDbm = 0;
-
- if (evdoSnr >= 7) levelEvdoSnr = 4;
- else if (evdoSnr >= 5) levelEvdoSnr = 3;
- else if (evdoSnr >= 3) levelEvdoSnr = 2;
- else if (evdoSnr >= 1) levelEvdoSnr = 1;
- else levelEvdoSnr = 0;
-
- return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
- }
-
private final void updateDataNetType(int net) {
switch (net) {
case TelephonyManager.NETWORK_TYPE_EDGE:
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 42868db00788..317490fe719b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -33,6 +33,11 @@ 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;
import android.provider.Settings;
import android.provider.Telephony;
@@ -50,6 +55,7 @@ import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.cdma.EriInfo;
import com.android.server.am.BatteryStatsService;
+import com.android.internal.util.AsyncChannel;
import com.android.systemui.R;
@@ -82,6 +88,7 @@ public class NetworkController extends BroadcastReceiver {
// wifi
final WifiManager mWifiManager;
+ AsyncChannel mWifiChannel;
boolean mWifiEnabled, mWifiConnected;
int mWifiLevel;
String mWifiSsid;
@@ -140,6 +147,14 @@ public class NetworkController extends BroadcastReceiver {
// wifi
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ HandlerThread handlerThread = new HandlerThread("WifiServiceThread");
+ handlerThread.start();
+ Handler handler = new WifiHandler(handlerThread.getLooper());
+ mWifiChannel = new AsyncChannel();
+ Messenger wifiMessenger = mWifiManager.getMessenger();
+ if (wifiMessenger != null) {
+ mWifiChannel.connect(mContext, handler, wifiMessenger);
+ }
// broadcasts
IntentFilter filter = new IntentFilter();
@@ -185,6 +200,7 @@ public class NetworkController extends BroadcastReceiver {
mLabelViews.add(v);
}
+ @Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(WifiManager.RSSI_CHANGED_ACTION)
@@ -300,13 +316,6 @@ public class NetworkController extends BroadcastReceiver {
return (mSignalStrength != null) && !mSignalStrength.isGsm();
}
- private boolean isEvdo() {
- return ((mServiceState != null)
- && ((mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
- || (mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_A)
- || (mServiceState.getRadioTechnology() == ServiceState.RADIO_TECHNOLOGY_EVDO_B)));
- }
-
private boolean hasService() {
if (mServiceState != null) {
switch (mServiceState.getState()) {
@@ -321,51 +330,6 @@ public class NetworkController extends BroadcastReceiver {
}
}
- private int getCdmaLevel() {
- if (mSignalStrength == null) return 0;
- final int cdmaDbm = mSignalStrength.getCdmaDbm();
- final int cdmaEcio = mSignalStrength.getCdmaEcio();
- int levelDbm = 0;
- int levelEcio = 0;
-
- if (cdmaDbm >= -75) levelDbm = 4;
- else if (cdmaDbm >= -85) levelDbm = 3;
- else if (cdmaDbm >= -95) levelDbm = 2;
- else if (cdmaDbm >= -100) levelDbm = 1;
- else levelDbm = 0;
-
- // Ec/Io are in dB*10
- if (cdmaEcio >= -90) levelEcio = 4;
- else if (cdmaEcio >= -110) levelEcio = 3;
- else if (cdmaEcio >= -130) levelEcio = 2;
- else if (cdmaEcio >= -150) levelEcio = 1;
- else levelEcio = 0;
-
- return (levelDbm < levelEcio) ? levelDbm : levelEcio;
- }
-
- private int getEvdoLevel() {
- if (mSignalStrength == null) return 0;
- int evdoDbm = mSignalStrength.getEvdoDbm();
- int evdoSnr = mSignalStrength.getEvdoSnr();
- int levelEvdoDbm = 0;
- int levelEvdoSnr = 0;
-
- if (evdoDbm >= -65) levelEvdoDbm = 4;
- else if (evdoDbm >= -75) levelEvdoDbm = 3;
- else if (evdoDbm >= -90) levelEvdoDbm = 2;
- else if (evdoDbm >= -105) levelEvdoDbm = 1;
- else levelEvdoDbm = 0;
-
- if (evdoSnr >= 7) levelEvdoSnr = 4;
- else if (evdoSnr >= 5) levelEvdoSnr = 3;
- else if (evdoSnr >= 3) levelEvdoSnr = 2;
- else if (evdoSnr >= 1) levelEvdoSnr = 1;
- else levelEvdoSnr = 0;
-
- return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
- }
-
private final void updateTelephonySignalStrength() {
// Display signal strength while in "emergency calls only" mode
if (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly())) {
@@ -382,44 +346,23 @@ 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
- } else if (isCdma()) {
- // If 3G(EV) and 1x network are available than 3G should be
- // displayed, displayed RSSI should be from the EV side.
- // If a voice call is made then RSSI should switch to 1x.
- int iconLevel;
- if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){
- iconLevel = getEvdoLevel();
- } else {
- iconLevel = getCdmaLevel();
- }
- int[] iconList;
- if (isCdmaEri()) {
- iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition];
- } else {
- iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition];
- }
- mPhoneSignalIconId = iconList[iconLevel];
- mDataSignalIconId = TelephonyIcons.DATA_SIGNAL_STRENGTH[mInetCondition][iconLevel];
} else {
- int asu = mSignalStrength.getGsmSignalStrength();
-
- // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
- // asu = 0 (-113dB or less) is very weak
- // signal, its better to show 0 bars to the user in such cases.
- // asu = 99 is a special case, where the signal strength is unknown.
int iconLevel;
- if (asu <= 2 || asu == 99) iconLevel = 0;
- else if (asu >= 12) iconLevel = 4;
- else if (asu >= 8) iconLevel = 3;
- else if (asu >= 5) iconLevel = 2;
- else iconLevel = 1;
-
- // Though mPhone is a Manager, this call is not an IPC
int[] iconList;
- if (mPhone.isNetworkRoaming()) {
- iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition];
+ iconLevel = mSignalStrength.getLevel();
+ if (isCdma()) {
+ if (isCdmaEri()) {
+ iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition];
+ } else {
+ iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition];
+ }
} else {
- iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition];
+ // Though mPhone is a Manager, this call is not an IPC
+ if (mPhone.isNetworkRoaming()) {
+ iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[mInetCondition];
+ } else {
+ iconList = TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[mInetCondition];
+ }
}
mPhoneSignalIconId = iconList[iconLevel];
mDataSignalIconId = TelephonyIcons.DATA_SIGNAL_STRENGTH[mInetCondition][iconLevel];
@@ -584,6 +527,44 @@ public class NetworkController extends BroadcastReceiver {
// ===== Wifi ===================================================================
+ class WifiHandler extends Handler {
+
+ WifiHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+ if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
+ mWifiChannel.sendMessage(Message.obtain(this,
+ AsyncChannel.CMD_CHANNEL_FULL_CONNECTION));
+ } else {
+ Slog.e(TAG, "Failed to connect to wifi");
+ }
+ break;
+ case WifiManager.DATA_ACTIVITY_NOTIFICATION:
+ int dataActivity = msg.arg1;
+ /* TODO: update icons based on data activity */
+ switch (dataActivity) {
+ case WifiManager.DATA_ACTIVITY_IN:
+ break;
+ case WifiManager.DATA_ACTIVITY_OUT:
+ break;
+ case WifiManager.DATA_ACTIVITY_INOUT:
+ break;
+ case WifiManager.DATA_ACTIVITY_NONE:
+ break;
+ }
+ break;
+ default:
+ //Ignore
+ break;
+ }
+ }
+ }
+
private void updateWifiState(Intent intent) {
final String action = intent.getAction();
if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
index 86c3e7597884..e0d558f2580d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
@@ -374,8 +374,9 @@ public class RecentAppsPanel extends RelativeLayout implements StatusBarPanel, O
if (title != null && title.length() > 0 && icon != null) {
if (DEBUG) Log.v(TAG, "creating activity desc for id=" + id + ", label=" + title);
ActivityDescription item = new ActivityDescription(
- recentInfo.thumbnail, icon, title,
- recentInfo.description, intent, id, index, info.packageName);
+ am.getTaskThumbnail(recentInfo.persistentId),
+ icon, title, recentInfo.description, intent, id,
+ index, info.packageName);
activityDescriptions.add(item);
++index;
} else {
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 7a13fded41b9..afb73a9033d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -28,6 +28,7 @@ import android.app.Notification;
import android.app.StatusBarManager;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
@@ -67,6 +68,7 @@ import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.Prefs;
import com.android.systemui.recent.RecentApplicationsActivity;
public class TabletStatusBar extends StatusBar implements
@@ -105,7 +107,7 @@ public class TabletStatusBar extends StatusBar implements
IWindowManager mWindowManager;
// tracking all current notifications
- private NotificationData mNotns = new NotificationData();
+ private NotificationData mNotificationData = new NotificationData();
TabletStatusBarView mStatusBarView;
View mNotificationArea;
@@ -113,6 +115,9 @@ public class TabletStatusBar extends StatusBar implements
NotificationIconArea mNotificationIconArea;
View mNavigationArea;
+ boolean mNotificationDNDMode;
+ NotificationData.Entry mNotificationDNDDummyEntry;
+
ImageView mBackButton;
View mHomeButton;
View mMenuButton;
@@ -489,25 +494,43 @@ public class TabletStatusBar extends StatusBar implements
switch (m.what) {
case MSG_OPEN_NOTIFICATION_PEEK:
if (DEBUG) Slog.d(TAG, "opening notification peek window; arg=" + m.arg1);
+
if (m.arg1 >= 0) {
- final int N = mNotns.size();
- if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
- NotificationData.Entry entry = mNotns.get(N-1-mNotificationPeekIndex);
- entry.icon.setBackgroundColor(0);
- mNotificationPeekIndex = -1;
- mNotificationPeekKey = null;
+ final int N = mNotificationData.size();
+
+ if (!mNotificationDNDMode) {
+ if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
+ NotificationData.Entry entry = mNotificationData.get(N-1-mNotificationPeekIndex);
+ entry.icon.setBackgroundColor(0);
+ mNotificationPeekIndex = -1;
+ mNotificationPeekKey = null;
+ }
}
final int peekIndex = m.arg1;
if (peekIndex < N) {
//Slog.d(TAG, "loading peek: " + peekIndex);
- NotificationData.Entry entry = mNotns.get(N-1-peekIndex);
+ NotificationData.Entry entry =
+ mNotificationDNDMode
+ ? mNotificationDNDDummyEntry
+ : mNotificationData.get(N-1-peekIndex);
NotificationData.Entry copy = new NotificationData.Entry(
entry.key,
entry.notification,
entry.icon);
inflateViews(copy, mNotificationPeekRow);
+ if (mNotificationDNDMode) {
+ copy.content.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ SharedPreferences.Editor editor = Prefs.edit(mContext);
+ editor.putBoolean(Prefs.DO_NOT_DISTURB_PREF, false);
+ editor.apply();
+ animateCollapse();
+ }
+ });
+ }
+
entry.icon.setBackgroundColor(0x20FFFFFF);
// mNotificationPeekRow.setLayoutTransition(
@@ -530,9 +553,13 @@ public class TabletStatusBar extends StatusBar implements
if (DEBUG) Slog.d(TAG, "closing notification peek window");
mNotificationPeekWindow.setVisibility(View.GONE);
mNotificationPeekRow.removeAllViews();
- final int N = mNotns.size();
+
+ final int N = mNotificationData.size();
if (mNotificationPeekIndex >= 0 && mNotificationPeekIndex < N) {
- NotificationData.Entry entry = mNotns.get(N-1-mNotificationPeekIndex);
+ NotificationData.Entry entry =
+ mNotificationDNDMode
+ ? mNotificationDNDDummyEntry
+ : mNotificationData.get(N-1-mNotificationPeekIndex);
entry.icon.setBackgroundColor(0);
}
@@ -643,7 +670,7 @@ public class TabletStatusBar extends StatusBar implements
public void updateNotification(IBinder key, StatusBarNotification notification) {
if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ") // TODO");
- final NotificationData.Entry oldEntry = mNotns.findByKey(key);
+ final NotificationData.Entry oldEntry = mNotificationData.findByKey(key);
if (oldEntry == null) {
Slog.w(TAG, "updateNotification for unknown key: " + key);
return;
@@ -781,14 +808,15 @@ public class TabletStatusBar extends StatusBar implements
if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
- // synchronize with current shadow state
- mNotificationIconArea.setVisibility(View.GONE);
mTicker.halt();
} else {
Slog.i(TAG, "DISABLE_NOTIFICATION_ICONS: no");
- // synchronize with current shadow state
- mNotificationIconArea.setVisibility(View.VISIBLE);
}
+ // refresh icons to show either notifications or the DND message
+ mNotificationDNDMode = Prefs.read(mContext)
+ .getBoolean(Prefs.DO_NOT_DISTURB_PREF, Prefs.DO_NOT_DISTURB_DEFAULT);
+ Slog.d(TAG, "DND: " + mNotificationDNDMode);
+ reloadAllNotificationIcons();
} else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
if ((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
mTicker.halt();
@@ -947,7 +975,7 @@ public class TabletStatusBar extends StatusBar implements
}
private void setAreThereNotifications() {
- final boolean hasClearable = mNotns.hasClearableItems();
+ final boolean hasClearable = mNotificationData.hasClearableItems();
}
/**
@@ -1081,7 +1109,7 @@ public class TabletStatusBar extends StatusBar implements
}
StatusBarNotification removeNotificationViews(IBinder key) {
- NotificationData.Entry entry = mNotns.remove(key);
+ NotificationData.Entry entry = mNotificationData.remove(key);
if (entry == null) {
Slog.w(TAG, "removeNotification for unknown key: " + key);
return null;
@@ -1192,7 +1220,7 @@ public class TabletStatusBar extends StatusBar implements
}
// Add the icon.
- int pos = mNotns.add(entry);
+ int pos = mNotificationData.add(entry);
if (DEBUG) {
Slog.d(TAG, "addNotificationViews: added at " + pos);
}
@@ -1216,7 +1244,31 @@ public class TabletStatusBar extends StatusBar implements
final LinearLayout.LayoutParams params
= new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
- int N = mNotns.size();
+ // alternate behavior in DND mode
+ if (mNotificationDNDMode && 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))
+ .setSmallIcon(R.drawable.ic_notification_dnd)
+ .setOngoing(true)
+ .getNotification();
+
+ mNotificationDNDDummyEntry = new NotificationData.Entry(
+ null,
+ new StatusBarNotification("", 0, "", 0, 0, dndNotification),
+ iconView);
+
+ mIconLayout.addView(iconView, params);
+
+ return;
+ }
+
+ int N = mNotificationData.size();
if (DEBUG) {
Slog.d(TAG, "refreshing icons: " + N + " notifications, mIconLayout=" + mIconLayout);
@@ -1231,7 +1283,7 @@ public class TabletStatusBar extends StatusBar implements
MAX_NOTIFICATION_ICONS_IME_BUTTON_VISIBLE : MAX_NOTIFICATION_ICONS;
for (int i=0; i< maxNotificationIconsCount; i++) {
if (i>=N) break;
- toShow.add(mNotns.get(N-i-1).icon);
+ toShow.add(mNotificationData.get(N-i-1).icon);
}
ArrayList<View> toRemove = new ArrayList<View>();
@@ -1258,12 +1310,12 @@ public class TabletStatusBar extends StatusBar implements
}
private void loadNotificationPanel() {
- int N = mNotns.size();
+ int N = mNotificationData.size();
ArrayList<View> toShow = new ArrayList<View>();
for (int i=0; i<N; i++) {
- View row = mNotns.get(N-i-1).row;
+ View row = mNotificationData.get(N-i-1).row;
toShow.add(row);
}
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 780996171a7e..b32a72970151 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -89,7 +89,7 @@ import android.view.WindowManagerPolicy;
* This class is created by the initialization routine of the {@link WindowManagerPolicy},
* and runs on its thread. The keyguard UI is created from that thread in the
* constructor of this class. The apis may be called from other threads, including the
- * {@link com.android.server.InputManager}'s and {@link android.view.WindowManager}'s.
+ * {@link com.android.server.wm.InputManager}'s and {@link android.view.WindowManager}'s.
* Therefore, methods on this class are synchronized, and any action that is pointed
* directly to the keyguard UI is posted to a {@link Handler} to ensure it is taken on the UI
* thread of the keyguard.
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 066daa89d267..84588b78c2a8 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -117,6 +117,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
import android.view.WindowManagerImpl;
import android.view.WindowManagerPolicy;
+import android.view.KeyCharacterMap.FallbackAction;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.media.IAudioService;
@@ -1453,7 +1454,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
// Check for fallback actions.
- if (kcm.getFallbackAction(keyCode, metaState, mFallbackAction)) {
+ if (getFallbackAction(kcm, keyCode, metaState, mFallbackAction)) {
if (DEBUG_FALLBACK) {
Slog.d(TAG, "Fallback: keyCode=" + mFallbackAction.keyCode
+ " metaState=" + Integer.toHexString(mFallbackAction.metaState));
@@ -1485,6 +1486,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return null;
}
+ private boolean getFallbackAction(KeyCharacterMap kcm, int keyCode, int metaState,
+ FallbackAction outFallbackAction) {
+ // Consult the key character map for specific fallback actions.
+ // For example, map NUMPAD_1 to MOVE_HOME when NUMLOCK is not pressed.
+ return kcm.getFallbackAction(keyCode, metaState, outFallbackAction);
+ }
+
/**
* A home key -> launch home action was detected. Take the appropriate action
* given the situation with the keyguard.
@@ -2430,6 +2438,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return mKeyguardMediator.isShowingAndNotHidden();
}
+
+ /** {@inheritDoc} */
+ public boolean isKeyguardLocked() {
+ return keyguardOn();
+ }
+
+ /** {@inheritDoc} */
+ public boolean isKeyguardSecure() {
+ return mKeyguardMediator.isSecure();
+ }
+
/** {@inheritDoc} */
public boolean inKeyguardRestrictedKeyInputMode() {
return mKeyguardMediator.isInputRestricted();
@@ -2455,6 +2474,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public int rotationForOrientationLw(int orientation, int lastRotation,
boolean displayEnabled) {
+ if (false) {
+ Slog.v(TAG, "rotationForOrientationLw(orient="
+ + orientation + ", last=" + lastRotation
+ + "); user=" + mUserRotation + " "
+ + ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED)
+ ? "USER_ROTATION_LOCKED" : "")
+ );
+ }
+
if (mPortraitRotation < 0) {
// Initialize the rotation angles for each orientation once.
Display d = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
@@ -2573,15 +2601,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// User rotation: to be used when all else fails in assigning an orientation to the device
public void setUserRotationMode(int mode, int rot) {
ContentResolver res = mContext.getContentResolver();
- mUserRotationMode = mode;
+
+ // mUserRotationMode and mUserRotation will be assigned by the content observer
if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
- mUserRotation = rot;
- Settings.System.putInt(res,
- Settings.System.ACCELEROMETER_ROTATION,
- 0);
Settings.System.putInt(res,
Settings.System.USER_ROTATION,
rot);
+ Settings.System.putInt(res,
+ Settings.System.ACCELEROMETER_ROTATION,
+ 0);
} else {
Settings.System.putInt(res,
Settings.System.ACCELEROMETER_ROTATION,
@@ -2899,7 +2927,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
pw.print(" mDeskDockRotation="); pw.println(mDeskDockRotation);
pw.print(prefix); pw.print("mUserRotationMode="); pw.print(mUserRotationMode);
pw.print(" mUserRotation="); pw.print(mUserRotation);
- pw.print("mAllowAllRotations="); pw.println(mAllowAllRotations);
+ pw.print(" mAllowAllRotations="); pw.println(mAllowAllRotations);
pw.print(prefix); pw.print("mAccelerometerDefault="); pw.print(mAccelerometerDefault);
pw.print(" mCurrentAppOrientation="); pw.println(mCurrentAppOrientation);
pw.print(prefix); pw.print("mCarDockEnablesAccelerometer=");
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index 38a896fa4029..b31381a3531e 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -101,12 +101,14 @@ EventHub::Device::Device(int fd, int32_t id, const String8& path,
const InputDeviceIdentifier& identifier) :
next(NULL),
fd(fd), id(id), path(path), identifier(identifier),
- classes(0), keyBitmask(NULL), configuration(NULL), virtualKeyMap(NULL) {
+ classes(0), keyBitmask(NULL), relBitmask(NULL),
+ configuration(NULL), virtualKeyMap(NULL) {
}
EventHub::Device::~Device() {
close();
delete[] keyBitmask;
+ delete[] relBitmask;
delete configuration;
delete virtualKeyMap;
}
@@ -127,9 +129,7 @@ EventHub::EventHub(void) :
mOpened(false), mNeedToSendFinishedDeviceScan(false),
mInputBufferIndex(0), mInputBufferCount(0), mInputFdIndex(0) {
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
-#ifdef EV_SW
memset(mSwitches, 0, sizeof(mSwitches));
-#endif
}
EventHub::~EventHub(void) {
@@ -191,6 +191,18 @@ status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
return OK;
}
+bool EventHub::hasRelativeAxis(int32_t deviceId, int axis) const {
+ if (axis >= 0 && axis <= REL_MAX) {
+ AutoMutex _l(mLock);
+
+ Device* device = getDeviceLocked(deviceId);
+ if (device && device->relBitmask) {
+ return test_bit(axis, device->relBitmask);
+ }
+ }
+ return false;
+}
+
int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const {
if (scanCode >= 0 && scanCode <= KEY_MAX) {
AutoMutex _l(mLock);
@@ -229,7 +241,7 @@ int32_t EventHub::getKeyCodeStateLocked(Device* device, int32_t keyCode) const {
}
Vector<int32_t> scanCodes;
- device->keyMap.keyLayoutMap->findScanCodes(keyCode, &scanCodes);
+ device->keyMap.keyLayoutMap->findScanCodesForKey(keyCode, &scanCodes);
uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
memset(key_bitmask, 0, sizeof(key_bitmask));
@@ -253,7 +265,6 @@ int32_t EventHub::getKeyCodeStateLocked(Device* device, int32_t keyCode) const {
}
int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
-#ifdef EV_SW
if (sw >= 0 && sw <= SW_MAX) {
AutoMutex _l(mLock);
@@ -262,7 +273,6 @@ int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
return getSwitchStateLocked(device, sw);
}
}
-#endif
return AKEY_STATE_UNKNOWN;
}
@@ -297,7 +307,8 @@ bool EventHub::markSupportedKeyCodesLocked(Device* device, size_t numCodes,
for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
scanCodes.clear();
- status_t err = device->keyMap.keyLayoutMap->findScanCodes(keyCodes[codeIndex], &scanCodes);
+ status_t err = device->keyMap.keyLayoutMap->findScanCodesForKey(
+ keyCodes[codeIndex], &scanCodes);
if (! err) {
// check the possible scan codes identified by the layout map against the
// map of codes actually emitted by the driver
@@ -312,14 +323,14 @@ bool EventHub::markSupportedKeyCodesLocked(Device* device, size_t numCodes,
return true;
}
-status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode,
+status_t EventHub::mapKey(int32_t deviceId, int scancode,
int32_t* outKeycode, uint32_t* outFlags) const
{
AutoMutex _l(mLock);
Device* device = getDeviceLocked(deviceId);
if (device && device->keyMap.haveKeyLayout()) {
- status_t err = device->keyMap.keyLayoutMap->map(scancode, outKeycode, outFlags);
+ status_t err = device->keyMap.keyLayoutMap->mapKey(scancode, outKeycode, outFlags);
if (err == NO_ERROR) {
return NO_ERROR;
}
@@ -329,7 +340,7 @@ status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode,
device = getDeviceLocked(mBuiltInKeyboardId);
if (device && device->keyMap.haveKeyLayout()) {
- status_t err = device->keyMap.keyLayoutMap->map(scancode, outKeycode, outFlags);
+ status_t err = device->keyMap.keyLayoutMap->mapKey(scancode, outKeycode, outFlags);
if (err == NO_ERROR) {
return NO_ERROR;
}
@@ -341,6 +352,34 @@ status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode,
return NAME_NOT_FOUND;
}
+status_t EventHub::mapAxis(int32_t deviceId, int scancode,
+ int32_t* outAxis) const
+{
+ AutoMutex _l(mLock);
+ Device* device = getDeviceLocked(deviceId);
+
+ if (device && device->keyMap.haveKeyLayout()) {
+ status_t err = device->keyMap.keyLayoutMap->mapAxis(scancode, outAxis);
+ if (err == NO_ERROR) {
+ return NO_ERROR;
+ }
+ }
+
+ if (mBuiltInKeyboardId != -1) {
+ device = getDeviceLocked(mBuiltInKeyboardId);
+
+ if (device && device->keyMap.haveKeyLayout()) {
+ status_t err = device->keyMap.keyLayoutMap->mapAxis(scancode, outAxis);
+ if (err == NO_ERROR) {
+ return NO_ERROR;
+ }
+ }
+ }
+
+ *outAxis = -1;
+ return NAME_NOT_FOUND;
+}
+
void EventHub::addExcludedDevice(const char* deviceName)
{
AutoMutex _l(mLock);
@@ -488,7 +527,7 @@ bool EventHub::getEvent(RawEvent* outEvent) {
if (iev.type == EV_KEY) {
outEvent->keyCode = AKEYCODE_UNKNOWN;
if (device->keyMap.haveKeyLayout()) {
- status_t err = device->keyMap.keyLayoutMap->map(iev.code,
+ status_t err = device->keyMap.keyLayoutMap->mapKey(iev.code,
&outEvent->keyCode, &outEvent->flags);
LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n",
iev.code, outEvent->keyCode, outEvent->flags, err);
@@ -731,86 +770,89 @@ int EventHub::openDevice(const char *devicePath) {
loadConfiguration(device);
// Figure out the kinds of events the device reports.
-
uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
memset(key_bitmask, 0, sizeof(key_bitmask));
+ ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask);
- LOGV("Getting keys...");
- if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) {
- //LOGI("MAP\n");
- //for (int i = 0; i < sizeof(key_bitmask); i++) {
- // LOGI("%d: 0x%02x\n", i, key_bitmask[i]);
- //}
-
- // See if this is a keyboard. Ignore everything in the button range except for
- // joystick and gamepad buttons which are also considered keyboards.
- if (containsNonZeroByte(key_bitmask, 0, sizeof_bit_array(BTN_MISC))
- || containsNonZeroByte(key_bitmask, sizeof_bit_array(BTN_JOYSTICK),
- sizeof_bit_array(BTN_DIGI))
- || containsNonZeroByte(key_bitmask, sizeof_bit_array(KEY_OK),
- sizeof_bit_array(KEY_MAX + 1))) {
- device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
+ uint8_t abs_bitmask[sizeof_bit_array(ABS_MAX + 1)];
+ memset(abs_bitmask, 0, sizeof(abs_bitmask));
+ ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
- device->keyBitmask = new uint8_t[sizeof(key_bitmask)];
- if (device->keyBitmask != NULL) {
- memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
- } else {
- delete device;
- LOGE("out of memory allocating key bitmask");
- return -1;
- }
- }
+ uint8_t rel_bitmask[sizeof_bit_array(REL_MAX + 1)];
+ memset(rel_bitmask, 0, sizeof(rel_bitmask));
+ ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask);
+
+ uint8_t sw_bitmask[sizeof_bit_array(SW_MAX + 1)];
+ memset(sw_bitmask, 0, sizeof(sw_bitmask));
+ ioctl(fd, EVIOCGBIT(EV_SW, sizeof(sw_bitmask)), sw_bitmask);
+
+ device->keyBitmask = new uint8_t[sizeof(key_bitmask)];
+ if (device->keyBitmask != NULL) {
+ memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
+ } else {
+ delete device;
+ LOGE("out of memory allocating key bitmask");
+ return -1;
}
-
+
+ device->relBitmask = new uint8_t[sizeof(rel_bitmask)];
+ if (device->relBitmask != NULL) {
+ memcpy(device->relBitmask, rel_bitmask, sizeof(rel_bitmask));
+ } else {
+ delete device;
+ LOGE("out of memory allocating rel bitmask");
+ return -1;
+ }
+
+ // See if this is a keyboard. Ignore everything in the button range except for
+ // joystick and gamepad buttons which are handled like keyboards for the most part.
+ bool haveKeyboardKeys = containsNonZeroByte(key_bitmask, 0, sizeof_bit_array(BTN_MISC))
+ || containsNonZeroByte(key_bitmask, sizeof_bit_array(KEY_OK),
+ sizeof_bit_array(KEY_MAX + 1));
+ bool haveGamepadButtons =containsNonZeroByte(key_bitmask, sizeof_bit_array(BTN_JOYSTICK),
+ sizeof_bit_array(BTN_DIGI));
+ if (haveKeyboardKeys || haveGamepadButtons) {
+ device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
+ }
+
// See if this is a cursor device such as a trackball or mouse.
- if (test_bit(BTN_MOUSE, key_bitmask)) {
- uint8_t rel_bitmask[sizeof_bit_array(REL_MAX + 1)];
- memset(rel_bitmask, 0, sizeof(rel_bitmask));
- LOGV("Getting relative controllers...");
- if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0) {
- if (test_bit(REL_X, rel_bitmask) && test_bit(REL_Y, rel_bitmask)) {
- device->classes |= INPUT_DEVICE_CLASS_CURSOR;
- }
- }
+ if (test_bit(BTN_MOUSE, key_bitmask)
+ && test_bit(REL_X, rel_bitmask)
+ && test_bit(REL_Y, rel_bitmask)) {
+ device->classes |= INPUT_DEVICE_CLASS_CURSOR;
}
// See if this is a touch pad.
- uint8_t abs_bitmask[sizeof_bit_array(ABS_MAX + 1)];
- memset(abs_bitmask, 0, sizeof(abs_bitmask));
- LOGV("Getting absolute controllers...");
- if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0) {
- // Is this a new modern multi-touch driver?
- if (test_bit(ABS_MT_POSITION_X, abs_bitmask)
- && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
+ // Is this a new modern multi-touch driver?
+ if (test_bit(ABS_MT_POSITION_X, abs_bitmask)
+ && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
+ // Some joysticks such as the PS3 controller report axes that conflict
+ // with the ABS_MT range. Try to confirm that the device really is
+ // a touch screen.
+ if (test_bit(BTN_TOUCH, key_bitmask) || !haveGamepadButtons) {
device->classes |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT;
-
- // Is this an old style single-touch driver?
- } else if (test_bit(BTN_TOUCH, key_bitmask)
- && test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
- device->classes |= INPUT_DEVICE_CLASS_TOUCH;
}
+ // Is this an old style single-touch driver?
+ } else if (test_bit(BTN_TOUCH, key_bitmask)
+ && test_bit(ABS_X, abs_bitmask)
+ && test_bit(ABS_Y, abs_bitmask)) {
+ device->classes |= INPUT_DEVICE_CLASS_TOUCH;
}
-#ifdef EV_SW
// figure out the switches this device reports
- uint8_t sw_bitmask[sizeof_bit_array(SW_MAX + 1)];
- memset(sw_bitmask, 0, sizeof(sw_bitmask));
- bool hasSwitches = false;
- if (ioctl(fd, EVIOCGBIT(EV_SW, sizeof(sw_bitmask)), sw_bitmask) >= 0) {
- for (int i=0; i<EV_SW; i++) {
- //LOGI("Device %d sw %d: has=%d", device->id, i, test_bit(i, sw_bitmask));
- if (test_bit(i, sw_bitmask)) {
- hasSwitches = true;
- if (mSwitches[i] == 0) {
- mSwitches[i] = device->id;
- }
+ bool haveSwitches = false;
+ for (int i=0; i<EV_SW; i++) {
+ //LOGI("Device %d sw %d: has=%d", device->id, i, test_bit(i, sw_bitmask));
+ if (test_bit(i, sw_bitmask)) {
+ haveSwitches = true;
+ if (mSwitches[i] == 0) {
+ mSwitches[i] = device->id;
}
}
}
- if (hasSwitches) {
+ if (haveSwitches) {
device->classes |= INPUT_DEVICE_CLASS_SWITCH;
}
-#endif
if ((device->classes & INPUT_DEVICE_CLASS_TOUCH)) {
// Load the virtual keys for the touch screen, if any.
@@ -862,12 +904,10 @@ int EventHub::openDevice(const char *devicePath) {
// See if this device is a joystick.
// Ignore touchscreens because they use the same absolute axes for other purposes.
+ // Assumes that joysticks always have buttons and the keymap has been loaded.
if (device->classes & INPUT_DEVICE_CLASS_GAMEPAD
&& !(device->classes & INPUT_DEVICE_CLASS_TOUCH)) {
- if (test_bit(ABS_X, abs_bitmask)
- || test_bit(ABS_Y, abs_bitmask)
- || test_bit(ABS_HAT0X, abs_bitmask)
- || test_bit(ABS_HAT0Y, abs_bitmask)) {
+ if (containsNonZeroByte(abs_bitmask, 0, sizeof_bit_array(ABS_MAX + 1))) {
device->classes |= INPUT_DEVICE_CLASS_JOYSTICK;
}
}
@@ -950,7 +990,7 @@ bool EventHub::hasKeycodeLocked(Device* device, int keycode) const {
}
Vector<int32_t> scanCodes;
- device->keyMap.keyLayoutMap->findScanCodes(keycode, &scanCodes);
+ device->keyMap.keyLayoutMap->findScanCodesForKey(keycode, &scanCodes);
const size_t N = scanCodes.size();
for (size_t i=0; i<N && i<=KEY_MAX; i++) {
int32_t sc = scanCodes.itemAt(i);
@@ -972,13 +1012,11 @@ int EventHub::closeDevice(const char *devicePath) {
device->path.string(), device->identifier.name.string(), device->id,
device->fd, device->classes);
-#ifdef EV_SW
for (int j=0; j<EV_SW; j++) {
if (mSwitches[j] == device->id) {
mSwitches[j] = 0;
}
}
-#endif
if (device->id == mBuiltInKeyboardId) {
LOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
diff --git a/services/input/EventHub.h b/services/input/EventHub.h
index 52993f705f2e..23bb34493471 100644
--- a/services/input/EventHub.h
+++ b/services/input/EventHub.h
@@ -167,9 +167,14 @@ public:
virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
RawAbsoluteAxisInfo* outAxisInfo) const = 0;
- virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
+ virtual bool hasRelativeAxis(int32_t deviceId, int axis) const = 0;
+
+ virtual status_t mapKey(int32_t deviceId, int scancode,
int32_t* outKeycode, uint32_t* outFlags) const = 0;
+ virtual status_t mapAxis(int32_t deviceId, int scancode,
+ int32_t* outAxis) const = 0;
+
// exclude a particular device from opening
// this can be used to ignore input devices for sensors
virtual void addExcludedDevice(const char* deviceName) = 0;
@@ -221,9 +226,14 @@ public:
virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
RawAbsoluteAxisInfo* outAxisInfo) const;
- virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
+ virtual bool hasRelativeAxis(int32_t deviceId, int axis) const;
+
+ virtual status_t mapKey(int32_t deviceId, int scancode,
int32_t* outKeycode, uint32_t* outFlags) const;
+ virtual status_t mapAxis(int32_t deviceId, int scancode,
+ int32_t* outAxis) const;
+
virtual void addExcludedDevice(const char* deviceName);
virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const;
@@ -266,6 +276,7 @@ private:
uint32_t classes;
uint8_t* keyBitmask;
+ uint8_t* relBitmask;
String8 configurationFile;
PropertyMap* configuration;
VirtualKeyMap* virtualKeyMap;
@@ -314,9 +325,7 @@ private:
List<String8> mExcludedDevices;
// device ids that report particular switches.
-#ifdef EV_SW
int32_t mSwitches[SW_MAX + 1];
-#endif
static const int INPUT_BUFFER_SIZE = 64;
struct input_event mInputBufferData[INPUT_BUFFER_SIZE];
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 466a9b364063..ef984d41cf17 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -115,6 +115,7 @@ static bool isValidMotionAction(int32_t action, size_t pointerCount) {
case AMOTION_EVENT_ACTION_CANCEL:
case AMOTION_EVENT_ACTION_MOVE:
case AMOTION_EVENT_ACTION_OUTSIDE:
+ case AMOTION_EVENT_ACTION_HOVER_MOVE:
return true;
case AMOTION_EVENT_ACTION_POINTER_DOWN:
case AMOTION_EVENT_ACTION_POINTER_UP: {
@@ -318,7 +319,8 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
uint32_t source = motionEntry->source;
if (! isAppSwitchDue
&& motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
- && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
+ && (motionEntry->action == AMOTION_EVENT_ACTION_MOVE
+ || motionEntry->action == AMOTION_EVENT_ACTION_HOVER_MOVE)
&& deviceId == mThrottleState.lastDeviceId
&& source == mThrottleState.lastSource) {
nsecs_t nextTime = mThrottleState.lastEventTime
@@ -478,14 +480,15 @@ bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
// If the application takes too long to catch up then we drop all events preceding
// the touch into the other window.
MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
- if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
+ if ((motionEntry->action == AMOTION_EVENT_ACTION_DOWN
+ || motionEntry->action == AMOTION_EVENT_ACTION_HOVER_MOVE)
&& (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
&& mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
&& mInputTargetWaitApplication != NULL) {
int32_t x = int32_t(motionEntry->firstSample.pointerCoords[0].
- getAxisValue(AINPUT_MOTION_AXIS_X));
+ getAxisValue(AMOTION_EVENT_AXIS_X));
int32_t y = int32_t(motionEntry->firstSample.pointerCoords[0].
- getAxisValue(AINPUT_MOTION_AXIS_Y));
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
const InputWindow* touchedWindow = findTouchedWindowAtLocked(x, y);
if (touchedWindow
&& touchedWindow->inputWindowHandle != NULL
@@ -838,12 +841,13 @@ bool InputDispatcher::dispatchMotionLocked(
bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
// Identify targets.
+ bool conflictingPointerActions = false;
if (! mCurrentInputTargetsValid) {
int32_t injectionResult;
if (isPointerEvent) {
// Pointer event. (eg. touchscreen)
injectionResult = findTouchedWindowTargetsLocked(currentTime,
- entry, nextWakeupTime);
+ entry, nextWakeupTime, &conflictingPointerActions);
} else {
// Non touch event. (eg. trackball)
injectionResult = findFocusedWindowTargetsLocked(currentTime,
@@ -863,6 +867,10 @@ bool InputDispatcher::dispatchMotionLocked(
}
// Dispatch the motion.
+ if (conflictingPointerActions) {
+ synthesizeCancelationEventsForAllConnectionsLocked(
+ InputState::CANCEL_POINTER_EVENTS, "Conflicting pointer actions.");
+ }
dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
return true;
}
@@ -890,15 +898,15 @@ void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const M
"touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
"orientation=%f",
i, entry->pointerIds[i],
- sample->pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_X),
- sample->pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_Y),
- sample->pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_PRESSURE),
- sample->pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_SIZE),
- sample->pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MAJOR),
- sample->pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MINOR),
- sample->pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR),
- sample->pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_TOOL_MINOR),
- sample->pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_ORIENTATION));
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+ sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
}
// Keep in mind that due to batching, it is possible for the number of samples actually
@@ -1123,7 +1131,7 @@ Unresponsive:
}
int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
- const MotionEntry* entry, nsecs_t* nextWakeupTime) {
+ const MotionEntry* entry, nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
enum InjectionPermission {
INJECTION_PERMISSION_UNKNOWN,
INJECTION_PERMISSION_GRANTED,
@@ -1166,38 +1174,45 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
// Update the touch state as needed based on the properties of the touch event.
int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
- bool isSplit, wrongDevice;
- if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
- mTempTouchState.reset();
- mTempTouchState.down = true;
- mTempTouchState.deviceId = entry->deviceId;
- mTempTouchState.source = entry->source;
- isSplit = false;
- wrongDevice = false;
+
+ bool isSplit = mTouchState.split;
+ bool wrongDevice = mTouchState.down
+ && (mTouchState.deviceId != entry->deviceId
+ || mTouchState.source != entry->source);
+ if (maskedAction == AMOTION_EVENT_ACTION_DOWN
+ || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
+ bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
+ if (wrongDevice && !down) {
+ mTempTouchState.copyFrom(mTouchState);
+ } else {
+ mTempTouchState.reset();
+ mTempTouchState.down = down;
+ mTempTouchState.deviceId = entry->deviceId;
+ mTempTouchState.source = entry->source;
+ isSplit = false;
+ wrongDevice = false;
+ }
} else {
mTempTouchState.copyFrom(mTouchState);
- isSplit = mTempTouchState.split;
- wrongDevice = mTempTouchState.down
- && (mTempTouchState.deviceId != entry->deviceId
- || mTempTouchState.source != entry->source);
- if (wrongDevice) {
+ }
+ if (wrongDevice) {
#if DEBUG_INPUT_DISPATCHER_POLICY
- LOGD("Dropping event because a pointer for a different device is already down.");
+ LOGD("Dropping event because a pointer for a different device is already down.");
#endif
- injectionResult = INPUT_EVENT_INJECTION_FAILED;
- goto Failed;
- }
+ injectionResult = INPUT_EVENT_INJECTION_FAILED;
+ goto Failed;
}
if (maskedAction == AMOTION_EVENT_ACTION_DOWN
- || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
+ || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)
+ || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
/* Case 1: New splittable pointer going down. */
int32_t pointerIndex = getMotionEventActionPointerIndex(action);
int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].
- getAxisValue(AINPUT_MOTION_AXIS_X));
+ getAxisValue(AMOTION_EVENT_AXIS_X));
int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].
- getAxisValue(AINPUT_MOTION_AXIS_Y));
+ getAxisValue(AMOTION_EVENT_AXIS_Y));
const InputWindow* newTouchedWindow = NULL;
const InputWindow* topErrorWindow = NULL;
@@ -1365,7 +1380,8 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
// If this is the first pointer going down and the touched window has a wallpaper
// then also add the touched wallpaper windows so they are locked in for the duration
// of the touch gesture.
- if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
+ if (maskedAction == AMOTION_EVENT_ACTION_DOWN
+ || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
if (foregroundWindow->hasWallpaper) {
for (size_t i = 0; i < mWindows.size(); i++) {
@@ -1404,12 +1420,14 @@ Failed:
if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
if (!wrongDevice) {
if (maskedAction == AMOTION_EVENT_ACTION_UP
- || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
+ || maskedAction == AMOTION_EVENT_ACTION_CANCEL
+ || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
// All pointers up or canceled.
mTempTouchState.reset();
} else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
// First pointer went down.
if (mTouchState.down) {
+ *outConflictingPointerActions = true;
#if DEBUG_FOCUS
LOGD("Pointer down received while already down.");
#endif
@@ -1750,29 +1768,7 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
// Update the connection's input state.
EventEntry* eventEntry = dispatchEntry->eventEntry;
- InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
-
-#if FILTER_INPUT_EVENTS
- // Filter out inconsistent sequences of input events.
- // The input system may drop or inject events in a way that could violate implicit
- // invariants on input state and potentially cause an application to crash
- // or think that a key or pointer is stuck down. Technically we make no guarantees
- // of consistency but it would be nice to improve on this where possible.
- // XXX: This code is a proof of concept only. Not ready for prime time.
- if (consistency == InputState::TOLERABLE) {
-#if DEBUG_DISPATCH_CYCLE
- LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
- "current input state but that is likely to be tolerated by the application.",
- connection->getInputChannelName());
-#endif
- } else if (consistency == InputState::BROKEN) {
- LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
- "current input state and that is likely to cause the application to crash.",
- connection->getInputChannelName());
- startNextDispatchCycleLocked(currentTime, connection);
- return;
- }
-#endif
+ connection->inputState.trackEvent(eventEntry);
// Publish the event.
status_t status;
@@ -2284,15 +2280,15 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
"touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
"orientation=%f",
i, pointerIds[i],
- pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_X),
- pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_Y),
- pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_PRESSURE),
- pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_SIZE),
- pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MAJOR),
- pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MINOR),
- pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR),
- pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_TOOL_MINOR),
- pointerCoords[i].getAxisValue(AINPUT_MOTION_AXIS_ORIENTATION));
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+ pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
}
#endif
if (! validateMotionEvent(action, pointerCount, pointerIds)) {
@@ -2307,7 +2303,8 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
AutoMutex _l(mLock);
// Attempt batching and streaming of move events.
- if (action == AMOTION_EVENT_ACTION_MOVE) {
+ if (action == AMOTION_EVENT_ACTION_MOVE
+ || action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
// BATCHING CASE
//
// Try to append a move sample to the tail of the inbound queue for this device.
@@ -2326,7 +2323,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
continue;
}
- if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
+ if (motionEntry->action != action
|| motionEntry->source != source
|| motionEntry->pointerCount != pointerCount
|| motionEntry->isInjected()) {
@@ -2385,7 +2382,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
MotionEntry* motionEntry = static_cast<MotionEntry*>(
dispatchEntry->eventEntry);
- if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
+ if (motionEntry->action != action
|| motionEntry->deviceId != deviceId
|| motionEntry->source != source
|| motionEntry->pointerCount != pointerCount
@@ -3529,21 +3526,20 @@ bool InputDispatcher::InputState::isNeutral() const {
return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
}
-InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
+void InputDispatcher::InputState::trackEvent(
const EventEntry* entry) {
switch (entry->type) {
case EventEntry::TYPE_KEY:
- return trackKey(static_cast<const KeyEntry*>(entry));
+ trackKey(static_cast<const KeyEntry*>(entry));
+ break;
case EventEntry::TYPE_MOTION:
- return trackMotion(static_cast<const MotionEntry*>(entry));
-
- default:
- return CONSISTENT;
+ trackMotion(static_cast<const MotionEntry*>(entry));
+ break;
}
}
-InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
+void InputDispatcher::InputState::trackKey(
const KeyEntry* entry) {
int32_t action = entry->action;
for (size_t i = 0; i < mKeyMementos.size(); i++) {
@@ -3555,19 +3551,20 @@ InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
switch (action) {
case AKEY_EVENT_ACTION_UP:
mKeyMementos.removeAt(i);
- return CONSISTENT;
+ return;
case AKEY_EVENT_ACTION_DOWN:
- return TOLERABLE;
+ mKeyMementos.removeAt(i);
+ goto Found;
default:
- return BROKEN;
+ return;
}
}
}
- switch (action) {
- case AKEY_EVENT_ACTION_DOWN: {
+Found:
+ if (action == AKEY_EVENT_ACTION_DOWN) {
mKeyMementos.push();
KeyMemento& memento = mKeyMementos.editTop();
memento.deviceId = entry->deviceId;
@@ -3576,15 +3573,10 @@ InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
memento.scanCode = entry->scanCode;
memento.flags = entry->flags;
memento.downTime = entry->downTime;
- return CONSISTENT;
- }
-
- default:
- return BROKEN;
}
}
-InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
+void InputDispatcher::InputState::trackMotion(
const MotionEntry* entry) {
int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
for (size_t i = 0; i < mMotionMementos.size(); i++) {
@@ -3594,40 +3586,28 @@ InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotio
switch (action) {
case AMOTION_EVENT_ACTION_UP:
case AMOTION_EVENT_ACTION_CANCEL:
+ case AMOTION_EVENT_ACTION_HOVER_MOVE:
mMotionMementos.removeAt(i);
- return CONSISTENT;
+ return;
case AMOTION_EVENT_ACTION_DOWN:
- return TOLERABLE;
-
- case AMOTION_EVENT_ACTION_POINTER_DOWN:
- if (entry->pointerCount == memento.pointerCount + 1) {
- memento.setPointers(entry);
- return CONSISTENT;
- }
- return BROKEN;
+ mMotionMementos.removeAt(i);
+ goto Found;
case AMOTION_EVENT_ACTION_POINTER_UP:
- if (entry->pointerCount == memento.pointerCount - 1) {
- memento.setPointers(entry);
- return CONSISTENT;
- }
- return BROKEN;
-
+ case AMOTION_EVENT_ACTION_POINTER_DOWN:
case AMOTION_EVENT_ACTION_MOVE:
- if (entry->pointerCount == memento.pointerCount) {
- return CONSISTENT;
- }
- return BROKEN;
+ memento.setPointers(entry);
+ return;
default:
- return BROKEN;
+ return;
}
}
}
- switch (action) {
- case AMOTION_EVENT_ACTION_DOWN: {
+Found:
+ if (action == AMOTION_EVENT_ACTION_DOWN) {
mMotionMementos.push();
MotionMemento& memento = mMotionMementos.editTop();
memento.deviceId = entry->deviceId;
@@ -3636,11 +3616,6 @@ InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotio
memento.yPrecision = entry->yPrecision;
memento.downTime = entry->downTime;
memento.setPointers(entry);
- return CONSISTENT;
- }
-
- default:
- return BROKEN;
}
}
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 006c6b8a22f8..7abe0140f445 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -593,19 +593,6 @@ private:
* synthesized when events are dropped. */
class InputState {
public:
- // Specifies whether a given event will violate input state consistency.
- enum Consistency {
- // The event is consistent with the current input state.
- CONSISTENT,
- // The event is inconsistent with the current input state but applications
- // will tolerate it. eg. Down followed by another down.
- TOLERABLE,
- // The event is inconsistent with the current input state and will probably
- // cause applications to crash. eg. Up without prior down, move with
- // unexpected number of pointers.
- BROKEN
- };
-
// Specifies the sources to cancel.
enum CancelationOptions {
CANCEL_ALL_EVENTS = 0,
@@ -621,16 +608,13 @@ private:
bool isNeutral() const;
// Records tracking information for an event that has just been published.
- // Returns whether the event is consistent with the current input state.
- Consistency trackEvent(const EventEntry* entry);
+ void trackEvent(const EventEntry* entry);
// Records tracking information for a key event that has just been published.
- // Returns whether the event is consistent with the current input state.
- Consistency trackKey(const KeyEntry* entry);
+ void trackKey(const KeyEntry* entry);
// Records tracking information for a motion event that has just been published.
- // Returns whether the event is consistent with the current input state.
- Consistency trackMotion(const MotionEntry* entry);
+ void trackMotion(const MotionEntry* entry);
// Synthesizes cancelation events for the current state and resets the tracked state.
void synthesizeCancelationEvents(nsecs_t currentTime, Allocator* allocator,
@@ -911,7 +895,7 @@ private:
int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry,
nsecs_t* nextWakeupTime);
int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry,
- nsecs_t* nextWakeupTime);
+ nsecs_t* nextWakeupTime, bool* outConflictingPointerActions);
void addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
BitSet32 pointerIds);
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 577da01527ad..a963c726a212 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -565,15 +565,6 @@ InputDevice::~InputDevice() {
mMappers.clear();
}
-static void dumpMotionRange(String8& dump, const InputDeviceInfo& deviceInfo,
- int32_t rangeType, const char* name) {
- const InputDeviceInfo::MotionRange* range = deviceInfo.getMotionRange(rangeType);
- if (range) {
- dump.appendFormat(INDENT3 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
- name, range->min, range->max, range->flat, range->fuzz);
- }
-}
-
void InputDevice::dump(String8& dump) {
InputDeviceInfo deviceInfo;
getDeviceInfo(& deviceInfo);
@@ -582,17 +573,24 @@ void InputDevice::dump(String8& dump) {
deviceInfo.getName().string());
dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
- if (!deviceInfo.getMotionRanges().isEmpty()) {
+
+ const KeyedVector<int32_t, InputDeviceInfo::MotionRange> ranges = deviceInfo.getMotionRanges();
+ if (!ranges.isEmpty()) {
dump.append(INDENT2 "Motion Ranges:\n");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_X, "X");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_Y, "Y");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_PRESSURE, "Pressure");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_SIZE, "Size");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOUCH_MAJOR, "TouchMajor");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOUCH_MINOR, "TouchMinor");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOOL_MAJOR, "ToolMajor");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOOL_MINOR, "ToolMinor");
- dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_ORIENTATION, "Orientation");
+ for (size_t i = 0; i < ranges.size(); i++) {
+ int32_t axis = ranges.keyAt(i);
+ const char* label = getAxisLabel(axis);
+ char name[32];
+ if (label) {
+ strncpy(name, label, sizeof(name));
+ name[sizeof(name) - 1] = '\0';
+ } else {
+ snprintf(name, sizeof(name), "%d", axis);
+ }
+ const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
+ dump.appendFormat(INDENT3 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
+ name, range.min, range.max, range.flat, range.fuzz);
+ }
}
size_t numMappers = mMappers.size();
@@ -1061,14 +1059,21 @@ void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
if (mParameters.mode == Parameters::MODE_POINTER) {
float minX, minY, maxX, maxY;
if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
- info->addMotionRange(AINPUT_MOTION_RANGE_X, minX, maxX, 0.0f, 0.0f);
- info->addMotionRange(AINPUT_MOTION_RANGE_Y, minY, maxY, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_X, minX, maxX, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_Y, minY, maxY, 0.0f, 0.0f);
}
} else {
- info->addMotionRange(AINPUT_MOTION_RANGE_X, -1.0f, 1.0f, 0.0f, mXScale);
- info->addMotionRange(AINPUT_MOTION_RANGE_Y, -1.0f, 1.0f, 0.0f, mYScale);
+ info->addMotionRange(AMOTION_EVENT_AXIS_X, -1.0f, 1.0f, 0.0f, mXScale);
+ info->addMotionRange(AMOTION_EVENT_AXIS_Y, -1.0f, 1.0f, 0.0f, mYScale);
+ }
+ info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, 0.0f, 1.0f, 0.0f, 0.0f);
+
+ if (mHaveVWheel) {
+ info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, -1.0f, 1.0f, 0.0f, 0.0f);
+ }
+ if (mHaveHWheel) {
+ info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, -1.0f, 1.0f, 0.0f, 0.0f);
}
- info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE, 0.0f, 1.0f, 0.0f, 0.0f);
}
void CursorInputMapper::dump(String8& dump) {
@@ -1076,8 +1081,14 @@ void CursorInputMapper::dump(String8& dump) {
AutoMutex _l(mLock);
dump.append(INDENT2 "Cursor Input Mapper:\n");
dumpParameters(dump);
+ dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
+ dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
+ dump.appendFormat(INDENT3 "HaveVWheel: %s\n", toString(mHaveVWheel));
+ dump.appendFormat(INDENT3 "HaveHWheel: %s\n", toString(mHaveHWheel));
+ dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
+ dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
dump.appendFormat(INDENT3 "Down: %s\n", toString(mLocked.down));
dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
} // release lock
@@ -1107,6 +1118,12 @@ void CursorInputMapper::configure() {
mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
break;
}
+
+ mVWheelScale = 1.0f;
+ mHWheelScale = 1.0f;
+
+ mHaveVWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_WHEEL);
+ mHaveHWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_HWHEEL);
}
void CursorInputMapper::configureParameters() {
@@ -1200,6 +1217,14 @@ void CursorInputMapper::process(const RawEvent* rawEvent) {
mAccumulator.fields |= Accumulator::FIELD_REL_Y;
mAccumulator.relY = rawEvent->value;
break;
+ case REL_WHEEL:
+ mAccumulator.fields |= Accumulator::FIELD_REL_WHEEL;
+ mAccumulator.relWheel = rawEvent->value;
+ break;
+ case REL_HWHEEL:
+ mAccumulator.fields |= Accumulator::FIELD_REL_HWHEEL;
+ mAccumulator.relHWheel = rawEvent->value;
+ break;
}
break;
@@ -1250,8 +1275,10 @@ void CursorInputMapper::sync(nsecs_t when) {
if (downChanged) {
motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
- } else {
+ } else if (mLocked.down || mPointerController == NULL) {
motionEventAction = AMOTION_EVENT_ACTION_MOVE;
+ } else {
+ motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
}
if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0
@@ -1294,14 +1321,21 @@ void CursorInputMapper::sync(nsecs_t when) {
}
float x, y;
mPointerController->getPosition(&x, &y);
- pointerCoords.setAxisValue(AINPUT_MOTION_AXIS_X, x);
- pointerCoords.setAxisValue(AINPUT_MOTION_AXIS_Y, y);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
} else {
- pointerCoords.setAxisValue(AINPUT_MOTION_AXIS_X, deltaX);
- pointerCoords.setAxisValue(AINPUT_MOTION_AXIS_Y, deltaY);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
}
- pointerCoords.setAxisValue(AINPUT_MOTION_AXIS_PRESSURE, mLocked.down ? 1.0f : 0.0f);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, mLocked.down ? 1.0f : 0.0f);
+
+ if (mHaveVWheel && (fields & Accumulator::FIELD_REL_WHEEL)) {
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, mAccumulator.relWheel);
+ }
+ if (mHaveHWheel && (fields & Accumulator::FIELD_REL_HWHEEL)) {
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, mAccumulator.relHWheel);
+ }
} // release lock
int32_t metaState = mContext->getGlobalMetaState();
@@ -1350,35 +1384,35 @@ void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
// noticed immediately.
configureSurfaceLocked();
- info->addMotionRange(AINPUT_MOTION_RANGE_X, mLocked.orientedRanges.x);
- info->addMotionRange(AINPUT_MOTION_RANGE_Y, mLocked.orientedRanges.y);
+ info->addMotionRange(AMOTION_EVENT_AXIS_X, mLocked.orientedRanges.x);
+ info->addMotionRange(AMOTION_EVENT_AXIS_Y, mLocked.orientedRanges.y);
if (mLocked.orientedRanges.havePressure) {
- info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE,
+ info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE,
mLocked.orientedRanges.pressure);
}
if (mLocked.orientedRanges.haveSize) {
- info->addMotionRange(AINPUT_MOTION_RANGE_SIZE,
+ info->addMotionRange(AMOTION_EVENT_AXIS_SIZE,
mLocked.orientedRanges.size);
}
if (mLocked.orientedRanges.haveTouchSize) {
- info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR,
+ info->addMotionRange(AMOTION_EVENT_AXIS_TOUCH_MAJOR,
mLocked.orientedRanges.touchMajor);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR,
+ info->addMotionRange(AMOTION_EVENT_AXIS_TOUCH_MINOR,
mLocked.orientedRanges.touchMinor);
}
if (mLocked.orientedRanges.haveToolSize) {
- info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR,
+ info->addMotionRange(AMOTION_EVENT_AXIS_TOOL_MAJOR,
mLocked.orientedRanges.toolMajor);
- info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR,
+ info->addMotionRange(AMOTION_EVENT_AXIS_TOOL_MINOR,
mLocked.orientedRanges.toolMinor);
}
if (mLocked.orientedRanges.haveOrientation) {
- info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION,
+ info->addMotionRange(AMOTION_EVENT_AXIS_ORIENTATION,
mLocked.orientedRanges.orientation);
}
} // release lock
@@ -1803,7 +1837,7 @@ void TouchInputMapper::configureVirtualKeysLocked() {
virtualKey.scanCode = virtualKeyDefinition.scanCode;
int32_t keyCode;
uint32_t flags;
- if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode,
+ if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode,
& keyCode, & flags)) {
LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
virtualKey.scanCode);
@@ -2686,15 +2720,15 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
// Write output coords.
PointerCoords& out = pointerCoords[outIndex];
out.clear();
- out.setAxisValue(AINPUT_MOTION_AXIS_X, x);
- out.setAxisValue(AINPUT_MOTION_AXIS_Y, y);
- out.setAxisValue(AINPUT_MOTION_AXIS_PRESSURE, pressure);
- out.setAxisValue(AINPUT_MOTION_AXIS_SIZE, size);
- out.setAxisValue(AINPUT_MOTION_AXIS_TOUCH_MAJOR, touchMajor);
- out.setAxisValue(AINPUT_MOTION_AXIS_TOUCH_MINOR, touchMinor);
- out.setAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR, toolMajor);
- out.setAxisValue(AINPUT_MOTION_AXIS_TOOL_MINOR, toolMinor);
- out.setAxisValue(AINPUT_MOTION_AXIS_ORIENTATION, orientation);
+ out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
+ out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+ out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
+ out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
+ out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
+ out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
+ out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
+ out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
+ out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
pointerIds[outIndex] = int32_t(id);
@@ -2706,8 +2740,8 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
// Check edge flags by looking only at the first pointer since the flags are
// global to the event.
if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
- float x = pointerCoords[0].getAxisValue(AINPUT_MOTION_AXIS_X);
- float y = pointerCoords[0].getAxisValue(AINPUT_MOTION_AXIS_Y);
+ float x = pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X);
+ float y = pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y);
if (x <= 0) {
motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
@@ -3715,7 +3749,6 @@ void MultiTouchInputMapper::configureRawAxes() {
JoystickInputMapper::JoystickInputMapper(InputDevice* device) :
InputMapper(device) {
- initialize();
}
JoystickInputMapper::~JoystickInputMapper() {
@@ -3728,176 +3761,219 @@ uint32_t JoystickInputMapper::getSources() {
void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
InputMapper::populateDeviceInfo(info);
- if (mAxes.x.valid) {
- info->addMotionRange(AINPUT_MOTION_RANGE_X,
- mAxes.x.min, mAxes.x.max, mAxes.x.flat, mAxes.x.fuzz);
- }
- if (mAxes.y.valid) {
- info->addMotionRange(AINPUT_MOTION_RANGE_Y,
- mAxes.y.min, mAxes.y.max, mAxes.y.flat, mAxes.y.fuzz);
+ for (size_t i = 0; i < mAxes.size(); i++) {
+ const Axis& axis = mAxes.valueAt(i);
+ info->addMotionRange(axis.axis, axis.min, axis.max, axis.flat, axis.fuzz);
}
}
void JoystickInputMapper::dump(String8& dump) {
dump.append(INDENT2 "Joystick Input Mapper:\n");
- dump.append(INDENT3 "Raw Axes:\n");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.x, "X");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.y, "Y");
-
- dump.append(INDENT3 "Normalized Axes:\n");
- dumpNormalizedAxis(dump, mAxes.x, "X");
- dumpNormalizedAxis(dump, mAxes.y, "Y");
- dumpNormalizedAxis(dump, mAxes.hat0X, "Hat0X");
- dumpNormalizedAxis(dump, mAxes.hat0Y, "Hat0Y");
-}
-
-void JoystickInputMapper::dumpNormalizedAxis(String8& dump,
- const NormalizedAxis& axis, const char* name) {
- if (axis.valid) {
+ dump.append(INDENT3 "Axes:\n");
+ size_t numAxes = mAxes.size();
+ for (size_t i = 0; i < numAxes; i++) {
+ const Axis& axis = mAxes.valueAt(i);
+ const char* label = getAxisLabel(axis.axis);
+ char name[32];
+ if (label) {
+ strncpy(name, label, sizeof(name));
+ name[sizeof(name) - 1] = '\0';
+ } else {
+ snprintf(name, sizeof(name), "%d", axis.axis);
+ }
dump.appendFormat(INDENT4 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, "
- "scale=%0.3f, center=%0.3f, precision=%0.3f, value=%0.3f\n",
+ "scale=%0.3f, offset=%0.3f\n",
name, axis.min, axis.max, axis.flat, axis.fuzz,
- axis.scale, axis.center, axis.precision, axis.value);
- } else {
- dump.appendFormat(INDENT4 "%s: unknown range\n", name);
+ axis.scale, axis.offset);
+ dump.appendFormat(INDENT4 " rawAxis=%d, rawMin=%d, rawMax=%d, rawFlat=%d, rawFuzz=%d\n",
+ mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
+ axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz);
}
}
void JoystickInputMapper::configure() {
InputMapper::configure();
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_HAT0X, & mRawAxes.hat0X);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_HAT0Y, & mRawAxes.hat0Y);
+ // Collect all axes.
+ for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
+ RawAbsoluteAxisInfo rawAxisInfo;
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), abs, &rawAxisInfo);
+ if (rawAxisInfo.valid) {
+ int32_t axisId;
+ bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisId);
+ if (!explicitlyMapped) {
+ // Axis is not explicitly mapped, will choose a generic axis later.
+ axisId = -1;
+ }
+
+ Axis axis;
+ if (isCenteredAxis(axisId)) {
+ float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
+ float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
+ axis.initialize(rawAxisInfo, axisId, explicitlyMapped,
+ scale, offset, -1.0f, 1.0f,
+ rawAxisInfo.flat * scale, rawAxisInfo.fuzz * scale);
+ } else {
+ float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
+ axis.initialize(rawAxisInfo, axisId, explicitlyMapped,
+ scale, 0.0f, 0.0f, 1.0f,
+ rawAxisInfo.flat * scale, rawAxisInfo.fuzz * scale);
+ }
+
+ // To eliminate noise while the joystick is at rest, filter out small variations
+ // in axis values up front.
+ axis.filter = axis.flat * 0.25f;
+
+ mAxes.add(abs, axis);
+ }
+ }
+
+ // If there are too many axes, start dropping them.
+ // Prefer to keep explicitly mapped axes.
+ if (mAxes.size() > PointerCoords::MAX_AXES) {
+ LOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.",
+ getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
+ pruneAxes(true);
+ pruneAxes(false);
+ }
- mAxes.x.configure(mRawAxes.x);
- mAxes.y.configure(mRawAxes.y);
- mAxes.hat0X.configure(mRawAxes.hat0X);
- mAxes.hat0Y.configure(mRawAxes.hat0Y);
+ // Assign generic axis ids to remaining axes.
+ int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1;
+ size_t numAxes = mAxes.size();
+ for (size_t i = 0; i < numAxes; i++) {
+ Axis& axis = mAxes.editValueAt(i);
+ if (axis.axis < 0) {
+ while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
+ && haveAxis(nextGenericAxisId)) {
+ nextGenericAxisId += 1;
+ }
+
+ if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
+ axis.axis = nextGenericAxisId;
+ nextGenericAxisId += 1;
+ } else {
+ LOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
+ "have already been assigned to other axes.",
+ getDeviceName().string(), mAxes.keyAt(i));
+ mAxes.removeItemsAt(i--);
+ numAxes -= 1;
+ }
+ }
+ }
}
-void JoystickInputMapper::initialize() {
- mAccumulator.clear();
+bool JoystickInputMapper::haveAxis(int32_t axis) {
+ size_t numAxes = mAxes.size();
+ for (size_t i = 0; i < numAxes; i++) {
+ if (mAxes.valueAt(i).axis == axis) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) {
+ size_t i = mAxes.size();
+ while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) {
+ if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) {
+ continue;
+ }
+ LOGI("Discarding joystick '%s' axis %d because there are too many axes.",
+ getDeviceName().string(), mAxes.keyAt(i));
+ mAxes.removeItemsAt(i);
+ }
+}
- mAxes.x.resetState();
- mAxes.y.resetState();
- mAxes.hat0X.resetState();
- mAxes.hat0Y.resetState();
+bool JoystickInputMapper::isCenteredAxis(int32_t axis) {
+ switch (axis) {
+ case AMOTION_EVENT_AXIS_X:
+ case AMOTION_EVENT_AXIS_Y:
+ case AMOTION_EVENT_AXIS_Z:
+ case AMOTION_EVENT_AXIS_RX:
+ case AMOTION_EVENT_AXIS_RY:
+ case AMOTION_EVENT_AXIS_RZ:
+ case AMOTION_EVENT_AXIS_HAT_X:
+ case AMOTION_EVENT_AXIS_HAT_Y:
+ case AMOTION_EVENT_AXIS_ORIENTATION:
+ return true;
+ default:
+ return false;
+ }
}
void JoystickInputMapper::reset() {
// Recenter all axes.
nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- mAccumulator.clear();
- mAccumulator.fields = Accumulator::FIELD_ALL;
- sync(when);
- // Reinitialize state.
- initialize();
+ size_t numAxes = mAxes.size();
+ for (size_t i = 0; i < numAxes; i++) {
+ Axis& axis = mAxes.editValueAt(i);
+ axis.newValue = 0;
+ }
+
+ sync(when, true /*force*/);
InputMapper::reset();
}
void JoystickInputMapper::process(const RawEvent* rawEvent) {
switch (rawEvent->type) {
- case EV_ABS:
- switch (rawEvent->scanCode) {
- case ABS_X:
- mAccumulator.fields |= Accumulator::FIELD_ABS_X;
- mAccumulator.absX = rawEvent->value;
- break;
- case ABS_Y:
- mAccumulator.fields |= Accumulator::FIELD_ABS_Y;
- mAccumulator.absY = rawEvent->value;
- break;
- case ABS_HAT0X:
- mAccumulator.fields |= Accumulator::FIELD_ABS_HAT0X;
- mAccumulator.absHat0X = rawEvent->value;
- break;
- case ABS_HAT0Y:
- mAccumulator.fields |= Accumulator::FIELD_ABS_HAT0Y;
- mAccumulator.absHat0Y = rawEvent->value;
- break;
+ case EV_ABS: {
+ ssize_t index = mAxes.indexOfKey(rawEvent->scanCode);
+ if (index >= 0) {
+ Axis& axis = mAxes.editValueAt(index);
+ float newValue = rawEvent->value * axis.scale + axis.offset;
+ if (newValue != axis.newValue) {
+ axis.newValue = newValue;
+ }
}
break;
+ }
case EV_SYN:
switch (rawEvent->scanCode) {
case SYN_REPORT:
- sync(rawEvent->when);
+ sync(rawEvent->when, false /*force*/);
break;
}
break;
}
}
-void JoystickInputMapper::sync(nsecs_t when) {
- uint32_t fields = mAccumulator.fields;
- if (fields == 0) {
- return; // no new state changes, so nothing to do
+void JoystickInputMapper::sync(nsecs_t when, bool force) {
+ if (!force && !haveAxesChangedSignificantly()) {
+ return;
}
int32_t metaState = mContext->getGlobalMetaState();
- bool motionAxisChanged = false;
- if (fields & Accumulator::FIELD_ABS_X) {
- if (mAxes.x.updateValue(mAccumulator.absX)) {
- motionAxisChanged = true;
- }
- }
-
- if (fields & Accumulator::FIELD_ABS_Y) {
- if (mAxes.y.updateValue(mAccumulator.absY)) {
- motionAxisChanged = true;
- }
- }
-
- if (motionAxisChanged) {
- PointerCoords pointerCoords;
- pointerCoords.clear();
- pointerCoords.setAxisValue(AINPUT_MOTION_AXIS_X, mAxes.x.value);
- pointerCoords.setAxisValue(AINPUT_MOTION_AXIS_Y, mAxes.y.value);
-
- int32_t pointerId = 0;
- getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, 0,
- AMOTION_EVENT_ACTION_MOVE, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
- 1, &pointerId, &pointerCoords, mAxes.x.precision, mAxes.y.precision, 0);
- }
-
- if (fields & Accumulator::FIELD_ABS_HAT0X) {
- if (mAxes.hat0X.updateValueAndDirection(mAccumulator.absHat0X)) {
- notifyDirectionalAxis(mAxes.hat0X, when, metaState,
- AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_RIGHT);
- }
- }
+ PointerCoords pointerCoords;
+ pointerCoords.clear();
- if (fields & Accumulator::FIELD_ABS_HAT0Y) {
- if (mAxes.hat0Y.updateValueAndDirection(mAccumulator.absHat0Y)) {
- notifyDirectionalAxis(mAxes.hat0Y, when, metaState,
- AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN);
- }
+ size_t numAxes = mAxes.size();
+ for (size_t i = 0; i < numAxes; i++) {
+ Axis& axis = mAxes.editValueAt(i);
+ pointerCoords.setAxisValue(axis.axis, axis.newValue);
+ axis.oldValue = axis.newValue;
}
- mAccumulator.clear();
+ int32_t pointerId = 0;
+ getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, 0,
+ AMOTION_EVENT_ACTION_MOVE, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ 1, &pointerId, &pointerCoords, 0, 0, 0);
}
-void JoystickInputMapper::notifyDirectionalAxis(DirectionalAxis& axis,
- nsecs_t when, int32_t metaState, int32_t lowKeyCode, int32_t highKeyCode) {
- if (axis.lastKeyCode) {
- getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, 0,
- AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_FROM_SYSTEM,
- axis.lastKeyCode, 0, metaState, when);
- axis.lastKeyCode = 0;
- }
- if (axis.direction) {
- axis.lastKeyCode = axis.direction > 0 ? highKeyCode : lowKeyCode;
- getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, 0,
- AKEY_EVENT_ACTION_DOWN, AKEY_EVENT_FLAG_FROM_SYSTEM,
- axis.lastKeyCode, 0, metaState, when);
+bool JoystickInputMapper::haveAxesChangedSignificantly() {
+ size_t numAxes = mAxes.size();
+ for (size_t i = 0; i < numAxes; i++) {
+ const Axis& axis = mAxes.valueAt(i);
+ if (axis.newValue != axis.oldValue
+ && fabs(axis.newValue - axis.oldValue) > axis.filter) {
+ return true;
+ }
}
+ return false;
}
-
} // namespace android
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 27cb8e1e685c..cf41535e097c 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -481,7 +481,9 @@ private:
enum {
FIELD_BTN_MOUSE = 1,
FIELD_REL_X = 2,
- FIELD_REL_Y = 4
+ FIELD_REL_Y = 4,
+ FIELD_REL_WHEEL = 8,
+ FIELD_REL_HWHEEL = 16,
};
uint32_t fields;
@@ -489,6 +491,8 @@ private:
bool btnMouse;
int32_t relX;
int32_t relY;
+ int32_t relWheel;
+ int32_t relHWheel;
inline void clear() {
fields = 0;
@@ -500,6 +504,12 @@ private:
float mYScale;
float mXPrecision;
float mYPrecision;
+
+ bool mHaveVWheel;
+ bool mHaveHWheel;
+ float mVWheelScale;
+ float mHWheelScale;
+
sp<PointerControllerInterface> mPointerController;
struct LockedState {
@@ -985,123 +995,53 @@ public:
virtual void process(const RawEvent* rawEvent);
private:
- struct RawAxes {
- RawAbsoluteAxisInfo x;
- RawAbsoluteAxisInfo y;
- RawAbsoluteAxisInfo hat0X;
- RawAbsoluteAxisInfo hat0Y;
- } mRawAxes;
-
- struct NormalizedAxis {
- bool valid;
-
- static const float min = -1.0f;
- static const float max = -1.0f;
-
- float scale; // scale factor
- float center; // center offset after scaling
- float precision; // precision
- float flat; // size of flat region
- float fuzz; // error tolerance
-
- float value; // most recent value
-
- NormalizedAxis() : valid(false), scale(0), center(0), precision(0),
- flat(0), fuzz(0), value(0) {
- }
-
- void configure(const RawAbsoluteAxisInfo& rawAxis) {
- if (rawAxis.valid && rawAxis.getRange() != 0) {
- valid = true;
- scale = 2.0f / rawAxis.getRange();
- precision = rawAxis.getRange();
- flat = rawAxis.flat * scale;
- fuzz = rawAxis.fuzz * scale;
- center = float(rawAxis.minValue + rawAxis.maxValue) / rawAxis.getRange();
- }
- }
-
- void resetState() {
- value = 0;
- }
-
- bool updateValue(int32_t rawValue) {
- float newValue = rawValue * scale - center;
- if (value == newValue) {
- return false;
- }
- value = newValue;
- return true;
- }
- };
-
- struct DirectionalAxis : NormalizedAxis {
- int32_t direction; // most recent direction vector: value is one of -1, 0, 1.
-
- int32_t lastKeyCode; // most recent key code produced
-
- DirectionalAxis() : lastKeyCode(0) {
- }
-
- void resetState() {
- NormalizedAxis::resetState();
- direction = 0;
- lastKeyCode = 0;
- }
-
- bool updateValueAndDirection(int32_t rawValue) {
- if (!updateValue(rawValue)) {
- return false;
- }
- if (value > flat) {
- direction = 1;
- } else if (value < -flat) {
- direction = -1;
- } else {
- direction = 0;
- }
- return true;
+ struct Axis {
+ RawAbsoluteAxisInfo rawAxisInfo;
+
+ int32_t axis; // axis id
+ bool explicitlyMapped; // true if the axis was explicitly assigned an axis id
+
+ float scale; // scale factor from raw to normalized values
+ float offset; // offset to add after scaling for normalization
+
+ float min; // normalized inclusive minimum
+ float max; // normalized inclusive maximum
+ float flat; // normalized flat region size
+ float fuzz; // normalized error tolerance
+
+ float oldValue; // previous value
+ float newValue; // most recent value
+
+ float filter; // filter out small variations of this size
+
+ void initialize(const RawAbsoluteAxisInfo& rawAxisInfo,
+ int32_t axis, bool explicitlyMapped, float scale, float offset,
+ float min, float max, float flat, float fuzz) {
+ this->rawAxisInfo = rawAxisInfo;
+ this->axis = axis;
+ this->explicitlyMapped = explicitlyMapped;
+ this->scale = scale;
+ this->offset = offset;
+ this->min = min;
+ this->max = max;
+ this->flat = flat;
+ this->fuzz = fuzz;
+ this->filter = 0;
+ this->oldValue = 0;
+ this->newValue = 0;
}
};
- struct Axes {
- NormalizedAxis x;
- NormalizedAxis y;
- DirectionalAxis hat0X;
- DirectionalAxis hat0Y;
- } mAxes;
-
- struct Accumulator {
- enum {
- FIELD_ABS_X = 1,
- FIELD_ABS_Y = 2,
- FIELD_ABS_HAT0X = 4,
- FIELD_ABS_HAT0Y = 8,
-
- FIELD_ALL = FIELD_ABS_X | FIELD_ABS_Y | FIELD_ABS_HAT0X | FIELD_ABS_HAT0Y,
- };
-
- uint32_t fields;
-
- int32_t absX;
- int32_t absY;
- int32_t absHat0X;
- int32_t absHat0Y;
-
- inline void clear() {
- fields = 0;
- }
- } mAccumulator;
+ // Axes indexed by raw ABS_* axis index.
+ KeyedVector<int32_t, Axis> mAxes;
- void initialize();
-
- void sync(nsecs_t when);
+ void sync(nsecs_t when, bool force);
- void notifyDirectionalAxis(DirectionalAxis& axis,
- nsecs_t when, int32_t metaState, int32_t lowKeyCode, int32_t highKeyCode);
+ bool haveAxis(int32_t axis);
+ void pruneAxes(bool ignoreExplicitlyMappedAxes);
+ bool haveAxesChangedSignificantly();
- static void dumpNormalizedAxis(String8& dump,
- const NormalizedAxis& axis, const char* name);
+ static bool isCenteredAxis(int32_t axis);
};
} // namespace android
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 34d613aa80e9..fac71bb7e0ec 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -561,7 +561,11 @@ private:
return -1;
}
- virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
+ virtual bool hasRelativeAxis(int32_t deviceId, int axis) const {
+ return false;
+ }
+
+ virtual status_t mapKey(int32_t deviceId, int scancode,
int32_t* outKeycode, uint32_t* outFlags) const {
Device* device = getDevice(deviceId);
if (device) {
@@ -579,6 +583,11 @@ private:
return NAME_NOT_FOUND;
}
+ virtual status_t mapAxis(int32_t deviceId, int scancode,
+ int32_t* outAxis) const {
+ return NAME_NOT_FOUND;
+ }
+
virtual void addExcludedDevice(const char* deviceName) {
mExcludedDevices.add(String8(deviceName));
}
@@ -1473,15 +1482,15 @@ protected:
float x, float y, float pressure, float size,
float touchMajor, float touchMinor, float toolMajor, float toolMinor,
float orientation) {
- ASSERT_NEAR(x, coords.getAxisValue(AINPUT_MOTION_AXIS_X), 1);
- ASSERT_NEAR(y, coords.getAxisValue(AINPUT_MOTION_AXIS_Y), 1);
- ASSERT_NEAR(pressure, coords.getAxisValue(AINPUT_MOTION_AXIS_PRESSURE), EPSILON);
- ASSERT_NEAR(size, coords.getAxisValue(AINPUT_MOTION_AXIS_SIZE), EPSILON);
- ASSERT_NEAR(touchMajor, coords.getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MAJOR), 1);
- ASSERT_NEAR(touchMinor, coords.getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MINOR), 1);
- ASSERT_NEAR(toolMajor, coords.getAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR), 1);
- ASSERT_NEAR(toolMinor, coords.getAxisValue(AINPUT_MOTION_AXIS_TOOL_MINOR), 1);
- ASSERT_NEAR(orientation, coords.getAxisValue(AINPUT_MOTION_AXIS_ORIENTATION), EPSILON);
+ ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+ ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON);
+ ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON);
+ ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), 1);
+ ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), 1);
+ ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), 1);
+ ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), 1);
+ ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON);
}
};
@@ -2892,8 +2901,8 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotate
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
- ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AINPUT_MOTION_AXIS_X), 1);
- ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AINPUT_MOTION_AXIS_Y), 1);
+ ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
@@ -2914,8 +2923,8 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions)
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
- ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AINPUT_MOTION_AXIS_X), 1);
- ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AINPUT_MOTION_AXIS_Y), 1);
+ ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
@@ -2927,8 +2936,8 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions)
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
- ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AINPUT_MOTION_AXIS_X), 1);
- ASSERT_NEAR(DISPLAY_WIDTH - 50, args.pointerCoords[0].getAxisValue(AINPUT_MOTION_AXIS_Y), 1);
+ ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ ASSERT_NEAR(DISPLAY_WIDTH - 50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
@@ -2940,8 +2949,8 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions)
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
- ASSERT_NEAR(DISPLAY_WIDTH - 50, args.pointerCoords[0].getAxisValue(AINPUT_MOTION_AXIS_X), 1);
- ASSERT_NEAR(DISPLAY_HEIGHT - 75, args.pointerCoords[0].getAxisValue(AINPUT_MOTION_AXIS_Y), 1);
+ ASSERT_NEAR(DISPLAY_WIDTH - 50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ ASSERT_NEAR(DISPLAY_HEIGHT - 75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
@@ -2953,8 +2962,8 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions)
processSync(mapper);
ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
- ASSERT_NEAR(DISPLAY_HEIGHT - 75, args.pointerCoords[0].getAxisValue(AINPUT_MOTION_AXIS_X), 1);
- ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AINPUT_MOTION_AXIS_Y), 1);
+ ASSERT_NEAR(DISPLAY_HEIGHT - 75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+ ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 51e9b0077b59..44b859098e05 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -26,7 +26,7 @@ import com.android.internal.view.IInputMethodManager;
import com.android.internal.view.IInputMethodSession;
import com.android.internal.view.InputBindResult;
-import com.android.server.StatusBarManagerService;
+import com.android.server.EventLogTags;
import org.xmlpull.v1.XmlPullParserException;
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index ef3e89a929b2..eaf68b0ed8cf 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -610,11 +610,10 @@ class NetworkManagementService extends INetworkManagementService.Stub {
* argv7 - Preamble
* argv8 - Max SCB
*/
- String str = String.format("softap set " + wlanIface + " " + softapIface +
- " %s %s %s", convertQuotedString(wifiConfig.SSID),
- wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ?
- "wpa2-psk" : "open",
- convertQuotedString(wifiConfig.preSharedKey));
+ String str = String.format("softap set " + wlanIface + " " + softapIface +
+ " %s %s %s", convertQuotedString(wifiConfig.SSID),
+ getSecurityType(wifiConfig),
+ convertQuotedString(wifiConfig.preSharedKey));
mConnector.doCommand(str);
}
mConnector.doCommand(String.format("softap startap"));
@@ -631,6 +630,17 @@ class NetworkManagementService extends INetworkManagementService.Stub {
return '"' + s.replaceAll("\\\\","\\\\\\\\").replaceAll("\"","\\\\\"") + '"';
}
+ private String getSecurityType(WifiConfiguration wifiConfig) {
+ switch (wifiConfig.getAuthType()) {
+ case KeyMgmt.WPA_PSK:
+ return "wpa-psk";
+ case KeyMgmt.WPA2_PSK:
+ return "wpa2-psk";
+ default:
+ return "open";
+ }
+ }
+
public void stopAccessPoint() throws IllegalStateException {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
@@ -656,7 +666,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
} else {
String str = String.format("softap set " + wlanIface + " " + softapIface
+ " %s %s %s", convertQuotedString(wifiConfig.SSID),
- wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ? "wpa2-psk" : "open",
+ getSecurityType(wifiConfig),
convertQuotedString(wifiConfig.preSharedKey));
mConnector.doCommand(str);
}
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index caf637600c11..d80a2cd41c2d 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -40,7 +40,6 @@ import android.hardware.SensorManager;
import android.os.BatteryManager;
import android.os.BatteryStats;
import android.os.Binder;
-import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -50,7 +49,6 @@ import android.os.Power;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.WorkSource;
import android.provider.Settings.SettingNotFoundException;
@@ -69,14 +67,13 @@ import static android.provider.Settings.System.WINDOW_ANIMATION_SCALE;
import static android.provider.Settings.System.TRANSITION_ANIMATION_SCALE;
import java.io.FileDescriptor;
-import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Observable;
import java.util.Observer;
-class PowerManagerService extends IPowerManager.Stub
+public class PowerManagerService extends IPowerManager.Stub
implements LocalPowerManager, Watchdog.Monitor {
private static final String TAG = "PowerManagerService";
@@ -2689,7 +2686,7 @@ class PowerManagerService extends IPowerManager.Stub
}
}
- void setPolicy(WindowManagerPolicy p) {
+ public void setPolicy(WindowManagerPolicy p) {
synchronized (mLocks) {
mPolicy = p;
mLocks.notifyAll();
diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java
index 5ada77bba9a2..8df817789af2 100644
--- a/services/java/com/android/server/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -39,6 +39,7 @@ import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
import com.android.internal.statusbar.StatusBarNotification;
+import com.android.server.wm.WindowManagerService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/services/java/com/android/server/SystemBackupAgent.java b/services/java/com/android/server/SystemBackupAgent.java
index a1f43b4bdc81..80b0174b22c3 100644
--- a/services/java/com/android/server/SystemBackupAgent.java
+++ b/services/java/com/android/server/SystemBackupAgent.java
@@ -16,6 +16,7 @@
package com.android.server;
+
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.app.backup.BackupAgentHelper;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 6a6cc2a5f691..52c47e172ae9 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -17,6 +17,7 @@
package com.android.server;
import com.android.server.am.ActivityManagerService;
+import com.android.server.wm.WindowManagerService;
import com.android.internal.app.ShutdownThread;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.SamplingProfilerIntegration;
diff --git a/services/java/com/android/server/UsbService.java b/services/java/com/android/server/UsbService.java
index af4c425c24e7..1bc203ef0a5b 100644
--- a/services/java/com/android/server/UsbService.java
+++ b/services/java/com/android/server/UsbService.java
@@ -44,7 +44,11 @@ import java.util.ArrayList;
import java.util.HashMap;
/**
- * <p>UsbService monitors for changes to USB state.
+ * UsbService monitors for changes to USB state.
+ * This includes code for both USB host support (where the android device is the host)
+ * as well as USB device support (android device is connected to a USB host).
+ * Accessory mode is a special case of USB device mode, where the android device is
+ * connected to a USB host that supports the android accessory protocol.
*/
class UsbService extends IUsbManager.Stub {
private static final String TAG = UsbService.class.getSimpleName();
@@ -63,7 +67,9 @@ class UsbService extends IUsbManager.Stub {
private static final String USB_COMPOSITE_CLASS_PATH =
"/sys/class/usb_composite";
- private static final int MSG_UPDATE = 0;
+ private static final int MSG_UPDATE_STATE = 0;
+ private static final int MSG_FUNCTION_ENABLED = 1;
+ private static final int MSG_FUNCTION_DISABLED = 2;
// Delay for debouncing USB disconnects.
// We often get rapid connect/disconnect events when enabling USB functions,
@@ -79,7 +85,6 @@ class UsbService extends IUsbManager.Stub {
private int mLastConfiguration = -1;
// lists of enabled and disabled USB functions (for USB device mode)
- // synchronize on mEnabledFunctions when using either of these lists
private final ArrayList<String> mEnabledFunctions = new ArrayList<String>();
private final ArrayList<String> mDisabledFunctions = new ArrayList<String>();
@@ -90,26 +95,48 @@ class UsbService extends IUsbManager.Stub {
private final String[] mHostBlacklist;
private boolean mSystemReady;
+
private UsbAccessory mCurrentAccessory;
+ // functions to restore after exiting accessory mode
+ private final ArrayList<String> mAccessoryRestoreFunctions = new ArrayList<String>();
private final Context mContext;
-
- private final void functionEnabled(String function, boolean enabled) {
- synchronized (mEnabledFunctions) {
- if (enabled) {
- if (!mEnabledFunctions.contains(function)) {
- mEnabledFunctions.add(function);
- }
- mDisabledFunctions.remove(function);
- } else {
- if (!mDisabledFunctions.contains(function)) {
- mDisabledFunctions.add(function);
+ private final Object mLock = new Object();
+
+ /*
+ * Handles USB function enable/disable events (device mode)
+ */
+ private final void functionEnabledLocked(String function, boolean enabled) {
+ boolean enteringAccessoryMode =
+ (enabled && UsbManager.USB_FUNCTION_ACCESSORY.equals(function));
+
+ if (enteringAccessoryMode) {
+ // keep a list of functions to reenable after exiting accessory mode
+ mAccessoryRestoreFunctions.clear();
+ int count = mEnabledFunctions.size();
+ for (int i = 0; i < count; i++) {
+ String f = mEnabledFunctions.get(i);
+ // RNDIS should not be restored and adb is handled automatically
+ if (!UsbManager.USB_FUNCTION_RNDIS.equals(f) &&
+ !UsbManager.USB_FUNCTION_ADB.equals(f) &&
+ !UsbManager.USB_FUNCTION_ACCESSORY.equals(f)) {
+ mAccessoryRestoreFunctions.add(f);
}
- mEnabledFunctions.remove(function);
}
}
+ if (enabled) {
+ if (!mEnabledFunctions.contains(function)) {
+ mEnabledFunctions.add(function);
+ }
+ mDisabledFunctions.remove(function);
+ } else {
+ if (!mDisabledFunctions.contains(function)) {
+ mDisabledFunctions.add(function);
+ }
+ mEnabledFunctions.remove(function);
+ }
- if (enabled && UsbManager.USB_FUNCTION_ACCESSORY.equals(function)) {
+ if (enteringAccessoryMode) {
String[] strings = nativeGetAccessoryStrings();
if (strings != null) {
Log.d(TAG, "entering USB accessory mode");
@@ -136,6 +163,9 @@ class UsbService extends IUsbManager.Stub {
}
}
+ /*
+ * Listens for uevent messages from the kernel to monitor the USB state (device mode)
+ */
private final UEventObserver mUEventObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
@@ -143,7 +173,7 @@ class UsbService extends IUsbManager.Stub {
Slog.v(TAG, "USB UEVENT: " + event.toString());
}
- synchronized (this) {
+ synchronized (mLock) {
String name = event.get("SWITCH_NAME");
String state = event.get("SWITCH_STATE");
if (name != null && state != null) {
@@ -172,8 +202,11 @@ class UsbService extends IUsbManager.Stub {
if (function != null && enabledStr != null) {
// Note: we do not broadcast a change when a function is enabled or disabled.
// We just record the state change for the next broadcast.
- boolean enabled = "1".equals(enabledStr);
- functionEnabled(function, enabled);
+ int what = ("1".equals(enabledStr) ?
+ MSG_FUNCTION_ENABLED : MSG_FUNCTION_DISABLED);
+ Message msg = Message.obtain(mHandler, what);
+ msg.obj = function;
+ mHandler.sendMessage(msg);
}
}
}
@@ -197,6 +230,7 @@ class UsbService extends IUsbManager.Stub {
private final void init() {
char[] buffer = new char[1024];
+ // Read initial USB state (device mode)
mConfiguration = -1;
try {
FileReader file = new FileReader(USB_CONNECTED_PATH);
@@ -217,21 +251,20 @@ class UsbService extends IUsbManager.Stub {
if (mConfiguration < 0)
return;
+ // Read initial list of enabled and disabled functions (device mode)
try {
- synchronized (mEnabledFunctions) {
- File[] files = new File(USB_COMPOSITE_CLASS_PATH).listFiles();
- for (int i = 0; i < files.length; i++) {
- File file = new File(files[i], "enable");
- FileReader reader = new FileReader(file);
- int len = reader.read(buffer, 0, 1024);
- reader.close();
- int value = Integer.valueOf((new String(buffer, 0, len)).trim());
- String functionName = files[i].getName();
- if (value == 1) {
- mEnabledFunctions.add(functionName);
- } else {
- mDisabledFunctions.add(functionName);
- }
+ File[] files = new File(USB_COMPOSITE_CLASS_PATH).listFiles();
+ for (int i = 0; i < files.length; i++) {
+ File file = new File(files[i], "enable");
+ FileReader reader = new FileReader(file);
+ int len = reader.read(buffer, 0, 1024);
+ reader.close();
+ int value = Integer.valueOf((new String(buffer, 0, len)).trim());
+ String functionName = files[i].getName();
+ if (value == 1) {
+ mEnabledFunctions.add(functionName);
+ } else {
+ mDisabledFunctions.add(functionName);
}
}
} catch (FileNotFoundException e) {
@@ -251,6 +284,7 @@ class UsbService extends IUsbManager.Stub {
return false;
}
+ /* returns true if the USB device should not be accessible by applications (host mode) */
private boolean isBlackListed(int clazz, int subClass, int protocol) {
// blacklist hubs
if (clazz == UsbConstants.USB_CLASS_HUB) return true;
@@ -264,7 +298,7 @@ class UsbService extends IUsbManager.Stub {
return false;
}
- // called from JNI in monitorUsbHostBus()
+ /* Called from JNI in monitorUsbHostBus() to report new USB devices (host mode) */
private void usbDeviceAdded(String deviceName, int vendorID, int productID,
int deviceClass, int deviceSubclass, int deviceProtocol,
/* array of quintuples containing id, class, subclass, protocol
@@ -279,7 +313,7 @@ class UsbService extends IUsbManager.Stub {
return;
}
- synchronized (mDevices) {
+ synchronized (mLock) {
if (mDevices.get(deviceName) != null) {
Log.w(TAG, "device already on mDevices list: " + deviceName);
return;
@@ -338,9 +372,9 @@ class UsbService extends IUsbManager.Stub {
}
}
- // called from JNI in monitorUsbHostBus()
+ /* Called from JNI in monitorUsbHostBus to report USB device removal (host mode) */
private void usbDeviceRemoved(String deviceName) {
- synchronized (mDevices) {
+ synchronized (mLock) {
UsbDevice device = mDevices.remove(deviceName);
if (device != null) {
Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_DETACHED);
@@ -363,7 +397,7 @@ class UsbService extends IUsbManager.Stub {
}
void systemReady() {
- synchronized (this) {
+ synchronized (mLock) {
if (mContext.getResources().getBoolean(
com.android.internal.R.bool.config_hasUsbHostSupport)) {
// start monitoring for connected USB devices
@@ -375,21 +409,27 @@ class UsbService extends IUsbManager.Stub {
}
}
+ /*
+ * Sends a message to update the USB connected and configured state (device mode).
+ * If delayed is true, then we add a small delay in sending the message to debounce
+ * the USB connection when enabling USB tethering.
+ */
private final void update(boolean delayed) {
- mHandler.removeMessages(MSG_UPDATE);
- mHandler.sendEmptyMessageDelayed(MSG_UPDATE, delayed ? UPDATE_DELAY : 0);
+ mHandler.removeMessages(MSG_UPDATE_STATE);
+ mHandler.sendEmptyMessageDelayed(MSG_UPDATE_STATE, delayed ? UPDATE_DELAY : 0);
}
- /* Returns a list of all currently attached USB devices */
+ /* Returns a list of all currently attached USB devices (host mdoe) */
public void getDeviceList(Bundle devices) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null);
- synchronized (mDevices) {
+ synchronized (mLock) {
for (String name : mDevices.keySet()) {
devices.putParcelable(name, mDevices.get(name));
}
}
}
+ /* Opens the specified USB device (host mode) */
public ParcelFileDescriptor openDevice(String deviceName) {
if (isBlackListed(deviceName)) {
throw new SecurityException("USB device is on a restricted bus");
@@ -403,34 +443,37 @@ class UsbService extends IUsbManager.Stub {
return nativeOpenDevice(deviceName);
}
+ /* returns the currently attached USB accessory (device mode) */
public UsbAccessory getCurrentAccessory() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null);
return mCurrentAccessory;
}
+ /* opens the currently attached USB accessory (device mode) */
public ParcelFileDescriptor openAccessory() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null);
return nativeOpenAccessory();
}
+ /*
+ * This handler is for deferred handling of events related to device mode and accessories.
+ */
private final Handler mHandler = new Handler() {
- private void addEnabledFunctions(Intent intent) {
- synchronized (mEnabledFunctions) {
+ private void addEnabledFunctionsLocked(Intent intent) {
// include state of all USB functions in our extras
- for (int i = 0; i < mEnabledFunctions.size(); i++) {
- intent.putExtra(mEnabledFunctions.get(i), UsbManager.USB_FUNCTION_ENABLED);
- }
- for (int i = 0; i < mDisabledFunctions.size(); i++) {
- intent.putExtra(mDisabledFunctions.get(i), UsbManager.USB_FUNCTION_DISABLED);
- }
+ for (int i = 0; i < mEnabledFunctions.size(); i++) {
+ intent.putExtra(mEnabledFunctions.get(i), UsbManager.USB_FUNCTION_ENABLED);
+ }
+ for (int i = 0; i < mDisabledFunctions.size(); i++) {
+ intent.putExtra(mDisabledFunctions.get(i), UsbManager.USB_FUNCTION_DISABLED);
}
}
@Override
public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_UPDATE:
- synchronized (this) {
+ synchronized (mLock) {
+ switch (msg.what) {
+ case MSG_UPDATE_STATE:
if (mConnected != mLastConnected || mConfiguration != mLastConfiguration) {
if (mConnected == 0 && mCurrentAccessory != null) {
// turn off accessory mode when we are disconnected
@@ -438,6 +481,14 @@ class UsbService extends IUsbManager.Stub {
UsbManager.USB_FUNCTION_ACCESSORY, false)) {
Log.d(TAG, "exited USB accessory mode");
+ // restore previously enabled functions
+ for (String function : mAccessoryRestoreFunctions) {
+ if (UsbManager.setFunctionEnabled(function, true)) {
+ Log.e(TAG, "could not reenable function " + function);
+ }
+ }
+ mAccessoryRestoreFunctions.clear();
+
Intent intent = new Intent(
UsbManager.ACTION_USB_ACCESSORY_DETACHED);
intent.putExtra(UsbManager.EXTRA_ACCESSORY, mCurrentAccessory);
@@ -468,17 +519,23 @@ class UsbService extends IUsbManager.Stub {
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.putExtra(UsbManager.USB_CONNECTED, mConnected != 0);
intent.putExtra(UsbManager.USB_CONFIGURATION, mConfiguration);
- addEnabledFunctions(intent);
+ addEnabledFunctionsLocked(intent);
mContext.sendStickyBroadcast(intent);
}
- }
- break;
+ break;
+ case MSG_FUNCTION_ENABLED:
+ case MSG_FUNCTION_DISABLED:
+ functionEnabledLocked((String)msg.obj, msg.what == MSG_FUNCTION_ENABLED);
+ break;
+ }
}
}
};
+ // host support
private native void monitorUsbHostBus();
private native ParcelFileDescriptor nativeOpenDevice(String deviceName);
+ // accessory support
private native String[] nativeGetAccessoryStrings();
private native ParcelFileDescriptor nativeOpenAccessory();
}
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 997e75039072..b1a6a9a5a42c 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -70,8 +70,6 @@ import com.android.internal.content.PackageMonitor;
import com.android.internal.service.wallpaper.ImageWallpaper;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
-import com.android.server.DevicePolicyManagerService.ActiveAdmin;
-import com.android.server.DevicePolicyManagerService.MyPackageMonitor;
class WallpaperManagerService extends IWallpaperManager.Stub {
static final String TAG = "WallpaperService";
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 5e78353d36d5..cc25e8d09996 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -42,14 +42,18 @@ import android.net.ConnectivityManager;
import android.net.DhcpInfo;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
+import android.net.NetworkInfo.DetailedState;
+import android.net.TrafficStats;
import android.os.Binder;
import android.os.Handler;
+import android.os.Messenger;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.INetworkManagementService;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemProperties;
import android.os.WorkSource;
import android.provider.Settings;
import android.text.TextUtils;
@@ -111,6 +115,20 @@ public class WifiService extends IWifiManager.Stub {
private final IBatteryStats mBatteryStats;
+ private boolean mEnableTrafficStatsPoll = false;
+ private int mTrafficStatsPollToken = 0;
+ private long mTxPkts;
+ private long mRxPkts;
+ /* Tracks last reported data activity */
+ private int mDataActivity;
+ private String mInterfaceName;
+
+ /**
+ * Interval in milliseconds between polling for traffic
+ * statistics
+ */
+ private static final int POLL_TRAFFIC_STATS_INTERVAL_MSECS = 1000;
+
/**
* See {@link Settings.Secure#WIFI_IDLE_MS}. This is the default value if a
* Settings.Secure value is not present. This timeout value is chosen as
@@ -123,6 +141,9 @@ public class WifiService extends IWifiManager.Stub {
private static final String ACTION_DEVICE_IDLE =
"com.android.server.WifiManager.action.DEVICE_IDLE";
+ private static final int CMD_ENABLE_TRAFFIC_STATS_POLL = 1;
+ private static final int CMD_TRAFFIC_STATS_POLL = 2;
+
private boolean mIsReceiverRegistered = false;
@@ -180,18 +201,20 @@ public class WifiService extends IWifiManager.Stub {
/**
* Asynchronous channel to WifiStateMachine
*/
- private AsyncChannel mChannel;
+ private AsyncChannel mWifiStateMachineChannel;
/**
- * TODO: Possibly change WifiService into an AsyncService.
+ * Clients receiving asynchronous messages
*/
- private class WifiServiceHandler extends Handler {
- private AsyncChannel mWshChannel;
+ private List<AsyncChannel> mClients = new ArrayList<AsyncChannel>();
- WifiServiceHandler(android.os.Looper looper, Context context) {
+ /**
+ * Handles client connections
+ */
+ private class AsyncServiceHandler extends Handler {
+
+ AsyncServiceHandler(android.os.Looper looper) {
super(looper);
- mWshChannel = new AsyncChannel();
- mWshChannel.connect(context, this, mWifiStateMachine.getHandler());
}
@Override
@@ -199,11 +222,33 @@ public class WifiService extends IWifiManager.Stub {
switch (msg.what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
- mChannel = mWshChannel;
+ Slog.d(TAG, "New client listening to asynchronous messages");
+ mClients.add((AsyncChannel) msg.obj);
} else {
- Slog.d(TAG, "WifiServicehandler.handleMessage could not connect error=" +
- msg.arg1);
- mChannel = null;
+ Slog.e(TAG, "Client connection failure, error=" + msg.arg1);
+ }
+ break;
+ }
+ case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
+ AsyncChannel ac = new AsyncChannel();
+ ac.connect(mContext, this, msg.replyTo);
+ break;
+ }
+ case CMD_ENABLE_TRAFFIC_STATS_POLL: {
+ mEnableTrafficStatsPoll = (msg.arg1 == 1);
+ mTrafficStatsPollToken++;
+ if (mEnableTrafficStatsPoll) {
+ notifyOnDataActivity();
+ sendMessageDelayed(Message.obtain(this, CMD_TRAFFIC_STATS_POLL,
+ mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS);
+ }
+ break;
+ }
+ case CMD_TRAFFIC_STATS_POLL: {
+ if (msg.arg1 == mTrafficStatsPollToken) {
+ notifyOnDataActivity();
+ sendMessageDelayed(Message.obtain(this, CMD_TRAFFIC_STATS_POLL,
+ mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS);
}
break;
}
@@ -214,7 +259,40 @@ public class WifiService extends IWifiManager.Stub {
}
}
}
- WifiServiceHandler mHandler;
+ private AsyncServiceHandler mAsyncServiceHandler;
+
+ /**
+ * Handles interaction with WifiStateMachine
+ */
+ private class WifiStateMachineHandler extends Handler {
+ private AsyncChannel mWsmChannel;
+
+ WifiStateMachineHandler(android.os.Looper looper) {
+ super(looper);
+ mWsmChannel = new AsyncChannel();
+ mWsmChannel.connect(mContext, this, mWifiStateMachine.getHandler());
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
+ if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
+ mWifiStateMachineChannel = mWsmChannel;
+ } else {
+ Slog.e(TAG, "WifiStateMachine connection failure, error=" + msg.arg1);
+ mWifiStateMachineChannel = null;
+ }
+ break;
+ }
+ default: {
+ Slog.d(TAG, "WifiStateMachineHandler.handleMessage ignoring msg=" + msg);
+ break;
+ }
+ }
+ }
+ }
+ WifiStateMachineHandler mWifiStateMachineHandler;
/**
* Temporary for computing UIDS that are responsible for starting WIFI.
@@ -224,7 +302,10 @@ public class WifiService extends IWifiManager.Stub {
WifiService(Context context) {
mContext = context;
- mWifiStateMachine = new WifiStateMachine(mContext);
+
+ mInterfaceName = SystemProperties.get("wifi.interface", "wlan0");
+
+ mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName);
mWifiStateMachine.enableRssiPolling(true);
mBatteryStats = BatteryStatsService.getService();
@@ -232,10 +313,6 @@ public class WifiService extends IWifiManager.Stub {
Intent idleIntent = new Intent(ACTION_DEVICE_IDLE, null);
mIdleIntent = PendingIntent.getBroadcast(mContext, IDLE_REQUEST, idleIntent, 0);
- HandlerThread wifiThread = new HandlerThread("WifiService");
- wifiThread.start();
- mHandler = new WifiServiceHandler(wifiThread.getLooper(), context);
-
mContext.registerReceiver(
new BroadcastReceiver() {
@Override
@@ -271,6 +348,7 @@ public class WifiService extends IWifiManager.Stub {
switch(mNetworkInfo.getDetailedState()) {
case CONNECTED:
case DISCONNECTED:
+ evaluateTrafficStatsPolling();
resetNotification();
break;
}
@@ -281,6 +359,11 @@ public class WifiService extends IWifiManager.Stub {
}
}, filter);
+ HandlerThread wifiThread = new HandlerThread("WifiService");
+ wifiThread.start();
+ mAsyncServiceHandler = new AsyncServiceHandler(wifiThread.getLooper());
+ mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper());
+
// Setting is in seconds
NOTIFICATION_REPEAT_DELAY_MS = Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, 900) * 1000l;
@@ -337,10 +420,10 @@ public class WifiService extends IWifiManager.Stub {
*/
public boolean pingSupplicant() {
enforceAccessPermission();
- if (mChannel != null) {
- return mWifiStateMachine.syncPingSupplicant(mChannel);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.syncPingSupplicant(mWifiStateMachineChannel);
} else {
- Slog.e(TAG, "mChannel is not initialized");
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
return false;
}
}
@@ -501,15 +584,12 @@ public class WifiService extends IWifiManager.Stub {
public synchronized void setWifiApConfiguration(WifiConfiguration wifiConfig) {
enforceChangePermission();
final ContentResolver cr = mContext.getContentResolver();
- boolean isWpa;
if (wifiConfig == null)
return;
+ int authType = wifiConfig.getAuthType();
Settings.Secure.putString(cr, Settings.Secure.WIFI_AP_SSID, wifiConfig.SSID);
- isWpa = wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK);
- Settings.Secure.putInt(cr,
- Settings.Secure.WIFI_AP_SECURITY,
- isWpa ? KeyMgmt.WPA_PSK : KeyMgmt.NONE);
- if (isWpa)
+ Settings.Secure.putInt(cr, Settings.Secure.WIFI_AP_SECURITY, authType);
+ if (authType != KeyMgmt.NONE)
Settings.Secure.putString(cr, Settings.Secure.WIFI_AP_PASSWD, wifiConfig.preSharedKey);
}
@@ -553,10 +633,10 @@ public class WifiService extends IWifiManager.Stub {
*/
public int addOrUpdateNetwork(WifiConfiguration config) {
enforceChangePermission();
- if (mChannel != null) {
- return mWifiStateMachine.syncAddOrUpdateNetwork(mChannel, config);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.syncAddOrUpdateNetwork(mWifiStateMachineChannel, config);
} else {
- Slog.e(TAG, "mChannel is not initialized");
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
return -1;
}
}
@@ -569,10 +649,10 @@ public class WifiService extends IWifiManager.Stub {
*/
public boolean removeNetwork(int netId) {
enforceChangePermission();
- if (mChannel != null) {
- return mWifiStateMachine.syncRemoveNetwork(mChannel, netId);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.syncRemoveNetwork(mWifiStateMachineChannel, netId);
} else {
- Slog.e(TAG, "mChannel is not initialized");
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
return false;
}
}
@@ -586,10 +666,11 @@ public class WifiService extends IWifiManager.Stub {
*/
public boolean enableNetwork(int netId, boolean disableOthers) {
enforceChangePermission();
- if (mChannel != null) {
- return mWifiStateMachine.syncEnableNetwork(mChannel, netId, disableOthers);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.syncEnableNetwork(mWifiStateMachineChannel, netId,
+ disableOthers);
} else {
- Slog.e(TAG, "mChannel is not initialized");
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
return false;
}
}
@@ -602,10 +683,10 @@ public class WifiService extends IWifiManager.Stub {
*/
public boolean disableNetwork(int netId) {
enforceChangePermission();
- if (mChannel != null) {
- return mWifiStateMachine.syncDisableNetwork(mChannel, netId);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.syncDisableNetwork(mWifiStateMachineChannel, netId);
} else {
- Slog.e(TAG, "mChannel is not initialized");
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
return false;
}
}
@@ -642,10 +723,10 @@ public class WifiService extends IWifiManager.Stub {
public boolean saveConfiguration() {
boolean result = true;
enforceChangePermission();
- if (mChannel != null) {
- return mWifiStateMachine.syncSaveConfig(mChannel);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.syncSaveConfig(mWifiStateMachineChannel);
} else {
- Slog.e(TAG, "mChannel is not initialized");
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
return false;
}
}
@@ -779,14 +860,23 @@ public class WifiService extends IWifiManager.Stub {
public WpsResult startWps(WpsConfiguration config) {
enforceChangePermission();
- if (mChannel != null) {
- return mWifiStateMachine.startWps(mChannel, config);
+ if (mWifiStateMachineChannel != null) {
+ return mWifiStateMachine.startWps(mWifiStateMachineChannel, config);
} else {
- Slog.e(TAG, "mChannel is not initialized");
+ Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
return new WpsResult(WpsResult.Status.FAILURE);
}
}
+ /**
+ * Get a reference to handler. This is used by a client to establish
+ * an AsyncChannel communication with WifiService
+ */
+ public Messenger getMessenger() {
+ enforceAccessPermission();
+ return new Messenger(mAsyncServiceHandler);
+ }
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -808,6 +898,7 @@ public class WifiService extends IWifiManager.Stub {
// Once the screen is on, we are not keeping WIFI running
// because of any locks so clear that tracking immediately.
reportStartWorkSource();
+ evaluateTrafficStatsPolling();
mWifiStateMachine.enableRssiPolling(true);
mWifiStateMachine.enableAllNetworks();
updateWifiState();
@@ -816,6 +907,7 @@ public class WifiService extends IWifiManager.Stub {
Slog.d(TAG, "ACTION_SCREEN_OFF");
}
mScreenOff = true;
+ evaluateTrafficStatsPolling();
mWifiStateMachine.enableRssiPolling(false);
/*
* Set a timer to put Wi-Fi to sleep, but only if the screen is off
@@ -1419,6 +1511,48 @@ public class WifiService extends IWifiManager.Stub {
}
}
+ /**
+ * Evaluate if traffic stats polling is needed based on
+ * connection and screen on status
+ */
+ private void evaluateTrafficStatsPolling() {
+ Message msg;
+ if (mNetworkInfo.getDetailedState() == DetailedState.CONNECTED && !mScreenOff) {
+ msg = Message.obtain(mAsyncServiceHandler, CMD_ENABLE_TRAFFIC_STATS_POLL, 1, 0);
+ } else {
+ msg = Message.obtain(mAsyncServiceHandler, CMD_ENABLE_TRAFFIC_STATS_POLL, 0, 0);
+ }
+ msg.sendToTarget();
+ }
+
+ private void notifyOnDataActivity() {
+ long sent, received;
+ long preTxPkts = mTxPkts, preRxPkts = mRxPkts;
+ int dataActivity = WifiManager.DATA_ACTIVITY_NONE;
+
+ mTxPkts = TrafficStats.getTxPackets(mInterfaceName);
+ mRxPkts = TrafficStats.getRxPackets(mInterfaceName);
+
+ if (preTxPkts > 0 || preRxPkts > 0) {
+ sent = mTxPkts - preTxPkts;
+ received = mRxPkts - preRxPkts;
+ if (sent > 0) {
+ dataActivity |= WifiManager.DATA_ACTIVITY_OUT;
+ }
+ if (received > 0) {
+ dataActivity |= WifiManager.DATA_ACTIVITY_IN;
+ }
+
+ if (dataActivity != mDataActivity && !mScreenOff) {
+ mDataActivity = dataActivity;
+ for (AsyncChannel client : mClients) {
+ client.sendMessage(WifiManager.DATA_ACTIVITY_NOTIFICATION, mDataActivity);
+ }
+ }
+ }
+ }
+
+
private void checkAndSetNotification() {
// If we shouldn't place a notification on available networks, then
// don't bother doing any of the following
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 9e3b9c6dd62a..399c19ae7f57 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -24,8 +24,8 @@ import com.android.server.ProcessMap;
import com.android.server.ProcessStats;
import com.android.server.SystemServer;
import com.android.server.Watchdog;
-import com.android.server.WindowManagerService;
import com.android.server.am.ActivityStack.ActivityState;
+import com.android.server.wm.WindowManagerService;
import dalvik.system.Zygote;
@@ -4969,11 +4969,6 @@ public final class ActivityManagerService extends ActivityManagerNative
enforceCallingPermission(android.Manifest.permission.GET_TASKS,
"getRecentTasks()");
- final boolean canReadFb = (flags&ActivityManager.TASKS_GET_THUMBNAILS) != 0
- && checkCallingPermission(
- android.Manifest.permission.READ_FRAME_BUFFER)
- == PackageManager.PERMISSION_GRANTED;
-
IPackageManager pm = AppGlobals.getPackageManager();
ActivityRecord resumed = mMainStack.mResumedActivity;
@@ -4991,17 +4986,10 @@ public final class ActivityManagerService extends ActivityManagerNative
ActivityManager.RecentTaskInfo rti
= new ActivityManager.RecentTaskInfo();
rti.id = tr.numActivities > 0 ? tr.taskId : -1;
+ rti.persistentId = tr.taskId;
rti.baseIntent = new Intent(
tr.intent != null ? tr.intent : tr.affinityIntent);
rti.origActivity = tr.origActivity;
-
- if (canReadFb) {
- if (resumed != null && resumed.task == tr) {
- rti.thumbnail = resumed.stack.screenshotActivities(resumed);
- } else {
- rti.thumbnail = tr.lastThumbnail;
- }
- }
rti.description = tr.lastDescription;
if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
@@ -5030,6 +5018,26 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ public Bitmap getTaskThumbnail(int id) {
+ synchronized (this) {
+ enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
+ "getTaskThumbnail()");
+ ActivityRecord resumed = mMainStack.mResumedActivity;
+ final int N = mRecentTasks.size();
+ for (int i=0; i<N; i++) {
+ TaskRecord tr = mRecentTasks.get(i);
+ if (tr.taskId == id) {
+ if (resumed != null && resumed.task == tr) {
+ return resumed.stack.screenshotActivities(resumed);
+ } else {
+ return tr.lastThumbnail;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
int j;
TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
@@ -5085,6 +5093,9 @@ public final class ActivityManagerService extends ActivityManagerNative
for (int i=0; i<N; i++) {
TaskRecord tr = mRecentTasks.get(i);
if (tr.taskId == task) {
+ if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
+ mMainStack.mUserLeaving = true;
+ }
if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
// Caller wants the home activity moved with it. To accomplish this,
// we'll just move the home task to the top first.
@@ -5097,6 +5108,9 @@ public final class ActivityManagerService extends ActivityManagerNative
for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
if (hr.task.taskId == task) {
+ if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
+ mMainStack.mUserLeaving = true;
+ }
if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
// Caller wants the home activity moved with it. To accomplish this,
// we'll just move the home task to the top first.
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
new file mode 100644
index 000000000000..d3d9df4359d5
--- /dev/null
+++ b/services/java/com/android/server/wm/AppWindowToken.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 com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+
+import com.android.server.wm.WindowManagerService.H;
+
+import android.content.pm.ActivityInfo;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Slog;
+import android.view.IApplicationToken;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Version of WindowToken that is specifically for a particular application (or
+ * really activity) that is displaying windows.
+ */
+class AppWindowToken extends WindowToken {
+ // Non-null only for application tokens.
+ final IApplicationToken appToken;
+
+ // All of the windows and child windows that are included in this
+ // application token. Note this list is NOT sorted!
+ final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
+
+ int groupId = -1;
+ boolean appFullscreen;
+ int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+
+ // The input dispatching timeout for this application token in nanoseconds.
+ long inputDispatchingTimeoutNanos;
+
+ // These are used for determining when all windows associated with
+ // an activity have been drawn, so they can be made visible together
+ // at the same time.
+ int lastTransactionSequence;
+ int numInterestingWindows;
+ int numDrawnWindows;
+ boolean inPendingTransaction;
+ boolean allDrawn;
+
+ // Is this token going to be hidden in a little while? If so, it
+ // won't be taken into account for setting the screen orientation.
+ boolean willBeHidden;
+
+ // Is this window's surface needed? This is almost like hidden, except
+ // it will sometimes be true a little earlier: when the token has
+ // been shown, but is still waiting for its app transition to execute
+ // before making its windows shown.
+ boolean hiddenRequested;
+
+ // Have we told the window clients to hide themselves?
+ boolean clientHidden;
+
+ // Last visibility state we reported to the app token.
+ boolean reportedVisible;
+
+ // Set to true when the token has been removed from the window mgr.
+ boolean removed;
+
+ // Have we been asked to have this token keep the screen frozen?
+ boolean freezingScreen;
+
+ boolean animating;
+ Animation animation;
+ boolean hasTransformation;
+ final Transformation transformation = new Transformation();
+
+ // Offset to the window of all layers in the token, for use by
+ // AppWindowToken animations.
+ int animLayerAdjustment;
+
+ // Information about an application starting window if displayed.
+ StartingData startingData;
+ WindowState startingWindow;
+ View startingView;
+ boolean startingDisplayed;
+ boolean startingMoved;
+ boolean firstWindowDrawn;
+
+ // Input application handle used by the input dispatcher.
+ InputApplicationHandle mInputApplicationHandle;
+
+ AppWindowToken(WindowManagerService _service, IApplicationToken _token) {
+ super(_service, _token.asBinder(),
+ WindowManager.LayoutParams.TYPE_APPLICATION, true);
+ appWindowToken = this;
+ appToken = _token;
+ mInputApplicationHandle = new InputApplicationHandle(this);
+ lastTransactionSequence = service.mTransactionSequence-1;
+ }
+
+ public void setAnimation(Animation anim) {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Setting animation in " + this + ": " + anim);
+ animation = anim;
+ animating = false;
+ anim.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
+ anim.scaleCurrentDuration(service.mTransitionAnimationScale);
+ int zorder = anim.getZAdjustment();
+ int adj = 0;
+ if (zorder == Animation.ZORDER_TOP) {
+ adj = WindowManagerService.TYPE_LAYER_OFFSET;
+ } else if (zorder == Animation.ZORDER_BOTTOM) {
+ adj = -WindowManagerService.TYPE_LAYER_OFFSET;
+ }
+
+ if (animLayerAdjustment != adj) {
+ animLayerAdjustment = adj;
+ updateLayers();
+ }
+ }
+
+ public void setDummyAnimation() {
+ if (animation == null) {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Setting dummy animation in " + this);
+ animation = WindowManagerService.sDummyAnimation;
+ }
+ }
+
+ public void clearAnimation() {
+ if (animation != null) {
+ animation = null;
+ animating = true;
+ }
+ }
+
+ void updateLayers() {
+ final int N = allAppWindows.size();
+ final int adj = animLayerAdjustment;
+ for (int i=0; i<N; i++) {
+ WindowState w = allAppWindows.get(i);
+ w.mAnimLayer = w.mLayer + adj;
+ if (WindowManagerService.DEBUG_LAYERS) Slog.v(WindowManagerService.TAG, "Updating layer " + w + ": "
+ + w.mAnimLayer);
+ if (w == service.mInputMethodTarget && !service.mInputMethodTargetWaitingAnim) {
+ service.setInputMethodAnimLayerAdjustment(adj);
+ }
+ if (w == service.mWallpaperTarget && service.mLowerWallpaperTarget == null) {
+ service.setWallpaperAnimLayerAdjustmentLocked(adj);
+ }
+ }
+ }
+
+ void sendAppVisibilityToClients() {
+ final int N = allAppWindows.size();
+ for (int i=0; i<N; i++) {
+ WindowState win = allAppWindows.get(i);
+ if (win == startingWindow && clientHidden) {
+ // Don't hide the starting window.
+ continue;
+ }
+ try {
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG,
+ "Setting visibility of " + win + ": " + (!clientHidden));
+ win.mClient.dispatchAppVisibility(!clientHidden);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ void showAllWindowsLocked() {
+ final int NW = allAppWindows.size();
+ for (int i=0; i<NW; i++) {
+ WindowState w = allAppWindows.get(i);
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG,
+ "performing show on: " + w);
+ w.performShowLocked();
+ }
+ }
+
+ // This must be called while inside a transaction.
+ boolean stepAnimationLocked(long currentTime, int dw, int dh) {
+ if (!service.mDisplayFrozen && service.mPolicy.isScreenOn()) {
+ // We will run animations as long as the display isn't frozen.
+
+ if (animation == WindowManagerService.sDummyAnimation) {
+ // This guy is going to animate, but not yet. For now count
+ // it as not animating for purposes of scheduling transactions;
+ // when it is really time to animate, this will be set to
+ // a real animation and the next call will execute normally.
+ return false;
+ }
+
+ if ((allDrawn || animating || startingDisplayed) && animation != null) {
+ if (!animating) {
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Starting animation in " + this +
+ " @ " + currentTime + ": dw=" + dw + " dh=" + dh
+ + " scale=" + service.mTransitionAnimationScale
+ + " allDrawn=" + allDrawn + " animating=" + animating);
+ animation.initialize(dw, dh, dw, dh);
+ animation.setStartTime(currentTime);
+ animating = true;
+ }
+ transformation.clear();
+ final boolean more = animation.getTransformation(
+ currentTime, transformation);
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Stepped animation in " + this +
+ ": more=" + more + ", xform=" + transformation);
+ if (more) {
+ // we're done!
+ hasTransformation = true;
+ return true;
+ }
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Finished animation in " + this +
+ " @ " + currentTime);
+ animation = null;
+ }
+ } else if (animation != null) {
+ // If the display is frozen, and there is a pending animation,
+ // clear it and make sure we run the cleanup code.
+ animating = true;
+ animation = null;
+ }
+
+ hasTransformation = false;
+
+ if (!animating) {
+ return false;
+ }
+
+ clearAnimation();
+ animating = false;
+ if (animLayerAdjustment != 0) {
+ animLayerAdjustment = 0;
+ updateLayers();
+ }
+ if (service.mInputMethodTarget != null && service.mInputMethodTarget.mAppToken == this) {
+ service.moveInputMethodWindowsIfNeededLocked(true);
+ }
+
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Animation done in " + this
+ + ": reportedVisible=" + reportedVisible);
+
+ transformation.clear();
+
+ final int N = windows.size();
+ for (int i=0; i<N; i++) {
+ windows.get(i).finishExit();
+ }
+ updateReportedVisibilityLocked();
+
+ return false;
+ }
+
+ void updateReportedVisibilityLocked() {
+ if (appToken == null) {
+ return;
+ }
+
+ int numInteresting = 0;
+ int numVisible = 0;
+ boolean nowGone = true;
+
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Update reported visibility: " + this);
+ final int N = allAppWindows.size();
+ for (int i=0; i<N; i++) {
+ WindowState win = allAppWindows.get(i);
+ if (win == startingWindow || win.mAppFreezing
+ || win.mViewVisibility != View.VISIBLE
+ || win.mAttrs.type == TYPE_APPLICATION_STARTING
+ || win.mDestroying) {
+ continue;
+ }
+ if (WindowManagerService.DEBUG_VISIBILITY) {
+ Slog.v(WindowManagerService.TAG, "Win " + win + ": isDrawn="
+ + win.isDrawnLw()
+ + ", isAnimating=" + win.isAnimating());
+ if (!win.isDrawnLw()) {
+ Slog.v(WindowManagerService.TAG, "Not displayed: s=" + win.mSurface
+ + " pv=" + win.mPolicyVisibility
+ + " dp=" + win.mDrawPending
+ + " cdp=" + win.mCommitDrawPending
+ + " ah=" + win.mAttachedHidden
+ + " th="
+ + (win.mAppToken != null
+ ? win.mAppToken.hiddenRequested : false)
+ + " a=" + win.mAnimating);
+ }
+ }
+ numInteresting++;
+ if (win.isDrawnLw()) {
+ if (!win.isAnimating()) {
+ numVisible++;
+ }
+ nowGone = false;
+ } else if (win.isAnimating()) {
+ nowGone = false;
+ }
+ }
+
+ boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "VIS " + this + ": interesting="
+ + numInteresting + " visible=" + numVisible);
+ if (nowVisible != reportedVisible) {
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(
+ WindowManagerService.TAG, "Visibility changed in " + this
+ + ": vis=" + nowVisible);
+ reportedVisible = nowVisible;
+ Message m = service.mH.obtainMessage(
+ H.REPORT_APPLICATION_TOKEN_WINDOWS,
+ nowVisible ? 1 : 0,
+ nowGone ? 1 : 0,
+ this);
+ service.mH.sendMessage(m);
+ }
+ }
+
+ WindowState findMainWindow() {
+ int j = windows.size();
+ while (j > 0) {
+ j--;
+ WindowState win = windows.get(j);
+ if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
+ || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
+ return win;
+ }
+ }
+ return null;
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ super.dump(pw, prefix);
+ if (appToken != null) {
+ pw.print(prefix); pw.println("app=true");
+ }
+ if (allAppWindows.size() > 0) {
+ pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
+ }
+ pw.print(prefix); pw.print("groupId="); pw.print(groupId);
+ pw.print(" appFullscreen="); pw.print(appFullscreen);
+ pw.print(" requestedOrientation="); pw.println(requestedOrientation);
+ pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
+ pw.print(" clientHidden="); pw.print(clientHidden);
+ pw.print(" willBeHidden="); pw.print(willBeHidden);
+ pw.print(" reportedVisible="); pw.println(reportedVisible);
+ if (paused || freezingScreen) {
+ pw.print(prefix); pw.print("paused="); pw.print(paused);
+ pw.print(" freezingScreen="); pw.println(freezingScreen);
+ }
+ if (numInterestingWindows != 0 || numDrawnWindows != 0
+ || inPendingTransaction || allDrawn) {
+ pw.print(prefix); pw.print("numInterestingWindows=");
+ pw.print(numInterestingWindows);
+ pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
+ pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
+ pw.print(" allDrawn="); pw.println(allDrawn);
+ }
+ if (animating || animation != null) {
+ pw.print(prefix); pw.print("animating="); pw.print(animating);
+ pw.print(" animation="); pw.println(animation);
+ }
+ if (hasTransformation) {
+ pw.print(prefix); pw.print("XForm: ");
+ transformation.printShortString(pw);
+ pw.println();
+ }
+ if (animLayerAdjustment != 0) {
+ pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
+ }
+ if (startingData != null || removed || firstWindowDrawn) {
+ pw.print(prefix); pw.print("startingData="); pw.print(startingData);
+ pw.print(" removed="); pw.print(removed);
+ pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
+ }
+ if (startingWindow != null || startingView != null
+ || startingDisplayed || startingMoved) {
+ pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
+ pw.print(" startingView="); pw.print(startingView);
+ pw.print(" startingDisplayed="); pw.print(startingDisplayed);
+ pw.print(" startingMoved"); pw.println(startingMoved);
+ }
+ }
+
+ @Override
+ public String toString() {
+ if (stringName == null) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("AppWindowToken{");
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(" token="); sb.append(token); sb.append('}');
+ stringName = sb.toString();
+ }
+ return stringName;
+ }
+} \ No newline at end of file
diff --git a/services/java/com/android/server/wm/DimAnimator.java b/services/java/com/android/server/wm/DimAnimator.java
new file mode 100644
index 000000000000..1fcb8697174a
--- /dev/null
+++ b/services/java/com/android/server/wm/DimAnimator.java
@@ -0,0 +1,187 @@
+/*
+ * 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.wm;
+
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.util.Slog;
+import android.util.TypedValue;
+import android.view.Surface;
+import android.view.SurfaceSession;
+
+import java.io.PrintWriter;
+
+/**
+ * DimAnimator class that controls the dim animation. This holds the surface and
+ * all state used for dim animation.
+ */
+class DimAnimator {
+ Surface mDimSurface;
+ boolean mDimShown = false;
+ float mDimCurrentAlpha;
+ float mDimTargetAlpha;
+ float mDimDeltaPerMs;
+ long mLastDimAnimTime;
+
+ int mLastDimWidth, mLastDimHeight;
+
+ DimAnimator (SurfaceSession session) {
+ if (mDimSurface == null) {
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM "
+ + mDimSurface + ": CREATE");
+ try {
+ mDimSurface = new Surface(session, 0,
+ "DimSurface",
+ -1, 16, 16, PixelFormat.OPAQUE,
+ Surface.FX_SURFACE_DIM);
+ mDimSurface.setAlpha(0.0f);
+ } catch (Exception e) {
+ Slog.e(WindowManagerService.TAG, "Exception creating Dim surface", e);
+ }
+ }
+ }
+
+ /**
+ * Show the dim surface.
+ */
+ void show(int dw, int dh) {
+ if (!mDimShown) {
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
+ dw + "x" + dh + ")");
+ mDimShown = true;
+ try {
+ mLastDimWidth = dw;
+ mLastDimHeight = dh;
+ mDimSurface.setPosition(0, 0);
+ mDimSurface.setSize(dw, dh);
+ mDimSurface.show();
+ } catch (RuntimeException e) {
+ Slog.w(WindowManagerService.TAG, "Failure showing dim surface", e);
+ }
+ } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
+ mLastDimWidth = dw;
+ mLastDimHeight = dh;
+ mDimSurface.setSize(dw, dh);
+ }
+ }
+
+ /**
+ * Set's the dim surface's layer and update dim parameters that will be used in
+ * {@link updateSurface} after all windows are examined.
+ */
+ void updateParameters(Resources res, WindowState w, long currentTime) {
+ mDimSurface.setLayer(w.mAnimLayer-1);
+
+ final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface
+ + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
+ if (mDimTargetAlpha != target) {
+ // If the desired dim level has changed, then
+ // start an animation to it.
+ mLastDimAnimTime = currentTime;
+ long duration = (w.mAnimating && w.mAnimation != null)
+ ? w.mAnimation.computeDurationHint()
+ : WindowManagerService.DEFAULT_DIM_DURATION;
+ if (target > mDimTargetAlpha) {
+ TypedValue tv = new TypedValue();
+ res.getValue(com.android.internal.R.fraction.config_dimBehindFadeDuration,
+ tv, true);
+ if (tv.type == TypedValue.TYPE_FRACTION) {
+ duration = (long)tv.getFraction((float)duration, (float)duration);
+ } else if (tv.type >= TypedValue.TYPE_FIRST_INT
+ && tv.type <= TypedValue.TYPE_LAST_INT) {
+ duration = tv.data;
+ }
+ }
+ if (duration < 1) {
+ // Don't divide by zero
+ duration = 1;
+ }
+ mDimTargetAlpha = target;
+ mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
+ }
+ }
+
+ /**
+ * Updating the surface's alpha. Returns true if the animation continues, or returns
+ * false when the animation is finished and the dim surface is hidden.
+ */
+ boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
+ if (!dimming) {
+ if (mDimTargetAlpha != 0) {
+ mLastDimAnimTime = currentTime;
+ mDimTargetAlpha = 0;
+ mDimDeltaPerMs = (-mDimCurrentAlpha) / WindowManagerService.DEFAULT_DIM_DURATION;
+ }
+ }
+
+ boolean animating = false;
+ if (mLastDimAnimTime != 0) {
+ mDimCurrentAlpha += mDimDeltaPerMs
+ * (currentTime-mLastDimAnimTime);
+ boolean more = true;
+ if (displayFrozen) {
+ // If the display is frozen, there is no reason to animate.
+ more = false;
+ } else if (mDimDeltaPerMs > 0) {
+ if (mDimCurrentAlpha > mDimTargetAlpha) {
+ more = false;
+ }
+ } else if (mDimDeltaPerMs < 0) {
+ if (mDimCurrentAlpha < mDimTargetAlpha) {
+ more = false;
+ }
+ } else {
+ more = false;
+ }
+
+ // Do we need to continue animating?
+ if (more) {
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM "
+ + mDimSurface + ": alpha=" + mDimCurrentAlpha);
+ mLastDimAnimTime = currentTime;
+ mDimSurface.setAlpha(mDimCurrentAlpha);
+ animating = true;
+ } else {
+ mDimCurrentAlpha = mDimTargetAlpha;
+ mLastDimAnimTime = 0;
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM "
+ + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
+ mDimSurface.setAlpha(mDimCurrentAlpha);
+ if (!dimming) {
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface
+ + ": HIDE");
+ try {
+ mDimSurface.hide();
+ } catch (RuntimeException e) {
+ Slog.w(WindowManagerService.TAG, "Illegal argument exception hiding dim surface");
+ }
+ mDimShown = false;
+ }
+ }
+ }
+ return animating;
+ }
+
+ public void printTo(PrintWriter pw) {
+ pw.print(" mDimShown="); pw.print(mDimShown);
+ pw.print(" current="); pw.print(mDimCurrentAlpha);
+ pw.print(" target="); pw.print(mDimTargetAlpha);
+ pw.print(" delta="); pw.print(mDimDeltaPerMs);
+ pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
+ }
+} \ No newline at end of file
diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java
new file mode 100644
index 000000000000..c8f8ff3ca03e
--- /dev/null
+++ b/services/java/com/android/server/wm/DragState.java
@@ -0,0 +1,368 @@
+/*
+ * 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.wm;
+
+import com.android.server.wm.WindowManagerService.H;
+
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.graphics.Region;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Slog;
+import android.view.DragEvent;
+import android.view.InputChannel;
+import android.view.InputQueue;
+import android.view.Surface;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManagerPolicy;
+
+import java.util.ArrayList;
+
+/**
+ * Drag/drop state
+ */
+class DragState {
+ final WindowManagerService mService;
+ IBinder mToken;
+ Surface mSurface;
+ int mFlags;
+ IBinder mLocalWin;
+ ClipData mData;
+ ClipDescription mDataDescription;
+ boolean mDragResult;
+ float mCurrentX, mCurrentY;
+ float mThumbOffsetX, mThumbOffsetY;
+ InputChannel mServerChannel, mClientChannel;
+ WindowState mTargetWindow;
+ ArrayList<WindowState> mNotifiedWindows;
+ boolean mDragInProgress;
+
+ private final Region mTmpRegion = new Region();
+
+ DragState(WindowManagerService service, IBinder token, Surface surface,
+ int flags, IBinder localWin) {
+ mService = service;
+ mToken = token;
+ mSurface = surface;
+ mFlags = flags;
+ mLocalWin = localWin;
+ mNotifiedWindows = new ArrayList<WindowState>();
+ }
+
+ void reset() {
+ if (mSurface != null) {
+ mSurface.destroy();
+ }
+ mSurface = null;
+ mFlags = 0;
+ mLocalWin = null;
+ mToken = null;
+ mData = null;
+ mThumbOffsetX = mThumbOffsetY = 0;
+ mNotifiedWindows = null;
+ }
+
+ void register() {
+ if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "registering drag input channel");
+ if (mClientChannel != null) {
+ Slog.e(WindowManagerService.TAG, "Duplicate register of drag input channel");
+ } else {
+ InputChannel[] channels = InputChannel.openInputChannelPair("drag");
+ mServerChannel = channels[0];
+ mClientChannel = channels[1];
+ mService.mInputManager.registerInputChannel(mServerChannel, null);
+ InputQueue.registerInputChannel(mClientChannel, mService.mDragInputHandler,
+ mService.mH.getLooper().getQueue());
+ }
+ }
+
+ void unregister() {
+ if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "unregistering drag input channel");
+ if (mClientChannel == null) {
+ Slog.e(WindowManagerService.TAG, "Unregister of nonexistent drag input channel");
+ } else {
+ mService.mInputManager.unregisterInputChannel(mServerChannel);
+ InputQueue.unregisterInputChannel(mClientChannel);
+ mClientChannel.dispose();
+ mServerChannel.dispose();
+ mClientChannel = null;
+ mServerChannel = null;
+ }
+ }
+
+ int getDragLayerLw() {
+ return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG)
+ * WindowManagerService.TYPE_LAYER_MULTIPLIER
+ + WindowManagerService.TYPE_LAYER_OFFSET;
+ }
+
+ /* call out to each visible window/session informing it about the drag
+ */
+ void broadcastDragStartedLw(final float touchX, final float touchY) {
+ // Cache a base-class instance of the clip metadata so that parceling
+ // works correctly in calling out to the apps.
+ mDataDescription = (mData != null) ? mData.getDescription() : null;
+ mNotifiedWindows.clear();
+ mDragInProgress = true;
+
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
+ }
+
+ final int N = mService.mWindows.size();
+ for (int i = 0; i < N; i++) {
+ sendDragStartedLw(mService.mWindows.get(i), touchX, touchY, mDataDescription);
+ }
+ }
+
+ /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
+ * designated window is potentially a drop recipient. There are race situations
+ * around DRAG_ENDED broadcast, so we make sure that once we've declared that
+ * the drag has ended, we never send out another DRAG_STARTED for this drag action.
+ *
+ * This method clones the 'event' parameter if it's being delivered to the same
+ * process, so it's safe for the caller to call recycle() on the event afterwards.
+ */
+ private void sendDragStartedLw(WindowState newWin, float touchX, float touchY,
+ ClipDescription desc) {
+ // Don't actually send the event if the drag is supposed to be pinned
+ // to the originating window but 'newWin' is not that window.
+ if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
+ final IBinder winBinder = newWin.mClient.asBinder();
+ if (winBinder != mLocalWin) {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "Not dispatching local DRAG_STARTED to " + newWin);
+ }
+ return;
+ }
+ }
+
+ if (mDragInProgress && newWin.isPotentialDragTarget()) {
+ DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED,
+ touchX - newWin.mFrame.left, touchY - newWin.mFrame.top,
+ null, desc, null, false);
+ try {
+ newWin.mClient.dispatchDragEvent(event);
+ // track each window that we've notified that the drag is starting
+ mNotifiedWindows.add(newWin);
+ } catch (RemoteException e) {
+ Slog.w(WindowManagerService.TAG, "Unable to drag-start window " + newWin);
+ } finally {
+ // if the callee was local, the dispatch has already recycled the event
+ if (Process.myPid() != newWin.mSession.mPid) {
+ event.recycle();
+ }
+ }
+ }
+ }
+
+ /* helper - construct and send a DRAG_STARTED event only if the window has not
+ * previously been notified, i.e. it became visible after the drag operation
+ * was begun. This is a rare case.
+ */
+ void sendDragStartedIfNeededLw(WindowState newWin) {
+ if (mDragInProgress) {
+ // If we have sent the drag-started, we needn't do so again
+ for (WindowState ws : mNotifiedWindows) {
+ if (ws == newWin) {
+ return;
+ }
+ }
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "need to send DRAG_STARTED to new window " + newWin);
+ }
+ sendDragStartedLw(newWin, mCurrentX, mCurrentY, mDataDescription);
+ }
+ }
+
+ void broadcastDragEndedLw() {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "broadcasting DRAG_ENDED");
+ }
+ DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
+ 0, 0, null, null, null, mDragResult);
+ for (WindowState ws: mNotifiedWindows) {
+ try {
+ ws.mClient.dispatchDragEvent(evt);
+ } catch (RemoteException e) {
+ Slog.w(WindowManagerService.TAG, "Unable to drag-end window " + ws);
+ }
+ }
+ mNotifiedWindows.clear();
+ mDragInProgress = false;
+ evt.recycle();
+ }
+
+ void endDragLw() {
+ mService.mDragState.broadcastDragEndedLw();
+
+ // stop intercepting input
+ mService.mDragState.unregister();
+ mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
+
+ // free our resources and drop all the object references
+ mService.mDragState.reset();
+ mService.mDragState = null;
+
+ if (WindowManagerService.DEBUG_ORIENTATION) Slog.d(WindowManagerService.TAG, "Performing post-drag rotation");
+ boolean changed = mService.setRotationUncheckedLocked(
+ WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
+ if (changed) {
+ mService.mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
+ }
+ }
+
+ void notifyMoveLw(float x, float y) {
+ final int myPid = Process.myPid();
+
+ // Move the surface to the given touch
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION notifyMoveLw");
+ Surface.openTransaction();
+ try {
+ mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DRAG "
+ + mSurface + ": pos=(" +
+ (int)(x - mThumbOffsetX) + "," + (int)(y - mThumbOffsetY) + ")");
+ } finally {
+ Surface.closeTransaction();
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION notifyMoveLw");
+ }
+
+ // Tell the affected window
+ WindowState touchedWin = getTouchedWinAtPointLw(x, y);
+ if (touchedWin == null) {
+ if (WindowManagerService.DEBUG_DRAG) Slog.d(WindowManagerService.TAG, "No touched win at x=" + x + " y=" + y);
+ return;
+ }
+ if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
+ final IBinder touchedBinder = touchedWin.mClient.asBinder();
+ if (touchedBinder != mLocalWin) {
+ // This drag is pinned only to the originating window, but the drag
+ // point is outside that window. Pretend it's over empty space.
+ touchedWin = null;
+ }
+ }
+ try {
+ // have we dragged over a new window?
+ if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "sending DRAG_EXITED to " + mTargetWindow);
+ }
+ // force DRAG_EXITED_EVENT if appropriate
+ DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
+ x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top,
+ null, null, null, false);
+ mTargetWindow.mClient.dispatchDragEvent(evt);
+ if (myPid != mTargetWindow.mSession.mPid) {
+ evt.recycle();
+ }
+ }
+ if (touchedWin != null) {
+ if (false && WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "sending DRAG_LOCATION to " + touchedWin);
+ }
+ DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
+ x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
+ null, null, null, false);
+ touchedWin.mClient.dispatchDragEvent(evt);
+ if (myPid != touchedWin.mSession.mPid) {
+ evt.recycle();
+ }
+ }
+ } catch (RemoteException e) {
+ Slog.w(WindowManagerService.TAG, "can't send drag notification to windows");
+ }
+ mTargetWindow = touchedWin;
+ }
+
+ // Tell the drop target about the data. Returns 'true' if we can immediately
+ // dispatch the global drag-ended message, 'false' if we need to wait for a
+ // result from the recipient.
+ boolean notifyDropLw(float x, float y) {
+ WindowState touchedWin = getTouchedWinAtPointLw(x, y);
+ if (touchedWin == null) {
+ // "drop" outside a valid window -- no recipient to apply a
+ // timeout to, and we can send the drag-ended message immediately.
+ mDragResult = false;
+ return true;
+ }
+
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "sending DROP to " + touchedWin);
+ }
+ final int myPid = Process.myPid();
+ final IBinder token = touchedWin.mClient.asBinder();
+ DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP,
+ x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
+ null, null, mData, false);
+ try {
+ touchedWin.mClient.dispatchDragEvent(evt);
+
+ // 5 second timeout for this window to respond to the drop
+ mService.mH.removeMessages(H.DRAG_END_TIMEOUT, token);
+ Message msg = mService.mH.obtainMessage(H.DRAG_END_TIMEOUT, token);
+ mService.mH.sendMessageDelayed(msg, 5000);
+ } catch (RemoteException e) {
+ Slog.w(WindowManagerService.TAG, "can't send drop notification to win " + touchedWin);
+ return true;
+ } finally {
+ if (myPid != touchedWin.mSession.mPid) {
+ evt.recycle();
+ }
+ }
+ mToken = token;
+ return false;
+ }
+
+ // Find the visible, touch-deliverable window under the given point
+ private WindowState getTouchedWinAtPointLw(float xf, float yf) {
+ WindowState touchedWin = null;
+ final int x = (int) xf;
+ final int y = (int) yf;
+ final ArrayList<WindowState> windows = mService.mWindows;
+ final int N = windows.size();
+ for (int i = N - 1; i >= 0; i--) {
+ WindowState child = windows.get(i);
+ final int flags = child.mAttrs.flags;
+ if (!child.isVisibleLw()) {
+ // not visible == don't tell about drags
+ continue;
+ }
+ if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
+ // not touchable == don't tell about drags
+ continue;
+ }
+
+ child.getTouchableRegion(mTmpRegion);
+
+ final int touchFlags = flags &
+ (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
+ if (mTmpRegion.contains(x, y) || touchFlags == 0) {
+ // Found it
+ touchedWin = child;
+ break;
+ }
+ }
+
+ return touchedWin;
+ }
+} \ No newline at end of file
diff --git a/services/java/com/android/server/wm/FadeInOutAnimation.java b/services/java/com/android/server/wm/FadeInOutAnimation.java
new file mode 100644
index 000000000000..06f76571b016
--- /dev/null
+++ b/services/java/com/android/server/wm/FadeInOutAnimation.java
@@ -0,0 +1,44 @@
+/*
+ * 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.wm;
+
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
+
+/**
+ * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
+ * This is used for opening/closing transition for apps in compatible mode.
+ */
+class FadeInOutAnimation extends Animation {
+ boolean mFadeIn;
+
+ public FadeInOutAnimation(boolean fadeIn) {
+ setInterpolator(new AccelerateInterpolator());
+ setDuration(WindowManagerService.DEFAULT_FADE_IN_OUT_DURATION);
+ mFadeIn = fadeIn;
+ }
+
+ @Override
+ protected void applyTransformation(float interpolatedTime, Transformation t) {
+ float x = interpolatedTime;
+ if (!mFadeIn) {
+ x = 1.0f - x; // reverse the interpolation for fade out
+ }
+ t.setAlpha(x);
+ }
+} \ No newline at end of file
diff --git a/services/java/com/android/server/InputApplication.java b/services/java/com/android/server/wm/InputApplication.java
index ae0948441757..e04fd31a3ffc 100644
--- a/services/java/com/android/server/InputApplication.java
+++ b/services/java/com/android/server/wm/InputApplication.java
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
+
/**
* Describes input-related application properties for use by the input dispatcher.
diff --git a/services/java/com/android/server/InputApplicationHandle.java b/services/java/com/android/server/wm/InputApplicationHandle.java
index d396d11caa41..64c8e7ed73db 100644
--- a/services/java/com/android/server/InputApplicationHandle.java
+++ b/services/java/com/android/server/wm/InputApplicationHandle.java
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
+
/**
* Functions as a handle for an application that can receive input.
@@ -29,11 +30,11 @@ public final class InputApplicationHandle {
private int ptr;
// The window manager's application window token.
- public final WindowManagerService.AppWindowToken appWindowToken;
+ public final AppWindowToken appWindowToken;
private native void nativeDispose();
- public InputApplicationHandle(WindowManagerService.AppWindowToken appWindowToken) {
+ public InputApplicationHandle(AppWindowToken appWindowToken) {
this.appWindowToken = appWindowToken;
}
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/wm/InputManager.java
index 8d249ff79b81..80a2a96b47dd 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/wm/InputManager.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
import com.android.internal.util.XmlUtils;
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
new file mode 100644
index 000000000000..b1833c45d9f3
--- /dev/null
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.graphics.Rect;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Slog;
+import android.view.KeyEvent;
+import android.view.WindowManager;
+
+import java.util.ArrayList;
+
+final class InputMonitor {
+ private final WindowManagerService mService;
+
+ // Current window with input focus for keys and other non-touch events. May be null.
+ private WindowState mInputFocus;
+
+ // When true, prevents input dispatch from proceeding until set to false again.
+ private boolean mInputDispatchFrozen;
+
+ // When true, input dispatch proceeds normally. Otherwise all events are dropped.
+ private boolean mInputDispatchEnabled = true;
+
+ // When true, need to call updateInputWindowsLw().
+ private boolean mUpdateInputWindowsNeeded = true;
+
+ // Temporary list of windows information to provide to the input dispatcher.
+ private InputWindowList mTempInputWindows = new InputWindowList();
+
+ // Temporary input application object to provide to the input dispatcher.
+ private InputApplication mTempInputApplication = new InputApplication();
+
+ // Set to true when the first input device configuration change notification
+ // is received to indicate that the input devices are ready.
+ private final Object mInputDevicesReadyMonitor = new Object();
+ private boolean mInputDevicesReady;
+
+ public InputMonitor(WindowManagerService service) {
+ mService = service;
+ }
+
+ /* Notifies the window manager about a broken input channel.
+ *
+ * Called by the InputManager.
+ */
+ public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
+ if (inputWindowHandle == null) {
+ return;
+ }
+
+ synchronized (mService.mWindowMap) {
+ WindowState windowState = (WindowState) inputWindowHandle.windowState;
+ Slog.i(WindowManagerService.TAG, "WINDOW DIED " + windowState);
+ mService.removeWindowLocked(windowState.mSession, windowState);
+ }
+ }
+
+ /* Notifies the window manager about an application that is not responding.
+ * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
+ *
+ * Called by the InputManager.
+ */
+ public long notifyANR(InputApplicationHandle inputApplicationHandle,
+ InputWindowHandle inputWindowHandle) {
+ AppWindowToken appWindowToken = null;
+ if (inputWindowHandle != null) {
+ synchronized (mService.mWindowMap) {
+ WindowState windowState = (WindowState) inputWindowHandle.windowState;
+ if (windowState != null) {
+ Slog.i(WindowManagerService.TAG, "Input event dispatching timed out sending to "
+ + windowState.mAttrs.getTitle());
+ appWindowToken = windowState.mAppToken;
+ }
+ }
+ }
+
+ if (appWindowToken == null && inputApplicationHandle != null) {
+ appWindowToken = inputApplicationHandle.appWindowToken;
+ Slog.i(WindowManagerService.TAG, "Input event dispatching timed out sending to application "
+ + appWindowToken.stringName);
+ }
+
+ if (appWindowToken != null && appWindowToken.appToken != null) {
+ try {
+ // Notify the activity manager about the timeout and let it decide whether
+ // to abort dispatching or keep waiting.
+ boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
+ if (! abort) {
+ // The activity manager declined to abort dispatching.
+ // Wait a bit longer and timeout again later.
+ return appWindowToken.inputDispatchingTimeoutNanos;
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+ return 0; // abort dispatching
+ }
+
+ private void addDragInputWindowLw(InputWindowList windowList) {
+ final InputWindow inputWindow = windowList.add();
+ inputWindow.inputChannel = mService.mDragState.mServerChannel;
+ inputWindow.name = "drag";
+ inputWindow.layoutParamsFlags = 0;
+ inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
+ inputWindow.dispatchingTimeoutNanos = WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
+ inputWindow.visible = true;
+ inputWindow.canReceiveKeys = false;
+ inputWindow.hasFocus = true;
+ inputWindow.hasWallpaper = false;
+ inputWindow.paused = false;
+ inputWindow.layer = mService.mDragState.getDragLayerLw();
+ inputWindow.ownerPid = Process.myPid();
+ inputWindow.ownerUid = Process.myUid();
+
+ // The drag window covers the entire display
+ inputWindow.frameLeft = 0;
+ inputWindow.frameTop = 0;
+ inputWindow.frameRight = mService.mDisplay.getWidth();
+ inputWindow.frameBottom = mService.mDisplay.getHeight();
+
+ // The drag window cannot receive new touches.
+ inputWindow.touchableRegion.setEmpty();
+ }
+
+ public void setUpdateInputWindowsNeededLw() {
+ mUpdateInputWindowsNeeded = true;
+ }
+
+ /* Updates the cached window information provided to the input dispatcher. */
+ public void updateInputWindowsLw(boolean force) {
+ if (!force && !mUpdateInputWindowsNeeded) {
+ return;
+ }
+ mUpdateInputWindowsNeeded = false;
+
+ // Populate the input window list with information about all of the windows that
+ // could potentially receive input.
+ // As an optimization, we could try to prune the list of windows but this turns
+ // out to be difficult because only the native code knows for sure which window
+ // currently has touch focus.
+ final ArrayList<WindowState> windows = mService.mWindows;
+
+ // If there's a drag in flight, provide a pseudowindow to catch drag input
+ final boolean inDrag = (mService.mDragState != null);
+ if (inDrag) {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Log.d(WindowManagerService.TAG, "Inserting drag window");
+ }
+ addDragInputWindowLw(mTempInputWindows);
+ }
+
+ final int N = windows.size();
+ for (int i = N - 1; i >= 0; i--) {
+ final WindowState child = windows.get(i);
+ if (child.mInputChannel == null || child.mRemoved) {
+ // Skip this window because it cannot possibly receive input.
+ continue;
+ }
+
+ final int flags = child.mAttrs.flags;
+ final int type = child.mAttrs.type;
+
+ final boolean hasFocus = (child == mInputFocus);
+ final boolean isVisible = child.isVisibleLw();
+ final boolean hasWallpaper = (child == mService.mWallpaperTarget)
+ && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
+
+ // If there's a drag in progress and 'child' is a potential drop target,
+ // make sure it's been told about the drag
+ if (inDrag && isVisible) {
+ mService.mDragState.sendDragStartedIfNeededLw(child);
+ }
+
+ // Add a window to our list of input windows.
+ final InputWindow inputWindow = mTempInputWindows.add();
+ inputWindow.inputWindowHandle = child.mInputWindowHandle;
+ inputWindow.inputChannel = child.mInputChannel;
+ inputWindow.name = child.toString();
+ inputWindow.layoutParamsFlags = flags;
+ inputWindow.layoutParamsType = type;
+ inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
+ inputWindow.visible = isVisible;
+ inputWindow.canReceiveKeys = child.canReceiveKeys();
+ inputWindow.hasFocus = hasFocus;
+ inputWindow.hasWallpaper = hasWallpaper;
+ inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
+ inputWindow.layer = child.mLayer;
+ inputWindow.ownerPid = child.mSession.mPid;
+ inputWindow.ownerUid = child.mSession.mUid;
+
+ final Rect frame = child.mFrame;
+ inputWindow.frameLeft = frame.left;
+ inputWindow.frameTop = frame.top;
+ inputWindow.frameRight = frame.right;
+ inputWindow.frameBottom = frame.bottom;
+
+ child.getTouchableRegion(inputWindow.touchableRegion);
+ }
+
+ // Send windows to native code.
+ mService.mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
+
+ // Clear the list in preparation for the next round.
+ // Also avoids keeping InputChannel objects referenced unnecessarily.
+ mTempInputWindows.clear();
+ }
+
+ /* Notifies that the input device configuration has changed. */
+ public void notifyConfigurationChanged() {
+ mService.sendNewConfiguration();
+
+ synchronized (mInputDevicesReadyMonitor) {
+ if (!mInputDevicesReady) {
+ mInputDevicesReady = true;
+ mInputDevicesReadyMonitor.notifyAll();
+ }
+ }
+ }
+
+ /* Waits until the built-in input devices have been configured. */
+ public boolean waitForInputDevicesReady(long timeoutMillis) {
+ synchronized (mInputDevicesReadyMonitor) {
+ if (!mInputDevicesReady) {
+ try {
+ mInputDevicesReadyMonitor.wait(timeoutMillis);
+ } catch (InterruptedException ex) {
+ }
+ }
+ return mInputDevicesReady;
+ }
+ }
+
+ /* Notifies that the lid switch changed state. */
+ public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
+ mService.mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
+ }
+
+ /* Provides an opportunity for the window manager policy to intercept early key
+ * processing as soon as the key has been read from the device. */
+ public int interceptKeyBeforeQueueing(
+ KeyEvent event, int policyFlags, boolean isScreenOn) {
+ return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags, isScreenOn);
+ }
+
+ /* Provides an opportunity for the window manager policy to process a key before
+ * ordinary dispatch. */
+ public boolean interceptKeyBeforeDispatching(
+ InputWindowHandle focus, KeyEvent event, int policyFlags) {
+ WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
+ return mService.mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
+ }
+
+ /* Provides an opportunity for the window manager policy to process a key that
+ * the application did not handle. */
+ public KeyEvent dispatchUnhandledKey(
+ InputWindowHandle focus, KeyEvent event, int policyFlags) {
+ WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
+ return mService.mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
+ }
+
+ /* Called when the current input focus changes.
+ * Layer assignment is assumed to be complete by the time this is called.
+ */
+ public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
+ if (WindowManagerService.DEBUG_INPUT) {
+ Slog.d(WindowManagerService.TAG, "Input focus has changed to " + newWindow);
+ }
+
+ if (newWindow != mInputFocus) {
+ if (newWindow != null && newWindow.canReceiveKeys()) {
+ // Displaying a window implicitly causes dispatching to be unpaused.
+ // This is to protect against bugs if someone pauses dispatching but
+ // forgets to resume.
+ newWindow.mToken.paused = false;
+ }
+
+ mInputFocus = newWindow;
+ setUpdateInputWindowsNeededLw();
+
+ if (updateInputWindows) {
+ updateInputWindowsLw(false /*force*/);
+ }
+ }
+ }
+
+ public void setFocusedAppLw(AppWindowToken newApp) {
+ // Focused app has changed.
+ if (newApp == null) {
+ mService.mInputManager.setFocusedApplication(null);
+ } else {
+ mTempInputApplication.inputApplicationHandle = newApp.mInputApplicationHandle;
+ mTempInputApplication.name = newApp.toString();
+ mTempInputApplication.dispatchingTimeoutNanos =
+ newApp.inputDispatchingTimeoutNanos;
+
+ mService.mInputManager.setFocusedApplication(mTempInputApplication);
+
+ mTempInputApplication.recycle();
+ }
+ }
+
+ public void pauseDispatchingLw(WindowToken window) {
+ if (! window.paused) {
+ if (WindowManagerService.DEBUG_INPUT) {
+ Slog.v(WindowManagerService.TAG, "Pausing WindowToken " + window);
+ }
+
+ window.paused = true;
+ updateInputWindowsLw(true /*force*/);
+ }
+ }
+
+ public void resumeDispatchingLw(WindowToken window) {
+ if (window.paused) {
+ if (WindowManagerService.DEBUG_INPUT) {
+ Slog.v(WindowManagerService.TAG, "Resuming WindowToken " + window);
+ }
+
+ window.paused = false;
+ updateInputWindowsLw(true /*force*/);
+ }
+ }
+
+ public void freezeInputDispatchingLw() {
+ if (! mInputDispatchFrozen) {
+ if (WindowManagerService.DEBUG_INPUT) {
+ Slog.v(WindowManagerService.TAG, "Freezing input dispatching");
+ }
+
+ mInputDispatchFrozen = true;
+ updateInputDispatchModeLw();
+ }
+ }
+
+ public void thawInputDispatchingLw() {
+ if (mInputDispatchFrozen) {
+ if (WindowManagerService.DEBUG_INPUT) {
+ Slog.v(WindowManagerService.TAG, "Thawing input dispatching");
+ }
+
+ mInputDispatchFrozen = false;
+ updateInputDispatchModeLw();
+ }
+ }
+
+ public void setEventDispatchingLw(boolean enabled) {
+ if (mInputDispatchEnabled != enabled) {
+ if (WindowManagerService.DEBUG_INPUT) {
+ Slog.v(WindowManagerService.TAG, "Setting event dispatching to " + enabled);
+ }
+
+ mInputDispatchEnabled = enabled;
+ updateInputDispatchModeLw();
+ }
+ }
+
+ private void updateInputDispatchModeLw() {
+ mService.mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
+ }
+} \ No newline at end of file
diff --git a/services/java/com/android/server/InputWindow.java b/services/java/com/android/server/wm/InputWindow.java
index 2c2cdfe8ae77..e3eb4732dc81 100644
--- a/services/java/com/android/server/InputWindow.java
+++ b/services/java/com/android/server/wm/InputWindow.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
import android.graphics.Region;
import android.view.InputChannel;
diff --git a/services/java/com/android/server/InputWindowHandle.java b/services/java/com/android/server/wm/InputWindowHandle.java
index 4b9293918031..cc508c6f7013 100644
--- a/services/java/com/android/server/InputWindowHandle.java
+++ b/services/java/com/android/server/wm/InputWindowHandle.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
import android.view.WindowManagerPolicy;
diff --git a/services/java/com/android/server/InputWindowList.java b/services/java/com/android/server/wm/InputWindowList.java
index 1cbb2cc6f9c0..6077337a8aae 100644
--- a/services/java/com/android/server/InputWindowList.java
+++ b/services/java/com/android/server/wm/InputWindowList.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
/**
diff --git a/services/java/com/android/server/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
index ef00b08ff1a4..4356ce5ae427 100644
--- a/services/java/com/android/server/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server; // TODO: use com.android.server.wm, once things move there
+package com.android.server.wm;
import android.content.Context;
import android.graphics.Bitmap;
diff --git a/services/java/com/android/server/wm/Session.java b/services/java/com/android/server/wm/Session.java
new file mode 100644
index 000000000000..b9db17702a81
--- /dev/null
+++ b/services/java/com/android/server/wm/Session.java
@@ -0,0 +1,419 @@
+/*
+ * 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.wm;
+
+import com.android.internal.view.IInputContext;
+import com.android.internal.view.IInputMethodClient;
+import com.android.internal.view.IInputMethodManager;
+import com.android.server.wm.WindowManagerService.H;
+
+import android.content.ClipData;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Slog;
+import android.view.IWindow;
+import android.view.IWindowSession;
+import android.view.InputChannel;
+import android.view.Surface;
+import android.view.SurfaceSession;
+import android.view.WindowManager;
+
+import java.io.PrintWriter;
+
+/**
+ * This class represents an active client session. There is generally one
+ * Session object per process that is interacting with the window manager.
+ */
+final class Session extends IWindowSession.Stub
+ implements IBinder.DeathRecipient {
+ final WindowManagerService mService;
+ final IInputMethodClient mClient;
+ final IInputContext mInputContext;
+ final int mUid;
+ final int mPid;
+ final String mStringName;
+ SurfaceSession mSurfaceSession;
+ int mNumWindow = 0;
+ boolean mClientDead = false;
+
+ public Session(WindowManagerService service, IInputMethodClient client,
+ IInputContext inputContext) {
+ mService = service;
+ mClient = client;
+ mInputContext = inputContext;
+ mUid = Binder.getCallingUid();
+ mPid = Binder.getCallingPid();
+ StringBuilder sb = new StringBuilder();
+ sb.append("Session{");
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(" uid ");
+ sb.append(mUid);
+ sb.append("}");
+ mStringName = sb.toString();
+
+ synchronized (mService.mWindowMap) {
+ if (mService.mInputMethodManager == null && mService.mHaveInputMethods) {
+ IBinder b = ServiceManager.getService(
+ Context.INPUT_METHOD_SERVICE);
+ mService.mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
+ }
+ }
+ long ident = Binder.clearCallingIdentity();
+ try {
+ // Note: it is safe to call in to the input method manager
+ // here because we are not holding our lock.
+ if (mService.mInputMethodManager != null) {
+ mService.mInputMethodManager.addClient(client, inputContext,
+ mUid, mPid);
+ } else {
+ client.setUsingInputMethod(false);
+ }
+ client.asBinder().linkToDeath(this, 0);
+ } catch (RemoteException e) {
+ // The caller has died, so we can just forget about this.
+ try {
+ if (mService.mInputMethodManager != null) {
+ mService.mInputMethodManager.removeClient(client);
+ }
+ } catch (RemoteException ee) {
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ try {
+ return super.onTransact(code, data, reply, flags);
+ } catch (RuntimeException e) {
+ // Log all 'real' exceptions thrown to the caller
+ if (!(e instanceof SecurityException)) {
+ Slog.e(WindowManagerService.TAG, "Window Session Crash", e);
+ }
+ throw e;
+ }
+ }
+
+ public void binderDied() {
+ // Note: it is safe to call in to the input method manager
+ // here because we are not holding our lock.
+ try {
+ if (mService.mInputMethodManager != null) {
+ mService.mInputMethodManager.removeClient(mClient);
+ }
+ } catch (RemoteException e) {
+ }
+ synchronized(mService.mWindowMap) {
+ mClient.asBinder().unlinkToDeath(this, 0);
+ mClientDead = true;
+ killSessionLocked();
+ }
+ }
+
+ public int add(IWindow window, WindowManager.LayoutParams attrs,
+ int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
+ return mService.addWindow(this, window, attrs, viewVisibility, outContentInsets,
+ outInputChannel);
+ }
+
+ public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
+ int viewVisibility, Rect outContentInsets) {
+ return mService.addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
+ }
+
+ public void remove(IWindow window) {
+ mService.removeWindow(this, window);
+ }
+
+ public int relayout(IWindow window, WindowManager.LayoutParams attrs,
+ int requestedWidth, int requestedHeight, int viewFlags,
+ boolean insetsPending, Rect outFrame, Rect outContentInsets,
+ Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
+ //Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
+ int res = mService.relayoutWindow(this, window, attrs,
+ requestedWidth, requestedHeight, viewFlags, insetsPending,
+ outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
+ //Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
+ return res;
+ }
+
+ public void setTransparentRegion(IWindow window, Region region) {
+ mService.setTransparentRegionWindow(this, window, region);
+ }
+
+ public void setInsets(IWindow window, int touchableInsets,
+ Rect contentInsets, Rect visibleInsets, Region touchableArea) {
+ mService.setInsetsWindow(this, window, touchableInsets, contentInsets,
+ visibleInsets, touchableArea);
+ }
+
+ public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
+ mService.getWindowDisplayFrame(this, window, outDisplayFrame);
+ }
+
+ public void finishDrawing(IWindow window) {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "IWindow finishDrawing called for " + window);
+ mService.finishDrawingWindow(this, window);
+ }
+
+ public void setInTouchMode(boolean mode) {
+ synchronized(mService.mWindowMap) {
+ mService.mInTouchMode = mode;
+ }
+ }
+
+ public boolean getInTouchMode() {
+ synchronized(mService.mWindowMap) {
+ return mService.mInTouchMode;
+ }
+ }
+
+ public boolean performHapticFeedback(IWindow window, int effectId,
+ boolean always) {
+ synchronized(mService.mWindowMap) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ return mService.mPolicy.performHapticFeedbackLw(
+ mService.windowForClientLocked(this, window, true),
+ effectId, always);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ /* Drag/drop */
+ public IBinder prepareDrag(IWindow window, int flags,
+ int width, int height, Surface outSurface) {
+ return mService.prepareDragSurface(window, mSurfaceSession, flags,
+ width, height, outSurface);
+ }
+
+ public boolean performDrag(IWindow window, IBinder dragToken,
+ float touchX, float touchY, float thumbCenterX, float thumbCenterY,
+ ClipData data) {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "perform drag: win=" + window + " data=" + data);
+ }
+
+ synchronized (mService.mWindowMap) {
+ if (mService.mDragState == null) {
+ Slog.w(WindowManagerService.TAG, "No drag prepared");
+ throw new IllegalStateException("performDrag() without prepareDrag()");
+ }
+
+ if (dragToken != mService.mDragState.mToken) {
+ Slog.w(WindowManagerService.TAG, "Performing mismatched drag");
+ throw new IllegalStateException("performDrag() does not match prepareDrag()");
+ }
+
+ WindowState callingWin = mService.windowForClientLocked(null, window, false);
+ if (callingWin == null) {
+ Slog.w(WindowManagerService.TAG, "Bad requesting window " + window);
+ return false; // !!! TODO: throw here?
+ }
+
+ // !!! TODO: if input is not still focused on the initiating window, fail
+ // the drag initiation (e.g. an alarm window popped up just as the application
+ // called performDrag()
+
+ mService.mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
+
+ // !!! TODO: extract the current touch (x, y) in screen coordinates. That
+ // will let us eliminate the (touchX,touchY) parameters from the API.
+
+ // !!! FIXME: put all this heavy stuff onto the mH looper, as well as
+ // the actual drag event dispatch stuff in the dragstate
+
+ mService.mDragState.register();
+ mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
+ if (!mService.mInputManager.transferTouchFocus(callingWin.mInputChannel,
+ mService.mDragState.mServerChannel)) {
+ Slog.e(WindowManagerService.TAG, "Unable to transfer touch focus");
+ mService.mDragState.unregister();
+ mService.mDragState = null;
+ mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
+ return false;
+ }
+
+ mService.mDragState.mData = data;
+ mService.mDragState.mCurrentX = touchX;
+ mService.mDragState.mCurrentY = touchY;
+ mService.mDragState.broadcastDragStartedLw(touchX, touchY);
+
+ // remember the thumb offsets for later
+ mService.mDragState.mThumbOffsetX = thumbCenterX;
+ mService.mDragState.mThumbOffsetY = thumbCenterY;
+
+ // Make the surface visible at the proper location
+ final Surface surface = mService.mDragState.mSurface;
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION performDrag");
+ Surface.openTransaction();
+ try {
+ surface.setPosition((int)(touchX - thumbCenterX),
+ (int)(touchY - thumbCenterY));
+ surface.setAlpha(.7071f);
+ surface.setLayer(mService.mDragState.getDragLayerLw());
+ surface.show();
+ } finally {
+ Surface.closeTransaction();
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION performDrag");
+ }
+ }
+
+ return true; // success!
+ }
+
+ public void reportDropResult(IWindow window, boolean consumed) {
+ IBinder token = window.asBinder();
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "Drop result=" + consumed + " reported by " + token);
+ }
+
+ synchronized (mService.mWindowMap) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ if (mService.mDragState == null || mService.mDragState.mToken != token) {
+ Slog.w(WindowManagerService.TAG, "Invalid drop-result claim by " + window);
+ throw new IllegalStateException("reportDropResult() by non-recipient");
+ }
+
+ // The right window has responded, even if it's no longer around,
+ // so be sure to halt the timeout even if the later WindowState
+ // lookup fails.
+ mService.mH.removeMessages(H.DRAG_END_TIMEOUT, window.asBinder());
+ WindowState callingWin = mService.windowForClientLocked(null, window, false);
+ if (callingWin == null) {
+ Slog.w(WindowManagerService.TAG, "Bad result-reporting window " + window);
+ return; // !!! TODO: throw here?
+ }
+
+ mService.mDragState.mDragResult = consumed;
+ mService.mDragState.endDragLw();
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ public void dragRecipientEntered(IWindow window) {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "Drag into new candidate view @ " + window.asBinder());
+ }
+ }
+
+ public void dragRecipientExited(IWindow window) {
+ if (WindowManagerService.DEBUG_DRAG) {
+ Slog.d(WindowManagerService.TAG, "Drag from old candidate view @ " + window.asBinder());
+ }
+ }
+
+ public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
+ synchronized(mService.mWindowMap) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ mService.setWindowWallpaperPositionLocked(
+ mService.windowForClientLocked(this, window, true),
+ x, y, xStep, yStep);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ public void wallpaperOffsetsComplete(IBinder window) {
+ mService.wallpaperOffsetsComplete(window);
+ }
+
+ public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
+ int z, Bundle extras, boolean sync) {
+ synchronized(mService.mWindowMap) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ return mService.sendWindowWallpaperCommandLocked(
+ mService.windowForClientLocked(this, window, true),
+ action, x, y, z, extras, sync);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ public void wallpaperCommandComplete(IBinder window, Bundle result) {
+ mService.wallpaperCommandComplete(window, result);
+ }
+
+ void windowAddedLocked() {
+ if (mSurfaceSession == null) {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "First window added to " + this + ", creating SurfaceSession");
+ mSurfaceSession = new SurfaceSession();
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
+ WindowManagerService.TAG, " NEW SURFACE SESSION " + mSurfaceSession);
+ mService.mSessions.add(this);
+ }
+ mNumWindow++;
+ }
+
+ void windowRemovedLocked() {
+ mNumWindow--;
+ killSessionLocked();
+ }
+
+ void killSessionLocked() {
+ if (mNumWindow <= 0 && mClientDead) {
+ mService.mSessions.remove(this);
+ if (mSurfaceSession != null) {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Last window removed from " + this
+ + ", destroying " + mSurfaceSession);
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
+ WindowManagerService.TAG, " KILL SURFACE SESSION " + mSurfaceSession);
+ try {
+ mSurfaceSession.kill();
+ } catch (Exception e) {
+ Slog.w(WindowManagerService.TAG, "Exception thrown when killing surface session "
+ + mSurfaceSession + " in session " + this
+ + ": " + e.toString());
+ }
+ mSurfaceSession = null;
+ }
+ }
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
+ pw.print(" mClientDead="); pw.print(mClientDead);
+ pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
+ }
+
+ @Override
+ public String toString() {
+ return mStringName;
+ }
+} \ No newline at end of file
diff --git a/services/java/com/android/server/wm/StartingData.java b/services/java/com/android/server/wm/StartingData.java
new file mode 100644
index 000000000000..625fcfeb27d6
--- /dev/null
+++ b/services/java/com/android/server/wm/StartingData.java
@@ -0,0 +1,36 @@
+/*
+ * 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.wm;
+
+final class StartingData {
+ final String pkg;
+ final int theme;
+ final CharSequence nonLocalizedLabel;
+ final int labelRes;
+ final int icon;
+ final int windowFlags;
+
+ StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
+ int _labelRes, int _icon, int _windowFlags) {
+ pkg = _pkg;
+ theme = _theme;
+ nonLocalizedLabel = _nonLocalizedLabel;
+ labelRes = _labelRes;
+ icon = _icon;
+ windowFlags = _windowFlags;
+ }
+} \ No newline at end of file
diff --git a/services/java/com/android/server/StrictModeFlash.java b/services/java/com/android/server/wm/StrictModeFlash.java
index 0a6c62514efd..2c62080ea7d2 100644
--- a/services/java/com/android/server/StrictModeFlash.java
+++ b/services/java/com/android/server/wm/StrictModeFlash.java
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package com.android.server; // TODO: use com.android.server.wm, once things move there
+package com.android.server.wm;
+
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Region;
import android.util.DisplayMetrics;
diff --git a/services/java/com/android/server/ViewServer.java b/services/java/com/android/server/wm/ViewServer.java
index 7b5d18ac8b2c..cebd5e70e8a8 100644
--- a/services/java/com/android/server/ViewServer.java
+++ b/services/java/com/android/server/wm/ViewServer.java
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
+
import android.util.Slog;
@@ -33,7 +34,7 @@ import java.io.OutputStreamWriter;
/**
* The ViewServer is local socket server that can be used to communicate with the
* views of the opened windows. Communication with the views is ensured by the
- * {@link com.android.server.WindowManagerService} and is a cross-process operation.
+ * {@link com.android.server.wm.WindowManagerService} and is a cross-process operation.
*
* {@hide}
*/
diff --git a/services/java/com/android/server/wm/Watermark.java b/services/java/com/android/server/wm/Watermark.java
new file mode 100644
index 000000000000..22126f3052ed
--- /dev/null
+++ b/services/java/com/android/server/wm/Watermark.java
@@ -0,0 +1,177 @@
+/*
+ * 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.wm;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.graphics.Paint.FontMetricsInt;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.Display;
+import android.view.Surface;
+import android.view.SurfaceSession;
+import android.view.Surface.OutOfResourcesException;
+
+/**
+ * Displays a watermark on top of the window manager's windows.
+ */
+class Watermark {
+ final String[] mTokens;
+ final String mText;
+ final Paint mTextPaint;
+ final int mTextWidth;
+ final int mTextHeight;
+ final int mTextAscent;
+ final int mTextDescent;
+ final int mDeltaX;
+ final int mDeltaY;
+
+ Surface mSurface;
+ int mLastDW;
+ int mLastDH;
+ boolean mDrawNeeded;
+
+ Watermark(Display display, SurfaceSession session, String[] tokens) {
+ final DisplayMetrics dm = new DisplayMetrics();
+ display.getMetrics(dm);
+
+ if (false) {
+ Log.i(WindowManagerService.TAG, "*********************** WATERMARK");
+ for (int i=0; i<tokens.length; i++) {
+ Log.i(WindowManagerService.TAG, " TOKEN #" + i + ": " + tokens[i]);
+ }
+ }
+
+ mTokens = tokens;
+
+ StringBuilder builder = new StringBuilder(32);
+ int len = mTokens[0].length();
+ len = len & ~1;
+ for (int i=0; i<len; i+=2) {
+ int c1 = mTokens[0].charAt(i);
+ int c2 = mTokens[0].charAt(i+1);
+ if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10;
+ else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10;
+ else c1 -= '0';
+ if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10;
+ else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10;
+ else c2 -= '0';
+ builder.append((char)(255-((c1*16)+c2)));
+ }
+ mText = builder.toString();
+ if (false) {
+ Log.i(WindowManagerService.TAG, "Final text: " + mText);
+ }
+
+ int fontSize = WindowManagerService.getPropertyInt(tokens, 1,
+ TypedValue.COMPLEX_UNIT_DIP, 20, dm);
+
+ mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mTextPaint.setTextSize(fontSize);
+ mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
+
+ FontMetricsInt fm = mTextPaint.getFontMetricsInt();
+ mTextWidth = (int)mTextPaint.measureText(mText);
+ mTextAscent = fm.ascent;
+ mTextDescent = fm.descent;
+ mTextHeight = fm.descent - fm.ascent;
+
+ mDeltaX = WindowManagerService.getPropertyInt(tokens, 2,
+ TypedValue.COMPLEX_UNIT_PX, mTextWidth*2, dm);
+ mDeltaY = WindowManagerService.getPropertyInt(tokens, 3,
+ TypedValue.COMPLEX_UNIT_PX, mTextHeight*3, dm);
+ int shadowColor = WindowManagerService.getPropertyInt(tokens, 4,
+ TypedValue.COMPLEX_UNIT_PX, 0xb0000000, dm);
+ int color = WindowManagerService.getPropertyInt(tokens, 5,
+ TypedValue.COMPLEX_UNIT_PX, 0x60ffffff, dm);
+ int shadowRadius = WindowManagerService.getPropertyInt(tokens, 6,
+ TypedValue.COMPLEX_UNIT_PX, 7, dm);
+ int shadowDx = WindowManagerService.getPropertyInt(tokens, 8,
+ TypedValue.COMPLEX_UNIT_PX, 0, dm);
+ int shadowDy = WindowManagerService.getPropertyInt(tokens, 9,
+ TypedValue.COMPLEX_UNIT_PX, 0, dm);
+
+ mTextPaint.setColor(color);
+ mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
+
+ try {
+ mSurface = new Surface(session, 0,
+ "WatermarkSurface", -1, 1, 1, PixelFormat.TRANSLUCENT, 0);
+ mSurface.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER*100);
+ mSurface.setPosition(0, 0);
+ mSurface.show();
+ } catch (OutOfResourcesException e) {
+ }
+ }
+
+ void positionSurface(int dw, int dh) {
+ if (mLastDW != dw || mLastDH != dh) {
+ mLastDW = dw;
+ mLastDH = dh;
+ mSurface.setSize(dw, dh);
+ mDrawNeeded = true;
+ }
+ }
+
+ void drawIfNeeded() {
+ if (mDrawNeeded) {
+ final int dw = mLastDW;
+ final int dh = mLastDH;
+
+ mDrawNeeded = false;
+ Rect dirty = new Rect(0, 0, dw, dh);
+ Canvas c = null;
+ try {
+ c = mSurface.lockCanvas(dirty);
+ } catch (IllegalArgumentException e) {
+ } catch (OutOfResourcesException e) {
+ }
+ if (c != null) {
+ c.drawColor(0, PorterDuff.Mode.CLEAR);
+
+ int deltaX = mDeltaX;
+ int deltaY = mDeltaY;
+
+ // deltaX shouldn't be close to a round fraction of our
+ // x step, or else things will line up too much.
+ int div = (dw+mTextWidth)/deltaX;
+ int rem = (dw+mTextWidth) - (div*deltaX);
+ int qdelta = deltaX/4;
+ if (rem < qdelta || rem > (deltaX-qdelta)) {
+ deltaX += deltaX/3;
+ }
+
+ int y = -mTextHeight;
+ int x = -mTextWidth;
+ while (y < (dh+mTextHeight)) {
+ c.drawText(mText, x, y, mTextPaint);
+ x += deltaX;
+ if (x >= dw) {
+ x -= (dw+mTextWidth);
+ y += deltaY;
+ }
+ }
+ mSurface.unlockCanvasAndPost(c);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index b662c5501187..b7cc3243255a 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
@@ -22,7 +22,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
-import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
@@ -42,6 +41,10 @@ import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
import com.android.internal.view.IInputMethodManager;
import com.android.internal.view.WindowManagerPolicyThread;
+import com.android.server.AttributeCache;
+import com.android.server.EventLogTags;
+import com.android.server.PowerManagerService;
+import com.android.server.Watchdog;
import com.android.server.am.BatteryStatsService;
import android.Manifest;
@@ -50,8 +53,6 @@ import android.app.IActivityManager;
import android.app.StatusBarManager;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
-import android.content.ClipData;
-import android.content.ClipDescription;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -59,17 +60,12 @@ import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
-import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
-import android.graphics.Paint;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Region;
-import android.graphics.Typeface;
-import android.graphics.Paint.FontMetricsInt;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Bundle;
@@ -98,8 +94,6 @@ import android.util.Slog;
import android.util.SparseIntArray;
import android.util.TypedValue;
import android.view.Display;
-import android.view.DragEvent;
-import android.view.Gravity;
import android.view.IApplicationToken;
import android.view.IOnKeyguardExitResult;
import android.view.IRotationWatcher;
@@ -116,13 +110,10 @@ import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceSession;
import android.view.View;
-import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.WindowManagerImpl;
import android.view.WindowManagerPolicy;
-import android.view.Surface.OutOfResourcesException;
import android.view.WindowManager.LayoutParams;
-import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Transformation;
@@ -219,7 +210,7 @@ public class WindowManagerService extends IWindowManager.Stub
private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
// Default input dispatching timeout in nanoseconds.
- private static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
+ static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
static final int UPDATE_FOCUS_NORMAL = 0;
static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
@@ -507,336 +498,8 @@ public class WindowManagerService extends IWindowManager.Stub
boolean mTurnOnScreen;
- /**
- * Drag/drop state
- */
- class DragState {
- IBinder mToken;
- Surface mSurface;
- int mFlags;
- IBinder mLocalWin;
- ClipData mData;
- ClipDescription mDataDescription;
- boolean mDragResult;
- float mCurrentX, mCurrentY;
- float mThumbOffsetX, mThumbOffsetY;
- InputChannel mServerChannel, mClientChannel;
- WindowState mTargetWindow;
- ArrayList<WindowState> mNotifiedWindows;
- boolean mDragInProgress;
-
- private final Region mTmpRegion = new Region();
-
- DragState(IBinder token, Surface surface, int flags, IBinder localWin) {
- mToken = token;
- mSurface = surface;
- mFlags = flags;
- mLocalWin = localWin;
- mNotifiedWindows = new ArrayList<WindowState>();
- }
-
- void reset() {
- if (mSurface != null) {
- mSurface.destroy();
- }
- mSurface = null;
- mFlags = 0;
- mLocalWin = null;
- mToken = null;
- mData = null;
- mThumbOffsetX = mThumbOffsetY = 0;
- mNotifiedWindows = null;
- }
-
- void register() {
- if (DEBUG_DRAG) Slog.d(TAG, "registering drag input channel");
- if (mClientChannel != null) {
- Slog.e(TAG, "Duplicate register of drag input channel");
- } else {
- InputChannel[] channels = InputChannel.openInputChannelPair("drag");
- mServerChannel = channels[0];
- mClientChannel = channels[1];
- mInputManager.registerInputChannel(mServerChannel, null);
- InputQueue.registerInputChannel(mClientChannel, mDragInputHandler,
- mH.getLooper().getQueue());
- }
- }
-
- void unregister() {
- if (DEBUG_DRAG) Slog.d(TAG, "unregistering drag input channel");
- if (mClientChannel == null) {
- Slog.e(TAG, "Unregister of nonexistent drag input channel");
- } else {
- mInputManager.unregisterInputChannel(mServerChannel);
- InputQueue.unregisterInputChannel(mClientChannel);
- mClientChannel.dispose();
- mServerChannel.dispose();
- mClientChannel = null;
- mServerChannel = null;
- }
- }
-
- int getDragLayerLw() {
- return mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG)
- * TYPE_LAYER_MULTIPLIER
- + TYPE_LAYER_OFFSET;
- }
-
- /* call out to each visible window/session informing it about the drag
- */
- void broadcastDragStartedLw(final float touchX, final float touchY) {
- // Cache a base-class instance of the clip metadata so that parceling
- // works correctly in calling out to the apps.
- mDataDescription = (mData != null) ? mData.getDescription() : null;
- mNotifiedWindows.clear();
- mDragInProgress = true;
-
- if (DEBUG_DRAG) {
- Slog.d(TAG, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
- }
-
- final int N = mWindows.size();
- for (int i = 0; i < N; i++) {
- sendDragStartedLw(mWindows.get(i), touchX, touchY, mDataDescription);
- }
- }
-
- /* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
- * designated window is potentially a drop recipient. There are race situations
- * around DRAG_ENDED broadcast, so we make sure that once we've declared that
- * the drag has ended, we never send out another DRAG_STARTED for this drag action.
- *
- * This method clones the 'event' parameter if it's being delivered to the same
- * process, so it's safe for the caller to call recycle() on the event afterwards.
- */
- private void sendDragStartedLw(WindowState newWin, float touchX, float touchY,
- ClipDescription desc) {
- // Don't actually send the event if the drag is supposed to be pinned
- // to the originating window but 'newWin' is not that window.
- if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
- final IBinder winBinder = newWin.mClient.asBinder();
- if (winBinder != mLocalWin) {
- if (DEBUG_DRAG) {
- Slog.d(TAG, "Not dispatching local DRAG_STARTED to " + newWin);
- }
- return;
- }
- }
-
- if (mDragInProgress && newWin.isPotentialDragTarget()) {
- DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED,
- touchX - newWin.mFrame.left, touchY - newWin.mFrame.top,
- null, desc, null, false);
- try {
- newWin.mClient.dispatchDragEvent(event);
- // track each window that we've notified that the drag is starting
- mNotifiedWindows.add(newWin);
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to drag-start window " + newWin);
- } finally {
- // if the callee was local, the dispatch has already recycled the event
- if (Process.myPid() != newWin.mSession.mPid) {
- event.recycle();
- }
- }
- }
- }
-
- /* helper - construct and send a DRAG_STARTED event only if the window has not
- * previously been notified, i.e. it became visible after the drag operation
- * was begun. This is a rare case.
- */
- private void sendDragStartedIfNeededLw(WindowState newWin) {
- if (mDragInProgress) {
- // If we have sent the drag-started, we needn't do so again
- for (WindowState ws : mNotifiedWindows) {
- if (ws == newWin) {
- return;
- }
- }
- if (DEBUG_DRAG) {
- Slog.d(TAG, "need to send DRAG_STARTED to new window " + newWin);
- }
- sendDragStartedLw(newWin, mCurrentX, mCurrentY, mDataDescription);
- }
- }
-
- void broadcastDragEndedLw() {
- if (DEBUG_DRAG) {
- Slog.d(TAG, "broadcasting DRAG_ENDED");
- }
- DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED,
- 0, 0, null, null, null, mDragResult);
- for (WindowState ws: mNotifiedWindows) {
- try {
- ws.mClient.dispatchDragEvent(evt);
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to drag-end window " + ws);
- }
- }
- mNotifiedWindows.clear();
- mDragInProgress = false;
- evt.recycle();
- }
-
- void endDragLw() {
- mDragState.broadcastDragEndedLw();
-
- // stop intercepting input
- mDragState.unregister();
- mInputMonitor.updateInputWindowsLw(true /*force*/);
-
- // free our resources and drop all the object references
- mDragState.reset();
- mDragState = null;
-
- if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-drag rotation");
- boolean changed = setRotationUncheckedLocked(
- WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
- if (changed) {
- mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
- }
- }
-
- void notifyMoveLw(float x, float y) {
- final int myPid = Process.myPid();
-
- // Move the surface to the given touch
- if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION notifyMoveLw");
- Surface.openTransaction();
- try {
- mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG "
- + mSurface + ": pos=(" +
- (int)(x - mThumbOffsetX) + "," + (int)(y - mThumbOffsetY) + ")");
- } finally {
- Surface.closeTransaction();
- if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION notifyMoveLw");
- }
-
- // Tell the affected window
- WindowState touchedWin = getTouchedWinAtPointLw(x, y);
- if (touchedWin == null) {
- if (DEBUG_DRAG) Slog.d(TAG, "No touched win at x=" + x + " y=" + y);
- return;
- }
- if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
- final IBinder touchedBinder = touchedWin.mClient.asBinder();
- if (touchedBinder != mLocalWin) {
- // This drag is pinned only to the originating window, but the drag
- // point is outside that window. Pretend it's over empty space.
- touchedWin = null;
- }
- }
- try {
- // have we dragged over a new window?
- if ((touchedWin != mTargetWindow) && (mTargetWindow != null)) {
- if (DEBUG_DRAG) {
- Slog.d(TAG, "sending DRAG_EXITED to " + mTargetWindow);
- }
- // force DRAG_EXITED_EVENT if appropriate
- DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
- x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top,
- null, null, null, false);
- mTargetWindow.mClient.dispatchDragEvent(evt);
- if (myPid != mTargetWindow.mSession.mPid) {
- evt.recycle();
- }
- }
- if (touchedWin != null) {
- if (false && DEBUG_DRAG) {
- Slog.d(TAG, "sending DRAG_LOCATION to " + touchedWin);
- }
- DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
- x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
- null, null, null, false);
- touchedWin.mClient.dispatchDragEvent(evt);
- if (myPid != touchedWin.mSession.mPid) {
- evt.recycle();
- }
- }
- } catch (RemoteException e) {
- Slog.w(TAG, "can't send drag notification to windows");
- }
- mTargetWindow = touchedWin;
- }
-
- // Tell the drop target about the data. Returns 'true' if we can immediately
- // dispatch the global drag-ended message, 'false' if we need to wait for a
- // result from the recipient.
- boolean notifyDropLw(float x, float y) {
- WindowState touchedWin = getTouchedWinAtPointLw(x, y);
- if (touchedWin == null) {
- // "drop" outside a valid window -- no recipient to apply a
- // timeout to, and we can send the drag-ended message immediately.
- mDragResult = false;
- return true;
- }
-
- if (DEBUG_DRAG) {
- Slog.d(TAG, "sending DROP to " + touchedWin);
- }
- final int myPid = Process.myPid();
- final IBinder token = touchedWin.mClient.asBinder();
- DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP,
- x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
- null, null, mData, false);
- try {
- touchedWin.mClient.dispatchDragEvent(evt);
-
- // 5 second timeout for this window to respond to the drop
- mH.removeMessages(H.DRAG_END_TIMEOUT, token);
- Message msg = mH.obtainMessage(H.DRAG_END_TIMEOUT, token);
- mH.sendMessageDelayed(msg, 5000);
- } catch (RemoteException e) {
- Slog.w(TAG, "can't send drop notification to win " + touchedWin);
- return true;
- } finally {
- if (myPid != touchedWin.mSession.mPid) {
- evt.recycle();
- }
- }
- mToken = token;
- return false;
- }
-
- // Find the visible, touch-deliverable window under the given point
- private WindowState getTouchedWinAtPointLw(float xf, float yf) {
- WindowState touchedWin = null;
- final int x = (int) xf;
- final int y = (int) yf;
- final ArrayList<WindowState> windows = mWindows;
- final int N = windows.size();
- for (int i = N - 1; i >= 0; i--) {
- WindowState child = windows.get(i);
- final int flags = child.mAttrs.flags;
- if (!child.isVisibleLw()) {
- // not visible == don't tell about drags
- continue;
- }
- if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) {
- // not touchable == don't tell about drags
- continue;
- }
-
- child.getTouchableRegion(mTmpRegion);
-
- final int touchFlags = flags &
- (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
- if (mTmpRegion.contains(x, y) || touchFlags == 0) {
- // Found it
- touchedWin = child;
- break;
- }
- }
-
- return touchedWin;
- }
- }
-
DragState mDragState = null;
- private final InputHandler mDragInputHandler = new BaseInputHandler() {
+ final InputHandler mDragInputHandler = new BaseInputHandler() {
@Override
public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
boolean handled = false;
@@ -2300,7 +1963,7 @@ public class WindowManagerService extends IWindowManager.Stub
+ attrs.token + ". Aborting.");
return WindowManagerImpl.ADD_BAD_APP_TOKEN;
}
- token = new WindowToken(attrs.token, -1, false);
+ token = new WindowToken(this, attrs.token, -1, false);
addToken = true;
} else if (attrs.type >= FIRST_APPLICATION_WINDOW
&& attrs.type <= LAST_APPLICATION_WINDOW) {
@@ -2334,7 +1997,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- win = new WindowState(session, client, token,
+ win = new WindowState(this, session, client, token,
attachedWindow, attrs, viewVisibility);
if (win.mDeathRecipient == null) {
// Client has apparently died, so there is no reason to
@@ -2632,7 +2295,7 @@ public class WindowManagerService extends IWindowManager.Stub
mInputMonitor.updateInputWindowsLw(true /*force*/);
}
- private static void logSurface(WindowState w, String msg, RuntimeException where) {
+ static void logSurface(WindowState w, String msg, RuntimeException where) {
String str = " SURFACE " + Integer.toHexString(w.hashCode())
+ ": " + msg + " / " + w.mAttrs.getTitle();
if (where != null) {
@@ -2642,7 +2305,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- private void setTransparentRegionWindow(Session session, IWindow client, Region region) {
+ void setTransparentRegionWindow(Session session, IWindow client, Region region) {
long origId = Binder.clearCallingIdentity();
try {
synchronized (mWindowMap) {
@@ -3096,7 +2759,7 @@ public class WindowManagerService extends IWindowManager.Stub
return null;
}
- private void applyEnterAnimationLocked(WindowState win) {
+ void applyEnterAnimationLocked(WindowState win) {
int transit = WindowManagerPolicy.TRANSIT_SHOW;
if (win.mEnterAnimationPending) {
win.mEnterAnimationPending = false;
@@ -3106,7 +2769,7 @@ public class WindowManagerService extends IWindowManager.Stub
applyAnimationLocked(win, transit, true);
}
- private boolean applyAnimationLocked(WindowState win,
+ boolean applyAnimationLocked(WindowState win,
int transit, boolean isEntrance) {
if (win.mLocalAnimating && win.mAnimationIsEntrance == isEntrance) {
// If we are trying to apply an animation, but already running
@@ -3362,7 +3025,7 @@ public class WindowManagerService extends IWindowManager.Stub
Slog.w(TAG, "Attempted to add existing input method token: " + token);
return;
}
- wtoken = new WindowToken(token, type, true);
+ wtoken = new WindowToken(this, token, type, true);
mTokenMap.put(token, wtoken);
if (type == TYPE_WALLPAPER) {
mWallpaperTokens.add(wtoken);
@@ -3450,7 +3113,7 @@ public class WindowManagerService extends IWindowManager.Stub
Slog.w(TAG, "Attempted to add existing app token: " + token);
return;
}
- wtoken = new AppWindowToken(token);
+ wtoken = new AppWindowToken(this, token);
wtoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
wtoken.groupId = groupId;
wtoken.appFullscreen = fullscreen;
@@ -4747,6 +4410,14 @@ public class WindowManagerService extends IWindowManager.Stub
return mPolicy.inKeyguardRestrictedKeyInputMode();
}
+ public boolean isKeyguardLocked() {
+ return mPolicy.isKeyguardLocked();
+ }
+
+ public boolean isKeyguardSecure() {
+ return mPolicy.isKeyguardSecure();
+ }
+
public void closeSystemDialogs(String reason) {
synchronized(mWindowMap) {
for (int i=mWindows.size()-1; i>=0; i--) {
@@ -5159,21 +4830,25 @@ public class WindowManagerService extends IWindowManager.Stub
public void freezeRotation() {
if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
- "setRotation()")) {
+ "freezeRotation()")) {
throw new SecurityException("Requires SET_ORIENTATION permission");
}
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
+
mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, mRotation);
setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
}
public void thawRotation() {
if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
- "setRotation()")) {
+ "thawRotation()")) {
throw new SecurityException("Requires SET_ORIENTATION permission");
}
- mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 0);
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
+
+ mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used
setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
}
@@ -5347,8 +5022,8 @@ public class WindowManagerService extends IWindowManager.Stub
*
* @return True if the server was successfully started, false otherwise.
*
- * @see com.android.server.ViewServer
- * @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
+ * @see com.android.server.wm.ViewServer
+ * @see com.android.server.wm.ViewServer#VIEW_SERVER_DEFAULT_PORT
*/
public boolean startViewServer(int port) {
if (isSystemSecure()) {
@@ -5394,7 +5069,7 @@ public class WindowManagerService extends IWindowManager.Stub
* @return True if the server stopped, false if it wasn't started or
* couldn't be stopped.
*
- * @see com.android.server.ViewServer
+ * @see com.android.server.wm.ViewServer
*/
public boolean stopViewServer() {
if (isSystemSecure()) {
@@ -5416,7 +5091,7 @@ public class WindowManagerService extends IWindowManager.Stub
*
* @return True if the server is running, false otherwise.
*
- * @see com.android.server.ViewServer
+ * @see com.android.server.wm.ViewServer
*/
public boolean isViewServerRunning() {
if (isSystemSecure()) {
@@ -5578,7 +5253,7 @@ public class WindowManagerService extends IWindowManager.Stub
parameters = "";
}
- final WindowManagerService.WindowState window = findWindow(hashCode);
+ final WindowState window = findWindow(hashCode);
if (window == null) {
return false;
}
@@ -5889,7 +5564,7 @@ public class WindowManagerService extends IWindowManager.Stub
outSurface.copyFrom(surface);
final IBinder winBinder = window.asBinder();
token = new Binder();
- mDragState = new DragState(token, surface, /*flags*/ 0, winBinder);
+ mDragState = new DragState(this, token, surface, /*flags*/ 0, winBinder);
mDragState.mSurface = surface;
token = mDragState.mToken = new Binder();
@@ -5919,355 +5594,8 @@ public class WindowManagerService extends IWindowManager.Stub
// Input Events and Focus Management
// -------------------------------------------------------------
- InputMonitor mInputMonitor = new InputMonitor();
+ final InputMonitor mInputMonitor = new InputMonitor(this);
- /* Tracks the progress of input dispatch and ensures that input dispatch state
- * is kept in sync with changes in window focus, visibility, registration, and
- * other relevant Window Manager state transitions. */
- final class InputMonitor {
- // Current window with input focus for keys and other non-touch events. May be null.
- private WindowState mInputFocus;
-
- // When true, prevents input dispatch from proceeding until set to false again.
- private boolean mInputDispatchFrozen;
-
- // When true, input dispatch proceeds normally. Otherwise all events are dropped.
- private boolean mInputDispatchEnabled = true;
-
- // When true, need to call updateInputWindowsLw().
- private boolean mUpdateInputWindowsNeeded = true;
-
- // Temporary list of windows information to provide to the input dispatcher.
- private InputWindowList mTempInputWindows = new InputWindowList();
-
- // Temporary input application object to provide to the input dispatcher.
- private InputApplication mTempInputApplication = new InputApplication();
-
- // Set to true when the first input device configuration change notification
- // is received to indicate that the input devices are ready.
- private final Object mInputDevicesReadyMonitor = new Object();
- private boolean mInputDevicesReady;
-
- /* Notifies the window manager about a broken input channel.
- *
- * Called by the InputManager.
- */
- public void notifyInputChannelBroken(InputWindowHandle inputWindowHandle) {
- if (inputWindowHandle == null) {
- return;
- }
-
- synchronized (mWindowMap) {
- WindowState windowState = (WindowState) inputWindowHandle.windowState;
- Slog.i(TAG, "WINDOW DIED " + windowState);
- removeWindowLocked(windowState.mSession, windowState);
- }
- }
-
- /* Notifies the window manager about an application that is not responding.
- * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
- *
- * Called by the InputManager.
- */
- public long notifyANR(InputApplicationHandle inputApplicationHandle,
- InputWindowHandle inputWindowHandle) {
- AppWindowToken appWindowToken = null;
- if (inputWindowHandle != null) {
- synchronized (mWindowMap) {
- WindowState windowState = (WindowState) inputWindowHandle.windowState;
- if (windowState != null) {
- Slog.i(TAG, "Input event dispatching timed out sending to "
- + windowState.mAttrs.getTitle());
- appWindowToken = windowState.mAppToken;
- }
- }
- }
-
- if (appWindowToken == null && inputApplicationHandle != null) {
- appWindowToken = inputApplicationHandle.appWindowToken;
- Slog.i(TAG, "Input event dispatching timed out sending to application "
- + appWindowToken.stringName);
- }
-
- if (appWindowToken != null && appWindowToken.appToken != null) {
- try {
- // Notify the activity manager about the timeout and let it decide whether
- // to abort dispatching or keep waiting.
- boolean abort = appWindowToken.appToken.keyDispatchingTimedOut();
- if (! abort) {
- // The activity manager declined to abort dispatching.
- // Wait a bit longer and timeout again later.
- return appWindowToken.inputDispatchingTimeoutNanos;
- }
- } catch (RemoteException ex) {
- }
- }
- return 0; // abort dispatching
- }
-
- private void addDragInputWindowLw(InputWindowList windowList) {
- final InputWindow inputWindow = windowList.add();
- inputWindow.inputChannel = mDragState.mServerChannel;
- inputWindow.name = "drag";
- inputWindow.layoutParamsFlags = 0;
- inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
- inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
- inputWindow.visible = true;
- inputWindow.canReceiveKeys = false;
- inputWindow.hasFocus = true;
- inputWindow.hasWallpaper = false;
- inputWindow.paused = false;
- inputWindow.layer = mDragState.getDragLayerLw();
- inputWindow.ownerPid = Process.myPid();
- inputWindow.ownerUid = Process.myUid();
-
- // The drag window covers the entire display
- inputWindow.frameLeft = 0;
- inputWindow.frameTop = 0;
- inputWindow.frameRight = mDisplay.getWidth();
- inputWindow.frameBottom = mDisplay.getHeight();
-
- // The drag window cannot receive new touches.
- inputWindow.touchableRegion.setEmpty();
- }
-
- public void setUpdateInputWindowsNeededLw() {
- mUpdateInputWindowsNeeded = true;
- }
-
- /* Updates the cached window information provided to the input dispatcher. */
- public void updateInputWindowsLw(boolean force) {
- if (!force && !mUpdateInputWindowsNeeded) {
- return;
- }
- mUpdateInputWindowsNeeded = false;
-
- // Populate the input window list with information about all of the windows that
- // could potentially receive input.
- // As an optimization, we could try to prune the list of windows but this turns
- // out to be difficult because only the native code knows for sure which window
- // currently has touch focus.
- final ArrayList<WindowState> windows = mWindows;
-
- // If there's a drag in flight, provide a pseudowindow to catch drag input
- final boolean inDrag = (mDragState != null);
- if (inDrag) {
- if (DEBUG_DRAG) {
- Log.d(TAG, "Inserting drag window");
- }
- addDragInputWindowLw(mTempInputWindows);
- }
-
- final int N = windows.size();
- for (int i = N - 1; i >= 0; i--) {
- final WindowState child = windows.get(i);
- if (child.mInputChannel == null || child.mRemoved) {
- // Skip this window because it cannot possibly receive input.
- continue;
- }
-
- final int flags = child.mAttrs.flags;
- final int type = child.mAttrs.type;
-
- final boolean hasFocus = (child == mInputFocus);
- final boolean isVisible = child.isVisibleLw();
- final boolean hasWallpaper = (child == mWallpaperTarget)
- && (type != WindowManager.LayoutParams.TYPE_KEYGUARD);
-
- // If there's a drag in progress and 'child' is a potential drop target,
- // make sure it's been told about the drag
- if (inDrag && isVisible) {
- mDragState.sendDragStartedIfNeededLw(child);
- }
-
- // Add a window to our list of input windows.
- final InputWindow inputWindow = mTempInputWindows.add();
- inputWindow.inputWindowHandle = child.mInputWindowHandle;
- inputWindow.inputChannel = child.mInputChannel;
- inputWindow.name = child.toString();
- inputWindow.layoutParamsFlags = flags;
- inputWindow.layoutParamsType = type;
- inputWindow.dispatchingTimeoutNanos = child.getInputDispatchingTimeoutNanos();
- inputWindow.visible = isVisible;
- inputWindow.canReceiveKeys = child.canReceiveKeys();
- inputWindow.hasFocus = hasFocus;
- inputWindow.hasWallpaper = hasWallpaper;
- inputWindow.paused = child.mAppToken != null ? child.mAppToken.paused : false;
- inputWindow.layer = child.mLayer;
- inputWindow.ownerPid = child.mSession.mPid;
- inputWindow.ownerUid = child.mSession.mUid;
-
- final Rect frame = child.mFrame;
- inputWindow.frameLeft = frame.left;
- inputWindow.frameTop = frame.top;
- inputWindow.frameRight = frame.right;
- inputWindow.frameBottom = frame.bottom;
-
- child.getTouchableRegion(inputWindow.touchableRegion);
- }
-
- // Send windows to native code.
- mInputManager.setInputWindows(mTempInputWindows.toNullTerminatedArray());
-
- // Clear the list in preparation for the next round.
- // Also avoids keeping InputChannel objects referenced unnecessarily.
- mTempInputWindows.clear();
- }
-
- /* Notifies that the input device configuration has changed. */
- public void notifyConfigurationChanged() {
- sendNewConfiguration();
-
- synchronized (mInputDevicesReadyMonitor) {
- if (!mInputDevicesReady) {
- mInputDevicesReady = true;
- mInputDevicesReadyMonitor.notifyAll();
- }
- }
- }
-
- /* Waits until the built-in input devices have been configured. */
- public boolean waitForInputDevicesReady(long timeoutMillis) {
- synchronized (mInputDevicesReadyMonitor) {
- if (!mInputDevicesReady) {
- try {
- mInputDevicesReadyMonitor.wait(timeoutMillis);
- } catch (InterruptedException ex) {
- }
- }
- return mInputDevicesReady;
- }
- }
-
- /* Notifies that the lid switch changed state. */
- public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
- mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);
- }
-
- /* Provides an opportunity for the window manager policy to intercept early key
- * processing as soon as the key has been read from the device. */
- public int interceptKeyBeforeQueueing(
- KeyEvent event, int policyFlags, boolean isScreenOn) {
- return mPolicy.interceptKeyBeforeQueueing(event, policyFlags, isScreenOn);
- }
-
- /* Provides an opportunity for the window manager policy to process a key before
- * ordinary dispatch. */
- public boolean interceptKeyBeforeDispatching(
- InputWindowHandle focus, KeyEvent event, int policyFlags) {
- WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
- return mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);
- }
-
- /* Provides an opportunity for the window manager policy to process a key that
- * the application did not handle. */
- public KeyEvent dispatchUnhandledKey(
- InputWindowHandle focus, KeyEvent event, int policyFlags) {
- WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
- return mPolicy.dispatchUnhandledKey(windowState, event, policyFlags);
- }
-
- /* Called when the current input focus changes.
- * Layer assignment is assumed to be complete by the time this is called.
- */
- public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
- if (DEBUG_INPUT) {
- Slog.d(TAG, "Input focus has changed to " + newWindow);
- }
-
- if (newWindow != mInputFocus) {
- if (newWindow != null && newWindow.canReceiveKeys()) {
- // Displaying a window implicitly causes dispatching to be unpaused.
- // This is to protect against bugs if someone pauses dispatching but
- // forgets to resume.
- newWindow.mToken.paused = false;
- }
-
- mInputFocus = newWindow;
- setUpdateInputWindowsNeededLw();
-
- if (updateInputWindows) {
- updateInputWindowsLw(false /*force*/);
- }
- }
- }
-
- public void setFocusedAppLw(AppWindowToken newApp) {
- // Focused app has changed.
- if (newApp == null) {
- mInputManager.setFocusedApplication(null);
- } else {
- mTempInputApplication.inputApplicationHandle = newApp.mInputApplicationHandle;
- mTempInputApplication.name = newApp.toString();
- mTempInputApplication.dispatchingTimeoutNanos =
- newApp.inputDispatchingTimeoutNanos;
-
- mInputManager.setFocusedApplication(mTempInputApplication);
-
- mTempInputApplication.recycle();
- }
- }
-
- public void pauseDispatchingLw(WindowToken window) {
- if (! window.paused) {
- if (DEBUG_INPUT) {
- Slog.v(TAG, "Pausing WindowToken " + window);
- }
-
- window.paused = true;
- updateInputWindowsLw(true /*force*/);
- }
- }
-
- public void resumeDispatchingLw(WindowToken window) {
- if (window.paused) {
- if (DEBUG_INPUT) {
- Slog.v(TAG, "Resuming WindowToken " + window);
- }
-
- window.paused = false;
- updateInputWindowsLw(true /*force*/);
- }
- }
-
- public void freezeInputDispatchingLw() {
- if (! mInputDispatchFrozen) {
- if (DEBUG_INPUT) {
- Slog.v(TAG, "Freezing input dispatching");
- }
-
- mInputDispatchFrozen = true;
- updateInputDispatchModeLw();
- }
- }
-
- public void thawInputDispatchingLw() {
- if (mInputDispatchFrozen) {
- if (DEBUG_INPUT) {
- Slog.v(TAG, "Thawing input dispatching");
- }
-
- mInputDispatchFrozen = false;
- updateInputDispatchModeLw();
- }
- }
-
- public void setEventDispatchingLw(boolean enabled) {
- if (mInputDispatchEnabled != enabled) {
- if (DEBUG_INPUT) {
- Slog.v(TAG, "Setting event dispatching to " + enabled);
- }
-
- mInputDispatchEnabled = enabled;
- updateInputDispatchModeLw();
- }
- }
-
- private void updateInputDispatchModeLw() {
- mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
- }
- }
-
public void pauseKeyDispatching(IBinder _token) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"pauseKeyDispatching()")) {
@@ -6496,2409 +5824,6 @@ public class WindowManagerService extends IWindowManager.Stub
mPolicy.systemReady();
}
- // -------------------------------------------------------------
- // Client Session State
- // -------------------------------------------------------------
-
- private final class Session extends IWindowSession.Stub
- implements IBinder.DeathRecipient {
- final IInputMethodClient mClient;
- final IInputContext mInputContext;
- final int mUid;
- final int mPid;
- final String mStringName;
- SurfaceSession mSurfaceSession;
- int mNumWindow = 0;
- boolean mClientDead = false;
-
- public Session(IInputMethodClient client, IInputContext inputContext) {
- mClient = client;
- mInputContext = inputContext;
- mUid = Binder.getCallingUid();
- mPid = Binder.getCallingPid();
- StringBuilder sb = new StringBuilder();
- sb.append("Session{");
- sb.append(Integer.toHexString(System.identityHashCode(this)));
- sb.append(" uid ");
- sb.append(mUid);
- sb.append("}");
- mStringName = sb.toString();
-
- synchronized (mWindowMap) {
- if (mInputMethodManager == null && mHaveInputMethods) {
- IBinder b = ServiceManager.getService(
- Context.INPUT_METHOD_SERVICE);
- mInputMethodManager = IInputMethodManager.Stub.asInterface(b);
- }
- }
- long ident = Binder.clearCallingIdentity();
- try {
- // Note: it is safe to call in to the input method manager
- // here because we are not holding our lock.
- if (mInputMethodManager != null) {
- mInputMethodManager.addClient(client, inputContext,
- mUid, mPid);
- } else {
- client.setUsingInputMethod(false);
- }
- client.asBinder().linkToDeath(this, 0);
- } catch (RemoteException e) {
- // The caller has died, so we can just forget about this.
- try {
- if (mInputMethodManager != null) {
- mInputMethodManager.removeClient(client);
- }
- } catch (RemoteException ee) {
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- try {
- return super.onTransact(code, data, reply, flags);
- } catch (RuntimeException e) {
- // Log all 'real' exceptions thrown to the caller
- if (!(e instanceof SecurityException)) {
- Slog.e(TAG, "Window Session Crash", e);
- }
- throw e;
- }
- }
-
- public void binderDied() {
- // Note: it is safe to call in to the input method manager
- // here because we are not holding our lock.
- try {
- if (mInputMethodManager != null) {
- mInputMethodManager.removeClient(mClient);
- }
- } catch (RemoteException e) {
- }
- synchronized(mWindowMap) {
- mClient.asBinder().unlinkToDeath(this, 0);
- mClientDead = true;
- killSessionLocked();
- }
- }
-
- public int add(IWindow window, WindowManager.LayoutParams attrs,
- int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
- return addWindow(this, window, attrs, viewVisibility, outContentInsets,
- outInputChannel);
- }
-
- public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
- int viewVisibility, Rect outContentInsets) {
- return addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
- }
-
- public void remove(IWindow window) {
- removeWindow(this, window);
- }
-
- public int relayout(IWindow window, WindowManager.LayoutParams attrs,
- int requestedWidth, int requestedHeight, int viewFlags,
- boolean insetsPending, Rect outFrame, Rect outContentInsets,
- Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
- //Log.d(TAG, ">>>>>> ENTERED relayout from " + Binder.getCallingPid());
- int res = relayoutWindow(this, window, attrs,
- requestedWidth, requestedHeight, viewFlags, insetsPending,
- outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
- //Log.d(TAG, "<<<<<< EXITING relayout to " + Binder.getCallingPid());
- return res;
- }
-
- public void setTransparentRegion(IWindow window, Region region) {
- setTransparentRegionWindow(this, window, region);
- }
-
- public void setInsets(IWindow window, int touchableInsets,
- Rect contentInsets, Rect visibleInsets, Region touchableArea) {
- setInsetsWindow(this, window, touchableInsets, contentInsets,
- visibleInsets, touchableArea);
- }
-
- public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
- getWindowDisplayFrame(this, window, outDisplayFrame);
- }
-
- public void finishDrawing(IWindow window) {
- if (localLOGV) Slog.v(
- TAG, "IWindow finishDrawing called for " + window);
- finishDrawingWindow(this, window);
- }
-
- public void setInTouchMode(boolean mode) {
- synchronized(mWindowMap) {
- mInTouchMode = mode;
- }
- }
-
- public boolean getInTouchMode() {
- synchronized(mWindowMap) {
- return mInTouchMode;
- }
- }
-
- public boolean performHapticFeedback(IWindow window, int effectId,
- boolean always) {
- synchronized(mWindowMap) {
- long ident = Binder.clearCallingIdentity();
- try {
- return mPolicy.performHapticFeedbackLw(
- windowForClientLocked(this, window, true),
- effectId, always);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- /* Drag/drop */
- public IBinder prepareDrag(IWindow window, int flags,
- int width, int height, Surface outSurface) {
- return prepareDragSurface(window, mSurfaceSession, flags,
- width, height, outSurface);
- }
-
- public boolean performDrag(IWindow window, IBinder dragToken,
- float touchX, float touchY, float thumbCenterX, float thumbCenterY,
- ClipData data) {
- if (DEBUG_DRAG) {
- Slog.d(TAG, "perform drag: win=" + window + " data=" + data);
- }
-
- synchronized (mWindowMap) {
- if (mDragState == null) {
- Slog.w(TAG, "No drag prepared");
- throw new IllegalStateException("performDrag() without prepareDrag()");
- }
-
- if (dragToken != mDragState.mToken) {
- Slog.w(TAG, "Performing mismatched drag");
- throw new IllegalStateException("performDrag() does not match prepareDrag()");
- }
-
- WindowState callingWin = windowForClientLocked(null, window, false);
- if (callingWin == null) {
- Slog.w(TAG, "Bad requesting window " + window);
- return false; // !!! TODO: throw here?
- }
-
- // !!! TODO: if input is not still focused on the initiating window, fail
- // the drag initiation (e.g. an alarm window popped up just as the application
- // called performDrag()
-
- mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
-
- // !!! TODO: extract the current touch (x, y) in screen coordinates. That
- // will let us eliminate the (touchX,touchY) parameters from the API.
-
- // !!! FIXME: put all this heavy stuff onto the mH looper, as well as
- // the actual drag event dispatch stuff in the dragstate
-
- mDragState.register();
- mInputMonitor.updateInputWindowsLw(true /*force*/);
- if (!mInputManager.transferTouchFocus(callingWin.mInputChannel,
- mDragState.mServerChannel)) {
- Slog.e(TAG, "Unable to transfer touch focus");
- mDragState.unregister();
- mDragState = null;
- mInputMonitor.updateInputWindowsLw(true /*force*/);
- return false;
- }
-
- mDragState.mData = data;
- mDragState.mCurrentX = touchX;
- mDragState.mCurrentY = touchY;
- mDragState.broadcastDragStartedLw(touchX, touchY);
-
- // remember the thumb offsets for later
- mDragState.mThumbOffsetX = thumbCenterX;
- mDragState.mThumbOffsetY = thumbCenterY;
-
- // Make the surface visible at the proper location
- final Surface surface = mDragState.mSurface;
- if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performDrag");
- Surface.openTransaction();
- try {
- surface.setPosition((int)(touchX - thumbCenterX),
- (int)(touchY - thumbCenterY));
- surface.setAlpha(.7071f);
- surface.setLayer(mDragState.getDragLayerLw());
- surface.show();
- } finally {
- Surface.closeTransaction();
- if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION performDrag");
- }
- }
-
- return true; // success!
- }
-
- public void reportDropResult(IWindow window, boolean consumed) {
- IBinder token = window.asBinder();
- if (DEBUG_DRAG) {
- Slog.d(TAG, "Drop result=" + consumed + " reported by " + token);
- }
-
- synchronized (mWindowMap) {
- long ident = Binder.clearCallingIdentity();
- try {
- if (mDragState == null || mDragState.mToken != token) {
- Slog.w(TAG, "Invalid drop-result claim by " + window);
- throw new IllegalStateException("reportDropResult() by non-recipient");
- }
-
- // The right window has responded, even if it's no longer around,
- // so be sure to halt the timeout even if the later WindowState
- // lookup fails.
- mH.removeMessages(H.DRAG_END_TIMEOUT, window.asBinder());
- WindowState callingWin = windowForClientLocked(null, window, false);
- if (callingWin == null) {
- Slog.w(TAG, "Bad result-reporting window " + window);
- return; // !!! TODO: throw here?
- }
-
- mDragState.mDragResult = consumed;
- mDragState.endDragLw();
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- public void dragRecipientEntered(IWindow window) {
- if (DEBUG_DRAG) {
- Slog.d(TAG, "Drag into new candidate view @ " + window.asBinder());
- }
- }
-
- public void dragRecipientExited(IWindow window) {
- if (DEBUG_DRAG) {
- Slog.d(TAG, "Drag from old candidate view @ " + window.asBinder());
- }
- }
-
- public void setWallpaperPosition(IBinder window, float x, float y, float xStep, float yStep) {
- synchronized(mWindowMap) {
- long ident = Binder.clearCallingIdentity();
- try {
- setWindowWallpaperPositionLocked(
- windowForClientLocked(this, window, true),
- x, y, xStep, yStep);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- public void wallpaperOffsetsComplete(IBinder window) {
- WindowManagerService.this.wallpaperOffsetsComplete(window);
- }
-
- public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
- int z, Bundle extras, boolean sync) {
- synchronized(mWindowMap) {
- long ident = Binder.clearCallingIdentity();
- try {
- return sendWindowWallpaperCommandLocked(
- windowForClientLocked(this, window, true),
- action, x, y, z, extras, sync);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- public void wallpaperCommandComplete(IBinder window, Bundle result) {
- WindowManagerService.this.wallpaperCommandComplete(window, result);
- }
-
- void windowAddedLocked() {
- if (mSurfaceSession == null) {
- if (localLOGV) Slog.v(
- TAG, "First window added to " + this + ", creating SurfaceSession");
- mSurfaceSession = new SurfaceSession();
- if (SHOW_TRANSACTIONS) Slog.i(
- TAG, " NEW SURFACE SESSION " + mSurfaceSession);
- mSessions.add(this);
- }
- mNumWindow++;
- }
-
- void windowRemovedLocked() {
- mNumWindow--;
- killSessionLocked();
- }
-
- void killSessionLocked() {
- if (mNumWindow <= 0 && mClientDead) {
- mSessions.remove(this);
- if (mSurfaceSession != null) {
- if (localLOGV) Slog.v(
- TAG, "Last window removed from " + this
- + ", destroying " + mSurfaceSession);
- if (SHOW_TRANSACTIONS) Slog.i(
- TAG, " KILL SURFACE SESSION " + mSurfaceSession);
- try {
- mSurfaceSession.kill();
- } catch (Exception e) {
- Slog.w(TAG, "Exception thrown when killing surface session "
- + mSurfaceSession + " in session " + this
- + ": " + e.toString());
- }
- mSurfaceSession = null;
- }
- }
- }
-
- void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
- pw.print(" mClientDead="); pw.print(mClientDead);
- pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
- }
-
- @Override
- public String toString() {
- return mStringName;
- }
- }
-
- // -------------------------------------------------------------
- // Client Window State
- // -------------------------------------------------------------
-
- private final class WindowState implements WindowManagerPolicy.WindowState {
- final Session mSession;
- final IWindow mClient;
- WindowToken mToken;
- WindowToken mRootToken;
- AppWindowToken mAppToken;
- AppWindowToken mTargetAppToken;
- final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
- final DeathRecipient mDeathRecipient;
- final WindowState mAttachedWindow;
- final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
- final int mBaseLayer;
- final int mSubLayer;
- final boolean mLayoutAttached;
- final boolean mIsImWindow;
- final boolean mIsWallpaper;
- final boolean mIsFloatingLayer;
- int mViewVisibility;
- boolean mPolicyVisibility = true;
- boolean mPolicyVisibilityAfterAnim = true;
- boolean mAppFreezing;
- Surface mSurface;
- boolean mReportDestroySurface;
- boolean mSurfacePendingDestroy;
- boolean mAttachedHidden; // is our parent window hidden?
- boolean mLastHidden; // was this window last hidden?
- boolean mWallpaperVisible; // for wallpaper, what was last vis report?
- int mRequestedWidth;
- int mRequestedHeight;
- int mLastRequestedWidth;
- int mLastRequestedHeight;
- int mLayer;
- int mAnimLayer;
- int mLastLayer;
- boolean mHaveFrame;
- boolean mObscured;
- boolean mTurnOnScreen;
-
- int mLayoutSeq = -1;
-
- Configuration mConfiguration = null;
-
- // Actual frame shown on-screen (may be modified by animation)
- final Rect mShownFrame = new Rect();
- final Rect mLastShownFrame = new Rect();
-
- /**
- * Set when we have changed the size of the surface, to know that
- * we must tell them application to resize (and thus redraw itself).
- */
- boolean mSurfaceResized;
-
- /**
- * Insets that determine the actually visible area
- */
- final Rect mVisibleInsets = new Rect();
- final Rect mLastVisibleInsets = new Rect();
- boolean mVisibleInsetsChanged;
-
- /**
- * Insets that are covered by system windows
- */
- final Rect mContentInsets = new Rect();
- final Rect mLastContentInsets = new Rect();
- boolean mContentInsetsChanged;
-
- /**
- * Set to true if we are waiting for this window to receive its
- * given internal insets before laying out other windows based on it.
- */
- boolean mGivenInsetsPending;
-
- /**
- * These are the content insets that were given during layout for
- * this window, to be applied to windows behind it.
- */
- final Rect mGivenContentInsets = new Rect();
-
- /**
- * These are the visible insets that were given during layout for
- * this window, to be applied to windows behind it.
- */
- final Rect mGivenVisibleInsets = new Rect();
-
- /**
- * This is the given touchable area relative to the window frame, or null if none.
- */
- final Region mGivenTouchableRegion = new Region();
-
- /**
- * Flag indicating whether the touchable region should be adjusted by
- * the visible insets; if false the area outside the visible insets is
- * NOT touchable, so we must use those to adjust the frame during hit
- * tests.
- */
- int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
-
- // Current transformation being applied.
- boolean mHaveMatrix;
- float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
- float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
- float mHScale=1, mVScale=1;
- float mLastHScale=1, mLastVScale=1;
- final Matrix mTmpMatrix = new Matrix();
-
- // "Real" frame that the application sees.
- final Rect mFrame = new Rect();
- final Rect mLastFrame = new Rect();
-
- final Rect mContainingFrame = new Rect();
- final Rect mDisplayFrame = new Rect();
- final Rect mContentFrame = new Rect();
- final Rect mParentFrame = new Rect();
- final Rect mVisibleFrame = new Rect();
-
- boolean mContentChanged;
-
- float mShownAlpha = 1;
- float mAlpha = 1;
- float mLastAlpha = 1;
-
- // Set to true if, when the window gets displayed, it should perform
- // an enter animation.
- boolean mEnterAnimationPending;
-
- // Currently running animation.
- boolean mAnimating;
- boolean mLocalAnimating;
- Animation mAnimation;
- boolean mAnimationIsEntrance;
- boolean mHasTransformation;
- boolean mHasLocalTransformation;
- final Transformation mTransformation = new Transformation();
-
- // If a window showing a wallpaper: the requested offset for the
- // wallpaper; if a wallpaper window: the currently applied offset.
- float mWallpaperX = -1;
- float mWallpaperY = -1;
-
- // If a window showing a wallpaper: what fraction of the offset
- // range corresponds to a full virtual screen.
- float mWallpaperXStep = -1;
- float mWallpaperYStep = -1;
-
- // Wallpaper windows: pixels offset based on above variables.
- int mXOffset;
- int mYOffset;
-
- // This is set after IWindowSession.relayout() has been called at
- // least once for the window. It allows us to detect the situation
- // where we don't yet have a surface, but should have one soon, so
- // we can give the window focus before waiting for the relayout.
- boolean mRelayoutCalled;
-
- // This is set after the Surface has been created but before the
- // window has been drawn. During this time the surface is hidden.
- boolean mDrawPending;
-
- // This is set after the window has finished drawing for the first
- // time but before its surface is shown. The surface will be
- // displayed when the next layout is run.
- boolean mCommitDrawPending;
-
- // This is set during the time after the window's drawing has been
- // committed, and before its surface is actually shown. It is used
- // to delay showing the surface until all windows in a token are ready
- // to be shown.
- boolean mReadyToShow;
-
- // Set when the window has been shown in the screen the first time.
- boolean mHasDrawn;
-
- // Currently running an exit animation?
- boolean mExiting;
-
- // Currently on the mDestroySurface list?
- boolean mDestroying;
-
- // Completely remove from window manager after exit animation?
- boolean mRemoveOnExit;
-
- // Set when the orientation is changing and this window has not yet
- // been updated for the new orientation.
- boolean mOrientationChanging;
-
- // Is this window now (or just being) removed?
- boolean mRemoved;
-
- // Temp for keeping track of windows that have been removed when
- // rebuilding window list.
- boolean mRebuilding;
-
- // For debugging, this is the last information given to the surface flinger.
- boolean mSurfaceShown;
- int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
- int mSurfaceLayer;
- float mSurfaceAlpha;
-
- // Input channel and input window handle used by the input dispatcher.
- InputWindowHandle mInputWindowHandle;
- InputChannel mInputChannel;
-
- // Used to improve performance of toString()
- String mStringNameCache;
- CharSequence mLastTitle;
- boolean mWasPaused;
-
- WindowState(Session s, IWindow c, WindowToken token,
- WindowState attachedWindow, WindowManager.LayoutParams a,
- int viewVisibility) {
- mSession = s;
- mClient = c;
- mToken = token;
- mAttrs.copyFrom(a);
- mViewVisibility = viewVisibility;
- DeathRecipient deathRecipient = new DeathRecipient();
- mAlpha = a.alpha;
- if (localLOGV) Slog.v(
- TAG, "Window " + this + " client=" + c.asBinder()
- + " token=" + token + " (" + mAttrs.token + ")");
- try {
- c.asBinder().linkToDeath(deathRecipient, 0);
- } catch (RemoteException e) {
- mDeathRecipient = null;
- mAttachedWindow = null;
- mLayoutAttached = false;
- mIsImWindow = false;
- mIsWallpaper = false;
- mIsFloatingLayer = false;
- mBaseLayer = 0;
- mSubLayer = 0;
- return;
- }
- mDeathRecipient = deathRecipient;
-
- if ((mAttrs.type >= FIRST_SUB_WINDOW &&
- mAttrs.type <= LAST_SUB_WINDOW)) {
- // The multiplier here is to reserve space for multiple
- // windows in the same type layer.
- mBaseLayer = mPolicy.windowTypeToLayerLw(
- attachedWindow.mAttrs.type) * TYPE_LAYER_MULTIPLIER
- + TYPE_LAYER_OFFSET;
- mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
- mAttachedWindow = attachedWindow;
- if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow);
- mAttachedWindow.mChildWindows.add(this);
- mLayoutAttached = mAttrs.type !=
- WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
- mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
- || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
- mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
- mIsFloatingLayer = mIsImWindow || mIsWallpaper;
- } else {
- // The multiplier here is to reserve space for multiple
- // windows in the same type layer.
- mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
- * TYPE_LAYER_MULTIPLIER
- + TYPE_LAYER_OFFSET;
- mSubLayer = 0;
- mAttachedWindow = null;
- mLayoutAttached = false;
- mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
- || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
- mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
- mIsFloatingLayer = mIsImWindow || mIsWallpaper;
- }
-
- WindowState appWin = this;
- while (appWin.mAttachedWindow != null) {
- appWin = mAttachedWindow;
- }
- WindowToken appToken = appWin.mToken;
- while (appToken.appWindowToken == null) {
- WindowToken parent = mTokenMap.get(appToken.token);
- if (parent == null || appToken == parent) {
- break;
- }
- appToken = parent;
- }
- mRootToken = appToken;
- mAppToken = appToken.appWindowToken;
-
- mSurface = null;
- mRequestedWidth = 0;
- mRequestedHeight = 0;
- mLastRequestedWidth = 0;
- mLastRequestedHeight = 0;
- mXOffset = 0;
- mYOffset = 0;
- mLayer = 0;
- mAnimLayer = 0;
- mLastLayer = 0;
- mInputWindowHandle = new InputWindowHandle(
- mAppToken != null ? mAppToken.mInputApplicationHandle : null, this);
- }
-
- void attach() {
- if (localLOGV) Slog.v(
- TAG, "Attaching " + this + " token=" + mToken
- + ", list=" + mToken.windows);
- mSession.windowAddedLocked();
- }
-
- public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
- mHaveFrame = true;
-
- final Rect container = mContainingFrame;
- container.set(pf);
-
- final Rect display = mDisplayFrame;
- display.set(df);
-
- if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
- container.intersect(mCompatibleScreenFrame);
- if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
- display.intersect(mCompatibleScreenFrame);
- }
- }
-
- final int pw = container.right - container.left;
- final int ph = container.bottom - container.top;
-
- int w,h;
- if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
- w = mAttrs.width < 0 ? pw : mAttrs.width;
- h = mAttrs.height< 0 ? ph : mAttrs.height;
- } else {
- w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
- h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
- }
-
- if (!mParentFrame.equals(pf)) {
- //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
- // + " to " + pf);
- mParentFrame.set(pf);
- mContentChanged = true;
- }
-
- final Rect content = mContentFrame;
- content.set(cf);
-
- final Rect visible = mVisibleFrame;
- visible.set(vf);
-
- final Rect frame = mFrame;
- final int fw = frame.width();
- final int fh = frame.height();
-
- //System.out.println("In: w=" + w + " h=" + h + " container=" +
- // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
-
- Gravity.apply(mAttrs.gravity, w, h, container,
- (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
- (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
-
- //System.out.println("Out: " + mFrame);
-
- // Now make sure the window fits in the overall display.
- Gravity.applyDisplay(mAttrs.gravity, df, frame);
-
- // Make sure the content and visible frames are inside of the
- // final window frame.
- if (content.left < frame.left) content.left = frame.left;
- if (content.top < frame.top) content.top = frame.top;
- if (content.right > frame.right) content.right = frame.right;
- if (content.bottom > frame.bottom) content.bottom = frame.bottom;
- if (visible.left < frame.left) visible.left = frame.left;
- if (visible.top < frame.top) visible.top = frame.top;
- if (visible.right > frame.right) visible.right = frame.right;
- if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
-
- final Rect contentInsets = mContentInsets;
- contentInsets.left = content.left-frame.left;
- contentInsets.top = content.top-frame.top;
- contentInsets.right = frame.right-content.right;
- contentInsets.bottom = frame.bottom-content.bottom;
-
- final Rect visibleInsets = mVisibleInsets;
- visibleInsets.left = visible.left-frame.left;
- visibleInsets.top = visible.top-frame.top;
- visibleInsets.right = frame.right-visible.right;
- visibleInsets.bottom = frame.bottom-visible.bottom;
-
- if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
- updateWallpaperOffsetLocked(this, mDisplay.getWidth(),
- mDisplay.getHeight(), false);
- }
-
- if (localLOGV) {
- //if ("com.google.android.youtube".equals(mAttrs.packageName)
- // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
- Slog.v(TAG, "Resolving (mRequestedWidth="
- + mRequestedWidth + ", mRequestedheight="
- + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
- + "): frame=" + mFrame.toShortString()
- + " ci=" + contentInsets.toShortString()
- + " vi=" + visibleInsets.toShortString());
- //}
- }
- }
-
- public Rect getFrameLw() {
- return mFrame;
- }
-
- public Rect getShownFrameLw() {
- return mShownFrame;
- }
-
- public Rect getDisplayFrameLw() {
- return mDisplayFrame;
- }
-
- public Rect getContentFrameLw() {
- return mContentFrame;
- }
-
- public Rect getVisibleFrameLw() {
- return mVisibleFrame;
- }
-
- public boolean getGivenInsetsPendingLw() {
- return mGivenInsetsPending;
- }
-
- public Rect getGivenContentInsetsLw() {
- return mGivenContentInsets;
- }
-
- public Rect getGivenVisibleInsetsLw() {
- return mGivenVisibleInsets;
- }
-
- public WindowManager.LayoutParams getAttrs() {
- return mAttrs;
- }
-
- public int getSurfaceLayer() {
- return mLayer;
- }
-
- public IApplicationToken getAppToken() {
- return mAppToken != null ? mAppToken.appToken : null;
- }
-
- public long getInputDispatchingTimeoutNanos() {
- return mAppToken != null
- ? mAppToken.inputDispatchingTimeoutNanos
- : DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
- }
-
- public boolean hasAppShownWindows() {
- return mAppToken != null ? mAppToken.firstWindowDrawn : false;
- }
-
- public void setAnimation(Animation anim) {
- if (localLOGV) Slog.v(
- TAG, "Setting animation in " + this + ": " + anim);
- mAnimating = false;
- mLocalAnimating = false;
- mAnimation = anim;
- mAnimation.restrictDuration(MAX_ANIMATION_DURATION);
- mAnimation.scaleCurrentDuration(mWindowAnimationScale);
- }
-
- public void clearAnimation() {
- if (mAnimation != null) {
- mAnimating = true;
- mLocalAnimating = false;
- mAnimation.cancel();
- mAnimation = null;
- }
- }
-
- Surface createSurfaceLocked() {
- if (mSurface == null) {
- mReportDestroySurface = false;
- mSurfacePendingDestroy = false;
- mDrawPending = true;
- mCommitDrawPending = false;
- mReadyToShow = false;
- if (mAppToken != null) {
- mAppToken.allDrawn = false;
- }
-
- int flags = 0;
-
- if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
- flags |= Surface.SECURE;
- }
- if (DEBUG_VISIBILITY) Slog.v(
- TAG, "Creating surface in session "
- + mSession.mSurfaceSession + " window " + this
- + " w=" + mFrame.width()
- + " h=" + mFrame.height() + " format="
- + mAttrs.format + " flags=" + flags);
-
- int w = mFrame.width();
- int h = mFrame.height();
- if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
- // for a scaled surface, we always want the requested
- // size.
- w = mRequestedWidth;
- h = mRequestedHeight;
- }
-
- // Something is wrong and SurfaceFlinger will not like this,
- // try to revert to sane values
- if (w <= 0) w = 1;
- if (h <= 0) h = 1;
-
- mSurfaceShown = false;
- mSurfaceLayer = 0;
- mSurfaceAlpha = 1;
- mSurfaceX = 0;
- mSurfaceY = 0;
- mSurfaceW = w;
- mSurfaceH = h;
- try {
- final boolean isHwAccelerated = (mAttrs.flags &
- WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
- final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format;
- if (isHwAccelerated && mAttrs.format == PixelFormat.OPAQUE) {
- flags |= Surface.OPAQUE;
- }
- mSurface = new Surface(
- mSession.mSurfaceSession, mSession.mPid,
- mAttrs.getTitle().toString(),
- 0, w, h, format, flags);
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " CREATE SURFACE "
- + mSurface + " IN SESSION "
- + mSession.mSurfaceSession
- + ": pid=" + mSession.mPid + " format="
- + mAttrs.format + " flags=0x"
- + Integer.toHexString(flags)
- + " / " + this);
- } catch (Surface.OutOfResourcesException e) {
- Slog.w(TAG, "OutOfResourcesException creating surface");
- reclaimSomeSurfaceMemoryLocked(this, "create");
- return null;
- } catch (Exception e) {
- Slog.e(TAG, "Exception creating surface", e);
- return null;
- }
-
- if (localLOGV) Slog.v(
- TAG, "Got surface: " + mSurface
- + ", set left=" + mFrame.left + " top=" + mFrame.top
- + ", animLayer=" + mAnimLayer);
- if (SHOW_TRANSACTIONS) {
- Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
- logSurface(this, "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
- mFrame.width() + "x" + mFrame.height() + "), layer=" +
- mAnimLayer + " HIDE", null);
- }
- Surface.openTransaction();
- try {
- try {
- mSurfaceX = mFrame.left + mXOffset;
- mSurfaceY = mFrame.top + mYOffset;
- mSurface.setPosition(mSurfaceX, mSurfaceY);
- mSurfaceLayer = mAnimLayer;
- mSurface.setLayer(mAnimLayer);
- mSurfaceShown = false;
- mSurface.hide();
- if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
- if (SHOW_TRANSACTIONS) logSurface(this, "DITHER", null);
- mSurface.setFlags(Surface.SURFACE_DITHER,
- Surface.SURFACE_DITHER);
- }
- } catch (RuntimeException e) {
- Slog.w(TAG, "Error creating surface in " + w, e);
- reclaimSomeSurfaceMemoryLocked(this, "create-init");
- }
- mLastHidden = true;
- } finally {
- Surface.closeTransaction();
- if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION createSurfaceLocked");
- }
- if (localLOGV) Slog.v(
- TAG, "Created surface " + this);
- }
- return mSurface;
- }
-
- void destroySurfaceLocked() {
- if (mAppToken != null && this == mAppToken.startingWindow) {
- mAppToken.startingDisplayed = false;
- }
-
- if (mSurface != null) {
- mDrawPending = false;
- mCommitDrawPending = false;
- mReadyToShow = false;
-
- int i = mChildWindows.size();
- while (i > 0) {
- i--;
- WindowState c = mChildWindows.get(i);
- c.mAttachedHidden = true;
- }
-
- if (mReportDestroySurface) {
- mReportDestroySurface = false;
- mSurfacePendingDestroy = true;
- try {
- mClient.dispatchGetNewSurface();
- // We'll really destroy on the next time around.
- return;
- } catch (RemoteException e) {
- }
- }
-
- try {
- if (DEBUG_VISIBILITY) {
- RuntimeException e = null;
- if (!HIDE_STACK_CRAWLS) {
- e = new RuntimeException();
- e.fillInStackTrace();
- }
- Slog.w(TAG, "Window " + this + " destroying surface "
- + mSurface + ", session " + mSession, e);
- }
- if (SHOW_TRANSACTIONS) {
- RuntimeException e = null;
- if (!HIDE_STACK_CRAWLS) {
- e = new RuntimeException();
- e.fillInStackTrace();
- }
- if (SHOW_TRANSACTIONS) logSurface(this, "DESTROY", e);
- }
- mSurface.destroy();
- } catch (RuntimeException e) {
- Slog.w(TAG, "Exception thrown when destroying Window " + this
- + " surface " + mSurface + " session " + mSession
- + ": " + e.toString());
- }
-
- mSurfaceShown = false;
- mSurface = null;
- }
- }
-
- boolean finishDrawingLocked() {
- if (mDrawPending) {
- if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) Slog.v(
- TAG, "finishDrawingLocked: " + mSurface);
- mCommitDrawPending = true;
- mDrawPending = false;
- return true;
- }
- return false;
- }
-
- // This must be called while inside a transaction.
- boolean commitFinishDrawingLocked(long currentTime) {
- //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
- if (!mCommitDrawPending) {
- return false;
- }
- mCommitDrawPending = false;
- mReadyToShow = true;
- final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
- final AppWindowToken atoken = mAppToken;
- if (atoken == null || atoken.allDrawn || starting) {
- performShowLocked();
- }
- return true;
- }
-
- // This must be called while inside a transaction.
- boolean performShowLocked() {
- if (DEBUG_VISIBILITY) {
- RuntimeException e = null;
- if (!HIDE_STACK_CRAWLS) {
- e = new RuntimeException();
- e.fillInStackTrace();
- }
- Slog.v(TAG, "performShow on " + this
- + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
- + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
- }
- if (mReadyToShow && isReadyForDisplay()) {
- if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION) logSurface(this,
- "SHOW (performShowLocked)", null);
- if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
- + " during animation: policyVis=" + mPolicyVisibility
- + " attHidden=" + mAttachedHidden
- + " tok.hiddenRequested="
- + (mAppToken != null ? mAppToken.hiddenRequested : false)
- + " tok.hidden="
- + (mAppToken != null ? mAppToken.hidden : false)
- + " animating=" + mAnimating
- + " tok animating="
- + (mAppToken != null ? mAppToken.animating : false));
- if (!showSurfaceRobustlyLocked(this)) {
- return false;
- }
- mLastAlpha = -1;
- mHasDrawn = true;
- mLastHidden = false;
- mReadyToShow = false;
- enableScreenIfNeededLocked();
-
- applyEnterAnimationLocked(this);
-
- int i = mChildWindows.size();
- while (i > 0) {
- i--;
- WindowState c = mChildWindows.get(i);
- if (c.mAttachedHidden) {
- c.mAttachedHidden = false;
- if (c.mSurface != null) {
- c.performShowLocked();
- // It hadn't been shown, which means layout not
- // performed on it, so now we want to make sure to
- // do a layout. If called from within the transaction
- // loop, this will cause it to restart with a new
- // layout.
- mLayoutNeeded = true;
- }
- }
- }
-
- if (mAttrs.type != TYPE_APPLICATION_STARTING
- && mAppToken != null) {
- mAppToken.firstWindowDrawn = true;
-
- if (mAppToken.startingData != null) {
- if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Slog.v(TAG,
- "Finish starting " + mToken
- + ": first real window is shown, no animation");
- // If this initial window is animating, stop it -- we
- // will do an animation to reveal it from behind the
- // starting window, so there is no need for it to also
- // be doing its own stuff.
- if (mAnimation != null) {
- mAnimation.cancel();
- mAnimation = null;
- // Make sure we clean up the animation.
- mAnimating = true;
- }
- mFinishedStarting.add(mAppToken);
- mH.sendEmptyMessage(H.FINISHED_STARTING);
- }
- mAppToken.updateReportedVisibilityLocked();
- }
- }
- return true;
- }
-
- // This must be called while inside a transaction. Returns true if
- // there is more animation to run.
- boolean stepAnimationLocked(long currentTime, int dw, int dh) {
- if (!mDisplayFrozen && mPolicy.isScreenOn()) {
- // We will run animations as long as the display isn't frozen.
-
- if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
- mHasTransformation = true;
- mHasLocalTransformation = true;
- if (!mLocalAnimating) {
- if (DEBUG_ANIM) Slog.v(
- TAG, "Starting animation in " + this +
- " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
- " dw=" + dw + " dh=" + dh + " scale=" + mWindowAnimationScale);
- mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
- mAnimation.setStartTime(currentTime);
- mLocalAnimating = true;
- mAnimating = true;
- }
- mTransformation.clear();
- final boolean more = mAnimation.getTransformation(
- currentTime, mTransformation);
- if (DEBUG_ANIM) Slog.v(
- TAG, "Stepped animation in " + this +
- ": more=" + more + ", xform=" + mTransformation);
- if (more) {
- // we're not done!
- return true;
- }
- if (DEBUG_ANIM) Slog.v(
- TAG, "Finished animation in " + this +
- " @ " + currentTime);
-
- if (mAnimation != null) {
- mAnimation.cancel();
- mAnimation = null;
- }
- //WindowManagerService.this.dump();
- }
- mHasLocalTransformation = false;
- if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
- && mAppToken.animation != null) {
- // When our app token is animating, we kind-of pretend like
- // we are as well. Note the mLocalAnimating mAnimationIsEntrance
- // part of this check means that we will only do this if
- // our window is not currently exiting, or it is not
- // locally animating itself. The idea being that one that
- // is exiting and doing a local animation should be removed
- // once that animation is done.
- mAnimating = true;
- mHasTransformation = true;
- mTransformation.clear();
- return false;
- } else if (mHasTransformation) {
- // Little trick to get through the path below to act like
- // we have finished an animation.
- mAnimating = true;
- } else if (isAnimating()) {
- mAnimating = true;
- }
- } else if (mAnimation != null) {
- // If the display is frozen, and there is a pending animation,
- // clear it and make sure we run the cleanup code.
- mAnimating = true;
- mLocalAnimating = true;
- mAnimation.cancel();
- mAnimation = null;
- }
-
- if (!mAnimating && !mLocalAnimating) {
- return false;
- }
-
- if (DEBUG_ANIM) Slog.v(
- TAG, "Animation done in " + this + ": exiting=" + mExiting
- + ", reportedVisible="
- + (mAppToken != null ? mAppToken.reportedVisible : false));
-
- mAnimating = false;
- mLocalAnimating = false;
- if (mAnimation != null) {
- mAnimation.cancel();
- mAnimation = null;
- }
- mAnimLayer = mLayer;
- if (mIsImWindow) {
- mAnimLayer += mInputMethodAnimLayerAdjustment;
- } else if (mIsWallpaper) {
- mAnimLayer += mWallpaperAnimLayerAdjustment;
- }
- if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
- + " anim layer: " + mAnimLayer);
- mHasTransformation = false;
- mHasLocalTransformation = false;
- if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
- if (DEBUG_VISIBILITY) {
- Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
- + mPolicyVisibilityAfterAnim);
- }
- mPolicyVisibility = mPolicyVisibilityAfterAnim;
- if (!mPolicyVisibility) {
- if (mCurrentFocus == this) {
- mFocusMayChange = true;
- }
- // Window is no longer visible -- make sure if we were waiting
- // for it to be displayed before enabling the display, that
- // we allow the display to be enabled now.
- enableScreenIfNeededLocked();
- }
- }
- mTransformation.clear();
- if (mHasDrawn
- && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
- && mAppToken != null
- && mAppToken.firstWindowDrawn
- && mAppToken.startingData != null) {
- if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
- + mToken + ": first real window done animating");
- mFinishedStarting.add(mAppToken);
- mH.sendEmptyMessage(H.FINISHED_STARTING);
- }
-
- finishExit();
-
- if (mAppToken != null) {
- mAppToken.updateReportedVisibilityLocked();
- }
-
- return false;
- }
-
- void finishExit() {
- if (DEBUG_ANIM) Slog.v(
- TAG, "finishExit in " + this
- + ": exiting=" + mExiting
- + " remove=" + mRemoveOnExit
- + " windowAnimating=" + isWindowAnimating());
-
- final int N = mChildWindows.size();
- for (int i=0; i<N; i++) {
- mChildWindows.get(i).finishExit();
- }
-
- if (!mExiting) {
- return;
- }
-
- if (isWindowAnimating()) {
- return;
- }
-
- if (localLOGV) Slog.v(
- TAG, "Exit animation finished in " + this
- + ": remove=" + mRemoveOnExit);
- if (mSurface != null) {
- mDestroySurface.add(this);
- mDestroying = true;
- if (SHOW_TRANSACTIONS) logSurface(this, "HIDE (finishExit)", null);
- mSurfaceShown = false;
- try {
- mSurface.hide();
- } catch (RuntimeException e) {
- Slog.w(TAG, "Error hiding surface in " + this, e);
- }
- mLastHidden = true;
- }
- mExiting = false;
- if (mRemoveOnExit) {
- mPendingRemove.add(this);
- mRemoveOnExit = false;
- }
- }
-
- boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
- if (dsdx < .99999f || dsdx > 1.00001f) return false;
- if (dtdy < .99999f || dtdy > 1.00001f) return false;
- if (dtdx < -.000001f || dtdx > .000001f) return false;
- if (dsdy < -.000001f || dsdy > .000001f) return false;
- return true;
- }
-
- void computeShownFrameLocked() {
- final boolean selfTransformation = mHasLocalTransformation;
- Transformation attachedTransformation =
- (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
- ? mAttachedWindow.mTransformation : null;
- Transformation appTransformation =
- (mAppToken != null && mAppToken.hasTransformation)
- ? mAppToken.transformation : null;
-
- // Wallpapers are animated based on the "real" window they
- // are currently targeting.
- if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
- && mWallpaperTarget != null) {
- if (mWallpaperTarget.mHasLocalTransformation &&
- mWallpaperTarget.mAnimation != null &&
- !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
- attachedTransformation = mWallpaperTarget.mTransformation;
- if (DEBUG_WALLPAPER && attachedTransformation != null) {
- Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
- }
- }
- if (mWallpaperTarget.mAppToken != null &&
- mWallpaperTarget.mAppToken.hasTransformation &&
- mWallpaperTarget.mAppToken.animation != null &&
- !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
- appTransformation = mWallpaperTarget.mAppToken.transformation;
- if (DEBUG_WALLPAPER && appTransformation != null) {
- Slog.v(TAG, "WP target app xform: " + appTransformation);
- }
- }
- }
-
- final boolean screenAnimation = mScreenRotationAnimation != null
- && mScreenRotationAnimation.isAnimating();
- if (selfTransformation || attachedTransformation != null
- || appTransformation != null || screenAnimation) {
- // cache often used attributes locally
- final Rect frame = mFrame;
- final float tmpFloats[] = mTmpFloats;
- final Matrix tmpMatrix = mTmpMatrix;
-
- // Compute the desired transformation.
- tmpMatrix.setTranslate(0, 0);
- if (selfTransformation) {
- tmpMatrix.postConcat(mTransformation.getMatrix());
- }
- tmpMatrix.postTranslate(frame.left + mXOffset, frame.top + mYOffset);
- if (attachedTransformation != null) {
- tmpMatrix.postConcat(attachedTransformation.getMatrix());
- }
- if (appTransformation != null) {
- tmpMatrix.postConcat(appTransformation.getMatrix());
- }
- if (screenAnimation) {
- tmpMatrix.postConcat(
- mScreenRotationAnimation.getEnterTransformation().getMatrix());
- }
-
- // "convert" it into SurfaceFlinger's format
- // (a 2x2 matrix + an offset)
- // Here we must not transform the position of the surface
- // since it is already included in the transformation.
- //Slog.i(TAG, "Transform: " + matrix);
-
- mHaveMatrix = true;
- tmpMatrix.getValues(tmpFloats);
- mDsDx = tmpFloats[Matrix.MSCALE_X];
- mDtDx = tmpFloats[Matrix.MSKEW_Y];
- mDsDy = tmpFloats[Matrix.MSKEW_X];
- mDtDy = tmpFloats[Matrix.MSCALE_Y];
- int x = (int)tmpFloats[Matrix.MTRANS_X];
- int y = (int)tmpFloats[Matrix.MTRANS_Y];
- int w = frame.width();
- int h = frame.height();
- mShownFrame.set(x, y, x+w, y+h);
-
- // Now set the alpha... but because our current hardware
- // can't do alpha transformation on a non-opaque surface,
- // turn it off if we are running an animation that is also
- // transforming since it is more important to have that
- // animation be smooth.
- mShownAlpha = mAlpha;
- if (!mLimitedAlphaCompositing
- || (!PixelFormat.formatHasAlpha(mAttrs.format)
- || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
- && x == frame.left && y == frame.top))) {
- //Slog.i(TAG, "Applying alpha transform");
- if (selfTransformation) {
- mShownAlpha *= mTransformation.getAlpha();
- }
- if (attachedTransformation != null) {
- mShownAlpha *= attachedTransformation.getAlpha();
- }
- if (appTransformation != null) {
- mShownAlpha *= appTransformation.getAlpha();
- }
- if (screenAnimation) {
- mShownAlpha *=
- mScreenRotationAnimation.getEnterTransformation().getAlpha();
- }
- } else {
- //Slog.i(TAG, "Not applying alpha transform");
- }
-
- if (localLOGV) Slog.v(
- TAG, "Continuing animation in " + this +
- ": " + mShownFrame +
- ", alpha=" + mTransformation.getAlpha());
- return;
- }
-
- mShownFrame.set(mFrame);
- if (mXOffset != 0 || mYOffset != 0) {
- mShownFrame.offset(mXOffset, mYOffset);
- }
- mShownAlpha = mAlpha;
- mHaveMatrix = false;
- mDsDx = 1;
- mDtDx = 0;
- mDsDy = 0;
- mDtDy = 1;
- }
-
- /**
- * Is this window visible? It is not visible if there is no
- * surface, or we are in the process of running an exit animation
- * that will remove the surface, or its app token has been hidden.
- */
- public boolean isVisibleLw() {
- final AppWindowToken atoken = mAppToken;
- return mSurface != null && mPolicyVisibility && !mAttachedHidden
- && (atoken == null || !atoken.hiddenRequested)
- && !mExiting && !mDestroying;
- }
-
- /**
- * Like {@link #isVisibleLw}, but also counts a window that is currently
- * "hidden" behind the keyguard as visible. This allows us to apply
- * things like window flags that impact the keyguard.
- * XXX I am starting to think we need to have ANOTHER visibility flag
- * for this "hidden behind keyguard" state rather than overloading
- * mPolicyVisibility. Ungh.
- */
- public boolean isVisibleOrBehindKeyguardLw() {
- final AppWindowToken atoken = mAppToken;
- return mSurface != null && !mAttachedHidden
- && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
- && !mDrawPending && !mCommitDrawPending
- && !mExiting && !mDestroying;
- }
-
- /**
- * Is this window visible, ignoring its app token? It is not visible
- * if there is no surface, or we are in the process of running an exit animation
- * that will remove the surface.
- */
- public boolean isWinVisibleLw() {
- final AppWindowToken atoken = mAppToken;
- return mSurface != null && mPolicyVisibility && !mAttachedHidden
- && (atoken == null || !atoken.hiddenRequested || atoken.animating)
- && !mExiting && !mDestroying;
- }
-
- /**
- * The same as isVisible(), but follows the current hidden state of
- * the associated app token, not the pending requested hidden state.
- */
- boolean isVisibleNow() {
- return mSurface != null && mPolicyVisibility && !mAttachedHidden
- && !mRootToken.hidden && !mExiting && !mDestroying;
- }
-
- /**
- * Can this window possibly be a drag/drop target? The test here is
- * a combination of the above "visible now" with the check that the
- * Input Manager uses when discarding windows from input consideration.
- */
- boolean isPotentialDragTarget() {
- return isVisibleNow() && (mInputChannel != null) && !mRemoved;
- }
-
- /**
- * Same as isVisible(), but we also count it as visible between the
- * call to IWindowSession.add() and the first relayout().
- */
- boolean isVisibleOrAdding() {
- final AppWindowToken atoken = mAppToken;
- return ((mSurface != null && !mReportDestroySurface)
- || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
- && mPolicyVisibility && !mAttachedHidden
- && (atoken == null || !atoken.hiddenRequested)
- && !mExiting && !mDestroying;
- }
-
- /**
- * Is this window currently on-screen? It is on-screen either if it
- * is visible or it is currently running an animation before no longer
- * being visible.
- */
- boolean isOnScreen() {
- final AppWindowToken atoken = mAppToken;
- if (atoken != null) {
- return mSurface != null && mPolicyVisibility && !mDestroying
- && ((!mAttachedHidden && !atoken.hiddenRequested)
- || mAnimation != null || atoken.animation != null);
- } else {
- return mSurface != null && mPolicyVisibility && !mDestroying
- && (!mAttachedHidden || mAnimation != null);
- }
- }
-
- /**
- * Like isOnScreen(), but we don't return true if the window is part
- * of a transition that has not yet been started.
- */
- boolean isReadyForDisplay() {
- if (mRootToken.waitingToShow &&
- mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
- return false;
- }
- final AppWindowToken atoken = mAppToken;
- final boolean animating = atoken != null
- ? (atoken.animation != null) : false;
- return mSurface != null && mPolicyVisibility && !mDestroying
- && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
- && !mRootToken.hidden)
- || mAnimation != null || animating);
- }
-
- /** Is the window or its container currently animating? */
- boolean isAnimating() {
- final WindowState attached = mAttachedWindow;
- final AppWindowToken atoken = mAppToken;
- return mAnimation != null
- || (attached != null && attached.mAnimation != null)
- || (atoken != null &&
- (atoken.animation != null
- || atoken.inPendingTransaction));
- }
-
- /** Is this window currently animating? */
- boolean isWindowAnimating() {
- return mAnimation != null;
- }
-
- /**
- * Like isOnScreen, but returns false if the surface hasn't yet
- * been drawn.
- */
- public boolean isDisplayedLw() {
- final AppWindowToken atoken = mAppToken;
- return mSurface != null && mPolicyVisibility && !mDestroying
- && !mDrawPending && !mCommitDrawPending
- && ((!mAttachedHidden &&
- (atoken == null || !atoken.hiddenRequested))
- || mAnimating);
- }
-
- /**
- * Returns true if the window has a surface that it has drawn a
- * complete UI in to.
- */
- public boolean isDrawnLw() {
- final AppWindowToken atoken = mAppToken;
- return mSurface != null && !mDestroying
- && !mDrawPending && !mCommitDrawPending;
- }
-
- /**
- * Return true if the window is opaque and fully drawn. This indicates
- * it may obscure windows behind it.
- */
- boolean isOpaqueDrawn() {
- return (mAttrs.format == PixelFormat.OPAQUE
- || mAttrs.type == TYPE_WALLPAPER)
- && mSurface != null && mAnimation == null
- && (mAppToken == null || mAppToken.animation == null)
- && !mDrawPending && !mCommitDrawPending;
- }
-
- /**
- * Return whether this window is wanting to have a translation
- * animation applied to it for an in-progress move. (Only makes
- * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
- */
- boolean shouldAnimateMove() {
- return mContentChanged && !mExiting && !mLastHidden && !mDisplayFrozen
- && (mFrame.top != mLastFrame.top
- || mFrame.left != mLastFrame.left)
- && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove())
- && mPolicy.isScreenOn();
- }
-
- boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
- return
- // only if the application is requesting compatible window
- (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
- // only if it's visible
- mHasDrawn && mViewVisibility == View.VISIBLE &&
- // and only if the application fills the compatible screen
- mFrame.left <= mCompatibleScreenFrame.left &&
- mFrame.top <= mCompatibleScreenFrame.top &&
- mFrame.right >= mCompatibleScreenFrame.right &&
- mFrame.bottom >= mCompatibleScreenFrame.bottom;
- }
-
- boolean isFullscreen(int screenWidth, int screenHeight) {
- return mFrame.left <= 0 && mFrame.top <= 0 &&
- mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
- }
-
- void removeLocked() {
- disposeInputChannel();
-
- if (mAttachedWindow != null) {
- if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow);
- mAttachedWindow.mChildWindows.remove(this);
- }
- destroySurfaceLocked();
- mSession.windowRemovedLocked();
- try {
- mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
- } catch (RuntimeException e) {
- // Ignore if it has already been removed (usually because
- // we are doing this as part of processing a death note.)
- }
- }
-
- void disposeInputChannel() {
- if (mInputChannel != null) {
- mInputManager.unregisterInputChannel(mInputChannel);
-
- mInputChannel.dispose();
- mInputChannel = null;
- }
- }
-
- private class DeathRecipient implements IBinder.DeathRecipient {
- public void binderDied() {
- try {
- synchronized(mWindowMap) {
- WindowState win = windowForClientLocked(mSession, mClient, false);
- Slog.i(TAG, "WIN DEATH: " + win);
- if (win != null) {
- removeWindowLocked(mSession, win);
- }
- }
- } catch (IllegalArgumentException ex) {
- // This will happen if the window has already been
- // removed.
- }
- }
- }
-
- /** Returns true if this window desires key events. */
- public final boolean canReceiveKeys() {
- return isVisibleOrAdding()
- && (mViewVisibility == View.VISIBLE)
- && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
- }
-
- public boolean hasDrawnLw() {
- return mHasDrawn;
- }
-
- public boolean showLw(boolean doAnimation) {
- return showLw(doAnimation, true);
- }
-
- boolean showLw(boolean doAnimation, boolean requestAnim) {
- if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
- return false;
- }
- if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
- if (doAnimation) {
- if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
- + mPolicyVisibility + " mAnimation=" + mAnimation);
- if (mDisplayFrozen || !mPolicy.isScreenOn()) {
- doAnimation = false;
- } else if (mPolicyVisibility && mAnimation == null) {
- // Check for the case where we are currently visible and
- // not animating; we do not want to do animation at such a
- // point to become visible when we already are.
- doAnimation = false;
- }
- }
- mPolicyVisibility = true;
- mPolicyVisibilityAfterAnim = true;
- if (doAnimation) {
- applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
- }
- if (requestAnim) {
- requestAnimationLocked(0);
- }
- return true;
- }
-
- public boolean hideLw(boolean doAnimation) {
- return hideLw(doAnimation, true);
- }
-
- boolean hideLw(boolean doAnimation, boolean requestAnim) {
- if (doAnimation) {
- if (mDisplayFrozen || !mPolicy.isScreenOn()) {
- doAnimation = false;
- }
- }
- boolean current = doAnimation ? mPolicyVisibilityAfterAnim
- : mPolicyVisibility;
- if (!current) {
- return false;
- }
- if (doAnimation) {
- applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
- if (mAnimation == null) {
- doAnimation = false;
- }
- }
- if (doAnimation) {
- mPolicyVisibilityAfterAnim = false;
- } else {
- if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
- mPolicyVisibilityAfterAnim = false;
- mPolicyVisibility = false;
- // Window is no longer visible -- make sure if we were waiting
- // for it to be displayed before enabling the display, that
- // we allow the display to be enabled now.
- enableScreenIfNeededLocked();
- if (mCurrentFocus == this) {
- mFocusMayChange = true;
- }
- }
- if (requestAnim) {
- requestAnimationLocked(0);
- }
- return true;
- }
-
- public void getTouchableRegion(Region outRegion) {
- final Rect frame = mFrame;
- switch (mTouchableInsets) {
- default:
- case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
- outRegion.set(frame);
- break;
- case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
- final Rect inset = mGivenContentInsets;
- outRegion.set(
- frame.left + inset.left, frame.top + inset.top,
- frame.right - inset.right, frame.bottom - inset.bottom);
- break;
- }
- case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
- final Rect inset = mGivenVisibleInsets;
- outRegion.set(
- frame.left + inset.left, frame.top + inset.top,
- frame.right - inset.right, frame.bottom - inset.bottom);
- break;
- }
- case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: {
- final Region givenTouchableRegion = mGivenTouchableRegion;
- outRegion.set(givenTouchableRegion);
- outRegion.translate(frame.left, frame.top);
- break;
- }
- }
- }
-
- void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.print("mSession="); pw.print(mSession);
- pw.print(" mClient="); pw.println(mClient.asBinder());
- pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
- if (mAttachedWindow != null || mLayoutAttached) {
- pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
- pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
- }
- if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
- pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
- pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
- pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
- pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
- }
- pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
- pw.print(" mSubLayer="); pw.print(mSubLayer);
- pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
- pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
- : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
- pw.print("="); pw.print(mAnimLayer);
- pw.print(" mLastLayer="); pw.println(mLastLayer);
- if (mSurface != null) {
- pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
- pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
- pw.print(" layer="); pw.print(mSurfaceLayer);
- pw.print(" alpha="); pw.print(mSurfaceAlpha);
- pw.print(" rect=("); pw.print(mSurfaceX);
- pw.print(","); pw.print(mSurfaceY);
- pw.print(") "); pw.print(mSurfaceW);
- pw.print(" x "); pw.println(mSurfaceH);
- }
- pw.print(prefix); pw.print("mToken="); pw.println(mToken);
- pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
- if (mAppToken != null) {
- pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
- }
- if (mTargetAppToken != null) {
- pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
- }
- pw.print(prefix); pw.print("mViewVisibility=0x");
- pw.print(Integer.toHexString(mViewVisibility));
- pw.print(" mLastHidden="); pw.print(mLastHidden);
- pw.print(" mHaveFrame="); pw.print(mHaveFrame);
- pw.print(" mObscured="); pw.println(mObscured);
- if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
- pw.print(prefix); pw.print("mPolicyVisibility=");
- pw.print(mPolicyVisibility);
- pw.print(" mPolicyVisibilityAfterAnim=");
- pw.print(mPolicyVisibilityAfterAnim);
- pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
- }
- if (!mRelayoutCalled) {
- pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
- }
- pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
- pw.print(" h="); pw.print(mRequestedHeight);
- pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
- if (mXOffset != 0 || mYOffset != 0) {
- pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
- pw.print(" y="); pw.println(mYOffset);
- }
- pw.print(prefix); pw.print("mGivenContentInsets=");
- mGivenContentInsets.printShortString(pw);
- pw.print(" mGivenVisibleInsets=");
- mGivenVisibleInsets.printShortString(pw);
- pw.println();
- if (mTouchableInsets != 0 || mGivenInsetsPending) {
- pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
- pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
- }
- pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
- pw.print(prefix); pw.print("mShownFrame=");
- mShownFrame.printShortString(pw);
- pw.print(" last="); mLastShownFrame.printShortString(pw);
- pw.println();
- pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
- pw.print(" last="); mLastFrame.printShortString(pw);
- pw.println();
- pw.print(prefix); pw.print("mContainingFrame=");
- mContainingFrame.printShortString(pw);
- pw.print(" mParentFrame=");
- mParentFrame.printShortString(pw);
- pw.print(" mDisplayFrame=");
- mDisplayFrame.printShortString(pw);
- pw.println();
- pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
- pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
- pw.println();
- pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
- pw.print(" last="); mLastContentInsets.printShortString(pw);
- pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
- pw.print(" last="); mLastVisibleInsets.printShortString(pw);
- pw.println();
- if (mAnimating || mLocalAnimating || mAnimationIsEntrance
- || mAnimation != null) {
- pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
- pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
- pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
- pw.print(" mAnimation="); pw.println(mAnimation);
- }
- if (mHasTransformation || mHasLocalTransformation) {
- pw.print(prefix); pw.print("XForm: has=");
- pw.print(mHasTransformation);
- pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
- pw.print(" "); mTransformation.printShortString(pw);
- pw.println();
- }
- if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
- pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
- pw.print(" mAlpha="); pw.print(mAlpha);
- pw.print(" mLastAlpha="); pw.println(mLastAlpha);
- }
- if (mHaveMatrix) {
- pw.print(prefix); pw.print("mDsDx="); pw.print(mDsDx);
- pw.print(" mDtDx="); pw.print(mDtDx);
- pw.print(" mDsDy="); pw.print(mDsDy);
- pw.print(" mDtDy="); pw.println(mDtDy);
- }
- pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
- pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
- pw.print(" mReadyToShow="); pw.print(mReadyToShow);
- pw.print(" mHasDrawn="); pw.println(mHasDrawn);
- if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
- pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
- pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
- pw.print(" mDestroying="); pw.print(mDestroying);
- pw.print(" mRemoved="); pw.println(mRemoved);
- }
- if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
- pw.print(prefix); pw.print("mOrientationChanging=");
- pw.print(mOrientationChanging);
- pw.print(" mAppFreezing="); pw.print(mAppFreezing);
- pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
- }
- if (mHScale != 1 || mVScale != 1) {
- pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
- pw.print(" mVScale="); pw.println(mVScale);
- }
- if (mWallpaperX != -1 || mWallpaperY != -1) {
- pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
- pw.print(" mWallpaperY="); pw.println(mWallpaperY);
- }
- if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
- pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
- pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
- }
- }
-
- String makeInputChannelName() {
- return Integer.toHexString(System.identityHashCode(this))
- + " " + mAttrs.getTitle();
- }
-
- @Override
- public String toString() {
- if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
- || mWasPaused != mToken.paused) {
- mLastTitle = mAttrs.getTitle();
- mWasPaused = mToken.paused;
- mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
- + " " + mLastTitle + " paused=" + mWasPaused + "}";
- }
- return mStringNameCache;
- }
- }
-
- // -------------------------------------------------------------
- // Window Token State
- // -------------------------------------------------------------
-
- class WindowToken {
- // The actual token.
- final IBinder token;
-
- // The type of window this token is for, as per WindowManager.LayoutParams.
- final int windowType;
-
- // Set if this token was explicitly added by a client, so should
- // not be removed when all windows are removed.
- final boolean explicit;
-
- // For printing.
- String stringName;
-
- // If this is an AppWindowToken, this is non-null.
- AppWindowToken appWindowToken;
-
- // All of the windows associated with this token.
- final ArrayList<WindowState> windows = new ArrayList<WindowState>();
-
- // Is key dispatching paused for this token?
- boolean paused = false;
-
- // Should this token's windows be hidden?
- boolean hidden;
-
- // Temporary for finding which tokens no longer have visible windows.
- boolean hasVisible;
-
- // Set to true when this token is in a pending transaction where it
- // will be shown.
- boolean waitingToShow;
-
- // Set to true when this token is in a pending transaction where it
- // will be hidden.
- boolean waitingToHide;
-
- // Set to true when this token is in a pending transaction where its
- // windows will be put to the bottom of the list.
- boolean sendingToBottom;
-
- // Set to true when this token is in a pending transaction where its
- // windows will be put to the top of the list.
- boolean sendingToTop;
-
- WindowToken(IBinder _token, int type, boolean _explicit) {
- token = _token;
- windowType = type;
- explicit = _explicit;
- }
-
- void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.print("token="); pw.println(token);
- pw.print(prefix); pw.print("windows="); pw.println(windows);
- pw.print(prefix); pw.print("windowType="); pw.print(windowType);
- pw.print(" hidden="); pw.print(hidden);
- pw.print(" hasVisible="); pw.println(hasVisible);
- if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
- pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
- pw.print(" waitingToHide="); pw.print(waitingToHide);
- pw.print(" sendingToBottom="); pw.print(sendingToBottom);
- pw.print(" sendingToTop="); pw.println(sendingToTop);
- }
- }
-
- @Override
- public String toString() {
- if (stringName == null) {
- StringBuilder sb = new StringBuilder();
- sb.append("WindowToken{");
- sb.append(Integer.toHexString(System.identityHashCode(this)));
- sb.append(" token="); sb.append(token); sb.append('}');
- stringName = sb.toString();
- }
- return stringName;
- }
- };
-
- class AppWindowToken extends WindowToken {
- // Non-null only for application tokens.
- final IApplicationToken appToken;
-
- // All of the windows and child windows that are included in this
- // application token. Note this list is NOT sorted!
- final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>();
-
- int groupId = -1;
- boolean appFullscreen;
- int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-
- // The input dispatching timeout for this application token in nanoseconds.
- long inputDispatchingTimeoutNanos;
-
- // These are used for determining when all windows associated with
- // an activity have been drawn, so they can be made visible together
- // at the same time.
- int lastTransactionSequence = mTransactionSequence-1;
- int numInterestingWindows;
- int numDrawnWindows;
- boolean inPendingTransaction;
- boolean allDrawn;
-
- // Is this token going to be hidden in a little while? If so, it
- // won't be taken into account for setting the screen orientation.
- boolean willBeHidden;
-
- // Is this window's surface needed? This is almost like hidden, except
- // it will sometimes be true a little earlier: when the token has
- // been shown, but is still waiting for its app transition to execute
- // before making its windows shown.
- boolean hiddenRequested;
-
- // Have we told the window clients to hide themselves?
- boolean clientHidden;
-
- // Last visibility state we reported to the app token.
- boolean reportedVisible;
-
- // Set to true when the token has been removed from the window mgr.
- boolean removed;
-
- // Have we been asked to have this token keep the screen frozen?
- boolean freezingScreen;
-
- boolean animating;
- Animation animation;
- boolean hasTransformation;
- final Transformation transformation = new Transformation();
-
- // Offset to the window of all layers in the token, for use by
- // AppWindowToken animations.
- int animLayerAdjustment;
-
- // Information about an application starting window if displayed.
- StartingData startingData;
- WindowState startingWindow;
- View startingView;
- boolean startingDisplayed;
- boolean startingMoved;
- boolean firstWindowDrawn;
-
- // Input application handle used by the input dispatcher.
- InputApplicationHandle mInputApplicationHandle;
-
- AppWindowToken(IApplicationToken _token) {
- super(_token.asBinder(),
- WindowManager.LayoutParams.TYPE_APPLICATION, true);
- appWindowToken = this;
- appToken = _token;
- mInputApplicationHandle = new InputApplicationHandle(this);
- }
-
- public void setAnimation(Animation anim) {
- if (localLOGV) Slog.v(
- TAG, "Setting animation in " + this + ": " + anim);
- animation = anim;
- animating = false;
- anim.restrictDuration(MAX_ANIMATION_DURATION);
- anim.scaleCurrentDuration(mTransitionAnimationScale);
- int zorder = anim.getZAdjustment();
- int adj = 0;
- if (zorder == Animation.ZORDER_TOP) {
- adj = TYPE_LAYER_OFFSET;
- } else if (zorder == Animation.ZORDER_BOTTOM) {
- adj = -TYPE_LAYER_OFFSET;
- }
-
- if (animLayerAdjustment != adj) {
- animLayerAdjustment = adj;
- updateLayers();
- }
- }
-
- public void setDummyAnimation() {
- if (animation == null) {
- if (localLOGV) Slog.v(
- TAG, "Setting dummy animation in " + this);
- animation = sDummyAnimation;
- }
- }
-
- public void clearAnimation() {
- if (animation != null) {
- animation = null;
- animating = true;
- }
- }
-
- void updateLayers() {
- final int N = allAppWindows.size();
- final int adj = animLayerAdjustment;
- for (int i=0; i<N; i++) {
- WindowState w = allAppWindows.get(i);
- w.mAnimLayer = w.mLayer + adj;
- if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
- + w.mAnimLayer);
- if (w == mInputMethodTarget && !mInputMethodTargetWaitingAnim) {
- setInputMethodAnimLayerAdjustment(adj);
- }
- if (w == mWallpaperTarget && mLowerWallpaperTarget == null) {
- setWallpaperAnimLayerAdjustmentLocked(adj);
- }
- }
- }
-
- void sendAppVisibilityToClients() {
- final int N = allAppWindows.size();
- for (int i=0; i<N; i++) {
- WindowState win = allAppWindows.get(i);
- if (win == startingWindow && clientHidden) {
- // Don't hide the starting window.
- continue;
- }
- try {
- if (DEBUG_VISIBILITY) Slog.v(TAG,
- "Setting visibility of " + win + ": " + (!clientHidden));
- win.mClient.dispatchAppVisibility(!clientHidden);
- } catch (RemoteException e) {
- }
- }
- }
-
- void showAllWindowsLocked() {
- final int NW = allAppWindows.size();
- for (int i=0; i<NW; i++) {
- WindowState w = allAppWindows.get(i);
- if (DEBUG_VISIBILITY) Slog.v(TAG,
- "performing show on: " + w);
- w.performShowLocked();
- }
- }
-
- // This must be called while inside a transaction.
- boolean stepAnimationLocked(long currentTime, int dw, int dh) {
- if (!mDisplayFrozen && mPolicy.isScreenOn()) {
- // We will run animations as long as the display isn't frozen.
-
- if (animation == sDummyAnimation) {
- // This guy is going to animate, but not yet. For now count
- // it as not animating for purposes of scheduling transactions;
- // when it is really time to animate, this will be set to
- // a real animation and the next call will execute normally.
- return false;
- }
-
- if ((allDrawn || animating || startingDisplayed) && animation != null) {
- if (!animating) {
- if (DEBUG_ANIM) Slog.v(
- TAG, "Starting animation in " + this +
- " @ " + currentTime + ": dw=" + dw + " dh=" + dh
- + " scale=" + mTransitionAnimationScale
- + " allDrawn=" + allDrawn + " animating=" + animating);
- animation.initialize(dw, dh, dw, dh);
- animation.setStartTime(currentTime);
- animating = true;
- }
- transformation.clear();
- final boolean more = animation.getTransformation(
- currentTime, transformation);
- if (DEBUG_ANIM) Slog.v(
- TAG, "Stepped animation in " + this +
- ": more=" + more + ", xform=" + transformation);
- if (more) {
- // we're done!
- hasTransformation = true;
- return true;
- }
- if (DEBUG_ANIM) Slog.v(
- TAG, "Finished animation in " + this +
- " @ " + currentTime);
- animation = null;
- }
- } else if (animation != null) {
- // If the display is frozen, and there is a pending animation,
- // clear it and make sure we run the cleanup code.
- animating = true;
- animation = null;
- }
-
- hasTransformation = false;
-
- if (!animating) {
- return false;
- }
-
- clearAnimation();
- animating = false;
- if (animLayerAdjustment != 0) {
- animLayerAdjustment = 0;
- updateLayers();
- }
- if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
- moveInputMethodWindowsIfNeededLocked(true);
- }
-
- if (DEBUG_ANIM) Slog.v(
- TAG, "Animation done in " + this
- + ": reportedVisible=" + reportedVisible);
-
- transformation.clear();
-
- final int N = windows.size();
- for (int i=0; i<N; i++) {
- windows.get(i).finishExit();
- }
- updateReportedVisibilityLocked();
-
- return false;
- }
-
- void updateReportedVisibilityLocked() {
- if (appToken == null) {
- return;
- }
-
- int numInteresting = 0;
- int numVisible = 0;
- boolean nowGone = true;
-
- if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
- final int N = allAppWindows.size();
- for (int i=0; i<N; i++) {
- WindowState win = allAppWindows.get(i);
- if (win == startingWindow || win.mAppFreezing
- || win.mViewVisibility != View.VISIBLE
- || win.mAttrs.type == TYPE_APPLICATION_STARTING
- || win.mDestroying) {
- continue;
- }
- if (DEBUG_VISIBILITY) {
- Slog.v(TAG, "Win " + win + ": isDrawn="
- + win.isDrawnLw()
- + ", isAnimating=" + win.isAnimating());
- if (!win.isDrawnLw()) {
- Slog.v(TAG, "Not displayed: s=" + win.mSurface
- + " pv=" + win.mPolicyVisibility
- + " dp=" + win.mDrawPending
- + " cdp=" + win.mCommitDrawPending
- + " ah=" + win.mAttachedHidden
- + " th="
- + (win.mAppToken != null
- ? win.mAppToken.hiddenRequested : false)
- + " a=" + win.mAnimating);
- }
- }
- numInteresting++;
- if (win.isDrawnLw()) {
- if (!win.isAnimating()) {
- numVisible++;
- }
- nowGone = false;
- } else if (win.isAnimating()) {
- nowGone = false;
- }
- }
-
- boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
- if (DEBUG_VISIBILITY) Slog.v(TAG, "VIS " + this + ": interesting="
- + numInteresting + " visible=" + numVisible);
- if (nowVisible != reportedVisible) {
- if (DEBUG_VISIBILITY) Slog.v(
- TAG, "Visibility changed in " + this
- + ": vis=" + nowVisible);
- reportedVisible = nowVisible;
- Message m = mH.obtainMessage(
- H.REPORT_APPLICATION_TOKEN_WINDOWS,
- nowVisible ? 1 : 0,
- nowGone ? 1 : 0,
- this);
- mH.sendMessage(m);
- }
- }
-
- WindowState findMainWindow() {
- int j = windows.size();
- while (j > 0) {
- j--;
- WindowState win = windows.get(j);
- if (win.mAttrs.type == WindowManager.LayoutParams.TYPE_BASE_APPLICATION
- || win.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
- return win;
- }
- }
- return null;
- }
-
- void dump(PrintWriter pw, String prefix) {
- super.dump(pw, prefix);
- if (appToken != null) {
- pw.print(prefix); pw.println("app=true");
- }
- if (allAppWindows.size() > 0) {
- pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows);
- }
- pw.print(prefix); pw.print("groupId="); pw.print(groupId);
- pw.print(" appFullscreen="); pw.print(appFullscreen);
- pw.print(" requestedOrientation="); pw.println(requestedOrientation);
- pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
- pw.print(" clientHidden="); pw.print(clientHidden);
- pw.print(" willBeHidden="); pw.print(willBeHidden);
- pw.print(" reportedVisible="); pw.println(reportedVisible);
- if (paused || freezingScreen) {
- pw.print(prefix); pw.print("paused="); pw.print(paused);
- pw.print(" freezingScreen="); pw.println(freezingScreen);
- }
- if (numInterestingWindows != 0 || numDrawnWindows != 0
- || inPendingTransaction || allDrawn) {
- pw.print(prefix); pw.print("numInterestingWindows=");
- pw.print(numInterestingWindows);
- pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
- pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
- pw.print(" allDrawn="); pw.println(allDrawn);
- }
- if (animating || animation != null) {
- pw.print(prefix); pw.print("animating="); pw.print(animating);
- pw.print(" animation="); pw.println(animation);
- }
- if (hasTransformation) {
- pw.print(prefix); pw.print("XForm: ");
- transformation.printShortString(pw);
- pw.println();
- }
- if (animLayerAdjustment != 0) {
- pw.print(prefix); pw.print("animLayerAdjustment="); pw.println(animLayerAdjustment);
- }
- if (startingData != null || removed || firstWindowDrawn) {
- pw.print(prefix); pw.print("startingData="); pw.print(startingData);
- pw.print(" removed="); pw.print(removed);
- pw.print(" firstWindowDrawn="); pw.println(firstWindowDrawn);
- }
- if (startingWindow != null || startingView != null
- || startingDisplayed || startingMoved) {
- pw.print(prefix); pw.print("startingWindow="); pw.print(startingWindow);
- pw.print(" startingView="); pw.print(startingView);
- pw.print(" startingDisplayed="); pw.print(startingDisplayed);
- pw.print(" startingMoved"); pw.println(startingMoved);
- }
- }
-
- @Override
- public String toString() {
- if (stringName == null) {
- StringBuilder sb = new StringBuilder();
- sb.append("AppWindowToken{");
- sb.append(Integer.toHexString(System.identityHashCode(this)));
- sb.append(" token="); sb.append(token); sb.append('}');
- stringName = sb.toString();
- }
- return stringName;
- }
- }
-
- // -------------------------------------------------------------
- // DummyAnimation
- // -------------------------------------------------------------
-
// This is an animation that does nothing: it just immediately finishes
// itself every time it is called. It is used as a stub animation in cases
// where we want to synchronize multiple things that may be animating.
@@ -8913,26 +5838,7 @@ public class WindowManagerService extends IWindowManager.Stub
// Async Handler
// -------------------------------------------------------------
- static final class StartingData {
- final String pkg;
- final int theme;
- final CharSequence nonLocalizedLabel;
- final int labelRes;
- final int icon;
- final int windowFlags;
-
- StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
- int _labelRes, int _icon, int _windowFlags) {
- pkg = _pkg;
- theme = _theme;
- nonLocalizedLabel = _nonLocalizedLabel;
- labelRes = _labelRes;
- icon = _icon;
- windowFlags = _windowFlags;
- }
- }
-
- private final class H extends Handler {
+ final class H extends Handler {
public static final int REPORT_FOCUS_CHANGE = 2;
public static final int REPORT_LOSING_FOCUS = 3;
public static final int ANIMATE = 4;
@@ -9342,7 +6248,7 @@ public class WindowManagerService extends IWindowManager.Stub
IInputContext inputContext) {
if (client == null) throw new IllegalArgumentException("null client");
if (inputContext == null) throw new IllegalArgumentException("null inputContext");
- Session session = new Session(client, inputContext);
+ Session session = new Session(this, client, inputContext);
return session;
}
@@ -11476,148 +8382,6 @@ public class WindowManagerService extends IWindowManager.Stub
return val;
}
- static class Watermark {
- final String[] mTokens;
- final String mText;
- final Paint mTextPaint;
- final int mTextWidth;
- final int mTextHeight;
- final int mTextAscent;
- final int mTextDescent;
- final int mDeltaX;
- final int mDeltaY;
-
- Surface mSurface;
- int mLastDW;
- int mLastDH;
- boolean mDrawNeeded;
-
- Watermark(Display display, SurfaceSession session, String[] tokens) {
- final DisplayMetrics dm = new DisplayMetrics();
- display.getMetrics(dm);
-
- if (false) {
- Log.i(TAG, "*********************** WATERMARK");
- for (int i=0; i<tokens.length; i++) {
- Log.i(TAG, " TOKEN #" + i + ": " + tokens[i]);
- }
- }
-
- mTokens = tokens;
-
- StringBuilder builder = new StringBuilder(32);
- int len = mTokens[0].length();
- len = len & ~1;
- for (int i=0; i<len; i+=2) {
- int c1 = mTokens[0].charAt(i);
- int c2 = mTokens[0].charAt(i+1);
- if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10;
- else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10;
- else c1 -= '0';
- if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10;
- else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10;
- else c2 -= '0';
- builder.append((char)(255-((c1*16)+c2)));
- }
- mText = builder.toString();
- if (false) {
- Log.i(TAG, "Final text: " + mText);
- }
-
- int fontSize = getPropertyInt(tokens, 1,
- TypedValue.COMPLEX_UNIT_DIP, 20, dm);
-
- mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mTextPaint.setTextSize(fontSize);
- mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
-
- FontMetricsInt fm = mTextPaint.getFontMetricsInt();
- mTextWidth = (int)mTextPaint.measureText(mText);
- mTextAscent = fm.ascent;
- mTextDescent = fm.descent;
- mTextHeight = fm.descent - fm.ascent;
-
- mDeltaX = getPropertyInt(tokens, 2,
- TypedValue.COMPLEX_UNIT_PX, mTextWidth*2, dm);
- mDeltaY = getPropertyInt(tokens, 3,
- TypedValue.COMPLEX_UNIT_PX, mTextHeight*3, dm);
- int shadowColor = getPropertyInt(tokens, 4,
- TypedValue.COMPLEX_UNIT_PX, 0xb0000000, dm);
- int color = getPropertyInt(tokens, 5,
- TypedValue.COMPLEX_UNIT_PX, 0x60ffffff, dm);
- int shadowRadius = getPropertyInt(tokens, 6,
- TypedValue.COMPLEX_UNIT_PX, 7, dm);
- int shadowDx = getPropertyInt(tokens, 8,
- TypedValue.COMPLEX_UNIT_PX, 0, dm);
- int shadowDy = getPropertyInt(tokens, 9,
- TypedValue.COMPLEX_UNIT_PX, 0, dm);
-
- mTextPaint.setColor(color);
- mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);
-
- try {
- mSurface = new Surface(session, 0,
- "WatermarkSurface", -1, 1, 1, PixelFormat.TRANSLUCENT, 0);
- mSurface.setLayer(TYPE_LAYER_MULTIPLIER*100);
- mSurface.setPosition(0, 0);
- mSurface.show();
- } catch (OutOfResourcesException e) {
- }
- }
-
- void positionSurface(int dw, int dh) {
- if (mLastDW != dw || mLastDH != dh) {
- mLastDW = dw;
- mLastDH = dh;
- mSurface.setSize(dw, dh);
- mDrawNeeded = true;
- }
- }
-
- void drawIfNeeded() {
- if (mDrawNeeded) {
- final int dw = mLastDW;
- final int dh = mLastDH;
-
- mDrawNeeded = false;
- Rect dirty = new Rect(0, 0, dw, dh);
- Canvas c = null;
- try {
- c = mSurface.lockCanvas(dirty);
- } catch (IllegalArgumentException e) {
- } catch (OutOfResourcesException e) {
- }
- if (c != null) {
- c.drawColor(0, PorterDuff.Mode.CLEAR);
-
- int deltaX = mDeltaX;
- int deltaY = mDeltaY;
-
- // deltaX shouldn't be close to a round fraction of our
- // x step, or else things will line up too much.
- int div = (dw+mTextWidth)/deltaX;
- int rem = (dw+mTextWidth) - (div*deltaX);
- int qdelta = deltaX/4;
- if (rem < qdelta || rem > (deltaX-qdelta)) {
- deltaX += deltaX/3;
- }
-
- int y = -mTextHeight;
- int x = -mTextWidth;
- while (y < (dh+mTextHeight)) {
- c.drawText(mText, x, y, mTextPaint);
- x += deltaX;
- if (x >= dw) {
- x -= (dw+mTextWidth);
- y += deltaY;
- }
- }
- mSurface.unlockCanvasAndPost(c);
- }
- }
- }
- }
-
void createWatermark() {
if (mWatermark != null) {
return;
@@ -11899,190 +8663,6 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mKeyguardTokenWatcher) { }
}
- /**
- * DimAnimator class that controls the dim animation. This holds the surface and
- * all state used for dim animation.
- */
- private static class DimAnimator {
- Surface mDimSurface;
- boolean mDimShown = false;
- float mDimCurrentAlpha;
- float mDimTargetAlpha;
- float mDimDeltaPerMs;
- long mLastDimAnimTime;
-
- int mLastDimWidth, mLastDimHeight;
-
- DimAnimator (SurfaceSession session) {
- if (mDimSurface == null) {
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
- + mDimSurface + ": CREATE");
- try {
- mDimSurface = new Surface(session, 0,
- "DimSurface",
- -1, 16, 16, PixelFormat.OPAQUE,
- Surface.FX_SURFACE_DIM);
- mDimSurface.setAlpha(0.0f);
- } catch (Exception e) {
- Slog.e(TAG, "Exception creating Dim surface", e);
- }
- }
- }
-
- /**
- * Show the dim surface.
- */
- void show(int dw, int dh) {
- if (!mDimShown) {
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface + ": SHOW pos=(0,0) (" +
- dw + "x" + dh + ")");
- mDimShown = true;
- try {
- mLastDimWidth = dw;
- mLastDimHeight = dh;
- mDimSurface.setPosition(0, 0);
- mDimSurface.setSize(dw, dh);
- mDimSurface.show();
- } catch (RuntimeException e) {
- Slog.w(TAG, "Failure showing dim surface", e);
- }
- } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
- mLastDimWidth = dw;
- mLastDimHeight = dh;
- mDimSurface.setSize(dw, dh);
- }
- }
-
- /**
- * Set's the dim surface's layer and update dim parameters that will be used in
- * {@link updateSurface} after all windows are examined.
- */
- void updateParameters(Resources res, WindowState w, long currentTime) {
- mDimSurface.setLayer(w.mAnimLayer-1);
-
- final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
- + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
- if (mDimTargetAlpha != target) {
- // If the desired dim level has changed, then
- // start an animation to it.
- mLastDimAnimTime = currentTime;
- long duration = (w.mAnimating && w.mAnimation != null)
- ? w.mAnimation.computeDurationHint()
- : DEFAULT_DIM_DURATION;
- if (target > mDimTargetAlpha) {
- TypedValue tv = new TypedValue();
- res.getValue(com.android.internal.R.fraction.config_dimBehindFadeDuration,
- tv, true);
- if (tv.type == TypedValue.TYPE_FRACTION) {
- duration = (long)tv.getFraction((float)duration, (float)duration);
- } else if (tv.type >= TypedValue.TYPE_FIRST_INT
- && tv.type <= TypedValue.TYPE_LAST_INT) {
- duration = tv.data;
- }
- }
- if (duration < 1) {
- // Don't divide by zero
- duration = 1;
- }
- mDimTargetAlpha = target;
- mDimDeltaPerMs = (mDimTargetAlpha-mDimCurrentAlpha) / duration;
- }
- }
-
- /**
- * Updating the surface's alpha. Returns true if the animation continues, or returns
- * false when the animation is finished and the dim surface is hidden.
- */
- boolean updateSurface(boolean dimming, long currentTime, boolean displayFrozen) {
- if (!dimming) {
- if (mDimTargetAlpha != 0) {
- mLastDimAnimTime = currentTime;
- mDimTargetAlpha = 0;
- mDimDeltaPerMs = (-mDimCurrentAlpha) / DEFAULT_DIM_DURATION;
- }
- }
-
- boolean animating = false;
- if (mLastDimAnimTime != 0) {
- mDimCurrentAlpha += mDimDeltaPerMs
- * (currentTime-mLastDimAnimTime);
- boolean more = true;
- if (displayFrozen) {
- // If the display is frozen, there is no reason to animate.
- more = false;
- } else if (mDimDeltaPerMs > 0) {
- if (mDimCurrentAlpha > mDimTargetAlpha) {
- more = false;
- }
- } else if (mDimDeltaPerMs < 0) {
- if (mDimCurrentAlpha < mDimTargetAlpha) {
- more = false;
- }
- } else {
- more = false;
- }
-
- // Do we need to continue animating?
- if (more) {
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
- + mDimSurface + ": alpha=" + mDimCurrentAlpha);
- mLastDimAnimTime = currentTime;
- mDimSurface.setAlpha(mDimCurrentAlpha);
- animating = true;
- } else {
- mDimCurrentAlpha = mDimTargetAlpha;
- mLastDimAnimTime = 0;
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM "
- + mDimSurface + ": final alpha=" + mDimCurrentAlpha);
- mDimSurface.setAlpha(mDimCurrentAlpha);
- if (!dimming) {
- if (SHOW_TRANSACTIONS) Slog.i(TAG, " DIM " + mDimSurface
- + ": HIDE");
- try {
- mDimSurface.hide();
- } catch (RuntimeException e) {
- Slog.w(TAG, "Illegal argument exception hiding dim surface");
- }
- mDimShown = false;
- }
- }
- }
- return animating;
- }
-
- public void printTo(PrintWriter pw) {
- pw.print(" mDimShown="); pw.print(mDimShown);
- pw.print(" current="); pw.print(mDimCurrentAlpha);
- pw.print(" target="); pw.print(mDimTargetAlpha);
- pw.print(" delta="); pw.print(mDimDeltaPerMs);
- pw.print(" lastAnimTime="); pw.println(mLastDimAnimTime);
- }
- }
-
- /**
- * Animation that fade in after 0.5 interpolate time, or fade out in reverse order.
- * This is used for opening/closing transition for apps in compatible mode.
- */
- private static class FadeInOutAnimation extends Animation {
- boolean mFadeIn;
-
- public FadeInOutAnimation(boolean fadeIn) {
- setInterpolator(new AccelerateInterpolator());
- setDuration(DEFAULT_FADE_IN_OUT_DURATION);
- mFadeIn = fadeIn;
- }
-
- @Override
- protected void applyTransformation(float interpolatedTime, Transformation t) {
- float x = interpolatedTime;
- if (!mFadeIn) {
- x = 1.0f - x; // reverse the interpolation for fade out
- }
- t.setAlpha(x);
- }
- }
-
public interface OnHardKeyboardStatusChangeListener {
public void onHardKeyboardStatusChange(boolean available, boolean enabled);
}
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
new file mode 100644
index 000000000000..d0eec898c3af
--- /dev/null
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -0,0 +1,1623 @@
+/*
+ * 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.wm;
+
+import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+
+import com.android.server.wm.WindowManagerService.H;
+
+import android.content.res.Configuration;
+import android.graphics.Matrix;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Slog;
+import android.view.Gravity;
+import android.view.IApplicationToken;
+import android.view.IWindow;
+import android.view.InputChannel;
+import android.view.Surface;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
+import android.view.WindowManagerPolicy;
+import android.view.WindowManager.LayoutParams;
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * A window in the window manager.
+ */
+final class WindowState implements WindowManagerPolicy.WindowState {
+ final WindowManagerService mService;
+ final Session mSession;
+ final IWindow mClient;
+ WindowToken mToken;
+ WindowToken mRootToken;
+ AppWindowToken mAppToken;
+ AppWindowToken mTargetAppToken;
+ final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
+ final DeathRecipient mDeathRecipient;
+ final WindowState mAttachedWindow;
+ final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
+ final int mBaseLayer;
+ final int mSubLayer;
+ final boolean mLayoutAttached;
+ final boolean mIsImWindow;
+ final boolean mIsWallpaper;
+ final boolean mIsFloatingLayer;
+ int mViewVisibility;
+ boolean mPolicyVisibility = true;
+ boolean mPolicyVisibilityAfterAnim = true;
+ boolean mAppFreezing;
+ Surface mSurface;
+ boolean mReportDestroySurface;
+ boolean mSurfacePendingDestroy;
+ boolean mAttachedHidden; // is our parent window hidden?
+ boolean mLastHidden; // was this window last hidden?
+ boolean mWallpaperVisible; // for wallpaper, what was last vis report?
+ int mRequestedWidth;
+ int mRequestedHeight;
+ int mLastRequestedWidth;
+ int mLastRequestedHeight;
+ int mLayer;
+ int mAnimLayer;
+ int mLastLayer;
+ boolean mHaveFrame;
+ boolean mObscured;
+ boolean mTurnOnScreen;
+
+ int mLayoutSeq = -1;
+
+ Configuration mConfiguration = null;
+
+ // Actual frame shown on-screen (may be modified by animation)
+ final Rect mShownFrame = new Rect();
+ final Rect mLastShownFrame = new Rect();
+
+ /**
+ * Set when we have changed the size of the surface, to know that
+ * we must tell them application to resize (and thus redraw itself).
+ */
+ boolean mSurfaceResized;
+
+ /**
+ * Insets that determine the actually visible area
+ */
+ final Rect mVisibleInsets = new Rect();
+ final Rect mLastVisibleInsets = new Rect();
+ boolean mVisibleInsetsChanged;
+
+ /**
+ * Insets that are covered by system windows
+ */
+ final Rect mContentInsets = new Rect();
+ final Rect mLastContentInsets = new Rect();
+ boolean mContentInsetsChanged;
+
+ /**
+ * Set to true if we are waiting for this window to receive its
+ * given internal insets before laying out other windows based on it.
+ */
+ boolean mGivenInsetsPending;
+
+ /**
+ * These are the content insets that were given during layout for
+ * this window, to be applied to windows behind it.
+ */
+ final Rect mGivenContentInsets = new Rect();
+
+ /**
+ * These are the visible insets that were given during layout for
+ * this window, to be applied to windows behind it.
+ */
+ final Rect mGivenVisibleInsets = new Rect();
+
+ /**
+ * This is the given touchable area relative to the window frame, or null if none.
+ */
+ final Region mGivenTouchableRegion = new Region();
+
+ /**
+ * Flag indicating whether the touchable region should be adjusted by
+ * the visible insets; if false the area outside the visible insets is
+ * NOT touchable, so we must use those to adjust the frame during hit
+ * tests.
+ */
+ int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
+
+ // Current transformation being applied.
+ boolean mHaveMatrix;
+ float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
+ float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
+ float mHScale=1, mVScale=1;
+ float mLastHScale=1, mLastVScale=1;
+ final Matrix mTmpMatrix = new Matrix();
+
+ // "Real" frame that the application sees.
+ final Rect mFrame = new Rect();
+ final Rect mLastFrame = new Rect();
+
+ final Rect mContainingFrame = new Rect();
+ final Rect mDisplayFrame = new Rect();
+ final Rect mContentFrame = new Rect();
+ final Rect mParentFrame = new Rect();
+ final Rect mVisibleFrame = new Rect();
+
+ boolean mContentChanged;
+
+ float mShownAlpha = 1;
+ float mAlpha = 1;
+ float mLastAlpha = 1;
+
+ // Set to true if, when the window gets displayed, it should perform
+ // an enter animation.
+ boolean mEnterAnimationPending;
+
+ // Currently running animation.
+ boolean mAnimating;
+ boolean mLocalAnimating;
+ Animation mAnimation;
+ boolean mAnimationIsEntrance;
+ boolean mHasTransformation;
+ boolean mHasLocalTransformation;
+ final Transformation mTransformation = new Transformation();
+
+ // If a window showing a wallpaper: the requested offset for the
+ // wallpaper; if a wallpaper window: the currently applied offset.
+ float mWallpaperX = -1;
+ float mWallpaperY = -1;
+
+ // If a window showing a wallpaper: what fraction of the offset
+ // range corresponds to a full virtual screen.
+ float mWallpaperXStep = -1;
+ float mWallpaperYStep = -1;
+
+ // Wallpaper windows: pixels offset based on above variables.
+ int mXOffset;
+ int mYOffset;
+
+ // This is set after IWindowSession.relayout() has been called at
+ // least once for the window. It allows us to detect the situation
+ // where we don't yet have a surface, but should have one soon, so
+ // we can give the window focus before waiting for the relayout.
+ boolean mRelayoutCalled;
+
+ // This is set after the Surface has been created but before the
+ // window has been drawn. During this time the surface is hidden.
+ boolean mDrawPending;
+
+ // This is set after the window has finished drawing for the first
+ // time but before its surface is shown. The surface will be
+ // displayed when the next layout is run.
+ boolean mCommitDrawPending;
+
+ // This is set during the time after the window's drawing has been
+ // committed, and before its surface is actually shown. It is used
+ // to delay showing the surface until all windows in a token are ready
+ // to be shown.
+ boolean mReadyToShow;
+
+ // Set when the window has been shown in the screen the first time.
+ boolean mHasDrawn;
+
+ // Currently running an exit animation?
+ boolean mExiting;
+
+ // Currently on the mDestroySurface list?
+ boolean mDestroying;
+
+ // Completely remove from window manager after exit animation?
+ boolean mRemoveOnExit;
+
+ // Set when the orientation is changing and this window has not yet
+ // been updated for the new orientation.
+ boolean mOrientationChanging;
+
+ // Is this window now (or just being) removed?
+ boolean mRemoved;
+
+ // Temp for keeping track of windows that have been removed when
+ // rebuilding window list.
+ boolean mRebuilding;
+
+ // For debugging, this is the last information given to the surface flinger.
+ boolean mSurfaceShown;
+ int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
+ int mSurfaceLayer;
+ float mSurfaceAlpha;
+
+ // Input channel and input window handle used by the input dispatcher.
+ InputWindowHandle mInputWindowHandle;
+ InputChannel mInputChannel;
+
+ // Used to improve performance of toString()
+ String mStringNameCache;
+ CharSequence mLastTitle;
+ boolean mWasPaused;
+
+ WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
+ WindowState attachedWindow, WindowManager.LayoutParams a,
+ int viewVisibility) {
+ mService = service;
+ mSession = s;
+ mClient = c;
+ mToken = token;
+ mAttrs.copyFrom(a);
+ mViewVisibility = viewVisibility;
+ DeathRecipient deathRecipient = new DeathRecipient();
+ mAlpha = a.alpha;
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Window " + this + " client=" + c.asBinder()
+ + " token=" + token + " (" + mAttrs.token + ")");
+ try {
+ c.asBinder().linkToDeath(deathRecipient, 0);
+ } catch (RemoteException e) {
+ mDeathRecipient = null;
+ mAttachedWindow = null;
+ mLayoutAttached = false;
+ mIsImWindow = false;
+ mIsWallpaper = false;
+ mIsFloatingLayer = false;
+ mBaseLayer = 0;
+ mSubLayer = 0;
+ return;
+ }
+ mDeathRecipient = deathRecipient;
+
+ if ((mAttrs.type >= FIRST_SUB_WINDOW &&
+ mAttrs.type <= LAST_SUB_WINDOW)) {
+ // The multiplier here is to reserve space for multiple
+ // windows in the same type layer.
+ mBaseLayer = mService.mPolicy.windowTypeToLayerLw(
+ attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER
+ + WindowManagerService.TYPE_LAYER_OFFSET;
+ mSubLayer = mService.mPolicy.subWindowTypeToLayerLw(a.type);
+ mAttachedWindow = attachedWindow;
+ if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(WindowManagerService.TAG, "Adding " + this + " to " + mAttachedWindow);
+ mAttachedWindow.mChildWindows.add(this);
+ mLayoutAttached = mAttrs.type !=
+ WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+ mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
+ || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
+ mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
+ mIsFloatingLayer = mIsImWindow || mIsWallpaper;
+ } else {
+ // The multiplier here is to reserve space for multiple
+ // windows in the same type layer.
+ mBaseLayer = mService.mPolicy.windowTypeToLayerLw(a.type)
+ * WindowManagerService.TYPE_LAYER_MULTIPLIER
+ + WindowManagerService.TYPE_LAYER_OFFSET;
+ mSubLayer = 0;
+ mAttachedWindow = null;
+ mLayoutAttached = false;
+ mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
+ || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
+ mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
+ mIsFloatingLayer = mIsImWindow || mIsWallpaper;
+ }
+
+ WindowState appWin = this;
+ while (appWin.mAttachedWindow != null) {
+ appWin = mAttachedWindow;
+ }
+ WindowToken appToken = appWin.mToken;
+ while (appToken.appWindowToken == null) {
+ WindowToken parent = mService.mTokenMap.get(appToken.token);
+ if (parent == null || appToken == parent) {
+ break;
+ }
+ appToken = parent;
+ }
+ mRootToken = appToken;
+ mAppToken = appToken.appWindowToken;
+
+ mSurface = null;
+ mRequestedWidth = 0;
+ mRequestedHeight = 0;
+ mLastRequestedWidth = 0;
+ mLastRequestedHeight = 0;
+ mXOffset = 0;
+ mYOffset = 0;
+ mLayer = 0;
+ mAnimLayer = 0;
+ mLastLayer = 0;
+ mInputWindowHandle = new InputWindowHandle(
+ mAppToken != null ? mAppToken.mInputApplicationHandle : null, this);
+ }
+
+ void attach() {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Attaching " + this + " token=" + mToken
+ + ", list=" + mToken.windows);
+ mSession.windowAddedLocked();
+ }
+
+ public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
+ mHaveFrame = true;
+
+ final Rect container = mContainingFrame;
+ container.set(pf);
+
+ final Rect display = mDisplayFrame;
+ display.set(df);
+
+ if ((mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0) {
+ container.intersect(mService.mCompatibleScreenFrame);
+ if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
+ display.intersect(mService.mCompatibleScreenFrame);
+ }
+ }
+
+ final int pw = container.right - container.left;
+ final int ph = container.bottom - container.top;
+
+ int w,h;
+ if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
+ w = mAttrs.width < 0 ? pw : mAttrs.width;
+ h = mAttrs.height< 0 ? ph : mAttrs.height;
+ } else {
+ w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
+ h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
+ }
+
+ if (!mParentFrame.equals(pf)) {
+ //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
+ // + " to " + pf);
+ mParentFrame.set(pf);
+ mContentChanged = true;
+ }
+
+ final Rect content = mContentFrame;
+ content.set(cf);
+
+ final Rect visible = mVisibleFrame;
+ visible.set(vf);
+
+ final Rect frame = mFrame;
+ final int fw = frame.width();
+ final int fh = frame.height();
+
+ //System.out.println("In: w=" + w + " h=" + h + " container=" +
+ // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
+
+ Gravity.apply(mAttrs.gravity, w, h, container,
+ (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
+ (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
+
+ //System.out.println("Out: " + mFrame);
+
+ // Now make sure the window fits in the overall display.
+ Gravity.applyDisplay(mAttrs.gravity, df, frame);
+
+ // Make sure the content and visible frames are inside of the
+ // final window frame.
+ if (content.left < frame.left) content.left = frame.left;
+ if (content.top < frame.top) content.top = frame.top;
+ if (content.right > frame.right) content.right = frame.right;
+ if (content.bottom > frame.bottom) content.bottom = frame.bottom;
+ if (visible.left < frame.left) visible.left = frame.left;
+ if (visible.top < frame.top) visible.top = frame.top;
+ if (visible.right > frame.right) visible.right = frame.right;
+ if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
+
+ final Rect contentInsets = mContentInsets;
+ contentInsets.left = content.left-frame.left;
+ contentInsets.top = content.top-frame.top;
+ contentInsets.right = frame.right-content.right;
+ contentInsets.bottom = frame.bottom-content.bottom;
+
+ final Rect visibleInsets = mVisibleInsets;
+ visibleInsets.left = visible.left-frame.left;
+ visibleInsets.top = visible.top-frame.top;
+ visibleInsets.right = frame.right-visible.right;
+ visibleInsets.bottom = frame.bottom-visible.bottom;
+
+ if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
+ mService.updateWallpaperOffsetLocked(this, mService.mDisplay.getWidth(),
+ mService.mDisplay.getHeight(), false);
+ }
+
+ if (WindowManagerService.localLOGV) {
+ //if ("com.google.android.youtube".equals(mAttrs.packageName)
+ // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
+ Slog.v(WindowManagerService.TAG, "Resolving (mRequestedWidth="
+ + mRequestedWidth + ", mRequestedheight="
+ + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
+ + "): frame=" + mFrame.toShortString()
+ + " ci=" + contentInsets.toShortString()
+ + " vi=" + visibleInsets.toShortString());
+ //}
+ }
+ }
+
+ public Rect getFrameLw() {
+ return mFrame;
+ }
+
+ public Rect getShownFrameLw() {
+ return mShownFrame;
+ }
+
+ public Rect getDisplayFrameLw() {
+ return mDisplayFrame;
+ }
+
+ public Rect getContentFrameLw() {
+ return mContentFrame;
+ }
+
+ public Rect getVisibleFrameLw() {
+ return mVisibleFrame;
+ }
+
+ public boolean getGivenInsetsPendingLw() {
+ return mGivenInsetsPending;
+ }
+
+ public Rect getGivenContentInsetsLw() {
+ return mGivenContentInsets;
+ }
+
+ public Rect getGivenVisibleInsetsLw() {
+ return mGivenVisibleInsets;
+ }
+
+ public WindowManager.LayoutParams getAttrs() {
+ return mAttrs;
+ }
+
+ public int getSurfaceLayer() {
+ return mLayer;
+ }
+
+ public IApplicationToken getAppToken() {
+ return mAppToken != null ? mAppToken.appToken : null;
+ }
+
+ public long getInputDispatchingTimeoutNanos() {
+ return mAppToken != null
+ ? mAppToken.inputDispatchingTimeoutNanos
+ : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
+ }
+
+ public boolean hasAppShownWindows() {
+ return mAppToken != null ? mAppToken.firstWindowDrawn : false;
+ }
+
+ public void setAnimation(Animation anim) {
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Setting animation in " + this + ": " + anim);
+ mAnimating = false;
+ mLocalAnimating = false;
+ mAnimation = anim;
+ mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
+ mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale);
+ }
+
+ public void clearAnimation() {
+ if (mAnimation != null) {
+ mAnimating = true;
+ mLocalAnimating = false;
+ mAnimation.cancel();
+ mAnimation = null;
+ }
+ }
+
+ Surface createSurfaceLocked() {
+ if (mSurface == null) {
+ mReportDestroySurface = false;
+ mSurfacePendingDestroy = false;
+ mDrawPending = true;
+ mCommitDrawPending = false;
+ mReadyToShow = false;
+ if (mAppToken != null) {
+ mAppToken.allDrawn = false;
+ }
+
+ int flags = 0;
+
+ if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
+ flags |= Surface.SECURE;
+ }
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(
+ WindowManagerService.TAG, "Creating surface in session "
+ + mSession.mSurfaceSession + " window " + this
+ + " w=" + mFrame.width()
+ + " h=" + mFrame.height() + " format="
+ + mAttrs.format + " flags=" + flags);
+
+ int w = mFrame.width();
+ int h = mFrame.height();
+ if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
+ // for a scaled surface, we always want the requested
+ // size.
+ w = mRequestedWidth;
+ h = mRequestedHeight;
+ }
+
+ // Something is wrong and SurfaceFlinger will not like this,
+ // try to revert to sane values
+ if (w <= 0) w = 1;
+ if (h <= 0) h = 1;
+
+ mSurfaceShown = false;
+ mSurfaceLayer = 0;
+ mSurfaceAlpha = 1;
+ mSurfaceX = 0;
+ mSurfaceY = 0;
+ mSurfaceW = w;
+ mSurfaceH = h;
+ try {
+ final boolean isHwAccelerated = (mAttrs.flags &
+ WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
+ final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format;
+ if (isHwAccelerated && mAttrs.format == PixelFormat.OPAQUE) {
+ flags |= Surface.OPAQUE;
+ }
+ mSurface = new Surface(
+ mSession.mSurfaceSession, mSession.mPid,
+ mAttrs.getTitle().toString(),
+ 0, w, h, format, flags);
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " CREATE SURFACE "
+ + mSurface + " IN SESSION "
+ + mSession.mSurfaceSession
+ + ": pid=" + mSession.mPid + " format="
+ + mAttrs.format + " flags=0x"
+ + Integer.toHexString(flags)
+ + " / " + this);
+ } catch (Surface.OutOfResourcesException e) {
+ Slog.w(WindowManagerService.TAG, "OutOfResourcesException creating surface");
+ mService.reclaimSomeSurfaceMemoryLocked(this, "create");
+ return null;
+ } catch (Exception e) {
+ Slog.e(WindowManagerService.TAG, "Exception creating surface", e);
+ return null;
+ }
+
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Got surface: " + mSurface
+ + ", set left=" + mFrame.left + " top=" + mFrame.top
+ + ", animLayer=" + mAnimLayer);
+ if (WindowManagerService.SHOW_TRANSACTIONS) {
+ Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
+ WindowManagerService.logSurface(this, "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
+ mFrame.width() + "x" + mFrame.height() + "), layer=" +
+ mAnimLayer + " HIDE", null);
+ }
+ Surface.openTransaction();
+ try {
+ try {
+ mSurfaceX = mFrame.left + mXOffset;
+ mSurfaceY = mFrame.top + mYOffset;
+ mSurface.setPosition(mSurfaceX, mSurfaceY);
+ mSurfaceLayer = mAnimLayer;
+ mSurface.setLayer(mAnimLayer);
+ mSurfaceShown = false;
+ mSurface.hide();
+ if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
+ if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "DITHER", null);
+ mSurface.setFlags(Surface.SURFACE_DITHER,
+ Surface.SURFACE_DITHER);
+ }
+ } catch (RuntimeException e) {
+ Slog.w(WindowManagerService.TAG, "Error creating surface in " + w, e);
+ mService.reclaimSomeSurfaceMemoryLocked(this, "create-init");
+ }
+ mLastHidden = true;
+ } finally {
+ Surface.closeTransaction();
+ if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION createSurfaceLocked");
+ }
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Created surface " + this);
+ }
+ return mSurface;
+ }
+
+ void destroySurfaceLocked() {
+ if (mAppToken != null && this == mAppToken.startingWindow) {
+ mAppToken.startingDisplayed = false;
+ }
+
+ if (mSurface != null) {
+ mDrawPending = false;
+ mCommitDrawPending = false;
+ mReadyToShow = false;
+
+ int i = mChildWindows.size();
+ while (i > 0) {
+ i--;
+ WindowState c = mChildWindows.get(i);
+ c.mAttachedHidden = true;
+ }
+
+ if (mReportDestroySurface) {
+ mReportDestroySurface = false;
+ mSurfacePendingDestroy = true;
+ try {
+ mClient.dispatchGetNewSurface();
+ // We'll really destroy on the next time around.
+ return;
+ } catch (RemoteException e) {
+ }
+ }
+
+ try {
+ if (WindowManagerService.DEBUG_VISIBILITY) {
+ RuntimeException e = null;
+ if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
+ Slog.w(WindowManagerService.TAG, "Window " + this + " destroying surface "
+ + mSurface + ", session " + mSession, e);
+ }
+ if (WindowManagerService.SHOW_TRANSACTIONS) {
+ RuntimeException e = null;
+ if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
+ if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "DESTROY", e);
+ }
+ mSurface.destroy();
+ } catch (RuntimeException e) {
+ Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window " + this
+ + " surface " + mSurface + " session " + mSession
+ + ": " + e.toString());
+ }
+
+ mSurfaceShown = false;
+ mSurface = null;
+ }
+ }
+
+ boolean finishDrawingLocked() {
+ if (mDrawPending) {
+ if (WindowManagerService.SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) Slog.v(
+ WindowManagerService.TAG, "finishDrawingLocked: " + mSurface);
+ mCommitDrawPending = true;
+ mDrawPending = false;
+ return true;
+ }
+ return false;
+ }
+
+ // This must be called while inside a transaction.
+ boolean commitFinishDrawingLocked(long currentTime) {
+ //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
+ if (!mCommitDrawPending) {
+ return false;
+ }
+ mCommitDrawPending = false;
+ mReadyToShow = true;
+ final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
+ final AppWindowToken atoken = mAppToken;
+ if (atoken == null || atoken.allDrawn || starting) {
+ performShowLocked();
+ }
+ return true;
+ }
+
+ // This must be called while inside a transaction.
+ boolean performShowLocked() {
+ if (WindowManagerService.DEBUG_VISIBILITY) {
+ RuntimeException e = null;
+ if (!WindowManagerService.HIDE_STACK_CRAWLS) {
+ e = new RuntimeException();
+ e.fillInStackTrace();
+ }
+ Slog.v(WindowManagerService.TAG, "performShow on " + this
+ + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
+ + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
+ }
+ if (mReadyToShow && isReadyForDisplay()) {
+ if (WindowManagerService.SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) WindowManagerService.logSurface(this,
+ "SHOW (performShowLocked)", null);
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Showing " + this
+ + " during animation: policyVis=" + mPolicyVisibility
+ + " attHidden=" + mAttachedHidden
+ + " tok.hiddenRequested="
+ + (mAppToken != null ? mAppToken.hiddenRequested : false)
+ + " tok.hidden="
+ + (mAppToken != null ? mAppToken.hidden : false)
+ + " animating=" + mAnimating
+ + " tok animating="
+ + (mAppToken != null ? mAppToken.animating : false));
+ if (!mService.showSurfaceRobustlyLocked(this)) {
+ return false;
+ }
+ mLastAlpha = -1;
+ mHasDrawn = true;
+ mLastHidden = false;
+ mReadyToShow = false;
+ mService.enableScreenIfNeededLocked();
+
+ mService.applyEnterAnimationLocked(this);
+
+ int i = mChildWindows.size();
+ while (i > 0) {
+ i--;
+ WindowState c = mChildWindows.get(i);
+ if (c.mAttachedHidden) {
+ c.mAttachedHidden = false;
+ if (c.mSurface != null) {
+ c.performShowLocked();
+ // It hadn't been shown, which means layout not
+ // performed on it, so now we want to make sure to
+ // do a layout. If called from within the transaction
+ // loop, this will cause it to restart with a new
+ // layout.
+ mService.mLayoutNeeded = true;
+ }
+ }
+ }
+
+ if (mAttrs.type != TYPE_APPLICATION_STARTING
+ && mAppToken != null) {
+ mAppToken.firstWindowDrawn = true;
+
+ if (mAppToken.startingData != null) {
+ if (WindowManagerService.DEBUG_STARTING_WINDOW || WindowManagerService.DEBUG_ANIM) Slog.v(WindowManagerService.TAG,
+ "Finish starting " + mToken
+ + ": first real window is shown, no animation");
+ // If this initial window is animating, stop it -- we
+ // will do an animation to reveal it from behind the
+ // starting window, so there is no need for it to also
+ // be doing its own stuff.
+ if (mAnimation != null) {
+ mAnimation.cancel();
+ mAnimation = null;
+ // Make sure we clean up the animation.
+ mAnimating = true;
+ }
+ mService.mFinishedStarting.add(mAppToken);
+ mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
+ }
+ mAppToken.updateReportedVisibilityLocked();
+ }
+ }
+ return true;
+ }
+
+ // This must be called while inside a transaction. Returns true if
+ // there is more animation to run.
+ boolean stepAnimationLocked(long currentTime, int dw, int dh) {
+ if (!mService.mDisplayFrozen && mService.mPolicy.isScreenOn()) {
+ // We will run animations as long as the display isn't frozen.
+
+ if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
+ mHasTransformation = true;
+ mHasLocalTransformation = true;
+ if (!mLocalAnimating) {
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Starting animation in " + this +
+ " @ " + currentTime + ": ww=" + mFrame.width() + " wh=" + mFrame.height() +
+ " dw=" + dw + " dh=" + dh + " scale=" + mService.mWindowAnimationScale);
+ mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
+ mAnimation.setStartTime(currentTime);
+ mLocalAnimating = true;
+ mAnimating = true;
+ }
+ mTransformation.clear();
+ final boolean more = mAnimation.getTransformation(
+ currentTime, mTransformation);
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Stepped animation in " + this +
+ ": more=" + more + ", xform=" + mTransformation);
+ if (more) {
+ // we're not done!
+ return true;
+ }
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Finished animation in " + this +
+ " @ " + currentTime);
+
+ if (mAnimation != null) {
+ mAnimation.cancel();
+ mAnimation = null;
+ }
+ //WindowManagerService.this.dump();
+ }
+ mHasLocalTransformation = false;
+ if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
+ && mAppToken.animation != null) {
+ // When our app token is animating, we kind-of pretend like
+ // we are as well. Note the mLocalAnimating mAnimationIsEntrance
+ // part of this check means that we will only do this if
+ // our window is not currently exiting, or it is not
+ // locally animating itself. The idea being that one that
+ // is exiting and doing a local animation should be removed
+ // once that animation is done.
+ mAnimating = true;
+ mHasTransformation = true;
+ mTransformation.clear();
+ return false;
+ } else if (mHasTransformation) {
+ // Little trick to get through the path below to act like
+ // we have finished an animation.
+ mAnimating = true;
+ } else if (isAnimating()) {
+ mAnimating = true;
+ }
+ } else if (mAnimation != null) {
+ // If the display is frozen, and there is a pending animation,
+ // clear it and make sure we run the cleanup code.
+ mAnimating = true;
+ mLocalAnimating = true;
+ mAnimation.cancel();
+ mAnimation = null;
+ }
+
+ if (!mAnimating && !mLocalAnimating) {
+ return false;
+ }
+
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "Animation done in " + this + ": exiting=" + mExiting
+ + ", reportedVisible="
+ + (mAppToken != null ? mAppToken.reportedVisible : false));
+
+ mAnimating = false;
+ mLocalAnimating = false;
+ if (mAnimation != null) {
+ mAnimation.cancel();
+ mAnimation = null;
+ }
+ mAnimLayer = mLayer;
+ if (mIsImWindow) {
+ mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
+ } else if (mIsWallpaper) {
+ mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
+ }
+ if (WindowManagerService.DEBUG_LAYERS) Slog.v(WindowManagerService.TAG, "Stepping win " + this
+ + " anim layer: " + mAnimLayer);
+ mHasTransformation = false;
+ mHasLocalTransformation = false;
+ if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
+ if (WindowManagerService.DEBUG_VISIBILITY) {
+ Slog.v(WindowManagerService.TAG, "Policy visibility changing after anim in " + this + ": "
+ + mPolicyVisibilityAfterAnim);
+ }
+ mPolicyVisibility = mPolicyVisibilityAfterAnim;
+ if (!mPolicyVisibility) {
+ if (mService.mCurrentFocus == this) {
+ mService.mFocusMayChange = true;
+ }
+ // Window is no longer visible -- make sure if we were waiting
+ // for it to be displayed before enabling the display, that
+ // we allow the display to be enabled now.
+ mService.enableScreenIfNeededLocked();
+ }
+ }
+ mTransformation.clear();
+ if (mHasDrawn
+ && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
+ && mAppToken != null
+ && mAppToken.firstWindowDrawn
+ && mAppToken.startingData != null) {
+ if (WindowManagerService.DEBUG_STARTING_WINDOW) Slog.v(WindowManagerService.TAG, "Finish starting "
+ + mToken + ": first real window done animating");
+ mService.mFinishedStarting.add(mAppToken);
+ mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
+ }
+
+ finishExit();
+
+ if (mAppToken != null) {
+ mAppToken.updateReportedVisibilityLocked();
+ }
+
+ return false;
+ }
+
+ void finishExit() {
+ if (WindowManagerService.DEBUG_ANIM) Slog.v(
+ WindowManagerService.TAG, "finishExit in " + this
+ + ": exiting=" + mExiting
+ + " remove=" + mRemoveOnExit
+ + " windowAnimating=" + isWindowAnimating());
+
+ final int N = mChildWindows.size();
+ for (int i=0; i<N; i++) {
+ mChildWindows.get(i).finishExit();
+ }
+
+ if (!mExiting) {
+ return;
+ }
+
+ if (isWindowAnimating()) {
+ return;
+ }
+
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Exit animation finished in " + this
+ + ": remove=" + mRemoveOnExit);
+ if (mSurface != null) {
+ mService.mDestroySurface.add(this);
+ mDestroying = true;
+ if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "HIDE (finishExit)", null);
+ mSurfaceShown = false;
+ try {
+ mSurface.hide();
+ } catch (RuntimeException e) {
+ Slog.w(WindowManagerService.TAG, "Error hiding surface in " + this, e);
+ }
+ mLastHidden = true;
+ }
+ mExiting = false;
+ if (mRemoveOnExit) {
+ mService.mPendingRemove.add(this);
+ mRemoveOnExit = false;
+ }
+ }
+
+ boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
+ if (dsdx < .99999f || dsdx > 1.00001f) return false;
+ if (dtdy < .99999f || dtdy > 1.00001f) return false;
+ if (dtdx < -.000001f || dtdx > .000001f) return false;
+ if (dsdy < -.000001f || dsdy > .000001f) return false;
+ return true;
+ }
+
+ void computeShownFrameLocked() {
+ final boolean selfTransformation = mHasLocalTransformation;
+ Transformation attachedTransformation =
+ (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
+ ? mAttachedWindow.mTransformation : null;
+ Transformation appTransformation =
+ (mAppToken != null && mAppToken.hasTransformation)
+ ? mAppToken.transformation : null;
+
+ // Wallpapers are animated based on the "real" window they
+ // are currently targeting.
+ if (mAttrs.type == TYPE_WALLPAPER && mService.mLowerWallpaperTarget == null
+ && mService.mWallpaperTarget != null) {
+ if (mService.mWallpaperTarget.mHasLocalTransformation &&
+ mService.mWallpaperTarget.mAnimation != null &&
+ !mService.mWallpaperTarget.mAnimation.getDetachWallpaper()) {
+ attachedTransformation = mService.mWallpaperTarget.mTransformation;
+ if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
+ Slog.v(WindowManagerService.TAG, "WP target attached xform: " + attachedTransformation);
+ }
+ }
+ if (mService.mWallpaperTarget.mAppToken != null &&
+ mService.mWallpaperTarget.mAppToken.hasTransformation &&
+ mService.mWallpaperTarget.mAppToken.animation != null &&
+ !mService.mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
+ appTransformation = mService.mWallpaperTarget.mAppToken.transformation;
+ if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
+ Slog.v(WindowManagerService.TAG, "WP target app xform: " + appTransformation);
+ }
+ }
+ }
+
+ final boolean screenAnimation = mService.mScreenRotationAnimation != null
+ && mService.mScreenRotationAnimation.isAnimating();
+ if (selfTransformation || attachedTransformation != null
+ || appTransformation != null || screenAnimation) {
+ // cache often used attributes locally
+ final Rect frame = mFrame;
+ final float tmpFloats[] = mService.mTmpFloats;
+ final Matrix tmpMatrix = mTmpMatrix;
+
+ // Compute the desired transformation.
+ tmpMatrix.setTranslate(0, 0);
+ if (selfTransformation) {
+ tmpMatrix.postConcat(mTransformation.getMatrix());
+ }
+ tmpMatrix.postTranslate(frame.left + mXOffset, frame.top + mYOffset);
+ if (attachedTransformation != null) {
+ tmpMatrix.postConcat(attachedTransformation.getMatrix());
+ }
+ if (appTransformation != null) {
+ tmpMatrix.postConcat(appTransformation.getMatrix());
+ }
+ if (screenAnimation) {
+ tmpMatrix.postConcat(
+ mService.mScreenRotationAnimation.getEnterTransformation().getMatrix());
+ }
+
+ // "convert" it into SurfaceFlinger's format
+ // (a 2x2 matrix + an offset)
+ // Here we must not transform the position of the surface
+ // since it is already included in the transformation.
+ //Slog.i(TAG, "Transform: " + matrix);
+
+ mHaveMatrix = true;
+ tmpMatrix.getValues(tmpFloats);
+ mDsDx = tmpFloats[Matrix.MSCALE_X];
+ mDtDx = tmpFloats[Matrix.MSKEW_Y];
+ mDsDy = tmpFloats[Matrix.MSKEW_X];
+ mDtDy = tmpFloats[Matrix.MSCALE_Y];
+ int x = (int)tmpFloats[Matrix.MTRANS_X];
+ int y = (int)tmpFloats[Matrix.MTRANS_Y];
+ int w = frame.width();
+ int h = frame.height();
+ mShownFrame.set(x, y, x+w, y+h);
+
+ // Now set the alpha... but because our current hardware
+ // can't do alpha transformation on a non-opaque surface,
+ // turn it off if we are running an animation that is also
+ // transforming since it is more important to have that
+ // animation be smooth.
+ mShownAlpha = mAlpha;
+ if (!mService.mLimitedAlphaCompositing
+ || (!PixelFormat.formatHasAlpha(mAttrs.format)
+ || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
+ && x == frame.left && y == frame.top))) {
+ //Slog.i(TAG, "Applying alpha transform");
+ if (selfTransformation) {
+ mShownAlpha *= mTransformation.getAlpha();
+ }
+ if (attachedTransformation != null) {
+ mShownAlpha *= attachedTransformation.getAlpha();
+ }
+ if (appTransformation != null) {
+ mShownAlpha *= appTransformation.getAlpha();
+ }
+ if (screenAnimation) {
+ mShownAlpha *=
+ mService.mScreenRotationAnimation.getEnterTransformation().getAlpha();
+ }
+ } else {
+ //Slog.i(TAG, "Not applying alpha transform");
+ }
+
+ if (WindowManagerService.localLOGV) Slog.v(
+ WindowManagerService.TAG, "Continuing animation in " + this +
+ ": " + mShownFrame +
+ ", alpha=" + mTransformation.getAlpha());
+ return;
+ }
+
+ mShownFrame.set(mFrame);
+ if (mXOffset != 0 || mYOffset != 0) {
+ mShownFrame.offset(mXOffset, mYOffset);
+ }
+ mShownAlpha = mAlpha;
+ mHaveMatrix = false;
+ mDsDx = 1;
+ mDtDx = 0;
+ mDsDy = 0;
+ mDtDy = 1;
+ }
+
+ /**
+ * Is this window visible? It is not visible if there is no
+ * surface, or we are in the process of running an exit animation
+ * that will remove the surface, or its app token has been hidden.
+ */
+ public boolean isVisibleLw() {
+ final AppWindowToken atoken = mAppToken;
+ return mSurface != null && mPolicyVisibility && !mAttachedHidden
+ && (atoken == null || !atoken.hiddenRequested)
+ && !mExiting && !mDestroying;
+ }
+
+ /**
+ * Like {@link #isVisibleLw}, but also counts a window that is currently
+ * "hidden" behind the keyguard as visible. This allows us to apply
+ * things like window flags that impact the keyguard.
+ * XXX I am starting to think we need to have ANOTHER visibility flag
+ * for this "hidden behind keyguard" state rather than overloading
+ * mPolicyVisibility. Ungh.
+ */
+ public boolean isVisibleOrBehindKeyguardLw() {
+ final AppWindowToken atoken = mAppToken;
+ return mSurface != null && !mAttachedHidden
+ && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
+ && !mDrawPending && !mCommitDrawPending
+ && !mExiting && !mDestroying;
+ }
+
+ /**
+ * Is this window visible, ignoring its app token? It is not visible
+ * if there is no surface, or we are in the process of running an exit animation
+ * that will remove the surface.
+ */
+ public boolean isWinVisibleLw() {
+ final AppWindowToken atoken = mAppToken;
+ return mSurface != null && mPolicyVisibility && !mAttachedHidden
+ && (atoken == null || !atoken.hiddenRequested || atoken.animating)
+ && !mExiting && !mDestroying;
+ }
+
+ /**
+ * The same as isVisible(), but follows the current hidden state of
+ * the associated app token, not the pending requested hidden state.
+ */
+ boolean isVisibleNow() {
+ return mSurface != null && mPolicyVisibility && !mAttachedHidden
+ && !mRootToken.hidden && !mExiting && !mDestroying;
+ }
+
+ /**
+ * Can this window possibly be a drag/drop target? The test here is
+ * a combination of the above "visible now" with the check that the
+ * Input Manager uses when discarding windows from input consideration.
+ */
+ boolean isPotentialDragTarget() {
+ return isVisibleNow() && (mInputChannel != null) && !mRemoved;
+ }
+
+ /**
+ * Same as isVisible(), but we also count it as visible between the
+ * call to IWindowSession.add() and the first relayout().
+ */
+ boolean isVisibleOrAdding() {
+ final AppWindowToken atoken = mAppToken;
+ return ((mSurface != null && !mReportDestroySurface)
+ || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
+ && mPolicyVisibility && !mAttachedHidden
+ && (atoken == null || !atoken.hiddenRequested)
+ && !mExiting && !mDestroying;
+ }
+
+ /**
+ * Is this window currently on-screen? It is on-screen either if it
+ * is visible or it is currently running an animation before no longer
+ * being visible.
+ */
+ boolean isOnScreen() {
+ final AppWindowToken atoken = mAppToken;
+ if (atoken != null) {
+ return mSurface != null && mPolicyVisibility && !mDestroying
+ && ((!mAttachedHidden && !atoken.hiddenRequested)
+ || mAnimation != null || atoken.animation != null);
+ } else {
+ return mSurface != null && mPolicyVisibility && !mDestroying
+ && (!mAttachedHidden || mAnimation != null);
+ }
+ }
+
+ /**
+ * Like isOnScreen(), but we don't return true if the window is part
+ * of a transition that has not yet been started.
+ */
+ boolean isReadyForDisplay() {
+ if (mRootToken.waitingToShow &&
+ mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
+ return false;
+ }
+ final AppWindowToken atoken = mAppToken;
+ final boolean animating = atoken != null
+ ? (atoken.animation != null) : false;
+ return mSurface != null && mPolicyVisibility && !mDestroying
+ && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
+ && !mRootToken.hidden)
+ || mAnimation != null || animating);
+ }
+
+ /** Is the window or its container currently animating? */
+ boolean isAnimating() {
+ final WindowState attached = mAttachedWindow;
+ final AppWindowToken atoken = mAppToken;
+ return mAnimation != null
+ || (attached != null && attached.mAnimation != null)
+ || (atoken != null &&
+ (atoken.animation != null
+ || atoken.inPendingTransaction));
+ }
+
+ /** Is this window currently animating? */
+ boolean isWindowAnimating() {
+ return mAnimation != null;
+ }
+
+ /**
+ * Like isOnScreen, but returns false if the surface hasn't yet
+ * been drawn.
+ */
+ public boolean isDisplayedLw() {
+ final AppWindowToken atoken = mAppToken;
+ return mSurface != null && mPolicyVisibility && !mDestroying
+ && !mDrawPending && !mCommitDrawPending
+ && ((!mAttachedHidden &&
+ (atoken == null || !atoken.hiddenRequested))
+ || mAnimating);
+ }
+
+ /**
+ * Returns true if the window has a surface that it has drawn a
+ * complete UI in to.
+ */
+ public boolean isDrawnLw() {
+ final AppWindowToken atoken = mAppToken;
+ return mSurface != null && !mDestroying
+ && !mDrawPending && !mCommitDrawPending;
+ }
+
+ /**
+ * Return true if the window is opaque and fully drawn. This indicates
+ * it may obscure windows behind it.
+ */
+ boolean isOpaqueDrawn() {
+ return (mAttrs.format == PixelFormat.OPAQUE
+ || mAttrs.type == TYPE_WALLPAPER)
+ && mSurface != null && mAnimation == null
+ && (mAppToken == null || mAppToken.animation == null)
+ && !mDrawPending && !mCommitDrawPending;
+ }
+
+ /**
+ * Return whether this window is wanting to have a translation
+ * animation applied to it for an in-progress move. (Only makes
+ * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
+ */
+ boolean shouldAnimateMove() {
+ return mContentChanged && !mExiting && !mLastHidden && !mService.mDisplayFrozen
+ && (mFrame.top != mLastFrame.top
+ || mFrame.left != mLastFrame.left)
+ && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove())
+ && mService.mPolicy.isScreenOn();
+ }
+
+ boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
+ return
+ // only if the application is requesting compatible window
+ (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0 &&
+ // only if it's visible
+ mHasDrawn && mViewVisibility == View.VISIBLE &&
+ // and only if the application fills the compatible screen
+ mFrame.left <= mService.mCompatibleScreenFrame.left &&
+ mFrame.top <= mService.mCompatibleScreenFrame.top &&
+ mFrame.right >= mService.mCompatibleScreenFrame.right &&
+ mFrame.bottom >= mService.mCompatibleScreenFrame.bottom;
+ }
+
+ boolean isFullscreen(int screenWidth, int screenHeight) {
+ return mFrame.left <= 0 && mFrame.top <= 0 &&
+ mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
+ }
+
+ void removeLocked() {
+ disposeInputChannel();
+
+ if (mAttachedWindow != null) {
+ if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(WindowManagerService.TAG, "Removing " + this + " from " + mAttachedWindow);
+ mAttachedWindow.mChildWindows.remove(this);
+ }
+ destroySurfaceLocked();
+ mSession.windowRemovedLocked();
+ try {
+ mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
+ } catch (RuntimeException e) {
+ // Ignore if it has already been removed (usually because
+ // we are doing this as part of processing a death note.)
+ }
+ }
+
+ void disposeInputChannel() {
+ if (mInputChannel != null) {
+ mService.mInputManager.unregisterInputChannel(mInputChannel);
+
+ mInputChannel.dispose();
+ mInputChannel = null;
+ }
+ }
+
+ private class DeathRecipient implements IBinder.DeathRecipient {
+ public void binderDied() {
+ try {
+ synchronized(mService.mWindowMap) {
+ WindowState win = mService.windowForClientLocked(mSession, mClient, false);
+ Slog.i(WindowManagerService.TAG, "WIN DEATH: " + win);
+ if (win != null) {
+ mService.removeWindowLocked(mSession, win);
+ }
+ }
+ } catch (IllegalArgumentException ex) {
+ // This will happen if the window has already been
+ // removed.
+ }
+ }
+ }
+
+ /** Returns true if this window desires key events. */
+ public final boolean canReceiveKeys() {
+ return isVisibleOrAdding()
+ && (mViewVisibility == View.VISIBLE)
+ && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
+ }
+
+ public boolean hasDrawnLw() {
+ return mHasDrawn;
+ }
+
+ public boolean showLw(boolean doAnimation) {
+ return showLw(doAnimation, true);
+ }
+
+ boolean showLw(boolean doAnimation, boolean requestAnim) {
+ if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
+ return false;
+ }
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Policy visibility true: " + this);
+ if (doAnimation) {
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "doAnimation: mPolicyVisibility="
+ + mPolicyVisibility + " mAnimation=" + mAnimation);
+ if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOn()) {
+ doAnimation = false;
+ } else if (mPolicyVisibility && mAnimation == null) {
+ // Check for the case where we are currently visible and
+ // not animating; we do not want to do animation at such a
+ // point to become visible when we already are.
+ doAnimation = false;
+ }
+ }
+ mPolicyVisibility = true;
+ mPolicyVisibilityAfterAnim = true;
+ if (doAnimation) {
+ mService.applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
+ }
+ if (requestAnim) {
+ mService.requestAnimationLocked(0);
+ }
+ return true;
+ }
+
+ public boolean hideLw(boolean doAnimation) {
+ return hideLw(doAnimation, true);
+ }
+
+ boolean hideLw(boolean doAnimation, boolean requestAnim) {
+ if (doAnimation) {
+ if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOn()) {
+ doAnimation = false;
+ }
+ }
+ boolean current = doAnimation ? mPolicyVisibilityAfterAnim
+ : mPolicyVisibility;
+ if (!current) {
+ return false;
+ }
+ if (doAnimation) {
+ mService.applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
+ if (mAnimation == null) {
+ doAnimation = false;
+ }
+ }
+ if (doAnimation) {
+ mPolicyVisibilityAfterAnim = false;
+ } else {
+ if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Policy visibility false: " + this);
+ mPolicyVisibilityAfterAnim = false;
+ mPolicyVisibility = false;
+ // Window is no longer visible -- make sure if we were waiting
+ // for it to be displayed before enabling the display, that
+ // we allow the display to be enabled now.
+ mService.enableScreenIfNeededLocked();
+ if (mService.mCurrentFocus == this) {
+ mService.mFocusMayChange = true;
+ }
+ }
+ if (requestAnim) {
+ mService.requestAnimationLocked(0);
+ }
+ return true;
+ }
+
+ public void getTouchableRegion(Region outRegion) {
+ final Rect frame = mFrame;
+ switch (mTouchableInsets) {
+ default:
+ case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
+ outRegion.set(frame);
+ break;
+ case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT: {
+ final Rect inset = mGivenContentInsets;
+ outRegion.set(
+ frame.left + inset.left, frame.top + inset.top,
+ frame.right - inset.right, frame.bottom - inset.bottom);
+ break;
+ }
+ case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE: {
+ final Rect inset = mGivenVisibleInsets;
+ outRegion.set(
+ frame.left + inset.left, frame.top + inset.top,
+ frame.right - inset.right, frame.bottom - inset.bottom);
+ break;
+ }
+ case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: {
+ final Region givenTouchableRegion = mGivenTouchableRegion;
+ outRegion.set(givenTouchableRegion);
+ outRegion.translate(frame.left, frame.top);
+ break;
+ }
+ }
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix); pw.print("mSession="); pw.print(mSession);
+ pw.print(" mClient="); pw.println(mClient.asBinder());
+ pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
+ if (mAttachedWindow != null || mLayoutAttached) {
+ pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
+ pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
+ }
+ if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
+ pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
+ pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
+ pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
+ pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
+ }
+ pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
+ pw.print(" mSubLayer="); pw.print(mSubLayer);
+ pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
+ pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
+ : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
+ pw.print("="); pw.print(mAnimLayer);
+ pw.print(" mLastLayer="); pw.println(mLastLayer);
+ if (mSurface != null) {
+ pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
+ pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
+ pw.print(" layer="); pw.print(mSurfaceLayer);
+ pw.print(" alpha="); pw.print(mSurfaceAlpha);
+ pw.print(" rect=("); pw.print(mSurfaceX);
+ pw.print(","); pw.print(mSurfaceY);
+ pw.print(") "); pw.print(mSurfaceW);
+ pw.print(" x "); pw.println(mSurfaceH);
+ }
+ pw.print(prefix); pw.print("mToken="); pw.println(mToken);
+ pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
+ if (mAppToken != null) {
+ pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
+ }
+ if (mTargetAppToken != null) {
+ pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
+ }
+ pw.print(prefix); pw.print("mViewVisibility=0x");
+ pw.print(Integer.toHexString(mViewVisibility));
+ pw.print(" mLastHidden="); pw.print(mLastHidden);
+ pw.print(" mHaveFrame="); pw.print(mHaveFrame);
+ pw.print(" mObscured="); pw.println(mObscured);
+ if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
+ pw.print(prefix); pw.print("mPolicyVisibility=");
+ pw.print(mPolicyVisibility);
+ pw.print(" mPolicyVisibilityAfterAnim=");
+ pw.print(mPolicyVisibilityAfterAnim);
+ pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
+ }
+ if (!mRelayoutCalled) {
+ pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
+ }
+ pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
+ pw.print(" h="); pw.print(mRequestedHeight);
+ pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
+ if (mXOffset != 0 || mYOffset != 0) {
+ pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
+ pw.print(" y="); pw.println(mYOffset);
+ }
+ pw.print(prefix); pw.print("mGivenContentInsets=");
+ mGivenContentInsets.printShortString(pw);
+ pw.print(" mGivenVisibleInsets=");
+ mGivenVisibleInsets.printShortString(pw);
+ pw.println();
+ if (mTouchableInsets != 0 || mGivenInsetsPending) {
+ pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
+ pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
+ }
+ pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
+ pw.print(prefix); pw.print("mShownFrame=");
+ mShownFrame.printShortString(pw);
+ pw.print(" last="); mLastShownFrame.printShortString(pw);
+ pw.println();
+ pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
+ pw.print(" last="); mLastFrame.printShortString(pw);
+ pw.println();
+ pw.print(prefix); pw.print("mContainingFrame=");
+ mContainingFrame.printShortString(pw);
+ pw.print(" mParentFrame=");
+ mParentFrame.printShortString(pw);
+ pw.print(" mDisplayFrame=");
+ mDisplayFrame.printShortString(pw);
+ pw.println();
+ pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
+ pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
+ pw.println();
+ pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
+ pw.print(" last="); mLastContentInsets.printShortString(pw);
+ pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
+ pw.print(" last="); mLastVisibleInsets.printShortString(pw);
+ pw.println();
+ if (mAnimating || mLocalAnimating || mAnimationIsEntrance
+ || mAnimation != null) {
+ pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
+ pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
+ pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
+ pw.print(" mAnimation="); pw.println(mAnimation);
+ }
+ if (mHasTransformation || mHasLocalTransformation) {
+ pw.print(prefix); pw.print("XForm: has=");
+ pw.print(mHasTransformation);
+ pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
+ pw.print(" "); mTransformation.printShortString(pw);
+ pw.println();
+ }
+ if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
+ pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
+ pw.print(" mAlpha="); pw.print(mAlpha);
+ pw.print(" mLastAlpha="); pw.println(mLastAlpha);
+ }
+ if (mHaveMatrix) {
+ pw.print(prefix); pw.print("mDsDx="); pw.print(mDsDx);
+ pw.print(" mDtDx="); pw.print(mDtDx);
+ pw.print(" mDsDy="); pw.print(mDsDy);
+ pw.print(" mDtDy="); pw.println(mDtDy);
+ }
+ pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
+ pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
+ pw.print(" mReadyToShow="); pw.print(mReadyToShow);
+ pw.print(" mHasDrawn="); pw.println(mHasDrawn);
+ if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
+ pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
+ pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
+ pw.print(" mDestroying="); pw.print(mDestroying);
+ pw.print(" mRemoved="); pw.println(mRemoved);
+ }
+ if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
+ pw.print(prefix); pw.print("mOrientationChanging=");
+ pw.print(mOrientationChanging);
+ pw.print(" mAppFreezing="); pw.print(mAppFreezing);
+ pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
+ }
+ if (mHScale != 1 || mVScale != 1) {
+ pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
+ pw.print(" mVScale="); pw.println(mVScale);
+ }
+ if (mWallpaperX != -1 || mWallpaperY != -1) {
+ pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
+ pw.print(" mWallpaperY="); pw.println(mWallpaperY);
+ }
+ if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
+ pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
+ pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
+ }
+ }
+
+ String makeInputChannelName() {
+ return Integer.toHexString(System.identityHashCode(this))
+ + " " + mAttrs.getTitle();
+ }
+
+ @Override
+ public String toString() {
+ if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
+ || mWasPaused != mToken.paused) {
+ mLastTitle = mAttrs.getTitle();
+ mWasPaused = mToken.paused;
+ mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
+ + " " + mLastTitle + " paused=" + mWasPaused + "}";
+ }
+ return mStringNameCache;
+ }
+} \ No newline at end of file
diff --git a/services/java/com/android/server/wm/WindowToken.java b/services/java/com/android/server/wm/WindowToken.java
new file mode 100644
index 000000000000..3cd256e85054
--- /dev/null
+++ b/services/java/com/android/server/wm/WindowToken.java
@@ -0,0 +1,110 @@
+/*
+ * 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.wm;
+
+import android.os.IBinder;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Container of a set of related windows in the window manager. Often this
+ * is an AppWindowToken, which is the handle for an Activity that it uses
+ * to display windows. For nested windows, there is a WindowToken created for
+ * the parent window to manage its children.
+ */
+class WindowToken {
+ // The window manager!
+ final WindowManagerService service;
+
+ // The actual token.
+ final IBinder token;
+
+ // The type of window this token is for, as per WindowManager.LayoutParams.
+ final int windowType;
+
+ // Set if this token was explicitly added by a client, so should
+ // not be removed when all windows are removed.
+ final boolean explicit;
+
+ // For printing.
+ String stringName;
+
+ // If this is an AppWindowToken, this is non-null.
+ AppWindowToken appWindowToken;
+
+ // All of the windows associated with this token.
+ final ArrayList<WindowState> windows = new ArrayList<WindowState>();
+
+ // Is key dispatching paused for this token?
+ boolean paused = false;
+
+ // Should this token's windows be hidden?
+ boolean hidden;
+
+ // Temporary for finding which tokens no longer have visible windows.
+ boolean hasVisible;
+
+ // Set to true when this token is in a pending transaction where it
+ // will be shown.
+ boolean waitingToShow;
+
+ // Set to true when this token is in a pending transaction where it
+ // will be hidden.
+ boolean waitingToHide;
+
+ // Set to true when this token is in a pending transaction where its
+ // windows will be put to the bottom of the list.
+ boolean sendingToBottom;
+
+ // Set to true when this token is in a pending transaction where its
+ // windows will be put to the top of the list.
+ boolean sendingToTop;
+
+ WindowToken(WindowManagerService _service, IBinder _token, int type, boolean _explicit) {
+ service = _service;
+ token = _token;
+ windowType = type;
+ explicit = _explicit;
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix); pw.print("token="); pw.println(token);
+ pw.print(prefix); pw.print("windows="); pw.println(windows);
+ pw.print(prefix); pw.print("windowType="); pw.print(windowType);
+ pw.print(" hidden="); pw.print(hidden);
+ pw.print(" hasVisible="); pw.println(hasVisible);
+ if (waitingToShow || waitingToHide || sendingToBottom || sendingToTop) {
+ pw.print(prefix); pw.print("waitingToShow="); pw.print(waitingToShow);
+ pw.print(" waitingToHide="); pw.print(waitingToHide);
+ pw.print(" sendingToBottom="); pw.print(sendingToBottom);
+ pw.print(" sendingToTop="); pw.println(sendingToTop);
+ }
+ }
+
+ @Override
+ public String toString() {
+ if (stringName == null) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("WindowToken{");
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(" token="); sb.append(token); sb.append('}');
+ stringName = sb.toString();
+ }
+ return stringName;
+ }
+} \ No newline at end of file
diff --git a/services/jni/com_android_server_InputApplication.cpp b/services/jni/com_android_server_InputApplication.cpp
index a46a162071e8..e64ec4ee4c8c 100644
--- a/services/jni/com_android_server_InputApplication.cpp
+++ b/services/jni/com_android_server_InputApplication.cpp
@@ -77,11 +77,11 @@ void android_server_InputApplication_toNative(
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputApplication(JNIEnv* env) {
- FIND_CLASS(gInputApplicationClassInfo.clazz, "com/android/server/InputApplication");
+ FIND_CLASS(gInputApplicationClassInfo.clazz, "com/android/server/wm/InputApplication");
GET_FIELD_ID(gInputApplicationClassInfo.inputApplicationHandle,
gInputApplicationClassInfo.clazz,
- "inputApplicationHandle", "Lcom/android/server/InputApplicationHandle;");
+ "inputApplicationHandle", "Lcom/android/server/wm/InputApplicationHandle;");
GET_FIELD_ID(gInputApplicationClassInfo.name, gInputApplicationClassInfo.clazz,
"name", "Ljava/lang/String;");
diff --git a/services/jni/com_android_server_InputApplicationHandle.cpp b/services/jni/com_android_server_InputApplicationHandle.cpp
index ab82635595d8..3a1214ff9655 100644
--- a/services/jni/com_android_server_InputApplicationHandle.cpp
+++ b/services/jni/com_android_server_InputApplicationHandle.cpp
@@ -106,11 +106,11 @@ static JNINativeMethod gInputApplicationHandleMethods[] = {
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputApplicationHandle(JNIEnv* env) {
- int res = jniRegisterNativeMethods(env, "com/android/server/InputApplicationHandle",
+ int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputApplicationHandle",
gInputApplicationHandleMethods, NELEM(gInputApplicationHandleMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
- FIND_CLASS(gInputApplicationHandleClassInfo.clazz, "com/android/server/InputApplicationHandle");
+ FIND_CLASS(gInputApplicationHandleClassInfo.clazz, "com/android/server/wm/InputApplicationHandle");
GET_FIELD_ID(gInputApplicationHandleClassInfo.ptr, gInputApplicationHandleClassInfo.clazz,
"ptr", "I");
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 427af2346901..0a50ff8b9bf2 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -1079,7 +1079,7 @@ static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz)
static JNINativeMethod gInputManagerMethods[] = {
/* name, signature, funcPtr */
- { "nativeInit", "(Lcom/android/server/InputManager$Callbacks;)V",
+ { "nativeInit", "(Lcom/android/server/wm/InputManager$Callbacks;)V",
(void*) android_server_InputManager_nativeInit },
{ "nativeStart", "()V",
(void*) android_server_InputManager_nativeStart },
@@ -1096,15 +1096,15 @@ static JNINativeMethod gInputManagerMethods[] = {
{ "nativeHasKeys", "(II[I[Z)Z",
(void*) android_server_InputManager_nativeHasKeys },
{ "nativeRegisterInputChannel",
- "(Landroid/view/InputChannel;Lcom/android/server/InputWindowHandle;Z)V",
+ "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
(void*) android_server_InputManager_nativeRegisterInputChannel },
{ "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
(void*) android_server_InputManager_nativeUnregisterInputChannel },
{ "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
(void*) android_server_InputManager_nativeInjectInputEvent },
- { "nativeSetInputWindows", "([Lcom/android/server/InputWindow;)V",
+ { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
(void*) android_server_InputManager_nativeSetInputWindows },
- { "nativeSetFocusedApplication", "(Lcom/android/server/InputApplication;)V",
+ { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
(void*) android_server_InputManager_nativeSetFocusedApplication },
{ "nativeSetInputDispatchMode", "(ZZ)V",
(void*) android_server_InputManager_nativeSetInputDispatchMode },
@@ -1134,13 +1134,13 @@ static JNINativeMethod gInputManagerMethods[] = {
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputManager(JNIEnv* env) {
- int res = jniRegisterNativeMethods(env, "com/android/server/InputManager",
+ int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
gInputManagerMethods, NELEM(gInputManagerMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
// Callbacks
- FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks");
+ FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/wm/InputManager$Callbacks");
GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
"notifyConfigurationChanged", "(J)V");
@@ -1149,22 +1149,22 @@ int register_android_server_InputManager(JNIEnv* env) {
"notifyLidSwitchChanged", "(JZ)V");
GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
- "notifyInputChannelBroken", "(Lcom/android/server/InputWindowHandle;)V");
+ "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
"notifyANR",
- "(Lcom/android/server/InputApplicationHandle;Lcom/android/server/InputWindowHandle;)J");
+ "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
"interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
"interceptKeyBeforeDispatching",
- "(Lcom/android/server/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
+ "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, gCallbacksClassInfo.clazz,
"dispatchUnhandledKey",
- "(Lcom/android/server/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
+ "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
"checkInjectEventsPermission", "(II)Z");
@@ -1188,7 +1188,7 @@ int register_android_server_InputManager(JNIEnv* env) {
"getPointerLayer", "()I");
GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, gCallbacksClassInfo.clazz,
- "getPointerIcon", "()Lcom/android/server/InputManager$PointerIcon;");
+ "getPointerIcon", "()Lcom/android/server/wm/InputManager$PointerIcon;");
// KeyEvent
@@ -1235,7 +1235,7 @@ int register_android_server_InputManager(JNIEnv* env) {
// PointerIcon
- FIND_CLASS(gPointerIconClassInfo.clazz, "com/android/server/InputManager$PointerIcon");
+ FIND_CLASS(gPointerIconClassInfo.clazz, "com/android/server/wm/InputManager$PointerIcon");
GET_FIELD_ID(gPointerIconClassInfo.bitmap, gPointerIconClassInfo.clazz,
"bitmap", "Landroid/graphics/Bitmap;");
diff --git a/services/jni/com_android_server_InputWindow.cpp b/services/jni/com_android_server_InputWindow.cpp
index 75154567c149..8548b47de606 100644
--- a/services/jni/com_android_server_InputWindow.cpp
+++ b/services/jni/com_android_server_InputWindow.cpp
@@ -144,10 +144,10 @@ void android_server_InputWindow_toNative(
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputWindow(JNIEnv* env) {
- FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow");
+ FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/wm/InputWindow");
GET_FIELD_ID(gInputWindowClassInfo.inputWindowHandle, gInputWindowClassInfo.clazz,
- "inputWindowHandle", "Lcom/android/server/InputWindowHandle;");
+ "inputWindowHandle", "Lcom/android/server/wm/InputWindowHandle;");
GET_FIELD_ID(gInputWindowClassInfo.inputChannel, gInputWindowClassInfo.clazz,
"inputChannel", "Landroid/view/InputChannel;");
diff --git a/services/jni/com_android_server_InputWindowHandle.cpp b/services/jni/com_android_server_InputWindowHandle.cpp
index 4d66212087ca..5b74e435c7ee 100644
--- a/services/jni/com_android_server_InputWindowHandle.cpp
+++ b/services/jni/com_android_server_InputWindowHandle.cpp
@@ -116,18 +116,18 @@ static JNINativeMethod gInputWindowHandleMethods[] = {
LOG_FATAL_IF(! var, "Unable to find field " fieldName);
int register_android_server_InputWindowHandle(JNIEnv* env) {
- int res = jniRegisterNativeMethods(env, "com/android/server/InputWindowHandle",
+ int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputWindowHandle",
gInputWindowHandleMethods, NELEM(gInputWindowHandleMethods));
LOG_FATAL_IF(res < 0, "Unable to register native methods.");
- FIND_CLASS(gInputWindowHandleClassInfo.clazz, "com/android/server/InputWindowHandle");
+ FIND_CLASS(gInputWindowHandleClassInfo.clazz, "com/android/server/wm/InputWindowHandle");
GET_FIELD_ID(gInputWindowHandleClassInfo.ptr, gInputWindowHandleClassInfo.clazz,
"ptr", "I");
GET_FIELD_ID(gInputWindowHandleClassInfo.inputApplicationHandle,
gInputWindowHandleClassInfo.clazz,
- "inputApplicationHandle", "Lcom/android/server/InputApplicationHandle;");
+ "inputApplicationHandle", "Lcom/android/server/wm/InputApplicationHandle;");
return 0;
}
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index c9e304ac7446..98ab3d1e5db2 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -27,7 +27,25 @@ import android.util.Log;
*/
public class SignalStrength implements Parcelable {
- static final String LOG_TAG = "PHONE";
+ private static final String LOG_TAG = "SignalStrength";
+ private static final boolean DBG = false;
+
+ /** @hide */
+ public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
+ /** @hide */
+ public static final int SIGNAL_STRENGTH_POOR = 1;
+ /** @hide */
+ public static final int SIGNAL_STRENGTH_MODERATE = 2;
+ /** @hide */
+ public static final int SIGNAL_STRENGTH_GOOD = 3;
+ /** @hide */
+ public static final int SIGNAL_STRENGTH_GREAT = 4;
+ /** @hide */
+ public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
+ /** @hide */
+ public static final String[] SIGNAL_STRENGTH_NAMES = {
+ "none", "poor", "moderate", "good", "great"
+ };
private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
private int mGsmBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5
@@ -36,6 +54,11 @@ public class SignalStrength implements Parcelable {
private int mEvdoDbm; // This value is the EVDO RSSI value
private int mEvdoEcio; // This value is the EVDO Ec/Io
private int mEvdoSnr; // Valid values are 0-8. 8 is the highest signal to noise ratio
+ private int mLteSignalStrength;
+ private int mLteRsrp;
+ private int mLteRsrq;
+ private int mLteRssnr;
+ private int mLteCqi;
private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult
@@ -70,6 +93,11 @@ public class SignalStrength implements Parcelable {
mEvdoDbm = -1;
mEvdoEcio = -1;
mEvdoSnr = -1;
+ mLteSignalStrength = -1;
+ mLteRsrp = -1;
+ mLteRsrq = -1;
+ mLteRssnr = -1;
+ mLteCqi = -1;
isGsm = true;
}
@@ -80,7 +108,9 @@ public class SignalStrength implements Parcelable {
*/
public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
int cdmaDbm, int cdmaEcio,
- int evdoDbm, int evdoEcio, int evdoSnr, boolean gsm) {
+ int evdoDbm, int evdoEcio, int evdoSnr,
+ int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
+ boolean gsm) {
mGsmSignalStrength = gsmSignalStrength;
mGsmBitErrorRate = gsmBitErrorRate;
mCdmaDbm = cdmaDbm;
@@ -88,10 +118,28 @@ public class SignalStrength implements Parcelable {
mEvdoDbm = evdoDbm;
mEvdoEcio = evdoEcio;
mEvdoSnr = evdoSnr;
+ mLteSignalStrength = lteSignalStrength;
+ mLteRsrp = lteRsrp;
+ mLteRsrq = lteRsrq;
+ mLteRssnr = lteRssnr;
+ mLteCqi = lteCqi;
isGsm = gsm;
}
/**
+ * Constructor
+ *
+ * @hide
+ */
+ public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
+ int cdmaDbm, int cdmaEcio,
+ int evdoDbm, int evdoEcio, int evdoSnr,
+ boolean gsm) {
+ this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
+ evdoDbm, evdoEcio, evdoSnr, -1, -1, -1, -1, -1, gsm);
+ }
+
+ /**
* Copy constructors
*
* @param s Source SignalStrength
@@ -113,6 +161,11 @@ public class SignalStrength implements Parcelable {
mEvdoDbm = s.mEvdoDbm;
mEvdoEcio = s.mEvdoEcio;
mEvdoSnr = s.mEvdoSnr;
+ mLteSignalStrength = s.mLteSignalStrength;
+ mLteRsrp = s.mLteRsrp;
+ mLteRsrq = s.mLteRsrq;
+ mLteRssnr = s.mLteRssnr;
+ mLteCqi = s.mLteCqi;
isGsm = s.isGsm;
}
@@ -129,6 +182,11 @@ public class SignalStrength implements Parcelable {
mEvdoDbm = in.readInt();
mEvdoEcio = in.readInt();
mEvdoSnr = in.readInt();
+ mLteSignalStrength = in.readInt();
+ mLteRsrp = in.readInt();
+ mLteRsrq = in.readInt();
+ mLteRssnr = in.readInt();
+ mLteCqi = in.readInt();
isGsm = (in.readInt() != 0);
}
@@ -143,6 +201,11 @@ public class SignalStrength implements Parcelable {
out.writeInt(mEvdoDbm);
out.writeInt(mEvdoEcio);
out.writeInt(mEvdoSnr);
+ out.writeInt(mLteSignalStrength);
+ out.writeInt(mLteRsrp);
+ out.writeInt(mLteRsrq);
+ out.writeInt(mLteRssnr);
+ out.writeInt(mLteCqi);
out.writeInt(isGsm ? 1 : 0);
}
@@ -218,6 +281,312 @@ public class SignalStrength implements Parcelable {
}
/**
+ * Get signal level as an int from 0..4
+ *
+ * @hide
+ */
+ public int getLevel() {
+ int level;
+
+ if (isGsm) {
+ if ((mLteSignalStrength == -1)
+ && (mLteRsrp == -1)
+ && (mLteRsrq == -1)
+ && (mLteRssnr == -1)
+ && (mLteCqi == -1)) {
+ level = getGsmLevel();
+ } else {
+ level = getLteLevel();
+ }
+ } else {
+ int cdmaLevel = getCdmaLevel();
+ int evdoLevel = getEvdoLevel();
+ if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ /* We don't know evdo, use cdma */
+ level = getCdmaLevel();
+ } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+ /* We don't know cdma, use evdo */
+ level = getEvdoLevel();
+ } else {
+ /* We know both, use the lowest level */
+ level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
+ }
+ }
+ if (DBG) log("getLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get the signal level as an asu value between 0..31, 99 is unknown
+ *
+ * @hide
+ */
+ public int getAsuLevel() {
+ int asuLevel;
+ if (isGsm) {
+ if ((mLteSignalStrength == -1)
+ && (mLteRsrp == -1)
+ && (mLteRsrq == -1)
+ && (mLteRssnr == -1)
+ && (mLteCqi == -1)) {
+ asuLevel = getGsmAsuLevel();
+ } else {
+ asuLevel = getLteAsuLevel();
+ }
+ } else {
+ int cdmaAsuLevel = getCdmaAsuLevel();
+ int evdoAsuLevel = getEvdoAsuLevel();
+ if (evdoAsuLevel == 0) {
+ /* We don't know evdo use, cdma */
+ asuLevel = cdmaAsuLevel;
+ } else if (cdmaAsuLevel == 0) {
+ /* We don't know cdma use, evdo */
+ asuLevel = evdoAsuLevel;
+ } else {
+ /* We know both, use the lowest level */
+ asuLevel = cdmaAsuLevel < evdoAsuLevel ? cdmaAsuLevel : evdoAsuLevel;
+ }
+ }
+ if (DBG) log("getAsuLevel=" + asuLevel);
+ return asuLevel;
+ }
+
+ /**
+ * Get the signal strength as dBm
+ *
+ * @hide
+ */
+ public int getDbm() {
+ int dBm;
+
+ if(isGsm()) {
+ if ((mLteSignalStrength == -1)
+ && (mLteRsrp == -1)
+ && (mLteRsrq == -1)
+ && (mLteRssnr == -1)
+ && (mLteCqi == -1)) {
+ dBm = getGsmDbm();
+ } else {
+ dBm = getLteDbm();
+ }
+ } else {
+ dBm = getCdmaDbm();
+ }
+ if (DBG) log("getDbm=" + dBm);
+ return dBm;
+ }
+
+ /**
+ * Get Gsm signal strength as dBm
+ *
+ * @hide
+ */
+ public int getGsmDbm() {
+ int dBm;
+
+ int gsmSignalStrength = getGsmSignalStrength();
+ int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
+ if (asu != -1) {
+ dBm = -113 + (2 * asu);
+ } else {
+ dBm = -1;
+ }
+ if (DBG) log("getGsmDbm=" + dBm);
+ return dBm;
+ }
+
+ /**
+ * Get gsm as level 0..4
+ *
+ * @hide
+ */
+ public int getGsmLevel() {
+ int level;
+
+ // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
+ // asu = 0 (-113dB or less) is very weak
+ // signal, its better to show 0 bars to the user in such cases.
+ // asu = 99 is a special case, where the signal strength is unknown.
+ int asu = getGsmSignalStrength();
+ if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT;
+ else if (asu >= 8) level = SIGNAL_STRENGTH_GOOD;
+ else if (asu >= 5) level = SIGNAL_STRENGTH_MODERATE;
+ else level = SIGNAL_STRENGTH_POOR;
+ if (DBG) log("getGsmLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get the gsm signal level as an asu value between 0..31, 99 is unknown
+ *
+ * @hide
+ */
+ public int getGsmAsuLevel() {
+ // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
+ // asu = 0 (-113dB or less) is very weak
+ // signal, its better to show 0 bars to the user in such cases.
+ // asu = 99 is a special case, where the signal strength is unknown.
+ int level = getGsmSignalStrength();
+ if (DBG) log("getGsmAsuLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get cdma as level 0..4
+ *
+ * @hide
+ */
+ public int getCdmaLevel() {
+ final int cdmaDbm = getCdmaDbm();
+ final int cdmaEcio = getCdmaEcio();
+ int levelDbm;
+ int levelEcio;
+
+ if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT;
+ else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD;
+ else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE;
+ else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR;
+ else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+
+ // Ec/Io are in dB*10
+ if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT;
+ else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD;
+ else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE;
+ else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR;
+ else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+
+ int level = (levelDbm < levelEcio) ? levelDbm : levelEcio;
+ if (DBG) log("getCdmaLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get the cdma signal level as an asu value between 0..31, 99 is unknown
+ *
+ * @hide
+ */
+ public int getCdmaAsuLevel() {
+ final int cdmaDbm = getCdmaDbm();
+ final int cdmaEcio = getCdmaEcio();
+ int cdmaAsuLevel;
+ int ecioAsuLevel;
+
+ if (cdmaDbm >= -75) cdmaAsuLevel = 16;
+ else if (cdmaDbm >= -82) cdmaAsuLevel = 8;
+ else if (cdmaDbm >= -90) cdmaAsuLevel = 4;
+ else if (cdmaDbm >= -95) cdmaAsuLevel = 2;
+ else if (cdmaDbm >= -100) cdmaAsuLevel = 1;
+ else cdmaAsuLevel = 99;
+
+ // Ec/Io are in dB*10
+ if (cdmaEcio >= -90) ecioAsuLevel = 16;
+ else if (cdmaEcio >= -100) ecioAsuLevel = 8;
+ else if (cdmaEcio >= -115) ecioAsuLevel = 4;
+ else if (cdmaEcio >= -130) ecioAsuLevel = 2;
+ else if (cdmaEcio >= -150) ecioAsuLevel = 1;
+ else ecioAsuLevel = 99;
+
+ int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel;
+ if (DBG) log("getCdmaAsuLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get Evdo as level 0..4
+ *
+ * @hide
+ */
+ public int getEvdoLevel() {
+ int evdoDbm = getEvdoDbm();
+ int evdoSnr = getEvdoSnr();
+ int levelEvdoDbm;
+ int levelEvdoSnr;
+
+ if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT;
+ else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD;
+ else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE;
+ else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR;
+ else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+
+ if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT;
+ else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD;
+ else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE;
+ else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR;
+ else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+
+ int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
+ if (DBG) log("getEvdoLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get the evdo signal level as an asu value between 0..31, 99 is unknown
+ *
+ * @hide
+ */
+ public int getEvdoAsuLevel() {
+ int evdoDbm = getEvdoDbm();
+ int evdoSnr = getEvdoSnr();
+ int levelEvdoDbm;
+ int levelEvdoSnr;
+
+ if (evdoDbm >= -65) levelEvdoDbm = 16;
+ else if (evdoDbm >= -75) levelEvdoDbm = 8;
+ else if (evdoDbm >= -85) levelEvdoDbm = 4;
+ else if (evdoDbm >= -95) levelEvdoDbm = 2;
+ else if (evdoDbm >= -105) levelEvdoDbm = 1;
+ else levelEvdoDbm = 99;
+
+ if (evdoSnr >= 7) levelEvdoSnr = 16;
+ else if (evdoSnr >= 6) levelEvdoSnr = 8;
+ else if (evdoSnr >= 5) levelEvdoSnr = 4;
+ else if (evdoSnr >= 3) levelEvdoSnr = 2;
+ else if (evdoSnr >= 1) levelEvdoSnr = 1;
+ else levelEvdoSnr = 99;
+
+ int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
+ if (DBG) log("getEvdoAsuLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get LTE as dBm
+ *
+ * @hide
+ */
+ public int getLteDbm() {
+ log("STOPSHIP teach getLteDbm to compute dBm properly");
+ int level = -1;
+ if (DBG) log("getLteDbm=" + level);
+ return level;
+ }
+
+ /**
+ * Get LTE as level 0..4
+ *
+ * @hide
+ */
+ public int getLteLevel() {
+ log("STOPSHIP teach getLteLevel to compute Level properly");
+ int level = SIGNAL_STRENGTH_MODERATE;
+ if (DBG) log("getLteLevel=" + level);
+ return level;
+ }
+
+ /**
+ * Get the LTE signal level as an asu value between 0..31, 99 is unknown
+ *
+ * @hide
+ */
+ public int getLteAsuLevel() {
+ log("STOPSHIP teach getLteAsuLevel to compute asu Level properly");
+ int level = 4;
+ if (DBG) log("getLteAsuLevel=" + level);
+ return level;
+ }
+
+ /**
* @return true if this is for GSM
*/
public boolean isGsm() {
@@ -229,10 +598,13 @@ public class SignalStrength implements Parcelable {
*/
@Override
public int hashCode() {
- return ((mGsmSignalStrength * 0x1234)
- + mGsmBitErrorRate
- + mCdmaDbm + mCdmaEcio
- + mEvdoDbm + mEvdoEcio + mEvdoSnr
+ int primeNum = 31;
+ return ((mGsmSignalStrength * primeNum)
+ + (mGsmBitErrorRate * primeNum)
+ + (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum)
+ + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum)
+ + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum)
+ + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum)
+ (isGsm ? 1 : 0));
}
@@ -260,6 +632,11 @@ public class SignalStrength implements Parcelable {
&& mEvdoDbm == s.mEvdoDbm
&& mEvdoEcio == s.mEvdoEcio
&& mEvdoSnr == s.mEvdoSnr
+ && mLteSignalStrength == s.mLteSignalStrength
+ && mLteRsrp == s.mLteRsrp
+ && mLteRsrq == s.mLteRsrq
+ && mLteRssnr == s.mLteRssnr
+ && mLteCqi == s.mLteCqi
&& isGsm == s.isGsm);
}
@@ -276,19 +653,12 @@ public class SignalStrength implements Parcelable {
+ " " + mEvdoDbm
+ " " + mEvdoEcio
+ " " + mEvdoSnr
- + " " + (isGsm ? "gsm" : "cdma"));
- }
-
- /**
- * Test whether two objects hold the same data values or both are null
- *
- * @param a first obj
- * @param b second obj
- * @return true if two objects equal or both are null
- * @hide
- */
- private static boolean equalsHandlesNulls (Object a, Object b) {
- return (a == null) ? (b == null) : a.equals (b);
+ + " " + mLteSignalStrength
+ + " " + mLteRsrp
+ + " " + mLteRsrq
+ + " " + mLteRssnr
+ + " " + mLteCqi
+ + " " + (isGsm ? "gsm|lte" : "cdma"));
}
/**
@@ -305,6 +675,11 @@ public class SignalStrength implements Parcelable {
mEvdoDbm = m.getInt("EvdoDbm");
mEvdoEcio = m.getInt("EvdoEcio");
mEvdoSnr = m.getInt("EvdoSnr");
+ mLteSignalStrength = m.getInt("LteSignalStrength");
+ mLteRsrp = m.getInt("LteRsrp");
+ mLteRsrq = m.getInt("LteRsrq");
+ mLteRssnr = m.getInt("LteRssnr");
+ mLteCqi = m.getInt("LteCqi");
isGsm = m.getBoolean("isGsm");
}
@@ -322,6 +697,18 @@ public class SignalStrength implements Parcelable {
m.putInt("EvdoDbm", mEvdoDbm);
m.putInt("EvdoEcio", mEvdoEcio);
m.putInt("EvdoSnr", mEvdoSnr);
+ m.putInt("LteSignalStrength", mLteSignalStrength);
+ m.putInt("LteRsrp", mLteRsrp);
+ m.putInt("LteRsrq", mLteRsrq);
+ m.putInt("LteRssnr", mLteRssnr);
+ m.putInt("LteCqi", mLteCqi);
m.putBoolean("isGsm", Boolean.valueOf(isGsm));
}
+
+ /**
+ * log
+ */
+ private static void log(String s) {
+ Log.w(LOG_TAG, s);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index 815fbfb416a3..9b196009cb95 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -47,8 +47,8 @@ public abstract class BaseCommands implements CommandsInterface {
protected RegistrantList mRUIMLockedRegistrants = new RegistrantList();
protected RegistrantList mNVReadyRegistrants = new RegistrantList();
protected RegistrantList mCallStateRegistrants = new RegistrantList();
- protected RegistrantList mNetworkStateRegistrants = new RegistrantList();
- protected RegistrantList mDataConnectionRegistrants = new RegistrantList();
+ protected RegistrantList mVoiceNetworkStateRegistrants = new RegistrantList();
+ protected RegistrantList mDataNetworkStateRegistrants = new RegistrantList();
protected RegistrantList mRadioTechnologyChangedRegistrants = new RegistrantList();
protected RegistrantList mIccStatusChangedRegistrants = new RegistrantList();
protected RegistrantList mVoicePrivacyOnRegistrants = new RegistrantList();
@@ -65,6 +65,9 @@ public abstract class BaseCommands implements CommandsInterface {
protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList();
protected RegistrantList mRingbackToneRegistrants = new RegistrantList();
protected RegistrantList mResendIncallMuteRegistrants = new RegistrantList();
+ protected RegistrantList mCdmaSubscriptionChangedRegistrants = new RegistrantList();
+ protected RegistrantList mCdmaPrlChangedRegistrants = new RegistrantList();
+ protected RegistrantList mExitEmergencyCallbackModeRegistrants = new RegistrantList();
protected Registrant mSMSRegistrant;
protected Registrant mNITZTimeRegistrant;
@@ -293,24 +296,24 @@ public abstract class BaseCommands implements CommandsInterface {
mCallStateRegistrants.remove(h);
}
- public void registerForNetworkStateChanged(Handler h, int what, Object obj) {
+ public void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
- mNetworkStateRegistrants.add(r);
+ mVoiceNetworkStateRegistrants.add(r);
}
- public void unregisterForNetworkStateChanged(Handler h) {
- mNetworkStateRegistrants.remove(h);
+ public void unregisterForVoiceNetworkStateChanged(Handler h) {
+ mVoiceNetworkStateRegistrants.remove(h);
}
- public void registerForDataStateChanged(Handler h, int what, Object obj) {
+ public void registerForDataNetworkStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
- mDataConnectionRegistrants.add(r);
+ mDataNetworkStateRegistrants.add(r);
}
- public void unregisterForDataStateChanged(Handler h) {
- mDataConnectionRegistrants.remove(h);
+ public void unregisterForDataNetworkStateChanged(Handler h) {
+ mDataNetworkStateRegistrants.remove(h);
}
public void registerForRadioTechnologyChanged(Handler h, int what, Object obj) {
@@ -588,6 +591,39 @@ public abstract class BaseCommands implements CommandsInterface {
mResendIncallMuteRegistrants.remove(h);
}
+ @Override
+ public void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mCdmaSubscriptionChangedRegistrants.add(r);
+ }
+
+ @Override
+ public void unregisterForCdmaSubscriptionChanged(Handler h) {
+ mCdmaSubscriptionChangedRegistrants.remove(h);
+ }
+
+ @Override
+ public void registerForCdmaPrlChanged(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mCdmaPrlChangedRegistrants.add(r);
+ }
+
+ @Override
+ public void unregisterForCdmaPrlChanged(Handler h) {
+ mCdmaPrlChangedRegistrants.remove(h);
+ }
+
+ @Override
+ public void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj) {
+ Registrant r = new Registrant (h, what, obj);
+ mExitEmergencyCallbackModeRegistrants.add(r);
+ }
+
+ @Override
+ public void unregisterForExitEmergencyCallbackMode(Handler h) {
+ mExitEmergencyCallbackModeRegistrants.remove(h);
+ }
+
//***** Protected Methods
/**
* Store new RadioState and send notification based on the changes
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 259acdb8c941..21e9e44ddee1 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -216,10 +216,10 @@ public interface CommandsInterface {
void registerForCallStateChanged(Handler h, int what, Object obj);
void unregisterForCallStateChanged(Handler h);
- void registerForNetworkStateChanged(Handler h, int what, Object obj);
- void unregisterForNetworkStateChanged(Handler h);
- void registerForDataStateChanged(Handler h, int what, Object obj);
- void unregisterForDataStateChanged(Handler h);
+ void registerForVoiceNetworkStateChanged(Handler h, int what, Object obj);
+ void unregisterForVoiceNetworkStateChanged(Handler h);
+ void registerForDataNetworkStateChanged(Handler h, int what, Object obj);
+ void unregisterForDataNetworkStateChanged(Handler h);
void registerForRadioTechnologyChanged(Handler h, int what, Object obj);
void unregisterForRadioTechnologyChanged(Handler h);
@@ -549,6 +549,39 @@ public interface CommandsInterface {
void registerForResendIncallMute(Handler h, int what, Object obj);
void unregisterForResendIncallMute(Handler h);
+ /**
+ * Registers the handler for when Cdma subscription changed events
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ *
+ */
+ void registerForCdmaSubscriptionChanged(Handler h, int what, Object obj);
+ void unregisterForCdmaSubscriptionChanged(Handler h);
+
+ /**
+ * Registers the handler for when Cdma prl changed events
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ *
+ */
+ void registerForCdmaPrlChanged(Handler h, int what, Object obj);
+ void unregisterForCdmaPrlChanged(Handler h);
+
+ /**
+ * Registers the handler for when Cdma prl changed events
+ *
+ * @param h Handler for notification message.
+ * @param what User-defined message code.
+ * @param obj User object.
+ *
+ */
+ void registerForExitEmergencyCallbackMode(Handler h, int what, Object obj);
+ void unregisterForExitEmergencyCallbackMode(Handler h);
+
/**
* Supply the ICC PIN to the ICC card
*
@@ -564,7 +597,23 @@ public interface CommandsInterface {
void supplyIccPin(String pin, Message result);
/**
- * Supply the ICC PUK to the ICC card
+ * Supply the PIN for the app with this AID on the ICC card
+ *
+ * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
+ *
+ * returned message
+ * retMsg.obj = AsyncResult ar
+ * ar.exception carries exception on failure
+ * This exception is CommandException with an error of PASSWORD_INCORRECT
+ * if the password is incorrect
+ *
+ * ar.exception and ar.result are null on success
+ */
+
+ void supplyIccPinForApp(String pin, String aid, Message result);
+
+ /**
+ * Supply the ICC PUK and newPin to the ICC card
*
* returned message
* retMsg.obj = AsyncResult ar
@@ -578,6 +627,22 @@ public interface CommandsInterface {
void supplyIccPuk(String puk, String newPin, Message result);
/**
+ * Supply the PUK, new pin for the app with this AID on the ICC card
+ *
+ * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
+ *
+ * returned message
+ * retMsg.obj = AsyncResult ar
+ * ar.exception carries exception on failure
+ * This exception is CommandException with an error of PASSWORD_INCORRECT
+ * if the password is incorrect
+ *
+ * ar.exception and ar.result are null on success
+ */
+
+ void supplyIccPukForApp(String puk, String newPin, String aid, Message result);
+
+ /**
* Supply the ICC PIN2 to the ICC card
* Only called following operation where ICC_PIN2 was
* returned as a a failure from a previous operation
@@ -594,6 +659,24 @@ public interface CommandsInterface {
void supplyIccPin2(String pin2, Message result);
/**
+ * Supply the PIN2 for the app with this AID on the ICC card
+ * Only called following operation where ICC_PIN2 was
+ * returned as a a failure from a previous operation
+ *
+ * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
+ *
+ * returned message
+ * retMsg.obj = AsyncResult ar
+ * ar.exception carries exception on failure
+ * This exception is CommandException with an error of PASSWORD_INCORRECT
+ * if the password is incorrect
+ *
+ * ar.exception and ar.result are null on success
+ */
+
+ void supplyIccPin2ForApp(String pin2, String aid, Message result);
+
+ /**
* Supply the SIM PUK2 to the SIM card
* Only called following operation where SIM_PUK2 was
* returned as a a failure from a previous operation
@@ -609,8 +692,28 @@ public interface CommandsInterface {
void supplyIccPuk2(String puk2, String newPin2, Message result);
+ /**
+ * Supply the PUK2, newPin2 for the app with this AID on the ICC card
+ * Only called following operation where SIM_PUK2 was
+ * returned as a a failure from a previous operation
+ *
+ * AID (Application ID), See ETSI 102.221 8.1 and 101.220 4
+ *
+ * returned message
+ * retMsg.obj = AsyncResult ar
+ * ar.exception carries exception on failure
+ * This exception is CommandException with an error of PASSWORD_INCORRECT
+ * if the password is incorrect
+ *
+ * ar.exception and ar.result are null on success
+ */
+
+ void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message result);
+
void changeIccPin(String oldPin, String newPin, Message result);
+ void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message result);
void changeIccPin2(String oldPin2, String newPin2, Message result);
+ void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr, Message result);
void changeBarringPassword(String facility, String oldPwd, String newPwd, Message result);
@@ -853,7 +956,7 @@ public interface CommandsInterface {
* Please note that registration state 4 ("unknown") is treated
* as "out of service" above
*/
- void getRegistrationState (Message response);
+ void getVoiceRegistrationState (Message response);
/**
* response.obj.result is an int[3]
@@ -865,7 +968,7 @@ public interface CommandsInterface {
* Please note that registration state 4 ("unknown") is treated
* as "out of service" above
*/
- void getGPRSRegistrationState (Message response);
+ void getDataRegistrationState (Message response);
/**
* response.obj.result is a String[3]
@@ -1286,7 +1389,7 @@ public interface CommandsInterface {
* @param cdmaSubscriptionType one of CDMA_SUBSCRIPTION_*
* @param response is callback message
*/
- void setCdmaSubscription(int cdmaSubscriptionType, Message response);
+ void setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response);
/**
* Set the TTY mode
diff --git a/telephony/java/com/android/internal/telephony/DataCallState.java b/telephony/java/com/android/internal/telephony/DataCallState.java
index df12153eba75..fda1e4747bf7 100644
--- a/telephony/java/com/android/internal/telephony/DataCallState.java
+++ b/telephony/java/com/android/internal/telephony/DataCallState.java
@@ -30,6 +30,7 @@ public class DataCallState {
public String ifname = "";
public String [] addresses = new String[0];
public String [] dnses = new String[0];
+ public String[] gateways = new String[0];
@Override
public String toString() {
@@ -53,6 +54,12 @@ public class DataCallState {
sb.append(",");
}
if (dnses.length > 0) sb.deleteCharAt(sb.length()-1);
+ sb.append("] gateways=[");
+ for (String addr : gateways) {
+ sb.append(addr);
+ sb.append(",");
+ }
+ if (gateways.length > 0) sb.deleteCharAt(sb.length()-1);
sb.append("]}");
return sb.toString();
}
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index aa9c4a37c08d..e0b960349717 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -398,22 +398,34 @@ public abstract class DataConnection extends HierarchicalStateMachine {
// a failure we'll clear again at the bottom of this code.
LinkProperties linkProperties = new LinkProperties();
if (response.status == FailCause.NONE.getErrorCode()) {
+ String propertyPrefix = "net." + response.ifname + ".";
+
try {
cid = response.cid;
linkProperties.setInterfaceName(response.ifname);
if (response.addresses != null && response.addresses.length > 0) {
for (String addr : response.addresses) {
LinkAddress la;
+ int addrPrefixLen;
+
+ String [] ap = addr.split("/");
+ if (ap.length == 2) {
+ addr = ap[0];
+ addrPrefixLen = Integer.parseInt(ap[1]);
+ } else {
+ addrPrefixLen = 0;
+ }
if (!InetAddress.isNumeric(addr)) {
EventLogTags.writeBadIpAddress(addr);
throw new UnknownHostException("Non-numeric ip addr=" + addr);
}
InetAddress ia = InetAddress.getByName(addr);
- if (ia instanceof Inet4Address) {
- la = new LinkAddress(ia, 32);
- } else {
- la = new LinkAddress(ia, 128);
+ if (addrPrefixLen == 0) {
+ // Assume point to point
+ addrPrefixLen = (ia instanceof Inet4Address) ? 32 : 128;
}
+ if (DBG) log("addr/pl=" + addr + "/" + addrPrefixLen);
+ la = new LinkAddress(ia, addrPrefixLen);
linkProperties.addLinkAddress(la);
}
} else {
@@ -431,11 +443,9 @@ public abstract class DataConnection extends HierarchicalStateMachine {
}
result = SetupResult.SUCCESS;
} else {
- String prefix = "net." + response.ifname + ".";
-
String dnsServers[] = new String[2];
- dnsServers[0] = SystemProperties.get(prefix + "dns1");
- dnsServers[1] = SystemProperties.get(prefix + "dns2");
+ dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
+ dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
if (isDnsOk(dnsServers)) {
for (String dnsAddr : dnsServers) {
if (!InetAddress.isNumeric(dnsAddr)) {
@@ -457,6 +467,23 @@ public abstract class DataConnection extends HierarchicalStateMachine {
throw new UnknownHostException("Unacceptable dns addresses=" + sb);
}
}
+ if ((response.gateways == null) || (response.gateways.length == 0)) {
+ String gateways = SystemProperties.get(propertyPrefix + "gw");
+ if (gateways != null) {
+ response.gateways = gateways.split(" ");
+ } else {
+ response.gateways = new String[0];
+ }
+ }
+ for (String addr : response.gateways) {
+ if (!InetAddress.isNumeric(addr)) {
+ EventLogTags.writePdpBadDnsAddress("gateway=" + addr);
+ throw new UnknownHostException("Non-numeric gateway addr=" + addr);
+ }
+ InetAddress ia = InetAddress.getByName(addr);
+ linkProperties.addGateway(ia);
+ }
+ result = SetupResult.SUCCESS;
} catch (UnknownHostException e) {
log("onSetupCompleted: UnknownHostException " + e);
e.printStackTrace();
diff --git a/telephony/java/com/android/internal/telephony/IccCardStatus.java b/telephony/java/com/android/internal/telephony/IccCardStatus.java
index 0e7bad770e6a..7199616acbd9 100644
--- a/telephony/java/com/android/internal/telephony/IccCardStatus.java
+++ b/telephony/java/com/android/internal/telephony/IccCardStatus.java
@@ -34,7 +34,7 @@ public class IccCardStatus {
boolean isCardPresent() {
return this == CARDSTATE_PRESENT;
}
- };
+ }
public enum PinState {
PINSTATE_UNKNOWN,
@@ -43,12 +43,13 @@ public class IccCardStatus {
PINSTATE_DISABLED,
PINSTATE_ENABLED_BLOCKED,
PINSTATE_ENABLED_PERM_BLOCKED
- };
+ }
private CardState mCardState;
private PinState mUniversalPinState;
private int mGsmUmtsSubscriptionAppIndex;
private int mCdmaSubscriptionAppIndex;
+ private int mImsSubscriptionAppIndex;
private int mNumApplications;
private ArrayList<IccCardApplication> mApplications =
@@ -74,6 +75,10 @@ public class IccCardStatus {
}
}
+ public PinState getUniversalPinState() {
+ return mUniversalPinState;
+ }
+
public void setUniversalPinState(int state) {
switch(state) {
case 0:
@@ -115,6 +120,14 @@ public class IccCardStatus {
mCdmaSubscriptionAppIndex = cdmaSubscriptionAppIndex;
}
+ public int getImsSubscriptionAppIndex() {
+ return mImsSubscriptionAppIndex;
+ }
+
+ public void setImsSubscriptionAppIndex(int imsSubscriptionAppIndex) {
+ mImsSubscriptionAppIndex = imsSubscriptionAppIndex;
+ }
+
public int getNumApplications() {
return mNumApplications;
}
@@ -130,4 +143,5 @@ public class IccCardStatus {
public IccCardApplication getApplication(int index) {
return mApplications.get(index);
}
+
}
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index cbff13099a4f..54341b10ab0d 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -679,7 +679,7 @@ public abstract class PhoneBase extends Handler implements Phone {
* Set the status of the CDMA subscription mode
*/
public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
- mCM.setCdmaSubscription(cdmaSubscriptionType, response);
+ mCM.setCdmaSubscriptionSource(cdmaSubscriptionType, response);
}
/**
diff --git a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java b/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
index b31161cb9281..898e624e92f6 100644
--- a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
+++ b/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java
@@ -95,25 +95,17 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver {
}
/**
- * Returns current signal strength in "asu", ranging from 0-31
- * or -1 if unknown
- *
- * For GSM, dBm = -113 + 2*asu
- * 0 means "-113 dBm or less"
- * 31 means "-51 dBm or greater"
+ * Returns current signal strength in as an asu 0..31
*
- * @return signal strength in asu, -1 if not yet updated
* Throws RuntimeException if client has not called notifySignalStrength()
*/
- public int getSignalStrength() {
+ public int getSignalStrengthLevelAsu() {
// TODO: use new SignalStrength instead of asu
if ((mWants & NOTIF_SIGNAL) == 0) {
throw new RuntimeException
("client must call notifySignalStrength(int)");
}
- int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
-
- return (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
+ return mSignalStrength.getAsuLevel();
}
/**
@@ -128,19 +120,7 @@ public final class PhoneStateIntentReceiver extends BroadcastReceiver {
throw new RuntimeException
("client must call notifySignalStrength(int)");
}
-
- int dBm = -1;
-
- if(!mSignalStrength.isGsm()) {
- dBm = mSignalStrength.getCdmaDbm();
- } else {
- int gsmSignalStrength = mSignalStrength.getGsmSignalStrength();
- int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
- if (asu != -1) {
- dBm = -113 + 2*asu;
- }
- }
- return dBm;
+ return mSignalStrength.getDbm();
}
public void notifyPhoneCallState(int eventWhat) {
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 3ef1924c55a2..76c6229b017d 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -224,7 +224,6 @@ public final class RIL extends BaseCommands implements CommandsInterface {
RILSender mSender;
Thread mReceiverThread;
RILReceiver mReceiver;
- private Context mContext;
WakeLock mWakeLock;
int mWakeLockTimeout;
// The number of requests pending to be sent out, it increases before calling
@@ -649,8 +648,6 @@ public final class RIL extends BaseCommands implements CommandsInterface {
mRequestMessagesPending = 0;
mRequestMessagesWaiting = 0;
- mContext = context;
-
mSenderThread = new HandlerThread("RILSender");
mSenderThread.start();
@@ -693,90 +690,126 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
- public void
+ @Override public void
supplyIccPin(String pin, Message result) {
+ supplyIccPinForApp(pin, null, result);
+ }
+
+ @Override public void
+ supplyIccPinForApp(String pin, String aid, Message result) {
//Note: This RIL request has not been renamed to ICC,
// but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
- rr.mp.writeInt(1);
+ rr.mp.writeInt(2);
rr.mp.writeString(pin);
+ rr.mp.writeString(aid);
send(rr);
}
- public void
+ @Override public void
supplyIccPuk(String puk, String newPin, Message result) {
+ supplyIccPukForApp(puk, newPin, null, result);
+ }
+
+ @Override public void
+ supplyIccPukForApp(String puk, String newPin, String aid, Message result) {
//Note: This RIL request has not been renamed to ICC,
// but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
- rr.mp.writeInt(2);
+ rr.mp.writeInt(3);
rr.mp.writeString(puk);
rr.mp.writeString(newPin);
+ rr.mp.writeString(aid);
send(rr);
}
- public void
+ @Override public void
supplyIccPin2(String pin, Message result) {
+ supplyIccPin2ForApp(pin, null, result);
+ }
+
+ @Override public void
+ supplyIccPin2ForApp(String pin, String aid, Message result) {
//Note: This RIL request has not been renamed to ICC,
// but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN2, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
- rr.mp.writeInt(1);
+ rr.mp.writeInt(2);
rr.mp.writeString(pin);
+ rr.mp.writeString(aid);
send(rr);
}
- public void
- supplyIccPuk2(String puk, String newPin2, Message result) {
+ @Override public void
+ supplyIccPuk2(String puk2, String newPin2, Message result) {
+ supplyIccPuk2ForApp(puk2, newPin2, null, result);
+ }
+
+ @Override public void
+ supplyIccPuk2ForApp(String puk, String newPin2, String aid, Message result) {
//Note: This RIL request has not been renamed to ICC,
// but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK2, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
- rr.mp.writeInt(2);
+ rr.mp.writeInt(3);
rr.mp.writeString(puk);
rr.mp.writeString(newPin2);
+ rr.mp.writeString(aid);
send(rr);
}
- public void
+ @Override public void
changeIccPin(String oldPin, String newPin, Message result) {
+ changeIccPinForApp(oldPin, newPin, null, result);
+ }
+
+ @Override public void
+ changeIccPinForApp(String oldPin, String newPin, String aid, Message result) {
//Note: This RIL request has not been renamed to ICC,
// but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
- rr.mp.writeInt(2);
+ rr.mp.writeInt(3);
rr.mp.writeString(oldPin);
rr.mp.writeString(newPin);
+ rr.mp.writeString(aid);
send(rr);
}
- public void
+ @Override public void
changeIccPin2(String oldPin2, String newPin2, Message result) {
+ changeIccPin2ForApp(oldPin2, newPin2, null, result);
+ }
+
+ @Override public void
+ changeIccPin2ForApp(String oldPin2, String newPin2, String aid, Message result) {
//Note: This RIL request has not been renamed to ICC,
// but this request is also valid for SIM and RUIM
RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN2, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
- rr.mp.writeInt(2);
+ rr.mp.writeInt(3);
rr.mp.writeString(oldPin2);
rr.mp.writeString(newPin2);
+ rr.mp.writeString(aid);
send(rr);
}
@@ -1072,9 +1105,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
public void
- getRegistrationState (Message result) {
+ getVoiceRegistrationState (Message result) {
RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_REGISTRATION_STATE, result);
+ = RILRequest.obtain(RIL_REQUEST_VOICE_REGISTRATION_STATE, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -1082,9 +1115,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
public void
- getGPRSRegistrationState (Message result) {
+ getDataRegistrationState (Message result) {
RILRequest rr
- = RILRequest.obtain(RIL_REQUEST_GPRS_REGISTRATION_STATE, result);
+ = RILRequest.obtain(RIL_REQUEST_DATA_REGISTRATION_STATE, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
@@ -1357,7 +1390,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rrPnt);
RILRequest rrCs = RILRequest.obtain(
- RIL_REQUEST_CDMA_SET_SUBSCRIPTION, null);
+ RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, null);
rrCs.mp.writeInt(1);
rrCs.mp.writeInt(mCdmaSubscription);
if (RILJ_LOGD) riljLog(rrCs.serialString() + "> "
@@ -2171,8 +2204,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_UDUB: ret = responseVoid(p); break;
case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret = responseInts(p); break;
case RIL_REQUEST_SIGNAL_STRENGTH: ret = responseSignalStrength(p); break;
- case RIL_REQUEST_REGISTRATION_STATE: ret = responseStrings(p); break;
- case RIL_REQUEST_GPRS_REGISTRATION_STATE: ret = responseStrings(p); break;
+ case RIL_REQUEST_VOICE_REGISTRATION_STATE: ret = responseStrings(p); break;
+ case RIL_REQUEST_DATA_REGISTRATION_STATE: ret = responseStrings(p); break;
case RIL_REQUEST_OPERATOR: ret = responseStrings(p); break;
case RIL_REQUEST_RADIO_POWER: ret = responseVoid(p); break;
case RIL_REQUEST_DTMF: ret = responseVoid(p); break;
@@ -2228,7 +2261,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret = responseInts(p); break;
case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseCellList(p); break;
case RIL_REQUEST_SET_LOCATION_UPDATES: ret = responseVoid(p); break;
- case RIL_REQUEST_CDMA_SET_SUBSCRIPTION: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: ret = responseVoid(p); break;
case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: ret = responseInts(p); break;
case RIL_REQUEST_SET_TTY_MODE: ret = responseVoid(p); break;
@@ -2255,6 +2288,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
+ case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: ret = responseInts(p); break;
default:
throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
//break;
@@ -2368,7 +2402,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); break;
- case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED: ret = responseVoid(p); break;
+ case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: ret = responseVoid(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS: ret = responseString(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret = responseString(p); break;
case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret = responseInts(p); break;
@@ -2396,6 +2430,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break;
case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break;
case RIL_UNSOL_RESEND_INCALL_MUTE: ret = responseVoid(p); break;
+ case RIL_UNSOL_CDMA_SUBSCRIPTION_CHANGED: ret = responseInts(p); break;
+ case RIL_UNSOl_CDMA_PRL_CHANGED: ret = responseInts(p); break;
+ case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
default:
throw new RuntimeException("Unrecognized unsol response: " + response);
@@ -2420,10 +2457,10 @@ public final class RIL extends BaseCommands implements CommandsInterface {
mCallStateRegistrants
.notifyRegistrants(new AsyncResult(null, null, null));
break;
- case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED:
+ case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED:
if (RILJ_LOGD) unsljLog(response);
- mNetworkStateRegistrants
+ mVoiceNetworkStateRegistrants
.notifyRegistrants(new AsyncResult(null, null, null));
break;
case RIL_UNSOL_RESPONSE_NEW_SMS: {
@@ -2515,7 +2552,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
if (RILJ_LOGD) unsljLogRet(response, ret);
- mDataConnectionRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
+ mDataNetworkStateRegistrants.notifyRegistrants(new AsyncResult(null, ret, null));
break;
case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
@@ -2698,6 +2735,34 @@ public final class RIL extends BaseCommands implements CommandsInterface {
mResendIncallMuteRegistrants.notifyRegistrants(
new AsyncResult (null, ret, null));
}
+ break;
+
+ case RIL_UNSOL_CDMA_SUBSCRIPTION_CHANGED:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mCdmaSubscriptionChangedRegistrants != null) {
+ mCdmaSubscriptionChangedRegistrants.notifyRegistrants(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOl_CDMA_PRL_CHANGED:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mCdmaPrlChangedRegistrants != null) {
+ mCdmaPrlChangedRegistrants.notifyRegistrants(
+ new AsyncResult (null, ret, null));
+ }
+ break;
+
+ case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
+ if (RILJ_LOGD) unsljLogRet(response, ret);
+
+ if (mExitEmergencyCallbackModeRegistrants != null) {
+ mExitEmergencyCallbackModeRegistrants.notifyRegistrants(
+ new AsyncResult (null, null, null));
+ }
+ break;
}
}
@@ -2848,6 +2913,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
status.setUniversalPinState(p.readInt());
status.setGsmUmtsSubscriptionAppIndex(p.readInt());
status.setCdmaSubscriptionAppIndex(p.readInt());
+ status.setImsSubscriptionAppIndex(p.readInt());
int numApplications = p.readInt();
// limit to maximum allowed applications
@@ -2905,16 +2971,15 @@ public final class RIL extends BaseCommands implements CommandsInterface {
dc.uusInfo.setDcs(p.readInt());
byte[] userData = p.createByteArray();
dc.uusInfo.setUserData(userData);
- Log
- .v(LOG_TAG, String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
+ riljLogv(String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
dc.uusInfo.getType(), dc.uusInfo.getDcs(),
dc.uusInfo.getUserData().length));
- Log.v(LOG_TAG, "Incoming UUS : data (string)="
+ riljLogv("Incoming UUS : data (string)="
+ new String(dc.uusInfo.getUserData()));
- Log.v(LOG_TAG, "Incoming UUS : data (hex): "
+ riljLogv("Incoming UUS : data (hex): "
+ IccUtils.bytesToHexString(dc.uusInfo.getUserData()));
} else {
- Log.v(LOG_TAG, "Incoming UUS : NOT present!");
+ riljLogv("Incoming UUS : NOT present!");
}
// Make sure there's a leading + on addresses with a TOA of 145
@@ -2924,10 +2989,10 @@ public final class RIL extends BaseCommands implements CommandsInterface {
if (dc.isVoicePrivacy) {
mVoicePrivacyOnRegistrants.notifyRegistrants();
- Log.d(LOG_TAG, "InCall VoicePrivacy is enabled");
+ riljLog("InCall VoicePrivacy is enabled");
} else {
mVoicePrivacyOffRegistrants.notifyRegistrants();
- Log.d(LOG_TAG, "InCall VoicePrivacy is disabled");
+ riljLog("InCall VoicePrivacy is disabled");
}
}
@@ -2944,7 +3009,6 @@ public final class RIL extends BaseCommands implements CommandsInterface {
dataCall.cid = p.readInt();
dataCall.active = p.readInt();
dataCall.type = p.readString();
- p.readString(); // Ignore apn
String addresses = p.readString();
if (TextUtils.isEmpty(addresses)) {
dataCall.addresses = addresses.split(" ");
@@ -2966,6 +3030,10 @@ public final class RIL extends BaseCommands implements CommandsInterface {
if (!TextUtils.isEmpty(dnses)) {
dataCall.dnses = dnses.split(" ");
}
+ String gateways = p.readString();
+ if (!TextUtils.isEmpty(gateways)) {
+ dataCall.gateways = gateways.split(" ");
+ }
}
return dataCall;
}
@@ -2976,7 +3044,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
int ver = p.readInt();
int num = p.readInt();
- Log.d(LOG_TAG, "responseDataCallList ver=" + ver + " num=" + num);
+ riljLog("responseDataCallList ver=" + ver + " num=" + num);
response = new ArrayList<DataCallState>(num);
for (int i = 0; i < num; i++) {
@@ -2990,7 +3058,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
responseSetupDataCall(Parcel p) {
int ver = p.readInt();
int num = p.readInt();
- Log.d(LOG_TAG, "responseSetupDataCall ver=" + ver + " num=" + num);
+ if (RILJ_LOGD) riljLog("responseSetupDataCall ver=" + ver + " num=" + num);
DataCallState dataCall;
@@ -3009,11 +3077,18 @@ public final class RIL extends BaseCommands implements CommandsInterface {
}
if (num >= 4) {
String dnses = p.readString();
- Log.d(LOG_TAG, "responseSetupDataCall got dnses=" + dnses);
+ if (RILJ_LOGD) riljLog("responseSetupDataCall got dnses=" + dnses);
if (!TextUtils.isEmpty(dnses)) {
dataCall.dnses = dnses.split(" ");
}
}
+ if (num >= 5) {
+ String gateways = p.readString();
+ if (RILJ_LOGD) riljLog("responseSetupDataCall got gateways=" + gateways);
+ if (!TextUtils.isEmpty(gateways)) {
+ dataCall.gateways = gateways.split(" ");
+ }
+ }
} else {
if (num != 1) {
throw new RuntimeException(
@@ -3156,7 +3231,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
private Object
responseSignalStrength(Parcel p) {
- int numInts = 7;
+ int numInts = 12;
int response[];
/* TODO: Add SignalStrength class to match RIL_SignalStrength */
@@ -3200,6 +3275,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
notification.signalType = p.readInt();
notification.alertPitch = p.readInt();
notification.signal = p.readInt();
+ notification.numberType = p.readInt();
+ notification.numberPlan = p.readInt();
return notification;
}
@@ -3291,8 +3368,8 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_UDUB: return "UDUB";
case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
- case RIL_REQUEST_REGISTRATION_STATE: return "REGISTRATION_STATE";
- case RIL_REQUEST_GPRS_REGISTRATION_STATE: return "GPRS_REGISTRATION_STATE";
+ case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
+ case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
case RIL_REQUEST_OPERATOR: return "OPERATOR";
case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
case RIL_REQUEST_DTMF: return "DTMF";
@@ -3348,7 +3425,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "REQUEST_GET_PREFERRED_NETWORK_TYPE";
case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "REQUEST_GET_NEIGHBORING_CELL_IDS";
case RIL_REQUEST_SET_LOCATION_UPDATES: return "REQUEST_SET_LOCATION_UPDATES";
- case RIL_REQUEST_CDMA_SET_SUBSCRIPTION: return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION";
+ case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE";
case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE";
case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: return "RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE";
case RIL_REQUEST_SET_TTY_MODE: return "RIL_REQUEST_SET_TTY_MODE";
@@ -3375,6 +3452,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "REQUEST_EXIT_EMERGENCY_CALLBACK_MODE";
case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "RIL_REQUEST_REPORT_SMS_MEMORY_STATUS";
case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING";
+ case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE";
default: return "<unknown request>";
}
}
@@ -3390,7 +3468,7 @@ public final class RIL extends BaseCommands implements CommandsInterface {
switch(request) {
case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
- case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_NETWORK_STATE_CHANGED";
+ case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
@@ -3419,6 +3497,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONG";
case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
+ case RIL_UNSOL_CDMA_SUBSCRIPTION_CHANGED: return "CDMA_SUBSCRIPTION_CHANGED";
+ case RIL_UNSOl_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
+ case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
default: return "<unknown reponse>";
}
}
@@ -3502,9 +3583,9 @@ public final class RIL extends BaseCommands implements CommandsInterface {
/**
* {@inheritDoc}
*/
- public void setCdmaSubscription(int cdmaSubscription , Message response) {
+ public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) {
RILRequest rr = RILRequest.obtain(
- RILConstants.RIL_REQUEST_CDMA_SET_SUBSCRIPTION, response);
+ RILConstants.RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, response);
rr.mp.writeInt(1);
rr.mp.writeInt(cdmaSubscription);
@@ -3518,6 +3599,19 @@ public final class RIL extends BaseCommands implements CommandsInterface {
/**
* {@inheritDoc}
*/
+ public void getCdmaSubscriptionSource(int cdmaSubscription , Message response) {
+ RILRequest rr = RILRequest.obtain(
+ RILConstants.RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, response);
+
+ if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+ + " : " + cdmaSubscription);
+
+ send(rr);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public void queryTTYMode(Message response) {
RILRequest rr = RILRequest.obtain(
RILConstants.RIL_REQUEST_QUERY_TTY_MODE, response);
@@ -3598,4 +3692,5 @@ public final class RIL extends BaseCommands implements CommandsInterface {
send(rr);
}
+
}
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 9b21de8f9b97..cdf1977dfec8 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -162,8 +162,8 @@ cat include/telephony/ril.h | \
int RIL_REQUEST_UDUB = 17;
int RIL_REQUEST_LAST_CALL_FAIL_CAUSE = 18;
int RIL_REQUEST_SIGNAL_STRENGTH = 19;
- int RIL_REQUEST_REGISTRATION_STATE = 20;
- int RIL_REQUEST_GPRS_REGISTRATION_STATE = 21;
+ int RIL_REQUEST_VOICE_REGISTRATION_STATE = 20;
+ int RIL_REQUEST_DATA_REGISTRATION_STATE = 21;
int RIL_REQUEST_OPERATOR = 22;
int RIL_REQUEST_RADIO_POWER = 23;
int RIL_REQUEST_DTMF = 24;
@@ -219,7 +219,7 @@ cat include/telephony/ril.h | \
int RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE = 74;
int RIL_REQUEST_GET_NEIGHBORING_CELL_IDS = 75;
int RIL_REQUEST_SET_LOCATION_UPDATES = 76;
- int RIL_REQUEST_CDMA_SET_SUBSCRIPTION = 77;
+ int RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE = 77;
int RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE = 78;
int RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE = 79;
int RIL_REQUEST_SET_TTY_MODE = 80;
@@ -246,10 +246,11 @@ cat include/telephony/ril.h | \
int RIL_REQUEST_SET_SMSC_ADDRESS = 101;
int RIL_REQUEST_REPORT_SMS_MEMORY_STATUS = 102;
int RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING = 103;
+ int RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE = 104;
int RIL_UNSOL_RESPONSE_BASE = 1000;
int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
- int RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED = 1002;
+ int RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED = 1002;
int RIL_UNSOL_RESPONSE_NEW_SMS = 1003;
int RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT = 1004;
int RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM = 1005;
@@ -278,4 +279,7 @@ cat include/telephony/ril.h | \
int RIL_UNSOL_OEM_HOOK_RAW = 1028;
int RIL_UNSOL_RINGBACK_TONE = 1029;
int RIL_UNSOL_RESEND_INCALL_MUTE = 1030;
+ int RIL_UNSOL_CDMA_SUBSCRIPTION_CHANGED = 1031;
+ int RIL_UNSOl_CDMA_PRL_CHANGED = 1032;
+ int RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE = 1033;
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
index f4119ad61b6f..81ff0425dc69 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
@@ -26,10 +26,12 @@ import com.android.internal.telephony.Connection;
*/
public class CdmaCallWaitingNotification {
static final String LOG_TAG = "CDMA";
- public String number =null;
+ public String number = null;
public int numberPresentation = 0;
public String name = null;
public int namePresentation = 0;
+ public int numberType = 0;
+ public int numberPlan = 0;
public int isPresent = 0;
public int signalType = 0;
public int alertPitch = 0;
@@ -42,6 +44,8 @@ public class CdmaCallWaitingNotification {
+ " numberPresentation: " + numberPresentation
+ " name: " + name
+ " namePresentation: " + namePresentation
+ + " numberType: " + numberType
+ + " numberPlan: " + numberPlan
+ " isPresent: " + isPresent
+ " signalType: " + signalType
+ " alertPitch: " + alertPitch
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index c324a717207f..8c36106d7339 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -101,7 +101,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
p.mRuimRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
p.mCM.registerForNVReady(this, EVENT_NV_READY, null);
- p.mCM.registerForDataStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
+ p.mCM.registerForDataNetworkStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
p.mCT.registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
p.mCT.registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
p.mSST.registerForCdmaDataConnectionAttached(this, EVENT_TRY_SETUP_DATA, null);
@@ -125,7 +125,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
mPhone.mCM.unregisterForOffOrNotAvailable(this);
mCdmaPhone.mRuimRecords.unregisterForRecordsLoaded(this);
mPhone.mCM.unregisterForNVReady(this);
- mPhone.mCM.unregisterForDataStateChanged(this);
+ mPhone.mCM.unregisterForDataNetworkStateChanged(this);
mCdmaPhone.mCT.unregisterForVoiceCallEnded(this);
mCdmaPhone.mCT.unregisterForVoiceCallStarted(this);
mCdmaPhone.mSST.unregisterForCdmaDataConnectionAttached(this);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index b217f07b9c1e..0debb4206178 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -186,7 +186,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
- cm.registerForNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED_CDMA, null);
+ cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED_CDMA, null);
cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
@@ -215,7 +215,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
// Unregister for all events.
cm.unregisterForAvailable(this);
cm.unregisterForRadioStateChanged(this);
- cm.unregisterForNetworkStateChanged(this);
+ cm.unregisterForVoiceNetworkStateChanged(this);
cm.unregisterForRUIMReady(this);
cm.unregisterForNVReady(this);
cm.unregisterForCdmaOtaProvision(this);
@@ -517,7 +517,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
ar = (AsyncResult) msg.obj;
if (ar.exception == null) {
- cm.getRegistrationState(obtainMessage(EVENT_GET_LOC_DONE_CDMA, null));
+ cm.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE_CDMA, null));
}
break;
@@ -897,7 +897,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
}
private void setSignalStrengthDefaultValues() {
- mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, false);
+ mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, false);
}
/**
@@ -955,8 +956,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
obtainMessage(EVENT_POLL_STATE_OPERATOR_CDMA, pollingContext));
pollingContext[0]++;
- // RIL_REQUEST_REGISTRATION_STATE is necessary for CDMA
- cm.getRegistrationState(
+ // RIL_REQUEST_VOICE_REGISTRATION_STATE is necessary for CDMA
+ cm.getVoiceRegistrationState(
obtainMessage(EVENT_POLL_STATE_REGISTRATION_CDMA, pollingContext));
break;
@@ -1252,7 +1253,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
//log(String.format("onSignalStrengthResult cdmaDbm=%d cdmaEcio=%d evdoRssi=%d evdoEcio=%d evdoSnr=%d",
// cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, evdoSnr));
mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio,
- evdoRssi, evdoEcio, evdoSnr, false);
+ evdoRssi, evdoEcio, evdoSnr, -1, -1, -1, -1, -1, false);
}
try {
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index f2cdf0c3066a..c57f2f162f5b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -141,7 +141,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
p.mSIMRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
- p.mCM.registerForDataStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
+ p.mCM.registerForDataNetworkStateChanged (this, EVENT_DATA_STATE_CHANGED, null);
p.mCT.registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null);
p.mCT.registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null);
p.mSST.registerForGprsAttached(this, EVENT_GPRS_ATTACHED, null);
@@ -171,7 +171,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
mPhone.mCM.unregisterForAvailable(this);
mPhone.mCM.unregisterForOffOrNotAvailable(this);
mGsmPhone.mSIMRecords.unregisterForRecordsLoaded(this);
- mPhone.mCM.unregisterForDataStateChanged(this);
+ mPhone.mCM.unregisterForDataNetworkStateChanged(this);
mGsmPhone.mCT.unregisterForVoiceCallEnded(this);
mGsmPhone.mCT.unregisterForVoiceCallStarted(this);
mGsmPhone.mSST.unregisterForGprsAttached(this);
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index bb99e4564c1d..ac838082828f 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -79,6 +79,10 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
private int gprsState = ServiceState.STATE_OUT_OF_SERVICE;
private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE;
+ private int mMaxDataCalls = 1;
+ private int mNewMaxDataCalls = 1;
+ private int mReasonDataDenied = -1;
+ private int mNewReasonDataDenied = -1;
/**
* Values correspond to ServiceStateTracker.DATA_ACCESS_ definitions.
@@ -212,7 +216,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
- cm.registerForNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
+ cm.registerForVoiceNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null);
cm.setOnNITZTime(this, EVENT_NITZ_TIME, null);
cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
cm.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null);
@@ -248,7 +252,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
// Unregister for all events.
cm.unregisterForAvailable(this);
cm.unregisterForRadioStateChanged(this);
- cm.unregisterForNetworkStateChanged(this);
+ cm.unregisterForVoiceNetworkStateChanged(this);
cm.unregisterForSIMReady(this);
phone.mSIMRecords.unregisterForRecordsLoaded(this);
@@ -491,7 +495,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
ar = (AsyncResult) msg.obj;
if (ar.exception == null) {
- cm.getRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null));
+ cm.getVoiceRegistrationState(obtainMessage(EVENT_GET_LOC_DONE, null));
}
break;
@@ -683,6 +687,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
int lac = -1;
int cid = -1;
int regState = -1;
+ int reasonRegStateDenied = -1;
int psc = -1;
if (states.length > 0) {
try {
@@ -724,6 +729,8 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
int type = 0;
regState = -1;
+ mNewReasonDataDenied = -1;
+ mNewMaxDataCalls = 1;
if (states.length > 0) {
try {
regState = Integer.parseInt(states[0]);
@@ -732,6 +739,12 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
if (states.length >= 4 && states[3] != null) {
type = Integer.parseInt(states[3]);
}
+ if ((states.length >= 5 ) && (regState == 3)) {
+ mNewReasonDataDenied = Integer.parseInt(states[4]);
+ }
+ if (states.length >= 6) {
+ mNewMaxDataCalls = Integer.parseInt(states[5]);
+ }
} catch (NumberFormatException ex) {
Log.w(LOG_TAG, "error parsing GprsRegistrationState: " + ex);
}
@@ -785,7 +798,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
private void setSignalStrengthDefaultValues() {
- mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, true);
+ mSignalStrength = new SignalStrength(99, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, true);
}
/**
@@ -842,12 +855,12 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
EVENT_POLL_STATE_OPERATOR, pollingContext));
pollingContext[0]++;
- cm.getGPRSRegistrationState(
+ cm.getDataRegistrationState(
obtainMessage(
EVENT_POLL_STATE_GPRS, pollingContext));
pollingContext[0]++;
- cm.getRegistrationState(
+ cm.getVoiceRegistrationState(
obtainMessage(
EVENT_POLL_STATE_REGISTRATION, pollingContext));
@@ -894,7 +907,11 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
if (DBG) {
Log.d(LOG_TAG, "Poll ServiceState done: " +
" oldSS=[" + ss + "] newSS=[" + newSS +
- "] oldGprs=" + gprsState + " newGprs=" + newGPRSState +
+ "] oldGprs=" + gprsState + " newData=" + newGPRSState +
+ " oldMaxDataCalls=" + mMaxDataCalls +
+ " mNewMaxDataCalls=" + mNewMaxDataCalls +
+ " oldReasonDataDenied=" + mReasonDataDenied +
+ " mNewReasonDataDenied=" + mNewReasonDataDenied +
" oldType=" + networkTypeToString(networkType) +
" newType=" + networkTypeToString(newNetworkType));
}
@@ -956,6 +973,8 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
gprsState = newGPRSState;
+ mReasonDataDenied = mNewReasonDataDenied;
+ mMaxDataCalls = mNewMaxDataCalls;
networkType = newNetworkType;
// this new state has been applied - forget it until we get a new new state
newNetworkType = 0;
@@ -1158,6 +1177,11 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
private void onSignalStrengthResult(AsyncResult ar) {
SignalStrength oldSignalStrength = mSignalStrength;
int rssi = 99;
+ int lteSignalStrength = -1;
+ int lteRsrp = -1;
+ int lteRsrq = -1;
+ int lteRssnr = -1;
+ int lteCqi = -1;
if (ar.exception != null) {
// -1 = unknown
@@ -1169,6 +1193,11 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
// bug 658816 seems to be a case where the result is 0-length
if (ints.length != 0) {
rssi = ints[0];
+ lteSignalStrength = ints[7];
+ lteRsrp = ints[8];
+ lteRsrq = ints[9];
+ lteRssnr = ints[10];
+ lteCqi = ints[11];
} else {
Log.e(LOG_TAG, "Bogus signal strength response");
rssi = 99;
@@ -1176,7 +1205,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
}
mSignalStrength = new SignalStrength(rssi, -1, -1, -1,
- -1, -1, -1, true);
+ -1, -1, -1, lteSignalStrength, lteRsrp, lteRsrq, lteRssnr, lteCqi, true);
if (!mSignalStrength.equals(oldSignalStrength)) {
try { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after
diff --git a/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java b/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
index 1939f953dd42..b6c3b67a134c 100644
--- a/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipCommandInterface.java
@@ -144,10 +144,10 @@ class SipCommandInterface extends BaseCommands implements CommandsInterface {
public void getSignalStrength (Message result) {
}
- public void getRegistrationState (Message result) {
+ public void getVoiceRegistrationState (Message result) {
}
- public void getGPRSRegistrationState (Message result) {
+ public void getDataRegistrationState (Message result) {
}
public void getOperator(Message result) {
@@ -339,7 +339,7 @@ class SipCommandInterface extends BaseCommands implements CommandsInterface {
public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
}
- public void setCdmaSubscription(int cdmaSubscription , Message response) {
+ public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) {
}
public void queryTTYMode(Message response) {
@@ -362,4 +362,29 @@ class SipCommandInterface extends BaseCommands implements CommandsInterface {
public void exitEmergencyCallbackMode(Message response) {
}
+
+ @Override
+ public void supplyIccPinForApp(String pin, String aid, Message response) {
+ }
+
+ @Override
+ public void supplyIccPukForApp(String puk, String newPin, String aid, Message response) {
+ }
+
+ @Override
+ public void supplyIccPin2ForApp(String pin2, String aid, Message response) {
+ }
+
+ @Override
+ public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message response) {
+ }
+
+ @Override
+ public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message response) {
+ }
+
+ @Override
+ public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr,
+ Message response) {
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
index 8b3a3adc2d74..242d44fc6aa3 100644
--- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
+++ b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java
@@ -825,7 +825,7 @@ public final class SimulatedCommands extends BaseCommands
* Please note that registration state 4 ("unknown") is treated
* as "out of service" above
*/
- public void getRegistrationState (Message result) {
+ public void getVoiceRegistrationState (Message result) {
String ret[] = new String[14];
ret[0] = "5"; // registered roam
@@ -863,7 +863,7 @@ public final class SimulatedCommands extends BaseCommands
* Please note that registration state 4 ("unknown") is treated
* as "out of service" in the Android telephony system
*/
- public void getGPRSRegistrationState (Message result) {
+ public void getDataRegistrationState (Message result) {
String ret[] = new String[4];
ret[0] = "5"; // registered roam
@@ -1361,7 +1361,7 @@ public final class SimulatedCommands extends BaseCommands
}
public void
- setCdmaSubscription(int cdmaSubscriptionType, Message response) {
+ setCdmaSubscriptionSource(int cdmaSubscriptionType, Message response) {
Log.w(LOG_TAG, "CDMA not implemented in SimulatedCommands");
unimplemented(response);
}
@@ -1468,4 +1468,35 @@ public final class SimulatedCommands extends BaseCommands
public void getGsmBroadcastConfig(Message response) {
unimplemented(response);
}
+
+ @Override
+ public void supplyIccPinForApp(String pin, String aid, Message response) {
+ unimplemented(response);
+ }
+
+ @Override
+ public void supplyIccPukForApp(String puk, String newPin, String aid, Message response) {
+ unimplemented(response);
+ }
+
+ @Override
+ public void supplyIccPin2ForApp(String pin2, String aid, Message response) {
+ unimplemented(response);
+ }
+
+ @Override
+ public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message response) {
+ unimplemented(response);
+ }
+
+ @Override
+ public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message response) {
+ unimplemented(response);
+ }
+
+ @Override
+ public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr,
+ Message response) {
+ unimplemented(response);
+ }
}
diff --git a/tests/RenderScriptTests/Android.mk b/tests/RenderScriptTests/Android.mk
new file mode 100644
index 000000000000..5053e7d64389
--- /dev/null
+++ b/tests/RenderScriptTests/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/libs/rs/java/ImageProcessing/Android.mk b/tests/RenderScriptTests/ImageProcessing/Android.mk
index 7fa30d0b8bdd..7fa30d0b8bdd 100644
--- a/libs/rs/java/ImageProcessing/Android.mk
+++ b/tests/RenderScriptTests/ImageProcessing/Android.mk
diff --git a/libs/rs/java/ImageProcessing/AndroidManifest.xml b/tests/RenderScriptTests/ImageProcessing/AndroidManifest.xml
index 0fcbf1e70ae5..69a33bc31d3f 100644
--- a/libs/rs/java/ImageProcessing/AndroidManifest.xml
+++ b/tests/RenderScriptTests/ImageProcessing/AndroidManifest.xml
@@ -6,8 +6,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-sdk android:minSdkVersion="11" />
<application android:label="Image Processing">
- <activity android:name="ImageProcessingActivity"
- android:screenOrientation="portrait">
+ <activity android:name="ImageProcessingActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
diff --git a/libs/rs/java/ImageProcessing/res/drawable-hdpi/data.jpg b/tests/RenderScriptTests/ImageProcessing/res/drawable-hdpi/data.jpg
index 81a87b1726c2..81a87b1726c2 100644
--- a/libs/rs/java/ImageProcessing/res/drawable-hdpi/data.jpg
+++ b/tests/RenderScriptTests/ImageProcessing/res/drawable-hdpi/data.jpg
Binary files differ
diff --git a/libs/rs/java/ImageProcessing/res/drawable/data.jpg b/tests/RenderScriptTests/ImageProcessing/res/drawable/data.jpg
index 81a87b1726c2..81a87b1726c2 100644
--- a/libs/rs/java/ImageProcessing/res/drawable/data.jpg
+++ b/tests/RenderScriptTests/ImageProcessing/res/drawable/data.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/ImageProcessing/res/layout/main.xml b/tests/RenderScriptTests/ImageProcessing/res/layout/main.xml
new file mode 100644
index 000000000000..b271b431a54c
--- /dev/null
+++ b/tests/RenderScriptTests/ImageProcessing/res/layout/main.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <SurfaceView
+ android:id="@+id/surface"
+ android:layout_width="1dip"
+ android:layout_height="1dip" />
+ <ImageView
+ android:id="@+id/display"
+ android:layout_width="320dip"
+ android:layout_height="266dip" />
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/benchmark"
+ android:onClick="benchmark"/>
+ <TextView
+ android:id="@+id/benchmarkText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:text="@string/saturation"/>
+ </LinearLayout>
+ <ScrollView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <TextView
+ android:id="@+id/inSaturationText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/saturation"/>
+ <SeekBar
+ android:id="@+id/inSaturation"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/inGammaText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/gamma"/>
+ <SeekBar
+ android:id="@+id/inGamma"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/outWhiteText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:textSize="8pt"
+ android:text="@string/out_white"/>
+ <SeekBar
+ android:id="@+id/outWhite"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/inWhiteText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/in_white"/>
+ <SeekBar
+ android:id="@+id/inWhite"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/outBlackText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/out_black"/>
+ <SeekBar
+ android:id="@+id/outBlack"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/inBlackText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/in_black"/>
+ <SeekBar
+ android:id="@+id/inBlack"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ <TextView
+ android:id="@+id/blurText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="8pt"
+ android:layout_marginLeft="10sp"
+ android:layout_marginTop="15sp"
+ android:text="@string/blur_description"/>
+ <SeekBar
+ android:id="@+id/radius"
+ android:layout_marginLeft="10sp"
+ android:layout_marginRight="10sp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ </LinearLayout>
+ </ScrollView>
+</LinearLayout>
+
diff --git a/libs/rs/java/ImageProcessing/res/values/strings.xml b/tests/RenderScriptTests/ImageProcessing/res/values/strings.xml
index cc5cc4de9782..cc5cc4de9782 100644
--- a/libs/rs/java/ImageProcessing/res/values/strings.xml
+++ b/tests/RenderScriptTests/ImageProcessing/res/values/strings.xml
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index 5de09f75322c..4f2f52ab656a 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -346,7 +346,7 @@ public class ImageProcessingActivity extends Activity
mSaturationSeekBar.setProgress(50);
mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText);
- mBenchmarkResult.setText("Benchmark not yet run");
+ mBenchmarkResult.setText("Result: not run");
}
public void surfaceCreated(SurfaceHolder holder) {
@@ -430,7 +430,7 @@ public class ImageProcessingActivity extends Activity
//long javaTime = javaFilter();
//mBenchmarkResult.setText("RS: " + t + " ms Java: " + javaTime + " ms");
- mBenchmarkResult.setText("RS: " + t + " ms");
+ mBenchmarkResult.setText("Result: " + t + " ms");
mRadius = oldRadius;
mScript.set_radius(mRadius);
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs
index 652ffd76dd3d..652ffd76dd3d 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ip.rsh b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ip.rsh
index 1d7a7197908d..1d7a7197908d 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ip.rsh
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ip.rsh
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/threshold.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/threshold.rs
index f2f9a361fa90..f2f9a361fa90 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/threshold.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/threshold.rs
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vertical_blur.rs
index bd4ae4eca3b7..bd4ae4eca3b7 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vertical_blur.rs
diff --git a/libs/rs/java/ModelViewer/Android.mk b/tests/RenderScriptTests/ModelViewer/Android.mk
index efe77d7ac73b..efe77d7ac73b 100644
--- a/libs/rs/java/ModelViewer/Android.mk
+++ b/tests/RenderScriptTests/ModelViewer/Android.mk
diff --git a/libs/rs/java/ModelViewer/AndroidManifest.xml b/tests/RenderScriptTests/ModelViewer/AndroidManifest.xml
index e5e449b31573..e5e449b31573 100644
--- a/libs/rs/java/ModelViewer/AndroidManifest.xml
+++ b/tests/RenderScriptTests/ModelViewer/AndroidManifest.xml
diff --git a/libs/rs/java/ModelViewer/res/drawable/robot.png b/tests/RenderScriptTests/ModelViewer/res/drawable/robot.png
index f7353fd61c5b..f7353fd61c5b 100644
--- a/libs/rs/java/ModelViewer/res/drawable/robot.png
+++ b/tests/RenderScriptTests/ModelViewer/res/drawable/robot.png
Binary files differ
diff --git a/libs/rs/java/ModelViewer/res/menu/loader_menu.xml b/tests/RenderScriptTests/ModelViewer/res/menu/loader_menu.xml
index 3c340238b778..3c340238b778 100644
--- a/libs/rs/java/ModelViewer/res/menu/loader_menu.xml
+++ b/tests/RenderScriptTests/ModelViewer/res/menu/loader_menu.xml
diff --git a/libs/rs/java/ModelViewer/res/raw/robot.a3d b/tests/RenderScriptTests/ModelViewer/res/raw/robot.a3d
index f48895cd8451..f48895cd8451 100644
--- a/libs/rs/java/ModelViewer/res/raw/robot.a3d
+++ b/tests/RenderScriptTests/ModelViewer/res/raw/robot.a3d
Binary files differ
diff --git a/libs/rs/java/ModelViewer/res/values/strings.xml b/tests/RenderScriptTests/ModelViewer/res/values/strings.xml
index 8e1673f41179..8e1673f41179 100644
--- a/libs/rs/java/ModelViewer/res/values/strings.xml
+++ b/tests/RenderScriptTests/ModelViewer/res/values/strings.xml
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/A3DSelector.java b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/A3DSelector.java
index 0e2004f2046f..0e2004f2046f 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/A3DSelector.java
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/A3DSelector.java
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraph.java b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SceneGraph.java
index b8717a732209..b8717a732209 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraph.java
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SceneGraph.java
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
index f91f31ee35e7..f91f31ee35e7 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphView.java b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SceneGraphView.java
index 0b6a3b863866..0b6a3b863866 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphView.java
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SceneGraphView.java
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SgTransform.java b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SgTransform.java
index f5484e29c424..f5484e29c424 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SgTransform.java
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SgTransform.java
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModel.java b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SimpleModel.java
index 01cb70996237..01cb70996237 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModel.java
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SimpleModel.java
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
index 63ef4666a587..63ef4666a587 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelView.java b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SimpleModelView.java
index 9ab0f22f9129..9ab0f22f9129 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelView.java
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/SimpleModelView.java
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/scenegraph.rs b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/scenegraph.rs
index 36790686feca..36790686feca 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/scenegraph.rs
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/scenegraph.rs
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs
index 1034b85c55d7..4c38745574c4 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs
@@ -157,5 +157,5 @@ int root(int launchID) {
drawDescription();
- return 10;
+ return 0;
}
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/transform.rs b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/transform.rs
index f328025ecf96..f328025ecf96 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/transform.rs
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/transform.rs
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/transform_def.rsh b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/transform_def.rsh
index 24a36c1db28e..24a36c1db28e 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/transform_def.rsh
+++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/transform_def.rsh
diff --git a/tests/RenderScriptTests/PerfTest/Android.mk b/tests/RenderScriptTests/PerfTest/Android.mk
new file mode 100644
index 000000000000..85b0a65dd289
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
+
+LOCAL_PACKAGE_NAME := PerfTest
+
+include $(BUILD_PACKAGE)
+
+endif
diff --git a/tests/RenderScriptTests/PerfTest/AndroidManifest.xml b/tests/RenderScriptTests/PerfTest/AndroidManifest.xml
new file mode 100644
index 000000000000..3afb3b289259
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.perftest">
+ <uses-sdk android:minSdkVersion="11" />
+ <application android:label="PerfTest"
+ android:icon="@drawable/test_pattern">
+ <activity android:name="RsBench"
+ android:label="RsBenchmark"
+ android:theme="@android:style/Theme.Black.NoTitleBar">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/tests/RenderScriptTests/PerfTest/res/drawable/checker.png b/tests/RenderScriptTests/PerfTest/res/drawable/checker.png
new file mode 100644
index 000000000000..b631e1ee4ba6
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/drawable/checker.png
Binary files differ
diff --git a/tests/RenderScriptTests/PerfTest/res/drawable/data.png b/tests/RenderScriptTests/PerfTest/res/drawable/data.png
new file mode 100644
index 000000000000..8e347146e331
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/drawable/data.png
Binary files differ
diff --git a/tests/RenderScriptTests/PerfTest/res/drawable/leaf.png b/tests/RenderScriptTests/PerfTest/res/drawable/leaf.png
new file mode 100644
index 000000000000..3cd37755f549
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/drawable/leaf.png
Binary files differ
diff --git a/libs/rs/java/tests/res/drawable/test_pattern.png b/tests/RenderScriptTests/PerfTest/res/drawable/test_pattern.png
index e7d145554c00..e7d145554c00 100644
--- a/libs/rs/java/tests/res/drawable/test_pattern.png
+++ b/tests/RenderScriptTests/PerfTest/res/drawable/test_pattern.png
Binary files differ
diff --git a/tests/RenderScriptTests/PerfTest/res/drawable/torusmap.png b/tests/RenderScriptTests/PerfTest/res/drawable/torusmap.png
new file mode 100644
index 000000000000..1e08f3b9ac3e
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/drawable/torusmap.png
Binary files differ
diff --git a/tests/RenderScriptTests/PerfTest/res/raw/multitexf.glsl b/tests/RenderScriptTests/PerfTest/res/raw/multitexf.glsl
new file mode 100644
index 000000000000..e492a477ff5b
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/raw/multitexf.glsl
@@ -0,0 +1,13 @@
+varying vec2 varTex0;
+
+void main() {
+ vec2 t0 = varTex0.xy;
+ lowp vec4 col0 = texture2D(UNI_Tex0, t0).rgba;
+ lowp vec4 col1 = texture2D(UNI_Tex1, t0*4.0).rgba;
+ lowp vec4 col2 = texture2D(UNI_Tex2, t0).rgba;
+ col0.xyz = col0.xyz*col1.xyz*1.5;
+ col0.xyz = mix(col0.xyz, col2.xyz, col2.w);
+ col0.w = 0.5;
+ gl_FragColor = col0;
+}
+
diff --git a/tests/RenderScriptTests/PerfTest/res/raw/shader2f.glsl b/tests/RenderScriptTests/PerfTest/res/raw/shader2f.glsl
new file mode 100644
index 000000000000..5fc05f14a812
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/raw/shader2f.glsl
@@ -0,0 +1,29 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+void main() {
+
+ vec3 V = normalize(-varWorldPos.xyz);
+ vec3 worldNorm = normalize(varWorldNormal);
+
+ vec3 light0Vec = normalize(UNI_light0_Posision.xyz - varWorldPos);
+ vec3 light0R = -reflect(light0Vec, worldNorm);
+ float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0) * UNI_light0_Diffuse;
+ float light0Spec = clamp(dot(light0R, V), 0.001, 1.0);
+ float light0_Specular = pow(light0Spec, UNI_light0_CosinePower) * UNI_light0_Specular;
+
+ vec3 light1Vec = normalize(UNI_light1_Posision.xyz - varWorldPos);
+ vec3 light1R = reflect(light1Vec, worldNorm);
+ float light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0) * UNI_light1_Diffuse;
+ float light1Spec = clamp(dot(light1R, V), 0.001, 1.0);
+ float light1_Specular = pow(light1Spec, UNI_light1_CosinePower) * UNI_light1_Specular;
+
+ vec2 t0 = varTex0.xy;
+ lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
+ col.xyz = col.xyz * (light0_Diffuse * UNI_light0_DiffuseColor.xyz + light1_Diffuse * UNI_light1_DiffuseColor.xyz);
+ col.xyz += light0_Specular * UNI_light0_SpecularColor.xyz;
+ col.xyz += light1_Specular * UNI_light1_SpecularColor.xyz;
+ gl_FragColor = col;
+}
+
diff --git a/tests/RenderScriptTests/PerfTest/res/raw/shader2movev.glsl b/tests/RenderScriptTests/PerfTest/res/raw/shader2movev.glsl
new file mode 100644
index 000000000000..a2c807e838cc
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/raw/shader2movev.glsl
@@ -0,0 +1,21 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+// This is where actual shader code begins
+void main() {
+ vec4 objPos = ATTRIB_position;
+ vec3 oldPos = objPos.xyz;
+ objPos.xyz += 0.1*sin(objPos.xyz*2.0 + UNI_time);
+ objPos.xyz += 0.05*sin(objPos.xyz*4.0 + UNI_time*0.5);
+ objPos.xyz += 0.02*sin(objPos.xyz*7.0 + UNI_time*0.75);
+ vec4 worldPos = UNI_model * objPos;
+ gl_Position = UNI_proj * worldPos;
+
+ mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
+ vec3 worldNorm = model3 * (ATTRIB_normal + oldPos - objPos.xyz);
+
+ varWorldPos = worldPos.xyz;
+ varWorldNormal = worldNorm;
+ varTex0 = ATTRIB_texture0;
+}
diff --git a/tests/RenderScriptTests/PerfTest/res/raw/shader2v.glsl b/tests/RenderScriptTests/PerfTest/res/raw/shader2v.glsl
new file mode 100644
index 000000000000..e6885a38aca0
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/raw/shader2v.glsl
@@ -0,0 +1,17 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+// This is where actual shader code begins
+void main() {
+ vec4 objPos = ATTRIB_position;
+ vec4 worldPos = UNI_model * objPos;
+ gl_Position = UNI_proj * worldPos;
+
+ mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
+ vec3 worldNorm = model3 * ATTRIB_normal;
+
+ varWorldPos = worldPos.xyz;
+ varWorldNormal = worldNorm;
+ varTex0 = ATTRIB_texture0;
+}
diff --git a/tests/RenderScriptTests/PerfTest/res/raw/shaderf.glsl b/tests/RenderScriptTests/PerfTest/res/raw/shaderf.glsl
new file mode 100644
index 000000000000..d56e203496c3
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/raw/shaderf.glsl
@@ -0,0 +1,16 @@
+
+varying lowp float light0_Diffuse;
+varying lowp float light0_Specular;
+varying lowp float light1_Diffuse;
+varying lowp float light1_Specular;
+varying vec2 varTex0;
+
+void main() {
+ vec2 t0 = varTex0.xy;
+ lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
+ col.xyz = col.xyz * (light0_Diffuse * UNI_light0_DiffuseColor.xyz + light1_Diffuse * UNI_light1_DiffuseColor.xyz);
+ col.xyz += light0_Specular * UNI_light0_SpecularColor.xyz;
+ col.xyz += light1_Specular * UNI_light1_SpecularColor.xyz;
+ gl_FragColor = col;
+}
+
diff --git a/tests/RenderScriptTests/PerfTest/res/raw/shaderv.glsl b/tests/RenderScriptTests/PerfTest/res/raw/shaderv.glsl
new file mode 100644
index 000000000000..f7d01de384cb
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/raw/shaderv.glsl
@@ -0,0 +1,30 @@
+varying float light0_Diffuse;
+varying float light0_Specular;
+varying float light1_Diffuse;
+varying float light1_Specular;
+varying vec2 varTex0;
+
+// This is where actual shader code begins
+void main() {
+ vec4 worldPos = UNI_model * ATTRIB_position;
+ gl_Position = UNI_proj * worldPos;
+
+ mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
+ vec3 worldNorm = model3 * ATTRIB_normal;
+ vec3 V = normalize(-worldPos.xyz);
+
+ vec3 light0Vec = normalize(UNI_light0_Posision.xyz - worldPos.xyz);
+ vec3 light0R = -reflect(light0Vec, worldNorm);
+ light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0) * UNI_light0_Diffuse;
+ float light0Spec = clamp(dot(light0R, V), 0.001, 1.0);
+ light0_Specular = pow(light0Spec, UNI_light0_CosinePower) * UNI_light0_Specular;
+
+ vec3 light1Vec = normalize(UNI_light1_Posision.xyz - worldPos.xyz);
+ vec3 light1R = reflect(light1Vec, worldNorm);
+ light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0) * UNI_light1_Diffuse;
+ float light1Spec = clamp(dot(light1R, V), 0.001, 1.0);
+ light1_Specular = pow(light1Spec, UNI_light1_CosinePower) * UNI_light1_Specular;
+
+ gl_PointSize = 1.0;
+ varTex0 = ATTRIB_texture0;
+}
diff --git a/tests/RenderScriptTests/PerfTest/res/raw/torus.a3d b/tests/RenderScriptTests/PerfTest/res/raw/torus.a3d
new file mode 100644
index 000000000000..0322b01be8a8
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/raw/torus.a3d
Binary files differ
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsBench.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java
index a29dddcf3390..cfe1970ba819 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsBench.java
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.samples;
+package com.android.perftest;
import android.renderscript.RSSurfaceView;
import android.renderscript.RenderScript;
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java
index 1afcee335a50..9757ec693f00 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsBenchRS.java
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.samples;
+package com.android.perftest;
import java.io.Writer;
@@ -84,9 +84,6 @@ public class RsBenchRS {
private ScriptField_VertexShaderConstants3_s mVSConstPixel;
private ScriptField_FragentShaderConstants3_s mFSConstPixel;
- private ProgramVertex mProgVertexCube;
- private ProgramFragment mProgFragmentCube;
-
private ProgramRaster mCullBack;
private ProgramRaster mCullFront;
private ProgramRaster mCullNone;
@@ -95,7 +92,6 @@ public class RsBenchRS {
private Allocation mTexOpaque;
private Allocation mTexTransparent;
private Allocation mTexChecker;
- private Allocation mTexCube;
private Mesh m10by10Mesh;
private Mesh m100by100Mesh;
@@ -247,19 +243,6 @@ public class RsBenchRS {
// Bind the source of constant data
mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0);
- // Cubemap test shaders
- pvbCustom = new ProgramVertex.Builder(mRS);
- pvbCustom.setShader(mRes, R.raw.shadercubev);
- pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
- pvbCustom.addConstant(mVSConst.getAllocation().getType());
- mProgVertexCube = pvbCustom.create();
- mProgVertexCube.bindConstants(mVSConst.getAllocation(), 0);
-
- pfbCustom = new ProgramFragment.Builder(mRS);
- pfbCustom.setShader(mRes, R.raw.shadercubef);
- pfbCustom.addTexture(Program.TextureType.TEXTURE_CUBE);
- mProgFragmentCube = pfbCustom.create();
-
pvbCustom = new ProgramVertex.Builder(mRS);
pvbCustom.setShader(mRes, R.raw.shader2v);
pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
@@ -290,8 +273,6 @@ public class RsBenchRS {
mScript.set_gProgVertexCustom(mProgVertexCustom);
mScript.set_gProgFragmentCustom(mProgFragmentCustom);
- mScript.set_gProgVertexCube(mProgVertexCube);
- mScript.set_gProgFragmentCube(mProgFragmentCube);
mScript.set_gProgVertexPixelLight(mProgVertexPixelLight);
mScript.set_gProgVertexPixelLightMove(mProgVertexPixelLightMove);
mScript.set_gProgFragmentPixelLight(mProgFragmentPixelLight);
@@ -316,14 +297,11 @@ public class RsBenchRS {
mTexOpaque = loadTextureRGB(R.drawable.data);
mTexTransparent = loadTextureARGB(R.drawable.leaf);
mTexChecker = loadTextureRGB(R.drawable.checker);
- Bitmap b = BitmapFactory.decodeResource(mRes, R.drawable.cubemap_test);
- mTexCube = Allocation.createCubemapFromBitmap(mRS, b);
mScript.set_gTexTorus(mTexTorus);
mScript.set_gTexOpaque(mTexOpaque);
mScript.set_gTexTransparent(mTexTransparent);
mScript.set_gTexChecker(mTexChecker);
- mScript.set_gTexCube(mTexCube);
}
private void initFonts() {
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsBenchView.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java
index 0a566682ea56..ee7e50837d0b 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsBenchView.java
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.samples;
+package com.android.perftest;
import java.io.Writer;
import java.util.ArrayList;
diff --git a/libs/rs/java/Samples/src/com/android/samples/rsbench.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
index a1368e68fc10..3c92725942c2 100644
--- a/libs/rs/java/Samples/src/com/android/samples/rsbench.rs
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
@@ -14,7 +14,7 @@
#pragma version(1)
-#pragma rs java_package_name(com.android.samples)
+#pragma rs java_package_name(com.android.perftest)
#include "rs_graphics.rsh"
#include "shader_def.rsh"
@@ -34,7 +34,6 @@ rs_allocation gTexOpaque;
rs_allocation gTexTorus;
rs_allocation gTexTransparent;
rs_allocation gTexChecker;
-rs_allocation gTexCube;
rs_mesh g10by10Mesh;
rs_mesh g100by100Mesh;
@@ -75,8 +74,6 @@ rs_program_fragment gProgFragmentCustom;
rs_program_vertex gProgVertexPixelLight;
rs_program_vertex gProgVertexPixelLightMove;
rs_program_fragment gProgFragmentPixelLight;
-rs_program_vertex gProgVertexCube;
-rs_program_fragment gProgFragmentCube;
rs_program_fragment gProgFragmentMultitex;
float gDt = 0;
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/shader_def.rsh b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/shader_def.rsh
new file mode 100644
index 000000000000..1d77ea9dce8b
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/shader_def.rsh
@@ -0,0 +1,83 @@
+// Copyright (C) 2009 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.perftest)
+
+typedef struct VertexShaderConstants_s {
+ rs_matrix4x4 model;
+ rs_matrix4x4 proj;
+ float4 light0_Posision;
+ float light0_Diffuse;
+ float light0_Specular;
+ float light0_CosinePower;
+
+ float4 light1_Posision;
+ float light1_Diffuse;
+ float light1_Specular;
+ float light1_CosinePower;
+} VertexShaderConstants;
+
+typedef struct VertexShaderConstants2_s {
+ rs_matrix4x4 model[2];
+ rs_matrix4x4 proj;
+ float4 light_Posision[2];
+ float light_Diffuse[2];
+ float light_Specular[2];
+ float light_CosinePower[2];
+} VertexShaderConstants2;
+
+typedef struct VertexShaderConstants3_s {
+ rs_matrix4x4 model;
+ rs_matrix4x4 proj;
+ float time;
+} VertexShaderConstants3;
+
+
+typedef struct FragentShaderConstants_s {
+ float4 light0_DiffuseColor;
+ float4 light0_SpecularColor;
+
+ float4 light1_DiffuseColor;
+ float4 light1_SpecularColor;
+} FragentShaderConstants;
+
+typedef struct FragentShaderConstants2_s {
+ float4 light_DiffuseColor[2];
+ float4 light_SpecularColor[2];
+} FragentShaderConstants2;
+
+typedef struct FragentShaderConstants3_s {
+ float4 light0_DiffuseColor;
+ float4 light0_SpecularColor;
+ float4 light0_Posision;
+ float light0_Diffuse;
+ float light0_Specular;
+ float light0_CosinePower;
+
+ float4 light1_DiffuseColor;
+ float4 light1_SpecularColor;
+ float4 light1_Posision;
+ float light1_Diffuse;
+ float light1_Specular;
+ float light1_CosinePower;
+} FragentShaderConstants3;
+
+typedef struct VertexShaderInputs_s {
+ float4 position;
+ float3 normal;
+ float2 texture0;
+} VertexShaderInputs;
+
diff --git a/libs/rs/java/tests/Android.mk b/tests/RenderScriptTests/tests/Android.mk
index 6c992d5baf0b..6c992d5baf0b 100644
--- a/libs/rs/java/tests/Android.mk
+++ b/tests/RenderScriptTests/tests/Android.mk
diff --git a/libs/rs/java/tests/AndroidManifest.xml b/tests/RenderScriptTests/tests/AndroidManifest.xml
index b660398de1a4..b660398de1a4 100644
--- a/libs/rs/java/tests/AndroidManifest.xml
+++ b/tests/RenderScriptTests/tests/AndroidManifest.xml
diff --git a/tests/RenderScriptTests/tests/res/drawable/test_pattern.png b/tests/RenderScriptTests/tests/res/drawable/test_pattern.png
new file mode 100644
index 000000000000..e7d145554c00
--- /dev/null
+++ b/tests/RenderScriptTests/tests/res/drawable/test_pattern.png
Binary files differ
diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTest.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTest.java
index 6b8fa6b8a02c..6b8fa6b8a02c 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/RSTest.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTest.java
diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
index 541bf2234f76..541bf2234f76 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestView.java
index 368f2866ad2d..368f2866ad2d 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestView.java
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_fp_mad.java
index f2c91afd045b..f2c91afd045b 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_fp_mad.java
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_math.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math.java
index bf133be07619..bf133be07619 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_math.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_math.java
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_primitives.java
index b7a65a57951e..b7a65a57951e 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_primitives.java
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_rsdebug.java
index 0614b1a63b80..0614b1a63b80 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_rsdebug.java
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_rstime.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_rstime.java
index f302e1a3f0e3..f302e1a3f0e3 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_rstime.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_rstime.java
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_rstypes.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_rstypes.java
index 74211c8d0a75..74211c8d0a75 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_rstypes.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_rstypes.java
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java
index a7722c7deab4..a7722c7deab4 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java
diff --git a/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/fp_mad.rs
index b6f2b2a60371..b6f2b2a60371 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/fp_mad.rs
diff --git a/libs/rs/java/tests/src/com/android/rs/test/math.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/math.rs
index 8cad82bfd569..8cad82bfd569 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/math.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/math.rs
diff --git a/libs/rs/java/tests/src/com/android/rs/test/primitives.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/primitives.rs
index ce451da8b415..ce451da8b415 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/primitives.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/primitives.rs
diff --git a/libs/rs/java/tests/src/com/android/rs/test/rsdebug.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/rsdebug.rs
index f7942a5eaf16..f7942a5eaf16 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/rsdebug.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/rsdebug.rs
diff --git a/libs/rs/java/tests/src/com/android/rs/test/rslist.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/rslist.rs
index 67c2b8623c61..67c2b8623c61 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/rslist.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/rslist.rs
diff --git a/libs/rs/java/tests/src/com/android/rs/test/rstime.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/rstime.rs
index 5e3e07816f9c..5e3e07816f9c 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/rstime.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/rstime.rs
diff --git a/libs/rs/java/tests/src/com/android/rs/test/rstypes.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/rstypes.rs
index f3bf2448a4f6..f3bf2448a4f6 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/rstypes.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/rstypes.rs
diff --git a/libs/rs/java/tests/src/com/android/rs/test/shared.rsh b/tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh
index 21be9af2678e..21be9af2678e 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/shared.rsh
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/shared.rsh
diff --git a/libs/rs/java/tests/src/com/android/rs/test/test_root.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/test_root.rs
index 6dc83ba13019..6dc83ba13019 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/test_root.rs
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/test_root.rs
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 90dcc2727e7f..acc7379990d4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -192,6 +192,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
Capability.UNBOUND_RENDERING,
Capability.CUSTOM_BACKGROUND_COLOR,
Capability.RENDER,
+ Capability.LAYOUT_ONLY,
Capability.EMBEDDED_LAYOUT,
Capability.VIEW_MANIPULATION,
Capability.PLAY_ANIMATION,
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 33dd2144ec53..7d794bd1a7f6 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -425,36 +425,72 @@ public final class BridgeContext extends Activity {
}
}
- if (defStyleValues == null && defStyleAttr != 0) {
- // get the name from the int.
- String defStyleName = searchAttr(defStyleAttr);
+ if (defStyleValues == null) {
+ if (defStyleAttr != 0) {
+ // get the name from the int.
+ String defStyleName = searchAttr(defStyleAttr);
- if (defaultPropMap != null) {
- defaultPropMap.put("style", defStyleName);
- }
+ if (defaultPropMap != null) {
+ defaultPropMap.put("style", defStyleName);
+ }
- // look for the style in the current theme, and its parent:
- ResourceValue item = mRenderResources.findItemInTheme(defStyleName);
+ // look for the style in the current theme, and its parent:
+ ResourceValue item = mRenderResources.findItemInTheme(defStyleName);
- if (item != null) {
- // item is a reference to a style entry. Search for it.
- item = mRenderResources.findResValue(item.getValue(),
- false /*forceFrameworkOnly*/);
+ if (item != null) {
+ // item is a reference to a style entry. Search for it.
+ item = mRenderResources.findResValue(item.getValue(),
+ false /*forceFrameworkOnly*/);
- if (item instanceof StyleResourceValue) {
- defStyleValues = (StyleResourceValue)item;
+ if (item instanceof StyleResourceValue) {
+ defStyleValues = (StyleResourceValue)item;
+ }
+ } else {
+ Bridge.getLog().error(null,
+ String.format(
+ "Failed to find style '%s' in current theme", defStyleName),
+ null /*data*/);
+ }
+ } else if (defStyleRes != 0) {
+ Pair<ResourceType, String> value = Bridge.resolveResourceId(defStyleRes);
+ if (value == null) {
+ value = mProjectCallback.resolveResourceId(defStyleRes);
}
- } else {
- Bridge.getLog().error(null,
- String.format(
- "Failed to find style '%s' in current theme", defStyleName),
- null /*data*/);
- }
- }
- if (defStyleRes != 0) {
- // FIXME: See what we need to do with this.
- throw new UnsupportedOperationException();
+ if (value != null) {
+ if (value.getFirst() == ResourceType.STYLE) {
+ // look for the style in the current theme, and its parent:
+ ResourceValue item = mRenderResources.findItemInTheme(value.getSecond());
+ if (item != null) {
+ if (item instanceof StyleResourceValue) {
+ if (defaultPropMap != null) {
+ defaultPropMap.put("style", item.getName());
+ }
+
+ defStyleValues = (StyleResourceValue)item;
+ }
+ } else {
+ Bridge.getLog().error(null,
+ String.format(
+ "Style with id 0x%x (resolved to '%s') does not exist.",
+ defStyleRes, value.getSecond()),
+ null /*data*/);
+ }
+ } else {
+ Bridge.getLog().error(null,
+ String.format(
+ "Resouce id 0x%x is not of type STYLE (instead %s)",
+ defStyleRes, value.getFirst().toString()),
+ null /*data*/);
+ }
+ } else {
+ Bridge.getLog().error(null,
+ String.format(
+ "Failed to find style with id 0x%x in current theme",
+ defStyleRes),
+ null /*data*/);
+ }
+ }
}
String namespace = BridgeConstants.NS_RESOURCES;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
index 30da2ffc13bc..c1d760069188 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
@@ -188,6 +188,10 @@ public final class BridgeTypedArray extends TypedArray {
String s = mResourceData[index].getValue();
+ if (RenderResources.REFERENCE_NULL.equals(s)) {
+ return defValue;
+ }
+
try {
return (s == null) ? defValue : XmlUtils.convertValueToInt(s, defValue);
} catch (NumberFormatException e) {
@@ -301,6 +305,10 @@ public final class BridgeTypedArray extends TypedArray {
return null;
}
+ if (RenderResources.REFERENCE_NULL.equals(value)) {
+ return null;
+ }
+
// let the framework inflate the ColorStateList from the XML file.
File f = new File(value);
if (f.isFile()) {
@@ -337,8 +345,6 @@ public final class BridgeTypedArray extends TypedArray {
Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, e.getMessage(), e, null /*data*/);
}
- assert false;
-
return null;
}
@@ -408,6 +414,10 @@ public final class BridgeTypedArray extends TypedArray {
return LayoutParams.WRAP_CONTENT;
}
+ if (RenderResources.REFERENCE_NULL.equals(s)) {
+ return defValue;
+ }
+
if (ResourceHelper.stringToFloat(s, mValue)) {
return mValue.getDimension(mBridgeResources.mMetrics);
}
@@ -418,8 +428,6 @@ public final class BridgeTypedArray extends TypedArray {
"\"%1$s\" in attribute \"%2$s\" is not a valid format.",
s, mNames[index]), null /*data*/);
- assert false;
-
return defValue;
}
@@ -480,6 +488,10 @@ public final class BridgeTypedArray extends TypedArray {
return LayoutParams.WRAP_CONTENT;
}
+ if (RenderResources.REFERENCE_NULL.equals(s)) {
+ return defValue;
+ }
+
// FIXME huh?
float f = getDimension(index, defValue);
@@ -553,8 +565,6 @@ public final class BridgeTypedArray extends TypedArray {
"\"%1$s\" in attribute \"%2$s\" cannont be converted to a fraction.",
value, mNames[index]), null /*data*/);
- assert false;
-
return defValue;
}
@@ -588,6 +598,10 @@ public final class BridgeTypedArray extends TypedArray {
return mContext.getDynamicIdByStyle((StyleResourceValue)resValue);
}
+ if (RenderResources.REFERENCE_NULL.equals(resValue.getValue())) {
+ return defValue;
+ }
+
// if the attribute was a reference to a resource, and not a declaration of an id (@+id),
// then the xml attribute value was "resolved" which leads us to a ResourceValue with a
// valid getType() and getName() returning a resource name.
@@ -666,8 +680,6 @@ public final class BridgeTypedArray extends TypedArray {
"Unable to resolve id \"%1$s\" for attribute \"%2$s\"", value, mNames[index]),
resValue);
- assert false;
-
return defValue;
}
@@ -715,6 +727,10 @@ public final class BridgeTypedArray extends TypedArray {
String value = mResourceData[index].getValue();
if (value != null) {
+ if (RenderResources.REFERENCE_NULL.equals(value)) {
+ return null;
+ }
+
return new CharSequence[] { value };
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index fedd789fe258..2fd58e425d9d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -421,57 +421,63 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
// now do the layout.
mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
- mViewRoot.mAttachInfo.mTreeObserver.dispatchOnPreDraw();
-
- // draw the views
- // create the BufferedImage into which the layout will be rendered.
- boolean newImage = false;
- if (newRenderSize || mCanvas == null) {
- if (params.getImageFactory() != null) {
- mImage = params.getImageFactory().getImage(
- mMeasuredScreenWidth,
- mMeasuredScreenHeight);
- } else {
- mImage = new BufferedImage(
- mMeasuredScreenWidth,
- mMeasuredScreenHeight,
- BufferedImage.TYPE_INT_ARGB);
- newImage = true;
+ if (params.isLayoutOnly()) {
+ // delete the canvas and image to reset them on the next full rendering
+ mImage = null;
+ mCanvas = null;
+ } else {
+ mViewRoot.mAttachInfo.mTreeObserver.dispatchOnPreDraw();
+
+ // draw the views
+ // create the BufferedImage into which the layout will be rendered.
+ boolean newImage = false;
+ if (newRenderSize || mCanvas == null) {
+ if (params.getImageFactory() != null) {
+ mImage = params.getImageFactory().getImage(
+ mMeasuredScreenWidth,
+ mMeasuredScreenHeight);
+ } else {
+ mImage = new BufferedImage(
+ mMeasuredScreenWidth,
+ mMeasuredScreenHeight,
+ BufferedImage.TYPE_INT_ARGB);
+ newImage = true;
+ }
+
+ if (params.isBgColorOverridden()) {
+ // since we override the content, it's the same as if it was a new image.
+ newImage = true;
+ Graphics2D gc = mImage.createGraphics();
+ gc.setColor(new Color(params.getOverrideBgColor(), true));
+ gc.setComposite(AlphaComposite.Src);
+ gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
+ gc.dispose();
+ }
+
+ // create an Android bitmap around the BufferedImage
+ Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
+ true /*isMutable*/, params.getDensity());
+
+ // create a Canvas around the Android bitmap
+ mCanvas = new Canvas(bitmap);
+ mCanvas.setDensity(params.getDensity().getDpiValue());
}
- if (params.isBgColorOverridden()) {
- // since we override the content, it's the same as if it was a new image.
- newImage = true;
+ if (freshRender && newImage == false) {
Graphics2D gc = mImage.createGraphics();
- gc.setColor(new Color(params.getOverrideBgColor(), true));
gc.setComposite(AlphaComposite.Src);
- gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
- gc.dispose();
- }
-
- // create an Android bitmap around the BufferedImage
- Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
- true /*isMutable*/, params.getDensity());
-
- // create a Canvas around the Android bitmap
- mCanvas = new Canvas(bitmap);
- mCanvas.setDensity(params.getDensity().getDpiValue());
- }
- if (freshRender && newImage == false) {
- Graphics2D gc = mImage.createGraphics();
- gc.setComposite(AlphaComposite.Src);
+ gc.setColor(new Color(0x00000000, true));
+ gc.fillRect(0, 0,
+ mMeasuredScreenWidth, mMeasuredScreenHeight);
- gc.setColor(new Color(0x00000000, true));
- gc.fillRect(0, 0,
- mMeasuredScreenWidth, mMeasuredScreenHeight);
+ // done
+ gc.dispose();
+ }
- // done
- gc.dispose();
+ mViewRoot.draw(mCanvas);
}
- mViewRoot.draw(mCanvas);
-
mViewInfoList = startVisitingViews(mViewRoot, 0);
// success!
diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp
index 097b109ab1f3..8ab9b6ae3de6 100644
--- a/tools/validatekeymaps/Main.cpp
+++ b/tools/validatekeymaps/Main.cpp
@@ -17,6 +17,7 @@
#include <ui/KeyCharacterMap.h>
#include <ui/KeyLayoutMap.h>
#include <ui/VirtualKeyMap.h>
+#include <utils/PropertyMap.h>
#include <utils/String8.h>
#include <stdio.h>
@@ -32,6 +33,7 @@ enum FileType {
FILETYPE_KEYLAYOUT,
FILETYPE_KEYCHARACTERMAP,
FILETYPE_VIRTUALKEYDEFINITION,
+ FILETYPE_INPUTDEVICECONFIGURATION,
};
@@ -39,9 +41,9 @@ static void usage() {
fprintf(stderr, "Keymap Validation Tool\n\n");
fprintf(stderr, "Usage:\n");
fprintf(stderr,
- " %s [*.kl] [*.kcm] [virtualkeys.*] [...]\n"
- " Validates the specified key layouts, key character maps \n"
- " or virtual key definitions.\n\n",
+ " %s [*.kl] [*.kcm] [*.idc] [virtualkeys.*] [...]\n"
+ " Validates the specified key layouts, key character maps, \n"
+ " input device configurations, or virtual key definitions.\n\n",
gProgName);
}
@@ -54,6 +56,9 @@ static FileType getFileType(const char* filename) {
if (strcmp(extension, ".kcm") == 0) {
return FILETYPE_KEYCHARACTERMAP;
}
+ if (strcmp(extension, ".idc") == 0) {
+ return FILETYPE_INPUTDEVICECONFIGURATION;
+ }
}
if (strstr(filename, "virtualkeys.")) {
@@ -92,6 +97,16 @@ static bool validateFile(const char* filename) {
break;
}
+ case FILETYPE_INPUTDEVICECONFIGURATION: {
+ PropertyMap* map;
+ status_t status = PropertyMap::load(String8(filename), &map);
+ if (status) {
+ fprintf(stderr, "Error %d parsing input device configuration file.\n\n", status);
+ return false;
+ }
+ break;
+ }
+
case FILETYPE_VIRTUALKEYDEFINITION: {
VirtualKeyMap* map;
status_t status = VirtualKeyMap::load(String8(filename), &map);
diff --git a/voip/java/android/net/sip/SipProfile.java b/voip/java/android/net/sip/SipProfile.java
index c7e18dfbae65..34d91dd7f84f 100644
--- a/voip/java/android/net/sip/SipProfile.java
+++ b/voip/java/android/net/sip/SipProfile.java
@@ -150,9 +150,8 @@ public class SipProfile implements Parcelable, Serializable, Cloneable {
/**
* Sets the username used for authentication.
*
- * @param name auth. name of the profile
+ * @param name authentication username of the profile
* @return this builder object
- * @hide // TODO: remove when we make it public
*/
public Builder setAuthUserName(String name) {
mProfile.mAuthUserName = name;
@@ -391,10 +390,10 @@ public class SipProfile implements Parcelable, Serializable, Cloneable {
/**
* Gets the username for authentication. If it is null, then the username
- * should be used in authentication instead.
+ * is used in authentication instead.
*
- * @return the auth. username
- * @hide // TODO: remove when we make it public
+ * @return the authentication username
+ * @see #getUserName
*/
public String getAuthUserName() {
return mAuthUserName;
diff --git a/voip/java/com/android/server/sip/SipHelper.java b/voip/java/com/android/server/sip/SipHelper.java
index 518543a5cbb2..ac580e740055 100644
--- a/voip/java/com/android/server/sip/SipHelper.java
+++ b/voip/java/com/android/server/sip/SipHelper.java
@@ -284,6 +284,13 @@ class SipHelper {
mHeaderFactory.createContentTypeHeader(
"application", "sdp"));
+ // Adding rport argument in the request could fix some SIP servers
+ // in resolving the initiator's NAT port mapping for relaying the
+ // response message from the other end.
+
+ ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
+ if (viaHeader != null) viaHeader.setRPort();
+
ClientTransaction clientTransaction =
mSipProvider.getNewClientTransaction(request);
if (DEBUG) Log.d(TAG, "send RE-INVITE: " + request);
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 847577fea4ff..7a9276d8e434 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -1,16 +1,16 @@
/**
* Copyright (c) 2008, The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
* limitations under the License.
*/
@@ -23,6 +23,7 @@ import android.net.wifi.WpsResult;
import android.net.wifi.ScanResult;
import android.net.DhcpInfo;
+import android.os.Messenger;
import android.os.WorkSource;
/**
@@ -111,5 +112,7 @@ interface IWifiManager
void forgetNetwork(int networkId);
WpsResult startWps(in WpsConfiguration config);
+
+ Messenger getMessenger();
}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index d5fb63e71412..28a5bc60609e 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -107,9 +107,16 @@ public class WifiConfiguration implements Parcelable {
* generated WEP keys. */
public static final int IEEE8021X = 3;
+ /** WPA2 pre-shared key for use with soft access point
+ * (requires {@code preSharedKey} to be specified).
+ * @hide
+ */
+ public static final int WPA2_PSK = 4;
+
public static final String varName = "key_mgmt";
- public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X" };
+ public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X",
+ "WPA2_PSK" };
}
/**
@@ -480,6 +487,20 @@ public class WifiConfiguration implements Parcelable {
dest.writeInt(nextSetBit);
}
+ /** @hide */
+ public int getAuthType() {
+ if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
+ return KeyMgmt.WPA_PSK;
+ } else if (allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) {
+ return KeyMgmt.WPA2_PSK;
+ } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) {
+ return KeyMgmt.WPA_EAP;
+ } else if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
+ return KeyMgmt.IEEE8021X;
+ }
+ return KeyMgmt.NONE;
+ }
+
/** Implement the Parcelable interface {@hide} */
public int describeContents() {
return 0;
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 4ac03a869d11..0807a241b29d 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -24,6 +24,7 @@ import android.os.IBinder;
import android.os.Handler;
import android.os.RemoteException;
import android.os.WorkSource;
+import android.os.Messenger;
import java.util.List;
@@ -60,7 +61,7 @@ public class WifiManager {
* Broadcast intent action indicating that Wi-Fi has been enabled, disabled,
* enabling, disabling, or unknown. One extra provides this state as an int.
* Another extra provides the previous state, if available.
- *
+ *
* @see #EXTRA_WIFI_STATE
* @see #EXTRA_PREVIOUS_WIFI_STATE
*/
@@ -71,7 +72,7 @@ public class WifiManager {
* The lookup key for an int that indicates whether Wi-Fi is enabled,
* disabled, enabling, disabling, or unknown. Retrieve it with
* {@link android.content.Intent#getIntExtra(String,int)}.
- *
+ *
* @see #WIFI_STATE_DISABLED
* @see #WIFI_STATE_DISABLING
* @see #WIFI_STATE_ENABLED
@@ -81,22 +82,22 @@ public class WifiManager {
public static final String EXTRA_WIFI_STATE = "wifi_state";
/**
* The previous Wi-Fi state.
- *
+ *
* @see #EXTRA_WIFI_STATE
*/
public static final String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
-
+
/**
* Wi-Fi is currently being disabled. The state will change to {@link #WIFI_STATE_DISABLED} if
* it finishes successfully.
- *
+ *
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
public static final int WIFI_STATE_DISABLING = 0;
/**
* Wi-Fi is disabled.
- *
+ *
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
@@ -104,14 +105,14 @@ public class WifiManager {
/**
* Wi-Fi is currently being enabled. The state will change to {@link #WIFI_STATE_ENABLED} if
* it finishes successfully.
- *
+ *
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
public static final int WIFI_STATE_ENABLING = 2;
/**
* Wi-Fi is enabled.
- *
+ *
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
@@ -119,7 +120,7 @@ public class WifiManager {
/**
* Wi-Fi is in an unknown state. This state will occur when an error happens while enabling
* or disabling.
- *
+ *
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
@@ -418,6 +419,22 @@ public class WifiManager {
*/
public static final int WIFI_FREQUENCY_BAND_2GHZ = 2;
+ /** List of asyncronous notifications
+ * @hide
+ */
+ public static final int DATA_ACTIVITY_NOTIFICATION = 1;
+
+ //Lowest bit indicates data reception and the second lowest
+ //bit indicates data transmitted
+ /** @hide */
+ public static final int DATA_ACTIVITY_NONE = 0x00;
+ /** @hide */
+ public static final int DATA_ACTIVITY_IN = 0x01;
+ /** @hide */
+ public static final int DATA_ACTIVITY_OUT = 0x02;
+ /** @hide */
+ public static final int DATA_ACTIVITY_INOUT = 0x03;
+
IWifiManager mService;
Handler mHandler;
@@ -478,7 +495,7 @@ public class WifiManager {
* <p/>
* The new network will be marked DISABLED by default. To enable it,
* called {@link #enableNetwork}.
- *
+ *
* @param config the set of variables that describe the configuration,
* contained in a {@link WifiConfiguration} object.
* @return the ID of the newly created network description. This is used in
@@ -518,7 +535,7 @@ public class WifiManager {
/**
* Internal method for doing the RPC that creates a new network description
* or updates an existing one.
- *
+ *
* @param config The possibly sparse object containing the variables that
* are to set or updated in the network description.
* @return the ID of the network on success, {@code -1} on failure.
@@ -705,7 +722,7 @@ public class WifiManager {
* Note: It is possible for this method to change the network IDs of
* existing networks. You should assume the network IDs can be different
* after calling this method.
- *
+ *
* @return {@code true} if the operation succeeded
*/
public boolean saveConfiguration() {
@@ -816,20 +833,20 @@ public class WifiManager {
return WIFI_STATE_UNKNOWN;
}
}
-
+
/**
- * Return whether Wi-Fi is enabled or disabled.
+ * Return whether Wi-Fi is enabled or disabled.
* @return {@code true} if Wi-Fi is enabled
* @see #getWifiState()
*/
public boolean isWifiEnabled() {
return getWifiState() == WIFI_STATE_ENABLED;
}
-
+
/**
* Calculates the level of the signal. This should be used any time a signal
* is being shown.
- *
+ *
* @param rssi The power of the signal measured in RSSI.
* @param numLevels The number of levels to consider in the calculated
* level.
@@ -847,10 +864,10 @@ public class WifiManager {
return (int)((float)(rssi - MIN_RSSI) * outputRange / inputRange);
}
}
-
+
/**
* Compares two signal strengths.
- *
+ *
* @param rssiA The power of the first signal measured in RSSI.
* @param rssiB The power of the second signal measured in RSSI.
* @return Returns <0 if the first signal is weaker than the second signal,
@@ -1115,9 +1132,24 @@ public class WifiManager {
}
/**
+ * Get a reference to WifiService handler. This is used by a client to establish
+ * an AsyncChannel communication with WifiService
+ *
+ * @return Messenger pointing to the WifiService handler
+ * @hide
+ */
+ public Messenger getMessenger() {
+ try {
+ return mService.getMessenger();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
* Allows an application to keep the Wi-Fi radio awake.
* Normally the Wi-Fi radio may turn off when the user has not used the device in a while.
- * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple
+ * Acquiring a WifiLock will keep the radio on until the lock is released. Multiple
* applications may hold WifiLocks, and the radio will only be allowed to turn off when no
* WifiLocks are held in any application.
*
@@ -1153,7 +1185,7 @@ public class WifiManager {
* Locks the Wi-Fi radio on until {@link #release} is called.
*
* If this WifiLock is reference-counted, each call to {@code acquire} will increment the
- * reference count, and the radio will remain locked as long as the reference count is
+ * reference count, and the radio will remain locked as long as the reference count is
* above zero.
*
* If this WifiLock is not reference-counted, the first call to {@code acquire} will lock
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 26fae7f95ae7..fc42ab8bdad9 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -435,10 +435,11 @@ public class WifiStateMachine extends HierarchicalStateMachine {
private final IBatteryStats mBatteryStats;
- public WifiStateMachine(Context context) {
+ public WifiStateMachine(Context context, String wlanInterface) {
super(TAG);
mContext = context;
+ mInterfaceName = wlanInterface;
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
@@ -449,7 +450,6 @@ public class WifiStateMachine extends HierarchicalStateMachine {
mWifiMonitor = new WifiMonitor(this);
mDhcpInfoInternal = new DhcpInfoInternal();
mWifiInfo = new WifiInfo();
- mInterfaceName = SystemProperties.get("wifi.interface", "tiwlan0");
mSupplicantStateTracker = new SupplicantStateTracker(context, this, getHandler());
mWpsStateMachine = new WpsStateMachine(context, this, getHandler());
mLinkProperties = new LinkProperties();
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 2aff7ecd94da..07900ae4ca43 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -45,7 +45,6 @@ public class WifiStateTracker implements NetworkStateTracker {
private AtomicBoolean mTeardownRequested = new AtomicBoolean(false);
private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false);
- private AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
private LinkProperties mLinkProperties;
@@ -136,40 +135,6 @@ public class WifiStateTracker implements NetworkStateTracker {
}
/**
- * Tells the underlying networking system that the caller wants to
- * begin using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- * @param feature the name of the feature to be used
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- * TODO: needs to go away
- */
- public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- return -1;
- }
-
- /**
- * Tells the underlying networking system that the caller is finished
- * using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- * @param feature the name of the feature that is no longer needed.
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- * TODO: needs to go away
- */
- public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- return -1;
- }
-
- /**
* @param enabled
*/
public void setDataEnable(boolean enabled) {
@@ -215,13 +180,6 @@ public class WifiStateTracker implements NetworkStateTracker {
}
/**
- * Fetch default gateway address for the network
- */
- public int getDefaultGatewayAddr() {
- return mDefaultGatewayAddr.get();
- }
-
- /**
* Check if default route is set
*/
public boolean isDefaultRouteSet() {