12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)package org.chromium.ui;
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.base.CalledByNative;
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.base.JNINamespace;
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.ClipData;
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.ClipboardManager;
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.Context;
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.text.TextUtils;
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Simple proxy that provides C++ code with an access pathway to the Android
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * clipboard.
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)@JNINamespace("ui")
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public class Clipboard {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Necessary for coercing clipboard contents to text if they require
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // access to network resources, etceteras (e.g., URI in clipboard)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private final Context mContext;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private final ClipboardManager mClipboardManager;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Use the factory constructor instead.
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     *
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * @param context for accessing the clipboard
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private Clipboard(final Context context) {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mContext = context;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mClipboardManager = (ClipboardManager)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                context.getSystemService(Context.CLIPBOARD_SERVICE);
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Returns a new Clipboard object bound to the specified context.
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     *
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * @param context for accessing the clipboard
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * @return the new object
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @CalledByNative
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private static Clipboard create(final Context context) {
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return new Clipboard(context);
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Emulates the behavior of the now-deprecated
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * {@link android.text.ClipboardManager#getText()} by invoking
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * {@link android.content.ClipData.Item#coerceToText(Context)} on the first
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * item in the clipboard (if any) and returning the result as a string.
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * <p>
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * This is quite different than simply calling {@link Object#toString()} on
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * the clip; consumers of this API should familiarize themselves with the
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * process described in
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * {@link android.content.ClipData.Item#coerceToText(Context)} before using
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * this method.
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     *
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * @return a string representation of the first item on the clipboard, if
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     *         the clipboard currently has an item and coercion of the item into
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     *         a string is possible; otherwise, <code>null</code>
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @SuppressWarnings("javadoc")
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @CalledByNative
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private String getCoercedText() {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        final ClipData clip = mClipboardManager.getPrimaryClip();
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (clip != null && clip.getItemCount() > 0) {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            final CharSequence sequence = clip.getItemAt(0).coerceToText(mContext);
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            if (sequence != null) {
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                return sequence.toString();
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return null;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Emulates the behavior of the now-deprecated
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * {@link android.text.ClipboardManager#setText(CharSequence)}, setting the
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * clipboard's current primary clip to a plain-text clip that consists of
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * the specified string.
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     *
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * @param text will become the content of the clipboard's primary clip
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @SuppressWarnings("javadoc")
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @CalledByNative
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private void setText(final String text) {
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mClipboardManager.setPrimaryClip(ClipData.newPlainText(null, text));
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Approximates the behavior of the now-deprecated
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * {@link android.text.ClipboardManager#hasText()}, returning true if and
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * only if the clipboard has a primary clip and that clip contains a plain
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * non-empty text entry (without attempting coercion - URLs and intents
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * will cause this method to return false).
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     *
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * @return as described above
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @SuppressWarnings("javadoc")
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    @CalledByNative
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private boolean hasPlainText() {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        final ClipData clip = mClipboardManager.getPrimaryClip();
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (clip != null && clip.getItemCount() > 0) {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            final CharSequence text = clip.getItemAt(0).getText();
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return !TextUtils.isEmpty(text);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return false;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
112