Merge change 4524 into donut
* changes:
FileRestoreHelper and RestoreHelperDispatcher work.
diff --git a/Android.mk b/Android.mk
index 6e292a8..0e8793d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -70,10 +70,8 @@
core/java/android/app/IActivityPendingResult.aidl \
core/java/android/app/IActivityWatcher.aidl \
core/java/android/app/IAlarmManager.aidl \
- core/java/android/app/IBackupAgent.aidl \
+ core/java/android/app/IBackupAgent.aidl \
core/java/android/app/IInstrumentationWatcher.aidl \
- core/java/android/app/IIntentReceiver.aidl \
- core/java/android/app/IIntentSender.aidl \
core/java/android/app/INotificationManager.aidl \
core/java/android/app/ISearchManager.aidl \
core/java/android/app/ISearchManagerCallback.aidl \
@@ -89,10 +87,12 @@
core/java/android/bluetooth/IBluetoothDevice.aidl \
core/java/android/bluetooth/IBluetoothDeviceCallback.aidl \
core/java/android/bluetooth/IBluetoothHeadset.aidl \
- core/java/android/content/IContentService.aidl \
+ core/java/android/content/IContentService.aidl \
+ core/java/android/content/IIntentReceiver.aidl \
+ core/java/android/content/IIntentSender.aidl \
core/java/android/content/ISyncAdapter.aidl \
core/java/android/content/ISyncContext.aidl \
- core/java/android/content/ISyncStatusObserver.aidl \
+ core/java/android/content/ISyncStatusObserver.aidl \
core/java/android/content/pm/IPackageDataObserver.aidl \
core/java/android/content/pm/IPackageDeleteObserver.aidl \
core/java/android/content/pm/IPackageInstallObserver.aidl \
@@ -198,6 +198,7 @@
frameworks/base/core/java/android/app/PendingIntent.aidl \
frameworks/base/core/java/android/content/ComponentName.aidl \
frameworks/base/core/java/android/content/Intent.aidl \
+ frameworks/base/core/java/android/content/IntentSender.aidl \
frameworks/base/core/java/android/content/SyncStats.aidl \
frameworks/base/core/java/android/content/res/Configuration.aidl \
frameworks/base/core/java/android/appwidget/AppWidgetProviderInfo.aidl \
diff --git a/api/current.xml b/api/current.xml
index f375257..2128e5b 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -22948,6 +22948,17 @@
<parameter name="flags" type="int">
</parameter>
</method>
+<method name="getIntentSender"
+ return="android.content.IntentSender"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getService"
return="android.app.PendingIntent"
abstract="false"
@@ -29629,6 +29640,70 @@
</parameter>
</method>
</interface>
+<interface name="IIntentReceiver"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.IInterface">
+</implements>
+<method name="performReceive"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="resultCode" type="int">
+</parameter>
+<parameter name="data" type="java.lang.String">
+</parameter>
+<parameter name="extras" type="android.os.Bundle">
+</parameter>
+<parameter name="ordered" type="boolean">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+</interface>
+<interface name="IIntentSender"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.IInterface">
+</implements>
+<method name="send"
+ return="int"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="code" type="int">
+</parameter>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="resolvedType" type="java.lang.String">
+</parameter>
+<parameter name="finishedReceiver" type="android.content.IIntentReceiver">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+</interface>
<class name="Intent"
extends="java.lang.Object"
abstract="false"
@@ -33648,6 +33723,190 @@
</parameter>
</constructor>
</class>
+<class name="IntentSender"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<constructor name="IntentSender"
+ type="android.content.IntentSender"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="target" type="android.content.IIntentSender">
+</parameter>
+</constructor>
+<constructor name="IntentSender"
+ type="android.content.IntentSender"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="target" type="android.os.IBinder">
+</parameter>
+</constructor>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="readIntentSenderOrNullFromParcel"
+ return="android.content.IntentSender"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="in" type="android.os.Parcel">
+</parameter>
+</method>
+<method name="sendIntent"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="code" type="int">
+</parameter>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="onFinished" type="android.content.IntentSender.OnFinished">
+</parameter>
+<parameter name="handler" type="android.os.Handler">
+</parameter>
+<exception name="IntentSender.SendIntentException" type="android.content.IntentSender.SendIntentException">
+</exception>
+</method>
+<method name="writeIntentSenderOrNullToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="sender" type="android.content.IntentSender">
+</parameter>
+<parameter name="out" type="android.os.Parcel">
+</parameter>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="out" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<interface name="IntentSender.OnFinished"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onSendFinished"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="IntentSender" type="android.content.IntentSender">
+</parameter>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="resultCode" type="int">
+</parameter>
+<parameter name="resultData" type="java.lang.String">
+</parameter>
+<parameter name="resultExtras" type="android.os.Bundle">
+</parameter>
+</method>
+</interface>
+<class name="IntentSender.SendIntentException"
+ extends="android.util.AndroidException"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="IntentSender.SendIntentException"
+ type="android.content.IntentSender.SendIntentException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<constructor name="IntentSender.SendIntentException"
+ type="android.content.IntentSender.SendIntentException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+</constructor>
+<constructor name="IntentSender.SendIntentException"
+ type="android.content.IntentSender.SendIntentException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="cause" type="java.lang.Exception">
+</parameter>
+</constructor>
+</class>
<class name="MutableContextWrapper"
extends="android.content.ContextWrapper"
abstract="false"
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 7fb3449..501be01 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -23,6 +23,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.content.IIntentSender;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 3d3d7d5f..b6f855a2 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -17,9 +17,10 @@
package android.app;
import android.content.ComponentName;
-import android.content.ContentResolver;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.IIntentSender;
+import android.content.IIntentReceiver;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.IPackageDataObserver;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 3676594..477badb 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.content.IContentProvider;
import android.content.Intent;
+import android.content.IIntentReceiver;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index fc3cdcf..fa3d5c2 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -32,6 +32,8 @@
import android.content.IContentProvider;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.IIntentReceiver;
+import android.content.IntentSender;
import android.content.ReceiverCallNotAllowedException;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
@@ -2357,11 +2359,20 @@
// Should never happen!
}
}
-
+
@Override
- public void freeStorage(long idealStorageSize, PendingIntent opFinishedIntent) {
+ public void freeStorage(long freeStorageSize, PendingIntent pi) {
try {
- mPM.freeStorage(idealStorageSize, opFinishedIntent);
+ mPM.freeStorage(freeStorageSize, pi);
+ } catch (RemoteException e) {
+ // Should never happen!
+ }
+ }
+
+ @Override
+ public void freeStorageWithIntent(long freeStorageSize, IntentSender pi) {
+ try {
+ mPM.freeStorageWithIntent(freeStorageSize, pi);
} catch (RemoteException e) {
// Should never happen!
}
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index 0c8f95d..6b17236 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -151,6 +151,11 @@
public String exceptionClassName;
/**
+ * Message stored in the exception.
+ */
+ public String exceptionMessage;
+
+ /**
* File which the exception was thrown from.
*/
public String throwFileName;
@@ -181,6 +186,7 @@
*/
public CrashInfo(Parcel in) {
exceptionClassName = in.readString();
+ exceptionMessage = in.readString();
throwFileName = in.readString();
throwClassName = in.readString();
throwMethodName = in.readString();
@@ -192,6 +198,7 @@
*/
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(exceptionClassName);
+ dest.writeString(exceptionMessage);
dest.writeString(throwFileName);
dest.writeString(throwClassName);
dest.writeString(throwMethodName);
@@ -203,6 +210,7 @@
*/
public void dump(Printer pw, String prefix) {
pw.println(prefix + "exceptionClassName: " + exceptionClassName);
+ pw.println(prefix + "exceptionMessage: " + exceptionMessage);
pw.println(prefix + "throwFileName: " + throwFileName);
pw.println(prefix + "throwClassName: " + throwClassName);
pw.println(prefix + "throwMethodName: " + throwMethodName);
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 6750d12..4b64c94 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -18,6 +18,7 @@
import android.content.ComponentName;
import android.content.Intent;
+import android.content.IIntentReceiver;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ProviderInfo;
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index c948aec..66bc85b 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -21,6 +21,8 @@
import android.content.IContentProvider;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.IIntentSender;
+import android.content.IIntentReceiver;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.IPackageDataObserver;
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index bca1fea..029c650 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -18,6 +18,7 @@
import android.content.ComponentName;
import android.content.Intent;
+import android.content.IIntentReceiver;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ProviderInfo;
diff --git a/core/java/android/app/IIntentReceiver.aidl b/core/java/android/app/IIntentReceiver.aidl
deleted file mode 100755
index 5f5d0eb..0000000
--- a/core/java/android/app/IIntentReceiver.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-**
-** Copyright 2006, 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 android.app;
-
-import android.content.Intent;
-import android.os.Bundle;
-
-/**
- * System private API for dispatching intent broadcasts. This is given to the
- * activity manager as part of registering for an intent broadcasts, and is
- * called when it receives intents.
- *
- * {@hide}
- */
-oneway interface IIntentReceiver {
- void performReceive(in Intent intent, int resultCode,
- String data, in Bundle extras, boolean ordered);
-}
-
diff --git a/core/java/android/app/IIntentSender.aidl b/core/java/android/app/IIntentSender.aidl
deleted file mode 100644
index 53e135a..0000000
--- a/core/java/android/app/IIntentSender.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/* //device/java/android/android/app/IActivityPendingResult.aidl
-**
-** Copyright 2007, 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 android.app;
-
-import android.app.IIntentReceiver;
-import android.content.Intent;
-
-/** @hide */
-interface IIntentSender {
- int send(int code, in Intent intent, String resolvedType,
- IIntentReceiver finishedReceiver);
-}
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index cb660c7..f9c38f9 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -18,6 +18,9 @@
import android.content.Context;
import android.content.Intent;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
+import android.content.IntentSender;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.Handler;
@@ -105,7 +108,7 @@
public CanceledException(Exception cause) {
super(cause);
}
- };
+ }
/**
* Callback interface for discovering when a send operation has
@@ -270,6 +273,21 @@
return null;
}
+ private class IntentSenderWrapper extends IntentSender {
+ protected IntentSenderWrapper(IIntentSender target) {
+ super(target);
+ }
+ }
+ /**
+ * Retrieve a IntentSender object that wraps the existing sender of the PendingIntent
+ *
+ * @return Returns a IntentSender object that wraps the sender of PendingIntent
+ *
+ */
+ public IntentSender getIntentSender() {
+ return new IntentSenderWrapper(mTarget);
+ }
+
/**
* Cancel a currently active PendingIntent. Only the original application
* owning an PendingIntent can cancel it.
diff --git a/core/java/android/content/IIntentReceiver.aidl b/core/java/android/content/IIntentReceiver.aidl
new file mode 100755
index 0000000..443db2d
--- /dev/null
+++ b/core/java/android/content/IIntentReceiver.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006 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 android.content;
+
+import android.content.Intent;
+import android.os.Bundle;
+
+/**
+ * System private API for dispatching intent broadcasts. This is given to the
+ * activity manager as part of registering for an intent broadcasts, and is
+ * called when it receives intents.
+ *
+ * {@hide}
+ */
+oneway interface IIntentReceiver {
+ void performReceive(in Intent intent, int resultCode,
+ String data, in Bundle extras, boolean ordered);
+}
+
diff --git a/core/java/android/content/IIntentSender.aidl b/core/java/android/content/IIntentSender.aidl
new file mode 100644
index 0000000..b7da472
--- /dev/null
+++ b/core/java/android/content/IIntentSender.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2006 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 android.content;
+
+import android.content.IIntentReceiver;
+import android.content.Intent;
+
+/** @hide */
+interface IIntentSender {
+ int send(int code, in Intent intent, String resolvedType,
+ IIntentReceiver finishedReceiver);
+}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 24262f5..d4a7815 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -240,35 +240,35 @@
*
* <activity class=".NotesList" android:label="@string/title_notes_list">
* <intent-filter>
- * <action android:value="android.intent.action.MAIN" />
- * <category android:value="android.intent.category.LAUNCHER" />
+ * <action android:name="android.intent.action.MAIN" />
+ * <category android:name="android.intent.category.LAUNCHER" />
* </intent-filter>
* <intent-filter>
- * <action android:value="android.intent.action.VIEW" />
- * <action android:value="android.intent.action.EDIT" />
- * <action android:value="android.intent.action.PICK" />
- * <category android:value="android.intent.category.DEFAULT" />
- * <type android:value="vnd.android.cursor.dir/<i>vnd.google.note</i>" />
+ * <action android:name="android.intent.action.VIEW" />
+ * <action android:name="android.intent.action.EDIT" />
+ * <action android:name="android.intent.action.PICK" />
+ * <category android:name="android.intent.category.DEFAULT" />
+ * <data android:mimeType="vnd.android.cursor.dir/<i>vnd.google.note</i>" />
* </intent-filter>
* <intent-filter>
- * <action android:value="android.intent.action.GET_CONTENT" />
- * <category android:value="android.intent.category.DEFAULT" />
- * <type android:value="vnd.android.cursor.item/<i>vnd.google.note</i>" />
+ * <action android:name="android.intent.action.GET_CONTENT" />
+ * <category android:name="android.intent.category.DEFAULT" />
+ * <data android:mimeType="vnd.android.cursor.item/<i>vnd.google.note</i>" />
* </intent-filter>
* </activity>
*
* <activity class=".NoteEditor" android:label="@string/title_note">
* <intent-filter android:label="@string/resolve_edit">
- * <action android:value="android.intent.action.VIEW" />
- * <action android:value="android.intent.action.EDIT" />
- * <category android:value="android.intent.category.DEFAULT" />
- * <type android:value="vnd.android.cursor.item/<i>vnd.google.note</i>" />
+ * <action android:name="android.intent.action.VIEW" />
+ * <action android:name="android.intent.action.EDIT" />
+ * <category android:name="android.intent.category.DEFAULT" />
+ * <data android:mimeType="vnd.android.cursor.item/<i>vnd.google.note</i>" />
* </intent-filter>
*
* <intent-filter>
- * <action android:value="android.intent.action.INSERT" />
- * <category android:value="android.intent.category.DEFAULT" />
- * <type android:value="vnd.android.cursor.dir/<i>vnd.google.note</i>" />
+ * <action android:name="android.intent.action.INSERT" />
+ * <category android:name="android.intent.category.DEFAULT" />
+ * <data android:mimeType="vnd.android.cursor.dir/<i>vnd.google.note</i>" />
* </intent-filter>
*
* </activity>
@@ -276,11 +276,11 @@
* <activity class=".TitleEditor" android:label="@string/title_edit_title"
* android:theme="@android:style/Theme.Dialog">
* <intent-filter android:label="@string/resolve_title">
- * <action android:value="<i>com.android.notepad.action.EDIT_TITLE</i>" />
- * <category android:value="android.intent.category.DEFAULT" />
- * <category android:value="android.intent.category.ALTERNATIVE" />
- * <category android:value="android.intent.category.SELECTED_ALTERNATIVE" />
- * <type android:value="vnd.android.cursor.item/<i>vnd.google.note</i>" />
+ * <action android:name="<i>com.android.notepad.action.EDIT_TITLE</i>" />
+ * <category android:name="android.intent.category.DEFAULT" />
+ * <category android:name="android.intent.category.ALTERNATIVE" />
+ * <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
+ * <data android:mimeType="vnd.android.cursor.item/<i>vnd.google.note</i>" />
* </intent-filter>
* </activity>
*
@@ -294,8 +294,8 @@
* <ol>
* <li><pre>
* <intent-filter>
- * <action android:value="{@link #ACTION_MAIN android.intent.action.MAIN}" />
- * <category android:value="{@link #CATEGORY_LAUNCHER android.intent.category.LAUNCHER}" />
+ * <action android:name="{@link #ACTION_MAIN android.intent.action.MAIN}" />
+ * <category android:name="{@link #CATEGORY_LAUNCHER android.intent.category.LAUNCHER}" />
* </intent-filter></pre>
* <p>This provides a top-level entry into the NotePad application: the standard
* MAIN action is a main entry point (not requiring any other information in
@@ -303,11 +303,11 @@
* listed in the application launcher.</p>
* <li><pre>
* <intent-filter>
- * <action android:value="{@link #ACTION_VIEW android.intent.action.VIEW}" />
- * <action android:value="{@link #ACTION_EDIT android.intent.action.EDIT}" />
- * <action android:value="{@link #ACTION_PICK android.intent.action.PICK}" />
- * <category android:value="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" />
- * <type android:value="vnd.android.cursor.dir/<i>vnd.google.note</i>" />
+ * <action android:name="{@link #ACTION_VIEW android.intent.action.VIEW}" />
+ * <action android:name="{@link #ACTION_EDIT android.intent.action.EDIT}" />
+ * <action android:name="{@link #ACTION_PICK android.intent.action.PICK}" />
+ * <category android:name="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" />
+ * <data mimeType:name="vnd.android.cursor.dir/<i>vnd.google.note</i>" />
* </intent-filter></pre>
* <p>This declares the things that the activity can do on a directory of
* notes. The type being supported is given with the <type> tag, where
@@ -322,9 +322,9 @@
* activity when its component name is not explicitly specified.</p>
* <li><pre>
* <intent-filter>
- * <action android:value="{@link #ACTION_GET_CONTENT android.intent.action.GET_CONTENT}" />
- * <category android:value="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" />
- * <type android:value="vnd.android.cursor.item/<i>vnd.google.note</i>" />
+ * <action android:name="{@link #ACTION_GET_CONTENT android.intent.action.GET_CONTENT}" />
+ * <category android:name="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" />
+ * <data android:mimeType="vnd.android.cursor.item/<i>vnd.google.note</i>" />
* </intent-filter></pre>
* <p>This filter describes the ability return to the caller a note selected by
* the user without needing to know where it came from. The data type
@@ -371,10 +371,10 @@
* <ol>
* <li><pre>
* <intent-filter android:label="@string/resolve_edit">
- * <action android:value="{@link #ACTION_VIEW android.intent.action.VIEW}" />
- * <action android:value="{@link #ACTION_EDIT android.intent.action.EDIT}" />
- * <category android:value="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" />
- * <type android:value="vnd.android.cursor.item/<i>vnd.google.note</i>" />
+ * <action android:name="{@link #ACTION_VIEW android.intent.action.VIEW}" />
+ * <action android:name="{@link #ACTION_EDIT android.intent.action.EDIT}" />
+ * <category android:name="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" />
+ * <data android:mimeType="vnd.android.cursor.item/<i>vnd.google.note</i>" />
* </intent-filter></pre>
* <p>The first, primary, purpose of this activity is to let the user interact
* with a single note, as decribed by the MIME type
@@ -384,9 +384,9 @@
* specifying its component.</p>
* <li><pre>
* <intent-filter>
- * <action android:value="{@link #ACTION_INSERT android.intent.action.INSERT}" />
- * <category android:value="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" />
- * <type android:value="vnd.android.cursor.dir/<i>vnd.google.note</i>" />
+ * <action android:name="{@link #ACTION_INSERT android.intent.action.INSERT}" />
+ * <category android:name="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" />
+ * <data android:mimeType="vnd.android.cursor.dir/<i>vnd.google.note</i>" />
* </intent-filter></pre>
* <p>The secondary use of this activity is to insert a new note entry into
* an existing directory of notes. This is used when the user creates a new
@@ -422,11 +422,11 @@
*
* <pre>
* <intent-filter android:label="@string/resolve_title">
- * <action android:value="<i>com.android.notepad.action.EDIT_TITLE</i>" />
- * <category android:value="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" />
- * <category android:value="{@link #CATEGORY_ALTERNATIVE android.intent.category.ALTERNATIVE}" />
- * <category android:value="{@link #CATEGORY_SELECTED_ALTERNATIVE android.intent.category.SELECTED_ALTERNATIVE}" />
- * <type android:value="vnd.android.cursor.item/<i>vnd.google.note</i>" />
+ * <action android:name="<i>com.android.notepad.action.EDIT_TITLE</i>" />
+ * <category android:name="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" />
+ * <category android:name="{@link #CATEGORY_ALTERNATIVE android.intent.category.ALTERNATIVE}" />
+ * <category android:name="{@link #CATEGORY_SELECTED_ALTERNATIVE android.intent.category.SELECTED_ALTERNATIVE}" />
+ * <data android:mimeType="vnd.android.cursor.item/<i>vnd.google.note</i>" />
* </intent-filter></pre>
*
* <p>In the single intent template here, we
@@ -509,8 +509,8 @@
* <li> {@link #ACTION_UID_REMOVED}
* <li> {@link #ACTION_BATTERY_CHANGED}
* <li> {@link #ACTION_POWER_CONNECTED}
- * <li> {@link #ACTION_POWER_DISCONNECTED}
- * <li> {@link #ACTION_SHUTDOWN}
+ * <li> {@link #ACTION_POWER_DISCONNECTED}
+ * <li> {@link #ACTION_SHUTDOWN}
* </ul>
*
* <h3>Standard Categories</h3>
@@ -1277,10 +1277,10 @@
* This is intended for applications that wish to register specifically to this notification.
* Unlike ACTION_BATTERY_CHANGED, applications will be woken for this and so do not have to
* stay active to receive this notification. This action can be used to implement actions
- * that wait until power is available to trigger.
+ * that wait until power is available to trigger.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_POWER_DISCONNECTED = "android.intent.action.ACTION_POWER_DISCONNECTED";
+ public static final String ACTION_POWER_DISCONNECTED = "android.intent.action.ACTION_POWER_DISCONNECTED";
/**
* Broadcast Action: Device is shutting down.
* This is broadcast when the device is being shut down (completely turned
@@ -1289,7 +1289,7 @@
* to handle this, since the forground activity will be paused as well.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN";
+ public static final String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN";
/**
* Broadcast Action: Indicates low memory condition on the device
*/
@@ -1791,23 +1791,23 @@
* delivered.
*/
public static final String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
-
+
/**
* Used as a parcelable extra field in {@link #ACTION_APP_ERROR}, containing
* the bug report.
- *
+ *
* @hide
*/
public static final String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
/**
- * Used as a string extra field when sending an intent to PackageInstaller to install a
+ * Used as a string extra field when sending an intent to PackageInstaller to install a
* package. Specifies the installer package name; this package will receive the
* {@link #ACTION_APP_ERROR} intent.
- *
+ *
* @hide
*/
- public static final String EXTRA_INSTALLER_PACKAGE_NAME
+ public static final String EXTRA_INSTALLER_PACKAGE_NAME
= "android.intent.extra.INSTALLER_PACKAGE_NAME";
// ---------------------------------------------------------------------
@@ -3239,7 +3239,7 @@
* only specify a type and not data, for example to indicate the type of
* data to return. This method automatically clears any data that was
* previously set by {@link #setData}.
- *
+ *
* <p><em>Note: MIME type matching in the Android framework is
* case-sensitive, unlike formal RFC MIME types. As a result,
* you should always write your MIME types with lower case letters,
@@ -4444,7 +4444,7 @@
toShortString(b, comp, extras);
return b.toString();
}
-
+
/** @hide */
public void toShortString(StringBuilder b, boolean comp, boolean extras) {
boolean first = true;
diff --git a/core/java/android/content/IntentSender.aidl b/core/java/android/content/IntentSender.aidl
new file mode 100644
index 0000000..741bc8c
--- /dev/null
+++ b/core/java/android/content/IntentSender.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+package android.content;
+
+parcelable IntentSender;
diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java
new file mode 100644
index 0000000..4da49d9
--- /dev/null
+++ b/core/java/android/content/IntentSender.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2006 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 android.content;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IIntentSender;
+import android.content.IIntentReceiver;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AndroidException;
+
+
+/**
+ * A description of an Intent and target action to perform with it.
+ * The returned object can be
+ * handed to other applications so that they can perform the action you
+ * described on your behalf at a later time.
+ *
+ * <p>By giving a IntentSender to another application,
+ * you are granting it the right to perform the operation you have specified
+ * as if the other application was yourself (with the same permissions and
+ * identity). As such, you should be careful about how you build the IntentSender:
+ * often, for example, the base Intent you supply will have the component
+ * name explicitly set to one of your own components, to ensure it is ultimately
+ * sent there and nowhere else.
+ *
+ * <p>A IntentSender itself is simply a reference to a token maintained by
+ * the system describing the original data used to retrieve it. This means
+ * that, even if its owning application's process is killed, the
+ * IntentSender itself will remain usable from other processes that
+ * have been given it. If the creating application later re-retrieves the
+ * same kind of IntentSender (same operation, same Intent action, data,
+ * categories, and components, and same flags), it will receive a IntentSender
+ * representing the same token if that is still valid.
+ *
+ */
+public class IntentSender implements Parcelable {
+ private final IIntentSender mTarget;
+
+ /**
+ * Exception thrown when trying to send through a PendingIntent that
+ * has been canceled or is otherwise no longer able to execute the request.
+ */
+ public static class SendIntentException extends AndroidException {
+ public SendIntentException() {
+ }
+
+ public SendIntentException(String name) {
+ super(name);
+ }
+
+ public SendIntentException(Exception cause) {
+ super(cause);
+ }
+ }
+
+ /**
+ * Callback interface for discovering when a send operation has
+ * completed. Primarily for use with a IntentSender that is
+ * performing a broadcast, this provides the same information as
+ * calling {@link Context#sendOrderedBroadcast(Intent, String,
+ * android.content.BroadcastReceiver, Handler, int, String, Bundle)
+ * Context.sendBroadcast()} with a final BroadcastReceiver.
+ */
+ public interface OnFinished {
+ /**
+ * Called when a send operation as completed.
+ *
+ * @param IntentSender The IntentSender this operation was sent through.
+ * @param intent The original Intent that was sent.
+ * @param resultCode The final result code determined by the send.
+ * @param resultData The final data collected by a broadcast.
+ * @param resultExtras The final extras collected by a broadcast.
+ */
+ void onSendFinished(IntentSender IntentSender, Intent intent,
+ int resultCode, String resultData, Bundle resultExtras);
+ }
+
+ private static class FinishedDispatcher extends IIntentReceiver.Stub
+ implements Runnable {
+ private final IntentSender mIntentSender;
+ private final OnFinished mWho;
+ private final Handler mHandler;
+ private Intent mIntent;
+ private int mResultCode;
+ private String mResultData;
+ private Bundle mResultExtras;
+ FinishedDispatcher(IntentSender pi, OnFinished who, Handler handler) {
+ mIntentSender = pi;
+ mWho = who;
+ mHandler = handler;
+ }
+ public void performReceive(Intent intent, int resultCode,
+ String data, Bundle extras, boolean serialized) {
+ mIntent = intent;
+ mResultCode = resultCode;
+ mResultData = data;
+ mResultExtras = extras;
+ if (mHandler == null) {
+ run();
+ } else {
+ mHandler.post(this);
+ }
+ }
+ public void run() {
+ mWho.onSendFinished(mIntentSender, mIntent, mResultCode,
+ mResultData, mResultExtras);
+ }
+ }
+
+ /**
+ * Perform the operation associated with this IntentSender, allowing the
+ * caller to specify information about the Intent to use and be notified
+ * when the send has completed.
+ *
+ * @param context The Context of the caller. This may be null if
+ * <var>intent</var> is also null.
+ * @param code Result code to supply back to the IntentSender's target.
+ * @param intent Additional Intent data. See {@link Intent#fillIn
+ * Intent.fillIn()} for information on how this is applied to the
+ * original Intent. Use null to not modify the original Intent.
+ * @param onFinished The object to call back on when the send has
+ * completed, or null for no callback.
+ * @param handler Handler identifying the thread on which the callback
+ * should happen. If null, the callback will happen from the thread
+ * pool of the process.
+ *
+ *
+ * @throws SendIntentException Throws CanceledIntentException if the IntentSender
+ * is no longer allowing more intents to be sent through it.
+ */
+ public void sendIntent(Context context, int code, Intent intent,
+ OnFinished onFinished, Handler handler) throws SendIntentException {
+ try {
+ String resolvedType = intent != null ?
+ intent.resolveTypeIfNeeded(context.getContentResolver())
+ : null;
+ int res = mTarget.send(code, intent, resolvedType,
+ onFinished != null
+ ? new FinishedDispatcher(this, onFinished, handler)
+ : null);
+ if (res < 0) {
+ throw new SendIntentException();
+ }
+ } catch (RemoteException e) {
+ throw new SendIntentException();
+ }
+ }
+
+ /**
+ * Comparison operator on two IntentSender objects, such that true
+ * is returned then they both represent the same operation from the
+ * same package.
+ */
+ @Override
+ public boolean equals(Object otherObj) {
+ if (otherObj instanceof IntentSender) {
+ return mTarget.asBinder().equals(((IntentSender)otherObj)
+ .mTarget.asBinder());
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return mTarget.asBinder().hashCode();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("IntentSender{");
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(": ");
+ sb.append(mTarget != null ? mTarget.asBinder() : null);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeStrongBinder(mTarget.asBinder());
+ }
+
+ public static final Parcelable.Creator<IntentSender> CREATOR
+ = new Parcelable.Creator<IntentSender>() {
+ public IntentSender createFromParcel(Parcel in) {
+ IBinder target = in.readStrongBinder();
+ return target != null ? new IntentSender(target) : null;
+ }
+
+ public IntentSender[] newArray(int size) {
+ return new IntentSender[size];
+ }
+ };
+
+ /**
+ * Convenience function for writing either a IntentSender or null pointer to
+ * a Parcel. You must use this with {@link #readIntentSenderOrNullFromParcel}
+ * for later reading it.
+ *
+ * @param sender The IntentSender to write, or null.
+ * @param out Where to write the IntentSender.
+ */
+ public static void writeIntentSenderOrNullToParcel(IntentSender sender,
+ Parcel out) {
+ out.writeStrongBinder(sender != null ? sender.mTarget.asBinder()
+ : null);
+ }
+
+ /**
+ * Convenience function for reading either a Messenger or null pointer from
+ * a Parcel. You must have previously written the Messenger with
+ * {@link #writeIntentSenderOrNullToParcel}.
+ *
+ * @param in The Parcel containing the written Messenger.
+ *
+ * @return Returns the Messenger read from the Parcel, or null if null had
+ * been written.
+ */
+ public static IntentSender readIntentSenderOrNullFromParcel(Parcel in) {
+ IBinder b = in.readStrongBinder();
+ return b != null ? new IntentSender(b) : null;
+ }
+
+ protected IntentSender(IIntentSender target) {
+ mTarget = target;
+ }
+
+ protected IntentSender(IBinder target) {
+ mTarget = IIntentSender.Stub.asInterface(target);
+ }
+}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 5f62248..1a0f31f 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -35,6 +35,7 @@
import android.content.pm.ServiceInfo;
import android.net.Uri;
import android.app.PendingIntent;
+import android.content.IntentSender;
/**
* See {@link PackageManager} for documentation on most of the APIs
@@ -243,6 +244,30 @@
*/
void freeStorage(in long freeStorageSize,
in PendingIntent opFinishedIntent);
+
+ /**
+ * 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 pi IntentSender call back used to
+ * notify when the operation is completed.May be null
+ * to indicate that no call back is desired.
+ */
+ void freeStorageWithIntent(in long freeStorageSize,
+ in IntentSender pi);
/**
* 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 65783917..f74f3c2 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.IntentSender;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.drawable.Drawable;
@@ -1522,7 +1523,7 @@
* @hide
*/
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
@@ -1543,10 +1544,37 @@
* @param opFinishedIntent PendingIntent call back used to
* notify when the operation is completed.May be null
* to indicate that no call back is desired.
+ *
+ * @deprecated
+ * @hide
+ */
+ @Deprecated
+ public abstract void freeStorage(long freeStorageSize, PendingIntent opFinishedIntent);
+
+ /**
+ * 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 pi IntentSender 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);
+ public abstract void freeStorageWithIntent(long freeStorageSize, IntentSender pi);
/**
* Retrieve the size information for a package.
diff --git a/core/java/android/speech/tts/ITts.aidl b/core/java/android/speech/tts/ITts.aidl
index 739a8e4..02211fd4 100755
--- a/core/java/android/speech/tts/ITts.aidl
+++ b/core/java/android/speech/tts/ITts.aidl
@@ -39,7 +39,7 @@
void addSpeechFile(in String text, in String filename);
- void setLanguage(in String language);
+ void setLanguage(in String language, in String country, in String variant);
boolean synthesizeToFile(in String text, in String[] params, in String outputDirectory);
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 2c0c09e..8f58194 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -22,13 +22,12 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import java.util.HashMap;
+import java.util.Locale;
/**
*
@@ -36,7 +35,7 @@
*
* {@hide}
*/
-//TODO #TTS# review + complete javadoc
+//TODO #TTS# review + complete javadoc + add links to constants
public class TextToSpeech {
/**
@@ -52,9 +51,18 @@
*/
public static final int TTS_ERROR_MISSING_RESOURCE = -2;
+ /**
+ * Queue mode where all entries in the playback queue (media to be played
+ * and text to be synthesized) are dropped and replaced by the new entry.
+ */
+ public static final int TTS_QUEUE_FLUSH = 0;
+ /**
+ * Queue mode where the new entry is added at the end of the playback queue.
+ */
+ public static final int TTS_QUEUE_ADD = 1;
/**
- * Called when the TTS has initialized
+ * Called when the TTS has initialized.
*
* The InitListener must implement the onInit function. onInit is passed a
* status code indicating the result of the TTS initialization.
@@ -73,9 +81,9 @@
}
/**
- * Connection needed for the TTS
+ * Connection needed for the TTS.
*/
- private ServiceConnection serviceConnection;
+ private ServiceConnection mServiceConnection;
private ITts mITts = null;
private Context mContext = null;
@@ -104,8 +112,7 @@
}
- public void setOnSpeechCompletedListener(
- final OnSpeechCompletedListener listener) {
+ public void setOnSpeechCompletedListener(final OnSpeechCompletedListener listener) {
synchronized(mSpeechCompListenerLock) {
mSpeechCompListener = listener;
}
@@ -126,7 +133,7 @@
mStarted = false;
// Initialize the TTS, run the callback after the binding is successful
- serviceConnection = new ServiceConnection() {
+ mServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
synchronized(mStartLock) {
mITts = ITts.Stub.asInterface(service);
@@ -176,7 +183,7 @@
Intent intent = new Intent("android.intent.action.USE_TTS");
intent.addCategory("android.intent.category.TTS");
- mContext.bindService(intent, serviceConnection,
+ mContext.bindService(intent, mServiceConnection,
Context.BIND_AUTO_CREATE);
// TODO handle case where the binding works (should always work) but
// the plugin fails
@@ -190,7 +197,7 @@
*/
public void shutdown() {
try {
- mContext.unbindService(serviceConnection);
+ mContext.unbindService(mServiceConnection);
} catch (IllegalArgumentException e) {
// Do nothing and fail silently since an error here indicates that
// binding never succeeded in the first place.
@@ -291,8 +298,8 @@
* @param text
* The string of text to be spoken.
* @param queueMode
- * The queuing strategy to use. Use 0 for no queuing, and 1 for
- * queuing.
+ * The queuing strategy to use.
+ * See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
* @param params
* The hashmap of speech parameters to be used.
*/
@@ -329,12 +336,11 @@
* @param earcon
* The earcon that should be played
* @param queueMode
- * 0 for no queue (interrupts all previous utterances), 1 for
- * queued
+ * See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
* @param params
* The hashmap of parameters to be used.
*/
- public void playEarcon(String earcon, int queueMode,
+ public void playEarcon(String earcon, int queueMode,
HashMap<String,String> params) {
synchronized (mStartLock) {
if (!mStarted) {
@@ -358,8 +364,8 @@
}
}
}
-
-
+
+
public void playSilence(long durationInMs, int queueMode) {
// TODO implement, already present in TTS service
}
@@ -429,20 +435,22 @@
* Note that the speech rate is not universally supported by all engines and
* will be treated as a hint. The TTS library will try to use the specified
* speech rate, but there is no guarantee.
- *
- * Currently, this will change the speech rate for the espeak engine, but it
- * has no effect on any pre-recorded speech.
+ * This has no effect on any pre-recorded speech.
*
* @param speechRate
- * The speech rate for the TTS engine.
+ * The speech rate for the TTS engine. 1 is the normal speed,
+ * lower values slow down the speech (0.5 is half the normal speech rate),
+ * greater values accelerate it (2 is twice the normal speech rate).
*/
- public void setSpeechRate(int speechRate) {
+ public void setSpeechRate(float speechRate) {
synchronized (mStartLock) {
if (!mStarted) {
return;
}
try {
- mITts.setSpeechRate(speechRate);
+ if (speechRate > 0) {
+ mITts.setSpeechRate((int)(speechRate*100));
+ }
} catch (RemoteException e) {
// TTS died; restart it.
mStarted = false;
@@ -457,24 +465,18 @@
*
* Note that the language is not universally supported by all engines and
* will be treated as a hint. The TTS library will try to use the specified
- * language, but there is no guarantee.
+ * language as represented by the Locale, but there is no guarantee.
*
- * Currently, this will change the language for the espeak engine, but it
- * has no effect on any pre-recorded speech.
- *
- * @param language
- * The language to be used. The languages are specified by their
- * IETF language tags as defined by BCP 47. This is the same
- * standard used for the lang attribute in HTML. See:
- * http://en.wikipedia.org/wiki/IETF_language_tag
+ * @param loc
+ * The locale describing the language to be used.
*/
- public void setLanguage(String language) {
+ public void setLanguage(Locale loc) {
synchronized (mStartLock) {
if (!mStarted) {
return;
}
try {
- mITts.setLanguage(language);
+ mITts.setLanguage(loc.getISO3Language(), loc.getISO3Country(), loc.getVariant());
} catch (RemoteException e) {
// TTS died; restart it.
mStarted = false;
diff --git a/core/jni/android_bluetooth_Database.cpp b/core/jni/android_bluetooth_Database.cpp
index 136c9a3..73b8efd 100644
--- a/core/jni/android_bluetooth_Database.cpp
+++ b/core/jni/android_bluetooth_Database.cpp
@@ -53,6 +53,7 @@
LOGE("Could not get onto the system bus!");
dbus_error_free(&err);
}
+ dbus_connection_set_exit_on_disconnect(conn, FALSE);
}
#endif
}
diff --git a/core/jni/android_server_BluetoothA2dpService.cpp b/core/jni/android_server_BluetoothA2dpService.cpp
index fe94642..91a8e8e 100644
--- a/core/jni/android_server_BluetoothA2dpService.cpp
+++ b/core/jni/android_server_BluetoothA2dpService.cpp
@@ -84,6 +84,7 @@
dbus_error_free(&err);
return false;
}
+ dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
#endif /*HAVE_BLUETOOTH*/
return true;
}
diff --git a/core/jni/android_server_BluetoothDeviceService.cpp b/core/jni/android_server_BluetoothDeviceService.cpp
index b6e9798..58ae4f6 100644
--- a/core/jni/android_server_BluetoothDeviceService.cpp
+++ b/core/jni/android_server_BluetoothDeviceService.cpp
@@ -109,6 +109,7 @@
dbus_error_free(&err);
return false;
}
+ dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
nat->adapter = BLUEZ_ADAPTER_OBJECT_NAME;
#endif /*HAVE_BLUETOOTH*/
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 7c5da5b..ff8f28a 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -132,6 +132,7 @@
LOGE("%s: Could not get onto the system bus!", __FUNCTION__);
dbus_error_free(&err);
}
+ dbus_connection_set_exit_on_disconnect(nat->conn, FALSE);
}
#endif
}
diff --git a/core/res/res/layout/recent_apps_dialog.xml b/core/res/res/layout/recent_apps_dialog.xml
index 852b2f1..c4ee95d 100644
--- a/core/res/res/layout/recent_apps_dialog.xml
+++ b/core/res/res/layout/recent_apps_dialog.xml
@@ -17,67 +17,63 @@
*/
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
- android:layout_height="wrap_content">
-
+ android:layout_height="wrap_content"
+ android:padding="3dip"
+ android:orientation="vertical">
+
+ <!-- This is only intended to be visible when all buttons (below) are invisible -->
+ <TextView
+ android:id="@+id/no_applications_message"
+ android:layout_width="285dip"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="15dip"
+ android:layout_marginBottom="15dip"
+ android:gravity="center"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@android:string/no_recent_tasks" />
+
+ <!-- The first row has a fixed-width because the UI spec requires the box
+ to display with full-width no matter how many icons are visible, but to
+ adjust height based on number of rows. -->
+ <!-- TODO Adjust all sizes, padding, etc. to meet pixel-perfect specs -->
+ <LinearLayout
+ android:layout_width="285dip"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal" >
+
+ <include
+ layout="@android:layout/recent_apps_icon"
+ android:id="@+id/button1" />
+
+ <include
+ layout="@android:layout/recent_apps_icon"
+ android:id="@+id/button2" />
+
+ <include
+ layout="@android:layout/recent_apps_icon"
+ android:id="@+id/button3" />
+
+ </LinearLayout>
+
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:padding="3dip"
- android:orientation="vertical">
-
- <!-- This is only intended to be visible when all buttons (below) are invisible -->
- <TextView
- android:id="@+id/no_applications_message"
- android:layout_width="285dip"
- android:layout_height="wrap_content"
- android:layout_marginTop="15dip"
- android:layout_marginBottom="15dip"
- android:gravity="center"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:text="@android:string/no_recent_tasks" />
-
- <!-- The first row has a fixed-width because the UI spec requires the box
- to display with full-width no matter how many icons are visible, but to
- adjust height based on number of rows. -->
- <!-- TODO Adjust all sizes, padding, etc. to meet pixel-perfect specs -->
- <LinearLayout
- android:layout_width="285dip"
- android:layout_height="wrap_content"
- android:orientation="horizontal" >
+ android:orientation="horizontal" >
- <include
- layout="@android:layout/recent_apps_icon"
- android:id="@+id/button1" />
-
- <include
- layout="@android:layout/recent_apps_icon"
- android:id="@+id/button2" />
-
- <include
- layout="@android:layout/recent_apps_icon"
- android:id="@+id/button3" />
-
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal" >
-
- <include
- layout="@android:layout/recent_apps_icon"
- android:id="@+id/button4" />
-
- <include
- layout="@android:layout/recent_apps_icon"
- android:id="@+id/button5" />
-
- <include
- layout="@android:layout/recent_apps_icon"
- android:id="@+id/button6" />
-
- </LinearLayout>
+ <include
+ layout="@android:layout/recent_apps_icon"
+ android:id="@+id/button4" />
+
+ <include
+ layout="@android:layout/recent_apps_icon"
+ android:id="@+id/button5" />
+
+ <include
+ layout="@android:layout/recent_apps_icon"
+ android:id="@+id/button6" />
+
</LinearLayout>
-</FrameLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/recent_apps_icon.xml b/core/res/res/layout/recent_apps_icon.xml
index b8cf089..d32643c 100644
--- a/core/res/res/layout/recent_apps_icon.xml
+++ b/core/res/res/layout/recent_apps_icon.xml
@@ -18,27 +18,22 @@
-->
<!-- This is not a standalone element - it is imported into recent_apps_dialog.xml -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="87dip"
- android:layout_height="78dip"
- android:layout_margin="3dip"
- android:orientation="vertical"
- android:gravity="center_vertical"
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/label"
style="?android:attr/buttonStyle"
- android:background="@drawable/btn_application_selector">
- <ImageView android:id="@+id/icon"
- android:layout_width="@android:dimen/app_icon_size"
- android:layout_height="@android:dimen/app_icon_size"
- android:layout_gravity="center_horizontal"
- android:scaleType="fitCenter" />
- <TextView android:id="@+id/label"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textSize="12dip"
- android:maxLines="1"
- android:ellipsize="end"
- android:duplicateParentState="true"
- android:textColor="@color/primary_text_dark_focused"
- android:gravity="center_horizontal" />
-</LinearLayout>
+ android:background="@drawable/btn_application_selector"
+ android:layout_width="87dip"
+ android:layout_height="88dip"
+ android:layout_margin="3dip"
+ android:textColor="@color/primary_text_dark_focused"
+
+ android:paddingTop="5dip"
+ android:paddingBottom="2dip"
+ android:drawablePadding="0dip"
+
+ android:textSize="13dip"
+ android:maxLines="2"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ android:gravity="top|center_horizontal" />
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index 16c66a6..2407d87 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -3,7 +3,7 @@
android:sharedUserId="android.uid.system">
<application android:allowClearUserData="false"
- android:label="Settings Storage"
+ android:label="@string/app_label"
android:icon="@drawable/ic_launcher_settings">
<provider android:name="SettingsProvider" android:authorities="settings"
diff --git a/packages/SettingsProvider/res/values/strings.xml b/packages/SettingsProvider/res/values/strings.xml
new file mode 100644
index 0000000..9ca575e
--- /dev/null
+++ b/packages/SettingsProvider/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2007, 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.
+ */
+-->
+<resources>
+ <!-- Name of the activity for Settings storage. -->
+ <string name="app_label">Settings Storage</string>
+</resources>
diff --git a/packages/SubscribedFeedsProvider/AndroidManifest.xml b/packages/SubscribedFeedsProvider/AndroidManifest.xml
index 6ecda48..ca00a9b 100644
--- a/packages/SubscribedFeedsProvider/AndroidManifest.xml
+++ b/packages/SubscribedFeedsProvider/AndroidManifest.xml
@@ -10,7 +10,7 @@
<application android:process="system"
android:allowClearUserData="false"
android:icon="@drawable/app_icon"
- android:label="Sync Feeds">
+ android:label="@string/app_label">
<uses-library android:name="com.google.android.gtalkservice" />
<provider android:name="SubscribedFeedsProvider"
android:authorities="subscribedfeeds" android:syncable="false"
diff --git a/packages/SubscribedFeedsProvider/res/values/strings.xml b/packages/SubscribedFeedsProvider/res/values/strings.xml
new file mode 100644
index 0000000..072571d
--- /dev/null
+++ b/packages/SubscribedFeedsProvider/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<resources>
+ <!-- Title of the feed synchronization activity. -->
+ <string name="app_label">Sync Feeds</string>
+</resources>
+
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index dfecfd8..54d038a 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -269,10 +269,10 @@
}
}
-// TODO update to use language, country, variant
+
static void
android_tts_SynthProxy_setLanguage(JNIEnv *env, jobject thiz, jint jniData,
- jstring language)
+ jstring language, jstring country, jstring variant)
{
if (jniData == 0) {
LOGE("android_tts_SynthProxy_setLanguage(): invalid JNI data");
@@ -281,14 +281,16 @@
SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
const char *langNativeString = env->GetStringUTFChars(language, 0);
+ const char *countryNativeString = env->GetStringUTFChars(country, 0);
+ const char *variantNativeString = env->GetStringUTFChars(variant, 0);
// TODO check return codes
if (pSynthData->mNativeSynthInterface) {
- // TODO update to use language, country, variant
- // commented out to not break the build
- //pSynthData->mNativeSynthInterface->setLanguage(langNativeString,
- // strlen(langNativeString));
+ pSynthData->mNativeSynthInterface->setLanguage(langNativeString, countryNativeString,
+ variantNativeString);
}
env->ReleaseStringUTFChars(language, langNativeString);
+ env->ReleaseStringUTFChars(language, countryNativeString);
+ env->ReleaseStringUTFChars(language, variantNativeString);
}
@@ -496,6 +498,7 @@
return env->NewStringUTF(buf);
}
+
JNIEXPORT int JNICALL
android_tts_SynthProxy_getRate(JNIEnv *env, jobject thiz, jint jniData)
{
@@ -531,7 +534,7 @@
(void*)android_tts_SynthProxy_synthesizeToFile
},
{ "native_setLanguage",
- "(ILjava/lang/String;)V",
+ "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
(void*)android_tts_SynthProxy_setLanguage
},
{ "native_setSpeechRate",
@@ -567,7 +570,6 @@
#define SP_JNIDATA_FIELD_NAME "mJniData"
#define SP_POSTSPEECHSYNTHESIZED_METHOD_NAME "postNativeSpeechSynthesizedInJava"
-// TODO: verify this is the correct path
static const char* const kClassPathName = "android/tts/SynthProxy";
jint JNI_OnLoad(JavaVM* vm, void* reserved)
diff --git a/packages/TtsService/src/android/tts/SynthProxy.java b/packages/TtsService/src/android/tts/SynthProxy.java
index e065f40..364dc58 100755
--- a/packages/TtsService/src/android/tts/SynthProxy.java
+++ b/packages/TtsService/src/android/tts/SynthProxy.java
@@ -70,8 +70,8 @@
/**
* Sets the language
*/
- public void setLanguage(String language) {
- native_setLanguage(mJniData, language);
+ public void setLanguage(String language, String country, String variant) {
+ native_setLanguage(mJniData, language, country, variant);
}
/**
@@ -141,7 +141,8 @@
private native final void native_synthesizeToFile(int jniData, String text, String filename);
- private native final void native_setLanguage(int jniData, String language);
+ private native final void native_setLanguage(int jniData, String language, String country,
+ String variant);
private native final void native_setSpeechRate(int jniData, int speechRate);
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index 8a64113..f7dd0e8 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -129,7 +129,9 @@
mSpeechQueue = new ArrayList<SpeechItem>();
mPlayer = null;
- setLanguage(prefs.getString("lang_pref", "en-rUS"));
+ // TODO set default settings
+ //setLanguage(prefs.getString("lang_pref", "en-rUS"));
+ setLanguage("eng", "USA", "");
setSpeechRate(Integer.parseInt(prefs.getString("rate_pref", "140")));
}
@@ -155,7 +157,7 @@
nativeSynth.setSpeechRate(rate);
}
- private void setLanguage(String lang) {
+ private void setLanguage(String lang, String country, String variant) {
if (prefs.getBoolean("override_pref", false)) {
// This is set to the default here so that the preview in the prefs
// activity will show the change without a restart, even if apps are
@@ -163,7 +165,8 @@
// allowed to change the defaults.
lang = prefs.getString("lang_pref", "en-rUS");
}
- nativeSynth.setLanguage(lang);
+ Log.v("TTS", "TtsService.setLanguage("+lang+", "+country+", "+variant+")");
+ nativeSynth.setLanguage(lang, country, variant);
}
/**
@@ -683,20 +686,14 @@
}
/**
- * Sets the speech rate for the TTS. Note that this will only have an
- * effect on synthesized speech; it will not affect pre-recorded speech.
+ * Sets the speech rate for the TTS, which affects the synthesized voice.
*
- * @param language
- * Language values are based on the Android conventions for
- * localization as described in the Android platform
- * documentation on internationalization. This implies that
- * language data is specified in the format xx-rYY, where xx
- * is a two letter ISO 639-1 language code in lowercase and
- * rYY is a two letter ISO 3166-1-alpha-2 language code in
- * uppercase preceded by a lowercase "r".
+ * @param lang the three letter ISO language code.
+ * @param country the three letter ISO country code.
+ * @param variant the variant code associated with the country and language pair.
*/
- public void setLanguage(String language) {
- mSelf.setLanguage(language);
+ public void setLanguage(String lang, String country, String variant) {
+ mSelf.setLanguage(lang, country, variant);
}
/**
diff --git a/packages/VpnServices/AndroidManifest.xml b/packages/VpnServices/AndroidManifest.xml
index e48b2da..6092e30 100644
--- a/packages/VpnServices/AndroidManifest.xml
+++ b/packages/VpnServices/AndroidManifest.xml
@@ -3,7 +3,7 @@
package="com.android.server.vpn"
android:sharedUserId="android.uid.system"
>
- <application android:label="VPN Services">
+ <application android:label="@string/app_label">
<service android:name=".VpnServiceBinder" android:process=":remote">
<intent-filter>
diff --git a/packages/VpnServices/res/values/strings.xml b/packages/VpnServices/res/values/strings.xml
index 892850a..e42c1e8 100755
--- a/packages/VpnServices/res/values/strings.xml
+++ b/packages/VpnServices/res/values/strings.xml
@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
+ <!-- Title for the VPN Services activity. -->
+ <string name="app_label">VPN Services</string>
+
<string name="vpn_notification_title">%s VPN %s</string>
<string name="vpn_notification_connected">connected</string>
<string name="vpn_notification_disconnected">disconnected</string>
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 0d142da..73478e4 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -34,6 +34,8 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.IntentSender.SendIntentException;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ComponentInfo;
@@ -955,6 +957,34 @@
}
});
}
+
+ public void freeStorageWithIntent(final long freeStorageSize, final IntentSender pi) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.CLEAR_APP_CACHE, null);
+ // Queue up an async operation since clearing cache may take a little while.
+ mHandler.post(new Runnable() {
+ public void run() {
+ mHandler.removeCallbacks(this);
+ int retCode = -1;
+ if (mInstaller != null) {
+ retCode = mInstaller.freeCache(freeStorageSize);
+ if (retCode < 0) {
+ Log.w(TAG, "Couldn't clear application caches");
+ }
+ }
+ if(pi != null) {
+ try {
+ // Callback via pending intent
+ int code = (retCode >= 0) ? 1 : 0;
+ pi.sendIntent(null, code, null,
+ null, null);
+ } catch (SendIntentException e1) {
+ Log.i(TAG, "Failed to send pending intent");
+ }
+ }
+ }
+ });
+ }
public ActivityInfo getActivityInfo(ComponentName component, int flags) {
synchronized (mPackages) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 07d6b6f..755f9c8 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -34,8 +34,6 @@
import android.app.IActivityWatcher;
import android.app.IApplicationThread;
import android.app.IInstrumentationWatcher;
-import android.app.IIntentReceiver;
-import android.app.IIntentSender;
import android.app.IServiceConnection;
import android.app.IThumbnailReceiver;
import android.app.Instrumentation;
@@ -48,6 +46,8 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
@@ -61,7 +61,6 @@
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
-import android.os.BatteryStats;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
@@ -88,7 +87,6 @@
import android.util.Config;
import android.util.EventLog;
import android.util.Log;
-import android.util.LogPrinter;
import android.util.PrintWriterPrinter;
import android.util.SparseArray;
import android.view.Gravity;
@@ -127,6 +125,7 @@
static final boolean DEBUG_OOM_ADJ = localLOGV || false;
static final boolean DEBUG_TRANSITION = localLOGV || false;
static final boolean DEBUG_BROADCAST = localLOGV || false;
+ static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
static final boolean DEBUG_SERVICE = localLOGV || false;
static final boolean DEBUG_VISBILITY = localLOGV || false;
static final boolean DEBUG_PROCESSES = localLOGV || false;
@@ -8219,12 +8218,19 @@
report.time = crashData.getTime();
report.crashInfo.stackTrace = throwData.toString();
- // extract the source of the exception, useful for report
- // clustering
+ // Extract the source of the exception, useful for report
+ // clustering. Also extract the "deepest" non-null exception
+ // message.
+ String exceptionMessage = throwData.getMessage();
while (throwData.getCause() != null) {
throwData = throwData.getCause();
+ String msg = throwData.getMessage();
+ if (msg != null && msg.length() > 0) {
+ exceptionMessage = msg;
+ }
}
StackTraceElementData trace = throwData.getStackTrace()[0];
+ report.crashInfo.exceptionMessage = exceptionMessage;
report.crashInfo.exceptionClassName = throwData.getType();
report.crashInfo.throwFileName = trace.getFileName();
report.crashInfo.throwClassName = trace.getClassName();
@@ -10596,7 +10602,7 @@
boolean ordered, boolean sticky, int callingPid, int callingUid) {
intent = new Intent(intent);
- if (DEBUG_BROADCAST) Log.v(
+ if (DEBUG_BROADCAST_LIGHT) Log.v(
TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
+ " ordered=" + ordered);
if ((resultTo != null) && !ordered) {
@@ -11088,7 +11094,7 @@
boolean started = false;
try {
- if (DEBUG_BROADCAST) Log.v(TAG,
+ if (DEBUG_BROADCAST_LIGHT) Log.v(TAG,
"Delivering to component " + r.curComponent
+ ": " + r);
app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
@@ -11158,12 +11164,22 @@
r.curFilter = filter;
filter.receiverList.curBroadcast = r;
r.state = BroadcastRecord.CALL_IN_RECEIVE;
+ if (filter.receiverList.app != null) {
+ // Bump hosting application to no longer be in background
+ // scheduling class. Note that we can't do that if there
+ // isn't an app... but we can only be in that case for
+ // things that directly call the IActivityManager API, which
+ // are already core system stuff so don't matter for this.
+ r.curApp = filter.receiverList.app;
+ filter.receiverList.app.curReceiver = r;
+ updateOomAdjLocked();
+ }
}
try {
- if (DEBUG_BROADCAST) {
+ if (DEBUG_BROADCAST_LIGHT) {
int seq = r.intent.getIntExtra("seq", -1);
- Log.i(TAG, "Sending broadcast " + r.intent.getAction() + " seq=" + seq
- + " app=" + filter.receiverList.app);
+ Log.i(TAG, "Delivering to " + filter.receiverList.app
+ + " (seq=" + seq + "): " + r);
}
performReceive(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode,
@@ -11177,6 +11193,9 @@
r.receiver = null;
r.curFilter = null;
filter.receiverList.curBroadcast = null;
+ if (filter.receiverList.app != null) {
+ filter.receiverList.app.curReceiver = null;
+ }
}
}
}
@@ -11200,6 +11219,8 @@
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);
final int N = r.receivers.size();
+ if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing parallel broadcast "
+ + r);
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
if (DEBUG_BROADCAST) Log.v(TAG,
@@ -11207,6 +11228,8 @@
+ target + ": " + r);
deliverToRegisteredReceiver(r, (BroadcastFilter)target, false);
}
+ if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Done with parallel broadcast "
+ + r);
}
// Now take care of the next serialized one...
@@ -11232,10 +11255,18 @@
}
}
+ boolean looped = false;
+
do {
if (mOrderedBroadcasts.size() == 0) {
// No more broadcasts pending, so all done!
scheduleAppGcsLocked();
+ if (looped) {
+ // If we had finished the last ordered broadcast, then
+ // make sure all processes have correct oom and sched
+ // adjustments.
+ updateOomAdjLocked();
+ }
return;
}
r = mOrderedBroadcasts.get(0);
@@ -11292,9 +11323,13 @@
if (DEBUG_BROADCAST) Log.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
+ if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Finished with ordered broadcast "
+ + r);
+
// ... and on to the next...
mOrderedBroadcasts.remove(0);
r = null;
+ looped = true;
continue;
}
} while (r == null);
@@ -11308,6 +11343,8 @@
if (recIdx == 0) {
r.dispatchTime = r.startTime;
+ if (DEBUG_BROADCAST_LIGHT) Log.v(TAG, "Processing ordered broadcast "
+ + r);
if (DEBUG_BROADCAST) Log.v(TAG,
"Submitting BROADCAST_TIMEOUT_MSG for "
+ (r.startTime + BROADCAST_TIMEOUT));
diff --git a/services/java/com/android/server/am/BroadcastRecord.java b/services/java/com/android/server/am/BroadcastRecord.java
index 4057ae8..da55049 100644
--- a/services/java/com/android/server/am/BroadcastRecord.java
+++ b/services/java/com/android/server/am/BroadcastRecord.java
@@ -16,7 +16,7 @@
package com.android.server.am;
-import android.app.IIntentReceiver;
+import android.content.IIntentReceiver;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java
index 4381392..fa2a100 100644
--- a/services/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/java/com/android/server/am/PendingIntentRecord.java
@@ -17,8 +17,8 @@
package com.android.server.am;
import android.app.IActivityManager;
-import android.app.IIntentSender;
-import android.app.IIntentReceiver;
+import android.content.IIntentSender;
+import android.content.IIntentReceiver;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Binder;
diff --git a/services/java/com/android/server/am/ReceiverList.java b/services/java/com/android/server/am/ReceiverList.java
index 0facefc..32c24c6 100644
--- a/services/java/com/android/server/am/ReceiverList.java
+++ b/services/java/com/android/server/am/ReceiverList.java
@@ -16,7 +16,7 @@
package com.android.server.am;
-import android.app.IIntentReceiver;
+import android.content.IIntentReceiver;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
diff --git a/test-runner/android/test/mock/MockPackageManager.java b/test-runner/android/test/mock/MockPackageManager.java
index 6ef5539..5e7802d 100644
--- a/test-runner/android/test/mock/MockPackageManager.java
+++ b/test-runner/android/test/mock/MockPackageManager.java
@@ -20,6 +20,7 @@
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageDeleteObserver;
@@ -345,6 +346,15 @@
* @hide - to match hiding in superclass
*/
@Override
+ public void freeStorageWithIntent(
+ long idealStorageSize, IntentSender pi) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @hide - to match hiding in superclass
+ */
+ @Override
public void deletePackage(
String packageName, IPackageDeleteObserver observer, int flags) {
throw new UnsupportedOperationException();
diff --git a/tests/permission/src/com/android/framework/permission/tests/SmsManagerPermissionTest.java b/tests/permission/src/com/android/framework/permission/tests/SmsManagerPermissionTest.java
new file mode 100644
index 0000000..273943f
--- /dev/null
+++ b/tests/permission/src/com/android/framework/permission/tests/SmsManagerPermissionTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.permission.tests;
+
+import java.util.ArrayList;
+
+import android.telephony.SmsManager;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Verify that SmsManager apis cannot be called without required permissions.
+ */
+public class SmsManagerPermissionTest extends AndroidTestCase {
+
+ private static final String MSG_CONTENTS = "hi";
+ private static final short DEST_PORT = (short)1004;
+ private static final String DEST_NUMBER = "4567";
+ private static final String SRC_NUMBER = "1234";
+
+ /**
+ * Verify that SmsManager.sendTextMessage requires permissions.
+ * <p>Tests Permission:
+ * {@link android.Manifest.permission#SEND_SMS}.
+ */
+ @SmallTest
+ public void testSendTextMessage() {
+ try {
+ SmsManager.getDefault().sendTextMessage(SRC_NUMBER, DEST_NUMBER, MSG_CONTENTS, null,
+ null);
+ fail("SmsManager.sendTextMessage did not throw SecurityException as expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Verify that SmsManager.sendDataMessage requires permissions.
+ * <p>Tests Permission:
+ * {@link android.Manifest.permission#SEND_SMS}.
+ */
+ @SmallTest
+ public void testSendDataMessage() {
+ try {
+ SmsManager.getDefault().sendDataMessage(SRC_NUMBER, DEST_NUMBER, DEST_PORT,
+ MSG_CONTENTS.getBytes(), null, null);
+ fail("SmsManager.sendDataMessage did not throw SecurityException as expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Verify that SmsManager.sendMultipartMessage requires permissions.
+ * <p>Tests Permission:
+ * {@link android.Manifest.permission#SEND_MMS}.
+ */
+ @SmallTest
+ public void testSendMultipartMessage() {
+ try {
+ ArrayList<String> msgParts = new ArrayList<String>(2);
+ msgParts.add(MSG_CONTENTS);
+ msgParts.add("foo");
+ SmsManager.getDefault().sendMultipartTextMessage(SRC_NUMBER, DEST_NUMBER, msgParts,
+ null, null);
+ fail("SmsManager.sendMultipartTextMessage did not throw SecurityException as expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+}