Skip to content

Commit

Permalink
fix(android): refactor clipboard to remove deprecated apis (#13105)
Browse files Browse the repository at this point in the history
* fix(android): refactor clipboard to remove deprecated apis

* test(android): amend clipboard tests

Co-authored-by: Ewan Harris <ewanharris93@gmail.com>
Co-authored-by: Joshua Quick <jquick@axway.com>
  • Loading branch information
3 people committed Oct 20, 2021
1 parent 87553fa commit 09e3e0d
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 55 deletions.
Original file line number Diff line number Diff line change
@@ -1,115 +1,126 @@
/**
* Appcelerator Titanium Mobile
* Copyright (c) 2009-2016 by Appcelerator, Inc. All Rights Reserved.
* Copyright (c) 2009-2021 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
package ti.modules.titanium.ui.clipboard;

import org.appcelerator.kroll.KrollModule;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.titanium.TiApplication;

import ti.modules.titanium.ui.UIModule;

import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Context;
import android.text.ClipboardManager;
import android.content.ClipboardManager;
import android.os.Build;

@SuppressWarnings("deprecation")
@Kroll.module(parentModule = UIModule.class)
public class ClipboardModule extends KrollModule
{
private static final String TAG = "Clipboard";

private static ClipboardManager clipboardManager;

public ClipboardModule()
{
super();

if (clipboardManager == null) {
clipboardManager =
(ClipboardManager) TiApplication.getInstance().getSystemService(Context.CLIPBOARD_SERVICE);
}
}

/**
* Get the native clipboard instance.
*/
private ClipboardManager board()
private static boolean isTypeText(String type)
{
return (ClipboardManager) TiApplication.getInstance().getSystemService(Context.CLIPBOARD_SERVICE);
return type != null && type.toLowerCase().startsWith("text");
}

/**
* Android's clipboard currently only handles text; when working with
* arbitrary data check if it looks like text that we're being handed.
*/
private boolean isTextType(String type)
@Kroll.method
public void clearText()
{
String mimeType = type.toLowerCase();
return mimeType.equals("text/plain") || mimeType.startsWith("text");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
clipboardManager.clearPrimaryClip();
} else {
clipboardManager.setPrimaryClip(ClipData.newPlainText("label", null));
}
}

@Kroll.method
public void clearData(@Kroll.argument(optional = true) String type)
public boolean hasText()
{
clearText();
String text = getText();
return text != null;
}

@Kroll.method
public void clearText()
@Kroll.getProperty
public String getText()
{
board().setText(""); // can we use null?
ClipData clip = clipboardManager.getPrimaryClip();

if (clip != null && clip.getItemCount() > 0) {
ClipData.Item item = clip.getItemAt(0);

if (item.getText() != null) {
return item.getText().toString();
}
}
return null;
}

@Kroll.method
public Object getData(String type)
@Kroll.setProperty
public void setText(String text)
{
if (isTextType(type)) {
return getText();
} else {
// Android clipboard is text-only... :(
return null;
}
final ClipData clip = ClipData.newPlainText("label", text);

clipboardManager.setPrimaryClip(clip);
}

@Kroll.method
@Kroll.getProperty
public String getText()
public void clearData(@Kroll.argument(optional = true) String type)
{
CharSequence text = board().getText();
if (text != null) {
return text.toString();
}
return null;
clearText();
}

@Kroll.method
public boolean hasData(@Kroll.argument(optional = true) String type)
{
if (type == null || isTextType(type)) {
return hasText();
if (type == null) {
type = "text";
}
ClipData clip = clipboardManager.getPrimaryClip();

if (clip != null) {
ClipDescription description = clip.getDescription();

if (description.getMimeTypeCount() > 0
&& description.getMimeType(0).startsWith(type)) {
return isTypeText(type) ? hasText() : true;
}
}
return false;
}

@Kroll.method
public boolean hasText()
public Object getData(@Kroll.argument(optional = true) String type)
{
return board().hasText();
return isTypeText(type) ? getText() : null;
}

@Kroll.method
public void setData(String type, Object data)
{
if (isTextType(type) && data != null) {
board().setText(data.toString());
} else {
Log.w(TAG, "Android clipboard only supports text data");
if (data != null && isTypeText(type)) {
setText(data.toString());
}
}

@Kroll.method
@Kroll.setProperty
public void setText(String text)
{
board().setText(text);
}

@Override
public String getApiName()
{
Expand Down
7 changes: 1 addition & 6 deletions tests/Resources/ti.ui.clipboard.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -446,12 +446,7 @@ describe('Titanium.UI.Clipboard', () => {
describe('examples', () => {
it('Copy Text to the Clipboard', () => {
Ti.UI.Clipboard.clearText();
// returns empty string on Android and undefined on iOS
if (OS_ANDROID) {
should(Ti.UI.Clipboard.getText()).eql('');
} else {
should.not.exist(Ti.UI.Clipboard.getText());
}
should.not.exist(Ti.UI.Clipboard.getText());
Ti.UI.Clipboard.setText('hello');
should(Ti.UI.Clipboard.hasText()).be.true();
should(Ti.UI.Clipboard.getText()).eql('hello');
Expand Down

0 comments on commit 09e3e0d

Please sign in to comment.