diff options
-rw-r--r-- | AndroidManifest.xml | 20 | ||||
-rw-r--r-- | res/layout/bluetooth_connection_access.xml | 40 | ||||
-rw-r--r-- | res/layout/bluetooth_pb_access.xml | 48 | ||||
-rw-r--r-- | res/layout/vpn_dialog.xml | 24 | ||||
-rw-r--r-- | res/values/strings.xml | 11 | ||||
-rw-r--r-- | res/values/styles.xml | 5 | ||||
-rw-r--r-- | src/com/android/settings/TrustedCredentialsSettings.java | 5 | ||||
-rw-r--r-- | src/com/android/settings/bluetooth/BluetoothPermissionActivity.java | 232 | ||||
-rw-r--r-- | src/com/android/settings/bluetooth/BluetoothPermissionRequest.java | 107 | ||||
-rw-r--r-- | src/com/android/settings/vpn2/VpnDialog.java | 11 | ||||
-rw-r--r-- | src/com/android/settings/vpn2/VpnSettings.java | 52 |
11 files changed, 524 insertions, 31 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 5b6d24a..ff4f63e 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -23,6 +23,7 @@ <uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> @@ -981,6 +982,25 @@ </intent-filter> </receiver> + <receiver android:name=".bluetooth.BluetoothPermissionRequest"> + <intent-filter> + <action android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST" /> + <action android:name="android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL" /> + </intent-filter> + </receiver> + + <activity android:name=".bluetooth.BluetoothPermissionActivity" + android:label="@string/bluetooth_connection_permission_request" + android:excludeFromRecents="true" + android:permission="android.permission.BLUETOOTH_ADMIN" + android:theme="@*android:style/Theme.Holo.Dialog.Alert"> + <intent-filter> + <action android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST" /> + <action android:name="android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + <activity android:name="ActivityPicker" android:label="@string/activity_picker_label" android:theme="@*android:style/Theme.Dialog.Alert" diff --git a/res/layout/bluetooth_connection_access.xml b/res/layout/bluetooth_connection_access.xml new file mode 100644 index 0000000..1e74162 --- /dev/null +++ b/res/layout/bluetooth_connection_access.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 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. +*/ +--> + +<ScrollView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="match_parent" + android:layout_width="match_parent"> + + <LinearLayout + android:layout_height="match_parent" + android:layout_width="match_parent" + android:orientation="vertical"> + + <TextView + android:id="@+id/message" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginLeft="20dip" + android:layout_marginRight="20dip" + android:gravity="center_horizontal" + android:textAppearance="?android:attr/textAppearanceMedium" /> + </LinearLayout> + +</ScrollView> diff --git a/res/layout/bluetooth_pb_access.xml b/res/layout/bluetooth_pb_access.xml new file mode 100644 index 0000000..80f78a6 --- /dev/null +++ b/res/layout/bluetooth_pb_access.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2009, 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. +*/ +--> + +<ScrollView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="match_parent" + android:layout_width="match_parent"> + + <LinearLayout + android:layout_height="match_parent" + android:layout_width="match_parent" + android:orientation="vertical"> + + <TextView + android:id="@+id/message" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginLeft="20dip" + android:layout_marginRight="20dip" + android:gravity="center_horizontal" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <CheckBox android:id="@+id/bluetooth_pb_alwaysallowed" + style="?android:attr/textAppearanceMedium" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="2dip" + android:text="@string/bluetooth_pb_alwaysallowed" /> + + </LinearLayout> + +</ScrollView> diff --git a/res/layout/vpn_dialog.xml b/res/layout/vpn_dialog.xml index a4bb216..ffbfd4d 100644 --- a/res/layout/vpn_dialog.xml +++ b/res/layout/vpn_dialog.xml @@ -20,7 +20,7 @@ <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:padding="5mm"> + android:padding="3mm"> <LinearLayout android:id="@+id/editor" android:layout_width="match_parent" @@ -30,7 +30,7 @@ <TextView style="@style/vpn_label" android:text="@string/vpn_name"/> <EditText style="@style/vpn_value" android:id="@+id/name" - android:singleLine="true"/> + android:inputType="textCapWords"/> <TextView style="@style/vpn_label" android:text="@string/vpn_type"/> <Spinner style="@style/vpn_value" android:id="@+id/type" @@ -38,11 +38,11 @@ android:entries="@array/vpn_types"/> <TextView style="@style/vpn_label" android:text="@string/vpn_server"/> - <EditText style="@style/vpn_value" android:id="@+id/server" - android:singleLine="true"/> + <EditText style="@style/vpn_value" android:id="@+id/server"/> <CheckBox style="@style/vpn_value" android:id="@+id/mppe" android:text="@string/vpn_mppe" + android:singleLine="false" android:visibility="gone"/> <LinearLayout android:id="@+id/l2tp" @@ -52,24 +52,27 @@ android:visibility="gone"> <TextView style="@style/vpn_label" android:text="@string/vpn_l2tp_secret"/> <EditText style="@style/vpn_value" android:id="@+id/l2tp_secret" - android:singleLine="true" android:password="true" android:hint="@string/vpn_not_used"/> </LinearLayout> - <LinearLayout android:id="@+id/ipsec_psk" + <LinearLayout android:id="@+id/ipsec_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:visibility="gone"> <TextView style="@style/vpn_label" android:text="@string/vpn_ipsec_identifier"/> <EditText style="@style/vpn_value" android:id="@+id/ipsec_identifier" - android:singleLine="true" android:hint="@string/vpn_not_used"/> + </LinearLayout> + <LinearLayout android:id="@+id/ipsec_psk" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:visibility="gone"> <TextView style="@style/vpn_label" android:text="@string/vpn_ipsec_secret"/> <EditText style="@style/vpn_value" android:id="@+id/ipsec_secret" - android:singleLine="true" android:password="true"/> </LinearLayout> @@ -111,15 +114,14 @@ android:visibility="gone"> <TextView style="@style/vpn_label" android:text="@string/vpn_username"/> - <EditText style="@style/vpn_value" android:id="@+id/username" - android:singleLine="true"/> + <EditText style="@style/vpn_value" android:id="@+id/username"/> <TextView style="@style/vpn_label" android:text="@string/vpn_password"/> <EditText style="@style/vpn_value" android:id="@+id/password" - android:singleLine="true" android:password="true"/> <CheckBox style="@style/vpn_value" android:id="@+id/save_login" + android:singleLine="false" android:text="@string/vpn_save_login"/> </LinearLayout> </LinearLayout> diff --git a/res/values/strings.xml b/res/values/strings.xml index 364ae3e..0378aeb 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -295,6 +295,15 @@ <!-- Bluetooth connection permission Alert Activity text [CHAR LIMIT=none]--> <string name="bluetooth_connection_dialog_text">"Do you want to connect to \u0022<xliff:g id="device_name">%1$s</xliff:g>\u0022?"</string> + <!-- Activity label of BluetoothPbPermissionActivity, also used as Strings in the permission dialog [CHAR LIMIT=none] --> + <string name="bluetooth_phonebook_request">"Phone book request"</string> + + <!-- Bluetooth phone book permission Alert Activity text [CHAR LIMIT=none] --> + <string name="bluetooth_pb_acceptance_dialog_text">%1$s would like to access your contacts and call history. Give access to %2$s?</string> + + <!-- Bluetooth phone book permission Alert Activity checkbox text [CHAR LIMIT=none] --> + <string name="bluetooth_pb_alwaysallowed">Always allowed?</string> + <!-- Date & time settings screen title --> <string name="date_and_time">Date & time settings</string> <!-- Date/time settings. Summary of the checkbox for choosing between 12 hour time or 24 hour time. Sample of 12-hour time --> @@ -3447,7 +3456,7 @@ found in the list of installed applications.</string> <!-- Checkbox label to save the username and the password for a VPN network. [CHAR LIMIT=40] --> <string name="vpn_save_login">Save account information</string> - <!-- Hint for an optional input of a VPN network. [CHAR LIMIT=40] --> + <!-- Hint for not filling an optional field in a VPN configuration. [CHAR LIMIT=40] --> <string name="vpn_not_used">(not used)</string> <!-- Option to not use a CA certificate to verify the VPN server. [CHAR LIMIT=40] --> <string name="vpn_no_ca_cert">(do not verify server)</string> diff --git a/res/values/styles.xml b/res/values/styles.xml index 0f73abf..d7f8d9b 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -143,12 +143,15 @@ <style name="vpn_label"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> - <item name="android:textSize">14sp</item> + <item name="android:textSize">16sp</item> </style> <style name="vpn_value"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> + <item name="android:textSize">18sp</item> + <item name="android:singleLine">true</item> + <item name="android:paddingBottom">1mm</item> </style> <style name="InputMethodPreferenceStyle"> diff --git a/src/com/android/settings/TrustedCredentialsSettings.java b/src/com/android/settings/TrustedCredentialsSettings.java index 55a0010..687663a 100644 --- a/src/com/android/settings/TrustedCredentialsSettings.java +++ b/src/com/android/settings/TrustedCredentialsSettings.java @@ -251,8 +251,9 @@ public class TrustedCredentialsSettings extends Fragment { mCertHolders.addAll(certHolders); notifyDataSetChanged(); View content = mTabHost.getTabContentView(); - content.findViewById(mTab.mProgress).setVisibility(View.GONE); - content.findViewById(mTab.mList).setVisibility(View.VISIBLE); + mProgressBar.setVisibility(View.GONE); + mList.setVisibility(View.VISIBLE); + mProgressBar.setProgress(0); } } } diff --git a/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java b/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java new file mode 100644 index 0000000..1a0965c --- /dev/null +++ b/src/com/android/settings/bluetooth/BluetoothPermissionActivity.java @@ -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; + } +} diff --git a/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java b/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java new file mode 100644 index 0000000..c769ba6 --- /dev/null +++ b/src/com/android/settings/bluetooth/BluetoothPermissionRequest.java @@ -0,0 +1,107 @@ +/* + * 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.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.bluetooth.BluetoothDevice; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.PowerManager; +import android.util.Log; + +import com.android.settings.R; + +/** + * BluetoothPermissionRequest is a receiver to receive Bluetooth connection + * access request. + */ +public final class BluetoothPermissionRequest extends BroadcastReceiver { + + private static final String TAG = "BluetoothPermissionRequest"; + private static final boolean DEBUG = Utils.V; + public static final int NOTIFICATION_ID = android.R.drawable.stat_sys_data_bluetooth; + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + + if (DEBUG) Log.d(TAG, "onReceive"); + + if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST)) { + // convert broadcast intent into activity intent (same action string) + BluetoothDevice device = + intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + int requestType = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, + BluetoothDevice.REQUEST_TYPE_PROFILE_CONNECTION); + String returnPackage = intent.getStringExtra(BluetoothDevice.EXTRA_PACKAGE_NAME); + String returnClass = intent.getStringExtra(BluetoothDevice.EXTRA_CLASS_NAME); + + Intent connectionAccessIntent = new Intent(action); + connectionAccessIntent.setClass(context, BluetoothPermissionActivity.class); + connectionAccessIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + connectionAccessIntent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, requestType); + connectionAccessIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); + connectionAccessIntent.putExtra(BluetoothDevice.EXTRA_PACKAGE_NAME, returnPackage); + connectionAccessIntent.putExtra(BluetoothDevice.EXTRA_CLASS_NAME, returnClass); + + String deviceAddress = device != null ? device.getAddress() : null; + + PowerManager powerManager = + (PowerManager) context.getSystemService(Context.POWER_SERVICE); + + if (powerManager.isScreenOn() && + LocalBluetoothPreferences.shouldShowDialogInForeground(context, deviceAddress) ) { + context.startActivity(connectionAccessIntent); + } else { + // Put up a notification that leads to the dialog + + // Create an intent triggered by clicking on the + // "Clear All Notifications" button + + Intent deleteIntent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY); + deleteIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); + deleteIntent.putExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, + BluetoothDevice.CONNECTION_ACCESS_NO); + + Notification notification = new Notification(android.R.drawable.stat_sys_data_bluetooth, + context.getString(R.string.bluetooth_connection_permission_request), + System.currentTimeMillis()); + String deviceName = device != null ? device.getName() : null; + notification.setLatestEventInfo(context, + context.getString(R.string.bluetooth_connection_permission_request), + context.getString(R.string.bluetooth_connection_notif_message, deviceName), + PendingIntent.getActivity(context, 0, connectionAccessIntent, 0)); + notification.flags = Notification.FLAG_AUTO_CANCEL | + Notification.FLAG_ONLY_ALERT_ONCE; + notification.defaults = Notification.DEFAULT_SOUND; + notification.deleteIntent = PendingIntent.getBroadcast(context, 0, deleteIntent, 0); + + NotificationManager notificationManager = + (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + notificationManager.notify(NOTIFICATION_ID, notification); + } + } else if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL)) { + // Remove the notification + NotificationManager manager = (NotificationManager) context + .getSystemService(Context.NOTIFICATION_SERVICE); + manager.cancel(NOTIFICATION_ID); + } + } +} diff --git a/src/com/android/settings/vpn2/VpnDialog.java b/src/com/android/settings/vpn2/VpnDialog.java index b3609a6..4f9d0a2 100644 --- a/src/com/android/settings/vpn2/VpnDialog.java +++ b/src/com/android/settings/vpn2/VpnDialog.java @@ -197,6 +197,7 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen // First, hide everything. mMppe.setVisibility(View.GONE); mView.findViewById(R.id.l2tp).setVisibility(View.GONE); + mView.findViewById(R.id.ipsec_id).setVisibility(View.GONE); mView.findViewById(R.id.ipsec_psk).setVisibility(View.GONE); mView.findViewById(R.id.ipsec_user).setVisibility(View.GONE); mView.findViewById(R.id.ipsec_ca).setVisibility(View.GONE); @@ -206,11 +207,12 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen case VpnProfile.TYPE_PPTP: mMppe.setVisibility(View.VISIBLE); break; - case VpnProfile.TYPE_L2TP_IPSEC_PSK: mView.findViewById(R.id.l2tp).setVisibility(View.VISIBLE); - // fall through + mView.findViewById(R.id.ipsec_psk).setVisibility(View.VISIBLE); + break; case VpnProfile.TYPE_IPSEC_XAUTH_PSK: + mView.findViewById(R.id.ipsec_id).setVisibility(View.VISIBLE); mView.findViewById(R.id.ipsec_psk).setVisibility(View.VISIBLE); break; @@ -295,11 +297,12 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen case VpnProfile.TYPE_PPTP: profile.mppe = mMppe.isChecked(); break; - case VpnProfile.TYPE_L2TP_IPSEC_PSK: profile.l2tpSecret = getSecret(mProfile.l2tpSecret, mL2tpSecret); - // fall through + profile.ipsecSecret = getSecret(mProfile.ipsecSecret, mIpsecSecret); + break; case VpnProfile.TYPE_IPSEC_XAUTH_PSK: + profile.ipsecIdentifier = mIpsecIdentifier.getText().toString(); profile.ipsecSecret = getSecret(mProfile.ipsecSecret, mIpsecSecret); break; diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java index 7f6c9f4..f345c22 100644 --- a/src/com/android/settings/vpn2/VpnSettings.java +++ b/src/com/android/settings/vpn2/VpnSettings.java @@ -21,6 +21,7 @@ import com.android.settings.R; import android.content.Context; import android.content.DialogInterface; import android.net.IConnectivityManager; +import android.net.LinkProperties; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -41,6 +42,7 @@ import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; import com.android.settings.SettingsPreferenceFragment; +import java.nio.charset.Charsets; import java.util.Arrays; import java.util.HashMap; @@ -198,7 +200,11 @@ public class VpnSettings extends SettingsPreferenceFragment implements // If we are not editing, connect! if (!mDialog.isEditing()) { - connect(profile); + try { + connect(profile); + } catch (Exception e) { + Log.e(TAG, "connect", e); + } } } } @@ -314,20 +320,45 @@ public class VpnSettings extends SettingsPreferenceFragment implements return true; } - private void connect(VpnProfile profile) { + private void connect(VpnProfile profile) throws Exception { + // Get the current active interface. + LinkProperties network = mService.getActiveLinkProperties(); + String interfaze = (network == null) ? null : network.getInterfaceName(); + if (interfaze == null) { + throw new IllegalStateException("Cannot get network interface"); + } + + // Load certificates. + String privateKey = ""; + String userCert = ""; + String caCert = ""; + if (!profile.ipsecUserCert.isEmpty()) { + byte[] value = mKeyStore.get(Credentials.USER_PRIVATE_KEY + profile.ipsecUserCert); + privateKey = (value == null) ? null : new String(value, Charsets.UTF_8); + value = mKeyStore.get(Credentials.USER_CERTIFICATE + profile.ipsecUserCert); + userCert = (value == null) ? null : new String(value, Charsets.UTF_8); + } + if (!profile.ipsecCaCert.isEmpty()) { + byte[] value = mKeyStore.get(Credentials.CA_CERTIFICATE + profile.ipsecCaCert); + caCert = (value == null) ? null : new String(value, Charsets.UTF_8); + } + if (privateKey == null || userCert == null || caCert == null) { + // TODO: find out a proper way to handle this. Delete these keys? + throw new IllegalStateException("Cannot load credentials"); + } + Log.i(TAG, userCert); + + // Prepare arguments for racoon. String[] racoon = null; switch (profile.type) { case VpnProfile.TYPE_L2TP_IPSEC_PSK: racoon = new String[] { - profile.server, "1701", profile.ipsecSecret, + interfaze, profile.server, "udppsk", "1701", profile.ipsecSecret, }; break; case VpnProfile.TYPE_L2TP_IPSEC_RSA: racoon = new String[] { - profile.server, "1701", - Credentials.USER_PRIVATE_KEY + profile.ipsecUserCert, - Credentials.USER_CERTIFICATE + profile.ipsecUserCert, - Credentials.CA_CERTIFICATE + profile.ipsecCaCert, + interfaze, profile.server, "udprsa", "1701", privateKey, userCert, caCert, }; break; case VpnProfile.TYPE_IPSEC_XAUTH_PSK: @@ -338,6 +369,7 @@ public class VpnSettings extends SettingsPreferenceFragment implements break; } + // Prepare arguments for mtpd. String[] mtpd = null; switch (profile.type) { case VpnProfile.TYPE_PPTP: @@ -369,11 +401,7 @@ public class VpnSettings extends SettingsPreferenceFragment implements config.searchDomains = Arrays.asList(profile.searchDomains.split(" ")); } - try { - mService.startLegacyVpn(config, racoon, mtpd); - } catch (Exception e) { - Log.e(TAG, "connect", e); - } + mService.startLegacyVpn(config, racoon, mtpd); } private void disconnect(String key) { |