Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/android/physical_web/physical_web_data_source_android.h " | 5 #include "chrome/browser/android/physical_web/physical_web_data_source_android.h " |
| 6 | 6 |
| 7 #include <jni.h> | 7 #include <jni.h> |
| 8 | 8 |
| 9 #include "base/android/jni_string.h" | |
| 9 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 10 #include "base/values.h" | 11 #include "base/values.h" |
| 11 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
| 12 #include "jni/UrlManager_jni.h" | 13 #include "jni/UrlManager_jni.h" |
| 13 | 14 |
| 14 using base::android::AttachCurrentThread; | 15 using base::android::AttachCurrentThread; |
| 16 using base::android::ConvertJavaStringToUTF8; | |
| 15 using base::android::JavaParamRef; | 17 using base::android::JavaParamRef; |
| 16 using base::android::ScopedJavaLocalRef; | 18 using base::android::ScopedJavaLocalRef; |
| 17 | 19 |
| 20 namespace { | |
| 21 | |
| 22 // Fully-qualified class names. | |
|
gone
2016/10/13 22:48:30
I think that doing anything this deep in JNI (hard
mattreynolds
2016/10/18 00:59:30
I decided to go a different route, now the native
| |
| 23 const char kPwCollectionClassPath[] = | |
| 24 "org/chromium/chrome/browser/physicalweb/PwCollection"; | |
| 25 const char kPwsResultClassPath[] = | |
| 26 "org/chromium/chrome/browser/physicalweb/PwsResult"; | |
| 27 const char kUrlInfoClassPath[] = | |
| 28 "org/chromium/chrome/browser/physicalweb/UrlInfo"; | |
| 29 | |
| 30 // Field descriptors. | |
| 31 const char kPwsResultsFieldDescriptor[] = | |
| 32 "[Lorg/chromium/chrome/browser/physicalweb/PwsResult;"; | |
| 33 const char kUrlInfosFieldDescriptor[] = | |
| 34 "[Lorg/chromium/chrome/browser/physicalweb/UrlInfo;"; | |
| 35 const char kStringFieldDescriptor[] = "Ljava/lang/String;"; | |
| 36 const char kDoubleFieldDescriptor[] = "D"; | |
| 37 const char kLongFieldDescriptor[] = "J"; | |
| 38 } // namespace | |
| 39 | |
| 18 PhysicalWebDataSourceAndroid::PhysicalWebDataSourceAndroid() { | 40 PhysicalWebDataSourceAndroid::PhysicalWebDataSourceAndroid() { |
| 19 Initialize(); | 41 Initialize(); |
| 20 } | 42 } |
| 21 | 43 |
| 22 PhysicalWebDataSourceAndroid::~PhysicalWebDataSourceAndroid() {} | 44 PhysicalWebDataSourceAndroid::~PhysicalWebDataSourceAndroid() {} |
| 23 | 45 |
| 24 void PhysicalWebDataSourceAndroid::Initialize() { | 46 void PhysicalWebDataSourceAndroid::Initialize() { |
| 25 JNIEnv* env = AttachCurrentThread(); | 47 JNIEnv* env = AttachCurrentThread(); |
| 26 | 48 |
| 27 // Cache a reference to the singleton instance of UrlManager. | 49 // Cache a reference to the singleton instance of UrlManager. |
| 28 url_manager_.Reset(Java_UrlManager_getInstance(env)); | 50 url_manager_.Reset(Java_UrlManager_getInstance(env)); |
| 29 DCHECK(url_manager_.obj()); | 51 DCHECK(url_manager_.obj()); |
| 52 | |
| 53 // Cache field IDs for PwCollection fields. | |
| 54 auto pw_collection_cls = | |
| 55 ScopedJavaLocalRef<jclass>(env, env->FindClass(kPwCollectionClassPath)); | |
| 56 DCHECK(pw_collection_cls.obj()); | |
| 57 url_infos_fid_ = env->GetFieldID(pw_collection_cls.obj(), "urlInfos", | |
| 58 kUrlInfosFieldDescriptor); | |
| 59 DCHECK(url_infos_fid_); | |
| 60 pws_results_fid_ = env->GetFieldID(pw_collection_cls.obj(), "pwsResults", | |
| 61 kPwsResultsFieldDescriptor); | |
| 62 DCHECK(pws_results_fid_); | |
| 63 | |
| 64 // Cache field IDs for UrlInfo fields. | |
| 65 auto url_info_cls = | |
| 66 ScopedJavaLocalRef<jclass>(env, env->FindClass(kUrlInfoClassPath)); | |
| 67 DCHECK(url_info_cls.obj()); | |
| 68 url_fid_ = | |
| 69 env->GetFieldID(url_info_cls.obj(), "mUrl", kStringFieldDescriptor); | |
| 70 DCHECK(url_fid_); | |
| 71 distance_fid_ = | |
| 72 env->GetFieldID(url_info_cls.obj(), "mDistance", kDoubleFieldDescriptor); | |
| 73 DCHECK(distance_fid_); | |
| 74 scan_timestamp_fid_ = env->GetFieldID(url_info_cls.obj(), "mScanTimestamp", | |
| 75 kLongFieldDescriptor); | |
| 76 DCHECK(scan_timestamp_fid_); | |
| 77 | |
| 78 // Cache field IDs for PwsResult fields. | |
| 79 auto pws_result_cls = | |
| 80 ScopedJavaLocalRef<jclass>(env, env->FindClass(kPwsResultClassPath)); | |
| 81 DCHECK(pws_result_cls.obj()); | |
| 82 site_url_fid_ = | |
| 83 env->GetFieldID(pws_result_cls.obj(), "siteUrl", kStringFieldDescriptor); | |
| 84 DCHECK(site_url_fid_); | |
| 85 icon_url_fid_ = | |
| 86 env->GetFieldID(pws_result_cls.obj(), "iconUrl", kStringFieldDescriptor); | |
| 87 DCHECK(icon_url_fid_); | |
| 88 title_fid_ = | |
| 89 env->GetFieldID(pws_result_cls.obj(), "title", kStringFieldDescriptor); | |
| 90 DCHECK(title_fid_); | |
| 91 description_fid_ = env->GetFieldID(pws_result_cls.obj(), "description", | |
| 92 kStringFieldDescriptor); | |
| 93 DCHECK(description_fid_); | |
| 94 group_id_fid_ = | |
| 95 env->GetFieldID(pws_result_cls.obj(), "groupId", kStringFieldDescriptor); | |
| 96 DCHECK(group_id_fid_); | |
| 30 } | 97 } |
| 31 | 98 |
| 32 void PhysicalWebDataSourceAndroid::StartDiscovery( | 99 void PhysicalWebDataSourceAndroid::StartDiscovery( |
| 33 bool network_request_enabled) { | 100 bool network_request_enabled) { |
| 34 // On Android, scanning is started and stopped through the Java layer. | 101 // On Android, scanning is started and stopped through the Java layer. |
| 35 NOTREACHED(); | 102 NOTREACHED(); |
| 36 } | 103 } |
| 37 | 104 |
| 38 void PhysicalWebDataSourceAndroid::StopDiscovery() { | 105 void PhysicalWebDataSourceAndroid::StopDiscovery() { |
| 39 // On Android, scanning is started and stopped through the Java layer. | 106 // On Android, scanning is started and stopped through the Java layer. |
| 40 NOTREACHED(); | 107 NOTREACHED(); |
| 41 } | 108 } |
| 42 | 109 |
| 43 std::unique_ptr<base::ListValue> PhysicalWebDataSourceAndroid::GetMetadata() { | 110 std::unique_ptr<base::ListValue> PhysicalWebDataSourceAndroid::GetMetadata() { |
| 44 // TODO(mattreynolds): get the metadata from the Java layer | 111 JNIEnv* env = AttachCurrentThread(); |
| 45 return base::MakeUnique<base::ListValue>(); | 112 |
| 113 // PwCollection contains parallel arrays urlInfos and pwsResults. urlInfos | |
| 114 // holds data related to the devices broadcasting the URLs. pwsResults holds | |
| 115 // the site-related data fetched from the Physical Web service. The arrays | |
| 116 // should have the same size; if there is a URL in urlInfos for which we have | |
| 117 // not received metadata, the corresponding element of pwsResults will be | |
| 118 // null. | |
| 119 ScopedJavaLocalRef<jobject> pw_collection = | |
| 120 Java_UrlManager_getPwCollection(env, url_manager_.obj()); | |
| 121 DCHECK(pw_collection.obj()); | |
| 122 | |
| 123 auto url_infos = ScopedJavaLocalRef<jobjectArray>( | |
| 124 env, static_cast<jobjectArray>( | |
| 125 env->GetObjectField(pw_collection.obj(), url_infos_fid_))); | |
| 126 jsize url_infos_count = env->GetArrayLength(url_infos.obj()); | |
| 127 DCHECK_GE(url_infos_count, 0); | |
| 128 url_infos_count = std::max(0, url_infos_count); | |
| 129 | |
| 130 auto pws_results = ScopedJavaLocalRef<jobjectArray>( | |
| 131 env, static_cast<jobjectArray>( | |
| 132 env->GetObjectField(pw_collection.obj(), pws_results_fid_))); | |
| 133 jsize pws_results_count = env->GetArrayLength(pws_results.obj()); | |
| 134 DCHECK_GE(pws_results_count, 0); | |
| 135 pws_results_count = std::max(0, pws_results_count); | |
| 136 | |
| 137 DCHECK_EQ(url_infos_count, pws_results_count); | |
| 138 | |
| 139 auto metadata = base::MakeUnique<base::ListValue>(); | |
| 140 for (jsize i = 0; i < url_infos_count; i++) { | |
| 141 auto url_info = ScopedJavaLocalRef<jobject>( | |
| 142 env, env->GetObjectArrayElement(url_infos.obj(), i)); | |
| 143 auto pws_result = ScopedJavaLocalRef<jobject>( | |
| 144 env, env->GetObjectArrayElement(pws_results.obj(), i)); | |
| 145 | |
| 146 // Only include URLs for which we have metadata. | |
| 147 if (!url_info.obj() || !pws_result.obj()) { | |
| 148 continue; | |
| 149 } | |
| 150 | |
| 151 // Extract UrlInfo fields. | |
| 152 jstring url_java = | |
| 153 static_cast<jstring>(env->GetObjectField(url_info.obj(), url_fid_)); | |
| 154 double distance_estimate = | |
| 155 env->GetDoubleField(url_info.obj(), distance_fid_); | |
| 156 long scan_timestamp = | |
| 157 env->GetLongField(url_info.obj(), scan_timestamp_fid_); | |
| 158 | |
| 159 // Extract PwsResult fields. | |
| 160 jstring site_url_java = static_cast<jstring>( | |
| 161 env->GetObjectField(pws_result.obj(), site_url_fid_)); | |
| 162 jstring icon_url_java = static_cast<jstring>( | |
| 163 env->GetObjectField(pws_result.obj(), icon_url_fid_)); | |
| 164 jstring title_java = | |
| 165 static_cast<jstring>(env->GetObjectField(pws_result.obj(), title_fid_)); | |
| 166 jstring description_java = static_cast<jstring>( | |
| 167 env->GetObjectField(pws_result.obj(), description_fid_)); | |
| 168 jstring group_id_java = static_cast<jstring>( | |
| 169 env->GetObjectField(pws_result.obj(), group_id_fid_)); | |
| 170 | |
| 171 // Convert strings. | |
| 172 std::string url; | |
| 173 std::string site_url; | |
| 174 std::string icon_url; | |
| 175 std::string title; | |
| 176 std::string description; | |
| 177 std::string group_id; | |
| 178 ConvertJavaStringToUTF8(env, url_java, &url); | |
| 179 if (site_url_java) { | |
| 180 ConvertJavaStringToUTF8(env, site_url_java, &site_url); | |
| 181 } | |
| 182 if (icon_url_java) { | |
| 183 ConvertJavaStringToUTF8(env, icon_url_java, &icon_url); | |
| 184 } | |
| 185 if (title_java) { | |
| 186 ConvertJavaStringToUTF8(env, title_java, &title); | |
| 187 } | |
| 188 if (description_java) { | |
| 189 ConvertJavaStringToUTF8(env, description_java, &description); | |
| 190 } | |
| 191 if (group_id_java) { | |
| 192 ConvertJavaStringToUTF8(env, group_id_java, &group_id); | |
| 193 } | |
| 194 | |
| 195 // Append the new URL and associated metadata. | |
| 196 auto metadata_item = base::MakeUnique<base::DictionaryValue>(); | |
| 197 metadata_item->SetString("scannedUrl", url); | |
| 198 metadata_item->SetDouble("distanceEstimate", distance_estimate); | |
| 199 metadata_item->SetInteger("scanTimestamp", | |
| 200 static_cast<int>(scan_timestamp)); | |
| 201 metadata_item->SetString("resolvedUrl", site_url); | |
| 202 metadata_item->SetString("icon", icon_url); | |
| 203 metadata_item->SetString("title", title); | |
| 204 metadata_item->SetString("description", description); | |
| 205 metadata_item->SetString("groupId", group_id); | |
| 206 metadata->Append(std::move(metadata_item)); | |
| 207 } | |
| 208 return metadata; | |
| 46 } | 209 } |
| 47 | 210 |
| 48 bool PhysicalWebDataSourceAndroid::HasUnresolvedDiscoveries() { | 211 bool PhysicalWebDataSourceAndroid::HasUnresolvedDiscoveries() { |
| 49 NOTIMPLEMENTED(); | 212 NOTIMPLEMENTED(); |
| 50 return false; | 213 return false; |
| 51 } | 214 } |
| 52 | 215 |
| 53 // static | 216 // static |
| 54 bool PhysicalWebDataSourceAndroid::RegisterPhysicalWebDataSource(JNIEnv* env) { | 217 bool PhysicalWebDataSourceAndroid::RegisterPhysicalWebDataSource(JNIEnv* env) { |
| 55 return RegisterNativesImpl(env); | 218 return RegisterNativesImpl(env); |
| 56 } | 219 } |
| 57 | 220 |
| 58 static jlong Init(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 221 static jlong Init(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
| 59 PhysicalWebDataSource* data_source = | 222 PhysicalWebDataSource* data_source = |
| 60 g_browser_process->GetPhysicalWebDataSource(); | 223 g_browser_process->GetPhysicalWebDataSource(); |
| 61 return reinterpret_cast<intptr_t>(data_source); | 224 return reinterpret_cast<intptr_t>(data_source); |
| 62 } | 225 } |
| OLD | NEW |