summaryrefslogtreecommitdiffstats
path: root/src/com/android/bluetooth/a2dp/Avrcp.java
diff options
context:
space:
mode:
authorJohn Du <johnldu@google.com>2013-06-27 18:39:42 -0700
committerJohn Du <johnldu@google.com>2013-08-15 18:52:29 +0000
commitace834feb02adabd61f628c4471147aea02d939c (patch)
treeebd083e1abb02412b582db000c53e3ad91f6b920 /src/com/android/bluetooth/a2dp/Avrcp.java
parent8c85057a003441674807e2991092735011c72b26 (diff)
downloadandroid_packages_apps_Bluetooth-ace834feb02adabd61f628c4471147aea02d939c.tar.gz
android_packages_apps_Bluetooth-ace834feb02adabd61f628c4471147aea02d939c.tar.bz2
android_packages_apps_Bluetooth-ace834feb02adabd61f628c4471147aea02d939c.zip
Add support for ff/rew
Change-Id: I7ec60d94313b9ba5e4e8e62c82f19ae332b6fdd3 (cherry picked from commit 55123eff985f4d15ec198569a5db895ea086447a)
Diffstat (limited to 'src/com/android/bluetooth/a2dp/Avrcp.java')
-rwxr-xr-xsrc/com/android/bluetooth/a2dp/Avrcp.java93
1 files changed, 93 insertions, 0 deletions
diff --git a/src/com/android/bluetooth/a2dp/Avrcp.java b/src/com/android/bluetooth/a2dp/Avrcp.java
index ac7a323e0..73b6df698 100755
--- a/src/com/android/bluetooth/a2dp/Avrcp.java
+++ b/src/com/android/bluetooth/a2dp/Avrcp.java
@@ -16,6 +16,9 @@
package com.android.bluetooth.a2dp;
+import java.util.Timer;
+import java.util.TimerTask;
+
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
@@ -73,17 +76,33 @@ final class Avrcp {
private int mPlayPosChangedNT;
private long mNextPosMs;
private long mPrevPosMs;
+ private long mSkipStartTime;
+ private Timer mTimer;
+
+ /* AVRC IDs from avrc_defs.h */
+ private static final int AVRC_ID_REWIND = 0x48;
+ private static final int AVRC_ID_FAST_FOR = 0x49;
private static final int MESSAGE_GET_PLAY_STATUS = 1;
private static final int MESSAGE_GET_ELEM_ATTRS = 2;
private static final int MESSAGE_REGISTER_NOTIFICATION = 3;
private static final int MESSAGE_PLAY_INTERVAL_TIMEOUT = 4;
+ private static final int MESSAGE_FAST_FORWARD = 5;
+ private static final int MESSAGE_REWIND = 6;
+ private static final int MESSAGE_FF_REW_TIMEOUT = 7;
private static final int MSG_UPDATE_STATE = 100;
private static final int MSG_SET_METADATA = 101;
private static final int MSG_SET_TRANSPORT_CONTROLS = 102;
private static final int MSG_SET_ARTWORK = 103;
private static final int MSG_SET_GENERATION_ID = 104;
+ private static final int BUTTON_TIMEOUT_TIME = 2000;
+ private static final int BASE_SKIP_AMOUNT = 2000;
+ private static final int KEY_STATE_PRESS = 1;
+ private static final int KEY_STATE_RELEASE = 0;
+ private static final int SKIP_PERIOD = 400;
+ private static final int SKIP_DOUBLE_INTERVAL = 3000;
+
static {
classInitNative();
}
@@ -99,6 +118,7 @@ final class Avrcp {
mSongLengthMs = 0L;
mPlaybackIntervalMs = 0L;
mPlayPosChangedNT = NOTIFICATION_TYPE_CHANGED;
+ mTimer = null;
mContext = context;
@@ -262,6 +282,45 @@ final class Avrcp {
registerNotificationRspPlayPosNative(mPlayPosChangedNT, (int)getPlayPosition());
break;
+ case MESSAGE_FAST_FORWARD:
+ case MESSAGE_REWIND:
+ final int skipAmount;
+ if (msg.what == MESSAGE_FAST_FORWARD) {
+ if (DEBUG) Log.v(TAG, "MESSAGE_FAST_FORWARD");
+ skipAmount = BASE_SKIP_AMOUNT;
+ } else {
+ if (DEBUG) Log.v(TAG, "MESSAGE_REWIND");
+ skipAmount = -BASE_SKIP_AMOUNT;
+ }
+
+ removeMessages(MESSAGE_FF_REW_TIMEOUT);
+ if (msg.arg1 == KEY_STATE_PRESS) {
+ if (mTimer == null) {
+ /** Begin fast forwarding */
+ mSkipStartTime = SystemClock.elapsedRealtime();
+ TimerTask task = new TimerTask() {
+ @Override
+ public void run() {
+ changePositionBy(skipAmount*getSkipMultiplier());
+ }
+ };
+ mTimer = new Timer();
+ mTimer.schedule(task, 0, SKIP_PERIOD);
+ }
+ sendMessageDelayed(obtainMessage(MESSAGE_FF_REW_TIMEOUT), BUTTON_TIMEOUT_TIME);
+ } else if (msg.arg1 == KEY_STATE_RELEASE && mTimer != null) {
+ mTimer.cancel();
+ mTimer = null;
+ }
+ break;
+
+ case MESSAGE_FF_REW_TIMEOUT:
+ if (DEBUG) Log.v(TAG, "MESSAGE_FF_REW_TIMEOUT: FF/REW response timed out");
+ if (mTimer != null) {
+ mTimer.cancel();
+ mTimer = null;
+ }
+ break;
}
}
}
@@ -422,6 +481,40 @@ final class Avrcp {
}
}
+ private void handlePassthroughCmd(int id, int keyState) {
+ switch (id) {
+ case AVRC_ID_REWIND:
+ rewind(keyState);
+ break;
+ case AVRC_ID_FAST_FOR:
+ fastForward(keyState);
+ break;
+ }
+ }
+
+ private void fastForward(int keyState) {
+ Message msg = mHandler.obtainMessage(MESSAGE_FAST_FORWARD, keyState, 0);
+ mHandler.sendMessage(msg);
+ }
+
+ private void rewind(int keyState) {
+ Message msg = mHandler.obtainMessage(MESSAGE_REWIND, keyState, 0);
+ mHandler.sendMessage(msg);
+ }
+
+ private void changePositionBy(long amount) {
+ long currentPosMs = getPlayPosition();
+ if (currentPosMs == -1L) return;
+ long newPosMs = Math.max(0L, currentPosMs + amount);
+ mAudioManager.setRemoteControlClientPlaybackPosition(mClientGeneration,
+ newPosMs);
+ }
+
+ private int getSkipMultiplier() {
+ long currentTime = SystemClock.elapsedRealtime();
+ return (int) Math.pow(2, (currentTime - mSkipStartTime)/SKIP_DOUBLE_INTERVAL);
+ }
+
private void sendTrackChangedRsp() {
byte[] track = new byte[TRACK_ID_SIZE];
/* track is stored in big endian format */