• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
P2pEventManager(Context context, P2pEventListener.Callback callback)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
onP2pInRange()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
onP2pNfcTapRequested()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
onP2pTimeoutWaitingForLink()95     public void onP2pTimeoutWaitingForLink() {
96         if (mSendUi != null) {
97             mSendUi.finish(SendUi.FINISH_SCALE_UP);
98         }
99     }
100 
101     @Override
onP2pSendConfirmationRequested()102     public void onP2pSendConfirmationRequested() {
103         if (mSendUi != null) {
104             mSendUi.showPreSend(false);
105         } else {
106             mCallback.onP2pSendConfirmed();
107         }
108     }
109 
110     @Override
onP2pSendComplete()111     public void onP2pSendComplete() {
112         mNfcService.playSound(NfcService.SOUND_END);
113         mVibrator.vibrate(VIBRATION_PATTERN, -1);
114         if (mSendUi != null) {
115             mSendUi.finish(SendUi.FINISH_SEND_SUCCESS);
116         }
117         mSending = false;
118         mNdefSent = true;
119     }
120 
121     @Override
onP2pHandoverNotSupported()122     public void onP2pHandoverNotSupported() {
123         mNfcService.playSound(NfcService.SOUND_ERROR);
124         mVibrator.vibrate(VIBRATION_PATTERN, -1);
125         mSendUi.finishAndToast(SendUi.FINISH_SCALE_UP,
126                 mContext.getString(R.string.beam_handover_not_supported));
127         mSending = false;
128         mNdefSent = false;
129     }
130 
131     @Override
onP2pReceiveComplete(boolean playSound)132     public void onP2pReceiveComplete(boolean playSound) {
133         mVibrator.vibrate(VIBRATION_PATTERN, -1);
134         if (playSound) mNfcService.playSound(NfcService.SOUND_END);
135         if (mSendUi != null) {
136             // TODO we still don't have a nice receive solution
137             // The sanest solution right now is just to scale back up what we had
138             // and start the new activity. It is not perfect, but at least it is
139             // consistent behavior. All other variants involve making the old
140             // activity screenshot disappear, and then removing the animation
141             // window hoping the new activity has started by then. This just goes
142             // wrong too often and can look weird.
143             mSendUi.finish(SendUi.FINISH_SCALE_UP);
144         }
145         mNdefReceived = true;
146     }
147 
148     @Override
onP2pOutOfRange()149     public void onP2pOutOfRange() {
150         if (mSending) {
151             mNfcService.playSound(NfcService.SOUND_ERROR);
152             mSending = false;
153         }
154         if (!mNdefSent && !mNdefReceived && mSendUi != null) {
155             mSendUi.finish(SendUi.FINISH_SCALE_UP);
156         }
157         mInDebounce = false;
158     }
159 
160     @Override
onSendConfirmed()161     public void onSendConfirmed() {
162         if (!mSending) {
163             if (mSendUi != null) {
164                 mSendUi.showStartSend();
165             }
166             mCallback.onP2pSendConfirmed();
167         }
168         mSending = true;
169 
170     }
171 
172     @Override
onCanceled()173     public void onCanceled() {
174         mSendUi.finish(SendUi.FINISH_SCALE_UP);
175         mCallback.onP2pCanceled();
176     }
177 
178     @Override
onP2pSendDebounce()179     public void onP2pSendDebounce() {
180         mInDebounce = true;
181         mNfcService.playSound(NfcService.SOUND_ERROR);
182         if (mSendUi != null) {
183             mSendUi.showSendHint();
184         }
185     }
186 
187     @Override
onP2pResumeSend()188     public void onP2pResumeSend() {
189         if (mInDebounce) {
190             mVibrator.vibrate(VIBRATION_PATTERN, -1);
191             mNfcService.playSound(NfcService.SOUND_START);
192             if (mSendUi != null) {
193                 mSendUi.showStartSend();
194             }
195         }
196         mInDebounce = false;
197     }
198 
199 }
200