1d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru/*
2d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Copyright (C) 2011 The Android Open Source Project
3d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru *
4d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Licensed under the Apache License, Version 2.0 (the "License");
5d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * you may not use this file except in compliance with the License.
6d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * You may obtain a copy of the License at
7d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru *
8d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru *      http://www.apache.org/licenses/LICENSE-2.0
9d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru *
10d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Unless required by applicable law or agreed to in writing, software
11d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * distributed under the License is distributed on an "AS IS" BASIS,
12d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * See the License for the specific language governing permissions and
14d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * limitations under the License.
15d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */
16d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
17d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Querupackage com.android.volley.mock;
18d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
19d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport com.android.volley.NetworkResponse;
20d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport com.android.volley.Request;
21d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport com.android.volley.Response;
22d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
23d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.concurrent.PriorityBlockingQueue;
24d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.concurrent.Semaphore;
25d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.concurrent.TimeUnit;
26d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.concurrent.TimeoutException;
27d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
28d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru// TODO: the name of this class sucks
29d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru@SuppressWarnings({ "serial", "rawtypes" })
30d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Querupublic class WaitableQueue extends PriorityBlockingQueue<Request> {
31d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    private final Request<?> mStopRequest = new MagicStopRequest();
32d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    private final Semaphore mStopEvent = new Semaphore(0);
33d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
34d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    // TODO: this isn't really "until empty" it's "until next call to take() after empty"
35d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    public void waitUntilEmpty(long timeoutMillis)
36d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            throws TimeoutException, InterruptedException {
37d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        add(mStopRequest);
38d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        if (!mStopEvent.tryAcquire(timeoutMillis, TimeUnit.MILLISECONDS)) {
39d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            throw new TimeoutException();
40d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        }
41d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
42d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
43d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    @Override
44d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    public Request<?> take() throws InterruptedException {
45d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        Request<?> item = super.take();
46d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        if (item == mStopRequest) {
47d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            mStopEvent.release();
48d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            return take();
49d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        }
50d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        return item;
51d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
52d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
53d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    private static class MagicStopRequest extends Request<Object> {
54d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        public MagicStopRequest() {
55d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            super("", null);
56d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        }
57d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
58d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        @Override
59d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        public Priority getPriority() {
60d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            return Priority.LOW;
61d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        }
62d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
63d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        @Override
64d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        protected Response<Object> parseNetworkResponse(NetworkResponse response) {
65d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            return null;
66d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        }
67d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
68d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        @Override
69d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        protected void deliverResponse(Object response) {
70d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        }
71d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
72d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru}
73