Remove circular dependency in PackageManager. api freeStorage uses PendingIntent from android.app
Create a new public IntentSender class that can be used by PackageManager instead.
This new class uses IIntentSender internally and can only be created by PendingIntent for now.
Provide a new getIntentSender api in PendingIntent to create an instance of this class.
Move IIntentSender and IIntentReceiver from android.app to android.content
Change imports of IIntentSender and IIntentReceiver to reflect the new package name
The PackageManager api has been named as freeStorageWithIntent and will be renamed as freeStorage
once the older api(which has been deprecated) will be removed shortly.
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..b6f855a 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/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/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/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 c0d4496..ae867fb 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;
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();