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