1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/sharing/sharing_service_proxy_android.h"
6 
7 #include "base/android/callback_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/time/time.h"
10 #include "chrome/android/chrome_jni_headers/SharingServiceProxy_jni.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/profiles/profile_android.h"
13 #include "chrome/browser/sharing/features.h"
14 #include "chrome/browser/sharing/sharing_device_source.h"
15 #include "chrome/browser/sharing/sharing_metrics.h"
16 #include "chrome/browser/sharing/sharing_send_message_result.h"
17 #include "chrome/browser/sharing/sharing_service.h"
18 #include "chrome/browser/sharing/sharing_service_factory.h"
19 #include "components/sync_device_info/device_info.h"
20 
JNI_SharingServiceProxy_InitSharingService(JNIEnv * env,const base::android::JavaParamRef<jobject> & j_profile)21 void JNI_SharingServiceProxy_InitSharingService(
22     JNIEnv* env,
23     const base::android::JavaParamRef<jobject>& j_profile) {
24   SharingService* service = SharingServiceFactory::GetForBrowserContext(
25       ProfileAndroid::FromProfileAndroid(j_profile));
26   DCHECK(service);
27 }
28 
SharingServiceProxyAndroid(SharingService * sharing_service)29 SharingServiceProxyAndroid::SharingServiceProxyAndroid(
30     SharingService* sharing_service)
31     : sharing_service_(sharing_service) {
32   DCHECK(sharing_service_);
33   JNIEnv* env = base::android::AttachCurrentThread();
34   Java_SharingServiceProxy_onProxyCreated(env,
35                                           reinterpret_cast<intptr_t>(this));
36 }
37 
~SharingServiceProxyAndroid()38 SharingServiceProxyAndroid::~SharingServiceProxyAndroid() {
39   JNIEnv* env = base::android::AttachCurrentThread();
40   Java_SharingServiceProxy_onProxyDestroyed(env);
41 }
42 
SendSharedClipboardMessage(JNIEnv * env,const base::android::JavaParamRef<jstring> & j_guid,const base::android::JavaParamRef<jstring> & j_text,const jint j_retries,const base::android::JavaParamRef<jobject> & j_runnable)43 void SharingServiceProxyAndroid::SendSharedClipboardMessage(
44     JNIEnv* env,
45     const base::android::JavaParamRef<jstring>& j_guid,
46     const base::android::JavaParamRef<jstring>& j_text,
47     const jint j_retries,
48     const base::android::JavaParamRef<jobject>& j_runnable) {
49   auto callback =
50       base::BindOnce(base::android::RunIntCallbackAndroid,
51                      base::android::ScopedJavaGlobalRef<jobject>(j_runnable));
52 
53   std::string guid = base::android::ConvertJavaStringToUTF8(env, j_guid);
54   DCHECK(!guid.empty());
55 
56   std::unique_ptr<syncer::DeviceInfo> device =
57       sharing_service_->GetDeviceByGuid(guid);
58   LogSharingDeviceInfoAvailable(device != nullptr);
59 
60   if (!device) {
61     std::move(callback).Run(
62         static_cast<int>(SharingSendMessageResult::kDeviceNotFound));
63     return;
64   }
65 
66   std::string text = base::android::ConvertJavaStringToUTF8(env, j_text);
67   chrome_browser_sharing::SharingMessage sharing_message;
68   sharing_message.mutable_shared_clipboard_message()->set_text(std::move(text));
69 
70   sharing_service_->SendMessageToDevice(
71       *device, base::TimeDelta::FromSeconds(kSharingMessageTTLSeconds.Get()),
72       std::move(sharing_message),
73       base::BindOnce(
74           [](int retries, base::OnceCallback<void(int)> callback,
75              SharingSendMessageResult result,
76              std::unique_ptr<chrome_browser_sharing::ResponseMessage>
77                  response) {
78             LogSharedClipboardRetries(retries, result);
79             std::move(callback).Run(static_cast<int>(result));
80           },
81           j_retries, std::move(callback)));
82 }
83 
GetDeviceCandidates(JNIEnv * env,const base::android::JavaParamRef<jobject> & j_device_info,jint j_required_feature)84 void SharingServiceProxyAndroid::GetDeviceCandidates(
85     JNIEnv* env,
86     const base::android::JavaParamRef<jobject>& j_device_info,
87     jint j_required_feature) {
88   auto device_candidates = sharing_service_->GetDeviceCandidates(
89       static_cast<sync_pb::SharingSpecificFields::EnabledFeatures>(
90           j_required_feature));
91   for (const auto& device_info : device_candidates) {
92     Java_SharingServiceProxy_createDeviceInfoAndAppendToList(
93         env, j_device_info,
94         base::android::ConvertUTF8ToJavaString(env, device_info->guid()),
95         base::android::ConvertUTF8ToJavaString(env, device_info->client_name()),
96         device_info->device_type(),
97         device_info->last_updated_timestamp().ToJavaTime());
98   }
99 }
100 
AddDeviceCandidatesInitializedObserver(JNIEnv * env,const base::android::JavaParamRef<jobject> & j_runnable)101 void SharingServiceProxyAndroid::AddDeviceCandidatesInitializedObserver(
102     JNIEnv* env,
103     const base::android::JavaParamRef<jobject>& j_runnable) {
104   sharing_service_->GetDeviceSource()->AddReadyCallback(
105       base::BindOnce(base::android::RunRunnableAndroid,
106                      base::android::ScopedJavaGlobalRef<jobject>(j_runnable)));
107 }
108