blob: 5371fa5b29c09f76327b2087ab53d39349758fdd [file] [log] [blame]
Dianne Hackborn9f531192010-08-04 17:48:03 -07001/**
2 * Copyright (c) 2010, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.content;
18
19import android.content.Context;
20import android.os.Message;
21import android.os.RemoteException;
22import android.os.Handler;
23import android.os.IBinder;
24import android.os.ServiceManager;
25import android.util.Log;
26
27import java.util.ArrayList;
28
29/**
30 * Interface to the clipboard service, for placing and retrieving text in
31 * the global clipboard.
32 *
33 * <p>
34 * You do not instantiate this class directly; instead, retrieve it through
35 * {@link android.content.Context#getSystemService}.
36 *
37 * @see android.content.Context#getSystemService
38 */
39public class ClipboardManager extends android.text.ClipboardManager {
40 private final static Object sStaticLock = new Object();
41 private static IClipboard sService;
42
43 private final Context mContext;
44
45 private final ArrayList<OnPrimaryClipChangedListener> mPrimaryClipChangedListeners
46 = new ArrayList<OnPrimaryClipChangedListener>();
47
48 private final IOnPrimaryClipChangedListener.Stub mPrimaryClipChangedServiceListener
49 = new IOnPrimaryClipChangedListener.Stub() {
50 public void dispatchPrimaryClipChanged() {
51 mHandler.sendEmptyMessage(MSG_REPORT_PRIMARY_CLIP_CHANGED);
52 }
53 };
54
55 static final int MSG_REPORT_PRIMARY_CLIP_CHANGED = 1;
56
57 private final Handler mHandler = new Handler() {
58 @Override
59 public void handleMessage(Message msg) {
60 switch (msg.what) {
61 case MSG_REPORT_PRIMARY_CLIP_CHANGED:
62 reportPrimaryClipChanged();
63 }
64 }
65 };
66
67 public interface OnPrimaryClipChangedListener {
68 void onPrimaryClipChanged();
69 }
70
71 static private IClipboard getService() {
72 synchronized (sStaticLock) {
73 if (sService != null) {
74 return sService;
75 }
76 IBinder b = ServiceManager.getService("clipboard");
77 sService = IClipboard.Stub.asInterface(b);
78 return sService;
79 }
80 }
81
82 /** {@hide} */
83 public ClipboardManager(Context context, Handler handler) {
84 mContext = context;
85 }
86
87 /**
88 * Sets the current primary clip on the clipboard. This is the clip that
89 * is involved in normal cut and paste operations.
90 *
91 * @param clip The clipped data item to set.
92 */
93 public void setPrimaryClip(ClippedData clip) {
94 try {
95 getService().setPrimaryClip(clip);
96 } catch (RemoteException e) {
97 }
98 }
99
100 /**
101 * Returns the current primary clip on the clipboard.
102 */
103 public ClippedData getPrimaryClip() {
104 try {
105 return getService().getPrimaryClip();
106 } catch (RemoteException e) {
107 return null;
108 }
109 }
110
111 /**
112 * Returns true if there is currently a primary clip on the clipboard.
113 */
114 public boolean hasPrimaryClip() {
115 try {
116 return getService().hasPrimaryClip();
117 } catch (RemoteException e) {
118 return false;
119 }
120 }
121
122 public void addPrimaryClipChangedListener(OnPrimaryClipChangedListener what) {
123 synchronized (mPrimaryClipChangedListeners) {
124 if (mPrimaryClipChangedListeners.size() == 0) {
125 try {
126 getService().addPrimaryClipChangedListener(
127 mPrimaryClipChangedServiceListener);
128 } catch (RemoteException e) {
129 }
130 }
131 mPrimaryClipChangedListeners.add(what);
132 }
133 }
134
135 public void removePrimaryClipChangedListener(OnPrimaryClipChangedListener what) {
136 synchronized (mPrimaryClipChangedListeners) {
137 mPrimaryClipChangedListeners.remove(what);
138 if (mPrimaryClipChangedListeners.size() == 0) {
139 try {
140 getService().removePrimaryClipChangedListener(
141 mPrimaryClipChangedServiceListener);
142 } catch (RemoteException e) {
143 }
144 }
145 }
146 }
147
148 /**
149 * @deprecated Use {@link #getPrimaryClip()} instead. This retrieves
150 * the primary clip and tries to coerce it to a string.
151 */
152 public CharSequence getText() {
153 ClippedData clip = getPrimaryClip();
154 if (clip != null && clip.getItemCount() > 0) {
155 return clip.getItem(0).getText();
156 }
157 return null;
158 }
159
160 /**
161 * @deprecated Use {@link #setPrimaryClip(ClippedData)} instead. This
162 * creates a ClippedItem holding the given text and sets it as the
163 * primary clip. It has no label or icon.
164 */
165 public void setText(CharSequence text) {
166 setPrimaryClip(new ClippedData(null, null, new ClippedData.Item(text)));
167 }
168
169 /**
170 * Returns true if the clipboard has a primary clip containing text; false otherwise.
171 */
172 public boolean hasText() {
173 try {
174 return getService().hasClipboardText();
175 } catch (RemoteException e) {
176 return false;
177 }
178 }
179
180 void reportPrimaryClipChanged() {
181 Object[] listeners;
182
183 synchronized (mPrimaryClipChangedListeners) {
184 final int N = mPrimaryClipChangedListeners.size();
185 if (N <= 0) {
186 return;
187 }
188 listeners = mPrimaryClipChangedListeners.toArray();
189 }
190
191 for (int i=0; i<listeners.length; i++) {
192 ((OnPrimaryClipChangedListener)listeners[i]).onPrimaryClipChanged();
193 }
194 }
195}