diff options
| -rw-r--r-- | core/java/android/widget/ListPopupWindow.java | 2 | ||||
| -rw-r--r-- | core/java/android/widget/PopupWindow.java | 8 | ||||
| -rw-r--r-- | core/java/android/widget/Spinner.java | 21 | ||||
| -rw-r--r-- | core/res/res/values/styles.xml | 4 | ||||
| -rw-r--r-- | media/java/android/media/AudioManager.java | 144 | ||||
| -rw-r--r-- | media/java/android/media/AudioService.java | 9 | ||||
| -rw-r--r-- | media/java/android/media/IRemoteControlClient.aidl | 60 | ||||
| -rw-r--r-- | services/sensorservice/tests/sensorservicetest.cpp | 16 |
8 files changed, 230 insertions, 34 deletions
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index 307959b0cac5..a2910afc86eb 100644 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -449,6 +449,8 @@ public class ListPopupWindow { if (popupBackground != null) { popupBackground.getPadding(mTempRect); mDropDownWidth = mTempRect.left + mTempRect.right + width; + } else { + setWidth(width); } } diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index 36927ca434ef..4d45c2fee094 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -1065,9 +1065,10 @@ public class PopupWindow { private boolean findDropDownPosition(View anchor, WindowManager.LayoutParams p, int xoff, int yoff) { + final int anchorHeight = anchor.getHeight(); anchor.getLocationInWindow(mDrawingLocation); p.x = mDrawingLocation[0] + xoff; - p.y = mDrawingLocation[1] + anchor.getHeight() + yoff; + p.y = mDrawingLocation[1] + anchorHeight + yoff; boolean onTop = false; @@ -1076,9 +1077,12 @@ public class PopupWindow { anchor.getLocationOnScreen(mScreenLocation); final Rect displayFrame = new Rect(); anchor.getWindowVisibleDisplayFrame(displayFrame); + + int screenY = mScreenLocation[1] + anchorHeight + yoff; final View root = anchor.getRootView(); - if (p.y + mPopupHeight > displayFrame.bottom || p.x + mPopupWidth - root.getWidth() > 0) { + if (screenY + 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 diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java index 2fba18b12ec8..27d44bf9efe8 100644 --- a/core/java/android/widget/Spinner.java +++ b/core/java/android/widget/Spinner.java @@ -714,14 +714,27 @@ public class Spinner extends AbsSpinner implements OnClickListener { @Override public void show() { + final int spinnerPaddingLeft = Spinner.this.getPaddingLeft(); if (mDropDownWidth == WRAP_CONTENT) { - setWidth(Math.max(measureContentWidth((SpinnerAdapter) mAdapter, getBackground()), - Spinner.this.getWidth())); + final int spinnerWidth = Spinner.this.getWidth(); + final int spinnerPaddingRight = Spinner.this.getPaddingRight(); + setContentWidth(Math.max( + measureContentWidth((SpinnerAdapter) mAdapter, getBackground()), + spinnerWidth - spinnerPaddingLeft - spinnerPaddingRight)); } else if (mDropDownWidth == MATCH_PARENT) { - setWidth(Spinner.this.getWidth()); + final int spinnerWidth = Spinner.this.getWidth(); + final int spinnerPaddingRight = Spinner.this.getPaddingRight(); + setContentWidth(spinnerWidth - spinnerPaddingLeft - spinnerPaddingRight); } else { - setWidth(mDropDownWidth); + setContentWidth(mDropDownWidth); } + final Drawable background = getBackground(); + int bgOffset = 0; + if (background != null) { + background.getPadding(mTempRect); + bgOffset = -mTempRect.left; + } + setHorizontalOffset(bgOffset + spinnerPaddingLeft); setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED); super.show(); getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index d20d16c764bf..0f7bb171c435 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -1772,6 +1772,8 @@ please see styles_device_defaults.xml. <style name="Widget.Holo.DropDownItem" parent="Widget.DropDownItem"> <item name="android:textAppearance">@style/TextAppearance.Holo.Widget.DropDownItem</item> + <item name="android:paddingLeft">8dp</item> + <item name="android:paddingRight">8dp</item> </style> <style name="Widget.Holo.DropDownItem.Spinner"> @@ -1779,6 +1781,8 @@ please see styles_device_defaults.xml. <style name="Widget.Holo.TextView.SpinnerItem" parent="Widget.TextView.SpinnerItem"> <item name="android:textAppearance">@style/TextAppearance.Holo.Widget.TextView.SpinnerItem</item> + <item name="android:paddingLeft">8dp</item> + <item name="android:paddingRight">8dp</item> </style> <style name="Widget.Holo.KeyboardView" parent="Widget.KeyboardView"> diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 56a993398874..7a92b35c4f62 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -1743,7 +1743,13 @@ public class AudioManager { /** * @hide - * @param eventReceiver + * Unregisters the remote control client that was providing information to display on the + * remotes. + * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver} + * that receives the media button intent, and associated with the remote control + * client. + * @see #registerRemoteControlClient(ComponentName) + */ public void unregisterRemoteControlClient(ComponentName eventReceiver) { if (eventReceiver == null) { @@ -1783,27 +1789,152 @@ public class AudioManager { * Definitions of constants to be used in {@link android.media.IRemoteControlClient}. */ public final class RemoteControlParameters { + /** + * Playback state of an IRemoteControlClient which is stopped. + * + * @see android.media.IRemoteControlClient#getPlaybackState() + */ public final static int PLAYSTATE_STOPPED = 1; + /** + * Playback state of an IRemoteControlClient which is paused. + * + * @see android.media.IRemoteControlClient#getPlaybackState() + */ public final static int PLAYSTATE_PAUSED = 2; + /** + * Playback state of an IRemoteControlClient which is playing media. + * + * @see android.media.IRemoteControlClient#getPlaybackState() + */ public final static int PLAYSTATE_PLAYING = 3; + /** + * Playback state of an IRemoteControlClient which is fast forwarding in the media + * it is currently playing. + * + * @see android.media.IRemoteControlClient#getPlaybackState() + */ public final static int PLAYSTATE_FAST_FORWARDING = 4; + /** + * Playback state of an IRemoteControlClient which is fast rewinding in the media + * it is currently playing. + * + * @see android.media.IRemoteControlClient#getPlaybackState() + */ public final static int PLAYSTATE_REWINDING = 5; + /** + * Playback state of an IRemoteControlClient which is skipping to the next + * logical chapter (such as a song in a playlist) in the media it is currently playing. + * + * @see android.media.IRemoteControlClient#getPlaybackState() + */ public final static int PLAYSTATE_SKIPPING_FORWARDS = 6; + /** + * Playback state of an IRemoteControlClient which is skipping back to the previous + * logical chapter (such as a song in a playlist) in the media it is currently playing. + * + * @see android.media.IRemoteControlClient#getPlaybackState() + */ public final static int PLAYSTATE_SKIPPING_BACKWARDS = 7; + /** + * Playback state of an IRemoteControlClient which is buffering data to play before it can + * start or resume playback. + * + * @see android.media.IRemoteControlClient#getPlaybackState() + */ public final static int PLAYSTATE_BUFFERING = 8; + /** + * Playback state of an IRemoteControlClient which cannot perform any playback related + * operation because of an internal error. Examples of such situations are no network + * connectivity when attempting to stream data from a server, or expired user credentials + * when trying to play subscription-based content. + * + * @see android.media.IRemoteControlClient#getPlaybackState() + */ + public final static int PLAYSTATE_ERROR = 9; + /** + * Flag indicating an IRemoteControlClient makes use of the "previous" media key. + * + * @see android.media.IRemoteControlClient#getTransportControlFlags() + * @see android.view.KeyEvent#KEYCODE_MEDIA_PREVIOUS + */ public final static int FLAG_KEY_MEDIA_PREVIOUS = 1 << 0; + /** + * Flag indicating an IRemoteControlClient makes use of the "rewing" media key. + * + * @see android.media.IRemoteControlClient#getTransportControlFlags() + * @see android.view.KeyEvent#KEYCODE_MEDIA_REWIND + */ public final static int FLAG_KEY_MEDIA_REWIND = 1 << 1; + /** + * Flag indicating an IRemoteControlClient makes use of the "play" media key. + * + * @see android.media.IRemoteControlClient#getTransportControlFlags() + * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY + */ public final static int FLAG_KEY_MEDIA_PLAY = 1 << 2; + /** + * Flag indicating an IRemoteControlClient makes use of the "play/pause" media key. + * + * @see android.media.IRemoteControlClient#getTransportControlFlags() + * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE + */ public final static int FLAG_KEY_MEDIA_PLAY_PAUSE = 1 << 3; + /** + * Flag indicating an IRemoteControlClient makes use of the "pause" media key. + * + * @see android.media.IRemoteControlClient#getTransportControlFlags() + * @see android.view.KeyEvent#KEYCODE_MEDIA_PAUSE + */ public final static int FLAG_KEY_MEDIA_PAUSE = 1 << 4; + /** + * Flag indicating an IRemoteControlClient makes use of the "stop" media key. + * + * @see android.media.IRemoteControlClient#getTransportControlFlags() + * @see android.view.KeyEvent#KEYCODE_MEDIA_STOP + */ public final static int FLAG_KEY_MEDIA_STOP = 1 << 5; + /** + * Flag indicating an IRemoteControlClient makes use of the "fast forward" media key. + * + * @see android.media.IRemoteControlClient#getTransportControlFlags() + * @see android.view.KeyEvent#KEYCODE_MEDIA_FAST_FORWARD + */ public final static int FLAG_KEY_MEDIA_FAST_FORWARD = 1 << 6; + /** + * Flag indicating an IRemoteControlClient makes use of the "next" media key. + * + * @see android.media.IRemoteControlClient#getTransportControlFlags() + * @see android.view.KeyEvent#KEYCODE_MEDIA_NEXT + */ public final static int FLAG_KEY_MEDIA_NEXT = 1 << 7; + /** + * Flag used to signal that the metadata exposed by the IRemoteControlClient has changed. + * + * @see #notifyRemoteControlInformationChanged(ComponentName, int) + */ public final static int FLAG_INFORMATION_CHANGED_METADATA = 1 << 0; + /** + * Flag used to signal that the transport control buttons supported by the + * IRemoteControlClient have changed. + * This can for instance happen when playback is at the end of a playlist, and the "next" + * operation is not supported anymore. + * + * @see #notifyRemoteControlInformationChanged(ComponentName, int) + */ public final static int FLAG_INFORMATION_CHANGED_KEY_MEDIA = 1 << 1; + /** + * Flag used to signal that the playback state of the IRemoteControlClient has changed. + * + * @see #notifyRemoteControlInformationChanged(ComponentName, int) + */ public final static int FLAG_INFORMATION_CHANGED_PLAYSTATE = 1 << 2; + /** + * Flag used to signal that the album art for the IRemoteControlClient has changed. + * + * @see #notifyRemoteControlInformationChanged(ComponentName, int) + */ public final static int FLAG_INFORMATION_CHANGED_ALBUM_ART = 1 << 3; } @@ -1830,6 +1961,17 @@ public class AudioManager { /** * @hide + * The media button event receiver associated with the IRemoteControlClient. + * The {@link android.content.ComponentName} value of the event receiver can be retrieved with + * {@link android.content.ComponentName#unflattenFromString(String)} + * + * @see #REMOTE_CONTROL_CLIENT_CHANGED_ACTION + */ + public static final String EXTRA_REMOTE_CONTROL_EVENT_RECEIVER = + "android.media.EXTRA_REMOTE_CONTROL_EVENT_RECEIVER"; + + /** + * @hide * The flags describing what information has changed in the current remote control client. * * @see #REMOTE_CONTROL_CLIENT_CHANGED_ACTION diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 59512297bbca..714810d0f29e 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -2167,8 +2167,10 @@ public class AudioService extends IAudioService.Stub { case MSG_RCDISPLAY_UPDATE: synchronized(mCurrentRcLock) { + // msg.obj is guaranteed to be non null + RemoteControlStackEntry rcse = (RemoteControlStackEntry)msg.obj; if ((mCurrentRcClient == null) || - (!mCurrentRcClient.equals((IRemoteControlClient)msg.obj))) { + (!mCurrentRcClient.equals(rcse.mRcClient))) { // the remote control display owner has changed between the // the message to update the display was sent, and the time it // gets to be processed (now) @@ -2183,6 +2185,9 @@ public class AudioService extends IAudioService.Stub { rcClientIntent.putExtra( AudioManager.EXTRA_REMOTE_CONTROL_CLIENT_INFO_CHANGED, msg.arg1); + rcClientIntent.putExtra( + AudioManager.EXTRA_REMOTE_CONTROL_EVENT_RECEIVER, + rcse.mReceiverComponent.flattenToString()); rcClientIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mContext.sendBroadcast(rcClientIntent); } @@ -3131,7 +3136,7 @@ public class AudioService extends IAudioService.Stub { mCurrentRcClient = rcse.mRcClient; } mAudioHandler.sendMessage( mAudioHandler.obtainMessage(MSG_RCDISPLAY_UPDATE, - infoFlagsAboutToBeUsed /* arg1 */, 0, rcse.mRcClient /* obj */) ); + infoFlagsAboutToBeUsed /* arg1 */, 0, rcse /* obj, != null */) ); } /** diff --git a/media/java/android/media/IRemoteControlClient.aidl b/media/java/android/media/IRemoteControlClient.aidl index a49371c08668..76d178c16bcd 100644 --- a/media/java/android/media/IRemoteControlClient.aidl +++ b/media/java/android/media/IRemoteControlClient.aidl @@ -19,7 +19,12 @@ package android.media; import android.graphics.Bitmap; /** - * {@hide} + * @hide + * Interface for an object that exposes information meant to be consumed by remote controls + * capable of displaying metadata, album art and media transport control buttons. + * Such a remote control client object is associated with a media button event receiver + * when registered through + * {@link AudioManager#registerRemoteControlClient(ComponentName, IRemoteControlClient)}. */ interface IRemoteControlClient { @@ -41,36 +46,49 @@ interface IRemoteControlClient * {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE}, * {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER}, * {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}. - * @return null if the given field is not supported, or the String matching the metadata field. + * @return null if the requested field is not supported, or the String matching the + * metadata field. */ String getMetadataString(int field); /** - * Returns the current playback state. + * Called by a remote control to retrieve the current playback state. * @return one of the following values: - * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_STOPPED}, - * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_PAUSED}, - * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_PLAYING}, - * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_FAST_FORWARDING}, - * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_REWINDING}, - * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_SKIPPING_FORWARDS}, - * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_SKIPPING_BACKWARDS}, - * {@link android.media.AudioManager.RemoteControl#PLAYSTATE_BUFFERING}. + * {@link android.media.AudioManager.RemoteControlParameters#PLAYSTATE_STOPPED}, + * {@link android.media.AudioManager.RemoteControlParameters#PLAYSTATE_PAUSED}, + * {@link android.media.AudioManager.RemoteControlParameters#PLAYSTATE_PLAYING}, + * {@link android.media.AudioManager.RemoteControlParameters#PLAYSTATE_FAST_FORWARDING}, + * {@link android.media.AudioManager.RemoteControlParameters#PLAYSTATE_REWINDING}, + * {@link android.media.AudioManager.RemoteControlParameters#PLAYSTATE_SKIPPING_FORWARDS}, + * {@link android.media.AudioManager.RemoteControlParameters#PLAYSTATE_SKIPPING_BACKWARDS}, + * {@link android.media.AudioManager.RemoteControlParameters#PLAYSTATE_BUFFERING}, + * {@link android.media.AudioManager.RemoteControlParameters#PLAYSTATE_ERROR}. */ int getPlaybackState(); /** - * Returns the flags for the media transport control buttons this client supports. - * @see {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_PREVIOUS}, - * {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_REWIND}, - * {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_PLAY}, - * {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_PLAY_PAUSE}, - * {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_PAUSE}, - * {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_STOP}, - * {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_FAST_FORWARD}, - * {@link android.media.AudioManager.RemoteControl#FLAG_KEY_MEDIA_NEXT} + * Called by a remote control to retrieve the flags for the media transport control buttons + * that this client supports. + * @see {@link android.media.AudioManager.RemoteControlParameters#FLAG_KEY_MEDIA_PREVIOUS}, + * {@link android.media.AudioManager.RemoteControlParameters#FLAG_KEY_MEDIA_REWIND}, + * {@link android.media.AudioManager.RemoteControlParameters#FLAG_KEY_MEDIA_PLAY}, + * {@link android.media.AudioManager.RemoteControlParameters#FLAG_KEY_MEDIA_PLAY_PAUSE}, + * {@link android.media.AudioManager.RemoteControlParameters#FLAG_KEY_MEDIA_PAUSE}, + * {@link android.media.AudioManager.RemoteControlParameters#FLAG_KEY_MEDIA_STOP}, + * {@link android.media.AudioManager.RemoteControlParameters#FLAG_KEY_MEDIA_FAST_FORWARD}, + * {@link android.media.AudioManager.RemoteControlParameters#FLAG_KEY_MEDIA_NEXT} */ int getTransportControlFlags(); - Bitmap getAlbumArt(int width, int height); + /** + * Called by a remote control to retrieve the album art picture at the requested size. + * Note that returning a bitmap smaller than the maximum requested dimension is accepted + * and it will be scaled as needed, but exceeding the maximum dimensions may produce + * unspecified results, such as the image being cropped or simply not being displayed. + * @param maxWidth the maximum width of the requested bitmap expressed in pixels. + * @param maxHeight the maximum height of the requested bitmap expressed in pixels. + * @return the bitmap for the album art, or null if there isn't any. + * @see android.graphics.Bitmap + */ + Bitmap getAlbumArt(int maxWidth, int maxHeight); } diff --git a/services/sensorservice/tests/sensorservicetest.cpp b/services/sensorservice/tests/sensorservicetest.cpp index aea106224bda..54bce091f66f 100644 --- a/services/sensorservice/tests/sensorservicetest.cpp +++ b/services/sensorservice/tests/sensorservicetest.cpp @@ -22,6 +22,9 @@ using namespace android; +static nsecs_t sStartTime = 0; + + int receiver(int fd, int events, void* data) { sp<SensorEventQueue> q((SensorEventQueue*)data); @@ -32,7 +35,7 @@ int receiver(int fd, int events, void* data) while ((n = q->read(buffer, 8)) > 0) { for (int i=0 ; i<n ; i++) { - if (buffer[i].type == Sensor::TYPE_GYROSCOPE) { + if (buffer[i].type == Sensor::TYPE_ACCELEROMETER) { printf("time=%lld, value=<%5.1f,%5.1f,%5.1f>\n", buffer[i].timestamp, buffer[i].acceleration.x, @@ -43,9 +46,11 @@ int receiver(int fd, int events, void* data) if (oldTimeStamp) { float t = float(buffer[i].timestamp - oldTimeStamp) / s2ns(1); printf("%f ms (%f Hz)\n", t*1000, 1.0/t); + } else { + float t = float(buffer[i].timestamp - sStartTime) / s2ns(1); + printf("first event: %f ms\n", t*1000); } oldTimeStamp = buffer[i].timestamp; - } } if (n<0 && n != -EAGAIN) { @@ -66,12 +71,15 @@ int main(int argc, char** argv) sp<SensorEventQueue> q = mgr.createEventQueue(); printf("queue=%p\n", q.get()); - Sensor const* accelerometer = mgr.getDefaultSensor(Sensor::TYPE_GYROSCOPE); + Sensor const* accelerometer = mgr.getDefaultSensor(Sensor::TYPE_ACCELEROMETER); printf("accelerometer=%p (%s)\n", accelerometer, accelerometer->getName().string()); + + sStartTime = systemTime(); + q->enableSensor(accelerometer); - q->setEventRate(accelerometer, ms2ns(10)); + q->setEventRate(accelerometer, ms2ns(200)); sp<Looper> loop = new Looper(false); loop->addFd(q->getFd(), 0, ALOOPER_EVENT_INPUT, receiver, q.get()); |