blob: 54c17312def0a8fb88a53a2e1dba9686b3b6db52 [file] [log] [blame]
/*
* Copyright (C) 2019 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.car.settings.security;
import android.annotation.Nullable;
import android.bluetooth.BluetoothDevice;
import android.car.Car;
import android.car.CarNotConnectedException;
import android.car.drivingstate.CarUxRestrictions;
import android.car.trust.CarTrustAgentEnrollmentManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.view.WindowManagerGlobal;
import android.widget.Toast;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.car.settings.R;
import com.android.car.settings.common.FragmentController;
import com.android.car.settings.common.Logger;
import com.android.car.settings.common.PreferenceController;
import com.android.settingslib.utils.ThreadUtils;
/**
* Business logic when user click on add trusted device, a new screen will be shown and user can add
* a trusted device using CarTrustAgentEnrollmentManager, confirm pairing code dialog base on that.
* TODO(wentingzhai): test the enrollment process when CarTrustAgentEnrollment Service is done.
*
*/
public class AddTrustedDevicePreferenceController extends PreferenceController<Preference> {
private static final Logger LOG = new Logger(AddTrustedDevicePreferenceController.class);
private final SharedPreferences mPrefs;
private final Car mCar;
private BluetoothDevice mBluetoothDevice;
@Nullable
private CarTrustAgentEnrollmentManager mCarTrustAgentEnrollmentManager;
private final CarTrustAgentEnrollmentManager.CarTrustAgentEnrollmentCallback
mCarTrustAgentEnrollmentCallback =
new CarTrustAgentEnrollmentManager.CarTrustAgentEnrollmentCallback() {
@Override
public void onEnrollmentHandshakeFailure(BluetoothDevice device, int errorCode) {
LOG.e("Trust agent service time out");
}
@Override
public void onAuthStringAvailable(BluetoothDevice device, String authString) {
ConfirmPairingCodeDialog dialog = ConfirmPairingCodeDialog.newInstance(
device.getName(), authString);
dialog.setConfirmPairingCodeListener(mConfirmParingCodeListener);
getFragmentController().showDialog(dialog, ConfirmPairingCodeDialog.TAG);
}
@Override
public void onEscrowTokenAdded(long handle) {
try {
// User need to enter the correct authentication of the car to activate the
// added token.
WindowManagerGlobal.getWindowManagerService().lockNow(/* options= */ null);
} catch (RemoteException e) {
LOG.e(e.getMessage(), e);
}
}
@Override
public void onTrustRevoked(long handle, boolean success) {
}
@Override
public void onEscrowTokenActiveStateChanged(long handle, boolean active) {
if (active) {
ThreadUtils.postOnMainThread(
() -> mPrefs.edit().putString(String.valueOf(handle),
mBluetoothDevice.getName()).apply());
Toast.makeText(getContext(),
getContext().getString(
R.string.trusted_device_success_enrollment_toast,
mBluetoothDevice.getName()),
Toast.LENGTH_LONG).show();
} else {
LOG.d(handle + " has been deactivated");
}
try {
mCarTrustAgentEnrollmentManager.stopEnrollmentAdvertising();
mCarTrustAgentEnrollmentManager.setBleCallback(null);
mCarTrustAgentEnrollmentManager.setEnrollmentCallback(null);
} catch (CarNotConnectedException e) {
LOG.e(e.getMessage(), e);
}
getFragmentController().goBack();
}
};
private final CarTrustAgentEnrollmentManager.CarTrustAgentBleCallback
mCarTrustAgentBleCallback =
new CarTrustAgentEnrollmentManager.CarTrustAgentBleCallback() {
@Override
public void onBleEnrollmentDeviceConnected(BluetoothDevice device) {
mBluetoothDevice = device;
try {
mCarTrustAgentEnrollmentManager.initiateEnrollmentHandshake(
mBluetoothDevice);
} catch (CarNotConnectedException e) {
LOG.e(e.getMessage());
}
}
@Override
public void onBleEnrollmentDeviceDisconnected(BluetoothDevice device) {
LOG.d("Bluetooth device " + device.getName() + "has been disconnected");
mBluetoothDevice = null;
}
@Override
public void onEnrollmentAdvertisingStarted() {
LOG.d("Advertising started successfully");
}
@Override
public void onEnrollmentAdvertisingFailed(int errorCode) {
getFragmentController().goBack();
}
};
@VisibleForTesting
final ConfirmPairingCodeDialog.ConfirmPairingCodeListener mConfirmParingCodeListener =
new ConfirmPairingCodeDialog.ConfirmPairingCodeListener() {
public void onConfirmPairingCode() {
try {
mCarTrustAgentEnrollmentManager.enrollmentHandshakeAccepted();
} catch (CarNotConnectedException e) {
LOG.e(e.getMessage(), e);
}
}
public void onDialogCancelled() {
getFragmentController().goBack();
}
};
public AddTrustedDevicePreferenceController(Context context, String preferenceKey,
FragmentController fragmentController, CarUxRestrictions uxRestrictions) {
super(context, preferenceKey, fragmentController, uxRestrictions);
mCar = Car.createCar(context);
mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
try {
mCarTrustAgentEnrollmentManager = (CarTrustAgentEnrollmentManager) mCar.getCarManager(
Car.CAR_TRUST_AGENT_ENROLLMENT_SERVICE);
} catch (CarNotConnectedException e) {
LOG.e(e.getMessage(), e);
}
}
@Override
protected void checkInitialized() {
if (mCarTrustAgentEnrollmentManager == null) {
throw new IllegalStateException("mCarTrustAgentEnrollmentManager is null.");
}
}
@Override
protected Class<Preference> getPreferenceType() {
return Preference.class;
}
@Override
public boolean handlePreferenceClicked(Preference preference) {
try {
mCarTrustAgentEnrollmentManager.startEnrollmentAdvertising();
} catch (CarNotConnectedException e) {
LOG.e(e.getMessage(), e);
}
// return false to make sure AddTrustedDeviceProgressFragment will show up.
return false;
}
@Override
protected void onStartInternal() {
try {
mCarTrustAgentEnrollmentManager.setEnrollmentCallback(
mCarTrustAgentEnrollmentCallback);
mCarTrustAgentEnrollmentManager.setBleCallback(mCarTrustAgentBleCallback);
} catch (CarNotConnectedException e) {
LOG.e(e.getMessage(), e);
}
ConfirmPairingCodeDialog pairingCodeDialog =
(ConfirmPairingCodeDialog) getFragmentController().findDialogByTag(
ConfirmPairingCodeDialog.TAG);
if (pairingCodeDialog != null) {
pairingCodeDialog.setConfirmPairingCodeListener(mConfirmParingCodeListener);
}
}
}