diff options
-rw-r--r-- | Android.mk | 3 | ||||
-rw-r--r-- | api/current.xml | 433 | ||||
-rw-r--r-- | core/java/android/app/ContextImpl.java | 2 | ||||
-rw-r--r-- | core/java/android/content/ClipboardManager.java | 195 | ||||
-rw-r--r-- | core/java/android/content/ClippedData.aidl | 19 | ||||
-rw-r--r-- | core/java/android/content/ClippedData.java | 189 | ||||
-rw-r--r-- | core/java/android/content/IClipboard.aidl (renamed from core/java/android/text/IClipboard.aidl) | 22 | ||||
-rw-r--r-- | core/java/android/content/IOnPrimaryClipChangedListener.aidl | 21 | ||||
-rw-r--r-- | core/java/android/text/ClipboardManager.java | 61 | ||||
-rw-r--r-- | services/java/com/android/server/ClipboardService.java | 59 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 4 |
11 files changed, 923 insertions, 85 deletions
@@ -100,9 +100,11 @@ LOCAL_SRC_FILES += \ core/java/android/bluetooth/IBluetoothCallback.aidl \ core/java/android/bluetooth/IBluetoothHeadset.aidl \ core/java/android/bluetooth/IBluetoothPbap.aidl \ + core/java/android/content/IClipboard.aidl \ core/java/android/content/IContentService.aidl \ core/java/android/content/IIntentReceiver.aidl \ core/java/android/content/IIntentSender.aidl \ + core/java/android/content/IOnPrimaryClipChangedListener.aidl \ core/java/android/content/ISyncAdapter.aidl \ core/java/android/content/ISyncContext.aidl \ core/java/android/content/ISyncStatusObserver.aidl \ @@ -132,7 +134,6 @@ LOCAL_SRC_FILES += \ core/java/android/service/wallpaper/IWallpaperConnection.aidl \ core/java/android/service/wallpaper/IWallpaperEngine.aidl \ core/java/android/service/wallpaper/IWallpaperService.aidl \ - core/java/android/text/IClipboard.aidl \ core/java/android/view/accessibility/IAccessibilityManager.aidl \ core/java/android/view/accessibility/IAccessibilityManagerClient.aidl \ core/java/android/view/IApplicationToken.aidl \ diff --git a/api/current.xml b/api/current.xml index b24ba43..e183d23 100644 --- a/api/current.xml +++ b/api/current.xml @@ -38810,6 +38810,336 @@ </parameter> </method> </class> +<class name="ClipboardManager" + extends="android.text.ClipboardManager" + abstract="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<method name="addPrimaryClipChangedListener" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="what" type="android.content.ClipboardManager.OnPrimaryClipChangedListener"> +</parameter> +</method> +<method name="getPrimaryClip" + return="android.content.ClippedData" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getText" + return="java.lang.CharSequence" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="deprecated" + visibility="public" +> +</method> +<method name="hasPrimaryClip" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="hasText" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="removePrimaryClipChangedListener" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="what" type="android.content.ClipboardManager.OnPrimaryClipChangedListener"> +</parameter> +</method> +<method name="setPrimaryClip" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="clip" type="android.content.ClippedData"> +</parameter> +</method> +<method name="setText" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="deprecated" + visibility="public" +> +<parameter name="text" type="java.lang.CharSequence"> +</parameter> +</method> +</class> +<interface name="ClipboardManager.OnPrimaryClipChangedListener" + abstract="true" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<method name="onPrimaryClipChanged" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +</interface> +<class name="ClippedData" + extends="java.lang.Object" + abstract="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<implements name="android.os.Parcelable"> +</implements> +<constructor name="ClippedData" + type="android.content.ClippedData" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="label" type="java.lang.CharSequence"> +</parameter> +<parameter name="icon" type="android.graphics.Bitmap"> +</parameter> +<parameter name="item" type="android.content.ClippedData.Item"> +</parameter> +</constructor> +<method name="addItem" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="item" type="android.content.ClippedData.Item"> +</parameter> +</method> +<method name="describeContents" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getIcon" + return="android.graphics.Bitmap" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getItem" + return="android.content.ClippedData.Item" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="index" type="int"> +</parameter> +</method> +<method name="getItemCount" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getLabel" + return="java.lang.CharSequence" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="writeToParcel" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="dest" 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> +<class name="ClippedData.Item" + extends="java.lang.Object" + abstract="false" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<constructor name="ClippedData.Item" + type="android.content.ClippedData.Item" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="text" type="java.lang.CharSequence"> +</parameter> +</constructor> +<constructor name="ClippedData.Item" + type="android.content.ClippedData.Item" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="intent" type="android.content.Intent"> +</parameter> +</constructor> +<constructor name="ClippedData.Item" + type="android.content.ClippedData.Item" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="uri" type="android.net.Uri"> +</parameter> +</constructor> +<constructor name="ClippedData.Item" + type="android.content.ClippedData.Item" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="text" type="java.lang.CharSequence"> +</parameter> +<parameter name="intent" type="android.content.Intent"> +</parameter> +<parameter name="uri" type="android.net.Uri"> +</parameter> +</constructor> +<method name="getIntent" + return="android.content.Intent" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getText" + return="java.lang.CharSequence" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getUri" + return="android.net.Uri" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +</class> <interface name="ComponentCallbacks" abstract="true" static="false" @@ -44627,6 +44957,93 @@ > </method> </interface> +<interface name="IOnPrimaryClipChangedListener" + abstract="true" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<implements name="android.os.IInterface"> +</implements> +<method name="dispatchPrimaryClipChanged" + return="void" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<exception name="RemoteException" type="android.os.RemoteException"> +</exception> +</method> +</interface> +<class name="IOnPrimaryClipChangedListener.Stub" + extends="android.os.Binder" + abstract="true" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<implements name="android.content.IOnPrimaryClipChangedListener"> +</implements> +<constructor name="IOnPrimaryClipChangedListener.Stub" + type="android.content.IOnPrimaryClipChangedListener.Stub" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</constructor> +<method name="asBinder" + return="android.os.IBinder" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="asInterface" + return="android.content.IOnPrimaryClipChangedListener" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="obj" type="android.os.IBinder"> +</parameter> +</method> +<method name="onTransact" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="code" type="int"> +</parameter> +<parameter name="data" type="android.os.Parcel"> +</parameter> +<parameter name="reply" type="android.os.Parcel"> +</parameter> +<parameter name="flags" type="int"> +</parameter> +<exception name="RemoteException" type="android.os.RemoteException"> +</exception> +</method> +</class> <class name="Intent" extends="java.lang.Object" abstract="false" @@ -166226,15 +166643,23 @@ </class> <class name="ClipboardManager" extends="java.lang.Object" - abstract="false" + abstract="true" + static="false" + final="false" + deprecated="deprecated" + visibility="public" +> +<constructor name="ClipboardManager" + type="android.text.ClipboardManager" static="false" final="false" deprecated="not deprecated" visibility="public" > +</constructor> <method name="getText" return="java.lang.CharSequence" - abstract="false" + abstract="true" native="false" synchronized="false" static="false" @@ -166245,7 +166670,7 @@ </method> <method name="hasText" return="boolean" - abstract="false" + abstract="true" native="false" synchronized="false" static="false" @@ -166256,7 +166681,7 @@ </method> <method name="setText" return="void" - abstract="false" + abstract="true" native="false" synchronized="false" static="false" diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 10ebd60..2786372 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -92,7 +92,7 @@ import android.os.Vibrator; import android.os.FileUtils.FileStatus; import android.os.storage.StorageManager; import android.telephony.TelephonyManager; -import android.text.ClipboardManager; +import android.content.ClipboardManager; import android.util.AndroidRuntimeException; import android.util.Log; import android.view.ContextThemeWrapper; diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java new file mode 100644 index 0000000..5371fa5 --- /dev/null +++ b/core/java/android/content/ClipboardManager.java @@ -0,0 +1,195 @@ +/** + * Copyright (c) 2010, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content; + +import android.content.Context; +import android.os.Message; +import android.os.RemoteException; +import android.os.Handler; +import android.os.IBinder; +import android.os.ServiceManager; +import android.util.Log; + +import java.util.ArrayList; + +/** + * Interface to the clipboard service, for placing and retrieving text in + * the global clipboard. + * + * <p> + * You do not instantiate this class directly; instead, retrieve it through + * {@link android.content.Context#getSystemService}. + * + * @see android.content.Context#getSystemService + */ +public class ClipboardManager extends android.text.ClipboardManager { + private final static Object sStaticLock = new Object(); + private static IClipboard sService; + + private final Context mContext; + + private final ArrayList<OnPrimaryClipChangedListener> mPrimaryClipChangedListeners + = new ArrayList<OnPrimaryClipChangedListener>(); + + private final IOnPrimaryClipChangedListener.Stub mPrimaryClipChangedServiceListener + = new IOnPrimaryClipChangedListener.Stub() { + public void dispatchPrimaryClipChanged() { + mHandler.sendEmptyMessage(MSG_REPORT_PRIMARY_CLIP_CHANGED); + } + }; + + static final int MSG_REPORT_PRIMARY_CLIP_CHANGED = 1; + + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_REPORT_PRIMARY_CLIP_CHANGED: + reportPrimaryClipChanged(); + } + } + }; + + public interface OnPrimaryClipChangedListener { + void onPrimaryClipChanged(); + } + + static private IClipboard getService() { + synchronized (sStaticLock) { + if (sService != null) { + return sService; + } + IBinder b = ServiceManager.getService("clipboard"); + sService = IClipboard.Stub.asInterface(b); + return sService; + } + } + + /** {@hide} */ + public ClipboardManager(Context context, Handler handler) { + mContext = context; + } + + /** + * Sets the current primary clip on the clipboard. This is the clip that + * is involved in normal cut and paste operations. + * + * @param clip The clipped data item to set. + */ + public void setPrimaryClip(ClippedData clip) { + try { + getService().setPrimaryClip(clip); + } catch (RemoteException e) { + } + } + + /** + * Returns the current primary clip on the clipboard. + */ + public ClippedData getPrimaryClip() { + try { + return getService().getPrimaryClip(); + } catch (RemoteException e) { + return null; + } + } + + /** + * Returns true if there is currently a primary clip on the clipboard. + */ + public boolean hasPrimaryClip() { + try { + return getService().hasPrimaryClip(); + } catch (RemoteException e) { + return false; + } + } + + public void addPrimaryClipChangedListener(OnPrimaryClipChangedListener what) { + synchronized (mPrimaryClipChangedListeners) { + if (mPrimaryClipChangedListeners.size() == 0) { + try { + getService().addPrimaryClipChangedListener( + mPrimaryClipChangedServiceListener); + } catch (RemoteException e) { + } + } + mPrimaryClipChangedListeners.add(what); + } + } + + public void removePrimaryClipChangedListener(OnPrimaryClipChangedListener what) { + synchronized (mPrimaryClipChangedListeners) { + mPrimaryClipChangedListeners.remove(what); + if (mPrimaryClipChangedListeners.size() == 0) { + try { + getService().removePrimaryClipChangedListener( + mPrimaryClipChangedServiceListener); + } catch (RemoteException e) { + } + } + } + } + + /** + * @deprecated Use {@link #getPrimaryClip()} instead. This retrieves + * the primary clip and tries to coerce it to a string. + */ + public CharSequence getText() { + ClippedData clip = getPrimaryClip(); + if (clip != null && clip.getItemCount() > 0) { + return clip.getItem(0).getText(); + } + return null; + } + + /** + * @deprecated Use {@link #setPrimaryClip(ClippedData)} instead. This + * creates a ClippedItem holding the given text and sets it as the + * primary clip. It has no label or icon. + */ + public void setText(CharSequence text) { + setPrimaryClip(new ClippedData(null, null, new ClippedData.Item(text))); + } + + /** + * Returns true if the clipboard has a primary clip containing text; false otherwise. + */ + public boolean hasText() { + try { + return getService().hasClipboardText(); + } catch (RemoteException e) { + return false; + } + } + + void reportPrimaryClipChanged() { + Object[] listeners; + + synchronized (mPrimaryClipChangedListeners) { + final int N = mPrimaryClipChangedListeners.size(); + if (N <= 0) { + return; + } + listeners = mPrimaryClipChangedListeners.toArray(); + } + + for (int i=0; i<listeners.length; i++) { + ((OnPrimaryClipChangedListener)listeners[i]).onPrimaryClipChanged(); + } + } +} diff --git a/core/java/android/content/ClippedData.aidl b/core/java/android/content/ClippedData.aidl new file mode 100644 index 0000000..5246526 --- /dev/null +++ b/core/java/android/content/ClippedData.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2010, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content; + +parcelable ClippedData; diff --git a/core/java/android/content/ClippedData.java b/core/java/android/content/ClippedData.java new file mode 100644 index 0000000..ebb194f --- /dev/null +++ b/core/java/android/content/ClippedData.java @@ -0,0 +1,189 @@ +/** + * Copyright (c) 2010, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content; + +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; + +import java.util.ArrayList; + +/** + * Representation of a clipped data on the clipboard. + * + * <p>ClippedData is a complex type containing one or Item instances, + * each of which can hold one or more representations of an item of data. + * For display to the user, it also has a label and iconic representation.</p> + * + * <p>The types than an individial item can currently contain are:</p> + * + * <ul> + * <li> Text: a basic string of text. This is actually a CharSequence, + * so it can be formatted text supported by corresponding Android built-in + * style spans. (Custom application spans are not supported and will be + * stripped when transporting through the clipboard.) + * <li> Intent: an arbitrary Intent object. A typical use is the shortcut + * to create when pasting a clipped item on to the home screen. + * <li> Uri: a URI reference. Currently this should only be a content: URI. + * This representation allows an application to share complex or large clips, + * by providing a URI to a content provider holding the data. + * </ul> + */ +public class ClippedData implements Parcelable { + CharSequence mLabel; + Bitmap mIcon; + + final ArrayList<Item> mItems = new ArrayList<Item>(); + + public static class Item { + CharSequence mText; + Intent mIntent; + Uri mUri; + + public Item(CharSequence text) { + mText = text; + } + + public Item(Intent intent) { + mIntent = intent; + } + + public Item(Uri uri) { + mUri = uri; + } + + public Item(CharSequence text, Intent intent, Uri uri) { + mText = text; + mIntent = intent; + mUri = uri; + } + + public CharSequence getText() { + return mText; + } + + public Intent getIntent() { + return mIntent; + } + + public Uri getUri() { + return mUri; + } + } + + /** + * Create a new clip. + * + * @param label Label to show to the user describing this clip. + * @param icon Bitmap providing the user with an iconing representation of + * the clip. + * @param item The contents of the first item in the clip. + */ + public ClippedData(CharSequence label, Bitmap icon, Item item) { + if (item == null) { + throw new NullPointerException("item is null"); + } + mLabel = label; + mIcon = icon; + mItems.add(item); + } + + public void addItem(Item item) { + if (item == null) { + throw new NullPointerException("item is null"); + } + mItems.add(item); + } + + public CharSequence getLabel() { + return mLabel; + } + + public Bitmap getIcon() { + return mIcon; + } + + public int getItemCount() { + return mItems.size(); + } + + public Item getItem(int index) { + return mItems.get(index); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + TextUtils.writeToParcel(mLabel, dest, flags); + if (mIcon != null) { + dest.writeInt(1); + mIcon.writeToParcel(dest, flags); + } else { + dest.writeInt(0); + } + final int N = mItems.size(); + dest.writeInt(N); + for (int i=0; i<N; i++) { + Item item = mItems.get(i); + TextUtils.writeToParcel(item.mText, dest, flags); + if (item.mIntent != null) { + dest.writeInt(1); + item.mIntent.writeToParcel(dest, flags); + } else { + dest.writeInt(0); + } + if (item.mUri != null) { + dest.writeInt(1); + item.mUri.writeToParcel(dest, flags); + } else { + dest.writeInt(0); + } + } + } + + ClippedData(Parcel in) { + mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); + if (in.readInt() != 0) { + mIcon = Bitmap.CREATOR.createFromParcel(in); + } + final int N = in.readInt(); + for (int i=0; i<N; i++) { + CharSequence text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); + Intent intent = in.readInt() != 0 ? Intent.CREATOR.createFromParcel(in) : null; + Uri uri = in.readInt() != 0 ? Uri.CREATOR.createFromParcel(in) : null; + mItems.add(new Item(text, intent, uri)); + } + } + + public static final Parcelable.Creator<ClippedData> CREATOR = + new Parcelable.Creator<ClippedData>() { + + public ClippedData createFromParcel(Parcel source) { + return new ClippedData(source); + } + + public ClippedData[] newArray(int size) { + return new ClippedData[size]; + } + }; +} diff --git a/core/java/android/text/IClipboard.aidl b/core/java/android/content/IClipboard.aidl index 4deb5c8..b4534a9 100644 --- a/core/java/android/text/IClipboard.aidl +++ b/core/java/android/content/IClipboard.aidl @@ -14,7 +14,10 @@ * limitations under the License. */ -package android.text; +package android.content; + +import android.content.ClippedData; +import android.content.IOnPrimaryClipChangedListener; /** * Programming interface to the clipboard, which allows copying and pasting @@ -22,21 +25,14 @@ package android.text; * {@hide} */ interface IClipboard { - /** - * Returns the text on the clipboard. It will eventually be possible - * to store types other than text too, in which case this will return - * null if the type cannot be coerced to text. - */ - CharSequence getClipboardText(); - - /** - * Sets the contents of the clipboard to the specified text. - */ - void setClipboardText(CharSequence text); + void setPrimaryClip(in ClippedData clip); + ClippedData getPrimaryClip(); + boolean hasPrimaryClip(); + void addPrimaryClipChangedListener(in IOnPrimaryClipChangedListener listener); + void removePrimaryClipChangedListener(in IOnPrimaryClipChangedListener listener); /** * Returns true if the clipboard contains text; false otherwise. */ boolean hasClipboardText(); } - diff --git a/core/java/android/content/IOnPrimaryClipChangedListener.aidl b/core/java/android/content/IOnPrimaryClipChangedListener.aidl new file mode 100644 index 0000000..fb42a45 --- /dev/null +++ b/core/java/android/content/IOnPrimaryClipChangedListener.aidl @@ -0,0 +1,21 @@ +/** + * 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; + +oneway interface IOnPrimaryClipChangedListener { + void dispatchPrimaryClipChanged(); +} diff --git a/core/java/android/text/ClipboardManager.java b/core/java/android/text/ClipboardManager.java index 52039af..0b239cf 100644 --- a/core/java/android/text/ClipboardManager.java +++ b/core/java/android/text/ClipboardManager.java @@ -16,73 +16,26 @@ package android.text; -import android.content.Context; -import android.os.RemoteException; -import android.os.Handler; -import android.os.IBinder; -import android.os.ServiceManager; -import android.util.Log; - /** - * Interface to the clipboard service, for placing and retrieving text in - * the global clipboard. - * - * <p> - * You do not instantiate this class directly; instead, retrieve it through - * {@link android.content.Context#getSystemService}. - * - * @see android.content.Context#getSystemService + * @deprecated Old text-only interace to the clipboard. See + * {@link android.content.ClipboardManager} for the modern API. */ -public class ClipboardManager { - private static IClipboard sService; - - private Context mContext; - - static private IClipboard getService() { - if (sService != null) { - return sService; - } - IBinder b = ServiceManager.getService("clipboard"); - sService = IClipboard.Stub.asInterface(b); - return sService; - } - - /** {@hide} */ - public ClipboardManager(Context context, Handler handler) { - mContext = context; - } - +@Deprecated +public abstract class ClipboardManager { /** * Returns the text on the clipboard. It will eventually be possible * to store types other than text too, in which case this will return * null if the type cannot be coerced to text. */ - public CharSequence getText() { - try { - return getService().getClipboardText(); - } catch (RemoteException e) { - return null; - } - } + public abstract CharSequence getText(); /** * Sets the contents of the clipboard to the specified text. */ - public void setText(CharSequence text) { - try { - getService().setClipboardText(text); - } catch (RemoteException e) { - } - } + public abstract void setText(CharSequence text); /** * Returns true if the clipboard contains text; false otherwise. */ - public boolean hasText() { - try { - return getService().hasClipboardText(); - } catch (RemoteException e) { - return false; - } - } + public abstract boolean hasText(); } diff --git a/services/java/com/android/server/ClipboardService.java b/services/java/com/android/server/ClipboardService.java index aa8cded..4e4fc0c 100644 --- a/services/java/com/android/server/ClipboardService.java +++ b/services/java/com/android/server/ClipboardService.java @@ -16,42 +16,77 @@ package com.android.server; -import android.text.IClipboard; +import android.content.ClippedData; +import android.content.IClipboard; +import android.content.IOnPrimaryClipChangedListener; import android.content.Context; +import android.os.RemoteCallbackList; +import android.os.RemoteException; /** * Implementation of the clipboard for copy and paste. */ public class ClipboardService extends IClipboard.Stub { - private CharSequence mClipboard = ""; + private ClippedData mPrimaryClip; + private final RemoteCallbackList<IOnPrimaryClipChangedListener> mPrimaryClipListeners + = new RemoteCallbackList<IOnPrimaryClipChangedListener>(); /** * Instantiates the clipboard. */ public ClipboardService(Context context) { } - // javadoc from interface - public void setClipboardText(CharSequence text) { + public void setPrimaryClip(ClippedData clip) { synchronized (this) { - if (text == null) { - text = ""; + if (clip != null && clip.getItemCount() <= 0) { + throw new IllegalArgumentException("No items"); } + mPrimaryClip = clip; + final int n = mPrimaryClipListeners.beginBroadcast(); + for (int i = 0; i < n; i++) { + try { + mPrimaryClipListeners.getBroadcastItem(i).dispatchPrimaryClipChanged(); + } catch (RemoteException e) { + + // The RemoteCallbackList will take care of removing + // the dead object for us. + } + } + mPrimaryClipListeners.finishBroadcast(); + } + } - mClipboard = text; + public ClippedData getPrimaryClip() { + synchronized (this) { + return mPrimaryClip; + } + } + + public boolean hasPrimaryClip() { + synchronized (this) { + return mPrimaryClip != null; } } - // javadoc from interface - public CharSequence getClipboardText() { + public void addPrimaryClipChangedListener(IOnPrimaryClipChangedListener listener) { synchronized (this) { - return mClipboard; + mPrimaryClipListeners.register(listener); + } + } + + public void removePrimaryClipChangedListener(IOnPrimaryClipChangedListener listener) { + synchronized (this) { + mPrimaryClipListeners.unregister(listener); } } - // javadoc from interface public boolean hasClipboardText() { synchronized (this) { - return mClipboard.length() > 0; + if (mPrimaryClip != null) { + CharSequence text = mPrimaryClip.getItem(0).getText(); + return text != null && text.length() > 0; + } + return false; } } } diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 415073e..a32cd4c 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -2359,6 +2359,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } if (proc.thread != null) { + if (proc.pid == Process.myPid()) { + Log.w(TAG, "crashApplication: trying to crash self!"); + return; + } long ident = Binder.clearCallingIdentity(); try { proc.thread.scheduleCrash(message); |