in niap-cc/Permissions/Tester/app/src/main/java/com/android/certifications/niap/permissions/GmsPermissionTester.java [170:407]
public GmsPermissionTester(TestConfiguration configuration, Activity activity) {
super(configuration, activity);
mPermissionTasks = new HashMap<>();
mPermissionTasks.put(Manifest.permission.ACTIVITY_RECOGNITION,
new PermissionTest(false, () -> {
final String ACTIVITY_RECOGNITION_TEST = "ACTIVITY_RECOGNITION_TEST";
CountDownLatch[] latch = new CountDownLatch[1];
latch[0] = new CountDownLatch(1);
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
ActivityRecognitionResult result =
ActivityRecognitionResult.extractResult(
intent);
// The countdown on the latch should only occur if the provided
// intent includes a valid activity update.
if (result != null) {
mLogger.logDebug("Received a broadcast with the activity result: "
+ result.toString());
latch[0].countDown();
} else {
mLogger.logDebug(
"Received a broadcast with a null activity result");
}
}
};
mContext.registerReceiver(receiver,
new IntentFilter(ACTIVITY_RECOGNITION_TEST));
Intent intent = new Intent(ACTIVITY_RECOGNITION_TEST);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent,
0);
// The ActivityRecognitionClient will not throw a SecurityException if the
// caller does not have the ACTIVITY_RECOGNITION permission, instead activity
// updates will not be sent to the client without the permission.
ActivityRecognitionClient activityClient = ActivityRecognition.getClient(
mContext);
activityClient.requestActivityUpdates(1000, pendingIntent);
boolean broadcastReceived = false;
try {
broadcastReceived = latch[0].await(15, TimeUnit.SECONDS);
} catch (InterruptedException e) {
mLogger.logError("Caught an InterruptedException: ", e);
}
activityClient.removeActivityUpdates(pendingIntent);
mContext.unregisterReceiver(receiver);
if (!broadcastReceived) {
throw new SecurityException("An activity update was not received");
}
}));
mPermissionTasks.put(Manifest.permission.ACCESS_COARSE_LOCATION,
new PermissionTest(false, () -> {
final String ACCESS_COARSE_LOCATION_TEST = "ACCESS_COARSE_LOCATION_TEST";
CountDownLatch[] latch = new CountDownLatch[1];
latch[0] = new CountDownLatch(1);
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
LocationResult result = LocationResult.extractResult(intent);
// The countdown on the latch should only occur if the provided
// intent includes a valid location since additional updates can be sent
// without a location.
if (result != null) {
Location location = result.getLastLocation();
if (location != null) {
mLogger.logDebug(
"Received a lat,long of " + location.getLatitude()
+ ", "
+ location.getLongitude());
latch[0].countDown();
}
}
}
};
mContext.registerReceiver(receiver,
new IntentFilter(ACCESS_COARSE_LOCATION_TEST));
Intent intent = new Intent(ACCESS_COARSE_LOCATION_TEST);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent,
0);
LocationRequest locationRequest = LocationRequest.create().setPriority(
LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY).setInterval(1000);
FusedLocationProviderClient locationClient =
LocationServices.getFusedLocationProviderClient(mContext);
locationClient.requestLocationUpdates(locationRequest, pendingIntent);
boolean locationReceived = false;
try {
locationReceived = latch[0].await(30, TimeUnit.SECONDS);
} catch (InterruptedException e) {
mLogger.logError("Caught an InterruptedException: ", e);
}
locationClient.removeLocationUpdates(pendingIntent);
mContext.unregisterReceiver(receiver);
if (!locationReceived) {
throw new SecurityException("A location update was not received");
}
}));
mPermissionTasks.put(Manifest.permission.ACCESS_FINE_LOCATION,
new PermissionTest(false, () -> {
Task<Location> locationTask = LocationServices.getFusedLocationProviderClient(
mContext).getLastLocation();
try {
Tasks.await(locationTask, 5, TimeUnit.SECONDS);
Location location = locationTask.getResult();
if (location == null) {
throw new SecurityException("Unable to obtain the last location");
} else {
mLogger.logDebug(
"Received a lat,long of " + location.getLatitude() + ", "
+ location.getLongitude());
}
} catch (ExecutionException e) {
if (e.getCause() instanceof SecurityException) {
throw (SecurityException) e.getCause();
}
} catch (TimeoutException | InterruptedException e) {
throw new UnexpectedPermissionTestFailureException(e);
}
}));
mPermissionTasks.put(Manifest.permission.ACCESS_BACKGROUND_LOCATION,
new PermissionTest(false, () -> {
final String ACCESS_BACKGROUND_LOCATION_TEST =
"ACCESS_BACKGROUND_LOCATION_TEST";
CountDownLatch[] latch = new CountDownLatch[1];
latch[0] = new CountDownLatch(1);
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
LocationResult result = LocationResult.extractResult(intent);
// The countdown on the latch should only occur if the provided intent
// includes a valid location since additional updates can be sent
// without a location.
if (result != null) {
Location location = result.getLastLocation();
if (location != null) {
mLogger.logDebug(
"Received a lat,long of " + location.getLatitude()
+ ", "
+ location.getLongitude());
latch[0].countDown();
}
}
}
};
mContext.registerReceiver(receiver,
new IntentFilter(ACCESS_BACKGROUND_LOCATION_TEST));
Intent intent = new Intent(ACCESS_BACKGROUND_LOCATION_TEST);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent,
0);
GeofencingClient geofencingClient = LocationServices.getGeofencingClient(
mContext);
Geofence geofence = new Geofence.Builder().setRequestId(
"ACCESS_FINE_LOCATION_GEOFENCE_TEST").setCircularRegion(37.422136,
-122.084068,
1000)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
.setExpirationDuration(5000)
.build();
GeofencingRequest geofencingRequest =
new GeofencingRequest.Builder().setInitialTrigger(
GeofencingRequest.INITIAL_TRIGGER_ENTER).addGeofence(
geofence).build();
Task<Void> geofenceTask = geofencingClient.addGeofences(geofencingRequest,
pendingIntent);
try {
Tasks.await(geofenceTask);
geofenceTask.getResult();
} catch (ExecutionException e) {
// While the Geofencing Binder invocation will fail due to a
// SecurityException the ExecutionException does not contain the
// SecurityException as a cause, but it does contain the text from the
// SecurityException in the message.
if (e.getMessage().indexOf("SecurityException") != -1) {
throw new SecurityException(e);
}
throw new UnexpectedPermissionTestFailureException(e);
} catch (Exception e) {
throw new UnexpectedPermissionTestFailureException(e);
}
try {
latch[0].await(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new UnexpectedPermissionTestFailureException(e);
}
}));
mPermissionTasks.put(Manifest.permission.CAMERA, new PermissionTest(false, () -> {
CountDownLatch[] latch = new CountDownLatch[1];
latch[0] = new CountDownLatch(1);
Detector<Integer> detector = new Detector() {
@Override
public SparseArray<Integer> detect(Frame frame) {
mLogger.logDebug("detect: frame = " + frame);
latch[0].countDown();
return null;
}
};
Detector.Processor<Integer> processor = new Detector.Processor() {
@Override
public void receiveDetections(Detector.Detections detections) {
mLogger.logDebug("receiveDetections: detections = " + detections);
}
@Override
public void release() {
mLogger.logDebug("release");
}
};
detector.setProcessor(processor);
CameraSource cameraSource = new CameraSource.Builder(mContext, detector).setFacing(
CameraSource.CAMERA_FACING_BACK).setAutoFocusEnabled(true).setRequestedFps(
1).setRequestedPreviewSize(1024, 768).build();
try {
cameraSource.start();
} catch (IOException e) {
throw new UnexpectedPermissionTestFailureException(e);
} catch (RuntimeException e) {
if (e.getMessage().contains("Fail to connect to camera service")) {
// A RuntimeException occurs when the CAMERA permission check fails; wrap the
// exception in a SecurityException to fail the API call for this test.
throw new SecurityException(e);
}
throw e;
} finally {
cameraSource.release();
}
}));
}