Merge "Add bt anomaly action in testing app" into oc-mr1-dev

This commit is contained in:
TreeHugger Robot
2017-08-25 01:38:53 +00:00
committed by Android (Google) Code Review
6 changed files with 309 additions and 4 deletions

View File

@@ -14,8 +14,13 @@
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.settings.anomaly.tester">
package="com.android.settings.anomaly.tester">
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<application
android:allowBackup="false"
android:label="@string/app_name"
@@ -29,6 +34,10 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".service.AnomalyService"
android:exported="false"/>
</application>
</manifest>

View File

@@ -35,16 +35,21 @@
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content"
android:hint="Threshold(ms)"/>
android:hint="Threshold(ms)"
android:text="3000"
android:inputType="number"/>
<EditText
android:id="@+id/bluetooth_run_time"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content"
android:hint="Run time(ms)"/>
android:hint="Run time(ms)"
android:text="6000"
android:inputType="number"/>
<Button
android:id="@+id/bluetooth_button"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"

View File

@@ -15,18 +15,92 @@
package com.android.settings.anomaly.tester;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.android.settings.anomaly.tester.service.AnomalyService;
import com.android.settings.anomaly.tester.utils.AnomalyActions;
import com.android.settings.anomaly.tester.utils.AnomalyPolicyBuilder;
/**
* Main activity to control and start anomaly
*/
public class AnomalyActivity extends Activity {
private static final String TAG = AnomalyActivity.class.getSimpleName();
public static final String KEY_TARGET_BUTTON = "target_button";
private AnomalyResultReceiver mResultReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mResultReceiver = new AnomalyResultReceiver(new Handler());
}
public void startBluetoothAnomaly(View view) {
// Add in future cl
try {
// Enable anomaly detection and change the threshold
final String config = new AnomalyPolicyBuilder()
.addPolicy(AnomalyPolicyBuilder.KEY_ANOMALY_DETECTION_ENABLED, true)
.addPolicy(AnomalyPolicyBuilder.KEY_BLUETOOTH_SCAN_DETECTION_ENABLED, true)
.addPolicy(AnomalyPolicyBuilder.KEY_BLUETOOTH_SCAN_THRESHOLD,
getValueFromEditText(R.id.bluetooth_threshold))
.build();
Settings.Global.putString(getContentResolver(),
Settings.Global.ANOMALY_DETECTION_CONSTANTS, config);
// Start the anomaly service
Intent intent = new Intent(this, AnomalyService.class);
intent.putExtra(AnomalyActions.KEY_ACTION, AnomalyActions.ACTION_BLE_SCAN_UNOPTIMIZED);
intent.putExtra(AnomalyActions.KEY_DURATION_MS,
getValueFromEditText(R.id.bluetooth_run_time));
intent.putExtra(AnomalyActions.KEY_RESULT_RECEIVER, mResultReceiver);
intent.putExtra(KEY_TARGET_BUTTON, view.getId());
startService(intent);
view.setEnabled(false);
} catch (NumberFormatException e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
}
private long getValueFromEditText(final int id) throws NumberFormatException {
final EditText editText = findViewById(id);
if (editText != null) {
final long value = Long.parseLong(editText.getText().toString());
if (value > 0) {
return value;
}
}
throw new NumberFormatException("Number should be positive");
}
private class AnomalyResultReceiver extends ResultReceiver {
public AnomalyResultReceiver(Handler handler) {
super(handler);
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
final Button button = findViewById(resultData.getInt(KEY_TARGET_BUTTON));
if (button != null) {
button.setEnabled(true);
}
}
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.anomaly.tester.service;
import android.annotation.Nullable;
import android.app.IntentService;
import android.content.Intent;
import android.os.ResultReceiver;
import com.android.settings.anomaly.tester.utils.AnomalyActions;
/**
* Service to run the anomaly action
*/
public class AnomalyService extends IntentService {
private static final String TAG = AnomalyService.class.getSimpleName();
public AnomalyService() {
super(AnomalyService.class.getSimpleName());
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
final String action = intent.getStringExtra(AnomalyActions.KEY_ACTION);
final long durationMs = intent.getLongExtra(AnomalyActions.KEY_DURATION_MS, 0);
final ResultReceiver resultReceiver = intent.getParcelableExtra(
AnomalyActions.KEY_RESULT_RECEIVER);
AnomalyActions.doAction(this, action, durationMs);
if (resultReceiver != null) {
resultReceiver.send(0 /* resultCode */, intent.getExtras());
}
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.anomaly.tester.utils;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.util.Log;
import java.util.List;
/**
* Actions to generate anomaly.
*/
public class AnomalyActions {
private static final String TAG = AnomalyActions.class.getSimpleName();
public static final String KEY_ACTION = "action";
public static final String KEY_DURATION_MS = "duration_ms";
public static final String KEY_RESULT_RECEIVER = "result_receiver";
public static final String ACTION_BLE_SCAN_UNOPTIMIZED = "action.ble_scan_unoptimized";
public static void doAction(Context ctx, String actionCode, long durationMs) {
if (actionCode == null) {
Log.e(TAG, "Intent was missing action.");
return;
}
switch (actionCode) {
case ACTION_BLE_SCAN_UNOPTIMIZED:
doUnoptimizedBleScan(ctx, durationMs);
break;
default:
Log.e(TAG, "Intent had invalid action");
}
}
private static void doUnoptimizedBleScan(Context ctx, long durationMs) {
ScanSettings scanSettings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
// perform ble scanning
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled() ) {
Log.e(TAG, "Device does not support Bluetooth or Bluetooth not enabled");
return;
}
BluetoothLeScanner bleScanner = bluetoothAdapter.getBluetoothLeScanner();
if (bleScanner == null) {
Log.e(TAG, "Cannot access BLE scanner");
return;
}
ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
Log.v(TAG, "called onScanResult");
}
@Override
public void onScanFailed(int errorCode) {
Log.v(TAG, "called onScanFailed");
}
@Override
public void onBatchScanResults(List<ScanResult> results) {
Log.v(TAG, "called onBatchScanResults");
}
};
bleScanner.startScan(null, scanSettings, scanCallback);
try {
Thread.sleep(durationMs);
} catch (InterruptedException e) {
Log.e(TAG, "Thread couldn't sleep for " + durationMs, e);
}
bleScanner.stopScan(scanCallback);
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.anomaly.tester.utils;
import java.util.HashMap;
import java.util.Map;
/**
* Builder to build the anomaly policy string, used in {@link android.provider.Settings.Global}
*
* @see android.provider.Settings.Global#ANOMALY_DETECTION_CONSTANTS
*/
public class AnomalyPolicyBuilder {
public static final String KEY_ANOMALY_DETECTION_ENABLED = "anomaly_detection_enabled";
public static final String KEY_WAKELOCK_DETECTION_ENABLED = "wakelock_enabled";
public static final String KEY_WAKEUP_ALARM_DETECTION_ENABLED = "wakeup_alarm_enabled";
public static final String KEY_BLUETOOTH_SCAN_DETECTION_ENABLED = "bluetooth_scan_enabled";
public static final String KEY_WAKELOCK_THRESHOLD = "wakelock_threshold";
public static final String KEY_WAKEUP_ALARM_THRESHOLD = "wakeup_alarm_threshold";
public static final String KEY_BLUETOOTH_SCAN_THRESHOLD = "bluetooth_scan_threshold";
public static final String DELIM = ",";
private Map<String, String> mValues;
public AnomalyPolicyBuilder() {
mValues = new HashMap<>();
}
public AnomalyPolicyBuilder addPolicy(String key, String value) {
mValues.put(key, value);
return this;
}
public AnomalyPolicyBuilder addPolicy(String key, long value) {
mValues.put(key, Long.toString(value));
return this;
}
public AnomalyPolicyBuilder addPolicy(String key, boolean value) {
mValues.put(key, value ? "true" : "false");
return this;
}
public String build() {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : mValues.entrySet()) {
sb.append(entry.getKey() + "=" + entry.getValue() + DELIM);
}
if (sb.length() != 0) {
return sb.substring(0, sb.length() - 1);
} else {
return "";
}
}
}