summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2013-03-05 18:56:27 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-03-05 18:56:28 +0000
commit1f9744ddc418ae0d13dd2e71fe8442afe2222611 (patch)
tree3b89f24cd5c72ff4a0175460c3a8a04df0a38af8
parent836c5dac9017af8cd41f232c50985ff2b3a21810 (diff)
parent1a158c7f354d1e1b031fba88928dbaa022e0d0df (diff)
downloadandroid_packages_apps_Nfc-1f9744ddc418ae0d13dd2e71fe8442afe2222611.tar.gz
android_packages_apps_Nfc-1f9744ddc418ae0d13dd2e71fe8442afe2222611.tar.bz2
android_packages_apps_Nfc-1f9744ddc418ae0d13dd2e71fe8442afe2222611.zip
Merge "Make Beam more forgiving." into jb-mr2-dev
-rw-r--r--res/layout/screenshot.xml33
-rwxr-xr-xres/values/strings.xml1
-rw-r--r--src/com/android/nfc/P2pEventManager.java13
-rwxr-xr-xsrc/com/android/nfc/P2pLinkManager.java56
-rw-r--r--src/com/android/nfc/SendUi.java59
5 files changed, 153 insertions, 9 deletions
diff --git a/res/layout/screenshot.xml b/res/layout/screenshot.xml
index 24a3a71d..2523e500 100644
--- a/res/layout/screenshot.xml
+++ b/res/layout/screenshot.xml
@@ -49,5 +49,36 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
- />
+ />
+ <ImageView android:id="@+id/blacklayer"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#ff000000"
+ android:visibility="gone"
+ />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ >
+ <View
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="0.25"
+ />
+ <TextView android:id="@+id/retrytext"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0.5"
+ android:gravity="center"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:background="@null"
+ android:textColor="@android:color/holo_blue_light"
+ />
+ <View
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="0.25"
+ />
+ </LinearLayout>
</FrameLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a4bda3b9..b9449376 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -27,6 +27,7 @@
<string name="cancel">Cancel</string>
<string name="beam_touch_to_view">Touch to view</string>
<string name="beam_handover_not_supported">The receiver\'s device doesn\'t support large file transfer via beam.</string>
+ <string name="beam_try_again">Bring devices together again</string>
<string name="connecting_headset">Connecting</string>
<string name="connected_headset">Connected</string>
diff --git a/src/com/android/nfc/P2pEventManager.java b/src/com/android/nfc/P2pEventManager.java
index 68f479b8..65e428ea 100644
--- a/src/com/android/nfc/P2pEventManager.java
+++ b/src/com/android/nfc/P2pEventManager.java
@@ -144,4 +144,17 @@ public class P2pEventManager implements P2pEventListener, SendUi.Callback {
mSending = true;
}
+
+ @Override
+ public void onP2pSendDebounce() {
+ mNfcService.playSound(NfcService.SOUND_ERROR);
+ mSendUi.showSendHint();
+ }
+
+ @Override
+ public void onP2pResumeSend() {
+ mVibrator.vibrate(VIBRATION_PATTERN, -1);
+ mNfcService.playSound(NfcService.SOUND_START);
+ mSendUi.showStartSend();
+ }
}
diff --git a/src/com/android/nfc/P2pLinkManager.java b/src/com/android/nfc/P2pLinkManager.java
index 0b3fc736..b25b41d2 100755
--- a/src/com/android/nfc/P2pLinkManager.java
+++ b/src/com/android/nfc/P2pLinkManager.java
@@ -76,6 +76,20 @@ interface P2pEventListener {
public void onP2pSendComplete();
/**
+ *
+ * Called to indicate the link has broken while we were trying to send
+ * a message. We'll start a debounce timer for the user to get the devices
+ * back together. UI may show a hint to achieve that
+ */
+ public void onP2pSendDebounce();
+
+ /**
+ * Called to indicate a link has come back up after being temporarily
+ * broken, and sending is resuming
+ */
+ public void onP2pResumeSend();
+
+ /**
* Called to indicate the remote device does not support connection handover
*/
public void onP2pHandoverNotSupported();
@@ -124,8 +138,10 @@ public class P2pLinkManager implements Handler.Callback, P2pEventListener.Callba
static final int NDEFPUSH_SAP = 0x10;
static final int HANDOVER_SAP = 0x14;
- static final int LINK_DEBOUNCE_MS = 750;
-
+ static final int LINK_NOTHING_TO_SEND_DEBOUNCE_MS = 750;
+ static final int LINK_SEND_PENDING_DEBOUNCE_MS = 3000;
+ static final int LINK_SEND_CONFIRMED_DEBOUNCE_MS = 5000;
+ static final int LINK_SEND_COMPLETE_DEBOUNCE_MS = 250;
static final int MSG_DEBOUNCE_TIMEOUT = 1;
static final int MSG_RECEIVE_COMPLETE = 2;
static final int MSG_RECEIVE_HANDOVER = 3;
@@ -137,12 +153,13 @@ public class P2pLinkManager implements Handler.Callback, P2pEventListener.Callba
// values for mLinkState
static final int LINK_STATE_DOWN = 1;
static final int LINK_STATE_UP = 2;
- static final int LINK_STATE_DEBOUNCE =3;
+ static final int LINK_STATE_DEBOUNCE = 3;
// values for mSendState
static final int SEND_STATE_NOTHING_TO_SEND = 1;
static final int SEND_STATE_NEED_CONFIRMATION = 2;
static final int SEND_STATE_SENDING = 3;
+ static final int SEND_STATE_SEND_COMPLETE = 4;
// return values for doSnepProtocol
static final int SNEP_SUCCESS = 0;
@@ -263,7 +280,6 @@ public class P2pLinkManager implements Handler.Callback, P2pEventListener.Callba
if (mEchoServer != null) {
mEchoServer.onLlcpActivated();
}
-
switch (mLinkState) {
case LINK_STATE_DOWN:
mLinkState = LINK_STATE_UP;
@@ -442,7 +458,26 @@ public class P2pLinkManager implements Handler.Callback, P2pEventListener.Callba
case LINK_STATE_UP:
// Debounce
mLinkState = LINK_STATE_DEBOUNCE;
- mHandler.sendEmptyMessageDelayed(MSG_DEBOUNCE_TIMEOUT, LINK_DEBOUNCE_MS);
+ int debounceTimeout = 0;
+ switch (mSendState) {
+ case SEND_STATE_NOTHING_TO_SEND:
+ debounceTimeout = 0;
+ break;
+ case SEND_STATE_NEED_CONFIRMATION:
+ debounceTimeout = LINK_SEND_PENDING_DEBOUNCE_MS;
+ break;
+ case SEND_STATE_SENDING:
+ debounceTimeout = LINK_SEND_CONFIRMED_DEBOUNCE_MS;
+ break;
+ case SEND_STATE_SEND_COMPLETE:
+ debounceTimeout = LINK_SEND_COMPLETE_DEBOUNCE_MS;
+ break;
+ }
+ mHandler.sendEmptyMessageDelayed(MSG_DEBOUNCE_TIMEOUT, debounceTimeout);
+ if (mSendState == SEND_STATE_SENDING) {
+ Log.e(TAG, "onP2pSendDebounce()");
+ mEventListener.onP2pSendDebounce();
+ }
cancelSendNdefMessage();
disconnectLlcpServices();
break;
@@ -502,6 +537,7 @@ public class P2pLinkManager implements Handler.Callback, P2pEventListener.Callba
mLlcpServicesConnected = true;
if (mSendState == SEND_STATE_SENDING) {
// Send was previously confirmed, we probably cycled through a debounce
+ mEventListener.onP2pResumeSend();
sendNdefMessage();
} else {
// User still needs to confirm, or we may have received something already.
@@ -840,7 +876,8 @@ public class P2pLinkManager implements Handler.Callback, P2pEventListener.Callba
if (mLinkState == LINK_STATE_DOWN || mSendState != SEND_STATE_SENDING) {
break;
}
- mSendState = SEND_STATE_NOTHING_TO_SEND;
+ mSendState = SEND_STATE_SEND_COMPLETE;
+ mHandler.removeMessages(MSG_DEBOUNCE_TIMEOUT);
if (DBG) Log.d(TAG, "onP2pSendComplete()");
mEventListener.onP2pSendComplete();
if (mCallbackNdef != null) {
@@ -924,6 +961,13 @@ public class P2pLinkManager implements Handler.Callback, P2pEventListener.Callba
mSendState = SEND_STATE_SENDING;
if (mLinkState == LINK_STATE_UP && mLlcpServicesConnected) {
sendNdefMessage();
+ } else if (mLinkState == LINK_STATE_DEBOUNCE) {
+ // Restart debounce timeout
+ mHandler.removeMessages(MSG_DEBOUNCE_TIMEOUT);
+ mHandler.sendEmptyMessageDelayed(MSG_DEBOUNCE_TIMEOUT,
+ LINK_SEND_CONFIRMED_DEBOUNCE_MS);
+ // Tell user to tap devices again
+ mEventListener.onP2pSendDebounce();
}
}
}
diff --git a/src/com/android/nfc/SendUi.java b/src/com/android/nfc/SendUi.java
index 7839ed62..d153a626 100644
--- a/src/com/android/nfc/SendUi.java
+++ b/src/com/android/nfc/SendUi.java
@@ -43,6 +43,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;
import android.widget.TextView;
@@ -90,6 +91,9 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener,
static final int SLIDE_OUT_DURATION_MS = 300;
+ static final float[] BLACK_LAYER_ALPHA_DOWN_RANGE = {0.9f, 0.0f};
+ static final float[] BLACK_LAYER_ALPHA_UP_RANGE = {0.0f, 0.9f};
+
static final float[] TEXT_HINT_ALPHA_RANGE = {0.0f, 1.0f};
static final int TEXT_HINT_ALPHA_DURATION_MS = 500;
static final int TEXT_HINT_ALPHA_START_DELAY_MS = 300;
@@ -108,8 +112,10 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener,
final StatusBarManager mStatusBarManager;
final View mScreenshotLayout;
final ImageView mScreenshotView;
+ final ImageView mBlackLayer;
final TextureView mTextureView;
final TextView mTextHint;
+ final TextView mTextRetry;
final Callback mCallback;
// The mFrameCounter animation is purely used to count down a certain
@@ -129,6 +135,8 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener,
final ObjectAnimator mFadeInAnimator;
final ObjectAnimator mHintAnimator;
final ObjectAnimator mScaleUpAnimator;
+ final ObjectAnimator mAlphaDownAnimator;
+ final ObjectAnimator mAlphaUpAnimator;
final AnimatorSet mSuccessAnimatorSet;
// Besides animating the screenshot, the Beam UI also renders
@@ -177,7 +185,8 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener,
mScreenshotLayout.setFocusable(true);
mTextHint = (TextView) mScreenshotLayout.findViewById(R.id.calltoaction);
-
+ mTextRetry = (TextView) mScreenshotLayout.findViewById(R.id.retrytext);
+ mBlackLayer = (ImageView) mScreenshotLayout.findViewById(R.id.blacklayer);
mTextureView = (TextureView) mScreenshotLayout.findViewById(R.id.fireflies);
mTextureView.setSurfaceTextureListener(this);
@@ -245,6 +254,16 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener,
mHintAnimator.setDuration(TEXT_HINT_ALPHA_DURATION_MS);
mHintAnimator.setStartDelay(TEXT_HINT_ALPHA_START_DELAY_MS);
+ alphaDown = PropertyValuesHolder.ofFloat("alpha", BLACK_LAYER_ALPHA_DOWN_RANGE);
+ mAlphaDownAnimator = ObjectAnimator.ofPropertyValuesHolder(mBlackLayer, alphaDown);
+ mAlphaDownAnimator.setInterpolator(new DecelerateInterpolator());
+ mAlphaDownAnimator.setDuration(400);
+
+ alphaUp = PropertyValuesHolder.ofFloat("alpha", BLACK_LAYER_ALPHA_UP_RANGE);
+ mAlphaUpAnimator = ObjectAnimator.ofPropertyValuesHolder(mBlackLayer, alphaUp);
+ mAlphaUpAnimator.setInterpolator(new DecelerateInterpolator());
+ mAlphaUpAnimator.setDuration(200);
+
mSuccessAnimatorSet = new AnimatorSet();
mSuccessAnimatorSet.playSequentially(mFastSendAnimator, mFadeInAnimator);
@@ -271,6 +290,8 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener,
if (mScreenshotBitmap == null || mAttached) {
return;
}
+ mBlackLayer.setVisibility(View.GONE);
+ mBlackLayer.setAlpha(0f);
mScreenshotView.setOnTouchListener(this);
mScreenshotView.setImageBitmap(mScreenshotBitmap);
mScreenshotView.setTranslationX(0f);
@@ -279,6 +300,7 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener,
mScreenshotLayout.requestFocus();
+ mTextHint.setText(mContext.getResources().getString(R.string.touch));
mTextHint.setAlpha(0.0f);
mTextHint.setVisibility(View.VISIBLE);
mHintAnimator.start();
@@ -323,6 +345,7 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener,
public void showStartSend() {
if (!mAttached) return;
+ mTextRetry.setVisibility(View.GONE);
// Update the starting scale - touchscreen-mashers may trigger
// this before the pre-animation completes.
float currentScale = mScreenshotView.getScaleX();
@@ -332,6 +355,14 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener,
new float[] {currentScale, 0.0f});
mSlowSendAnimator.setValues(postX, postY);
+
+ float currentAlpha = mBlackLayer.getAlpha();
+ if (mBlackLayer.isShown() && currentAlpha > 0.0f) {
+ PropertyValuesHolder alphaDown = PropertyValuesHolder.ofFloat("alpha",
+ new float[] {currentAlpha, 0.0f});
+ mAlphaDownAnimator.setValues(alphaDown);
+ mAlphaDownAnimator.start();
+ }
mSlowSendAnimator.start();
}
@@ -352,11 +383,13 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener,
}
mTextHint.setVisibility(View.GONE);
+ mTextRetry.setVisibility(View.GONE);
float currentScale = mScreenshotView.getScaleX();
float currentAlpha = mScreenshotView.getAlpha();
if (finishMode == FINISH_SCALE_UP) {
+ mBlackLayer.setVisibility(View.GONE);
PropertyValuesHolder scaleUpX = PropertyValuesHolder.ofFloat("scaleX",
new float[] {currentScale, 1.0f});
PropertyValuesHolder scaleUpY = PropertyValuesHolder.ofFloat("scaleY",
@@ -373,7 +406,7 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener,
PropertyValuesHolder postY = PropertyValuesHolder.ofFloat("scaleY",
new float[] {currentScale, 0.0f});
PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha",
- new float[] {1.0f, 0.0f});
+ new float[] {currentAlpha, 0.0f});
mFastSendAnimator.setValues(postX, postY, alpha);
// Reset the fadeIn parameters to start from alpha 1
@@ -399,6 +432,8 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener,
mFastSendAnimator.cancel();
mSuccessAnimatorSet.cancel();
mScaleUpAnimator.cancel();
+ mAlphaUpAnimator.cancel();
+ mAlphaDownAnimator.cancel();
mWindowManager.removeView(mScreenshotLayout);
mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
releaseScreenshot();
@@ -595,4 +630,24 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener,
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) { }
+ public void showSendHint() {
+ if (mAlphaDownAnimator.isRunning()) {
+ mAlphaDownAnimator.cancel();
+ }
+ if (mSlowSendAnimator.isRunning()) {
+ mSlowSendAnimator.cancel();
+ }
+ mBlackLayer.setScaleX(mScreenshotView.getScaleX());
+ mBlackLayer.setScaleY(mScreenshotView.getScaleY());
+ mBlackLayer.setVisibility(View.VISIBLE);
+ mTextHint.setVisibility(View.GONE);
+
+ mTextRetry.setText(mContext.getResources().getString(R.string.beam_try_again));
+ mTextRetry.setVisibility(View.VISIBLE);
+
+ PropertyValuesHolder alphaUp = PropertyValuesHolder.ofFloat("alpha",
+ new float[] {mBlackLayer.getAlpha(), 0.9f});
+ mAlphaUpAnimator.setValues(alphaUp);
+ mAlphaUpAnimator.start();
+ }
}