mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
197 lines
6.6 KiB
C++
197 lines
6.6 KiB
C++
// Copyright 2023 Google LLC
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "sharing/nearby_sharing_service_extension.h"
|
|
|
|
#include <filesystem> // NOLINT(build/c++17)
|
|
#include <string>
|
|
|
|
#include "absl/status/status.h"
|
|
#include "absl/strings/string_view.h"
|
|
#include "absl/synchronization/notification.h"
|
|
#include "internal/network/url.h"
|
|
#include "sharing/attachment_container.h"
|
|
#include "sharing/file_attachment.h"
|
|
#include "sharing/internal/public/logging.h"
|
|
#include "sharing/nearby_sharing_service.h"
|
|
#include "sharing/proto/wire_format.pb.h"
|
|
#include "sharing/text_attachment.h"
|
|
#include "sharing/wifi_credentials_attachment.h"
|
|
|
|
namespace nearby {
|
|
namespace sharing {
|
|
|
|
namespace {
|
|
using ::nearby::sharing::service::proto::FileMetadata;
|
|
using ::nearby::sharing::service::proto::TextMetadata;
|
|
using StatusCodes = ::nearby::sharing::NearbySharingService::StatusCodes;
|
|
} // namespace
|
|
|
|
NearbySharingService::StatusCodes NearbySharingServiceExtension::Open(
|
|
const AttachmentContainer& container) {
|
|
if (!container.HasAttachments()) {
|
|
return StatusCodes::kInvalidArgument;
|
|
}
|
|
|
|
if (!container.GetFileAttachments().empty() &&
|
|
!container.GetTextAttachments().empty()) {
|
|
NL_LOG(ERROR)
|
|
<< __func__
|
|
<< ": Text attachments and file attachments can't come together.";
|
|
return StatusCodes::kError;
|
|
}
|
|
|
|
if (container.GetTextAttachments().size() == 1) {
|
|
const TextAttachment& text_attachment = container.GetTextAttachments()[0];
|
|
|
|
switch (text_attachment.type()) {
|
|
case TextMetadata::TEXT: {
|
|
CopyText(text_attachment.text_body());
|
|
break;
|
|
}
|
|
case TextMetadata::URL: {
|
|
OpenUrl(*nearby::network::Url::Create(text_attachment.text_body()));
|
|
break;
|
|
}
|
|
default: {
|
|
// Copy text for all other text types.
|
|
CopyText(text_attachment.text_title());
|
|
break;
|
|
}
|
|
}
|
|
return StatusCodes::kOk;
|
|
}
|
|
|
|
if (container.GetTextAttachments().size() > 1) {
|
|
NL_LOG(ERROR) << __func__
|
|
<< ": Multiple text attachments are not supported currently.";
|
|
return StatusCodes::kError;
|
|
}
|
|
|
|
if (container.GetWifiCredentialsAttachments().size() == 1) {
|
|
const WifiCredentialsAttachment& wifi_credentials_attachment =
|
|
container.GetWifiCredentialsAttachments()[0];
|
|
JoinWifiNetwork(wifi_credentials_attachment.ssid(),
|
|
wifi_credentials_attachment.password());
|
|
return StatusCodes::kOk;
|
|
}
|
|
|
|
if (container.GetWifiCredentialsAttachments().size() > 1) {
|
|
NL_LOG(ERROR) << __func__
|
|
<< ": Multiple WiFi credentials attachments are not "
|
|
"supported currently.";
|
|
return StatusCodes::kError;
|
|
}
|
|
|
|
const FileAttachment& file_attachment = container.GetFileAttachments()[0];
|
|
|
|
if ((container.GetFileAttachments().size() > 1) ||
|
|
((file_attachment.type() != FileMetadata::AUDIO) &&
|
|
(file_attachment.type() != FileMetadata::VIDEO) &&
|
|
(file_attachment.type() != FileMetadata::IMAGE))) {
|
|
// Opens download folder.
|
|
NearbySharingService::StatusCodes status_codes = StatusCodes::kOk;
|
|
absl::Notification notification;
|
|
context_->GetShell().Open(
|
|
std::filesystem::u8path(settings_->GetCustomSavePath()),
|
|
[&status_codes, ¬ification](absl::Status status) {
|
|
if (!status.ok()) {
|
|
NL_LOG(ERROR)
|
|
<< "Failed to open download folder with error message:"
|
|
<< status;
|
|
status_codes = StatusCodes::kError;
|
|
} else {
|
|
status_codes = StatusCodes::kOk;
|
|
}
|
|
notification.Notify();
|
|
});
|
|
notification.WaitForNotification();
|
|
return status_codes;
|
|
}
|
|
|
|
// Opens the file with default application.
|
|
std::filesystem::path file_path;
|
|
if (file_attachment.file_path().has_value()) {
|
|
file_path = *file_attachment.file_path();
|
|
} else {
|
|
file_path =
|
|
std::filesystem::u8path(settings_->GetCustomSavePath()) /
|
|
// NOLINTNEXTLINE cannot build without the new string creation
|
|
std::filesystem::u8path(std::string(file_attachment.file_name()));
|
|
}
|
|
|
|
NearbySharingService::StatusCodes status_codes = StatusCodes::kOk;
|
|
absl::Notification notification;
|
|
context_->GetShell().Open(
|
|
file_path, [file_name = file_attachment.file_name(), &status_codes,
|
|
¬ification](absl::Status status) {
|
|
if (!status.ok()) {
|
|
NL_LOG(ERROR) << "Failed to open file " << file_name;
|
|
status_codes = StatusCodes::kError;
|
|
} else {
|
|
status_codes = StatusCodes::kOk;
|
|
}
|
|
notification.Notify();
|
|
});
|
|
notification.WaitForNotification();
|
|
return status_codes;
|
|
}
|
|
|
|
// Opens an url target on a browser instance.
|
|
void NearbySharingServiceExtension::OpenUrl(const ::nearby::network::Url& url) {
|
|
absl::Notification notification;
|
|
context_->OpenUrl(url, [url, ¬ification](absl::Status status) {
|
|
if (!status.ok()) {
|
|
NL_LOG(ERROR) << "Failed to open URL " << url.GetUrlPath()
|
|
<< " with error " << status.message();
|
|
}
|
|
notification.Notify();
|
|
});
|
|
|
|
notification.WaitForNotification();
|
|
}
|
|
|
|
// Copies text to cache/clipboard.
|
|
void NearbySharingServiceExtension::CopyText(absl::string_view text) {
|
|
absl::Notification notification;
|
|
context_->CopyText(
|
|
text, [text = std::string(text), ¬ification](absl::Status status) {
|
|
if (!status.ok()) {
|
|
NL_LOG(ERROR) << "Failed to copy text " << text << " with error "
|
|
<< status.message();
|
|
}
|
|
notification.Notify();
|
|
});
|
|
notification.WaitForNotification();
|
|
}
|
|
|
|
// Persists and joins the Wi-Fi network.
|
|
void NearbySharingServiceExtension::JoinWifiNetwork(
|
|
absl::string_view ssid, absl::string_view password) {
|
|
absl::Notification notification;
|
|
context_->GetWifiAdapter().JoinNetwork(
|
|
ssid, password,
|
|
[ssid = std::string(ssid), ¬ification](absl::Status status) {
|
|
if (!status.ok()) {
|
|
NL_LOG(ERROR) << "Failed to join network " << ssid << " with error "
|
|
<< status.message();
|
|
}
|
|
notification.Notify();
|
|
});
|
|
notification.WaitForNotification();
|
|
}
|
|
|
|
} // namespace sharing
|
|
} // namespace nearby
|