1 package android.location.cts.common;
2 
3 import android.annotation.Nullable;
4 import android.location.Location;
5 import android.os.CancellationSignal;
6 
7 import java.util.concurrent.CountDownLatch;
8 import java.util.concurrent.TimeUnit;
9 import java.util.concurrent.TimeoutException;
10 import java.util.function.Consumer;
11 
12 public class GetCurrentLocationCapture implements Consumer<Location>, AutoCloseable {
13 
14     private final CancellationSignal mCancellationSignal;
15     private final CountDownLatch mLatch;
16     private @Nullable Location mLocation;
17 
GetCurrentLocationCapture()18     public GetCurrentLocationCapture() {
19         mCancellationSignal = new CancellationSignal();
20         mLatch = new CountDownLatch(1);
21     }
22 
getCancellationSignal()23     public CancellationSignal getCancellationSignal() {
24         return mCancellationSignal;
25     }
26 
hasLocation(long timeoutMs)27     public boolean hasLocation(long timeoutMs) throws InterruptedException {
28         return mLatch.await(timeoutMs, TimeUnit.MILLISECONDS);
29     }
30 
getLocation(long timeoutMs)31     public @Nullable Location getLocation(long timeoutMs) throws InterruptedException, TimeoutException {
32         if (mLatch.await(timeoutMs, TimeUnit.MILLISECONDS)) {
33             return mLocation;
34         } else {
35             throw new TimeoutException("no location received before timeout");
36         }
37     }
38 
39     @Override
accept(Location location)40     public void accept(Location location) {
41         if (mLatch.getCount() == 0) {
42             throw new AssertionError("callback received multiple locations");
43         }
44 
45         mLocation = location;
46         mLatch.countDown();
47     }
48 
49     @Override
close()50     public void close() {
51         mCancellationSignal.cancel();
52     }
53 }