diff options
| author | 2009-06-12 10:09:58 -0700 | |
|---|---|---|
| committer | 2009-06-17 11:31:26 -0700 | |
| commit | 1ccac75e1f1b97eccb916a8de04fc1012b30f6e5 (patch) | |
| tree | 181c91a427de2ea609eff1f42c3970a441225b45 | |
| parent | ef29f6afb4746eae8263ab901a5d3677bc04574b (diff) | |
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.
24 files changed, 740 insertions, 78 deletions
diff --git a/Android.mk b/Android.mk index 6e292a8f6d1b..0e8793da36ab 100644 --- a/Android.mk +++ b/Android.mk @@ -70,10 +70,8 @@ LOCAL_SRC_FILES += \ 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 @@ LOCAL_SRC_FILES += \ 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 @@ aidl_files := \ 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 f37525777a1f..2128e5b4acaa 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 7fb3449fcbf9..501be01797e5 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -23,6 +23,7 @@ import android.content.ComponentName; 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 3d3d7d5fc9f4..b6f855a2e51c 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 3676594e5fa4..477badbdf2d4 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -23,6 +23,7 @@ import android.content.ContentProvider; 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 fc3cdcfd30b8..fa3d5c2ad8a6 100644 --- a/core/java/android/app/ApplicationContext.java +++ b/core/java/android/app/ApplicationContext.java @@ -32,6 +32,8 @@ import android.content.ContextWrapper; 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 @@ class ApplicationContext extends Context { // Should never happen! } } - + + @Override + public void freeStorage(long freeStorageSize, PendingIntent pi) { + try { + mPM.freeStorage(freeStorageSize, pi); + } catch (RemoteException e) { + // Should never happen! + } + } + @Override - public void freeStorage(long idealStorageSize, PendingIntent opFinishedIntent) { + public void freeStorageWithIntent(long freeStorageSize, IntentSender pi) { try { - mPM.freeStorage(idealStorageSize, opFinishedIntent); + 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 6750d12ae64e..4b64c943f67e 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -18,6 +18,7 @@ package android.app; 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 c948aec964e5..66bc85be57d1 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -21,6 +21,8 @@ import android.content.ContentProviderNative; 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 bca1fea150d4..029c650f8c33 100644 --- a/core/java/android/app/IApplicationThread.java +++ b/core/java/android/app/IApplicationThread.java @@ -18,6 +18,7 @@ package android.app; 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 5f5d0eb133e5..000000000000 --- 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 53e135ab1bb0..000000000000 --- 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 cb660c7fde6f..f9c38f998c35 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -18,6 +18,9 @@ package android.app; 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 final class PendingIntent implements Parcelable { public CanceledException(Exception cause) { super(cause); } - }; + } /** * Callback interface for discovering when a send operation has @@ -270,6 +273,21 @@ public final class PendingIntent implements Parcelable { 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 000000000000..443db2d06d0f --- /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 000000000000..b7da47219ce4 --- /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 000000000000..741bc8c953cb --- /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 000000000000..4da49d974fd5 --- /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 5f62248bcd14..1a0f31f2cafe 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.ResolveInfo; 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 @@ interface IPackageManager { */ 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 65783917f909..f74f3c2a5a14 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -22,6 +22,7 @@ import android.content.ComponentName; 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 @@ public abstract class PackageManager { * @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,12 +1544,39 @@ public abstract class PackageManager { * @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 freeStorageWithIntent(long freeStorageSize, IntentSender pi); + + /** * Retrieve the size information for a package. * Since this may take a little while, the result will * be posted back to the given observer. The calling context diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index 0d142da549cc..73478e4b2432 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -34,6 +34,8 @@ import android.content.ContentResolver; 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 @@ class PackageManagerService extends IPackageManager.Stub { } }); } + + 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 c0d4496e00c0..ae867fb75537 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.Dialog; 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.ContentResolver; 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 4057ae82d374..da55049de7ad 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 438139282255..fa2a1004cda7 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 0facefc52d3a..32c24c6cbf6f 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 6ef5539ad0c8..5e7802d2994d 100644 --- a/test-runner/android/test/mock/MockPackageManager.java +++ b/test-runner/android/test/mock/MockPackageManager.java @@ -20,6 +20,7 @@ import android.app.PendingIntent; 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 @@ public class MockPackageManager extends PackageManager { * @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(); |