• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.bluetooth.tests;
2 
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.concurrent.CountDownLatch;
6 
7 import javax.obex.ClientSession;
8 import javax.obex.HeaderSet;
9 import javax.obex.ObexTransport;
10 import javax.obex.Operation;
11 import javax.obex.ServerSession;
12 
13 import junit.framework.Assert;
14 
15 import android.content.Context;
16 import android.hardware.camera2.impl.GetCommand;
17 import android.os.Handler;
18 import android.os.Handler.Callback;
19 import android.os.HandlerThread;
20 import android.os.Message;
21 import android.os.PowerManager;
22 import android.util.Log;
23 
24 public class TestSequencer implements Callback {
25     protected static String TAG = "TestSequencer";
26     protected static final boolean D = true;
27 
28     private final static int MSG_ID_TIMEOUT = 0x01;
29     private final static int TIMEOUT_VALUE = 100*2000; // ms
30     private ArrayList<SeqStep> mSequence = null;
31     private HandlerThread mHandlerThread = null;
32     private Handler mMessageHandler = null;
33     private ObexTransport mClientTransport;
34     private ObexTransport mServerTransport;
35 
36     private ClientSession mClientSession = null;
37     private ServerSession mServerSession = null;
38     public static final int STEP_INDEX_HEADER = 0xF1; /*0xFE*/
39 
40     public enum OPTYPE {CONNECT, PUT, GET, SET_PATH, DISCONNECT};
41 
42     private ITestSequenceConfigurator mConfigurator = null;
43 
TestSequencer(ObexTransport clientTransport, ObexTransport serverTransport, ITestSequenceConfigurator configurator)44     public TestSequencer(ObexTransport clientTransport, ObexTransport serverTransport,
45             ITestSequenceConfigurator configurator)
46             throws IOException {
47         /* Setup the looper thread to handle timeout messages */
48 //            mHandlerThread = new HandlerThread("TestTimeoutHandler",
49 //                      android.os.Process.THREAD_PRIORITY_BACKGROUND);
50 //            mHandlerThread.start();
51 //            Looper testLooper = mHandlerThread.getLooper();
52 //            mMessageHandler = new Handler(testLooper, this);
53         //TODO: fix looper cleanup on server - crash after 464 iterations - related to prepare?
54 
55         mClientTransport = clientTransport;
56         mServerTransport = serverTransport;
57 
58         /* Initialize members */
59         mSequence = new ArrayList<SeqStep>();
60         mConfigurator = configurator;
61         Assert.assertNotNull(configurator);
62     }
63 
64     /**
65      * Add a test step to the sequencer.
66      * @param type the OBEX operation to perform.
67      * @return the created step, which can be decorated before execution.
68      */
addStep(OPTYPE type, ISeqStepValidator validator)69     public SeqStep addStep(OPTYPE type, ISeqStepValidator validator) {
70         SeqStep newStep = new SeqStep(type);
71         newStep.mValidator = validator;
72         mSequence.add(newStep);
73         return newStep;
74     }
75 
76     /**
77      * Add a sub-step to a sequencer step. All requests added to the same index will be send to
78      * the SapServer in the order added before listening for the response.
79      * The response order is not validated - hence for each response received the entire list of
80      * responses in the step will be searched for a match.
81      * @param index the index returned from addStep() to which the sub-step is to be added.
82      * @param request The request to send to the SAP server
83      * @param response The response to EXPECT from the SAP server
84 
85     public void addSubStep(int index, SapMessage request, SapMessage response) {
86         SeqStep step = sequence.get(index);
87         step.add(request, response);
88     }*/
89 
90 
91     /**
92      * Run the sequence.
93      * Validate the response is either the expected response or one of the expected events.
94      *
95      * @return true when done - asserts at error/fail
96      */
run(Context context)97     public boolean run(Context context) throws IOException {
98         CountDownLatch stopLatch = new CountDownLatch(1);
99         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
100         PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
101         //wl.acquire();
102         try {
103             /* TODO:
104              * First create sequencer to validate using BT-snoop
105              * 1) Create the transports (this could include a validation sniffer on each side)
106              * 2) Create a server thread with a link to the transport
107              * 3) execute the client operation
108              * 4) validate response
109              *
110              * On server:
111              * 1) validate the request contains the expected content
112              * 2) send response.
113              * */
114 
115             /* Create the server */
116             if(mServerTransport != null) {
117                 mServerSession = new ServerSession(mServerTransport,
118                         mConfigurator.getObexServer(mSequence, stopLatch) , null);
119             }
120 
121             /* Create the client */
122             if(mClientTransport != null) {
123                 mClientSession = new ClientSession(mClientTransport);
124 
125                 for(SeqStep step : mSequence) {
126                     long stepIndex = mSequence.indexOf(step);
127 
128                     Log.i(TAG, "Executing step " + stepIndex + " of type: " + step.mType);
129 
130                     switch(step.mType) {
131                     case CONNECT: {
132                         HeaderSet reqHeaders = step.mReqHeaders;
133                         if(reqHeaders == null) {
134                             reqHeaders = new HeaderSet();
135                         }
136                         reqHeaders.setHeader(STEP_INDEX_HEADER, stepIndex);
137                         HeaderSet response = mClientSession.connect(reqHeaders);
138                         step.validate(response, null);
139                         step.clientPostAction(response, null);
140                         break;
141                     }
142                     case GET:{
143                         HeaderSet reqHeaders = step.mReqHeaders;
144                         if(reqHeaders == null) {
145                             reqHeaders = new HeaderSet();
146                         }
147                         reqHeaders.setHeader(STEP_INDEX_HEADER, stepIndex);
148                         Log.i(TAG, "  Starting operation...");
149                         Operation op = mClientSession.get(reqHeaders);
150                         Log.i(TAG, "  Operation done...");
151                         step.validate(null, op);
152                         step.clientPostAction(null, op);
153                         break;
154                     }
155                     case PUT: {
156                         HeaderSet reqHeaders = step.mReqHeaders;
157                         if(reqHeaders == null) {
158                             reqHeaders = new HeaderSet();
159                         }
160                         reqHeaders.setHeader(STEP_INDEX_HEADER, stepIndex);
161                         Operation op = mClientSession.put(reqHeaders);
162                         step.validate(null, op);
163                         step.clientPostAction(null, op);
164                         break;
165                     }
166                     case SET_PATH: {
167                         HeaderSet reqHeaders = step.mReqHeaders;
168                         if(reqHeaders == null) {
169                             reqHeaders = new HeaderSet();
170                         }
171                         reqHeaders.setHeader(STEP_INDEX_HEADER, stepIndex);
172                         try{
173                             HeaderSet response = mClientSession.setPath(reqHeaders,
174                                     step.mSetPathBackup, step.mSetPathCreate);;
175                             Log.i(TAG,"Received setPath response...");
176                             step.validate(response, null);
177                             step.clientPostAction(response, null);
178                         } catch (IOException e) {
179                             Log.e(TAG, "Error getting response code", e);
180                         }
181                         break;
182                     }
183                     case DISCONNECT: {
184                         Log.i(TAG,"Requesting disconnect...");
185                         HeaderSet reqHeaders = step.mReqHeaders;
186                         if(reqHeaders == null) {
187                             reqHeaders = new HeaderSet();
188                         }
189                         reqHeaders.setHeader(STEP_INDEX_HEADER, stepIndex);
190                         try{
191                             HeaderSet response = mClientSession.disconnect(reqHeaders);
192                             Log.i(TAG,"Received disconnect response...");
193                             step.validate(response, null);
194                             step.clientPostAction(response, null);
195                         } catch (IOException e) {
196                             Log.e(TAG, "Error getting response code", e);
197                         }
198                         break;
199                     }
200                     default:
201                         Assert.assertTrue("Unknown type: " + step.mType, false);
202                         break;
203 
204                     }
205                 }
206                 mClientSession.close();
207             }
208             /* All done, close down... */
209             if(mServerSession != null) {
210                 boolean interrupted = false;
211                 do {
212                     try {
213                         interrupted = false;
214                         Log.i(TAG,"Waiting for stopLatch signal...");
215                         stopLatch.await();
216                     } catch (InterruptedException e) {
217                         Log.w(TAG,e);
218                         interrupted = true;
219                     }
220                 } while (interrupted == true);
221                 Log.i(TAG,"stopLatch signal received closing down...");
222                 try {
223                     interrupted = false;
224                     Log.i(TAG,"  Sleep 50ms to allow disconnect signal to be send before closing.");
225                     Thread.sleep(50);
226                 } catch (InterruptedException e) {
227                     Log.w(TAG,e);
228                     interrupted = true;
229                 }
230                 mServerSession.close();
231             }
232             // this will close the I/O streams as well.
233         } finally {
234             //wl.release();
235         }
236         return true;
237     }
238 
shutdown()239     public void shutdown() {
240 //            mMessageHandler.removeCallbacksAndMessages(null);
241 //            mMessageHandler.quit();
242 //            mMessageHandler = null;
243     }
244 
245 
246 //        private void startTimer() {
247 //            Message timeoutMessage = mMessageHandler.obtainMessage(MSG_ID_TIMEOUT);
248 //            mMessageHandler.sendMessageDelayed(timeoutMessage, TIMEOUT_VALUE);
249 //        }
250 //
251 //        private void stopTimer() {
252 //            mMessageHandler.removeMessages(MSG_ID_TIMEOUT);
253 //        }
254 
255     @Override
handleMessage(Message msg)256     public boolean handleMessage(Message msg) {
257 
258         Log.i(TAG,"Handling message ID: " + msg.what);
259 
260         switch(msg.what) {
261         case MSG_ID_TIMEOUT:
262             Log.w(TAG, "Timeout occured!");
263 /*                try {
264                     //inStream.close();
265                 } catch (IOException e) {
266                     Log.e(TAG, "failed to close inStream", e);
267                 }
268                 try {
269                     //outStream.close();
270                 } catch (IOException e) {
271                     Log.e(TAG, "failed to close outStream", e);
272                 }*/
273             break;
274         default:
275             /* Message not handled */
276             return false;
277         }
278         return true; // Message handles
279     }
280 
281 
282 
283 }
284 
285