summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Wills <mwills@google.com>2016-06-24 22:23:15 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2016-06-24 22:23:15 +0000
commit55b1b58e72df2362888c7a1c60ad76a43523bfcf (patch)
tree1fc6395f20c9c4618da4e036a811981989fd014e
parentaf2c07c305e33b759b3b0e707fdc264b193626c4 (diff)
parent5751e82f645ab5b4366c63e0fbc561534c1cb3b8 (diff)
Merge "Reuse single scan results if a request comes in during an ongoing scan" into nyc-mr1-dev
-rw-r--r--service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java61
-rw-r--r--tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java257
2 files changed, 271 insertions, 47 deletions
diff --git a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
index 49172c135..ee0a060cb 100644
--- a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
@@ -418,6 +418,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
private final IdleState mIdleState = new IdleState();
private final ScanningState mScanningState = new ScanningState();
+ private WifiNative.ScanSettings mActiveScanSettings = null;
private RequestList<ScanSettings> mActiveScans = new RequestList<>();
private RequestList<ScanSettings> mPendingScans = new RequestList<>();
@@ -546,12 +547,24 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
scanParams.getParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY);
WorkSource workSource =
scanParams.getParcelable(WifiScanner.SCAN_PARAMS_WORK_SOURCE_KEY);
- if (validateAndAddToScanQueue(ci, handler, scanSettings, workSource)) {
+ if (validateScanRequest(ci, handler, scanSettings, workSource)) {
+ logScanRequest("addSingleScanRequest", ci, handler, workSource,
+ scanSettings, null);
replySucceeded(msg);
+
+ // If there is an active scan that will fulfill the scan request then
+ // mark this request as an active scan, otherwise mark it pending.
// If were not currently scanning then try to start a scan. Otherwise
// this scan will be scheduled when transitioning back to IdleState
// after finishing the current scan.
- if (getCurrentState() != mScanningState) {
+ if (getCurrentState() == mScanningState) {
+ if (activeScanSatisfies(scanSettings)) {
+ mActiveScans.addRequest(ci, handler, workSource, scanSettings);
+ } else {
+ mPendingScans.addRequest(ci, handler, workSource, scanSettings);
+ }
+ } else {
+ mPendingScans.addRequest(ci, handler, workSource, scanSettings);
tryToStartNewScan();
}
} else {
@@ -597,6 +610,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
@Override
public void exit() {
+ mActiveScanSettings = null;
try {
mBatteryStats.noteWifiScanStoppedFromSource(mScanWorkSource);
} catch (RemoteException e) {
@@ -638,7 +652,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
}
- boolean validateAndAddToScanQueue(ClientInfo ci, int handler, ScanSettings settings,
+ boolean validateScanRequest(ClientInfo ci, int handler, ScanSettings settings,
WorkSource workSource) {
if (ci == null) {
Log.d(TAG, "Failing single scan request ClientInfo not found " + handler);
@@ -650,8 +664,43 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
return false;
}
}
- logScanRequest("addSingleScanRequest", ci, handler, workSource, settings, null);
- mPendingScans.addRequest(ci, handler, workSource, settings);
+ return true;
+ }
+
+ boolean activeScanSatisfies(ScanSettings settings) {
+ if (mActiveScanSettings == null) {
+ return false;
+ }
+
+ // there is always one bucket for a single scan
+ WifiNative.BucketSettings activeBucket = mActiveScanSettings.buckets[0];
+
+ // validate that all requested channels are being scanned
+ ChannelCollection activeChannels = mChannelHelper.createChannelCollection();
+ activeChannels.addChannels(activeBucket);
+ if (!activeChannels.containsSettings(settings)) {
+ return false;
+ }
+
+ // if the request is for a full scan, but there is no ongoing full scan
+ if ((settings.reportEvents & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT) != 0
+ && (activeBucket.report_events & WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT)
+ == 0) {
+ return false;
+ }
+
+ if (settings.hiddenNetworkIds != null) {
+ Set<Integer> activeHiddenNetworkIds = new HashSet<>();
+ for (int id : mActiveScanSettings.hiddenNetworkIds) {
+ activeHiddenNetworkIds.add(id);
+ }
+ for (int id : settings.hiddenNetworkIds) {
+ if (!activeHiddenNetworkIds.contains(id)) {
+ return false;
+ }
+ }
+ }
+
return true;
}
@@ -710,6 +759,8 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
settings.buckets = new WifiNative.BucketSettings[] {bucketSettings};
if (mScannerImpl.startSingleScan(settings, this)) {
+ // store the active scan settings
+ mActiveScanSettings = settings;
// swap pending and active scan requests
RequestList<ScanSettings> tmp = mActiveScans;
mActiveScans = mPendingScans;
diff --git a/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java b/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
index 128815322..529b42988 100644
--- a/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/scanner/WifiScanningServiceTest.java
@@ -137,13 +137,13 @@ public class WifiScanningServiceTest {
return controlChannel;
}
- private Message verifyHandleMessageAndGetMessage(InOrder order, Handler handler) {
+ private static Message verifyHandleMessageAndGetMessage(InOrder order, Handler handler) {
ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
order.verify(handler).handleMessage(messageCaptor.capture());
return messageCaptor.getValue();
}
- private Message verifyHandleMessageAndGetMessage(InOrder order, Handler handler,
+ private static Message verifyHandleMessageAndGetMessage(InOrder order, Handler handler,
final int what) {
CapturingMatcher<Message> messageMatcher = new CapturingMatcher<Message>() {
public boolean matches(Object argument) {
@@ -155,14 +155,14 @@ public class WifiScanningServiceTest {
return messageMatcher.getLastValue();
}
- private void verifyScanResultsRecieved(InOrder order, Handler handler, int listenerId,
+ private static void verifyScanResultsRecieved(InOrder order, Handler handler, int listenerId,
WifiScanner.ScanData... expected) {
Message scanResultMessage = verifyHandleMessageAndGetMessage(order, handler,
WifiScanner.CMD_SCAN_RESULT);
assertScanResultsMessage(listenerId, expected, scanResultMessage);
}
- private void assertScanResultsMessage(int listenerId, WifiScanner.ScanData[] expected,
+ private static void assertScanResultsMessage(int listenerId, WifiScanner.ScanData[] expected,
Message scanResultMessage) {
assertEquals("what", WifiScanner.CMD_SCAN_RESULT, scanResultMessage.what);
assertEquals("listenerId", listenerId, scanResultMessage.arg2);
@@ -170,18 +170,19 @@ public class WifiScanningServiceTest {
((WifiScanner.ParcelableScanData) scanResultMessage.obj).getResults());
}
- private void verifySingleScanCompletedRecieved(InOrder order, Handler handler, int listenerId) {
+ private static void verifySingleScanCompletedRecieved(InOrder order, Handler handler,
+ int listenerId) {
Message completedMessage = verifyHandleMessageAndGetMessage(order, handler,
WifiScanner.CMD_SINGLE_SCAN_COMPLETED);
assertSingleScanCompletedMessage(listenerId, completedMessage);
}
- private void assertSingleScanCompletedMessage(int listenerId, Message completedMessage) {
+ private static void assertSingleScanCompletedMessage(int listenerId, Message completedMessage) {
assertEquals("what", WifiScanner.CMD_SINGLE_SCAN_COMPLETED, completedMessage.what);
assertEquals("listenerId", listenerId, completedMessage.arg2);
}
- private void sendBackgroundScanRequest(BidirectionalAsyncChannel controlChannel,
+ private static void sendBackgroundScanRequest(BidirectionalAsyncChannel controlChannel,
int scanRequestId, WifiScanner.ScanSettings settings, WorkSource workSource) {
Bundle scanParams = new Bundle();
scanParams.putParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY, settings);
@@ -190,7 +191,7 @@ public class WifiScanningServiceTest {
scanRequestId, scanParams));
}
- private void sendSingleScanRequest(BidirectionalAsyncChannel controlChannel,
+ private static void sendSingleScanRequest(BidirectionalAsyncChannel controlChannel,
int scanRequestId, WifiScanner.ScanSettings settings, WorkSource workSource) {
Bundle scanParams = new Bundle();
scanParams.putParcelable(WifiScanner.SCAN_PARAMS_SCAN_SETTINGS_KEY, settings);
@@ -199,12 +200,12 @@ public class WifiScanningServiceTest {
scanRequestId, scanParams));
}
- private void verifySuccessfulResponse(InOrder order, Handler handler, int arg2) {
+ private static void verifySuccessfulResponse(InOrder order, Handler handler, int arg2) {
Message response = verifyHandleMessageAndGetMessage(order, handler);
assertSuccessfulResponse(arg2, response);
}
- private void assertSuccessfulResponse(int arg2, Message response) {
+ private static void assertSuccessfulResponse(int arg2, Message response) {
if (response.what == WifiScanner.CMD_OP_FAILED) {
WifiScanner.OperationResult result = (WifiScanner.OperationResult) response.obj;
fail("response indicates failure, reason=" + result.reason
@@ -215,13 +216,47 @@ public class WifiScanningServiceTest {
}
}
- private void verifyFailedResponse(InOrder order, Handler handler, int arg2,
+ /**
+ * If multiple results are expected for a single hardware scan then the order that they are
+ * dispatched is dependant on the order which they are iterated through internally. This
+ * function validates that the order is either one way or the other.
+ */
+ private static void verifyMultipleSingleScanResults(InOrder handlerOrder, Handler handler,
+ int requestId1, ScanResults results1, int requestId2, ScanResults results2) {
+ ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+ handlerOrder.verify(handler, times(4))
+ .handleMessage(messageCaptor.capture());
+ int firstListenerId = messageCaptor.getAllValues().get(0).arg2;
+ assertTrue(firstListenerId + " was neither " + requestId2 + " nor " + requestId1,
+ firstListenerId == requestId2 || firstListenerId == requestId1);
+ if (firstListenerId == requestId2) {
+ assertScanResultsMessage(requestId2,
+ new WifiScanner.ScanData[] {results2.getScanData()},
+ messageCaptor.getAllValues().get(0));
+ assertSingleScanCompletedMessage(requestId2, messageCaptor.getAllValues().get(1));
+ assertScanResultsMessage(requestId1,
+ new WifiScanner.ScanData[] {results1.getScanData()},
+ messageCaptor.getAllValues().get(2));
+ assertSingleScanCompletedMessage(requestId1, messageCaptor.getAllValues().get(3));
+ } else {
+ assertScanResultsMessage(requestId1,
+ new WifiScanner.ScanData[] {results1.getScanData()},
+ messageCaptor.getAllValues().get(0));
+ assertSingleScanCompletedMessage(requestId1, messageCaptor.getAllValues().get(1));
+ assertScanResultsMessage(requestId2,
+ new WifiScanner.ScanData[] {results2.getScanData()},
+ messageCaptor.getAllValues().get(2));
+ assertSingleScanCompletedMessage(requestId2, messageCaptor.getAllValues().get(3));
+ }
+ }
+
+ private static void verifyFailedResponse(InOrder order, Handler handler, int arg2,
int expectedErrorReason, String expectedErrorDescription) {
Message response = verifyHandleMessageAndGetMessage(order, handler);
assertFailedResponse(arg2, expectedErrorReason, expectedErrorDescription, response);
}
- private void assertFailedResponse(int arg2, int expectedErrorReason,
+ private static void assertFailedResponse(int arg2, int expectedErrorReason,
String expectedErrorDescription, Message response) {
if (response.what == WifiScanner.CMD_OP_SUCCEEDED) {
fail("response indicates success");
@@ -629,8 +664,8 @@ public class WifiScanningServiceTest {
}
/**
- * Send a single scan request and then a second one before the first completes.
- * Verify that both are scheduled and succeed.
+ * Send a single scan request and then a second one not satisfied by the first before the first
+ * completes. Verify that both are scheduled and succeed.
*/
@Test
public void sendSingleScanRequestWhilePreviousScanRunning() {
@@ -695,8 +730,8 @@ public class WifiScanningServiceTest {
/**
- * Send a single scan request and then two more before the first completes.
- * Verify that the first completes and the second two are merged.
+ * Send a single scan request and then two more before the first completes. Neither are
+ * satisfied by the first scan. Verify that the first completes and the second two are merged.
*/
@Test
public void sendMultipleSingleScanRequestWhilePreviousScanRunning() throws RemoteException {
@@ -779,32 +814,8 @@ public class WifiScanningServiceTest {
mLooper.dispatchAll();
- // unfortunatally the order that these events are dispatched is dependant on the order which
- // they are iterated through internally
- ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
- handlerOrder.verify(handler, times(4)).handleMessage(messageCaptor.capture());
- int firstListenerId = messageCaptor.getAllValues().get(0).arg2;
- assertTrue(firstListenerId + " was neither " + requestId2 + " nor " + requestId3,
- firstListenerId == requestId2 || firstListenerId == requestId3);
- if (firstListenerId == requestId2) {
- assertScanResultsMessage(requestId2,
- new WifiScanner.ScanData[] {results2.getScanData()},
- messageCaptor.getAllValues().get(0));
- assertSingleScanCompletedMessage(requestId2, messageCaptor.getAllValues().get(1));
- assertScanResultsMessage(requestId3,
- new WifiScanner.ScanData[] {results3.getScanData()},
- messageCaptor.getAllValues().get(2));
- assertSingleScanCompletedMessage(requestId3, messageCaptor.getAllValues().get(3));
- } else {
- assertScanResultsMessage(requestId3,
- new WifiScanner.ScanData[] {results3.getScanData()},
- messageCaptor.getAllValues().get(0));
- assertSingleScanCompletedMessage(requestId3, messageCaptor.getAllValues().get(1));
- assertScanResultsMessage(requestId2,
- new WifiScanner.ScanData[] {results2.getScanData()},
- messageCaptor.getAllValues().get(2));
- assertSingleScanCompletedMessage(requestId2, messageCaptor.getAllValues().get(3));
- }
+ verifyMultipleSingleScanResults(handlerOrder, handler, requestId2, results2, requestId3,
+ results3);
assertEquals(mWifiMetrics.getOneshotScanCount(), 3);
assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 3);
@@ -821,6 +832,168 @@ public class WifiScanningServiceTest {
"results=" + results3.getRawScanResults().length);
}
+
+ /**
+ * Send a single scan request and then a second one satisfied by the first before the first
+ * completes. Verify that only one scan is scheduled.
+ */
+ @Test
+ public void sendSingleScanRequestWhilePreviousScanRunningAndMergeIntoFirstScan() {
+ // Split by frequency to make it easier to determine which results each request is expecting
+ ScanResults results24GHz = ScanResults.create(0, 2400, 2400, 2400, 2450);
+ ScanResults results5GHz = ScanResults.create(0, 5150, 5150, 5175);
+ ScanResults resultsBoth = ScanResults.merge(results24GHz, results5GHz);
+
+ WifiScanner.ScanSettings requestSettings1 = createRequest(WifiScanner.WIFI_BAND_BOTH, 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId1 = 12;
+ ScanResults results1 = resultsBoth;
+
+ WifiScanner.ScanSettings requestSettings2 = createRequest(WifiScanner.WIFI_BAND_24_GHZ, 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId2 = 13;
+ ScanResults results2 = results24GHz;
+
+
+ startServiceAndLoadDriver();
+
+ when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder handlerOrder = inOrder(handler);
+ InOrder nativeOrder = inOrder(mWifiScannerImpl);
+
+ // Run scan 1
+ sendSingleScanRequest(controlChannel, requestId1, requestSettings1, null);
+
+ mLooper.dispatchAll();
+ WifiNative.ScanEventHandler eventHandler = verifyStartSingleScan(nativeOrder,
+ computeSingleScanNativeSettings(requestSettings1));
+ verifySuccessfulResponse(handlerOrder, handler, requestId1);
+
+ // Queue scan 2 (will be folded into ongoing scan)
+ sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
+ mLooper.dispatchAll();
+ verifySuccessfulResponse(handlerOrder, handler, requestId2);
+
+ // dispatch scan 1 results
+ when(mWifiScannerImpl.getLatestSingleScanResults())
+ .thenReturn(resultsBoth.getScanData());
+ eventHandler.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+
+ mLooper.dispatchAll();
+ verifyMultipleSingleScanResults(handlerOrder, handler, requestId1, results1, requestId2,
+ results2);
+
+ assertEquals(mWifiMetrics.getOneshotScanCount(), 2);
+ assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 2);
+ }
+
+ /**
+ * Send a single scan request and then two more before the first completes, one of which is
+ * satisfied by the first scan. Verify that the first two complete together the second scan is
+ * just for the other scan.
+ */
+ @Test
+ public void sendMultipleSingleScanRequestWhilePreviousScanRunningAndMergeOneIntoFirstScan()
+ throws RemoteException {
+ // Split by frequency to make it easier to determine which results each request is expecting
+ ScanResults results2400 = ScanResults.create(0, 2400, 2400, 2400);
+ ScanResults results2450 = ScanResults.create(0, 2450);
+ ScanResults results1and3 = ScanResults.merge(results2400, results2450);
+
+ WifiScanner.ScanSettings requestSettings1 = createRequest(channelsToSpec(2400, 2450), 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId1 = 12;
+ WorkSource workSource1 = new WorkSource(1121);
+ ScanResults results1 = results1and3;
+
+ WifiScanner.ScanSettings requestSettings2 = createRequest(channelsToSpec(2450, 5175), 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId2 = 13;
+ WorkSource workSource2 = new WorkSource(Binder.getCallingUid()); // don't explicitly set
+ ScanResults results2 = ScanResults.create(0, 2450, 5175, 2450);
+
+ WifiScanner.ScanSettings requestSettings3 = createRequest(channelsToSpec(2400), 0,
+ 0, 20, WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN);
+ int requestId3 = 15;
+ WorkSource workSource3 = new WorkSource(2292);
+ ScanResults results3 = results2400;
+
+ startServiceAndLoadDriver();
+
+ when(mWifiScannerImpl.startSingleScan(any(WifiNative.ScanSettings.class),
+ any(WifiNative.ScanEventHandler.class))).thenReturn(true);
+
+ Handler handler = mock(Handler.class);
+ BidirectionalAsyncChannel controlChannel = connectChannel(handler);
+ InOrder handlerOrder = inOrder(handler);
+ InOrder nativeOrder = inOrder(mWifiScannerImpl);
+
+ // Run scan 1
+ sendSingleScanRequest(controlChannel, requestId1, requestSettings1, workSource1);
+
+ mLooper.dispatchAll();
+ WifiNative.ScanEventHandler eventHandler1 = verifyStartSingleScan(nativeOrder,
+ computeSingleScanNativeSettings(requestSettings1));
+ verifySuccessfulResponse(handlerOrder, handler, requestId1);
+ verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource1));
+
+
+ // Queue scan 2 (will not run because previous is in progress)
+ // uses uid of calling process
+ sendSingleScanRequest(controlChannel, requestId2, requestSettings2, null);
+ mLooper.dispatchAll();
+ verifySuccessfulResponse(handlerOrder, handler, requestId2);
+
+ // Queue scan 3 (will be merged into the active scan)
+ sendSingleScanRequest(controlChannel, requestId3, requestSettings3, workSource3);
+ mLooper.dispatchAll();
+ verifySuccessfulResponse(handlerOrder, handler, requestId3);
+
+ // dispatch scan 1 results
+ when(mWifiScannerImpl.getLatestSingleScanResults())
+ .thenReturn(results1and3.getScanData());
+ eventHandler1.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+
+ mLooper.dispatchAll();
+ verifyMultipleSingleScanResults(handlerOrder, handler, requestId1, results1, requestId3,
+ results3);
+ // only the requests know at the beginning of the scan get blamed
+ verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource1));
+ verify(mBatteryStats).noteWifiScanStartedFromSource(eq(workSource2));
+
+ // now that the first scan completed we expect the second and third ones to start
+ WifiNative.ScanEventHandler eventHandler2 = verifyStartSingleScan(nativeOrder,
+ computeSingleScanNativeSettings(requestSettings2));
+
+ // dispatch scan 2 and 3 results
+ when(mWifiScannerImpl.getLatestSingleScanResults())
+ .thenReturn(results2.getScanData());
+ eventHandler2.onScanStatus(WifiNative.WIFI_SCAN_RESULTS_AVAILABLE);
+
+ mLooper.dispatchAll();
+
+ verifyScanResultsRecieved(handlerOrder, handler, requestId2, results2.getScanData());
+ verifySingleScanCompletedRecieved(handlerOrder, handler, requestId2);
+ assertEquals(mWifiMetrics.getOneshotScanCount(), 3);
+ assertEquals(mWifiMetrics.getScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS), 3);
+
+ verify(mBatteryStats).noteWifiScanStoppedFromSource(eq(workSource2));
+
+ assertDumpContainsRequestLog("addSingleScanRequest", requestId1);
+ assertDumpContainsRequestLog("addSingleScanRequest", requestId2);
+ assertDumpContainsRequestLog("addSingleScanRequest", requestId3);
+ assertDumpContainsCallbackLog("singleScanResults", requestId1,
+ "results=" + results1.getRawScanResults().length);
+ assertDumpContainsCallbackLog("singleScanResults", requestId2,
+ "results=" + results2.getRawScanResults().length);
+ assertDumpContainsCallbackLog("singleScanResults", requestId3,
+ "results=" + results3.getRawScanResults().length);
+ }
+
private void doSuccessfulBackgroundScan(WifiScanner.ScanSettings requestSettings,
WifiNative.ScanSettings nativeSettings) {
startServiceAndLoadDriver();