Merge "Fix 3395616: Show IME by default when seting/changing password" into honeycomb
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 67eed06..1ef8a46 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1064,6 +1064,7 @@
<activity android:name="com.android.settings.accounts.AddAccountSettings"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
+ android:configChanges="orientation|keyboardHidden"
android:label="@string/header_add_an_account">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/assets/html/en_us/tethering_bluetooth_help.html b/assets/html/en_us/tethering_bluetooth_help.html
new file mode 100644
index 0000000..eb181f8
--- /dev/null
+++ b/assets/html/en_us/tethering_bluetooth_help.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html>
+<head>
+<style>
+P {
+ font-size: 14 px;
+ }
+B {
+ font-size: 16px;
+}
+A {
+ color: #OOC;
+}
+.style1 {
+ font-size: 16px;
+}
+</style>
+</head>
+<body>
+<p><b>Bluetooth tethering</b></p>
+<span class="style1">You can tether your Android device to your computer via a Bluetooth connection, to share your device's Internet connection with your computer</span>
+<ul>
+<li>Bluetooth tethering works with any computer or other device that can obtain an Internet connection via Bluetooth</li><br>
+<li>For more information, see <a href="http://www.android.com/tether#bluetooth">http://www.android.com/tether#bluetooth</a></li><br>
+</ul>
+</body>
+</html>
diff --git a/assets/html/en_us/tethering_help.html b/assets/html/en_us/tethering_help.html
index dfff700..e980b20 100644
--- a/assets/html/en_us/tethering_help.html
+++ b/assets/html/en_us/tethering_help.html
@@ -18,16 +18,24 @@
</head>
<body>
<p><b>USB tethering</b></p>
-<span class="style1">You can tether your phone to your computer with a USB cable, to share your phone's internet connection with your computer</span>
+<span class="style1">You can tether your Android device to your computer with a USB cable, to share your device's Internet connection with your computer</span>
<ul>
-<li>Tethering works with Windows Vista, Windows 7, and Linux</li><br>
-<li>You can't mount your phone's SD card on your computer when USB tethered</li><br>
+<li>USB tethering works with Windows Vista, Windows 7, and Linux</li><br>
+<li>If your device has an SD card or USB storage, you can't mount it on your computer when USB tethered</li><br>
<li>For more information, including using USB tethering with other OSs, see <a href="http://www.android.com/tether#usb">http://www.android.com/tether#usb</a></li><br>
</ul>
-<p><b>Portable Wi-Fi hotspot</b></p>
-<span class="style1">You can turn your phone into a portable Wi-Fi hotspot, to share your phone's internet connection with one or more computers or other devices</span>
+
+<p><b>Bluetooth tethering</b></p>
+<span class="style1">You can tether your Android device to your computer via a Bluetooth connection, to share your device's Internet connection with your computer</span>
<ul>
-<li>When your phone is serving as a Wi-Fi hotspot, you can't use your phone's applications to access the internet via its Wi-Fi connection</li><br>
+<li>Bluetooth tethering works with any computer or other device that can obtain an Internet connection via Bluetooth</li><br>
+<li>For more information, see <a href="http://www.android.com/tether#bluetooth">http://www.android.com/tether#bluetooth</a></li><br>
+</ul>
+
+<p><b>Portable Wi-Fi hotspot</b></p>
+<span class="style1">You can turn your Android device into a portable Wi-Fi hotspot, to share your Android device's Internet connection with one or more computers or other devices</span>
+<ul>
+<li>When your device is serving as a Wi-Fi hotspot, you can't use your phone's applications to access the Internet via its Wi-Fi connection (but of course you remain connected to the Internet via your mobile data network)</li><br>
<li>You configure the hotspot with the Wi-Fi hotspot settings</li><br>
<li>For more information, visit <a href="http://www.android.com/tether#wifi">http://www.android.com/tether#wifi</a></li><br>
</ul>
diff --git a/assets/html/en_us/tethering_usb_help.html b/assets/html/en_us/tethering_usb_help.html
index 23f39e5..b3dbf58 100644
--- a/assets/html/en_us/tethering_usb_help.html
+++ b/assets/html/en_us/tethering_usb_help.html
@@ -18,10 +18,10 @@
</head>
<body>
<p><b>USB tethering</b></p>
-<span class="style1">You can tether your phone to your computer with a USB cable, to share your phone's internet connection with your computer</span>
+<span class="style1">You can tether your Android device to your computer with a USB cable, to share your device's Internet connection with your computer</span>
<ul>
-<li>Tethering works with Windows Vista, Windows 7, and Linux</li><br>
-<li>You can't mount your phone's SD card on your computer when USB tethered</li><br>
+<li>USB tethering works with Windows Vista, Windows 7, and Linux</li><br>
+<li>If your device has an SD card or USB storage, you can't mount it on your computer when USB tethered</li><br>
<li>For more information, including using USB tethering with other OSs, see <a href="http://www.android.com/tether#usb">http://www.android.com/tether#usb</a></li><br>
</ul>
</body>
diff --git a/assets/html/en_us/tethering_wifi_help.html b/assets/html/en_us/tethering_wifi_help.html
index fac231b..621f869 100644
--- a/assets/html/en_us/tethering_wifi_help.html
+++ b/assets/html/en_us/tethering_wifi_help.html
@@ -18,9 +18,9 @@
</head>
<body>
<p><b>Portable Wi-Fi hotspot</b></p>
-<span class="style1">You can turn your phone into a portable Wi-Fi hotspot, to share your phone's internet connection with one or more computers or other devices</span>
+<span class="style1">You can turn your Android device into a portable Wi-Fi hotspot, to share your Android device's Internet connection with one or more computers or other devices</span>
<ul>
-<li>When your phone is serving as a Wi-Fi hotspot, you can't use your phone's applications to access the internet via its Wi-Fi connection</li><br>
+<li>When your device is serving as a Wi-Fi hotspot, you can't use your phone's applications to access the Internet via its Wi-Fi connection (but of course you remain connected to the Internet via your mobile data network)</li><br>
<li>You configure the hotspot with the Wi-Fi hotspot settings</li><br>
<li>For more information, visit <a href="http://www.android.com/tether#wifi">http://www.android.com/tether#wifi</a></li><br>
</ul>
diff --git a/res/layout/preference_bluetooth.xml b/res/layout/preference_bluetooth.xml
index d363dc9..bd437a9 100644
--- a/res/layout/preference_bluetooth.xml
+++ b/res/layout/preference_bluetooth.xml
@@ -31,7 +31,6 @@
android:id="@+id/divider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginRight="8dip"
android:layout_gravity="center_vertical"
android:src="@drawable/nav_divider"
/>
@@ -42,6 +41,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
+ android:padding="8dip"
+ android:background="?android:attr/selectableItemBackground"
android:src="@drawable/ic_bt_config" />
</LinearLayout>
diff --git a/res/layout/preference_bluetooth_profile.xml b/res/layout/preference_bluetooth_profile.xml
index 03f598a..4b6f1dd 100644
--- a/res/layout/preference_bluetooth_profile.xml
+++ b/res/layout/preference_bluetooth_profile.xml
@@ -24,7 +24,6 @@
android:id="@+id/divider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginRight="8dip"
android:layout_gravity="center_vertical"
android:src="@drawable/nav_divider"
/>
@@ -35,6 +34,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
+ android:padding="8dip"
+ android:background="?android:attr/selectableItemBackground"
android:src="@drawable/icon" />
</LinearLayout>
diff --git a/res/layout/user_dictionary_item.xml b/res/layout/user_dictionary_item.xml
index 926068f..3cdeb08 100644
--- a/res/layout/user_dictionary_item.xml
+++ b/res/layout/user_dictionary_item.xml
@@ -41,13 +41,10 @@
<ImageView
android:id="@+id/delete_button"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:layout_gravity="center"
- android:paddingLeft="16dip"
- android:paddingRight="16dip"
- android:paddingTop="8dip"
- android:paddingBottom="8dip"
+ android:padding="8dip"
android:src="@drawable/ic_item_delete"
- android:background="@android:drawable/list_selector_background"
+ android:background="?android:attr/selectableItemBackground"
/>
</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index eed510b..55c2be5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -582,23 +582,51 @@
<!-- In the security screen, the header title for settings related to Passwords-->
<string name="security_passwords_title">Passwords</string>
- <string name="crypt_keeper_settings_title">Device encryption</string>
+ <string name="crypt_keeper_settings_title">Encryption</string>
- <string name="crypt_keeper_encrypt_title">Encrypt data on device</string>
- <string name="crypt_keeper_encrypt_summary">Requires you to set a device unlock pin or password</string>
+ <string name="crypt_keeper_encrypt_title" product="tablet">Encrypt tablet</string>
+ <string name="crypt_keeper_encrypt_title" product="default">Encrypt phone</string>
+
+ <string name="crypt_keeper_encrypt_summary" product="tablet">
+ Require a numeric PIN or password to decrypt your tablet each time you
+ power it on</string>
+ <string name="crypt_keeper_encrypt_summary" product="default">
+ Require a numeric PIN or password to decrypt your phone each time you
+ power it on</string>
<string name="crypt_keeper_encrypted_summary">Encrypted</string>
<string name="crypt_keeper_confirm_title">Confirm encryption</string>
- <string name="crypt_keeper_desc" product="tablet">You can encrypt your accounts, settings, downloaded applications and their data, media, and other files. Once you encrypt your tablet, you can\'t unencrypt it except by performing a factory data reset, erasing all the data on your tablet.\n\nEncryption takes up to an hour. You must start with a charged battery and keep your tablet plugged in until encryption is complete. If you interrupt the encryption process, you will lose some or all of your data.</string>
- <string name="crypt_keeper_desc" product="default">You can encrypt your accounts, settings, downloaded applications and their data, media, and other files. Once you encrypt your phone, you can\'t unencrypt it except by performing a factory data reset, erasing all the data on your phone.\n\nEncryption takes up to an hour. You must start with a charged battery and keep your phone plugged in until encryption is complete. If you interrupt the encryption process, you will lose some or all of your data.</string>
-
+ <string name="crypt_keeper_desc" product="tablet">
+ You can encrypt your accounts, settings, downloaded applications and their data,
+ media, and other files. Once you encrypt your tablet, you must enter a numeric PIN
+ or password to decrypt it each time you power it on: you can\'t unencrypt your tablet
+ except by performing a factory data reset, erasing all your data.\n\nEncryption takes
+ an hour or more. You must start with a charged battery and keep your tablet plugged in
+ until encryption is complete. If you interrupt the encryption process, you will lose
+ some or all of your data.</string>
+ <string name="crypt_keeper_desc" product="default">
+ You can encrypt your accounts, settings, downloaded applications and their data,
+ media, and other files. Once you encrypt your phone, you must enter a numeric PIN or
+ password to decrypt it each time you power it on: you can\'t unencrypt your phone
+ except by performing a factory data reset, erasing all your data.\n\nEncryption takes
+ an hour or more. You must start with a charged battery and keep your phone plugged in
+ until encryption is complete. If you interrupt the encryption process, you will lose
+ some or all of your data.</string>
<string name="crypt_keeper_button_text" product="tablet">Encrypt tablet</string>
<string name="crypt_keeper_button_text" product="default">Encrypt phone</string>
-
- <string name="crypt_keeper_final_desc">Encrypt user data? This operation is not reversible and may not be interrupted without loss of data! Encryption may take up to an hour.</string>
+
+ <string name="crypt_keeper_low_charge_text">Please charge your battery and try again.</string>
+ <string name="crypt_keeper_unplugged_text">Please plug in your charger and try again.</string>
+
+ <string name="crypt_keeper_final_desc" product="tablet">
+ Encrypt tablet? This operation is irreversible and if you interrupt it,
+ you will lose data! Encryption takes an hour or more.</string>
+ <string name="crypt_keeper_final_desc" product="phone">
+ Encrypt phone? This operation is irreversible and if you interrupt it,
+ you will lose data! Encryption takes an hour or more.</string>
<string name="crypt_keeper_setup_title">Encrypting</string>
diff --git a/res/xml/application_settings.xml b/res/xml/application_settings.xml
index a06377d..4e77a93 100644
--- a/res/xml/application_settings.xml
+++ b/res/xml/application_settings.xml
@@ -19,32 +19,6 @@
android:summary="@string/applications_settings_summary"
android:key="applications_settings">
- <CheckBoxPreference
- android:key="toggle_install_applications"
- android:title="@string/install_applications"
- android:summaryOff="@string/install_unknown_applications"
- android:summaryOn="@string/install_unknown_applications"
- android:persistent="false" />
-
- <ListPreference
- android:key="app_install_location"
- android:title="@string/app_install_location_title"
- android:summary="@string/app_install_location_summary"
- android:persistent="false"
- android:entries="@array/app_install_location_entries"
- android:entryValues="@array/app_install_location_values"/>
-
- <!-- Disabled quick launch settings pending UI redesign.
- <PreferenceScreen
- android:key="quick_launch"
- android:title="@string/quick_launch_title"
- android:summary="@string/quick_launch_summary">
- <intent android:action="android.intent.action.MAIN"
- android:targetPackage="com.android.settings"
- android:targetClass="com.android.settings.quicklaunch.QuickLaunchSettings" />
- </PreferenceScreen>
- -->
-
<PreferenceScreen
android:fragment="com.android.settings.applications.ManageApplications"
android:title="@string/manageapplications_settings_title"
@@ -73,11 +47,38 @@
android:summary="@string/power_usage_summary">
</PreferenceScreen>
+ <CheckBoxPreference
+ android:key="toggle_install_applications"
+ android:title="@string/install_applications"
+ android:summaryOff="@string/install_unknown_applications"
+ android:summaryOn="@string/install_unknown_applications"
+ android:persistent="false" />
+
+ <ListPreference
+ android:key="app_install_location"
+ android:title="@string/app_install_location_title"
+ android:summary="@string/app_install_location_summary"
+ android:persistent="false"
+ android:entries="@array/app_install_location_entries"
+ android:entryValues="@array/app_install_location_values"/>
+
+ <!-- Disabled quick launch settings pending UI redesign.
+ <PreferenceScreen
+ android:key="quick_launch"
+ android:title="@string/quick_launch_title"
+ android:summary="@string/quick_launch_summary">
+ <intent android:action="android.intent.action.MAIN"
+ android:targetPackage="com.android.settings"
+ android:targetClass="com.android.settings.quicklaunch.QuickLaunchSettings" />
+ </PreferenceScreen>
+ -->
+
+
<PreferenceScreen
android:title="@string/development_settings_title"
android:summary="@string/development_settings_summary"
android:fragment="com.android.settings.DevelopmentSettings">
</PreferenceScreen>
-
+
</PreferenceScreen>
diff --git a/res/xml/bluetooth_device_advanced.xml b/res/xml/bluetooth_device_advanced.xml
index b4a0978..6610a69 100644
--- a/res/xml/bluetooth_device_advanced.xml
+++ b/res/xml/bluetooth_device_advanced.xml
@@ -28,12 +28,6 @@
android:order="20"
android:persistent="false" />
- <CheckBoxPreference
- android:key="allow_incoming"
- android:title="@string/bluetooth_device_advanced_enable_opp_title"
- android:order="30"
- android:persistent="false" />
-
<Preference
android:key="unpair"
android:title="@string/bluetooth_device_context_unpair"
diff --git a/src/com/android/settings/AirplaneModeEnabler.java b/src/com/android/settings/AirplaneModeEnabler.java
index ccfe541..00c416f 100644
--- a/src/com/android/settings/AirplaneModeEnabler.java
+++ b/src/com/android/settings/AirplaneModeEnabler.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.Intent;
+import android.database.ContentObserver;
import android.os.Handler;
import android.os.Message;
import android.os.SystemProperties;
@@ -51,6 +52,13 @@
}
};
+ private ContentObserver mAirplaneModeObserver = new ContentObserver(new Handler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ onAirplaneModeChanged();
+ }
+ };
+
public AirplaneModeEnabler(Context context, CheckBoxPreference airplaneModeCheckBoxPreference) {
mContext = context;
@@ -68,13 +76,17 @@
mPhoneStateReceiver.registerIntent();
mCheckBoxPref.setOnPreferenceChangeListener(this);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(Settings.System.AIRPLANE_MODE_ON), true,
+ mAirplaneModeObserver);
}
public void pause() {
mPhoneStateReceiver.unregisterIntent();
mCheckBoxPref.setOnPreferenceChangeListener(null);
+ mContext.getContentResolver().unregisterContentObserver(mAirplaneModeObserver);
}
-
+
public static boolean isAirplaneModeOn(Context context) {
return Settings.System.getInt(context.getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, 0) != 0;
@@ -84,7 +96,7 @@
mCheckBoxPref.setSummary(enabling ? R.string.airplane_mode_turning_on
: R.string.airplane_mode_turning_off);
-
+
// Change the system setting
Settings.System.putInt(mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
enabling ? 1 : 0);
@@ -106,8 +118,8 @@
* - mobile does not send failure notification, fail on timeout.
*/
private void onAirplaneModeChanged() {
- ServiceState serviceState = mPhoneStateReceiver.getServiceState();
- boolean airplaneModeEnabled = serviceState.getState() == ServiceState.STATE_POWER_OFF;
+ boolean airplaneModeEnabled = isAirplaneModeOn(mContext);
+ mCheckBoxPref.setChecked(isAirplaneModeOn(mContext));
mCheckBoxPref.setSummary(airplaneModeEnabled ? null :
mContext.getString(R.string.airplane_mode_summary));
}
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index 09faf41..dd078ba 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -21,6 +21,7 @@
import android.app.DialogFragment;
import android.app.Fragment;
import android.content.ContentResolver;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
@@ -104,13 +105,37 @@
}
protected void removeDialog(int dialogId) {
- if (mDialogFragment != null && mDialogFragment.getDialogId() == dialogId
- && mDialogFragment.isVisible()) {
+ // mDialogFragment may not be visible yet in parent fragment's onResume().
+ // To be able to dismiss dialog at that time, don't check
+ // mDialogFragment.isVisible().
+ if (mDialogFragment != null && mDialogFragment.getDialogId() == dialogId) {
mDialogFragment.dismiss();
}
mDialogFragment = null;
}
+ /**
+ * Sets the OnCancelListener of the dialog shown. This method can only be
+ * called after showDialog(int) and before removeDialog(int). The method
+ * does nothing otherwise.
+ */
+ protected void setOnCancelListener(DialogInterface.OnCancelListener listener) {
+ if (mDialogFragment != null) {
+ mDialogFragment.mOnCancelListener = listener;
+ }
+ }
+
+ /**
+ * Sets the OnDismissListener of the dialog shown. This method can only be
+ * called after showDialog(int) and before removeDialog(int). The method
+ * does nothing otherwise.
+ */
+ protected void setOnDismissListener(DialogInterface.OnDismissListener listener) {
+ if (mDialogFragment != null) {
+ mDialogFragment.mOnDismissListener = listener;
+ }
+ }
+
public static class SettingsDialogFragment extends DialogFragment {
private static final String KEY_DIALOG_ID = "key_dialog_id";
private static final String KEY_PARENT_FRAGMENT_ID = "key_parent_fragment_id";
@@ -119,6 +144,9 @@
private Fragment mParentFragment;
+ private DialogInterface.OnCancelListener mOnCancelListener;
+ private DialogInterface.OnDismissListener mOnDismissListener;
+
public SettingsDialogFragment() {
/* do nothing */
}
@@ -163,6 +191,21 @@
return ((DialogCreatable) mParentFragment).onCreateDialog(mDialogId);
}
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ super.onCancel(dialog);
+ if (mOnCancelListener != null) {
+ mOnCancelListener.onCancel(dialog);
+ }
+ }
+
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ super.onDismiss(dialog);
+ if (mOnDismissListener != null) {
+ mOnDismissListener.onDismiss(dialog);
+ }
+ }
public int getDialogId() {
return mDialogId;
}
diff --git a/src/com/android/settings/applications/RunningServiceDetails.java b/src/com/android/settings/applications/RunningServiceDetails.java
index eccff93..631e747 100644
--- a/src/com/android/settings/applications/RunningServiceDetails.java
+++ b/src/com/android/settings/applications/RunningServiceDetails.java
@@ -2,6 +2,7 @@
import com.android.settings.R;
+import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.ApplicationErrorReport;
@@ -23,6 +24,7 @@
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Debug;
+import android.os.Handler;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
@@ -406,7 +408,15 @@
}
private void finish() {
- getActivity().onBackPressed();
+ (new Handler()).post(new Runnable() {
+ @Override
+ public void run() {
+ Activity a = getActivity();
+ if (a != null) {
+ a.onBackPressed();
+ }
+ }
+ });
}
@Override
diff --git a/src/com/android/settings/bluetooth/BluetoothProfilePreference.java b/src/com/android/settings/bluetooth/BluetoothProfilePreference.java
index 6be1480..c74012a 100644
--- a/src/com/android/settings/bluetooth/BluetoothProfilePreference.java
+++ b/src/com/android/settings/bluetooth/BluetoothProfilePreference.java
@@ -80,9 +80,9 @@
} else {
mProfileExpandView.setOnClickListener(this);
mProfileExpandView.setTag(mProfile);
-
- mProfileExpandView.setImageResource(mExpanded ? R.drawable.ic_preferences_expanded
- : R.drawable.ic_preferences_collapsed);
+ mProfileExpandView.setImageResource(mExpanded
+ ? com.android.internal.R.drawable.expander_open_holo_dark
+ : com.android.internal.R.drawable.expander_close_holo_dark);
}
}
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index 2893ce3..c1fda6b 100644
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -18,7 +18,10 @@
import android.app.Activity;
import android.bluetooth.BluetoothDevice;
+import android.content.Intent;
import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
import android.util.Log;
import android.view.View;
@@ -36,11 +39,16 @@
private static final String KEY_BT_CHECKBOX = "bt_checkbox";
private static final String KEY_BT_DISCOVERABLE = "bt_discoverable";
private static final String KEY_BT_NAME = "bt_name";
+ private static final String KEY_BT_SHOW_RECEIVED = "bt_show_received_files";
private BluetoothEnabler mEnabler;
private BluetoothDiscoverableEnabler mDiscoverableEnabler;
private BluetoothNamePreference mNamePreference;
+ /* Private intent to show the list of received files */
+ private static final String BTOPP_ACTION_OPEN_RECEIVED_FILES =
+ "android.btopp.intent.action.OPEN_RECEIVED_FILES";
+
void addPreferencesForActivity(Activity activity) {
addPreferencesFromResource(R.xml.bluetooth_settings);
@@ -75,6 +83,18 @@
mEnabler.pause();
}
+ @Override
+ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
+ Preference preference) {
+ if (KEY_BT_SHOW_RECEIVED.equals(preference.getKey())) {
+ Intent intent = new Intent(BTOPP_ACTION_OPEN_RECEIVED_FILES);
+ getActivity().sendBroadcast(intent);
+ return true;
+ }
+
+ return super.onPreferenceTreeClick(preferenceScreen, preference);
+ }
+
public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice,
int bondState) {
if (bondState == BluetoothDevice.BOND_BONDED) {
diff --git a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
index 8ddeef5..db20411 100644
--- a/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
+++ b/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
@@ -111,8 +111,10 @@
" newProfileState " + newProfileState);
}
- int newState = LocalBluetoothProfileManager.getProfileManager(mLocalManager,
- profile).convertState(newProfileState);
+ final LocalBluetoothProfileManager pm =
+ LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
+ if (pm == null) return;
+ int newState = pm.convertState(newProfileState);
if (newState == SettingsBtStatus.CONNECTION_STATUS_CONNECTED) {
if (!mProfiles.contains(profile)) {
diff --git a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
index 479cbe0..f39eabd 100644
--- a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
+++ b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java
@@ -58,7 +58,6 @@
private CachedBluetoothDevice mCachedDevice;
private PreferenceGroup mProfileContainer;
- private CheckBoxPreference mAllowIncomingPref;
private EditTextPreference mDeviceNamePref;
private final HashMap<String,CheckBoxPreference> mAutoConnectPrefs
= new HashMap<String,CheckBoxPreference>();
@@ -93,17 +92,6 @@
getPreferenceScreen().setOrderingAsAdded(false);
mProfileContainer = (PreferenceGroup) findPreference(KEY_PROFILE_CONTAINER);
- mAllowIncomingPref = (CheckBoxPreference) findPreference(KEY_ALLOW_INCOMING);
-
- // Configure incoming file transfer preference if device supports OPP
- // or else remove the preference item
- if (isObjectPushSupported(device)) {
- mAllowIncomingPref.setChecked(isIncomingFileTransfersAllowed());
- mAllowIncomingPref.setOnPreferenceChangeListener(this);
- } else {
- getPreferenceScreen().removePreference(mAllowIncomingPref);
- mAllowIncomingPref = null;
- }
mDeviceNamePref = (EditTextPreference) findPreference(KEY_RENAME_DEVICE);
mDeviceNamePref.setSummary(mCachedDevice.getName());
@@ -210,9 +198,7 @@
}
public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (preference == mAllowIncomingPref) {
- setIncomingFileTransfersAllowed((Boolean) newValue);
- } else if (preference == mDeviceNamePref) {
+ if (preference == mDeviceNamePref) {
mCachedDevice.setName((String) newValue);
} else if (preference instanceof CheckBoxPreference) {
boolean autoConnect = (Boolean) newValue;
diff --git a/src/com/android/settings/deviceinfo/Memory.java b/src/com/android/settings/deviceinfo/Memory.java
index c3df2d5..3e0f0a2 100644
--- a/src/com/android/settings/deviceinfo/Memory.java
+++ b/src/com/android/settings/deviceinfo/Memory.java
@@ -311,19 +311,29 @@
}})
.setNegativeButton(R.string.cancel, null)
.setMessage(R.string.dlg_confirm_unmount_text)
- .setOnCancelListener(this)
.create();
case DLG_ERROR_UNMOUNT:
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.dlg_error_unmount_title)
.setNeutralButton(R.string.dlg_ok, null)
.setMessage(R.string.dlg_error_unmount_text)
- .setOnCancelListener(this)
.create();
}
return null;
}
+ @Override
+ protected void showDialog(int id) {
+ super.showDialog(id);
+
+ switch (id) {
+ case DLG_CONFIRM_UNMOUNT:
+ case DLG_ERROR_UNMOUNT:
+ setOnCancelListener(this);
+ break;
+ }
+ }
+
private void doUnmount(boolean force) {
// Present a toast here
Toast.makeText(getActivity(), R.string.unmount_inform_text, Toast.LENGTH_SHORT).show();
diff --git a/src/com/android/settings/vpn/VpnEditor.java b/src/com/android/settings/vpn/VpnEditor.java
index 161d34b..f4f5828 100644
--- a/src/com/android/settings/vpn/VpnEditor.java
+++ b/src/com/android/settings/vpn/VpnEditor.java
@@ -78,14 +78,16 @@
}
}
- mProfileEditor = getEditor(p);
- mAddingProfile = TextUtils.isEmpty(p.getName());
-
- initViewFor(p);
-
Parcel parcel = Parcel.obtain();
p.writeToParcel(parcel, 0);
mOriginalProfileData = parcel.marshall();
+ parcel.setDataPosition(0);
+ VpnProfile profile = (VpnProfile) VpnProfile.CREATOR.createFromParcel(parcel);
+
+ mProfileEditor = getEditor(profile);
+ mAddingProfile = TextUtils.isEmpty(profile.getName());
+
+ initViewFor(profile);
registerForContextMenu(getListView());
setHasOptionsMenu(true);
diff --git a/src/com/android/settings/vpn/VpnSettings.java b/src/com/android/settings/vpn/VpnSettings.java
index 03687f2..318a5bf 100644
--- a/src/com/android/settings/vpn/VpnSettings.java
+++ b/src/com/android/settings/vpn/VpnSettings.java
@@ -106,12 +106,13 @@
private static final String KEY_PREFIX_IPSEC_PSK = Credentials.VPN + 'i';
private static final String KEY_PREFIX_L2TP_SECRET = Credentials.VPN + 'l';
+ private static List<VpnProfile> sVpnProfileList = new ArrayList<VpnProfile>();
+
private PreferenceScreen mAddVpn;
private PreferenceCategory mVpnListContainer;
// profile name --> VpnPreference
private Map<String, VpnPreference> mVpnPreferenceMap;
- private List<VpnProfile> mVpnProfileList;
// profile engaged in a connection
private VpnProfile mActiveProfile;
@@ -131,7 +132,9 @@
private int mConnectingErrorCode = NO_ERROR;
- private Dialog mShowingDialog, mConnectDialog;
+ private Dialog mShowingDialog;
+
+ private boolean mConnectDialogShowing = false;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -190,12 +193,18 @@
public void onPause() {
// ignore vpn connectivity event
mVpnManager.unregisterConnectivityReceiver(mConnectivityReceiver);
+ if ((mShowingDialog != null) && mShowingDialog.isShowing()) {
+ mShowingDialog.dismiss();
+ mShowingDialog = null;
+ }
super.onPause();
}
@Override
public void onResume() {
super.onResume();
+ updatePreferenceMap();
+
if (DEBUG)
Log.d(TAG, "onResume");
@@ -207,21 +216,22 @@
mUnlockAction = null;
getActivity().runOnUiThread(action);
}
- if (mConnectDialog == null || !mConnectDialog.isShowing()) {
+
+ if (!mConnectDialogShowing) {
checkVpnConnectionStatus();
} else {
// Dismiss the connect dialog in case there is another instance
// trying to operate a vpn connection.
- if (!mVpnManager.isIdle()) removeConnectDialog();
+ if (!mVpnManager.isIdle() || (mActiveProfile == null)) {
+ removeDialog(DIALOG_CONNECT);
+ checkVpnConnectionStatus();
+ }
}
}
@Override
public void onDestroyView() {
unregisterForContextMenu(getListView());
- if ((mShowingDialog != null) && mShowingDialog.isShowing()) {
- mShowingDialog.dismiss();
- }
// This should be called after the procedure above as ListView inside this Fragment
// will be deleted here.
super.onDestroyView();
@@ -239,11 +249,36 @@
}
@Override
+ protected void showDialog(int dialogId) {
+ super.showDialog(dialogId);
+
+ if (dialogId == DIALOG_CONNECT) {
+ mConnectDialogShowing = true;
+ setOnDismissListener(new DialogInterface.OnDismissListener() {
+ public void onDismiss(DialogInterface dialog) {
+ mConnectDialogShowing = false;
+ }
+ });
+ }
+ setOnCancelListener(new DialogInterface.OnCancelListener() {
+ public void onCancel(DialogInterface dialog) {
+ if (mActiveProfile != null) {
+ changeState(mActiveProfile, VpnState.IDLE);
+ }
+ // Make sure onIdle() is called as the above changeState()
+ // may not be effective if the state is already IDLE.
+ // XXX: VpnService should broadcast non-IDLE state, say UNUSABLE,
+ // when an error occurs.
+ onIdle();
+ }
+ });
+ }
+
+ @Override
public Dialog onCreateDialog (int id) {
switch (id) {
case DIALOG_CONNECT:
- mConnectDialog = createConnectDialog();
- return mConnectDialog;
+ return createConnectDialog();
case DIALOG_SECRET_NOT_SET:
return createSecretNotSetDialog();
@@ -259,35 +294,17 @@
}
}
- private void removeConnectDialog() {
- if (mConnectDialog != null) {
- mConnectDialog.dismiss();
- mConnectDialog = null;
- checkVpnConnectionStatus();
- }
- }
-
- private class ConnectDialog extends AlertDialog {
- public ConnectDialog(Context context) {
- super(context);
- setTitle(String.format(getString(R.string.vpn_connect_to),
- mConnectingActor.getProfile().getName()));
- setButton(DialogInterface.BUTTON_POSITIVE,
- getString(R.string.vpn_connect_button),
- VpnSettings.this);
- setButton(DialogInterface.BUTTON_NEGATIVE,
- getString(android.R.string.cancel),
- VpnSettings.this);
- setView(mConnectingActor.createConnectView());
- }
- public void onBackPressed() {
- changeState(mActiveProfile, VpnState.IDLE);
- super.onBackPressed();
- }
- }
-
private Dialog createConnectDialog() {
- return new ConnectDialog(getActivity());
+ final Activity activity = getActivity();
+ return new AlertDialog.Builder(activity)
+ .setView(mConnectingActor.createConnectView())
+ .setTitle(String.format(activity.getString(R.string.vpn_connect_to),
+ mConnectingActor.getProfile().getName()))
+ .setPositiveButton(activity.getString(R.string.vpn_connect_button),
+ this)
+ .setNegativeButton(activity.getString(android.R.string.cancel),
+ this)
+ .create();
}
private Dialog createReconnectDialog(int id) {
@@ -375,11 +392,6 @@
public void onClick(DialogInterface dialog, int w) {
onIdle();
}
- })
- .setOnCancelListener(new DialogInterface.OnCancelListener() {
- public void onCancel(DialogInterface dialog) {
- onIdle();
- }
});
}
@@ -512,14 +524,10 @@
String error = mConnectingActor.validateInputs(d);
if (error == null) {
mConnectingActor.connect(d);
- removeConnectDialog();
return;
} else {
- // dismissDialog(DIALOG_CONNECT);
- removeConnectDialog();
-
- final Activity activity = getActivity();
// show error dialog
+ final Activity activity = getActivity();
mShowingDialog = new AlertDialog.Builder(activity)
.setTitle(android.R.string.dialog_alert_title)
.setIcon(android.R.drawable.ic_dialog_alert)
@@ -533,16 +541,20 @@
}
})
.create();
+ // The profile state is "connecting". If we allow the dialog to
+ // be cancelable, then we need to clear the state in the
+ // onCancel handler.
+ mShowingDialog.setCancelable(false);
mShowingDialog.show();
}
} else {
- removeConnectDialog();
+ changeState(mActiveProfile, VpnState.IDLE);
}
}
private int getProfileIndexFromId(String id) {
int index = 0;
- for (VpnProfile p : mVpnProfileList) {
+ for (VpnProfile p : sVpnProfileList) {
if (p.getId().equals(id)) {
return index;
} else {
@@ -552,10 +564,10 @@
return -1;
}
- // Replaces the profile at index in mVpnProfileList with p.
+ // Replaces the profile at index in sVpnProfileList with p.
// Returns true if p's name is a duplicate.
private boolean checkDuplicateName(VpnProfile p, int index) {
- List<VpnProfile> list = mVpnProfileList;
+ List<VpnProfile> list = sVpnProfileList;
VpnPreference pref = mVpnPreferenceMap.get(p.getName());
if ((pref != null) && (index >= 0) && (index < list.size())) {
// not a duplicate if p is to replace the profile at index
@@ -569,20 +581,24 @@
return menuInfo.position - mVpnListContainer.getOrder() - 1;
}
- // position: position in mVpnProfileList
+ // position: position in sVpnProfileList
private VpnProfile getProfile(int position) {
- return ((position >= 0) ? mVpnProfileList.get(position) : null);
+ return ((position >= 0) ? sVpnProfileList.get(position) : null);
}
- // position: position in mVpnProfileList
+ // position: position in sVpnProfileList
private void deleteProfile(final int position) {
- if ((position < 0) || (position >= mVpnProfileList.size())) return;
+ if ((position < 0) || (position >= sVpnProfileList.size())) return;
+ final VpnProfile target = sVpnProfileList.get(position);
DialogInterface.OnClickListener onClickListener =
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
+ // Double check if the target is still the one we want
+ // to remove.
+ VpnProfile p = sVpnProfileList.get(position);
+ if (p != target) return;
if (which == OK_BUTTON) {
- VpnProfile p = mVpnProfileList.remove(position);
+ sVpnProfileList.remove(position);
VpnPreference pref =
mVpnPreferenceMap.remove(p.getName());
mVpnListContainer.removePreference(pref);
@@ -610,7 +626,7 @@
Double.doubleToLongBits(Math.random())));
if (id.length() >= 8) break;
}
- for (VpnProfile p : mVpnProfileList) {
+ for (VpnProfile p : sVpnProfileList) {
if (p.getId().equals(id)) {
setProfileId(profile);
return;
@@ -624,7 +640,7 @@
processSecrets(p);
saveProfileToStorage(p);
- mVpnProfileList.add(p);
+ sVpnProfileList.add(p);
addPreferenceFor(p, true);
disableProfilePreferencesIfOneActive();
}
@@ -646,10 +662,10 @@
return pref;
}
- // index: index to mVpnProfileList
+ // index: index to sVpnProfileList
private void replaceProfile(int index, VpnProfile p) throws IOException {
Map<String, VpnPreference> map = mVpnPreferenceMap;
- VpnProfile oldProfile = mVpnProfileList.set(index, p);
+ VpnProfile oldProfile = sVpnProfileList.set(index, p);
VpnPreference pref = map.remove(oldProfile.getName());
if (pref.mProfile != oldProfile) {
throw new RuntimeException("inconsistent state!");
@@ -672,7 +688,9 @@
}
private void startVpnTypeSelection() {
- ((PreferenceActivity)getActivity()).startPreferencePanel(
+ if (getActivity() == null) return;
+
+ ((PreferenceActivity) getActivity()).startPreferencePanel(
VpnTypeSelection.class.getCanonicalName(), null, R.string.vpn_type_title, null,
this, REQUEST_SELECT_VPN_TYPE);
}
@@ -778,7 +796,6 @@
private void changeState(VpnProfile p, VpnState state) {
VpnState oldState = p.getState();
if (oldState == state) return;
-
p.setState(state);
mVpnPreferenceMap.get(p.getName()).setSummary(
getProfileSummaryString(p));
@@ -816,7 +833,7 @@
}
private void onIdle() {
- Log.d(TAG, " onIdle()");
+ if (DEBUG) Log.d(TAG, " onIdle()");
mActiveProfile = null;
mConnectingActor = null;
enableProfilePreferences();
@@ -825,7 +842,7 @@
private void disableProfilePreferencesIfOneActive() {
if (mActiveProfile == null) return;
- for (VpnProfile p : mVpnProfileList) {
+ for (VpnProfile p : sVpnProfileList) {
switch (p.getState()) {
case CONNECTING:
case DISCONNECTING:
@@ -840,7 +857,7 @@
}
private void enableProfilePreferences() {
- for (VpnProfile p : mVpnProfileList) {
+ for (VpnProfile p : sVpnProfileList) {
mVpnPreferenceMap.get(p.getName()).setEnabled(true);
}
}
@@ -862,12 +879,23 @@
Util.deleteFile(getProfileDir(p));
}
- private void retrieveVpnListFromStorage() {
+ private void updatePreferenceMap() {
mVpnPreferenceMap = new LinkedHashMap<String, VpnPreference>();
- mVpnProfileList = Collections.synchronizedList(
- new ArrayList<VpnProfile>());
mVpnListContainer.removeAll();
+ for (VpnProfile p : sVpnProfileList) {
+ addPreferenceFor(p, false);
+ }
+ // reset the mActiveProfile if the profile has been removed from the
+ // other instance.
+ if ((mActiveProfile != null)
+ && mVpnPreferenceMap.containsKey(mActiveProfile.getName())) {
+ onIdle();
+ }
+ }
+ private void retrieveVpnListFromStorage() {
+ // skip the loop if the profile is loaded already.
+ if (sVpnProfileList.size() > 0) return;
File root = new File(PROFILES_ROOT);
String[] dirs = root.list();
if (dirs == null) return;
@@ -879,30 +907,25 @@
if (p == null) continue;
if (!checkIdConsistency(dir, p)) continue;
- mVpnProfileList.add(p);
+ sVpnProfileList.add(p);
} catch (IOException e) {
Log.e(TAG, "retrieveVpnListFromStorage()", e);
}
}
- Collections.sort(mVpnProfileList, new Comparator<VpnProfile>() {
+ Collections.sort(sVpnProfileList, new Comparator<VpnProfile>() {
public int compare(VpnProfile p1, VpnProfile p2) {
return p1.getName().compareTo(p2.getName());
}
});
- // Delay adding preferences to mVpnListContainer until states are
- // obtained so that the user won't see initial state transition.
- for (VpnProfile p : mVpnProfileList) {
- Preference pref = addPreferenceFor(p, false);
- }
disableProfilePreferencesIfOneActive();
}
private void checkVpnConnectionStatus() {
- for (VpnProfile p : mVpnProfileList) {
+ for (VpnProfile p : sVpnProfileList) {
changeState(p, mVpnManager.getState(p));
}
// make preferences appear
- for (VpnProfile p : mVpnProfileList) {
+ for (VpnProfile p : sVpnProfileList) {
VpnPreference pref = mVpnPreferenceMap.get(p.getName());
mVpnListContainer.addPreference(pref);
}
@@ -1074,6 +1097,8 @@
Log.d(TAG, "received connectivity: " + profileName
+ ": connected? " + s
+ " err=" + mConnectingErrorCode);
+ // XXX: VpnService should broadcast non-IDLE state, say UNUSABLE,
+ // when an error occurs.
changeState(pref.mProfile, s);
} else {
Log.e(TAG, "received connectivity: " + profileName
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index ccc40fb..2e26eba 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -265,7 +265,15 @@
}
return true;
case MENU_ID_ADVANCED:
- startFragment(this, AdvancedSettings.class.getCanonicalName(), -1, null);
+ if (getActivity() instanceof PreferenceActivity) {
+ ((PreferenceActivity) getActivity()).startPreferencePanel(
+ AdvancedSettings.class.getCanonicalName(),
+ null,
+ R.string.wifi_advanced_titlebar, null,
+ this, 0);
+ } else {
+ startFragment(this, AdvancedSettings.class.getCanonicalName(), -1, null);
+ }
return true;
}
return super.onOptionsItemSelected(item);