Merge branch 'master' into honeycomb-release

This commit is contained in:
The Android Automerger
2010-11-04 09:33:14 -07:00
21 changed files with 383 additions and 242 deletions

View File

@@ -7,3 +7,6 @@
-keep class com.android.settings.bluetooth.*
-keep class com.android.settings.applications.*
-keep class com.android.settings.inputmethod.*
-keep class com.android.settings.MasterClear
-keep class com.android.settings.MasterClearConfirm

View File

@@ -26,7 +26,7 @@
<TextView
android:id="@+id/wifi_setup_title"
android:layout_width="fill_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
@@ -39,13 +39,13 @@
android:id="@+id/scanning_progress_bar"
android:layout_width="100dip"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_above="@+id/scanning_progress_text"
android:layout_alignParentRight="true"
style="?android:attr/progressBarStyleHorizontal" />
<TextView
android:id="@+id/scanning_progress_text"
android:layout_width="fill_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_above="@+id/top_divider"
@@ -85,27 +85,23 @@
android:layout_height="wrap_content" />
</FrameLayout>
<RelativeLayout
<LinearLayout
android:id="@+id/right_buttons"
android:layout_width="300dip"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true">
<Button android:id="@+id/wifi_setup_connect"
android:layout_width="260dip"
android:layout_height="60dip"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:textSize="24dip"
android:text="@string/wifi_connect"
android:visibility="gone" />
<Button android:id="@+id/wifi_setup_forget"
android:layout_width="260dip"
android:layout_height="60dip"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:textSize="24dip"
android:text="@string/wifi_forget"
android:visibility="gone" />
@@ -113,8 +109,6 @@
<Button android:id="@+id/wifi_setup_add_network"
android:layout_width="260dip"
android:layout_height="60dip"
android:layout_above="@+id/wifi_setup_refresh_list"
android:layout_alignParentRight="true"
android:textSize="24dip"
android:text="@string/wifi_setup_add_network"
android:enabled="false" />
@@ -122,8 +116,6 @@
<Button android:id="@+id/wifi_setup_refresh_list"
android:layout_width="260dip"
android:layout_height="60dip"
android:layout_above="@+id/wifi_setup_skip_or_next"
android:layout_alignParentRight="true"
android:textSize="24dip"
android:text="@string/wifi_setup_refresh_list"
android:enabled="false" />
@@ -132,12 +124,10 @@
android:layout_width="260dip"
android:layout_height="60dip"
android:layout_marginTop="30dip"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:textSize="24dip"
android:text="@string/wifi_setup_skip"
android:enabled="false" />
</RelativeLayout>
</LinearLayout>
<Button android:id="@+id/wifi_setup_detail"
android:layout_width="260dip"

View File

@@ -1,29 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright (C) 2008 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.
*/
<!-- Copyright (C) 2010 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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/info_layout">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ScrollView
android:layout_width="fill_parent"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_marginTop="12dp"
android:layout_weight="1">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -42,13 +44,14 @@
<CheckBox android:id="@+id/erase_external"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_gravity="center_vertical"
android:paddingRight="8dp"
android:focusable="false"
android:clickable="false"
android:duplicateParentState="true" />
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
@@ -70,7 +73,8 @@
android:id="@+id/initiate_master_clear"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dip"
android:layout_width="150dip"
android:layout_marginBottom="12dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/master_clear_button_text"
android:gravity="center" />

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_marginTop="12dp"
android:textSize="20sp"
android:text="@string/master_clear_final_desc" />
<Button android:id="@+id/execute_master_clear"
android:layout_gravity="center_horizontal"
android:layout_marginTop="40dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/master_clear_final_button_text"
android:gravity="center" />
</LinearLayout>

View File

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright (C) 2008 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.
*/
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/info_layout">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="@string/master_clear_final_desc" />
<Button android:id="@+id/execute_master_clear"
android:layout_gravity="center_horizontal"
android:layout_marginTop="40dip"
android:layout_width="150dip"
android:layout_height="wrap_content"
android:text="@string/master_clear_final_button_text"
android:gravity="center" />
</LinearLayout>

View File

@@ -837,6 +837,17 @@
<!-- Bluetooth settings. The summary string when a device is connected to the PAN profile. [CHAR LIMIT=35]-->
<string name="bluetooth_summary_connected_to_pan">Tethered</string>
<!-- Bluetooth settings. Message for disconnecting from the A2DP profile. -->
<string name="bluetooth_disconnect_a2dp_profile"><xliff:g id="device_name">%1$s</xliff:g> will be disconnected from media audio.</string>
<!-- Bluetooth settings. Message for disconnecting from the headset profile. -->
<string name="bluetooth_disconnect_headset_profile" product="tablet"><xliff:g id="device_name">%1$s</xliff:g> will be disconnected from tablet audio.</string>
<!-- Bluetooth settings. Message for disconnecting from the headset profile. -->
<string name="bluetooth_disconnect_headset_profile" product="default"><xliff:g id="device_name">%1$s</xliff:g> will be disconnected from phone audio.</string>
<!-- Bluetooth settings. Message for disconnecting from the HID profile. -->
<string name="bluetooth_disconnect_hid_profile"><xliff:g id="device_name">%1$s</xliff:g> will be disconnected from input device.</string>
<!-- Bluetooth settings. Message for disconnecting from the PAN profile. -->
<string name="bluetooth_disconnect_pan_profile"><xliff:g id="device_name">%1$s</xliff:g> will be disconnected from tethering.</string>
<!-- Bluetooth settings. Connection options screen. The title of the screen. -->
<string name="bluetooth_device_advanced_title"><xliff:g id="device_name">%1$s</xliff:g> options</string>
<!-- Bluetooth settings. Connection options screen. Title of device actions section. [CHAR LIMIT=30] -->
@@ -1608,6 +1619,8 @@
<string name="master_clear_gesture_explanation">You must draw your unlock pattern to confirm a factory data reset.</string>
<!-- Master clear failed message -->
<string name="master_clear_failed">No reset was performed because the System Clear service is not available.</string>
<!-- Master clear confirmation screen title [CHAR LIMIT=30] -->
<string name="master_clear_confirm_title">Confirm reset</string>
<!-- Media Format -->
<!-- SD card & phone storage settings screen, setting option name under Internal phone storage heading [CHAR LIMIT=25] -->

View File

@@ -33,15 +33,11 @@
</PreferenceCategory>
<PreferenceCategory
android:title="@string/personal_data_section_title">
android:title="@string/personal_data_section_title"/>
<!-- Factory reset -->
<PreferenceScreen
android:title="@string/master_clear_title"
android:summary="@string/master_clear_summary">
<intent android:action="android.intent.action.MAIN"
android:targetPackage="com.android.settings"
android:targetClass="com.android.settings.MasterClear" />
</PreferenceScreen>
</PreferenceCategory>
<PreferenceScreen
android:title="@string/master_clear_title"
android:summary="@string/master_clear_summary"
android:fragment="com.android.settings.MasterClear" />
</PreferenceScreen>

View File

@@ -16,21 +16,28 @@
package com.android.settings;
import com.android.internal.widget.LockPatternUtils;
import android.app.Activity;
import android.app.Fragment;
import android.app.admin.DevicePolicyManager;
import android.content.Intent;
import com.android.internal.widget.LockPatternUtils;
public class ChooseLockSettingsHelper {
private LockPatternUtils mLockPatternUtils;
private Activity mActivity;
private Fragment mFragment;
public ChooseLockSettingsHelper(Activity activity) {
mActivity = activity;
mLockPatternUtils = new LockPatternUtils(activity);
}
public ChooseLockSettingsHelper(Activity activity, Fragment fragment) {
this(activity);
mFragment = fragment;
}
public LockPatternUtils utils() {
return mLockPatternUtils;
}
@@ -76,7 +83,11 @@ public class ChooseLockSettingsHelper {
intent.putExtra(ConfirmLockPattern.HEADER_TEXT, message);
intent.putExtra(ConfirmLockPattern.FOOTER_TEXT, details);
intent.setClassName("com.android.settings", "com.android.settings.ConfirmLockPattern");
mActivity.startActivityForResult(intent, request);
if (mFragment != null) {
mFragment.startActivityForResult(intent, request);
} else {
mActivity.startActivityForResult(intent, request);
}
return true;
}
@@ -89,7 +100,11 @@ public class ChooseLockSettingsHelper {
if (!mLockPatternUtils.isLockPasswordEnabled()) return false;
final Intent intent = new Intent();
intent.setClassName("com.android.settings", "com.android.settings.ConfirmLockPassword");
mActivity.startActivityForResult(intent, request);
if (mFragment != null) {
mFragment.startActivityForResult(intent, request);
} else {
mActivity.startActivityForResult(intent, request);
}
return true;
}

View File

@@ -16,14 +16,18 @@
package com.android.settings;
import com.android.internal.os.storage.ExternalStorageFormatter;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
@@ -34,44 +38,20 @@ import android.widget.CheckBox;
* has defined one, followed by a final strongly-worded "THIS WILL ERASE EVERYTHING
* ON THE PHONE" prompt. If at any time the phone is allowed to go to sleep, is
* locked, et cetera, then the confirmation sequence is abandoned.
*
* This is the initial screen.
*/
public class MasterClear extends Activity {
public class MasterClear extends Fragment {
private static final int KEYGUARD_REQUEST = 55;
private LayoutInflater mInflater;
private LockPatternUtils mLockUtils;
static final String ERASE_EXTERNAL_EXTRA = "erase_sd";
private View mInitialView;
private View mContentView;
private Button mInitiateButton;
private View mExternalStorageContainer;
private CheckBox mExternalStorage;
private View mFinalView;
private Button mFinalButton;
/**
* The user has gone through the multiple confirmation, so now we go ahead
* and invoke the Checkin Service to reset the device to its factory-default
* state (rebooting in the process).
*/
private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {
public void onClick(View v) {
if (Utils.isMonkeyRunning()) {
return;
}
if (mExternalStorage.isChecked()) {
Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
startService(intent);
} else {
sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR"));
// Intent handling is asynchronous -- assume it will happen soon.
}
}
};
/**
* Keyguard validation is run using the standard {@link ConfirmLockPattern}
* component as a subactivity
@@ -79,14 +59,15 @@ public class MasterClear extends Activity {
* @return true if confirmation launched
*/
private boolean runKeyguardConfirmation(int request) {
return new ChooseLockSettingsHelper(this)
Resources res = getActivity().getResources();
return new ChooseLockSettingsHelper(getActivity(), this)
.launchConfirmationActivity(request,
getText(R.string.master_clear_gesture_prompt),
getText(R.string.master_clear_gesture_explanation));
res.getText(R.string.master_clear_gesture_prompt),
res.getText(R.string.master_clear_gesture_explanation));
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode != KEYGUARD_REQUEST) {
@@ -96,40 +77,33 @@ public class MasterClear extends Activity {
// If the user entered a valid keyguard trace, present the final
// confirmation prompt; otherwise, go back to the initial state.
if (resultCode == Activity.RESULT_OK) {
establishFinalConfirmationState();
} else if (resultCode == Activity.RESULT_CANCELED) {
finish();
showFinalConfirmation();
} else {
establishInitialState();
}
}
private void showFinalConfirmation() {
Preference preference = new Preference(getActivity());
preference.setFragment(MasterClearConfirm.class.getName());
preference.setTitle(R.string.master_clear_confirm_title);
preference.getExtras().putBoolean(ERASE_EXTERNAL_EXTRA, mExternalStorage.isChecked());
((PreferenceActivity) getActivity()).onPreferenceStartFragment(null, preference);
}
/**
* If the user clicks to begin the reset sequence, we next require a
* keyguard confirmation if the user has currently enabled one. If there
* is no keyguard available, we simply go to the final confirmation prompt.
*/
private Button.OnClickListener mInitiateListener = new Button.OnClickListener() {
public void onClick(View v) {
if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
establishFinalConfirmationState();
}
public void onClick(View v) {
if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
showFinalConfirmation();
}
};
/**
* Configure the UI for the final confirmation interaction
*/
private void establishFinalConfirmationState() {
if (mFinalView == null) {
mFinalView = mInflater.inflate(R.layout.master_clear_final, null);
mFinalButton =
(Button) mFinalView.findViewById(R.id.execute_master_clear);
mFinalButton.setOnClickListener(mFinalClickListener);
}
setContentView(mFinalView);
}
};
/**
* In its initial state, the activity presents a button for the user to
@@ -144,48 +118,25 @@ public class MasterClear extends Activity {
* to change contents.
*/
private void establishInitialState() {
if (mInitialView == null) {
mInitialView = mInflater.inflate(R.layout.master_clear_primary, null);
mInitiateButton =
(Button) mInitialView.findViewById(R.id.initiate_master_clear);
mInitiateButton.setOnClickListener(mInitiateListener);
mExternalStorageContainer =
mInitialView.findViewById(R.id.erase_external_container);
mExternalStorage =
(CheckBox) mInitialView.findViewById(R.id.erase_external);
mExternalStorageContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mExternalStorage.toggle();
}
});
}
mInitiateButton = (Button) mContentView.findViewById(R.id.initiate_master_clear);
mInitiateButton.setOnClickListener(mInitiateListener);
mExternalStorageContainer = mContentView.findViewById(R.id.erase_external_container);
mExternalStorage = (CheckBox) mContentView.findViewById(R.id.erase_external);
setContentView(mInitialView);
mExternalStorageContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mExternalStorage.toggle();
}
});
}
@Override
protected void onCreate(Bundle savedState) {
super.onCreate(savedState);
mInitialView = null;
mFinalView = null;
mInflater = LayoutInflater.from(this);
mLockUtils = new LockPatternUtils(this);
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mContentView = inflater.inflate(R.layout.master_clear, null);
establishInitialState();
}
/** Abandon all progress through the confirmation sequence by returning
* to the initial view any time the activity is interrupted (e.g. by
* idle timeout).
*/
@Override
public void onPause() {
super.onPause();
if (!isFinishing()) {
establishInitialState();
}
return mContentView;
}
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright (C) 2010 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;
import com.android.internal.os.storage.ExternalStorageFormatter;
import com.android.internal.widget.LockPatternUtils;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
/**
* Confirm and execute a reset of the device to a clean "just out of the box"
* state. Multiple confirmations are required: first, a general "are you sure
* you want to do this?" prompt, followed by a keyguard pattern trace if the user
* has defined one, followed by a final strongly-worded "THIS WILL ERASE EVERYTHING
* ON THE PHONE" prompt. If at any time the phone is allowed to go to sleep, is
* locked, et cetera, then the confirmation sequence is abandoned.
*
* This is the confirmation screen.
*/
public class MasterClearConfirm extends Fragment {
private View mContentView;
private boolean mEraseSdCard;
private Button mFinalButton;
/**
* The user has gone through the multiple confirmation, so now we go ahead
* and invoke the Checkin Service to reset the device to its factory-default
* state (rebooting in the process).
*/
private Button.OnClickListener mFinalClickListener = new Button.OnClickListener() {
public void onClick(View v) {
if (Utils.isMonkeyRunning()) {
return;
}
if (mEraseSdCard) {
Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
getActivity().startService(intent);
} else {
getActivity().sendBroadcast(new Intent("android.intent.action.MASTER_CLEAR"));
// Intent handling is asynchronous -- assume it will happen soon.
}
}
};
/**
* Configure the UI for the final confirmation interaction
*/
private void establishFinalConfirmationState() {
mFinalButton = (Button) mContentView.findViewById(R.id.execute_master_clear);
mFinalButton.setOnClickListener(mFinalClickListener);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mContentView = inflater.inflate(R.layout.master_clear_confirm, null);
establishFinalConfirmationState();
return mContentView;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
mEraseSdCard = args != null ? args.getBoolean(MasterClear.ERASE_EXTERNAL_EXTRA) : false;
}
}

View File

@@ -98,7 +98,7 @@ public class PrivacySettings extends SettingsPreferenceFragment implements
}
}
return false;
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
private void showEraseBackupDialog() {

View File

@@ -155,7 +155,6 @@ public class SettingsPreferenceFragment extends PreferenceFragment
mDialogFragment.show(getActivity().getFragmentManager(), Integer.toString(dialogId));
}
@Override
public Dialog onCreateDialog(int dialogId) {
return null;
}

View File

@@ -46,8 +46,8 @@ public class BluetoothPairingDialog extends AlertActivity implements DialogInter
TextWatcher {
private static final String TAG = "BluetoothPairingDialog";
private final int BLUETOOTH_PIN_MAX_LENGTH = 16;
private final int BLUETOOTH_PASSKEY_MAX_LENGTH = 6;
private static final int BLUETOOTH_PIN_MAX_LENGTH = 16;
private static final int BLUETOOTH_PASSKEY_MAX_LENGTH = 6;
private LocalBluetoothManager mLocalManager;
private BluetoothDevice mDevice;
private int mType;

View File

@@ -251,7 +251,6 @@ public class BluetoothSettings extends SettingsPreferenceFragment
}
}
@Override
public void onUserLeaveHint() {
mLocalManager.stopScanning();
}

View File

@@ -104,9 +104,9 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
* @param profile Profile to describe
* @return Description of the device and profile
*/
private String describe(CachedBluetoothDevice cachedDevice, Profile profile) {
private String describe(Profile profile) {
StringBuilder sb = new StringBuilder();
sb.append("Address:").append(cachedDevice.mDevice);
sb.append("Address:").append(mDevice);
if (profile != null) {
sb.append(" Profile:").append(profile.name());
}
@@ -114,10 +114,6 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
return sb.toString();
}
private String describe(Profile profile) {
return describe(this, profile);
}
public void onProfileStateChanged(Profile profile, int newProfileState) {
if (D) {
Log.d(TAG, "onProfileStateChanged: profile " + profile.toString() +
@@ -166,20 +162,13 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
}
public void disconnect(Profile profile) {
disconnectInt(this, profile);
}
private boolean disconnectInt(CachedBluetoothDevice cachedDevice, Profile profile) {
LocalBluetoothProfileManager profileManager =
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
int status = profileManager.getConnectionStatus(cachedDevice.mDevice);
if (profileManager.disconnect(cachedDevice.mDevice)) {
if (profileManager.disconnect(mDevice)) {
if (D) {
Log.d(TAG, "Command sent successfully:DISCONNECT " + describe(profile));
}
return true;
}
return false;
}
public void askDisconnect() {
@@ -204,6 +193,57 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
}
};
showDisconnectDialog(context, disconnectListener, message);
}
public void askDisconnect(final Profile profile) {
Context context = mLocalManager.getForegroundActivity();
if (context == null) {
// Cannot ask, since we need an activity context
disconnect(profile);
return;
}
Resources res = context.getResources();
String name = getName();
if (TextUtils.isEmpty(name)) {
name = res.getString(R.string.bluetooth_device);
}
int disconnectMessage;
switch (profile) {
case A2DP:
disconnectMessage = R.string.bluetooth_disconnect_a2dp_profile;
break;
case HEADSET:
disconnectMessage = R.string.bluetooth_disconnect_headset_profile;
break;
case HID:
disconnectMessage = R.string.bluetooth_disconnect_hid_profile;
break;
case PAN:
disconnectMessage = R.string.bluetooth_disconnect_pan_profile;
break;
default:
Log.w(TAG, "askDisconnect: unexpected profile " + profile);
disconnectMessage = R.string.bluetooth_disconnect_blank;
break;
}
String message = res.getString(disconnectMessage, name);
DialogInterface.OnClickListener disconnectListener =
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
disconnect(profile);
}
};
showDisconnectDialog(context, disconnectListener, message);
}
private void showDisconnectDialog(Context context,
DialogInterface.OnClickListener disconnectListener,
String message) {
if (mDialog == null) {
mDialog = new AlertDialog.Builder(context)
.setPositiveButton(android.R.string.ok, disconnectListener)
@@ -213,6 +253,10 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
if (mDialog.isShowing()) {
mDialog.dismiss();
}
// use disconnectListener for the correct profile(s)
CharSequence okText = context.getText(android.R.string.ok);
mDialog.setButton(DialogInterface.BUTTON_POSITIVE,
okText, disconnectListener);
}
mDialog.setTitle(getName());
mDialog.setMessage(message);
@@ -311,7 +355,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
CachedBluetoothDevice cachedDevice = cachedDeviceManager.findDevice(btDevice);
if (cachedDevice != null && !cachedDevice.equals(device)) {
disconnectInt(cachedDevice, profile);
cachedDevice.disconnect(profile);
}
}
}
@@ -321,7 +365,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
LocalBluetoothProfileManager profileManager =
LocalBluetoothProfileManager.getProfileManager(mLocalManager, profile);
int status = profileManager.getConnectionStatus(cachedDevice.mDevice);
if (profileManager.connect(cachedDevice.mDevice)) {
if (D) {
Log.d(TAG, "Command sent successfully:CONNECT " + describe(profile));

View File

@@ -21,7 +21,6 @@ import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
@@ -35,8 +34,8 @@ import android.view.View;
import java.util.HashMap;
/**
* ConnectSpecificProfilesActivity presents the user with all of the profiles
* for a particular device, and allows him to choose which should be connected
* This preference fragment presents the user with all of the profiles
* for a particular device, and allows them to be individually connected
* (or disconnected).
*/
public class DeviceProfilesSettings extends SettingsPreferenceFragment
@@ -155,9 +154,6 @@ public class DeviceProfilesSettings extends SettingsPreferenceFragment
pref.setOrder(getProfilePreferenceIndex(profile));
pref.setOnExpandClickListener(this);
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
.getProfileManager(mManager, profile);
/**
* Gray out profile while connecting and disconnecting
*/
@@ -172,7 +168,7 @@ public class DeviceProfilesSettings extends SettingsPreferenceFragment
public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
String key = preference.getKey();
if (preference instanceof BluetoothProfilePreference) {
onProfileClicked(preference, Profile.valueOf(key));
onProfileClicked(Profile.valueOf(key));
return true;
} else if (key.equals(KEY_UNPAIR)) {
unpairDevice();
@@ -196,18 +192,24 @@ public class DeviceProfilesSettings extends SettingsPreferenceFragment
return true;
}
private void onProfileClicked(Preference preference, Profile profile) {
private void onProfileClicked(Profile profile) {
BluetoothDevice device = mCachedDevice.getDevice();
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
.getProfileManager(mManager, profile);
// TODO: Get the current state and flip it, updating the summary for the preference
// profileManager.setPreferred(mCachedDevice.getDevice(), checked);
//
// if (checked) {
// mCachedDevice.connect(profile);
// } else {
// mCachedDevice.disconnect(profile);
// }
int status = profileManager.getConnectionStatus(device);
boolean isConnected =
SettingsBtStatus.isConnectionStatusConnected(status);
// TODO: only change the preference on disconnect if user confirms
// TODO: add method to change priority of individual profiles
// profileManager.setPreferred(device, !isConnected);
if (isConnected) {
mCachedDevice.askDisconnect(profile);
} else {
mCachedDevice.connect(profile);
}
}
public void onDeviceAttributesChanged(CachedBluetoothDevice cachedDevice) {

View File

@@ -496,7 +496,7 @@ public class DockService extends Service implements AlertDialog.OnMultiChoiceCli
private CharSequence[] initBtSettings(DockService service, BluetoothDevice device, int state,
boolean firstTime) {
// TODO Avoid hardcoding dock and profiles. Read from system properties
int numOfProfiles = 0;
int numOfProfiles;
switch (state) {
case Intent.EXTRA_DOCK_STATE_DESK:
numOfProfiles = 1;
@@ -729,7 +729,7 @@ public class DockService extends Service implements AlertDialog.OnMultiChoiceCli
profileManager.setPreferred(device, mCheckedItems[i]);
if (DEBUG) {
if (mCheckedItems[i] != profileManager.isPreferred(device)) {
Log.e(TAG, "Can't save prefered value");
Log.e(TAG, "Can't save preferred value");
}
}
}

View File

@@ -70,7 +70,7 @@ public class LocalBluetoothManager {
// If a device was picked from the device picker or was in discoverable mode
// in the last 60 seconds, show the pairing dialogs in foreground instead
// of raising notifications
private static long GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND = 60 * 1000;
private static final int GRACE_PERIOD_TO_SHOW_DIALOGS_IN_FOREGROUND = 60 * 1000;
public static final String SHARED_PREFERENCES_KEY_DISCOVERING_TIMESTAMP =
"last_discovering_time";

View File

@@ -225,7 +225,7 @@ public abstract class LocalBluetoothProfileManager {
}
// TODO: int instead of enum
public enum Profile {
public static enum Profile {
HEADSET(R.string.bluetooth_profile_headset),
A2DP(R.string.bluetooth_profile_a2dp),
OPP(R.string.bluetooth_profile_opp),
@@ -433,7 +433,7 @@ public abstract class LocalBluetoothProfileManager {
public boolean disconnect(BluetoothDevice device) {
List<BluetoothDevice> deviceList = getConnectedDevices();
if (deviceList.size() != 0 && deviceList.get(0).equals(device)) {
// Downgrade prority as user is disconnecting the headset.
// Downgrade priority as user is disconnecting the headset.
if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
}

View File

@@ -48,15 +48,19 @@ public class InputMethodAndSubtypeUtil {
private static final TextUtils.SimpleStringSplitter sStringInputMethodSubtypeSplitter
= new TextUtils.SimpleStringSplitter(INPUT_METHOD_SUBTYPE_SEPARATER);
private static boolean isInputMethodSubtypeSelected(ContentResolver resolver) {
private static int getInputMethodSubtypeSelected(ContentResolver resolver) {
try {
return Settings.Secure.getInt(resolver,
Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE) != NOT_A_SUBTYPE_ID;
Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE);
} catch (SettingNotFoundException e) {
return false;
return NOT_A_SUBTYPE_ID;
}
}
private static boolean isInputMethodSubtypeSelected(ContentResolver resolver) {
return getInputMethodSubtypeSelected(resolver) != NOT_A_SUBTYPE_ID;
}
private static void putSelectedInputMethodSubtype(ContentResolver resolver, int hashCode) {
Settings.Secure.putInt(resolver, Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, hashCode);
}
@@ -98,6 +102,7 @@ public class InputMethodAndSubtypeUtil {
boolean hasHardKeyboard, String lastTickedInputMethodId) {
String currentInputMethodId = Settings.Secure.getString(resolver,
Settings.Secure.DEFAULT_INPUT_METHOD);
final int selectedInputMethodSubtype = getInputMethodSubtypeSelected(resolver);
StringBuilder builder = new StringBuilder();
StringBuilder disabledSysImes = new StringBuilder();
@@ -105,6 +110,7 @@ public class InputMethodAndSubtypeUtil {
int firstSubtypeHashCode = NOT_A_SUBTYPE_ID;
final boolean onlyOneIME = inputMethodProperties.size() == 1;
boolean existsSelectedIME = false;
for (InputMethodInfo property : inputMethodProperties) {
final String id = property.getId();
CheckBoxPreference pref = (CheckBoxPreference) context.findPreference(id);
@@ -123,8 +129,12 @@ public class InputMethodAndSubtypeUtil {
id + subtype.hashCode());
if (subtypePref != null && subtypePref.isChecked()) {
builder.append(INPUT_METHOD_SUBTYPE_SEPARATER).append(subtype.hashCode());
if (firstSubtypeHashCode == NOT_A_SUBTYPE_ID) {
firstSubtypeHashCode = subtype.hashCode();
if (isCurrentInputMethod) {
if (selectedInputMethodSubtype == subtype.hashCode()) {
existsSelectedIME = true;
} else if (firstSubtypeHashCode == NOT_A_SUBTYPE_ID) {
firstSubtypeHashCode = subtype.hashCode();
}
}
}
}
@@ -158,9 +168,10 @@ public class InputMethodAndSubtypeUtil {
Log.d(TAG, "--- Save default inputmethod settings. :" + currentInputMethodId);
}
// redefines SelectedSubtype when all subtypes are unchecked or there is no subtype
// selected.
if (firstSubtypeHashCode == NOT_A_SUBTYPE_ID || !isInputMethodSubtypeSelected(resolver)) {
// Redefines SelectedSubtype when all subtypes are unchecked or there is no subtype
// selected. And if the selected subtype of the current input method was disabled,
// We should reset the selected input method's subtype.
if (!existsSelectedIME || !isInputMethodSubtypeSelected(resolver)) {
if (DEBUG) {
Log.d(TAG, "--- Set inputmethod subtype because it's not defined."
+ firstSubtypeHashCode);

View File

@@ -74,6 +74,8 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
// This is a tweak for letting users not confused with WiFi state during a first first steps.
private int mIgnoringWifiNotificationCount = 5;
private boolean mShowingConnectingMessageManually = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -127,6 +129,14 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
break;
case R.id.wifi_setup_connect:
mWifiSettings.submit();
// updateConnectionState() isn't called soon after the user's "connect" action,
// and the user still sees "not connected" message for a while, which looks strange.
// We instead manually show "connecting" message before the system gets actual
// "connecting" message from Wi-Fi module.
showConnectingStatus();
mShowingConnectingMessageManually = true;
mIgnoringWifiNotificationCount = 2;
break;
case R.id.wifi_setup_forget:
mWifiSettings.forget();
@@ -167,10 +177,8 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
break;
}
case CONNECTING: {
mProgressBar.setIndeterminate(false);
mProgressBar.setProgress(1);
mStatusText.setText(R.string.wifi_setup_status_connecting);
mProgressText.setText(Summary.get(this, state));
mShowingConnectingMessageManually = false;
showConnectingStatus();
break;
}
case CONNECTED: {
@@ -200,12 +208,15 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
break;
}
default: // Not connected.
if (mWifiSettings.getAccessPointsCount() == 0 &&
mIgnoringWifiNotificationCount > 0) {
if (mWifiSettings.getAccessPointsCount() == 0 && mIgnoringWifiNotificationCount > 0) {
mIgnoringWifiNotificationCount--;
mProgressBar.setIndeterminate(true);
mProgressText.setText(Summary.get(this, DetailedState.SCANNING));
} else if (mShowingConnectingMessageManually && mIgnoringWifiNotificationCount > 0) {
mIgnoringWifiNotificationCount--;
showConnectingStatus();
} else {
mShowingConnectingMessageManually = false;
mProgressBar.setIndeterminate(false);
mProgressBar.setProgress(0);
mStatusText.setText(R.string.wifi_setup_status_select_network);
@@ -217,6 +228,13 @@ public class WifiSettingsForSetupWizardXL extends Activity implements OnClickLis
}
}
private void showConnectingStatus() {
mProgressBar.setIndeterminate(false);
mProgressBar.setProgress(1);
mStatusText.setText(R.string.wifi_setup_status_connecting);
mProgressText.setText(Summary.get(this, DetailedState.CONNECTING));
}
private void enableButtons() {
((Button)findViewById(R.id.wifi_setup_refresh_list)).setEnabled(true);
((Button)findViewById(R.id.wifi_setup_add_network)).setEnabled(true);