Home | History | Annotate | Download | only in nfc
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.nfc;
     18 
     19 import com.android.nfc.beam.SendUi;
     20 
     21 import android.app.NotificationManager;
     22 import android.content.Context;
     23 import android.content.res.Configuration;
     24 import android.os.Vibrator;
     25 
     26 /**
     27  * Manages vibration, sound and animation for P2P events.
     28  */
     29 public class P2pEventManager implements P2pEventListener, SendUi.Callback {
     30     static final String TAG = "NfcP2pEventManager";
     31     static final boolean DBG = true;
     32 
     33     static final long[] VIBRATION_PATTERN = {0, 100, 10000};
     34 
     35     final Context mContext;
     36     final NfcService mNfcService;
     37     final P2pEventListener.Callback mCallback;
     38     final Vibrator mVibrator;
     39     final NotificationManager mNotificationManager;
     40     final SendUi mSendUi;
     41 
     42     // only used on UI thread
     43     boolean mSending;
     44     boolean mNdefSent;
     45     boolean mNdefReceived;
     46     boolean mInDebounce;
     47 
     48     public P2pEventManager(Context context, P2pEventListener.Callback callback) {
     49         mNfcService = NfcService.getInstance();
     50         mContext = context;
     51         mCallback = callback;
     52         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
     53         mNotificationManager = (NotificationManager) mContext.getSystemService(
     54                 Context.NOTIFICATION_SERVICE);
     55 
     56         mSending = false;
     57         final int uiModeType = mContext.getResources().getConfiguration().uiMode
     58                 & Configuration.UI_MODE_TYPE_MASK;
     59         if (uiModeType == Configuration.UI_MODE_TYPE_APPLIANCE) {
     60             // "Appliances" don't intrinsically have a way of confirming this, so we
     61             // don't use the UI and just autoconfirm where necessary.
     62             // Don't instantiate SendUi or else we'll use memory and never reclaim it.
     63             mSendUi = null;
     64         } else {
     65             mSendUi = new SendUi(context, this);
     66         }
     67     }
     68 
     69     @Override
     70     public void onP2pInRange() {
     71         mNdefSent = false;
     72         mNdefReceived = false;
     73         mInDebounce = false;
     74 
     75         if (mSendUi != null) {
     76             mSendUi.takeScreenshot();
     77         }
     78     }
     79 
     80     @Override
     81     public void onP2pNfcTapRequested() {
     82         mNfcService.playSound(NfcService.SOUND_START);
     83         mNdefSent = false;
     84         mNdefReceived = false;
     85         mInDebounce = false;
     86 
     87         mVibrator.vibrate(VIBRATION_PATTERN, -1);
     88         if (mSendUi != null) {
     89             mSendUi.takeScreenshot();
     90             mSendUi.showPreSend(true);
     91         }
     92     }
     93 
     94     @Override
     95     public void onP2pTimeoutWaitingForLink() {
     96         if (mSendUi != null) {
     97             mSendUi.finish(SendUi.FINISH_SCALE_UP);
     98         }
     99     }
    100 
    101     @Override
    102     public void onP2pSendConfirmationRequested() {
    103         mNfcService.playSound(NfcService.SOUND_START);
    104         mVibrator.vibrate(VIBRATION_PATTERN, -1);
    105         if (mSendUi != null) {
    106             mSendUi.showPreSend(false);
    107         } else {
    108             mCallback.onP2pSendConfirmed();
    109         }
    110     }
    111 
    112     @Override
    113     public void onP2pSendComplete() {
    114         mNfcService.playSound(NfcService.SOUND_END);
    115         mVibrator.vibrate(VIBRATION_PATTERN, -1);
    116         if (mSendUi != null) {
    117             mSendUi.finish(SendUi.FINISH_SEND_SUCCESS);
    118         }
    119         mSending = false;
    120         mNdefSent = true;
    121     }
    122 
    123     @Override
    124     public void onP2pHandoverNotSupported() {
    125         mNfcService.playSound(NfcService.SOUND_ERROR);
    126         mVibrator.vibrate(VIBRATION_PATTERN, -1);
    127         mSendUi.finishAndToast(SendUi.FINISH_SCALE_UP,
    128                 mContext.getString(R.string.beam_handover_not_supported));
    129         mSending = false;
    130         mNdefSent = false;
    131     }
    132 
    133     @Override
    134     public void onP2pHandoverBusy() {
    135         mNfcService.playSound(NfcService.SOUND_ERROR);
    136         mVibrator.vibrate(VIBRATION_PATTERN, -1);
    137         mSendUi.finishAndToast(SendUi.FINISH_SCALE_UP, mContext.getString(R.string.beam_busy));
    138         mSending = false;
    139         mNdefSent = false;
    140     }
    141 
    142     @Override
    143     public void onP2pReceiveComplete(boolean playSound) {
    144         mVibrator.vibrate(VIBRATION_PATTERN, -1);
    145         if (playSound) mNfcService.playSound(NfcService.SOUND_END);
    146         if (mSendUi != null) {
    147             // TODO we still don't have a nice receive solution
    148             // The sanest solution right now is just to scale back up what we had
    149             // and start the new activity. It is not perfect, but at least it is
    150             // consistent behavior. All other variants involve making the old
    151             // activity screenshot disappear, and then removing the animation
    152             // window hoping the new activity has started by then. This just goes
    153             // wrong too often and can look weird.
    154             mSendUi.finish(SendUi.FINISH_SCALE_UP);
    155         }
    156         mNdefReceived = true;
    157     }
    158 
    159     @Override
    160     public void onP2pOutOfRange() {
    161         if (mSending) {
    162             mNfcService.playSound(NfcService.SOUND_ERROR);
    163             mSending = false;
    164         }
    165         if (!mNdefSent && !mNdefReceived && mSendUi != null) {
    166             mSendUi.finish(SendUi.FINISH_SCALE_UP);
    167         }
    168         mInDebounce = false;
    169     }
    170 
    171     @Override
    172     public void onSendConfirmed() {
    173         if (!mSending) {
    174             if (mSendUi != null) {
    175                 mSendUi.showStartSend();
    176             }
    177             mCallback.onP2pSendConfirmed();
    178         }
    179         mSending = true;
    180 
    181     }
    182 
    183     @Override
    184     public void onCanceled() {
    185         mSendUi.finish(SendUi.FINISH_SCALE_UP);
    186         mCallback.onP2pCanceled();
    187     }
    188 
    189     @Override
    190     public void onP2pSendDebounce() {
    191         mInDebounce = true;
    192         mNfcService.playSound(NfcService.SOUND_ERROR);
    193         if (mSendUi != null) {
    194             mSendUi.showSendHint();
    195         }
    196     }
    197 
    198     @Override
    199     public void onP2pResumeSend() {
    200         mVibrator.vibrate(VIBRATION_PATTERN, -1);
    201         mNfcService.playSound(NfcService.SOUND_START);
    202         if (mInDebounce) {
    203             if (mSendUi != null) {
    204                 mSendUi.showStartSend();
    205             }
    206         }
    207         mInDebounce = false;
    208     }
    209 
    210 }
    211