First pass at a new clipboard API.

ClipboardManager was in android.text(!!) so it needed to be moved
up to android.content to have access to the richer data types we
now need.

ClippedData is the data representation.  Still needs a lot of
fleshing out to allow holding more than one data type at a time
and perhaps conversions between them.  (MIME-oriented interrogation
and conversion will be done through ContentProvider, which needs
to grow an ability to report multiple MIME types and accept a
desired MIME type when a stream is being opened.)

Change-Id: Ifa51bedcd084a677813b255d171804e8496b0cb5
This commit is contained in:
Dianne Hackborn
2010-08-04 17:48:03 -07:00
parent 2184abfead
commit 9f53119b72
11 changed files with 926 additions and 88 deletions

View File

@ -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;
}
}
// javadoc from interface
public CharSequence getClipboardText() {
public ClippedData getPrimaryClip() {
synchronized (this) {
return mClipboard;
return mPrimaryClip;
}
}
public boolean hasPrimaryClip() {
synchronized (this) {
return mPrimaryClip != null;
}
}
public void addPrimaryClipChangedListener(IOnPrimaryClipChangedListener listener) {
synchronized (this) {
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;
}
}
}