19f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn/** 29f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * Copyright (c) 2010, The Android Open Source Project 39f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 49f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 59f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * you may not use this file except in compliance with the License. 69f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * You may obtain a copy of the License at 79f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 89f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 99f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 109f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * Unless required by applicable law or agreed to in writing, software 119f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 129f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * See the License for the specific language governing permissions and 149f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * limitations under the License. 159f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn */ 169f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 179f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornpackage android.content; 189f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 199f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.content.Context; 209f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.os.Message; 219f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.os.RemoteException; 229f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.os.Handler; 239f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.os.IBinder; 249f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport android.os.ServiceManager; 259f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 269f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornimport java.util.ArrayList; 279f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 289f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn/** 299f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * Interface to the clipboard service, for placing and retrieving text in 309f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * the global clipboard. 319f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 329f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * <p> 339f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * You do not instantiate this class directly; instead, retrieve it through 349f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * {@link android.content.Context#getSystemService}. 359f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 3623fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * <p> 3723fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * The ClipboardManager API itself is very simple: it consists of methods 3823fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * to atomically get and set the current primary clipboard data. That data 391040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * is expressed as a {@link ClipData} object, which defines the protocol 4023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * for data exchange between applications. 4123fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * 423aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <div class="special reference"> 433aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <h3>Developer Guides</h3> 443aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <p>For more information about using the clipboard framework, read the 453aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <a href="{@docRoot}guide/topics/clipboard/copy-paste.html">Copy and Paste</a> 463aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * developer guide.</p> 473aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * </div> 483aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * 499f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * @see android.content.Context#getSystemService 509f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn */ 519f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackbornpublic class ClipboardManager extends android.text.ClipboardManager { 529f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn private final static Object sStaticLock = new Object(); 539f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn private static IClipboard sService; 549f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 559f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn private final Context mContext; 569f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 579f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn private final ArrayList<OnPrimaryClipChangedListener> mPrimaryClipChangedListeners 589f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn = new ArrayList<OnPrimaryClipChangedListener>(); 599f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 609f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn private final IOnPrimaryClipChangedListener.Stub mPrimaryClipChangedServiceListener 619f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn = new IOnPrimaryClipChangedListener.Stub() { 629f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public void dispatchPrimaryClipChanged() { 639f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mHandler.sendEmptyMessage(MSG_REPORT_PRIMARY_CLIP_CHANGED); 649f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 659f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn }; 669f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 679f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn static final int MSG_REPORT_PRIMARY_CLIP_CHANGED = 1; 689f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 699f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn private final Handler mHandler = new Handler() { 709f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn @Override 719f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public void handleMessage(Message msg) { 729f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn switch (msg.what) { 739f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn case MSG_REPORT_PRIMARY_CLIP_CHANGED: 749f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn reportPrimaryClipChanged(); 759f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 769f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 779f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn }; 789f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 79413e9b3a5c1392ed8b80b66f00d9de5de0858b85Joe Malin /** 80413e9b3a5c1392ed8b80b66f00d9de5de0858b85Joe Malin * Defines a listener callback that is invoked when the primary clip on the clipboard changes. 81413e9b3a5c1392ed8b80b66f00d9de5de0858b85Joe Malin * Objects that want to register a listener call 82413e9b3a5c1392ed8b80b66f00d9de5de0858b85Joe Malin * {@link android.content.ClipboardManager#addPrimaryClipChangedListener(OnPrimaryClipChangedListener) 83413e9b3a5c1392ed8b80b66f00d9de5de0858b85Joe Malin * addPrimaryClipChangedListener()} with an 84413e9b3a5c1392ed8b80b66f00d9de5de0858b85Joe Malin * object that implements OnPrimaryClipChangedListener. 85413e9b3a5c1392ed8b80b66f00d9de5de0858b85Joe Malin * 86413e9b3a5c1392ed8b80b66f00d9de5de0858b85Joe Malin */ 879f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public interface OnPrimaryClipChangedListener { 88413e9b3a5c1392ed8b80b66f00d9de5de0858b85Joe Malin 89413e9b3a5c1392ed8b80b66f00d9de5de0858b85Joe Malin /** 90413e9b3a5c1392ed8b80b66f00d9de5de0858b85Joe Malin * Callback that is invoked by {@link android.content.ClipboardManager} when the primary 91413e9b3a5c1392ed8b80b66f00d9de5de0858b85Joe Malin * clip changes. 92413e9b3a5c1392ed8b80b66f00d9de5de0858b85Joe Malin */ 939f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn void onPrimaryClipChanged(); 949f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 959f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 969f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn static private IClipboard getService() { 979f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn synchronized (sStaticLock) { 989f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (sService != null) { 999f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return sService; 1009f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1019f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn IBinder b = ServiceManager.getService("clipboard"); 1029f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn sService = IClipboard.Stub.asInterface(b); 1039f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return sService; 1049f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1059f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1069f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 1079f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn /** {@hide} */ 1089f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public ClipboardManager(Context context, Handler handler) { 1099f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mContext = context; 1109f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1119f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 1129f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn /** 1139f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * Sets the current primary clip on the clipboard. This is the clip that 1149f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * is involved in normal cut and paste operations. 1159f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * 1169f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * @param clip The clipped data item to set. 1179f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn */ 1181040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn public void setPrimaryClip(ClipData clip) { 1199f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn try { 120a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey if (clip != null) { 121a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey clip.prepareToLeaveProcess(); 122a14acd20b8d563319ea1a5974dca0e9a29f0aaefJeff Sharkey } 12395d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn getService().setPrimaryClip(clip, mContext.getOpPackageName()); 1249f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } catch (RemoteException e) { 1259f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1269f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1279f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 1289f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn /** 1299f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * Returns the current primary clip on the clipboard. 1309f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn */ 1311040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn public ClipData getPrimaryClip() { 1329f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn try { 13395d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn return getService().getPrimaryClip(mContext.getOpPackageName()); 1349f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } catch (RemoteException e) { 1359f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return null; 1369f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1379f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1389f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 1399f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn /** 1401040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * Returns a description of the current primary clip on the clipboard 1411040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * but not a copy of its data. 1421040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn */ 1431040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn public ClipDescription getPrimaryClipDescription() { 1441040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn try { 14595d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn return getService().getPrimaryClipDescription(mContext.getOpPackageName()); 1461040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } catch (RemoteException e) { 1471040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn return null; 1481040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 1491040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn } 1501040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn 1511040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn /** 1529f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * Returns true if there is currently a primary clip on the clipboard. 1539f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn */ 1549f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public boolean hasPrimaryClip() { 1559f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn try { 15695d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn return getService().hasPrimaryClip(mContext.getOpPackageName()); 1579f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } catch (RemoteException e) { 1589f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return false; 1599f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1609f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1619f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 1629f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public void addPrimaryClipChangedListener(OnPrimaryClipChangedListener what) { 1639f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn synchronized (mPrimaryClipChangedListeners) { 1649f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (mPrimaryClipChangedListeners.size() == 0) { 1659f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn try { 1669f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn getService().addPrimaryClipChangedListener( 16795d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn mPrimaryClipChangedServiceListener, mContext.getOpPackageName()); 1689f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } catch (RemoteException e) { 1699f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1709f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1719f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mPrimaryClipChangedListeners.add(what); 1729f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1739f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1749f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 1759f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public void removePrimaryClipChangedListener(OnPrimaryClipChangedListener what) { 1769f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn synchronized (mPrimaryClipChangedListeners) { 1779f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mPrimaryClipChangedListeners.remove(what); 1789f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (mPrimaryClipChangedListeners.size() == 0) { 1799f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn try { 1809f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn getService().removePrimaryClipChangedListener( 1819f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn mPrimaryClipChangedServiceListener); 1829f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } catch (RemoteException e) { 1839f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1849f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1859f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1869f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1879f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 1889f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn /** 1899f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * @deprecated Use {@link #getPrimaryClip()} instead. This retrieves 1909f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * the primary clip and tries to coerce it to a string. 1919f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn */ 1929f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public CharSequence getText() { 1931040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn ClipData clip = getPrimaryClip(); 1949f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (clip != null && clip.getItemCount() > 0) { 195327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn return clip.getItemAt(0).coerceToText(mContext); 1969f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1979f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return null; 1989f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 1999f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 2009f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn /** 2011040dc465cbf5ca8f834a87c949e476abefa3f76Dianne Hackborn * @deprecated Use {@link #setPrimaryClip(ClipData)} instead. This 2029f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * creates a ClippedItem holding the given text and sets it as the 2039f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn * primary clip. It has no label or icon. 2049f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn */ 2059f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public void setText(CharSequence text) { 206327fbd2c8fa294b919475feb4c74a74ee1981e02Dianne Hackborn setPrimaryClip(ClipData.newPlainText(null, text)); 2079f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2089f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 2099f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn /** 21023fdaf6fb62a9b5154b2508916a21c678462c5d0Dianne Hackborn * @deprecated Use {@link #hasPrimaryClip()} instead. 2119f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn */ 2129f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn public boolean hasText() { 2139f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn try { 21495d785346b4dae808a2d8f77356175e55a572d96Dianne Hackborn return getService().hasClipboardText(mContext.getOpPackageName()); 2159f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } catch (RemoteException e) { 2169f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return false; 2179f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2189f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2199f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 2209f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn void reportPrimaryClipChanged() { 2219f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn Object[] listeners; 2229f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 2239f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn synchronized (mPrimaryClipChangedListeners) { 2249f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn final int N = mPrimaryClipChangedListeners.size(); 2259f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn if (N <= 0) { 2269f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn return; 2279f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2289f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn listeners = mPrimaryClipChangedListeners.toArray(); 2299f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2309f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn 2319f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn for (int i=0; i<listeners.length; i++) { 2329f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn ((OnPrimaryClipChangedListener)listeners[i]).onPrimaryClipChanged(); 2339f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2349f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn } 2359f53119b72e6da865bcd53173d3dacd1eba01aeeDianne Hackborn} 236