mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Add Transfer File payload function
PiperOrigin-RevId: 420862465
This commit is contained in:
@@ -12,11 +12,18 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "third_party/dart_lang/v2/runtime/include/dart_api_dl.h"
|
||||
#include "third_party/dart_lang/v2/runtime/include/dart_native_api.h"
|
||||
#include "core/core.h"
|
||||
#include "third_party/nearby/windows/dart/core_adapter_dart.h"
|
||||
|
||||
#include <shlobj.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "core/core.h"
|
||||
#include "core/payload.h"
|
||||
#include "platform/base/logging.h"
|
||||
#include "platform/public/file.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
@@ -351,8 +358,7 @@ void RequestConnectionDart(Core *pCore, const char *endpoint_id,
|
||||
RequestConnection(pCore, endpoint_id, info, std::move(options), callback);
|
||||
}
|
||||
|
||||
void AcceptConnectionDart(Core *pCore,
|
||||
const char *endpoint_id,
|
||||
void AcceptConnectionDart(Core *pCore, const char *endpoint_id,
|
||||
PayloadListenerDart listener_dart,
|
||||
Dart_Port result_cb) {
|
||||
if (!pCore) {
|
||||
@@ -362,105 +368,119 @@ void AcceptConnectionDart(Core *pCore,
|
||||
|
||||
PayloadListener listener;
|
||||
listener.payload_cb = [listener_dart](const std::string &endpoint_id,
|
||||
Payload payload) {
|
||||
NEARBY_LOG(INFO, "Payload callback called. id: %s, "
|
||||
"payload_id: %d, type: %d, offset: %d",
|
||||
endpoint_id.c_str(),
|
||||
payload.GetId(),
|
||||
payload.GetType(),
|
||||
payload.GetOffset());
|
||||
Payload payload) {
|
||||
NEARBY_LOG(INFO,
|
||||
"Payload callback called. id: %s, "
|
||||
"payload_id: %d, type: %d, offset: %d",
|
||||
endpoint_id.c_str(), payload.GetId(), payload.GetType(),
|
||||
payload.GetOffset());
|
||||
|
||||
Dart_CObject dart_object_endpoint_id;
|
||||
dart_object_endpoint_id.type = Dart_CObject_kString;
|
||||
dart_object_endpoint_id.value.as_string =
|
||||
(char *)endpoint_id.data();
|
||||
Dart_CObject dart_object_endpoint_id;
|
||||
dart_object_endpoint_id.type = Dart_CObject_kString;
|
||||
dart_object_endpoint_id.value.as_string = (char *)endpoint_id.data();
|
||||
|
||||
Dart_CObject dart_object_payload_id;
|
||||
dart_object_payload_id.type = Dart_CObject_kInt64;
|
||||
dart_object_payload_id.value.as_int64 = payload.GetId();
|
||||
Dart_CObject dart_object_payload_id;
|
||||
dart_object_payload_id.type = Dart_CObject_kInt64;
|
||||
dart_object_payload_id.value.as_int64 = payload.GetId();
|
||||
|
||||
Dart_CObject dart_object_payload_type;
|
||||
dart_object_payload_type.type = Dart_CObject_kInt64;
|
||||
dart_object_payload_type.value.as_int64 = (int)payload.GetType();
|
||||
Dart_CObject dart_object_payload_type;
|
||||
dart_object_payload_type.type = Dart_CObject_kInt64;
|
||||
dart_object_payload_type.value.as_int64 = (int)payload.GetType();
|
||||
|
||||
Dart_CObject dart_object_offset;
|
||||
dart_object_offset.type = Dart_CObject_kInt64;
|
||||
dart_object_offset.value.as_int64 = payload.GetOffset();
|
||||
Dart_CObject dart_object_offset;
|
||||
dart_object_offset.type = Dart_CObject_kInt64;
|
||||
dart_object_offset.value.as_int64 = payload.GetOffset();
|
||||
|
||||
Dart_CObject* elements[4];
|
||||
elements[0] = &dart_object_endpoint_id;
|
||||
elements[1] = &dart_object_payload_id;
|
||||
elements[2] = &dart_object_payload_type;
|
||||
elements[3] = &dart_object_offset;
|
||||
Dart_CObject *elements[4];
|
||||
elements[0] = &dart_object_endpoint_id;
|
||||
elements[1] = &dart_object_payload_id;
|
||||
elements[2] = &dart_object_payload_type;
|
||||
elements[3] = &dart_object_offset;
|
||||
|
||||
Dart_CObject dart_object_payload;
|
||||
dart_object_payload.type = Dart_CObject_kArray;
|
||||
dart_object_payload.value.as_array.length = 4;
|
||||
dart_object_payload.value.as_array.values = elements;
|
||||
Dart_CObject dart_object_payload;
|
||||
dart_object_payload.type = Dart_CObject_kArray;
|
||||
dart_object_payload.value.as_array.length = 4;
|
||||
dart_object_payload.value.as_array.values = elements;
|
||||
|
||||
const bool result = Dart_PostCObject_DL(listener_dart.payload_cb,
|
||||
&dart_object_payload);
|
||||
if (!result) {
|
||||
NEARBY_LOG(INFO, "Posting message to port failed.");
|
||||
if (!Dart_PostCObject_DL(listener_dart.payload_cb, &dart_object_payload)) {
|
||||
NEARBY_LOG(INFO, "Posting message to port failed.");
|
||||
}
|
||||
};
|
||||
listener.payload_progress_cb = [listener_dart](
|
||||
const std::string &endpoint_id,
|
||||
const PayloadProgressInfo& info) {
|
||||
NEARBY_LOG(INFO, "Payload progress callback called. id: %s, "
|
||||
const std::string &endpoint_id,
|
||||
const PayloadProgressInfo &info) {
|
||||
NEARBY_LOG(INFO,
|
||||
"Payload progress callback called. id: %s, "
|
||||
"payload_id: %d, bytes transferred: %d, total: %d, status: %d",
|
||||
endpoint_id.c_str(),
|
||||
info.payload_id,
|
||||
info.bytes_transferred,
|
||||
info.total_bytes,
|
||||
info.status);
|
||||
Dart_CObject dart_object_endpoint_id;
|
||||
dart_object_endpoint_id.type = Dart_CObject_kString;
|
||||
dart_object_endpoint_id.value.as_string =
|
||||
(char *)endpoint_id.data();
|
||||
endpoint_id.c_str(), info.payload_id, info.bytes_transferred,
|
||||
info.total_bytes, info.status);
|
||||
Dart_CObject dart_object_endpoint_id;
|
||||
dart_object_endpoint_id.type = Dart_CObject_kString;
|
||||
dart_object_endpoint_id.value.as_string = (char *)endpoint_id.data();
|
||||
|
||||
Dart_CObject dart_object_payload_id;
|
||||
dart_object_payload_id.type = Dart_CObject_kInt64;
|
||||
dart_object_payload_id.value.as_int64 = info.payload_id;
|
||||
Dart_CObject dart_object_payload_id;
|
||||
dart_object_payload_id.type = Dart_CObject_kInt64;
|
||||
dart_object_payload_id.value.as_int64 = info.payload_id;
|
||||
|
||||
Dart_CObject dart_object_bytes_transferred;
|
||||
dart_object_bytes_transferred.type = Dart_CObject_kInt64;
|
||||
dart_object_bytes_transferred.value.as_int64 = info.bytes_transferred;
|
||||
Dart_CObject dart_object_bytes_transferred;
|
||||
dart_object_bytes_transferred.type = Dart_CObject_kInt64;
|
||||
dart_object_bytes_transferred.value.as_int64 = info.bytes_transferred;
|
||||
|
||||
Dart_CObject dart_object_total_bytes;
|
||||
dart_object_total_bytes.type = Dart_CObject_kInt64;
|
||||
dart_object_total_bytes.value.as_int64 = info.total_bytes;
|
||||
Dart_CObject dart_object_total_bytes;
|
||||
dart_object_total_bytes.type = Dart_CObject_kInt64;
|
||||
dart_object_total_bytes.value.as_int64 = info.total_bytes;
|
||||
|
||||
Dart_CObject dart_object_status;
|
||||
dart_object_status.type = Dart_CObject_kInt64;
|
||||
dart_object_status.value.as_int64 = (int64_t)info.status;
|
||||
Dart_CObject dart_object_status;
|
||||
dart_object_status.type = Dart_CObject_kInt64;
|
||||
dart_object_status.value.as_int64 = (int64_t)info.status;
|
||||
|
||||
Dart_CObject* elements[5];
|
||||
elements[0] = &dart_object_endpoint_id;
|
||||
elements[1] = &dart_object_payload_id;
|
||||
elements[2] = &dart_object_bytes_transferred;
|
||||
elements[3] = &dart_object_total_bytes;
|
||||
elements[4] = &dart_object_status;
|
||||
Dart_CObject *elements[5];
|
||||
elements[0] = &dart_object_endpoint_id;
|
||||
elements[1] = &dart_object_payload_id;
|
||||
elements[2] = &dart_object_bytes_transferred;
|
||||
elements[3] = &dart_object_total_bytes;
|
||||
elements[4] = &dart_object_status;
|
||||
|
||||
Dart_CObject dart_object_payload_progress;
|
||||
dart_object_payload_progress.type = Dart_CObject_kArray;
|
||||
dart_object_payload_progress.value.as_array.length = 5;
|
||||
dart_object_payload_progress.value.as_array.values = elements;
|
||||
Dart_CObject dart_object_payload_progress;
|
||||
dart_object_payload_progress.type = Dart_CObject_kArray;
|
||||
dart_object_payload_progress.value.as_array.length = 5;
|
||||
dart_object_payload_progress.value.as_array.values = elements;
|
||||
|
||||
const bool result =
|
||||
Dart_PostCObject_DL(listener_dart.payload_progress_cb,
|
||||
&dart_object_payload_progress);
|
||||
if (!result) {
|
||||
NEARBY_LOG(INFO,
|
||||
"Posting message to port failed.");
|
||||
}
|
||||
};
|
||||
if (!Dart_PostCObject_DL(listener_dart.payload_progress_cb,
|
||||
&dart_object_payload_progress)) {
|
||||
NEARBY_LOG(INFO, "Posting message to port failed.");
|
||||
}
|
||||
};
|
||||
|
||||
ResultCallback callback;
|
||||
SetResultCallback(callback, result_cb);
|
||||
AcceptConnection(pCore, endpoint_id, listener, callback);
|
||||
}
|
||||
|
||||
std::string GetPayloadPath(location::nearby::PayloadId payload_id) {
|
||||
PWSTR basePath;
|
||||
|
||||
// Retrieves the full path of a known folder identified by the folder's
|
||||
// KNOWNFOLDERID.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath
|
||||
SHGetKnownFolderPath(
|
||||
FOLDERID_Downloads, // rfid: A reference to the KNOWNFOLDERID that
|
||||
// identifies the folder.
|
||||
0, // dwFlags: Flags that specify special retrieval options.
|
||||
NULL, // hToken: An access token that represents a particular user.
|
||||
&basePath); // ppszPath: When this method returns, contains the address
|
||||
// of a pointer to a null-terminated Unicode string that
|
||||
// specifies the path of the known folder. The calling
|
||||
// process is responsible for freeing this resource once it
|
||||
// is no longer needed by calling CoTaskMemFree, whether
|
||||
// SHGetKnownFolderPath succeeds or not.
|
||||
|
||||
char *fullpathUTF8 = new char((wcslen(basePath) + 1) * sizeof(char));
|
||||
wcstombs(fullpathUTF8, basePath, (wcslen(basePath) + 1) * sizeof(char));
|
||||
|
||||
return absl::StrCat(fullpathUTF8, "\\", payload_id);
|
||||
}
|
||||
|
||||
void SendPayloadDart(Core *pCore, const char *endpoint_id,
|
||||
PayloadDart payload_dart, Dart_Port result_cb) {
|
||||
if (!pCore) {
|
||||
@@ -471,10 +491,43 @@ void SendPayloadDart(Core *pCore, const char *endpoint_id,
|
||||
ResultCallback callback;
|
||||
std::vector<string> endpoint_ids = {string(endpoint_id)};
|
||||
|
||||
Payload payload(Payload::GenerateId(), ByteArray(payload_dart.data));
|
||||
SetResultCallback(callback, result_cb);
|
||||
SendPayload(pCore, absl::Span<const std::string>(endpoint_ids),
|
||||
std::move(payload), callback);
|
||||
NEARBY_LOG(INFO, "Payload type: %d", payload_dart.type);
|
||||
switch (payload_dart.type) {
|
||||
case UNKNOWN:
|
||||
case STREAM:
|
||||
NEARBY_LOG(INFO, "Payload type not supported yet");
|
||||
PostResult(result_cb, Status::Value::kPayloadUnknown);
|
||||
break;
|
||||
case BYTE: {
|
||||
Payload payload(Payload::GenerateId(), ByteArray(payload_dart.data));
|
||||
SendPayload(pCore, absl::Span<const std::string>(endpoint_ids),
|
||||
std::move(payload), callback);
|
||||
}
|
||||
SetResultCallback(callback, result_cb);
|
||||
break;
|
||||
case FILE:
|
||||
NEARBY_LOG(INFO, "File name: %s, size %d", payload_dart.data,
|
||||
payload_dart.size);
|
||||
std::string file_name_str(payload_dart.data);
|
||||
|
||||
// TODO(yanfangliu) Clean this up when John's file payload change rolls
|
||||
// out
|
||||
Payload::Id id = std::hash<std::string>()(file_name_str);
|
||||
std::string download_path = GetPayloadPath(id);
|
||||
CopyFileA((LPSTR)payload_dart.data, (LPSTR)download_path.c_str(),
|
||||
/*FailIfFileAlreadyExists=*/ false);
|
||||
NEARBY_LOGS(INFO) << "Copy File to " << download_path;
|
||||
|
||||
InputFile input_file{id, payload_dart.size};
|
||||
{
|
||||
Payload payload{id, std::move(input_file)};
|
||||
SendPayload(pCore, absl::Span<const std::string>(endpoint_ids),
|
||||
std::move(payload), callback);
|
||||
}
|
||||
SetResultCallback(callback, result_cb);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // namespace windows
|
||||
} // namespace connections
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#ifndef LOCATION_NEARBY_CONNECTIONS_WINDOWS_DART_CORE_ADAPTER_DART_H_
|
||||
#define LOCATION_NEARBY_CONNECTIONS_WINDOWS_DART_CORE_ADAPTER_DART_H_
|
||||
|
||||
#include "third_party/dart_lang/v2/runtime/include/dart_api_dl.h"
|
||||
#include "third_party/dart_lang/v2/runtime/include/dart_native_api.h"
|
||||
#include "third_party/nearby/windows/core_adapter.h"
|
||||
|
||||
namespace location {
|
||||
@@ -74,7 +76,7 @@ struct PayloadDart {
|
||||
int64_t id;
|
||||
PayloadType type;
|
||||
int64_t size;
|
||||
char* data;
|
||||
char *data;
|
||||
};
|
||||
|
||||
// Starts advertising an endpoint for a local app.
|
||||
@@ -191,10 +193,9 @@ DLL_EXPORT void __stdcall AcceptConnectionDart(
|
||||
// still occur during transmission (and at different times for
|
||||
// different endpoints), and will be delivered via
|
||||
// PayloadCallback#onPayloadTransferUpdate.
|
||||
DLL_EXPORT void __stdcall SendPayloadDart(Core* pCore,
|
||||
const char* endpoint_id,
|
||||
PayloadDart payload_dart,
|
||||
Dart_Port result_cb);
|
||||
DLL_EXPORT void __stdcall SendPayloadDart(Core *pCore, const char *endpoint_id,
|
||||
PayloadDart payload_dart,
|
||||
Dart_Port result_cb);
|
||||
|
||||
} // namespace windows
|
||||
} // namespace connections
|
||||
|
||||
Reference in New Issue
Block a user