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 android.app.NotificationManager;
     20 import android.content.Context;
     21 import android.content.res.Configuration;
     22 import android.os.Vibrator;
     23 
     24 /**
     25  * Manages vibration, sound and animation for P2P events.
     26  */
     27 public class P2pEventManager implements P2pEventListener, SendUi.Callback {
     28     static final String TAG = "NfcP2pEventManager";
     29     static final boolean DBG = true;
     30 
     31     static final long[] VIBRATION_PATTERN = {0, 100, 10000};
     32 
     33     final Context mContext;
     34     final NfcService mNfcService;
     35     final P2pEventListener.Callback mCallback;
     36     final Vibrator mVibrator;
     37     final NotificationManager mNotificationManager;
     38     final SendUi mSendUi;
     39 
     40     // only used on UI thread
     41     boolean mSending;
     42     boolean mNdefSent;
     43     boolean mNdefReceived;
     44     boolean mInDebounce;
     45 
     46     public P2pEventManager(Context context, P2pEventListener.Callback callback) {
     47         mNfcService = NfcService.getInstance();
     48         mContext = context;
     49         mCallback = callback;
     50         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
     51         mNotificationManager = (NotificationManager) mContext.getSystemService(
     52                 Context.NOTIFICATION_SERVICE);
     53 
     54         mSending = false;
     55         final int uiModeType = mContext.getResources().getConfiguration().uiMode
     56                 & Configuration.UI_MODE_TYPE_MASK;
     57         if (uiModeType == Configuration.UI_MODE_TYPE_APPLIANCE) {
     58             // "Appliances" don't intrinsically have a way of confirming this, so we
     59             // don't use the UI and just autoconfirm where necessary.
     60             // Don't instantiate SendUi or else we'll use memory and never reclaim it.
     61             mSendUi = null;
     62         } else {
     63             mSendUi = new SendUi(context, this);
     64         }
     65     }
     66 
     67     @Override
     68     public void onP2pInRange() {
     69         mNfcService.playSound(NfcService.SOUND_START);
     70         mNdefSent = false;
     71         mNdefReceived = false;
     72         mInDebounce = false;
     73 
     74         mVibrator.vibrate(VIBRATION_PATTERN, -1);
     75         if (mSendUi != null) {
     76             mSendUi.takeScreenshot();
     77         }
     78     }
     79 
     80     @Override
     81     public void onP2pSendConfirmationRequested() {
     82         if (mSendUi != null) {
     83             mSendUi.showPreSend();
     84         } else {
     85             mCallback.onP2pSendConfirmed();
     86         }
     87     }
     88 
     89     @Override
     90     public void onP2pSendComplete() {
     91         mNfcService.playSound(NfcService.SOUND_END);
     92         mVibrator.vibrate(VIBRATION_PATTERN, -1);
     93         if (mSendUi != null) {
     94             mSendUi.finish(SendUi.FINISH_SEND_SUCCESS);
     95         }
     96         mSending = false;
     97         mNdefSent = true;
     98     }
     99 
    100     @Override
    101     public void onP2pHandoverNotSupported() {
    102         mNfcService.playSound(NfcService.SOUND_ERROR);
    103         mVibrator.vibrate(VIBRATION_PATTERN, -1);
    104         mSendUi.finishAndToast(SendUi.FINISH_SCALE_UP,
    105                 mContext.getString(R.string.beam_handover_not_supported));
    106         mSending = false;
    107         mNdefSent = false;
    108     }
    109 
    110     @Override
    111     public void onP2pReceiveComplete(boolean playSound) {
    112         mVibrator.vibrate(VIBRATION_PATTERN, -1);
    113         if (playSound) mNfcService.playSound(NfcService.SOUND_END);
    114         if (mSendUi != null) {
    115             // TODO we still don't have a nice receive solution
    116             // The sanest solution right now is just to scale back up what we had
    117             // and start the new activity. It is not perfect, but at least it is
    118             // consistent behavior. All other variants involve making the old
    119             // activity screenshot disappear, and then removing the animation
    120             // window hoping the new activity has started by then. This just goes
    121             // wrong too often and can look weird.
    122             mSendUi.finish(SendUi.FINISH_SCALE_UP);
    123         }
    124         mNdefReceived = true;
    125     }
    126 
    127     @Override
    128     public void onP2pOutOfRange() {
    129         if (mSending) {
    130             mNfcService.playSound(NfcService.SOUND_ERROR);
    131             mSending = false;
    132         }
    133         if (!mNdefSent && !mNdefReceived && mSendUi != null) {
    134             mSendUi.finish(SendUi.FINISH_SCALE_UP);
    135         }
    136         mInDebounce = false;
    137     }
    138 
    139     @Override
    140     public void onSendConfirmed() {
    141         if (!mSending) {
    142             if (mSendUi != null) {
    143                 mSendUi.showStartSend();
    144             }
    145             mCallback.onP2pSendConfirmed();
    146         }
    147         mSending = true;
    148 
    149     }
    150 
    151     @Override
    152     public void onP2pSendDebounce() {
    153         mInDebounce = true;
    154         mNfcService.playSound(NfcService.SOUND_ERROR);
    155         if (mSendUi != null) {
    156             mSendUi.showSendHint();
    157         }
    158     }
    159 
    160     @Override
    161     public void onP2pResumeSend() {
    162         if (mInDebounce) {
    163             mVibrator.vibrate(VIBRATION_PATTERN, -1);
    164             mNfcService.playSound(NfcService.SOUND_START);
    165             if (mSendUi != null) {
    166                 mSendUi.showStartSend();
    167             }
    168         }
    169         mInDebounce = false;
    170     }
    171 }
    172