From b3cf0e32fa38ce3f33df6648f3b85e4f8dd986ec Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Mon, 17 Oct 2016 15:46:47 -0700 Subject: [PATCH] Add clipboard functionality to platform plugin (flutter/engine#3139) This will eventually replace the clipboard mojom. --- .../plugin/platform/PlatformPlugin.java | 31 +++++++++++++++++++ .../framework/Source/FlutterPlatformPlugin.mm | 24 +++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java b/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java index 66261504726..3417c36486c 100644 --- a/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java +++ b/engine/src/flutter/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java @@ -5,6 +5,10 @@ package io.flutter.plugin.platform; import android.app.Activity; +import android.content.ClipboardManager; +import android.content.ClipData; +import android.content.ClipDescription; +import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.net.Uri; @@ -27,6 +31,7 @@ public class PlatformPlugin extends JSONMessageListener implements ActivityLifec private final Activity mActivity; public static final int DEFAULT_SYSTEM_UI = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + private static final String kTextPlainFormat = "text/plain"; public PlatformPlugin(Activity activity) { mActivity = activity; @@ -53,6 +58,10 @@ public class PlatformPlugin extends JSONMessageListener implements ActivityLifec setSystemChromeSystemUIOverlayStyle(args.getString(0)); } else if (method.equals("SystemNavigator.pop")) { popSystemNavigator(); + } else if (method.equals("Clipboard.getData")) { + return getClipboardData(args.getString(0)); + } else if (method.equals("Clipboard.setData")) { + setClipboardData(args.getJSONObject(0)); } else if (method.equals("PathProvider.getTemporaryDirectory")) { return getPathProviderTemporaryDirectory(); } else if (method.equals("PathProvider.getApplicationDocumentsDirectory")) { @@ -166,6 +175,28 @@ public class PlatformPlugin extends JSONMessageListener implements ActivityLifec mActivity.finish(); } + private JSONObject getClipboardData(String format) throws JSONException { + ClipboardManager clipboard = (ClipboardManager) mActivity.getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = clipboard.getPrimaryClip(); + if (clip == null) + return null; + + if ((format == null || format.equals(kTextPlainFormat)) && + clip.getDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) { + JSONObject result = new JSONObject(); + result.put("text", clip.getItemAt(0).getText().toString()); + return result; + } + + return null; + } + + private void setClipboardData(JSONObject data) throws JSONException { + ClipboardManager clipboard = (ClipboardManager) mActivity.getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("text label?", data.getString("text")); + clipboard.setPrimaryClip(clip); + } + private JSONObject getPathProviderTemporaryDirectory() throws JSONException { JSONObject result = new JSONObject(); result.put("path", mActivity.getCacheDir().getPath()); diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm index 02676de8942..9e968c7ac11 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformPlugin.mm @@ -9,7 +9,11 @@ #include #include -static NSDictionary* GetDirectoryOfType(NSSearchPathDirectory dir) { +namespace { + +constexpr char kTextPlainFormat[] = "text/plain"; + +NSDictionary* GetDirectoryOfType(NSSearchPathDirectory dir) { NSArray* paths = NSSearchPathForDirectoriesInDomains(dir, NSUserDomainMask, YES); if (paths.count == 0) @@ -17,6 +21,8 @@ static NSDictionary* GetDirectoryOfType(NSSearchPathDirectory dir) { return @{ @"path": paths.firstObject }; } +} // namespaces + namespace shell { // TODO(abarth): Move these definitions from system_chrome_impl.cc to here. @@ -58,6 +64,10 @@ using namespace shell; [self setSystemChromeSystemUIOverlayStyle:args.firstObject]; } else if ([method isEqualToString:@"SystemNavigator.pop"]) { [self popSystemNavigator]; + } else if ([method isEqualToString:@"Clipboard.getData"]) { + return [self getClipboardData:args.firstObject]; + } else if ([method isEqualToString:@"Clipboard.setData"]) { + [self setClipboardData:args.firstObject]; } else if ([method isEqualToString:@"PathProvider.getTemporaryDirectory"]) { return [self getPathProviderTemporaryDirectory]; } else if ([method isEqualToString:@"PathProvider.getApplicationDocumentsDirectory"]) { @@ -166,6 +176,18 @@ using namespace shell; // Apple's human user guidelines say not to terminate iOS applications. } +- (NSDictionary*)getClipboardData:(NSString*)format { + UIPasteboard* pasteboard = [UIPasteboard generalPasteboard]; + if (!format || [format isEqualToString:@(kTextPlainFormat)]) + return @{ @"text": pasteboard.string }; + return nil; +} + +- (void)setClipboardData:(NSDictionary *)data { + UIPasteboard* pasteboard = [UIPasteboard generalPasteboard]; + pasteboard.string = data[@"text"]; +} + - (NSDictionary*)getPathProviderTemporaryDirectory { return GetDirectoryOfType(NSCachesDirectory); }