Commit 68f89b61 authored by Juliet Levesque's avatar Juliet Levesque Committed by Chromium LUCI CQ

[Nearby] Add State Button to chrome://nearby-internals.

Add a button that triggers the retrieval of Nearby-related state
booleans and displays the result as messages on the UI Trigger Tab
as follows:
https://screenshot.googleplex.com/4NyiQsiPAocTMmY.

Bug: 1093634
Change-Id: I28927f14eab542b41d950b553d0c779ecf22c940
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2637775Reviewed-by: default avatarJosh Nohle <nohle@chromium.org>
Reviewed-by: default avatarJames Vecore <vecore@google.com>
Commit-Queue: Juliet Levesque <julietlevesque@google.com>
Cr-Commit-Position: refs/heads/master@{#846334}
parent cb5c4b2a
...@@ -39,8 +39,12 @@ class MockNearbySharingService : public NearbySharingService { ...@@ -39,8 +39,12 @@ class MockNearbySharingService : public NearbySharingService {
(TransferUpdateCallback*), (TransferUpdateCallback*),
(override)); (override));
MOCK_METHOD(StatusCodes, ClearForegroundReceiveSurfaces, (), (override)); MOCK_METHOD(StatusCodes, ClearForegroundReceiveSurfaces, (), (override));
MOCK_METHOD(bool, IsInHighVisibility, (), (override)); MOCK_METHOD(bool, IsInHighVisibility, (), (const override));
MOCK_METHOD(bool, IsTransferring, (), (const override)); MOCK_METHOD(bool, IsTransferring, (), (const override));
MOCK_METHOD(bool, IsSendingFile, (), (const override));
MOCK_METHOD(bool, IsReceivingFile, (), (const override));
MOCK_METHOD(bool, IsConnecting, (), (const override));
MOCK_METHOD(bool, IsScanning, (), (const override));
MOCK_METHOD(StatusCodes, MOCK_METHOD(StatusCodes,
SendAttachments, SendAttachments,
(const ShareTarget&, std::vector<std::unique_ptr<Attachment>>), (const ShareTarget&, std::vector<std::unique_ptr<Attachment>>),
......
...@@ -112,11 +112,24 @@ class NearbySharingService : public KeyedService { ...@@ -112,11 +112,24 @@ class NearbySharingService : public KeyedService {
virtual StatusCodes ClearForegroundReceiveSurfaces() = 0; virtual StatusCodes ClearForegroundReceiveSurfaces() = 0;
// Returns true if a foreground receive surface is registered. // Returns true if a foreground receive surface is registered.
virtual bool IsInHighVisibility() = 0; virtual bool IsInHighVisibility() const = 0;
// Returns true if there is an ongoing file transfer. // Returns true if there is an ongoing file transfer.
virtual bool IsTransferring() const = 0; virtual bool IsTransferring() const = 0;
// Returns true if we're currently receiving a file.
virtual bool IsReceivingFile() const = 0;
// Returns true if we're currently sending a file.
virtual bool IsSendingFile() const = 0;
// Returns true if we're currently attempting to connect to a
// remote device.
virtual bool IsConnecting() const = 0;
// Returns true if we are currently scanning for remote devices.
virtual bool IsScanning() const = 0;
// Sends |attachments| to the remote |share_target|. // Sends |attachments| to the remote |share_target|.
virtual StatusCodes SendAttachments( virtual StatusCodes SendAttachments(
const ShareTarget& share_target, const ShareTarget& share_target,
......
...@@ -598,10 +598,30 @@ NearbySharingServiceImpl::ClearForegroundReceiveSurfaces() { ...@@ -598,10 +598,30 @@ NearbySharingServiceImpl::ClearForegroundReceiveSurfaces() {
return status; return status;
} }
bool NearbySharingServiceImpl::IsInHighVisibility() { bool NearbySharingServiceImpl::IsInHighVisibility() const {
return in_high_visibility; return in_high_visibility;
} }
bool NearbySharingServiceImpl::IsTransferring() const {
return is_transferring_;
}
bool NearbySharingServiceImpl::IsReceivingFile() const {
return is_receiving_files_;
}
bool NearbySharingServiceImpl::IsSendingFile() const {
return is_sending_files_;
}
bool NearbySharingServiceImpl::IsScanning() const {
return is_scanning_;
}
bool NearbySharingServiceImpl::IsConnecting() const {
return is_connecting_;
}
NearbySharingService::StatusCodes NearbySharingServiceImpl::SendAttachments( NearbySharingService::StatusCodes NearbySharingServiceImpl::SendAttachments(
const ShareTarget& share_target, const ShareTarget& share_target,
std::vector<std::unique_ptr<Attachment>> attachments) { std::vector<std::unique_ptr<Attachment>> attachments) {
...@@ -3145,10 +3165,6 @@ void NearbySharingServiceImpl::OnIncomingConnectionDisconnected( ...@@ -3145,10 +3165,6 @@ void NearbySharingServiceImpl::OnIncomingConnectionDisconnected(
UnregisterShareTarget(share_target); UnregisterShareTarget(share_target);
} }
bool NearbySharingServiceImpl::IsTransferring() const {
return is_transferring_;
}
void NearbySharingServiceImpl::OnOutgoingConnectionDisconnected( void NearbySharingServiceImpl::OnOutgoingConnectionDisconnected(
const ShareTarget& share_target) { const ShareTarget& share_target) {
ShareTargetInfo* info = GetShareTargetInfo(share_target); ShareTargetInfo* info = GetShareTargetInfo(share_target);
......
...@@ -91,7 +91,12 @@ class NearbySharingServiceImpl ...@@ -91,7 +91,12 @@ class NearbySharingServiceImpl
StatusCodes UnregisterReceiveSurface( StatusCodes UnregisterReceiveSurface(
TransferUpdateCallback* transfer_callback) override; TransferUpdateCallback* transfer_callback) override;
StatusCodes ClearForegroundReceiveSurfaces() override; StatusCodes ClearForegroundReceiveSurfaces() override;
bool IsInHighVisibility() override; bool IsInHighVisibility() const override;
bool IsTransferring() const override;
bool IsReceivingFile() const override;
bool IsSendingFile() const override;
bool IsScanning() const override;
bool IsConnecting() const override;
StatusCodes SendAttachments( StatusCodes SendAttachments(
const ShareTarget& share_target, const ShareTarget& share_target,
std::vector<std::unique_ptr<Attachment>> attachments) override; std::vector<std::unique_ptr<Attachment>> attachments) override;
...@@ -122,8 +127,6 @@ class NearbySharingServiceImpl ...@@ -122,8 +127,6 @@ class NearbySharingServiceImpl
const std::vector<uint8_t>& endpoint_info, const std::vector<uint8_t>& endpoint_info,
NearbyConnection* connection) override; NearbyConnection* connection) override;
bool IsTransferring() const override;
// Test methods // Test methods
void FlushMojoForTesting(); void FlushMojoForTesting();
void set_free_disk_space_for_testing(int64_t free_disk_space) { void set_free_disk_space_for_testing(int64_t free_disk_space) {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js';
import {StatusCode} from './types.js'; import {NearbyShareStates, StatusCode} from './types.js';
/** /**
* JavaScript hooks into the native WebUI handler to pass information to the * JavaScript hooks into the native WebUI handler to pass information to the
...@@ -110,6 +110,14 @@ export class NearbyUiTriggerBrowserProxy { ...@@ -110,6 +110,14 @@ export class NearbyUiTriggerBrowserProxy {
unregisterReceiveSurface() { unregisterReceiveSurface() {
return sendWithPromise('unregisterReceiveSurface'); return sendWithPromise('unregisterReceiveSurface');
} }
/**
* Requests states of Nearby Share booleans.
* @return {!Promise<!NearbyShareStates>}
*/
getState() {
return sendWithPromise('getStates');
}
} }
addSingletonGetter(NearbyUiTriggerBrowserProxy); addSingletonGetter(NearbyUiTriggerBrowserProxy);
...@@ -125,3 +125,15 @@ export const ShareTargetDiscoveryChange = { ...@@ -125,3 +125,15 @@ export const ShareTargetDiscoveryChange = {
* value: string}} * value: string}}
*/ */
export let ShareTargetSelectOption; export let ShareTargetSelectOption;
/**
* Dictionary for Nearby Share State booleans
* @typedef {{isScanning: boolean,
* isTransferring: boolean,
* isSending: boolean,
* isReceiving: boolean,
* isConnecting: boolean,
* isInHighVisibility: boolean,
* time: number}}
*/
export let NearbyShareStates;
<style> <style>
#generic-object { #generic-object {
left: 0; display: inline-block;
padding-left: 5px; text-align: start;
position: absolute;
text-align: left;
width: 100%; width: 100%;
} }
...@@ -15,8 +13,7 @@ ...@@ -15,8 +13,7 @@
} }
#item { #item {
margin: 10px; padding: 6px;
padding: 10px;
} }
</style> </style>
<div id="item"> <div id="item">
......
...@@ -18,7 +18,10 @@ ...@@ -18,7 +18,10 @@
} }
#logging-section { #logging-section {
width: 100%; display: flex;
flex-direction: column;
height: 100%;
white-space: pre-wrap;
} }
#share-select { #share-select {
...@@ -76,6 +79,9 @@ ...@@ -76,6 +79,9 @@
on-click="onUnregisterReceiveSurfaceClicked_"> on-click="onUnregisterReceiveSurfaceClicked_">
Unregister Current ReceiveSurface Unregister Current ReceiveSurface
</cr-button> </cr-button>
<cr-button class="internals-button" on-click="onGetStatesClicked_">
Get States
</cr-button>
<span id="flex"></span> <span id="flex"></span>
<select id="share-select" on-change="onSelectChange_"> <select id="share-select" on-change="onSelectChange_">
<template is="dom-repeat" items="[[shareTargetSelectOptionList_]]"> <template is="dom-repeat" items="[[shareTargetSelectOptionList_]]">
......
...@@ -10,7 +10,7 @@ import './shared_style.js'; ...@@ -10,7 +10,7 @@ import './shared_style.js';
import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js'; import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {NearbyUiTriggerBrowserProxy} from './nearby_ui_trigger_browser_proxy.js'; import {NearbyUiTriggerBrowserProxy} from './nearby_ui_trigger_browser_proxy.js';
import {ShareTarget, ShareTargetDiscoveryChange, ShareTargetSelectOption, StatusCode, TimestampedMessage, TransferMetadataStatus} from './types.js'; import {NearbyShareStates, ShareTarget, ShareTargetDiscoveryChange, ShareTargetSelectOption, StatusCode, TimestampedMessage, TransferMetadataStatus} from './types.js';
Polymer({ Polymer({
is: 'ui-trigger-tab', is: 'ui-trigger-tab',
...@@ -142,6 +142,24 @@ Polymer({ ...@@ -142,6 +142,24 @@ Polymer({
this.unshift('uiTriggerObjectList_', {'message': message, 'time': time}); this.unshift('uiTriggerObjectList_', {'message': message, 'time': time});
}, },
/**
* Updates state variables based on the dictionary returned once triggered
* by |GetState|.
* @param {!NearbyShareStates} currentStates
* @private
*/
onCurrentStatesReturned_(currentStates) {
const time = currentStates.time;
const message =
`Is Scanning? : ${currentStates.isScanning}\nIs Transferring? : ${
currentStates.isTransferring}\nIs Receiving? : ${
currentStates.isReceiving}\nIs Sending? : ${
currentStates.isSending}\nIs Connecting? : ${
currentStates.isConnecting}\nIs In High Visibility? : ${
currentStates.isInHighVisibility}`;
this.unshift('uiTriggerObjectList_', {'message': message, 'time': time});
},
/** /**
* Triggers sendText with selected |shareTargetId|. * Triggers sendText with selected |shareTargetId|.
* @private * @private
...@@ -183,6 +201,17 @@ Polymer({ ...@@ -183,6 +201,17 @@ Polymer({
this.browserProxy_.open(this.selectedShareTargetId_); this.browserProxy_.open(this.selectedShareTargetId_);
}, },
/**
* Triggers GetState to retrieve current states and update display
* accordingly.
* @private
*/
onGetStatesClicked_() {
this.browserProxy_.getState().then(
currentStates => this.onCurrentStatesReturned_(currentStates));
},
/** /**
* Updates |selectedShareTargetId_| with the new selected option. * Updates |selectedShareTargetId_| with the new selected option.
* @private * @private
......
...@@ -28,6 +28,15 @@ const char kStatusCodeKey[] = "statusCode"; ...@@ -28,6 +28,15 @@ const char kStatusCodeKey[] = "statusCode";
const char kTriggerEventKey[] = "triggerEvent"; const char kTriggerEventKey[] = "triggerEvent";
const char kTransferUpdateMetaDataKey[] = "transfer_metadataStatus"; const char kTransferUpdateMetaDataKey[] = "transfer_metadataStatus";
// Keys in the JSON representation of a dictiory send to UITriggerTab for
// the state of the transfer.
const char kIsConnecting[] = "isConnecting";
const char kIsInHighVisibility[] = "isInHighVisibility";
const char kIsReceiving[] = "isReceiving";
const char kIsScanning[] = "isScanning";
const char kIsSending[] = "isSending";
const char kIsTransferring[] = "isTransferring";
// TriggerEvents in alphabetical order. // TriggerEvents in alphabetical order.
enum class TriggerEvent { enum class TriggerEvent {
kAccept, kAccept,
...@@ -184,6 +193,23 @@ base::Value TransferUpdateToDictionary( ...@@ -184,6 +193,23 @@ base::Value TransferUpdateToDictionary(
return dictionary; return dictionary;
} }
base::Value StatusBooleansToDictionary(const bool is_scanning,
const bool is_transferring,
const bool is_receiving_files,
const bool is_sending_files,
const bool is_conecting,
const bool is_in_high_visibility) {
base::Value dictionary(base::Value::Type::DICTIONARY);
dictionary.SetBoolKey(kIsScanning, is_scanning);
dictionary.SetBoolKey(kIsTransferring, is_transferring);
dictionary.SetBoolKey(kIsSending, is_sending_files);
dictionary.SetBoolKey(kIsReceiving, is_receiving_files);
dictionary.SetBoolKey(kIsConnecting, is_conecting);
dictionary.SetBoolKey(kIsInHighVisibility, is_in_high_visibility);
dictionary.SetKey(kTimeStampKey, GetJavascriptTimestamp());
return dictionary;
}
} // namespace } // namespace
NearbyInternalsUiTriggerHandler::NearbyInternalsUiTriggerHandler( NearbyInternalsUiTriggerHandler::NearbyInternalsUiTriggerHandler(
...@@ -243,6 +269,10 @@ void NearbyInternalsUiTriggerHandler::RegisterMessages() { ...@@ -243,6 +269,10 @@ void NearbyInternalsUiTriggerHandler::RegisterMessages() {
base::BindRepeating( base::BindRepeating(
&NearbyInternalsUiTriggerHandler::UnregisterReceiveSurface, &NearbyInternalsUiTriggerHandler::UnregisterReceiveSurface,
base::Unretained(this))); base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"getStates",
base::BindRepeating(&NearbyInternalsUiTriggerHandler::GetState,
base::Unretained(this)));
} }
void NearbyInternalsUiTriggerHandler::InitializeContents( void NearbyInternalsUiTriggerHandler::InitializeContents(
...@@ -519,3 +549,20 @@ void NearbyInternalsUiTriggerHandler::Cancel(const base::ListValue* args) { ...@@ -519,3 +549,20 @@ void NearbyInternalsUiTriggerHandler::Cancel(const base::ListValue* args) {
base::BindOnce(&NearbyInternalsUiTriggerHandler::OnCancelCalled, base::BindOnce(&NearbyInternalsUiTriggerHandler::OnCancelCalled,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
} }
void NearbyInternalsUiTriggerHandler::GetState(const base::ListValue* args) {
NearbySharingService* service_ =
NearbySharingServiceFactory::GetForBrowserContext(context_);
if (!service_) {
NS_LOG(ERROR) << "No NearbyShareService instance to call.";
return;
}
const base::Value& callback_id = args->GetList()[0];
ResolveJavascriptCallback(
callback_id,
StatusBooleansToDictionary(
service_->IsScanning(), service_->IsTransferring(),
service_->IsReceivingFile(), service_->IsSendingFile(),
service_->IsConnecting(), service_->IsInHighVisibility()));
}
...@@ -108,6 +108,12 @@ class NearbyInternalsUiTriggerHandler : public content::WebUIMessageHandler, ...@@ -108,6 +108,12 @@ class NearbyInternalsUiTriggerHandler : public content::WebUIMessageHandler,
// the receive surface to be unregistered. // the receive surface to be unregistered.
void UnregisterReceiveSurface(const base::ListValue* args); void UnregisterReceiveSurface(const base::ListValue* args);
// Message handler callback that calls IsScanning, IsTransferring,
// IsReceivingFile, IsSendingFile, IsConnecting, and IsInHighVisibility in the
// NearbySharingService and passes booleans to JavaScript to eventually be
// displayed.
void GetState(const base::ListValue* args);
content::BrowserContext* const context_; content::BrowserContext* const context_;
base::flat_map<std::string, ShareTarget> id_to_share_target_map_; base::flat_map<std::string, ShareTarget> id_to_share_target_map_;
base::WeakPtrFactory<NearbyInternalsUiTriggerHandler> weak_ptr_factory_{this}; base::WeakPtrFactory<NearbyInternalsUiTriggerHandler> weak_ptr_factory_{this};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment