1 package com.android.server.location;
2 
3 import android.util.Log;
4 
5 import com.android.internal.annotations.VisibleForTesting;
6 
7 /**
8  * Manages GNSS Batching operations.
9  *
10  * <p>This class is not thread safe (It's client's responsibility to make sure calls happen on
11  * the same thread).
12  */
13 public class GnssBatchingProvider {
14 
15     private static final String TAG = "GnssBatchingProvider";
16     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
17 
18     private final GnssBatchingProviderNative mNative;
19     private boolean mEnabled;
20     private boolean mStarted;
21     private long mPeriodNanos;
22     private boolean mWakeOnFifoFull;
23 
GnssBatchingProvider()24     GnssBatchingProvider() {
25         this(new GnssBatchingProviderNative());
26     }
27 
28     @VisibleForTesting
GnssBatchingProvider(GnssBatchingProviderNative gnssBatchingProviderNative)29     GnssBatchingProvider(GnssBatchingProviderNative gnssBatchingProviderNative) {
30         mNative = gnssBatchingProviderNative;
31     }
32 
33     /**
34      * Returns the GNSS batching size
35      */
getBatchSize()36     public int getBatchSize() {
37         return mNative.getBatchSize();
38     }
39 
40     /** Enable GNSS batching. */
enable()41     public void enable() {
42         mEnabled = mNative.initBatching();
43         if (!mEnabled) {
44             Log.e(TAG, "Failed to initialize GNSS batching");
45         }
46     }
47 
48     /**
49      * Starts the hardware batching operation
50      */
start(long periodNanos, boolean wakeOnFifoFull)51     public boolean start(long periodNanos, boolean wakeOnFifoFull) {
52         if (!mEnabled) {
53             throw new IllegalStateException();
54         }
55         if (periodNanos <= 0) {
56             Log.e(TAG, "Invalid periodNanos " + periodNanos +
57                     " in batching request, not started");
58             return false;
59         }
60         mStarted = mNative.startBatch(periodNanos, wakeOnFifoFull);
61         if (mStarted) {
62             mPeriodNanos = periodNanos;
63             mWakeOnFifoFull = wakeOnFifoFull;
64         }
65         return mStarted;
66     }
67 
68     /**
69      * Forces a flush of existing locations from the hardware batching
70      */
flush()71     public void flush() {
72         if (!mStarted) {
73             Log.w(TAG, "Cannot flush since GNSS batching has not started.");
74             return;
75         }
76         mNative.flushBatch();
77     }
78 
79     /**
80      * Stops the batching operation
81      */
stop()82     public boolean stop() {
83         boolean stopped = mNative.stopBatch();
84         if (stopped) {
85             mStarted = false;
86         }
87         return stopped;
88     }
89 
90     /** Disable GNSS batching. */
disable()91     public void disable() {
92         stop();
93         mNative.cleanupBatching();
94         mEnabled = false;
95     }
96 
97     // TODO(b/37460011): Use this with death recovery logic.
resumeIfStarted()98     void resumeIfStarted() {
99         if (DEBUG) {
100             Log.d(TAG, "resumeIfStarted");
101         }
102         if (mStarted) {
103             mNative.startBatch(mPeriodNanos, mWakeOnFifoFull);
104         }
105     }
106 
107     @VisibleForTesting
108     static class GnssBatchingProviderNative {
getBatchSize()109         public int getBatchSize() {
110             return native_get_batch_size();
111         }
112 
startBatch(long periodNanos, boolean wakeOnFifoFull)113         public boolean startBatch(long periodNanos, boolean wakeOnFifoFull) {
114             return native_start_batch(periodNanos, wakeOnFifoFull);
115         }
116 
flushBatch()117         public void flushBatch() {
118             native_flush_batch();
119         }
120 
stopBatch()121         public boolean stopBatch() {
122             return native_stop_batch();
123         }
124 
initBatching()125         public boolean initBatching() {
126             return native_init_batching();
127         }
128 
cleanupBatching()129         public void cleanupBatching() {
130             native_cleanup_batching();
131         }
132     }
133 
native_get_batch_size()134     private static native int native_get_batch_size();
135 
native_start_batch(long periodNanos, boolean wakeOnFifoFull)136     private static native boolean native_start_batch(long periodNanos, boolean wakeOnFifoFull);
137 
native_flush_batch()138     private static native void native_flush_batch();
139 
native_stop_batch()140     private static native boolean native_stop_batch();
141 
native_init_batching()142     private static native boolean native_init_batching();
143 
native_cleanup_batching()144     private static native void native_cleanup_batching();
145 }
146