blob: a3def8e03aac7e03fb726489984244e673d5c9eb [file] [log] [blame]
/*
* Copyright (C) 2021 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.cts.verifier.managedprovisioning;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationRequest;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.util.Log;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.android.cts.verifier.R;
import java.util.List;
import java.util.stream.Collectors;
/**
* Activity that checks whether it can obtain location. Asks for permission in case it is missing.
* Result is reported to whoever invoked it with startActivityForResult.
*/
public class LocationCheckerActivity extends Activity {
private static final String TAG = LocationCheckerActivity.class.getSimpleName();
public static final String ACTION_CHECK_LOCATION_PRIMARY =
"com.android.cts.verifier.managedprovisioning.CHECK_LOCATION_ACCESS_PRIMARY";
public static final String ACTION_CHECK_LOCATION_WORK =
"com.android.cts.verifier.managedprovisioning.CHECK_LOCATION_ACCESS_WORK";
public static final String WORK_ACTIVITY_ALIAS =
"com.android.cts.verifier.managedprovisioning.WorkLocationCheckerActivityAlias";
public static final String EXTRA_ERROR_ID = "extra-error-id";
public static final int LOCATION_PERMISSION_REQUEST = 125;
private static final int REQUEST_MAX_DURATION_MILLIS = 15000;
private List<String> mProviders;
private LocationManager mLocationManager;
private TextView mStatusText;
private final CancellationSignal mCancellationSignal = new CancellationSignal();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.location_checker);
mLocationManager = getSystemService(LocationManager.class);
mStatusText = findViewById(R.id.status_text);
if (hasLocationPermission()) {
requestCurrentLocation();
} else {
requestLocationPermission();
}
}
private void requestCurrentLocation() {
synchronized (this) {
mProviders = mLocationManager.getAllProviders().stream()
.filter(mLocationManager::isProviderEnabled)
.collect(Collectors.toList());
if (mProviders.isEmpty()) {
finish(R.string.provisioning_byod_location_no_provider);
return;
}
// Callback will be invoked with null if duration exceeded.
LocationRequest request = new LocationRequest.Builder(0)
.setDurationMillis(REQUEST_MAX_DURATION_MILLIS).build();
// Request location from all available providers.
for (String provider: mProviders) {
mLocationManager.getCurrentLocation(provider, request, mCancellationSignal,
getMainExecutor(), l -> onLocation(provider, l));
}
updateStatusLocked();
}
}
private void updateStatusLocked() {
String providers = String.join(", ", mProviders);
mStatusText.setText(getString(R.string.provisioning_byod_location_trying, providers));
}
private boolean hasLocationPermission() {
return ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED;
}
private void requestLocationPermission() {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
LOCATION_PERMISSION_REQUEST);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grants) {
// Test that the right permission was granted.
if (requestCode == LOCATION_PERMISSION_REQUEST) {
if (!permissions[0].equals(Manifest.permission.ACCESS_FINE_LOCATION)
|| grants[0] != PackageManager.PERMISSION_GRANTED
|| !hasLocationPermission()) {
Log.e(TAG, "The test needs location permission.");
finish(R.string.provisioning_byod_location_mode_enable_missing_permission);
return;
}
requestCurrentLocation();
}
}
private void onLocation(String provider, Location location) {
if (mCancellationSignal.isCanceled()) {
return;
} else if (location != null) {
mCancellationSignal.cancel();
finish(-1 /* no error */);
}
// location == null, provider wasn't able to get location, see if there are more providers
synchronized (this) {
mProviders.remove(provider);
if (mProviders.isEmpty()) {
finish(R.string.provisioning_byod_location_failed);
} else {
updateStatusLocked();
}
}
}
void finish(int messageId) {
Intent result = new Intent();
result.putExtra(EXTRA_ERROR_ID, messageId);
setResult(Activity.RESULT_OK, result);
finish();
}
}