From f1e484acb594a726fb57ad0ae4cfe902c7f35858 Mon Sep 17 00:00:00 2001
From: The Android Open Source Project
Date: Thu, 22 Jan 2009 00:13:42 -0800
Subject: [PATCH] auto import from //branches/cupcake/...@127436
---
api/current.xml | 166 ++++++++++++
cmds/installd/commands.c | 6 +-
core/java/android/app/Activity.java | 15 ++
core/java/android/app/ActivityThread.java | 21 +-
core/java/android/app/ApplicationContext.java | 22 +-
core/java/android/app/ApplicationThreadNative.java | 6 +-
core/java/android/app/IApplicationThread.java | 2 +-
core/java/android/app/Instrumentation.java | 10 +
core/java/android/app/SearchDialog.java | 34 ++-
core/java/android/bluetooth/BluetoothDevice.java | 102 ++++----
core/java/android/bluetooth/BluetoothIntent.java | 23 +-
core/java/android/bluetooth/IBluetoothDevice.aidl | 10 +-
.../bluetooth/IBluetoothDeviceCallback.aidl | 1 -
core/java/android/content/Intent.java | 34 +++
core/java/android/content/pm/IPackageManager.aidl | 60 +++--
core/java/android/content/pm/PackageManager.java | 60 +++--
core/java/android/gadget/GadgetManager.java | 22 +-
.../inputmethodservice/InputMethodService.java | 35 ++-
.../android/inputmethodservice/KeyboardView.java | 22 +-
core/java/android/os/BatteryStats.java | 17 +-
core/java/android/provider/Gmail.java | 12 +-
core/java/android/provider/MediaStore.java | 7 +
core/java/android/provider/Settings.java | 22 ++
core/java/android/server/BluetoothA2dpService.java | 19 +-
.../android/server/BluetoothDeviceService.java | 270 +++++++++++--------
core/java/android/server/BluetoothEventLoop.java | 92 +++----
.../java/android/server/search/SearchableInfo.java | 2 +
core/java/android/text/TextUtils.java | 6 +-
core/java/android/view/WindowManagerPolicy.java | 12 +-
.../android/view/inputmethod/InputConnection.java | 13 +
.../view/inputmethod/InputConnectionWrapper.java | 8 +
.../view/inputmethod/InputMethodManager.java | 14 +
core/java/android/webkit/LoadListener.java | 23 +-
core/java/android/webkit/WebView.java | 7 +-
core/java/android/widget/Button.java | 2 +
core/java/android/widget/ImageButton.java | 2 +
core/java/android/widget/RemoteViews.java | 66 ++++-
core/java/android/widget/TextView.java | 40 ++-
.../android/internal/gadget/IGadgetService.aidl | 1 +
.../internal/view/IInputConnectionWrapper.java | 18 ++
.../com/android/internal/view/IInputContext.aidl | 4 +
.../internal/view/InputConnectionWrapper.java | 18 ++
.../internal/widget/EditableInputConnection.java | 12 +
core/jni/android/graphics/Bitmap.cpp | 25 +-
core/jni/android_server_BluetoothDeviceService.cpp | 43 +--
core/jni/android_server_BluetoothEventLoop.cpp | 31 ++-
core/res/res/anim/status_bar_enter.xml | 24 ++
core/res/res/anim/status_bar_exit.xml | 24 ++
core/res/res/values-cs/arrays.xml | 4 -
core/res/res/values-cs/strings.xml | 14 +
core/res/res/values-de/arrays.xml | 4 -
core/res/res/values-de/strings.xml | 14 +
core/res/res/values-es/arrays.xml | 4 -
core/res/res/values-es/strings.xml | 14 +
core/res/res/values-fr/arrays.xml | 4 -
core/res/res/values-fr/strings.xml | 14 +
core/res/res/values-it/arrays.xml | 4 -
core/res/res/values-it/strings.xml | 14 +
core/res/res/values-ja/arrays.xml | 4 -
core/res/res/values-ja/strings.xml | 14 +
core/res/res/values-mcc204-cs/strings.xml | 14 +
core/res/res/values-mcc204-de/strings.xml | 14 +
core/res/res/values-mcc204-es/strings.xml | 14 +
core/res/res/values-mcc204-fr/strings.xml | 14 +
core/res/res/values-mcc204-it/strings.xml | 14 +
core/res/res/values-mcc204-ja/strings.xml | 14 +
core/res/res/values-mcc204-nl/strings.xml | 14 +
core/res/res/values-mcc204-pl/strings.xml | 14 +
core/res/res/values-mcc204-ru/strings.xml | 14 +
core/res/res/values-mcc204-zh-rCN/strings.xml | 14 +
core/res/res/values-mcc204-zh-rTW/strings.xml | 14 +
core/res/res/values-mcc230-cs/strings.xml | 14 +
core/res/res/values-mcc230-de/strings.xml | 14 +
core/res/res/values-mcc230-es/strings.xml | 14 +
core/res/res/values-mcc230-fr/strings.xml | 14 +
core/res/res/values-mcc230-it/strings.xml | 14 +
core/res/res/values-mcc230-ja/strings.xml | 14 +
core/res/res/values-mcc230-nl/strings.xml | 14 +
core/res/res/values-mcc230-pl/strings.xml | 14 +
core/res/res/values-mcc230-ru/strings.xml | 14 +
core/res/res/values-mcc230-zh-rCN/strings.xml | 14 +
core/res/res/values-mcc230-zh-rTW/strings.xml | 14 +
core/res/res/values-mcc232-cs/strings.xml | 14 +
core/res/res/values-mcc232-de/strings.xml | 14 +
core/res/res/values-mcc232-es/strings.xml | 14 +
core/res/res/values-mcc232-fr/strings.xml | 14 +
core/res/res/values-mcc232-it/strings.xml | 14 +
core/res/res/values-mcc232-ja/strings.xml | 14 +
core/res/res/values-mcc232-nl/strings.xml | 14 +
core/res/res/values-mcc232-pl/strings.xml | 14 +
core/res/res/values-mcc232-ru/strings.xml | 14 +
core/res/res/values-mcc232-zh-rCN/strings.xml | 14 +
core/res/res/values-mcc232-zh-rTW/strings.xml | 14 +
core/res/res/values-mcc234-cs/strings.xml | 14 +
core/res/res/values-mcc234-de/strings.xml | 14 +
core/res/res/values-mcc234-es/strings.xml | 14 +
core/res/res/values-mcc234-fr/strings.xml | 14 +
core/res/res/values-mcc234-it/strings.xml | 14 +
core/res/res/values-mcc234-ja/strings.xml | 14 +
core/res/res/values-mcc234-nl/strings.xml | 14 +
core/res/res/values-mcc234-pl/strings.xml | 14 +
core/res/res/values-mcc234-ru/strings.xml | 14 +
core/res/res/values-mcc234-zh-rCN/strings.xml | 14 +
core/res/res/values-mcc234-zh-rTW/strings.xml | 14 +
core/res/res/values-mcc260-cs/strings.xml | 14 +
core/res/res/values-mcc260-de/strings.xml | 14 +
core/res/res/values-mcc260-es/strings.xml | 14 +
core/res/res/values-mcc260-fr/strings.xml | 14 +
core/res/res/values-mcc260-it/strings.xml | 14 +
core/res/res/values-mcc260-ja/strings.xml | 14 +
core/res/res/values-mcc260-nl/strings.xml | 14 +
core/res/res/values-mcc260-pl/strings.xml | 14 +
core/res/res/values-mcc260-ru/strings.xml | 14 +
core/res/res/values-mcc260-zh-rCN/strings.xml | 14 +
core/res/res/values-mcc260-zh-rTW/strings.xml | 14 +
core/res/res/values-mcc262-cs/strings.xml | 14 +
core/res/res/values-mcc262-de/strings.xml | 14 +
core/res/res/values-mcc262-es/strings.xml | 14 +
core/res/res/values-mcc262-fr/strings.xml | 14 +
core/res/res/values-mcc262-it/strings.xml | 14 +
core/res/res/values-mcc262-ja/strings.xml | 14 +
core/res/res/values-mcc262-nl/strings.xml | 14 +
core/res/res/values-mcc262-pl/strings.xml | 14 +
core/res/res/values-mcc262-ru/strings.xml | 14 +
core/res/res/values-mcc262-zh-rCN/strings.xml | 14 +
core/res/res/values-mcc262-zh-rTW/strings.xml | 14 +
core/res/res/values-nl/arrays.xml | 4 -
core/res/res/values-nl/strings.xml | 14 +
core/res/res/values-pl/arrays.xml | 4 -
core/res/res/values-pl/strings.xml | 14 +
core/res/res/values-ru/arrays.xml | 4 -
core/res/res/values-ru/strings.xml | 14 +
core/res/res/values-zh-rCN/arrays.xml | 4 -
core/res/res/values-zh-rCN/strings.xml | 14 +
core/res/res/values-zh-rTW/arrays.xml | 4 -
core/res/res/values-zh-rTW/strings.xml | 14 +
core/res/res/values/attrs.xml | 17 ++
core/res/res/values/public.xml | 2 +
core/res/res/values/styles.xml | 6 +
core/res/res/values/themes.xml | 2 +-
data/localization/import-from-xtb | 7 +-
graphics/java/android/graphics/Bitmap.java | 32 +++
graphics/java/android/graphics/BitmapFactory.java | 5 -
.../android/graphics/drawable/LayerDrawable.java | 8 +-
libs/audioflinger/AudioFlinger.cpp | 80 +++++-
libs/audioflinger/AudioFlinger.h | 13 +
.../internal/location/GpsLocationProvider.java | 34 ++-
.../com/android/server/DeviceMemoryMonitor.java | 288 ---------------------
.../server/DeviceStorageMonitorService.java | 2 +-
.../java/com/android/server/GadgetService.java | 248 +++++++++++++++++-
.../com/android/server/PackageManagerService.java | 47 +++-
.../com/android/server/WindowManagerService.java | 56 +++-
.../android/server/am/ActivityManagerService.java | 43 ++-
.../android/server/status/StatusBarService.java | 1 +
.../internal/telephony/gsm/stk/StkService.java | 19 +-
.../android/test/mock/MockPackageManager.java | 12 +-
.../src/com/android/unit_tests/AppCacheTest.java | 82 +++++-
.../src/com/android/unit_tests/BluetoothTest.java | 21 +-
.../res/layout/remote_view_test_good.xml | 9 +
.../view/RemoteViewsActivityTest.java | 2 +
tests/GadgetHost/AndroidManifest.xml | 4 +
tests/GadgetHost/res/xml/gadget_info.xml | 7 +
.../com/android/gadgethost/GadgetHostActivity.java | 3 -
.../com/android/gadgethost/GadgetPickActivity.java | 17 +-
tests/ImfTest/Android.mk | 15 ++
tests/ImfTest/AndroidManifest.xml | 24 ++
tests/ImfTest/res/layout/sample_edit_text.xml | 53 ++++
tests/ImfTest/res/values/strings.xml | 39 +++
.../android/imftest/samples/ButtonActivity.java | 52 ++++
.../android/imftest/samples/InputTypeActivity.java | 140 ++++++++++
170 files changed, 3180 insertions(+), 817 deletions(-)
create mode 100644 core/res/res/anim/status_bar_enter.xml
create mode 100644 core/res/res/anim/status_bar_exit.xml
delete mode 100644 core/res/res/values-cs/arrays.xml
delete mode 100644 core/res/res/values-de/arrays.xml
delete mode 100644 core/res/res/values-es/arrays.xml
delete mode 100644 core/res/res/values-fr/arrays.xml
delete mode 100644 core/res/res/values-it/arrays.xml
delete mode 100644 core/res/res/values-ja/arrays.xml
delete mode 100644 core/res/res/values-nl/arrays.xml
delete mode 100644 core/res/res/values-pl/arrays.xml
delete mode 100644 core/res/res/values-ru/arrays.xml
delete mode 100644 core/res/res/values-zh-rCN/arrays.xml
delete mode 100644 core/res/res/values-zh-rTW/arrays.xml
delete mode 100644 services/java/com/android/server/DeviceMemoryMonitor.java
create mode 100644 tests/GadgetHost/res/xml/gadget_info.xml
create mode 100755 tests/ImfTest/Android.mk
create mode 100755 tests/ImfTest/AndroidManifest.xml
create mode 100755 tests/ImfTest/res/layout/sample_edit_text.xml
create mode 100755 tests/ImfTest/res/values/strings.xml
create mode 100644 tests/ImfTest/src/com/android/imftest/samples/ButtonActivity.java
create mode 100755 tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
diff --git a/api/current.xml b/api/current.xml
index e183217d003c..935454a19e53 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -3738,6 +3738,17 @@
visibility="public"
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ free_size) return 0;
+ if (avail >= free_size) return 0;
d = opendir(PKG_DIR_PREFIX);
if (d == NULL) {
LOGE("cannot open %s\n", PKG_DIR_PREFIX);
- return 0;
+ return -1;
}
dfd = dirfd(d);
@@ -144,7 +144,7 @@ int free_cache(int free_size)
close(subfd);
avail = disk_free();
- if (avail > free_size) {
+ if (avail >= free_size) {
closedir(d);
return 0;
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index c98cf1bbd356..4dc4b6a48b85 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1132,6 +1132,17 @@ public class Activity extends ContextThemeWrapper
}
/**
+ * Called as part of the activity lifecycle when an activity is about to go
+ * into the background as the result of user choice. For example, when the
+ * user presses the Home key, {@link #onUserLeaving} will be called, but
+ * when an incoming phone call causes the in-call Activity to be automatically
+ * brought to the foreground, {@link #onUserLeaving} will not be called on
+ * the activity being interrupted.
+ */
+ protected void onUserLeaving() {
+ }
+
+ /**
* Generate a new thumbnail for this activity. This method is called before
* pausing the activity, and should draw into outBitmap the
* imagery for the desired thumbnail in the dimensions of that bitmap. It
@@ -3470,6 +3481,10 @@ public class Activity extends ContextThemeWrapper
onPause();
}
+ final void performUserLeaving() {
+ onUserLeaving();
+ }
+
final void performStop() {
if (!mStopped) {
if (mWindow != null) {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index a98e29594aac..e4c1057e3878 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1207,10 +1207,12 @@ public final class ActivityThread {
private static final String TWO_COUNT_COLUMNS = "%17s %8d %17s %8d";
public final void schedulePauseActivity(IBinder token, boolean finished,
- int configChanges) {
+ boolean userLeaving, int configChanges) {
queueOrSendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
- token, configChanges);
+ token,
+ (userLeaving ? 1 : 0),
+ configChanges);
}
public final void scheduleStopActivity(IBinder token, boolean showWindow,
@@ -1588,10 +1590,10 @@ public final class ActivityThread {
handleRelaunchActivity(r, msg.arg1);
} break;
case PAUSE_ACTIVITY:
- handlePauseActivity((IBinder)msg.obj, false, msg.arg2);
+ handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
break;
case PAUSE_ACTIVITY_FINISHING:
- handlePauseActivity((IBinder)msg.obj, true, msg.arg2);
+ handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
break;
case STOP_ACTIVITY_SHOW:
handleStopActivity((IBinder)msg.obj, true, msg.arg2);
@@ -2647,9 +2649,14 @@ public final class ActivityThread {
}
private final void handlePauseActivity(IBinder token, boolean finished,
- int configChanges) {
+ boolean userLeaving, int configChanges) {
ActivityRecord r = mActivities.get(token);
if (r != null) {
+ //Log.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
+ if (userLeaving) {
+ performUserLeavingActivity(r);
+ }
+
r.activity.mConfigChangeFlags |= configChanges;
Bundle state = performPauseActivity(token, finished, true);
@@ -2661,6 +2668,10 @@ public final class ActivityThread {
}
}
+ final void performUserLeavingActivity(ActivityRecord r) {
+ mInstrumentation.callActivityOnUserLeaving(r.activity);
+ }
+
final Bundle performPauseActivity(IBinder token, boolean finished,
boolean saveState) {
ActivityRecord r = mActivities.get(token);
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index 0e41ae6f2faf..4236a00e1b58 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -315,8 +315,13 @@ class ApplicationContext extends Context {
backup.renameTo(f);
}
+ // Debugging
+ if (f.exists() && !f.canRead()) {
+ Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
+ }
+
Map map = null;
- if (f.exists()) {
+ if (f.exists() && f.canRead()) {
try {
str = new FileInputStream(f);
map = XmlUtils.readMapXml(str);
@@ -2264,14 +2269,23 @@ class ApplicationContext extends Context {
}
}
@Override
- public void freeApplicationCache(long idealStorageSize,
- IPackageDataObserver observer) {
+ public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
try {
- mPM.freeApplicationCache(idealStorageSize, observer);
+ mPM.freeStorageAndNotify(idealStorageSize, observer);
} catch (RemoteException e) {
// Should never happen!
}
}
+
+ @Override
+ public void freeStorage(long idealStorageSize, PendingIntent opFinishedIntent) {
+ try {
+ mPM.freeStorage(idealStorageSize, opFinishedIntent);
+ } catch (RemoteException e) {
+ // Should never happen!
+ }
+ }
+
@Override
public void getPackageSizeInfo(String packageName,
IPackageStatsObserver observer) {
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 54237aea53d8..d2cf55a427cc 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -69,8 +69,9 @@ public abstract class ApplicationThreadNative extends Binder
data.enforceInterface(IApplicationThread.descriptor);
IBinder b = data.readStrongBinder();
boolean finished = data.readInt() != 0;
+ boolean userLeaving = data.readInt() != 0;
int configChanges = data.readInt();
- schedulePauseActivity(b, finished, configChanges);
+ schedulePauseActivity(b, finished, userLeaving, configChanges);
return true;
}
@@ -344,11 +345,12 @@ class ApplicationThreadProxy implements IApplicationThread {
}
public final void schedulePauseActivity(IBinder token, boolean finished,
- int configChanges) throws RemoteException {
+ boolean userLeaving, int configChanges) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
data.writeInt(finished ? 1 : 0);
+ data.writeInt(userLeaving ? 1 :0);
data.writeInt(configChanges);
mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index a35158136422..47476b5da211 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -40,7 +40,7 @@ import java.util.Map;
* {@hide}
*/
public interface IApplicationThread extends IInterface {
- void schedulePauseActivity(IBinder token, boolean finished,
+ void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
int configChanges) throws RemoteException;
void scheduleStopActivity(IBinder token, boolean showWindow,
int configChanges) throws RemoteException;
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 17618ff26fd4..f96d78710463 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1266,6 +1266,16 @@ public class Instrumentation {
activity.performPause();
}
+ /**
+ * Perform calling of an activity's {@link Activity#onUserLeaving} method.
+ * The default implementation simply calls through to that method.
+ *
+ * @param activity The activity being notified that the user has navigated away
+ */
+ public void callActivityOnUserLeaving(Activity activity) {
+ activity.performUserLeaving();
+ }
+
/*
* Starts allocation counting. This triggers a gc and resets the counts.
*/
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 5af08f77298a..2e2a1a17a52e 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -222,17 +222,27 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
// configure the autocomplete aspects of the input box
mSearchTextField.setOnItemClickListener(this);
mSearchTextField.setOnItemSelectedListener(this);
-
- // attach the suggestions adapter
- mSuggestionsAdapter = new SuggestionsAdapter(getContext(), mSearchable);
- mSearchTextField.setAdapter(mSuggestionsAdapter);
- // finally, load the user's initial text (which may trigger suggestions)
- mSuggestionsAdapter.setNonUserQuery(false);
+ // This conversion is necessary to force a preload of the EditText and thus force
+ // suggestions to be presented (even for an empty query)
if (initialQuery == null) {
initialQuery = ""; // This forces the preload to happen, triggering suggestions
}
- mSearchTextField.setText(initialQuery);
+
+ // attach the suggestions adapter, if suggestions are available
+ // The existence of a suggestions authority is the proxy for "suggestions available here"
+ if (mSearchable.getSuggestAuthority() == null) {
+ mSuggestionsAdapter = null;
+ mSearchTextField.setAdapter(mSuggestionsAdapter);
+ mSearchTextField.setText(initialQuery);
+ } else {
+ mSuggestionsAdapter = new SuggestionsAdapter(getContext(), mSearchable);
+ mSearchTextField.setAdapter(mSuggestionsAdapter);
+
+ // finally, load the user's initial text (which may trigger suggestions)
+ mSuggestionsAdapter.setNonUserQuery(false);
+ mSearchTextField.setText(initialQuery);
+ }
if (selectInitialQuery) {
mSearchTextField.selectAll();
@@ -344,7 +354,9 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
return;
}
- mSuggestionsAdapter.setNonUserQuery(true);
+ if (mSuggestionsAdapter != null) {
+ mSuggestionsAdapter.setNonUserQuery(true);
+ }
mSearchTextField.setText(displayQuery);
// TODO because the new query is (not) processed in another thread, we can't just
// take away this flag (yet). The better solution here is going to require a new API
@@ -539,7 +551,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
}
updateWidgetState();
// Only do suggestions if actually typed by user
- if (!mSuggestionsAdapter.getNonUserQuery()) {
+ if ((mSuggestionsAdapter != null) && !mSuggestionsAdapter.getNonUserQuery()) {
mPreviousSuggestionQuery = s.toString();
mUserQuery = mSearchTextField.getText().toString();
mUserQuerySelStart = mSearchTextField.getSelectionStart();
@@ -822,6 +834,10 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
* React to the user typing an action key while in the suggestions list
*/
private boolean doSuggestionsKey(View v, int keyCode, KeyEvent event) {
+ // Exit early in case of race condition
+ if (mSuggestionsAdapter == null) {
+ return false;
+ }
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (DBG_LOG_TIMING == 1) {
dbgLogTiming("doSuggestionsKey()");
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index d1f71c55f05a..d613e1cfba27 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -39,6 +39,28 @@ public class BluetoothDevice {
public static final int RESULT_FAILURE = -1;
public static final int RESULT_SUCCESS = 0;
+ /** We do not have a link key for the remote device, and are therefore not
+ * bonded */
+ public static final int BOND_NOT_BONDED = 0;
+ /** We have a link key for the remote device, and are probably bonded. */
+ public static final int BOND_BONDED = 1;
+ /** We are currently attempting bonding */
+ public static final int BOND_BONDING = 2;
+
+ //TODO: Unify these result codes in BluetoothResult or BluetoothError
+ /** A bond attempt failed because pins did not match, or remote device did
+ * not respond to pin request in time */
+ public static final int UNBOND_REASON_AUTH_FAILED = 1;
+ /** A bond attempt failed because the other side explicilty rejected
+ * bonding */
+ public static final int UNBOND_REASON_AUTH_REJECTED = 2;
+ /** A bond attempt failed because we cancelled the bonding process */
+ public static final int UNBOND_REASON_CANCELLED = 3;
+ /** A bond attempt failed because we could not contact the remote device */
+ public static final int UNBOND_REASON_AUTH_REMOTE_DEVICE_DOWN = 4;
+ /** An existing bond was explicitly revoked */
+ public static final int UNBOND_REASON_REMOVED = 5;
+
private static final String TAG = "BluetoothDevice";
private final IBluetoothDevice mService;
@@ -325,42 +347,36 @@ public class BluetoothDevice {
/**
* Create a bonding with a remote bluetooth device.
*
- * This is an asynchronous call. BluetoothIntent.BONDING_CREATED_ACTION
- * will be broadcast if and when the remote device is successfully bonded.
+ * This is an asynchronous call. The result of this bonding attempt can be
+ * observed through BluetoothIntent.BOND_STATE_CHANGED_ACTION intents.
*
* @param address the remote device Bluetooth address.
- * @return false if we cannot create a bonding to that device, true if
- * there were no problems beginning the bonding process.
+ * @return false If there was an immediate problem creating the bonding,
+ * true otherwise.
*/
- public boolean createBonding(String address) {
- return createBonding(address, null);
+ public boolean createBond(String address) {
+ try {
+ return mService.createBond(address);
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return false;
}
/**
- * Create a bonding with a remote bluetooth device.
- *
- * This is an asynchronous call. onCreateBondingResult() of your callback
- * will be called when the call is complete, with either RESULT_SUCCESS or
- * RESULT_FAILURE.
- *
- * In addition to the callback, BluetoothIntent.BONDING_CREATED_ACTION will
- * be broadcast if the remote device is successfully bonded.
- *
- * @param address The remote device Bluetooth address.
- * @param callback Your callback, null is ok.
- * @return true if your callback was successfully registered, or false if
- * there was an error, implying your callback will never be called.
+ * Cancel an in-progress bonding request started with createBond.
*/
- public boolean createBonding(String address, IBluetoothDeviceCallback callback) {
+ public boolean cancelBondProcess(String address) {
try {
- return mService.createBonding(address, callback);
+ return mService.cancelBondProcess(address);
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
- public boolean cancelBondingProcess(String address) {
+ /**
+ * Remove an already exisiting bonding (delete the link key).
+ */
+ public boolean removeBond(String address) {
try {
- return mService.cancelBondingProcess(address);
+ return mService.removeBond(address);
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
}
@@ -382,48 +398,34 @@ public class BluetoothDevice {
*
* This function does not check if the remote device is in range.
*
+ * Remote devices that have an in-progress bonding attempt are not
+ * returned.
+ *
* @return bluetooth hardware addresses of remote devices that are
* bonded. Array size is 0 if no devices are bonded. Null on error.
*/
- public String[] listBondings() {
+ public String[] listBonds() {
try {
- return mService.listBondings();
+ return mService.listBonds();
} catch (RemoteException e) {Log.e(TAG, "", e);}
return null;
}
/**
- * Check if a remote device is bonded (paired) to the local device.
+ * Get the bonding state of a remote device.
*
- * Bonding (pairing) is the process by which the user enters a pin code for
- * the device, which generates a shared link key, allowing for
- * authentication and encryption of future connections. In Android we
- * require bonding before RFCOMM or SCO connections can be made to a remote
- * device.
- *
- * This function checks if we have a link key with the remote device. It
- * does not cause any RF transmission, and does not check if the remote
- * device still has it's link key with us. If the other side no longer has
- * a link key then the RFCOMM or SCO connection attempt will result in an
- * error.
- *
- * This function does not check if the remote device is in range.
+ * Result is one of:
+ * BluetoothError.*
+ * BOND_*
*
* @param address Bluetooth hardware address of the remote device to check.
- * @return true if bonded, false otherwise and on error.
+ * @return Result code
*/
- public boolean hasBonding(String address) {
+ public int getBondState(String address) {
try {
- return mService.hasBonding(address);
+ return mService.getBondState(address);
} catch (RemoteException e) {Log.e(TAG, "", e);}
- return false;
- }
-
- public boolean removeBonding(String address) {
- try {
- return mService.removeBonding(address);
- } catch (RemoteException e) {Log.e(TAG, "", e);}
- return false;
+ return BluetoothError.ERROR_IPC;
}
public String getRemoteName(String address) {
diff --git a/core/java/android/bluetooth/BluetoothIntent.java b/core/java/android/bluetooth/BluetoothIntent.java
index 8e2279189035..57c46f98c299 100644
--- a/core/java/android/bluetooth/BluetoothIntent.java
+++ b/core/java/android/bluetooth/BluetoothIntent.java
@@ -45,6 +45,12 @@ public interface BluetoothIntent {
"android.bluetooth.intent.HEADSET_STATE";
public static final String HEADSET_PREVIOUS_STATE =
"android.bluetooth.intent.HEADSET_PREVIOUS_STATE";
+ public static final String BOND_STATE =
+ "android.bluetooth.intent.BOND_STATE";
+ public static final String BOND_PREVIOUS_STATE =
+ "android.bluetooth.intent.BOND_PREVIOUS_STATE";
+ public static final String REASON =
+ "android.bluetooth.intent.REASON";
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ENABLED_ACTION =
@@ -105,12 +111,17 @@ public interface BluetoothIntent {
public static final String REMOTE_ALIAS_CLEARED_ACTION =
"android.bluetooth.intent.action.REMOTE_ALIAS_CLEARED";
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String BONDING_CREATED_ACTION =
- "android.bluetooth.intent.action.BONDING_CREATED";
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String BONDING_REMOVED_ACTION =
- "android.bluetooth.intent.action.BONDING_REMOVED";
+ /**
+ * Broadcast when the bond state of a remote device changes.
+ * Has string extra ADDRESS and int extras BOND_STATE and
+ * BOND_PREVIOUS_STATE.
+ * If BOND_STATE is BluetoothDevice.BOND_NOT_BONDED then will
+ * also have an int extra REASON with a value of:
+ * BluetoothDevice.BOND_RESULT_*
+ * */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String BOND_STATE_CHANGED_ACTION =
+ "android.bluetooth.intent.action.BOND_STATE_CHANGED_ACTION";
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String HEADSET_STATE_CHANGED_ACTION =
diff --git a/core/java/android/bluetooth/IBluetoothDevice.aidl b/core/java/android/bluetooth/IBluetoothDevice.aidl
index e7cc8edc9c6c..59f679f3cd6a 100644
--- a/core/java/android/bluetooth/IBluetoothDevice.aidl
+++ b/core/java/android/bluetooth/IBluetoothDevice.aidl
@@ -57,11 +57,11 @@ interface IBluetoothDevice
boolean isAclConnected(in String address);
boolean disconnectRemoteDeviceAcl(in String address);
- boolean createBonding(in String address, in IBluetoothDeviceCallback callback);
- boolean cancelBondingProcess(in String address);
- String[] listBondings();
- boolean hasBonding(in String address);
- boolean removeBonding(in String address);
+ boolean createBond(in String address);
+ boolean cancelBondProcess(in String address);
+ boolean removeBond(in String address);
+ String[] listBonds();
+ int getBondState(in String address);
String getRemoteName(in String address);
String getRemoteAlias(in String address);
diff --git a/core/java/android/bluetooth/IBluetoothDeviceCallback.aidl b/core/java/android/bluetooth/IBluetoothDeviceCallback.aidl
index 86f44dde9ac4..d25bd560d034 100644
--- a/core/java/android/bluetooth/IBluetoothDeviceCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothDeviceCallback.aidl
@@ -21,7 +21,6 @@ package android.bluetooth;
*/
oneway interface IBluetoothDeviceCallback
{
- void onCreateBondingResult(in String address, int result);
void onGetRemoteServiceChannelResult(in String address, int channel);
void onEnableResult(int result);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 4a92b4c8fb7f..e2d357694bba 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1225,6 +1225,22 @@ public class Intent implements Parcelable {
public static final String ACTION_MEDIA_UNMOUNTED = "android.intent.action.MEDIA_UNMOUNTED";
/**
+ * Broadcast Action: External media is present, and being disk-checked
+ * The path to the mount point for the checking media is contained in the Intent.mData field.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_MEDIA_CHECKING = "android.intent.action.MEDIA_CHECKING";
+
+ /**
+ * Broadcast Action: External media is present, but is using an incompatible fs (or is blank)
+ * The path to the mount point for the checking media is contained in the Intent.mData field.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_MEDIA_NOFS = "android.intent.action.MEDIA_NOFS";
+
+ /**
* Broadcast Action: External media is present and mounted at its mount point.
* The path to the mount point for the removed media is contained in the Intent.mData field.
* The Intent contains an extra with name "read-only" and Boolean value to indicate if the
@@ -1838,6 +1854,23 @@ public class Intent implements Parcelable {
* to mail.
*/
public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 0x00080000;
+ /**
+ * If set, this flag will prevent the normal {@link android.app.Activity#onUserLeaving}
+ * callback from occurring on the current frontmost activity before it is
+ * paused as the newly-started activity is brought to the front.
+ *
+ *
Typically, an activity can rely on that callback to indicate that an
+ * explicit user action has caused their activity to be moved out of the
+ * foreground. The callback marks an appropriate point in the activity's
+ * lifecycle for it to dismiss any notifications that it intends to display
+ * "until the user has seen them," such as a blinking LED.
+ *
+ *
If an activity is ever started via any non-user-driven events such as
+ * phone-call receipt or an alarm handler, this flag should be passed to {@link
+ * Context#startActivity Context.startActivity}, ensuring that the pausing
+ * activity does not think the user has acknowledged its notification.
+ */
+ public static final int FLAG_ACTIVITY_NO_USER_ACTION = 0x00040000;
/**
* If set, when sending a broadcast only registered receivers will be
@@ -3836,6 +3869,7 @@ public class Intent implements Parcelable {
* @see #FLAG_ACTIVITY_MULTIPLE_TASK
* @see #FLAG_ACTIVITY_NEW_TASK
* @see #FLAG_ACTIVITY_NO_HISTORY
+ * @see #FLAG_ACTIVITY_NO_USER_ACTION
* @see #FLAG_ACTIVITY_PREVIOUS_IS_TOP
* @see #FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
* @see #FLAG_ACTIVITY_SINGLE_TOP
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index fdb2a2f4a3b6..ea86188d2bf9 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -34,6 +34,7 @@ import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.net.Uri;
+import android.app.PendingIntent;
/**
* See {@link PackageManager} for documentation on most of the APIs
@@ -184,22 +185,51 @@ interface IPackageManager {
int getApplicationEnabledSetting(in String packageName);
/**
- * Free storage by deleting LRU sorted list of cache files across all applications.
- * If the currently available free storage on the device is greater than or equal to the
- * requested free storage, no cache files are cleared. If the currently available storage on the
- * device is less than the requested free storage, some or all of the cache files across
- * all applications are deleted(based on last accessed time) to increase the free storage
- * space on the device to the requested value. There is no gurantee that clearing all
- * the cache files from all applications will clear up enough storage to achieve the desired
- * value.
- * @param freeStorageSize The number of bytes of storage to be
- * freed by the system. Say if freeStorageSize is XX,
- * and the current free storage is YY,
- * if XX is less than YY, just return. if not free XX-YY number of
- * bytes if possible.
- * @param observer callback used to notify when the operation is completed
+ * Free storage by deleting LRU sorted list of cache files across
+ * all applications. If the currently available free storage
+ * on the device is greater than or equal to the requested
+ * free storage, no cache files are cleared. If the currently
+ * available storage on the device is less than the requested
+ * free storage, some or all of the cache files across
+ * all applications are deleted (based on last accessed time)
+ * to increase the free storage space on the device to
+ * the requested value. There is no guarantee that clearing all
+ * the cache files from all applications will clear up
+ * enough storage to achieve the desired value.
+ * @param freeStorageSize The number of bytes of storage to be
+ * freed by the system. Say if freeStorageSize is XX,
+ * and the current free storage is YY,
+ * if XX is less than YY, just return. if not free XX-YY number
+ * of bytes if possible.
+ * @param observer call back used to notify when
+ * the operation is completed
*/
- void freeApplicationCache(in long freeStorageSize, IPackageDataObserver observer);
+ void freeStorageAndNotify(in long freeStorageSize,
+ IPackageDataObserver observer);
+
+ /**
+ * Free storage by deleting LRU sorted list of cache files across
+ * all applications. If the currently available free storage
+ * on the device is greater than or equal to the requested
+ * free storage, no cache files are cleared. If the currently
+ * available storage on the device is less than the requested
+ * free storage, some or all of the cache files across
+ * all applications are deleted (based on last accessed time)
+ * to increase the free storage space on the device to
+ * the requested value. There is no guarantee that clearing all
+ * the cache files from all applications will clear up
+ * enough storage to achieve the desired value.
+ * @param freeStorageSize The number of bytes of storage to be
+ * freed by the system. Say if freeStorageSize is XX,
+ * and the current free storage is YY,
+ * if XX is less than YY, just return. if not free XX-YY number
+ * of bytes if possible.
+ * @param opFinishedIntent PendingIntent call back used to
+ * notify when the operation is completed.May be null
+ * to indicate that no call back is desired.
+ */
+ void freeStorage(in long freeStorageSize,
+ in PendingIntent opFinishedIntent);
/**
* Delete all the cache files in an applications cache directory
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index a5445507a043..4b902e9fe944 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -17,6 +17,7 @@
package android.content.pm;
+import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -1357,28 +1358,53 @@ public abstract class PackageManager {
IPackageDataObserver observer);
/**
- * Free storage by deleting LRU sorted list of cache files across all applications.
- * If the currently available free storage on the device is greater than or equal to the
- * requested free storage, no cache files are cleared. If the currently available storage on the
- * device is less than the requested free storage, some or all of the cache files across
- * all applications are deleted(based on last accessed time) to increase the free storage
- * space on the device to the requested value. There is no gurantee that clearing all
- * the cache files from all applications will clear up enough storage to achieve the desired
- * value.
+ * Free storage by deleting LRU sorted list of cache files across
+ * all applications. If the currently available free storage
+ * on the device is greater than or equal to the requested
+ * free storage, no cache files are cleared. If the currently
+ * available storage on the device is less than the requested
+ * free storage, some or all of the cache files across
+ * all applications are deleted (based on last accessed time)
+ * to increase the free storage space on the device to
+ * the requested value. There is no guarantee that clearing all
+ * the cache files from all applications will clear up
+ * enough storage to achieve the desired value.
* @param freeStorageSize The number of bytes of storage to be
* freed by the system. Say if freeStorageSize is XX,
* and the current free storage is YY,
- * if XX is less than YY, just return. if not free XX-YY number of
- * bytes if possible.
- * @param observer callback used to notify when the operation is completed
- * {@link android.content.pm.IPackageDataObserver#onRemoveCompleted(String, boolean)}
- * will be called when that happens. observer may be null to indicate that
- * no callback is desired.
- *
+ * if XX is less than YY, just return. if not free XX-YY number
+ * of bytes if possible.
+ * @param observer call back used to notify when
+ * the operation is completed
+ *
* @hide
*/
- public abstract void freeApplicationCache(long freeStorageSize,
- IPackageDataObserver observer);
+ public abstract void freeStorageAndNotify(long freeStorageSize, IPackageDataObserver observer);
+
+ /**
+ * Free storage by deleting LRU sorted list of cache files across
+ * all applications. If the currently available free storage
+ * on the device is greater than or equal to the requested
+ * free storage, no cache files are cleared. If the currently
+ * available storage on the device is less than the requested
+ * free storage, some or all of the cache files across
+ * all applications are deleted (based on last accessed time)
+ * to increase the free storage space on the device to
+ * the requested value. There is no guarantee that clearing all
+ * the cache files from all applications will clear up
+ * enough storage to achieve the desired value.
+ * @param freeStorageSize The number of bytes of storage to be
+ * freed by the system. Say if freeStorageSize is XX,
+ * and the current free storage is YY,
+ * if XX is less than YY, just return. if not free XX-YY number
+ * of bytes if possible.
+ * @param opFinishedIntent PendingIntent call back used to
+ * notify when the operation is completed.May be null
+ * to indicate that no call back is desired.
+ *
+ * @hide
+ */
+ public abstract void freeStorage(long freeStorageSize, PendingIntent opFinishedIntent);
/**
* Retrieve the size information for a package.
diff --git a/core/java/android/gadget/GadgetManager.java b/core/java/android/gadget/GadgetManager.java
index 49c706e83add..088dc86f9d58 100644
--- a/core/java/android/gadget/GadgetManager.java
+++ b/core/java/android/gadget/GadgetManager.java
@@ -54,17 +54,22 @@ public class GadgetManager {
/**
* Sent when it is time to update your gadget.
*/
- public static final String GADGET_UPDATE_ACTION = "android.gadget.GADGET_UPDATE";
+ public static final String GADGET_UPDATE_ACTION = "android.gadget.action.GADGET_UPDATE";
/**
* Sent when the gadget is added to a host for the first time. TODO: Maybe we don't want this.
*/
- public static final String GADGET_ENABLE_ACTION = "android.gadget.GADGET_ENABLE";
+ public static final String GADGET_ENABLE_ACTION = "android.gadget.action.GADGET_ENABLE";
/**
* Sent when the gadget is removed from the last host. TODO: Maybe we don't want this.
*/
- public static final String GADGET_DISABLE_ACTION = "android.gadget.GADGET_DISABLE";
+ public static final String GADGET_DISABLE_ACTION = "android.gadget.action.GADGET_DISABLE";
+
+ /**
+ * Field for the manifest meta-data tag.
+ */
+ public static final String GADGET_PROVIDER_META_DATA = "android.gadget.provider";
static WeakHashMap> sManagerCache = new WeakHashMap();
static IGadgetService sService;
@@ -108,10 +113,15 @@ public class GadgetManager {
}
/**
- * Return a list of the gadgets that are currently installed.
+ * Return a list of the gadget providers that are currently installed.
*/
- public List getAvailableGadgets() {
- return null;
+ public List getInstalledProviders() {
+ try {
+ return sService.getInstalledProviders();
+ }
+ catch (RemoteException e) {
+ throw new RuntimeException("system server dead?", e);
+ }
}
/**
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 1a7547df6da0..3a9b26a9c6f5 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -498,7 +498,15 @@ public class InputMethodService extends AbstractInputMethodService {
if (showingCandidates) {
setCandidatesViewShown(true);
}
- showWindow(showingInput);
+ if (showingInput) {
+ // If we are showing the full soft keyboard, then go through
+ // this path to take care of current decisions about fullscreen
+ // etc.
+ onShowRequested(InputMethod.SHOW_EXPLICIT);
+ } else {
+ // Otherwise just put it back for its candidates.
+ showWindow(false);
+ }
}
}
@@ -649,16 +657,14 @@ public class InputMethodService extends AbstractInputMethodService {
/**
* Override this to control when the input method should run in
* fullscreen mode. The default implementation runs in fullsceen only
- * when the screen is in landscape mode and the input view is being
- * shown ({@link #onEvaluateInputViewShown} returns true). If you change what
+ * when the screen is in landscape mode. If you change what
* this returns, you will need to call {@link #updateFullscreenMode()}
* yourself whenever the returned value may have changed to have it
* re-evaluated and applied.
*/
public boolean onEvaluateFullscreenMode() {
Configuration config = getResources().getConfiguration();
- return config.orientation == Configuration.ORIENTATION_LANDSCAPE
- && onEvaluateInputViewShown();
+ return config.orientation == Configuration.ORIENTATION_LANDSCAPE;
}
/**
@@ -870,7 +876,11 @@ public class InputMethodService extends AbstractInputMethodService {
}
/**
- * Called when an input session is starting or restarting.
+ * Called when the input view is being shown and input has started on
+ * a new editor. This will always be called after {@link #onStartInput},
+ * allowing you to do your general setup there and just view-specific
+ * setup here. You are guaranteed that {@link #onCreateInputView()} will
+ * have been called some time before this function is called.
*
* @param info Description of the type of text being edited.
* @param restarting Set to true if we are restarting input on the
@@ -892,6 +902,9 @@ public class InputMethodService extends AbstractInputMethodService {
* as per {@link InputMethod#showSoftInput(int) InputMethod.showSoftInput(int)}.
*/
public void onShowRequested(int flags) {
+ if (!onEvaluateInputViewShown()) {
+ return;
+ }
if ((flags&InputMethod.SHOW_EXPLICIT) == 0 && onEvaluateFullscreenMode()) {
// Don't show if this is not explicit requested by the user and
// the input method is fullscreen. That would be too disruptive.
@@ -911,9 +924,11 @@ public class InputMethodService extends AbstractInputMethodService {
boolean wasVisible = mWindowVisible;
mWindowVisible = true;
if (!mShowInputRequested) {
- if (showInput) {
- doShowInput = true;
- mShowInputRequested = true;
+ if (mInputStarted) {
+ if (showInput) {
+ doShowInput = true;
+ mShowInputRequested = true;
+ }
}
} else {
showInput = true;
@@ -1001,7 +1016,7 @@ public class InputMethodService extends AbstractInputMethodService {
mInputEditorInfo = attribute;
onStartInput(attribute, restarting);
if (mWindowVisible) {
- if (mWindowCreated) {
+ if (mShowInputRequested) {
onStartInputView(mInputEditorInfo, restarting);
}
startExtractingText();
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 6f044b61ada6..2f3b54bee716 100755
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -153,9 +153,10 @@ public class KeyboardView extends View implements View.OnClickListener {
/** Listener for {@link OnKeyboardActionListener}. */
private OnKeyboardActionListener mKeyboardActionListener;
- private static final int MSG_REMOVE_PREVIEW = 1;
- private static final int MSG_REPEAT = 2;
- private static final int MSG_LONGPRESS = 3;
+ private static final int MSG_SHOW_PREVIEW = 1;
+ private static final int MSG_REMOVE_PREVIEW = 2;
+ private static final int MSG_REPEAT = 3;
+ private static final int MSG_LONGPRESS = 4;
private int mVerticalCorrection;
private int mProximityThreshold;
@@ -198,7 +199,8 @@ public class KeyboardView extends View implements View.OnClickListener {
private static final int REPEAT_INTERVAL = 50; // ~20 keys per second
private static final int REPEAT_START_DELAY = 400;
- private static final int LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout();
+ private static final int LONGPRESS_TIMEOUT = 800;
+ // Deemed to be too short : ViewConfiguration.getLongPressTimeout();
private static int MAX_NEARBY_KEYS = 12;
private int[] mDistances = new int[MAX_NEARBY_KEYS];
@@ -215,6 +217,9 @@ public class KeyboardView extends View implements View.OnClickListener {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
+ case MSG_SHOW_PREVIEW:
+ mPreviewText.setVisibility(VISIBLE);
+ break;
case MSG_REMOVE_PREVIEW:
mPreviewText.setVisibility(INVISIBLE);
break;
@@ -731,7 +736,7 @@ public class KeyboardView extends View implements View.OnClickListener {
return adjustCase(key.label);
}
}
-
+
private void showPreview(int keyIndex) {
int oldKeyIndex = mCurrentKeyIndex;
final PopupWindow previewPopup = mPreviewPopup;
@@ -751,6 +756,7 @@ public class KeyboardView extends View implements View.OnClickListener {
}
// If key changed and preview is on ...
if (oldKeyIndex != mCurrentKeyIndex && mShowPreview) {
+ mHandler.removeMessages(MSG_SHOW_PREVIEW);
if (previewPopup.isShowing()) {
if (keyIndex == NOT_A_KEY) {
mHandler.sendMessageDelayed(mHandler
@@ -803,7 +809,7 @@ public class KeyboardView extends View implements View.OnClickListener {
mPreviewText.getBackground().setState(
key.popupResId != 0 ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET);
if (previewPopup.isShowing()) {
- previewPopup.update(mPopupPreviewX + mOffsetInWindow[0],
+ previewPopup.update(mPopupParent, mPopupPreviewX + mOffsetInWindow[0],
mPopupPreviewY + mOffsetInWindow[1],
popupWidth, popupHeight);
} else {
@@ -811,7 +817,8 @@ public class KeyboardView extends View implements View.OnClickListener {
mPopupPreviewX + mOffsetInWindow[0],
mPopupPreviewY + mOffsetInWindow[1]);
}
- mPreviewText.setVisibility(VISIBLE);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_PREVIEW, keyIndex, 0),
+ ViewConfiguration.getTapTimeout());
}
}
}
@@ -1014,6 +1021,7 @@ public class KeyboardView extends View implements View.OnClickListener {
break;
case MotionEvent.ACTION_UP:
+ mHandler.removeMessages(MSG_SHOW_PREVIEW);
mHandler.removeMessages(MSG_REPEAT);
mHandler.removeMessages(MSG_LONGPRESS);
if (keyIndex == mCurrentKey) {
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index e065063c21b0..ed7c3663ce28 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -237,7 +237,7 @@ public abstract class BatteryStats {
public abstract long computeBatteryRealtime(long curTime, int which);
/**
- * Returns the total, last, or current uptime in micropeconds.
+ * Returns the total, last, or current uptime in microseconds.
*
* @param curTime the current elapsed realtime in microseconds.
* @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
@@ -299,6 +299,9 @@ public abstract class BatteryStats {
}
private final String formatRatioLocked(long num, long den) {
+ if (den == 0L) {
+ return "---%";
+ }
float perc = ((float)num) / ((float)den) * 100;
mFormatBuilder.setLength(0);
mFormatter.format("%.1f%%", perc);
@@ -352,18 +355,20 @@ public abstract class BatteryStats {
long batteryUptime = computeBatteryUptime(uSecNow, which);
long batteryRealtime = computeBatteryRealtime(getBatteryRealtime(uSecTime), which);
long elapsedRealtime = computeRealtime(uSecTime, which);
+ long uptime = computeUptime(SystemClock.uptimeMillis() * 1000, which);
+
pw.println(prefix
- + " On battery: " + formatTimeMs(batteryUptime) + "("
+ + " On battery: " + formatTimeMs(batteryUptime / 1000) + "("
+ formatRatioLocked(batteryUptime, batteryRealtime)
+ ") uptime, "
- + formatTimeMs(batteryRealtime) + "("
+ + formatTimeMs(batteryRealtime / 1000) + "("
+ formatRatioLocked(batteryRealtime, elapsedRealtime)
+ ") realtime");
pw.println(prefix
+ " Total: "
- + formatTimeMs(computeUptime(SystemClock.uptimeMillis() * 1000, which))
+ + formatTimeMs(uptime / 1000)
+ "uptime, "
- + formatTimeMs(elapsedRealtime)
+ + formatTimeMs(elapsedRealtime / 1000)
+ "realtime");
pw.println(" ");
@@ -479,7 +484,7 @@ public abstract class BatteryStats {
if (startTime != 0 || starts != 0 || launches != 0) {
pw.println(prefix + " Service " + sent.getKey() + ":");
pw.println(prefix + " Time spent started: "
- + formatTimeMs(startTime));
+ + formatTimeMs(startTime / 1000));
pw.println(prefix + " Starts: " + starts
+ ", launches: " + launches);
apkActivity = true;
diff --git a/core/java/android/provider/Gmail.java b/core/java/android/provider/Gmail.java
index 1bbcc3342335..325f19db98a9 100644
--- a/core/java/android/provider/Gmail.java
+++ b/core/java/android/provider/Gmail.java
@@ -554,13 +554,15 @@ public final class Gmail {
*
* @param account the account of the conversation
* @param conversationId the conversation
- * @param maxMessageId the highest message id to whose labels should be changed
+ * @param maxServerMessageId the highest message id to whose labels should be changed. Note that
+ * everywhere else in this file messageId means local message id but here you need to use a
+ * server message id.
* @param label the label to add or remove
* @param add true to add the label, false to remove it
* @throws NonexistentLabelException thrown if the label does not exist
*/
public void addOrRemoveLabelOnConversation(
- String account, long conversationId, long maxMessageId, String label,
+ String account, long conversationId, long maxServerMessageId, String label,
boolean add)
throws NonexistentLabelException {
if (TextUtils.isEmpty(account)) {
@@ -571,7 +573,7 @@ public final class Gmail {
AUTHORITY_PLUS_CONVERSATIONS + account + "/" + conversationId + "/labels");
ContentValues values = new ContentValues();
values.put(LabelColumns.CANONICAL_NAME, label);
- values.put(ConversationColumns.MAX_MESSAGE_ID, maxMessageId);
+ values.put(ConversationColumns.MAX_MESSAGE_ID, maxServerMessageId);
mContentResolver.insert(uri, values);
} else {
String encodedLabel;
@@ -584,7 +586,7 @@ public final class Gmail {
AUTHORITY_PLUS_CONVERSATIONS + account + "/"
+ conversationId + "/labels/" + encodedLabel);
mContentResolver.delete(
- uri, ConversationColumns.MAX_MESSAGE_ID, new String[]{"" + maxMessageId});
+ uri, ConversationColumns.MAX_MESSAGE_ID, new String[]{"" + maxServerMessageId});
}
}
@@ -2373,7 +2375,7 @@ public final class Gmail {
/**
* @return the max message id in the conversation
*/
- public long getMaxMessageId() {
+ public long getMaxServerMessageId() {
return mCursor.getLong(mMaxMessageIdIndex);
}
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 0184db83ff7b..87a02e6c2ae2 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -148,6 +148,13 @@ public final class MediaStore
public final static String EXTRA_VIDEO_QUALITY = "android.intent.extra.videoQuality";
/**
+ * The name of the Intent-extra used to indicate a Uri to be used to
+ * store the requested image or video.
+ * @hide
+ */
+ public final static String EXTRA_OUTPUT = "output";
+
+ /**
* Common fields for most MediaProvider tables
*/
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a18f37c3ca1c..abbfd5bdb8e1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2121,6 +2121,12 @@ public final class Settings {
= "youtube_use_proxy";
/**
+ * MMS - maximum message size in bytes for a MMS message.
+ */
+ public static final String MMS_MAXIMUM_MESSAGE_SIZE
+ = "mms_maximum_message_size";
+
+ /**
* Event tags from the kernel event log to upload during checkin.
*/
public static final String CHECKIN_EVENTS = "checkin_events";
@@ -2685,6 +2691,22 @@ public final class Settings {
"short_keylight_delay_ms";
/**
+ * URL that points to the voice search servers. To be factored out of this class.
+ */
+ public static final String VOICE_SEARCH_URL = "voice_search_url";
+
+ /**
+ * Speech encoding used with voice search on 3G networks. To be factored out of this class.
+ */
+ public static final String VOICE_SEARCH_ENCODING_THREE_G = "voice_search_encoding_three_g";
+
+ /**
+ * Speech encoding used with voice search on WIFI networks. To be factored out of this class.
+ */
+ public static final String VOICE_SEARCH_ENCODING_WIFI = "voice_search_encoding_wifi";
+
+
+ /**
* @deprecated
* @hide
*/
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index be784ff3e2fc..8486e4b5acd1 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -84,8 +84,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
mIntentFilter = new IntentFilter(BluetoothIntent.ENABLED_ACTION);
mIntentFilter.addAction(BluetoothIntent.DISABLED_ACTION);
- mIntentFilter.addAction(BluetoothIntent.BONDING_CREATED_ACTION);
- mIntentFilter.addAction(BluetoothIntent.BONDING_REMOVED_ACTION);
+ mIntentFilter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
mContext.registerReceiver(mReceiver, mIntentFilter);
if (device.isEnabled()) {
@@ -111,10 +110,18 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
onBluetoothEnable();
} else if (action.equals(BluetoothIntent.DISABLED_ACTION)) {
onBluetoothDisable();
- } else if (action.equals(BluetoothIntent.BONDING_CREATED_ACTION)) {
- setSinkPriority(address, BluetoothA2dp.PRIORITY_AUTO);
- } else if (action.equals(BluetoothIntent.BONDING_REMOVED_ACTION)) {
- setSinkPriority(address, BluetoothA2dp.PRIORITY_OFF);
+ } else if (action.equals(BluetoothIntent.BOND_STATE_CHANGED_ACTION)) {
+ int bondState = intent.getIntExtra(BluetoothIntent.BOND_STATE,
+ BluetoothError.ERROR);
+ switch(bondState) {
+ case BluetoothDevice.BOND_BONDED:
+ setSinkPriority(address, BluetoothA2dp.PRIORITY_AUTO);
+ break;
+ case BluetoothDevice.BOND_BONDING:
+ case BluetoothDevice.BOND_NOT_BONDED:
+ setSinkPriority(address, BluetoothA2dp.PRIORITY_OFF);
+ break;
+ }
}
}
};
diff --git a/core/java/android/server/BluetoothDeviceService.java b/core/java/android/server/BluetoothDeviceService.java
index 9bdab9f2957a..3ce34c30a198 100644
--- a/core/java/android/server/BluetoothDeviceService.java
+++ b/core/java/android/server/BluetoothDeviceService.java
@@ -26,6 +26,7 @@ package android.server;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset; // just for dump()
+import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothIntent;
import android.bluetooth.IBluetoothDevice;
import android.bluetooth.IBluetoothDeviceCallback;
@@ -49,14 +50,19 @@ import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Map;
public class BluetoothDeviceService extends IBluetoothDevice.Stub {
private static final String TAG = "BluetoothDeviceService";
+ private static final boolean DBG = true;
+
private int mNativeData;
private BluetoothEventLoop mEventLoop;
private IntentFilter mIntentFilter;
private boolean mIsAirplaneSensitive;
+ private final BondState mBondState = new BondState(); // local cache of bondings
private volatile boolean mIsEnabled; // local cache of isEnabledNative()
private boolean mIsDiscovering;
@@ -79,10 +85,13 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
public synchronized void init() {
initializeNativeDataNative();
mIsEnabled = (isEnabledNative() == 1);
+ if (mIsEnabled) {
+ mBondState.loadBondState();
+ }
mIsDiscovering = false;
mEventLoop = new BluetoothEventLoop(mContext, this);
registerForAirplaneMode();
-
+
disableEsco(); // TODO: enable eSCO support once its fully supported
}
private native void initializeNativeDataNative();
@@ -112,7 +121,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
public synchronized boolean disable() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
-
+
if (mEnableThread != null && mEnableThread.isAlive()) {
return false;
}
@@ -171,7 +180,6 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
};
private EnableThread mEnableThread;
- private String mOutgoingBondingDevAddress = null;
private class EnableThread extends Thread {
private final IBluetoothDeviceCallback mEnableCallback;
@@ -198,6 +206,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
Settings.Secure.BLUETOOTH_ON, 1);
mIsDiscovering = false;
Intent intent = new Intent(BluetoothIntent.ENABLED_ACTION);
+ mBondState.loadBondState();
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
mHandler.sendMessageDelayed(mHandler.obtainMessage(REGISTER_SDP_RECORDS), 3000);
}
@@ -208,6 +217,119 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
private native int enableNative();
private native int disableNative();
+ /* package */ BondState getBondState() {
+ return mBondState;
+ }
+
+ /** local cache of bonding state.
+ /* we keep our own state to track the intermediate state BONDING, which
+ /* bluez does not track.
+ * All addreses must be passed in upper case.
+ */
+ public class BondState {
+ private final HashMap mState = new HashMap();
+ private final HashMap mPinAttempt = new HashMap();
+
+ public synchronized void loadBondState() {
+ if (!mIsEnabled) {
+ return;
+ }
+ String[] bonds = listBondingsNative();
+ if (bonds == null) {
+ return;
+ }
+ mState.clear();
+ if (DBG) log("found " + bonds.length + " bonded devices");
+ for (String address : bonds) {
+ mState.put(address.toUpperCase(), BluetoothDevice.BOND_BONDED);
+ }
+ }
+
+ public synchronized void setBondState(String address, int state) {
+ setBondState(address, state, 0);
+ }
+
+ /** reason is ignored unless state == BOND_NOT_BONDED */
+ public synchronized void setBondState(String address, int state, int reason) {
+ int oldState = getBondState(address);
+ if (oldState == state) {
+ return;
+ }
+ if (DBG) log(address + " bond state " + oldState + " -> " + state + " (" +
+ reason + ")");
+ Intent intent = new Intent(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
+ intent.putExtra(BluetoothIntent.ADDRESS, address);
+ intent.putExtra(BluetoothIntent.BOND_STATE, state);
+ intent.putExtra(BluetoothIntent.BOND_PREVIOUS_STATE, oldState);
+ if (state == BluetoothDevice.BOND_NOT_BONDED) {
+ if (reason <= 0) {
+ Log.w(TAG, "setBondState() called to unbond device with invalid reason code " +
+ "Setting reason = BOND_RESULT_REMOVED");
+ reason = BluetoothDevice.UNBOND_REASON_REMOVED;
+ }
+ intent.putExtra(BluetoothIntent.REASON, reason);
+ mState.remove(address);
+ } else {
+ mState.put(address, state);
+ }
+ if (state == BluetoothDevice.BOND_BONDING) {
+ mPinAttempt.put(address, Integer.valueOf(0));
+ } else {
+ mPinAttempt.remove(address);
+ }
+ mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+ }
+
+ public synchronized int getBondState(String address) {
+ Integer state = mState.get(address);
+ if (state == null) {
+ return BluetoothDevice.BOND_NOT_BONDED;
+ }
+ return state.intValue();
+ }
+
+ public synchronized String[] listBonds() {
+ ArrayList result = new ArrayList(mState.size());
+ for (Map.Entry e : mState.entrySet()) {
+ if (e.getValue().intValue() == BluetoothDevice.BOND_BONDED) {
+ result.add(e.getKey());
+ }
+ }
+ return result.toArray(new String[result.size()]);
+ }
+
+ public synchronized int getAttempt(String address) {
+ Integer attempt = mPinAttempt.get(address);
+ if (attempt == null) {
+ return 0;
+ }
+ return attempt.intValue();
+ }
+
+ public synchronized void attempt(String address) {
+ Integer attempt = mPinAttempt.get(address);
+ if (attempt == null) {
+ return;
+ }
+ mPinAttempt.put(address, new Integer(attempt.intValue() + 1));
+ }
+
+ }
+ private native String[] listBondingsNative();
+
+ private static String toBondStateString(int bondState) {
+ switch (bondState) {
+ case BluetoothDevice.BOND_NOT_BONDED:
+ return "not bonded";
+ case BluetoothDevice.BOND_BONDING:
+ return "bonding";
+ case BluetoothDevice.BOND_BONDED:
+ return "bonded";
+ default:
+ return "??????";
+ }
+ }
+
public synchronized String getAddress() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
return getAddressNative();
@@ -231,12 +353,6 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
}
private native boolean setNameNative(String name);
- public synchronized String[] listBondings() {
- mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return listBondingsNative();
- }
- private native String[] listBondingsNative();
-
public synchronized String getMajorClass() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
return getMajorClassNative();
@@ -551,106 +667,45 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
}
private native boolean disconnectRemoteDeviceNative(String address);
- private static final int MAX_OUTSTANDING_ASYNC = 32;
- /**
- * This method initiates a Bonding request to a remote device.
- *
- *
- * @param address The Bluetooth address of the remote device
- *
- * @see #createBonding
- * @see #cancelBondingProcess
- * @see #removeBonding
- * @see #hasBonding
- * @see #listBondings
- *
- * @see android.bluetooth.PasskeyAgent
- */
- public synchronized boolean createBonding(String address, IBluetoothDeviceCallback callback) {
+ public synchronized boolean createBond(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
if (!BluetoothDevice.checkBluetoothAddress(address)) {
return false;
}
-
- HashMap callbacks = mEventLoop.getCreateBondingCallbacks();
- if (callbacks.containsKey(address)) {
- Log.w(TAG, "createBonding() already in progress for " + address);
+ address = address.toUpperCase();
+ if (mBondState.getBondState(address) != BluetoothDevice.BOND_NOT_BONDED) {
return false;
}
- // Protect from malicious clients - limit number of outstanding requests
- if (callbacks.size() > MAX_OUTSTANDING_ASYNC) {
- Log.w(TAG, "Too many outstanding bonding requests, dropping request for " + address);
- return false;
- }
-
- callbacks.put(address, callback);
if (!createBondingNative(address, 60000 /* 1 minute */)) {
- callbacks.remove(address);
return false;
}
- mOutgoingBondingDevAddress = address;
+
+ mBondState.setBondState(address, BluetoothDevice.BOND_BONDING);
return true;
}
-
private native boolean createBondingNative(String address, int timeout_ms);
-
- /*package*/ String getOutgoingBondingDevAddress() {
- return mOutgoingBondingDevAddress;
- }
- /*package*/ void setOutgoingBondingDevAddress(String outgoingBondingDevAddress) {
- mOutgoingBondingDevAddress = outgoingBondingDevAddress;
- }
-
- /**
- * This method cancels a pending bonding request.
- *
- * @param address The Bluetooth address of the remote device to which a
- * bonding request has been initiated.
- *
- * Note: When a request is canceled, method
- * {@link CreateBondingResultNotifier#notifyAuthenticationFailed}
- * will be called on the object passed to method
- * {@link #createBonding}.
- *
- * Note: it is safe to call this method when there is no outstanding
- * bonding request.
- *
- * @see #createBonding
- * @see #cancelBondingProcess
- * @see #removeBonding
- * @see #hasBonding
- * @see #listBondings
- */
- public synchronized boolean cancelBondingProcess(String address) {
+ public synchronized boolean cancelBondProcess(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
if (!BluetoothDevice.checkBluetoothAddress(address)) {
return false;
}
- return cancelBondingProcessNative(address);
+ address = address.toUpperCase();
+ if (mBondState.getBondState(address) != BluetoothDevice.BOND_BONDING) {
+ return false;
+ }
+
+ mBondState.setBondState(address, BluetoothDevice.BOND_NOT_BONDED,
+ BluetoothDevice.UNBOND_REASON_CANCELLED);
+ cancelBondingProcessNative(address);
+ return true;
}
private native boolean cancelBondingProcessNative(String address);
- /**
- * This method removes a bonding to a remote device. This is a local
- * operation only, resulting in this adapter "forgetting" the bonding
- * information about the specified remote device. The other device itself
- * does not know what the bonding has been torn down. The next time either
- * device attemps to connect to the other, the connection will fail, and
- * the pairing procedure will have to be re-initiated.
- *
- * @param address The Bluetooth address of the remote device.
- *
- * @see #createBonding
- * @see #cancelBondingProcess
- * @see #removeBonding
- * @see #hasBonding
- * @see #listBondings
- */
- public synchronized boolean removeBonding(String address) {
+ public synchronized boolean removeBond(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
if (!BluetoothDevice.checkBluetoothAddress(address)) {
@@ -660,14 +715,18 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
}
private native boolean removeBondingNative(String address);
- public synchronized boolean hasBonding(String address) {
+ public synchronized String[] listBonds() {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ return mBondState.listBonds();
+ }
+
+ public synchronized int getBondState(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
if (!BluetoothDevice.checkBluetoothAddress(address)) {
- return false;
+ return BluetoothError.ERROR;
}
- return hasBondingNative(address);
+ return mBondState.getBondState(address.toUpperCase());
}
- private native boolean hasBondingNative(String address);
public synchronized String[] listAclConnections() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
@@ -1016,6 +1075,8 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
}
private native byte[] getRemoteServiceRecordNative(String address, int handle);
+ private static final int MAX_OUTSTANDING_ASYNC = 32;
+
// AIDL does not yet support short's
public synchronized boolean getRemoteServiceChannel(String address, int uuid16,
IBluetoothDeviceCallback callback) {
@@ -1051,6 +1112,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
!BluetoothDevice.checkBluetoothAddress(address)) {
return false;
}
+ address = address.toUpperCase();
Integer data = mEventLoop.getPasskeyAgentRequestData().remove(address);
if (data == null) {
Log.w(TAG, "setPin(" + address + ") called but no native data available, " +
@@ -1076,6 +1138,7 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
if (!BluetoothDevice.checkBluetoothAddress(address)) {
return false;
}
+ address = address.toUpperCase();
Integer data = mEventLoop.getPasskeyAgentRequestData().remove(address);
if (data == null) {
Log.w(TAG, "cancelPin(" + address + ") called but no native data available, " +
@@ -1143,25 +1206,20 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
BluetoothHeadset headset = new BluetoothHeadset(mContext, null);
- pw.println("\n--Bondings--");
- String[] addresses = listBondings();
- for (String address : addresses) {
- String name = getRemoteName(address);
- pw.println(address + " (" + name + ")");
- }
+ String[] addresses = listRemoteDevices();
- pw.println("\n--Current ACL Connections--");
- addresses = listAclConnections();
+ pw.println("\n--Known devices--");
for (String address : addresses) {
- String name = getRemoteName(address);
- pw.println(address + " (" + name + ")");
+ pw.printf("%s %10s (%d) %s\n", address,
+ toBondStateString(mBondState.getBondState(address)),
+ mBondState.getAttempt(address),
+ getRemoteName(address));
}
- pw.println("\n--Known Devices--");
- addresses = listRemoteDevices();
+ addresses = listAclConnections();
+ pw.println("\n--ACL connected devices--");
for (String address : addresses) {
- String name = getRemoteName(address);
- pw.println(address + " (" + name + ")");
+ pw.println(address);
}
// Rather not do this from here, but no-where else and I need this
@@ -1189,4 +1247,8 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
}
pw.println("\nmIsAirplaneSensitive = " + mIsAirplaneSensitive);
}
+
+ private static void log(String msg) {
+ Log.d(TAG, msg);
+ }
}
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 2d8aaccfb9bf..4f63f9835033 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -16,8 +16,9 @@
package android.server;
-import android.bluetooth.BluetoothClass.Device;
+import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothError;
import android.bluetooth.BluetoothIntent;
import android.bluetooth.IBluetoothDeviceCallback;
import android.content.Context;
@@ -41,11 +42,9 @@ class BluetoothEventLoop {
private int mNativeData;
private Thread mThread;
private boolean mInterrupted;
- private HashMap mCreateBondingCallbacks;
private HashMap mPasskeyAgentRequestData;
private HashMap mGetRemoteServiceChannelCallbacks;
- private HashMap mDefaultPinData;
- private BluetoothDeviceService mBluetoothService;
+ private BluetoothDeviceService mBluetoothService;
private Context mContext;
private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
@@ -57,10 +56,8 @@ class BluetoothEventLoop {
/* pacakge */ BluetoothEventLoop(Context context, BluetoothDeviceService bluetoothService) {
mBluetoothService = bluetoothService;
mContext = context;
- mCreateBondingCallbacks = new HashMap();
mPasskeyAgentRequestData = new HashMap();
mGetRemoteServiceChannelCallbacks = new HashMap();
- mDefaultPinData = new HashMap();
initializeNativeDataNative();
}
private native void initializeNativeDataNative();
@@ -74,9 +71,6 @@ class BluetoothEventLoop {
}
private native void cleanupNativeDataNative();
- /* pacakge */ HashMap getCreateBondingCallbacks() {
- return mCreateBondingCallbacks;
- }
/* pacakge */ HashMap getRemoteServiceChannelCallbacks() {
return mGetRemoteServiceChannelCallbacks;
}
@@ -235,33 +229,24 @@ class BluetoothEventLoop {
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
}
- private void onCreateBondingResult(String address, boolean result) {
- mBluetoothService.setOutgoingBondingDevAddress(null);
- IBluetoothDeviceCallback callback = mCreateBondingCallbacks.get(address);
- if (callback != null) {
- try {
- callback.onCreateBondingResult(address,
- result ? BluetoothDevice.RESULT_SUCCESS :
- BluetoothDevice.RESULT_FAILURE);
- } catch (RemoteException e) {}
- mCreateBondingCallbacks.remove(address);
- }
+ private void onCreateBondingResult(String address, int result) {
+ address = address.toUpperCase();
+ if (result == BluetoothError.SUCCESS) {
+ mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDED);
+ } else {
+ mBluetoothService.getBondState().setBondState(address,
+ BluetoothDevice.BOND_NOT_BONDED, result);
+ }
}
-
+
public void onBondingCreated(String address) {
- Intent intent = new Intent(BluetoothIntent.BONDING_CREATED_ACTION);
- intent.putExtra(BluetoothIntent.ADDRESS, address);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+ mBluetoothService.getBondState().setBondState(address.toUpperCase(),
+ BluetoothDevice.BOND_BONDED);
}
-
- public void onBondingRemoved(String address) {
- Intent intent = new Intent(BluetoothIntent.BONDING_REMOVED_ACTION);
- intent.putExtra(BluetoothIntent.ADDRESS, address);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- if (mDefaultPinData.containsKey(address)) {
- mDefaultPinData.remove(address);
- }
+ public void onBondingRemoved(String address) {
+ mBluetoothService.getBondState().setBondState(address.toUpperCase(),
+ BluetoothDevice.BOND_NOT_BONDED, BluetoothDevice.UNBOND_REASON_REMOVED);
}
public void onNameChanged(String name) {
@@ -271,24 +256,24 @@ class BluetoothEventLoop {
}
public void onPasskeyAgentRequest(String address, int nativeData) {
- mPasskeyAgentRequestData.put(address, new Integer(nativeData));
-
- if (address.equals(mBluetoothService.getOutgoingBondingDevAddress())) {
+ address = address.toUpperCase();
+ mPasskeyAgentRequestData.put(address, new Integer(nativeData));
+
+ if (mBluetoothService.getBondState().getBondState(address) ==
+ BluetoothDevice.BOND_BONDING) {
+ // we initiated the bonding
int btClass = mBluetoothService.getRemoteClass(address);
- int remoteDeviceClass = Device.getDevice(btClass);
- if (remoteDeviceClass == Device.AUDIO_VIDEO_WEARABLE_HEADSET ||
- remoteDeviceClass == Device.AUDIO_VIDEO_HANDSFREE ||
- remoteDeviceClass == Device.AUDIO_VIDEO_HEADPHONES ||
- remoteDeviceClass == Device.AUDIO_VIDEO_PORTABLE_AUDIO ||
- remoteDeviceClass == Device.AUDIO_VIDEO_CAR_AUDIO ||
- remoteDeviceClass == Device.AUDIO_VIDEO_HIFI_AUDIO) {
- if (!mDefaultPinData.containsKey(address)) {
- mDefaultPinData.put(address, false);
- }
- if (!mDefaultPinData.get(address)) {
- mDefaultPinData.remove(address);
- mDefaultPinData.put(address, true);
+ // try 0000 once if the device looks dumb
+ switch (BluetoothClass.Device.getDevice(btClass)) {
+ case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
+ case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
+ case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
+ case BluetoothClass.Device.AUDIO_VIDEO_PORTABLE_AUDIO:
+ case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
+ case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
+ if (mBluetoothService.getBondState().getAttempt(address) < 1) {
+ mBluetoothService.getBondState().attempt(address);
mBluetoothService.setPin(address, BluetoothDevice.convertPinToBytes("0000"));
return;
}
@@ -298,18 +283,17 @@ class BluetoothEventLoop {
intent.putExtra(BluetoothIntent.ADDRESS, address);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
}
-
+
public void onPasskeyAgentCancel(String address) {
+ address = address.toUpperCase();
mPasskeyAgentRequestData.remove(address);
- if (mDefaultPinData.containsKey(address)) {
- mDefaultPinData.remove(address);
- mDefaultPinData.put(address, false);
- }
Intent intent = new Intent(BluetoothIntent.PAIRING_CANCEL_ACTION);
intent.putExtra(BluetoothIntent.ADDRESS, address);
mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+ mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_NOT_BONDED,
+ BluetoothDevice.UNBOND_REASON_CANCELLED);
}
-
+
private void onGetRemoteServiceChannelResult(String address, int channel) {
IBluetoothDeviceCallback callback = mGetRemoteServiceChannelCallbacks.get(address);
if (callback != null) {
diff --git a/core/java/android/server/search/SearchableInfo.java b/core/java/android/server/search/SearchableInfo.java
index ac4cdb9d0cfc..c8f395e8a03c 100644
--- a/core/java/android/server/search/SearchableInfo.java
+++ b/core/java/android/server/search/SearchableInfo.java
@@ -704,6 +704,7 @@ public final class SearchableInfo implements Parcelable {
* positioned at the location in the buffer where it was written.
*/
public SearchableInfo(Parcel in) {
+ mSearchable = in.readInt() != 0;
mLabelId = in.readInt();
mSearchActivity = ComponentName.readFromParcel(in);
mHintId = in.readInt();
@@ -733,6 +734,7 @@ public final class SearchableInfo implements Parcelable {
}
public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mSearchable ? 1 : 0);
dest.writeInt(mLabelId);
mSearchActivity.writeToParcel(dest, flags);
dest.writeInt(mHintId);
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 64356d547152..405d9341181c 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -659,8 +659,8 @@ public class TextUtils {
p.writeInt(0);
}
- p.writeInt(tas.getTextSize());
p.writeInt(tas.getTextStyle());
+ p.writeInt(tas.getTextSize());
ColorStateList csl = tas.getTextColor();
if (csl == null) {
@@ -799,8 +799,8 @@ public class TextUtils {
p.readInt() != 0
? p.readString()
: null,
- p.readInt(),
- p.readInt(),
+ p.readInt(), // style
+ p.readInt(), // size
p.readInt() != 0
? ColorStateList.CREATOR.createFromParcel(p)
: null,
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index a6def51784c5..6af4915f8185 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -21,6 +21,7 @@ import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.LocalPowerManager;
+import android.view.animation.Animation;
/**
* This interface supplies all UI-specific behavior of the window manager. An
@@ -247,6 +248,13 @@ public interface WindowManagerPolicy {
public WindowState getAppStartingWindow();
/**
+ * Is this window visible? It is not visible if there is no
+ * surface, or we are in the process of running an exit animation
+ * that will remove the surface.
+ */
+ boolean isVisibleLw();
+
+ /**
* Is this window currently visible to the user on-screen? It is
* displayed either if it is visible or it is currently running an
* animation before no longer being visible. Must be called with the
@@ -282,7 +290,7 @@ public interface WindowManagerPolicy {
* regardless of whether the client or window manager would like
* it shown. Must be called with the window manager lock held.
*/
- public void hideLw();
+ public void hideLw(boolean doAnimation);
/**
* Can be called to undo the effect of {@link #hideLw}, allowing a
@@ -290,7 +298,7 @@ public interface WindowManagerPolicy {
* also like it to be shown. Must be called with the window manager
* lock held.
*/
- public void showLw();
+ public void showLw(boolean doAnimation);
}
/** No transition happening. */
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 27461ff6a687..bd7b0507d85b 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -177,6 +177,19 @@ public interface InputConnection {
public boolean commitCompletion(CompletionInfo text);
/**
+ * Tell the editor that you are starting a batch of editor operations.
+ * The editor will try to avoid sending you updates about its state
+ * until {@link #endBatchEdit} is called.
+ */
+ public boolean beginBatchEdit();
+
+ /**
+ * Tell the editor that you are done with a batch edit previously
+ * initiated with {@link #endBatchEdit}.
+ */
+ public boolean endBatchEdit();
+
+ /**
* Send a key event to the process that is currently attached through
* this input connection. The event will be dispatched like a normal
* key event, to the currently focused; this generally is the view that
diff --git a/core/java/android/view/inputmethod/InputConnectionWrapper.java b/core/java/android/view/inputmethod/InputConnectionWrapper.java
index a41955c04771..f65b2a1081c7 100644
--- a/core/java/android/view/inputmethod/InputConnectionWrapper.java
+++ b/core/java/android/view/inputmethod/InputConnectionWrapper.java
@@ -77,6 +77,14 @@ public class InputConnectionWrapper implements InputConnection {
return mBase.commitCompletion(text);
}
+ public boolean beginBatchEdit() {
+ return mBase.beginBatchEdit();
+ }
+
+ public boolean endBatchEdit() {
+ return mBase.endBatchEdit();
+ }
+
public boolean sendKeyEvent(KeyEvent event) {
return mBase.sendKeyEvent(event);
}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index ba40782072a9..a9a95944dc4a 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -293,6 +293,14 @@ public final class InputMethodManager {
return false;
}
+ public boolean beginBatchEdit() {
+ return false;
+ }
+
+ public boolean endBatchEdit() {
+ return false;
+ }
+
public boolean commitCompletion(CompletionInfo text) {
return false;
}
@@ -401,6 +409,12 @@ public final class InputMethodManager {
};
final InputConnection mDummyInputConnection = new BaseInputConnection(this) {
+ public boolean beginBatchEdit() {
+ return false;
+ }
+ public boolean endBatchEdit() {
+ return false;
+ }
public boolean commitText(CharSequence text, int newCursorPosition) {
return false;
}
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index c45ab29fa8c4..3f2bbe5a7908 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -167,7 +167,7 @@ class LoadListener extends Handler implements EventHandler {
* should do with them.
*/
if (mNativeLoader != 0) {
- commitHeaders();
+ commitHeadersCheckRedirect();
}
break;
@@ -458,11 +458,6 @@ class LoadListener extends Handler implements EventHandler {
if (Config.LOGV) {
Log.v(LOGTAG, "LoadListener.data(): url: " + url());
}
-
- if (ignoreCallbacks()) {
- return;
- }
-
// Decode base64 data
// Note: It's fine that we only decode base64 here and not in the other
// data call because the only caller of the stream version is not
@@ -484,7 +479,7 @@ class LoadListener extends Handler implements EventHandler {
sendMessage = mDataBuilder.isEmpty();
mDataBuilder.append(data, 0, length);
}
- if (sendMessage) {
+ if (sendMessage && !ignoreCallbacks()) {
// Send a message whenever data comes in after a write to WebCore
sendMessageInternal(obtainMessage(MSG_CONTENT_DATA));
}
@@ -850,7 +845,8 @@ class LoadListener extends Handler implements EventHandler {
return mContentLength;
}
- private void commitHeaders() {
+ // Commit the headers if the status code is not a redirect.
+ private void commitHeadersCheckRedirect() {
if (mCancelled) return;
// do not call webcore if it is redirect. According to the code in
@@ -860,6 +856,11 @@ class LoadListener extends Handler implements EventHandler {
return;
}
+ commitHeaders();
+ }
+
+ // This commits the headers without checking the response status code.
+ private void commitHeaders() {
// Commit the headers to WebCore
int nativeResponse = createNativeResponse();
// The native code deletes the native response object.
@@ -1075,7 +1076,11 @@ class LoadListener extends Handler implements EventHandler {
}
}
} else {
- cancel();
+ // With a null redirect, commit the original headers, the buffered
+ // data, and then finish the load.
+ commitHeaders();
+ commitLoad();
+ nativeFinished();
}
if (Config.LOGV) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9cfc6225a3d7..cab278beb375 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -288,10 +288,6 @@ public class WebView extends AbsoluteLayout
// The time that the Zoom Controls are visible before fading away
private static final long ZOOM_CONTROLS_TIMEOUT =
ViewConfiguration.getZoomControlsTimeout();
- // Wait a short time before sending kit focus message, in case
- // the user is still moving around, to avoid rebuilding the display list
- // prematurely
- private static final long SET_KIT_FOCUS_DELAY = 250;
// The amount of content to overlap between two screens when going through
// pages with the space bar, in pixels.
private static final int PAGE_SCROLL_OVERLAP = 24;
@@ -4725,8 +4721,7 @@ public class WebView extends AbsoluteLayout
// called by JNI
private void sendKitFocus() {
WebViewCore.FocusData focusData = new WebViewCore.FocusData(mFocusData);
- mWebViewCore.sendMessageDelayed(EventHub.SET_KIT_FOCUS, focusData,
- SET_KIT_FOCUS_DELAY);
+ mWebViewCore.sendMessage(EventHub.SET_KIT_FOCUS, focusData);
}
// called by JNI
diff --git a/core/java/android/widget/Button.java b/core/java/android/widget/Button.java
index f2868af76ae7..5e692d4fbbe1 100644
--- a/core/java/android/widget/Button.java
+++ b/core/java/android/widget/Button.java
@@ -21,6 +21,7 @@ import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.KeyEvent;
+import android.widget.RemoteViews.RemoteView;
/**
@@ -54,6 +55,7 @@ import android.view.KeyEvent;
* {@link android.R.styleable#View View Attributes}
*