diff options
author | andrewhayden@chromium.org <andrewhayden@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-15 20:05:34 +0000 |
---|---|---|
committer | andrewhayden@chromium.org <andrewhayden@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-15 20:05:34 +0000 |
commit | 329028c18c6c5da54cd89dbddc5cfc3911d6bccf (patch) | |
tree | 6ffd3c921d50e53d6ece274ff71591155035a431 /ui/android | |
parent | 1333be7637f72983dd46cb5cc8305a96cc347dc6 (diff) | |
download | chromium_src-329028c18c6c5da54cd89dbddc5cfc3911d6bccf.zip chromium_src-329028c18c6c5da54cd89dbddc5cfc3911d6bccf.tar.gz chromium_src-329028c18c6c5da54cd89dbddc5cfc3911d6bccf.tar.bz2 |
Chromium: Clipboard android code uses unsafe jni and is buggy
This change removes most of the explicit JNI manipulation from the
clipboard_android.cc implementation and replaces it with modernized
generated JNI stubs derived from a Java implementation class.
This change also migrates away from the deprecated
android.text.ClipboardManager to android.content.ClipboardManager,
which is the modern equivalent.
Note that the old implementation of clipboard_android.cc relied
almost exclusively upon deprecated functionality in the clipboard,
namely (1) assuming there is only one clip, (2) always treating
that clip as plain text and (3, indavertently) coercing non-text
content to text (such as URI objects in the clipboard). In this
change, we have NOT changed these behaviors - we have merely
moved away from the deprecated APIs. It will be left to another
change to perform a more invasive rewiring of the clipboard
implementation here that more closely aligns with the modern
capabilities of the Android clipboard (e.g., supporting bitmaps,
HTML text, and so on).
BUG=180476
TBR=ben
Review URL: https://chromiumcodereview.appspot.com/12633009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@188458 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/android')
-rw-r--r-- | ui/android/java/src/org/chromium/ui/Clipboard.java | 111 | ||||
-rw-r--r-- | ui/android/ui_jni_registrar.cc | 2 |
2 files changed, 113 insertions, 0 deletions
diff --git a/ui/android/java/src/org/chromium/ui/Clipboard.java b/ui/android/java/src/org/chromium/ui/Clipboard.java new file mode 100644 index 0000000..a66fa3d --- /dev/null +++ b/ui/android/java/src/org/chromium/ui/Clipboard.java @@ -0,0 +1,111 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.ui; + +import org.chromium.base.CalledByNative; +import org.chromium.base.JNINamespace; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.text.TextUtils; + +/** + * Simple proxy that provides C++ code with an access pathway to the Android + * clipboard. + */ +@JNINamespace("ui") +public class Clipboard { + // Necessary for coercing clipboard contents to text if they require + // access to network resources, etceteras (e.g., URI in clipboard) + private final Context mContext; + + private final ClipboardManager mClipboardManager; + + /** + * Use the factory constructor instead. + * + * @param context for accessing the clipboard + */ + private Clipboard(final Context context) { + mContext = context; + mClipboardManager = (ClipboardManager) + context.getSystemService(Context.CLIPBOARD_SERVICE); + } + + /** + * Returns a new Clipboard object bound to the specified context. + * + * @param context for accessing the clipboard + * @return the new object + */ + @CalledByNative + private static Clipboard create(final Context context) { + return new Clipboard(context); + } + + /** + * Emulates the behavior of the now-deprecated + * {@link android.text.ClipboardManager#getText()} by invoking + * {@link android.content.ClipData.Item#coerceToText(Context)} on the first + * item in the clipboard (if any) and returning the result as a string. + * <p> + * This is quite different than simply calling {@link Object#toString()} on + * the clip; consumers of this API should familiarize themselves with the + * process described in + * {@link android.content.ClipData.Item#coerceToText(Context)} before using + * this method. + * + * @return a string representation of the first item on the clipboard, if + * the clipboard currently has an item and coercion of the item into + * a string is possible; otherwise, <code>null</code> + */ + @SuppressWarnings("javadoc") + @CalledByNative + private String getCoercedText() { + final ClipData clip = mClipboardManager.getPrimaryClip(); + if (clip != null && clip.getItemCount() > 0) { + final CharSequence sequence = clip.getItemAt(0).coerceToText(mContext); + if (sequence != null) { + return sequence.toString(); + } + } + return null; + } + + /** + * Emulates the behavior of the now-deprecated + * {@link android.text.ClipboardManager#setText(CharSequence)}, setting the + * clipboard's current primary clip to a plain-text clip that consists of + * the specified string. + * + * @param text will become the content of the clipboard's primary clip + */ + @SuppressWarnings("javadoc") + @CalledByNative + private void setText(final String text) { + mClipboardManager.setPrimaryClip(ClipData.newPlainText(null, text)); + } + + /** + * Approximates the behavior of the now-deprecated + * {@link android.text.ClipboardManager#hasText()}, returning true if and + * only if the clipboard has a primary clip and that clip contains a plain + * non-empty text entry (without attempting coercion - URLs and intents + * will cause this method to return false). + * + * @return as described above + */ + @SuppressWarnings("javadoc") + @CalledByNative + private boolean hasPlainText() { + final ClipData clip = mClipboardManager.getPrimaryClip(); + if (clip != null && clip.getItemCount() > 0) { + final CharSequence text = clip.getItemAt(0).getText(); + return !TextUtils.isEmpty(text); + } + return false; + } +} diff --git a/ui/android/ui_jni_registrar.cc b/ui/android/ui_jni_registrar.cc index 37a3fb8..048d874 100644 --- a/ui/android/ui_jni_registrar.cc +++ b/ui/android/ui_jni_registrar.cc @@ -6,6 +6,7 @@ #include "base/android/jni_android.h" #include "base/android/jni_registrar.h" +#include "ui/base/clipboard/clipboard_android_initialization.h" #include "ui/gfx/android/device_display_info.h" #include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/android/window_android.h" @@ -17,6 +18,7 @@ static base::android::RegistrationMethod kUiRegisteredMethods[] = { { "DeviceDisplayInfo", gfx::DeviceDisplayInfo::RegisterDeviceDisplayInfo }, { "JavaBitmap", gfx::JavaBitmap::RegisterJavaBitmap }, { "NativeWindow", ui::WindowAndroid::RegisterWindowAndroid }, + { "Clipboard", ui::RegisterClipboardAndroid }, }; bool RegisterJni(JNIEnv* env) { |