Show user dialog for BT connection and phonebook access

Show user dialog for incoming BT connection requests from unknown
devices. Move phone book access permission dialog from bluetooth to settings.
The permision dialog pops up to the screen properly instead of
always as notification. AT+CPBR will also use the permission dialog
to ask for user permission.

bug 4489572

Change-Id: Ic1e74b2a9416a462cac4f519240a313691da90c4
This commit is contained in:
Matthew Xie
2011-06-27 18:21:25 -07:00
parent 29865fed4d
commit dbed12020c
6 changed files with 455 additions and 0 deletions

View File

@@ -0,0 +1,232 @@
/*
* Copyright (C) 2011 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.bluetooth;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.preference.Preference;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Button;
import android.widget.CompoundButton.OnCheckedChangeListener;
import com.android.internal.app.AlertActivity;
import com.android.internal.app.AlertController;
import com.android.settings.R;
/**
* BluetoothPermissionActivity shows a dialog for accepting incoming
* profile connection request from untrusted devices.
* It is also used to show a dialogue for accepting incoming phonebook
* read request. The request could be initiated by PBAP PCE or by HF AT+CPBR.
*/
public class BluetoothPermissionActivity extends AlertActivity implements
DialogInterface.OnClickListener, Preference.OnPreferenceChangeListener {
private static final String TAG = "BluetoothPermissionActivity";
private static final boolean DEBUG = Utils.D;
private View mView;
private TextView messageView;
private Button mOkButton;
private BluetoothDevice mDevice;
private CheckBox mAlwaysAllowed;
private boolean mAlwaysAllowedValue = true;
private String mReturnPackage = null;
private String mReturnClass = null;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (mDevice.equals(device)) dismissDialog();
}
}
};
private void dismissDialog() {
this.dismiss();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent i = getIntent();
String action = i.getAction();
mDevice = i.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mReturnPackage = i.getStringExtra(BluetoothDevice.EXTRA_PACKAGE_NAME);
mReturnClass = i.getStringExtra(BluetoothDevice.EXTRA_CLASS_NAME);
if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST)) {
mDevice = i.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (i.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS) ==
BluetoothDevice.REQUEST_TYPE_PROFILE_CONNECTION) {
showConnectionDialog();
} else {
showPbapDialog();
}
} else {
Log.e(TAG, "Error: this activity may be started only with intent "
+ "ACTION_CONNECTION_ACCESS_REQUEST");
finish();
}
registerReceiver(mReceiver,
new IntentFilter(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL));
}
private void showConnectionDialog() {
final AlertController.AlertParams p = mAlertParams;
p.mIconId = android.R.drawable.ic_dialog_info;
p.mTitle = getString(R.string.bluetooth_connection_permission_request);
p.mView = createConnectionDialogView();
p.mPositiveButtonText = getString(R.string.yes);
p.mPositiveButtonListener = this;
p.mNegativeButtonText = getString(R.string.no);
p.mNegativeButtonListener = this;
mOkButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
setupAlert();
}
private void showPbapDialog() {
final AlertController.AlertParams p = mAlertParams;
p.mIconId = android.R.drawable.ic_dialog_info;
p.mTitle = getString(R.string.bluetooth_phonebook_request);
p.mView = createPbapDialogView();
p.mPositiveButtonText = getString(android.R.string.yes);
p.mPositiveButtonListener = this;
p.mNegativeButtonText = getString(android.R.string.no);
p.mNegativeButtonListener = this;
mOkButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
setupAlert();
}
private String createConnectionDisplayText() {
String mRemoteName = mDevice != null ? mDevice.getName() : null;
if (mRemoteName == null) mRemoteName = getString(R.string.unknown);
String mMessage1 = getString(R.string.bluetooth_connection_dialog_text,
mRemoteName);
return mMessage1;
}
private String createPbapDisplayText() {
String mRemoteName = mDevice != null ? mDevice.getName() : null;
if (mRemoteName == null) mRemoteName = getString(R.string.unknown);
String mMessage1 = getString(R.string.bluetooth_pb_acceptance_dialog_text,
mRemoteName, mRemoteName);
return mMessage1;
}
private View createConnectionDialogView() {
mView = getLayoutInflater().inflate(R.layout.bluetooth_connection_access, null);
messageView = (TextView)mView.findViewById(R.id.message);
messageView.setText(createConnectionDisplayText());
return mView;
}
private View createPbapDialogView() {
mView = getLayoutInflater().inflate(R.layout.bluetooth_pb_access, null);
messageView = (TextView)mView.findViewById(R.id.message);
messageView.setText(createPbapDisplayText());
mAlwaysAllowed = (CheckBox)mView.findViewById(R.id.bluetooth_pb_alwaysallowed);
mAlwaysAllowed.setChecked(true);
mAlwaysAllowed.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
mAlwaysAllowedValue = true;
} else {
mAlwaysAllowedValue = false;
}
}
});
return mView;
}
private void onPositive() {
if (DEBUG) Log.d(TAG, "onPositive mAlwaysAllowedValue: " + mAlwaysAllowedValue);
sendIntentToReceiver(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY, true,
BluetoothDevice.EXTRA_ALWAYS_ALLOWED, mAlwaysAllowedValue);
finish();
}
private void onNegative() {
if (DEBUG) Log.d(TAG, "onNegative mAlwaysAllowedValue: " + mAlwaysAllowedValue);
sendIntentToReceiver(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY, false,
null, false // dummy value, no effect since last param is null
);
finish();
}
private void sendIntentToReceiver(final String intentName, final boolean allowed,
final String extraName, final boolean extraValue) {
Intent intent = new Intent(intentName);
if (mReturnPackage != null && mReturnClass != null) {
intent.setClassName(mReturnPackage, mReturnClass);
}
intent.putExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT,
allowed ? BluetoothDevice.CONNECTION_ACCESS_YES :
BluetoothDevice.CONNECTION_ACCESS_NO);
if (extraName != null) {
intent.putExtra(extraName, extraValue);
}
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
sendBroadcast(intent, android.Manifest.permission.BLUETOOTH_ADMIN);
}
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
onPositive();
break;
case DialogInterface.BUTTON_NEGATIVE:
onNegative();
break;
default:
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
public boolean onPreferenceChange(Preference preference, Object newValue) {
return true;
}
}