diff --git a/DEPS b/DEPS index 02688a1..36374f70 100644 --- a/DEPS +++ b/DEPS
@@ -54,7 +54,7 @@ 'checkout_telemetry_dependencies': False, # libaom provides support for AV1 but the bitstream is not frozen. - 'checkout_libaom': True, + 'checkout_libaom': False, # TODO(dpranke): change to != "small" once != is supported. 'checkout_traffic_annotation_tools': 'checkout_configuration == "default"',
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 939c7d1..9dad697 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -749,6 +749,8 @@ "wallpaper/wallpaper_controller.cc", "wallpaper/wallpaper_controller.h", "wallpaper/wallpaper_controller_observer.h", + "wallpaper/wallpaper_decoder.cc", + "wallpaper/wallpaper_decoder.h", "wallpaper/wallpaper_delegate.h", "wallpaper/wallpaper_delegate_mus.cc", "wallpaper/wallpaper_delegate_mus.h",
diff --git a/ash/wallpaper/DEPS b/ash/wallpaper/DEPS index f12a4015..f6a0335 100644 --- a/ash/wallpaper/DEPS +++ b/ash/wallpaper/DEPS
@@ -1,3 +1,4 @@ include_rules = [ "+components/wallpaper", + "+services/data_decoder/public", ]
diff --git a/ash/wallpaper/wallpaper_decoder.cc b/ash/wallpaper/wallpaper_decoder.cc new file mode 100644 index 0000000..39424416 --- /dev/null +++ b/ash/wallpaper/wallpaper_decoder.cc
@@ -0,0 +1,48 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/wallpaper/wallpaper_decoder.h" + +#include "ash/shell.h" +#include "ash/shell_delegate.h" +#include "base/sequenced_task_runner.h" +#include "components/user_manager/user_image/user_image.h" +#include "ipc/ipc_channel.h" +#include "services/data_decoder/public/cpp/decode_image.h" + +namespace ash { +namespace { + +const int64_t kMaxImageSizeInBytes = + static_cast<int64_t>(IPC::Channel::kMaximumMessageSize); + +// TODO(crbug.com/776464): This should be changed to |ConvertToImageSkia| after +// the use of |UserImage| in |WallpaperManager| is deprecated. +void ConvertToUserImage(OnWallpaperDecoded callback, const SkBitmap& image) { + SkBitmap final_image = image; + final_image.setImmutable(); + gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(final_image); + image_skia.MakeThreadSafe(); + auto user_image = std::make_unique<user_manager::UserImage>( + image_skia, new base::RefCountedBytes() /* unused */, + user_manager::UserImage::FORMAT_JPEG /* unused */); + + std::move(callback).Run(std::move(user_image)); +} + +} // namespace + +void DecodeWallpaper(std::unique_ptr<std::string> image_data, + OnWallpaperDecoded callback) { + std::vector<uint8_t> image_bytes(image_data.get()->begin(), + image_data.get()->end()); + data_decoder::DecodeImage( + Shell::Get()->shell_delegate()->GetShellConnector(), + std::move(image_bytes), data_decoder::mojom::ImageCodec::ROBUST_JPEG, + false /* shrink_to_fit */, kMaxImageSizeInBytes, + gfx::Size() /* desired_image_frame_size */, + base::BindOnce(&ConvertToUserImage, std::move(callback))); +} + +} // namespace ash \ No newline at end of file
diff --git a/ash/wallpaper/wallpaper_decoder.h b/ash/wallpaper/wallpaper_decoder.h new file mode 100644 index 0000000..5931f6e --- /dev/null +++ b/ash/wallpaper/wallpaper_decoder.h
@@ -0,0 +1,28 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_WALLPAPER_WALLPAPER_DECODER_H_ +#define ASH_WALLPAPER_WALLPAPER_DECODER_H_ + +#include "ash/ash_export.h" +#include "base/callback_forward.h" +#include "base/memory/scoped_refptr.h" + +namespace user_manager { +class UserImage; +} + +namespace ash { + +using OnWallpaperDecoded = base::OnceCallback<void( + std::unique_ptr<user_manager::UserImage> user_image)>; + +// Do an async wallpaper decode; |on_decoded| is run on the calling thread when +// the decode has finished. +ASH_EXPORT void DecodeWallpaper(std::unique_ptr<std::string> image_data, + OnWallpaperDecoded callback); + +} // namespace ash + +#endif // ASH_WALLPAPER_WALLPAPER_DECODER_H_ \ No newline at end of file
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc index b089fb04..9243eed6 100644 --- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc +++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
@@ -12,6 +12,7 @@ #include "ash/public/cpp/window_properties.h" #include "ash/public/interfaces/constants.mojom.h" #include "ash/shell.h" +#include "ash/wallpaper/wallpaper_decoder.h" #include "ash/wallpaper/wallpaper_window_state_manager.h" #include "base/bind.h" #include "base/bind_helpers.h" @@ -258,6 +259,40 @@ return written_bytes == size; } +// If |data_is_ready| is true, start decoding the image, which will run +// |callback| upon completion; if it's false, run |callback| immediately with +// an empty image. +// TODO(crbug.com/776464): Mash and some unit tests can't use this decoder +// because it depends on the Shell instance. Make it work after all the decoding +// code is moved to //ash. +void DecodeWallpaperIfApplicable(user_image_loader::LoadedCallback callback, + std::unique_ptr<std::string> data, + bool data_is_ready) { + if (!data_is_ready) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce( + std::move(callback), + base::Passed(std::make_unique<user_manager::UserImage>()))); + return; + } + ash::DecodeWallpaper(std::move(data), std::move(callback)); +} + +// Reads image from |file_path| on disk, and calls |DecodeWallpaperIfApplicable| +// with the result of |ReadFileToString|. +void ReadAndDecodeWallpaper( + user_image_loader::LoadedCallback callback, + scoped_refptr<base::SequencedTaskRunner> task_runner, + const base::FilePath& file_path) { + std::string* data = new std::string; + base::PostTaskAndReplyWithResult( + task_runner.get(), FROM_HERE, + base::Bind(&base::ReadFileToString, file_path, data), + base::Bind(&DecodeWallpaperIfApplicable, std::move(callback), + base::Passed(base::WrapUnique(data)))); +} + } // namespace void AssertCalledOnWallpaperSequence(base::SequencedTaskRunner* task_runner) { @@ -1029,11 +1064,18 @@ if (!data) return; - user_image_loader::StartWithData( - task_runner_, std::move(data), ImageDecoder::ROBUST_JPEG_CODEC, - 0, // Do not crop. - base::Bind(&WallpaperManager::SetPolicyControlledWallpaper, - weak_factory_.GetWeakPtr(), account_id)); + if (!ash::Shell::HasInstance() || ash_util::IsRunningInMash()) { + user_image_loader::StartWithData( + task_runner_, std::move(data), ImageDecoder::ROBUST_JPEG_CODEC, + 0, // Do not crop. + base::Bind(&WallpaperManager::SetPolicyControlledWallpaper, + weak_factory_.GetWeakPtr(), account_id)); + } else { + DecodeWallpaperIfApplicable( + base::Bind(&WallpaperManager::SetPolicyControlledWallpaper, + weak_factory_.GetWeakPtr(), account_id), + std::move(data), true /* data_is_ready */); + } } size_t WallpaperManager::GetPendingListSizeForTesting() const { @@ -1749,12 +1791,21 @@ (*GetWallpaperCacheMap())[account_id] = ash::CustomWallpaperElement(wallpaper_path, gfx::ImageSkia()); } - user_image_loader::StartWithFilePath( - task_runner_, wallpaper_path, ImageDecoder::ROBUST_JPEG_CODEC, - 0, // Do not crop. - base::Bind(&WallpaperManager::OnWallpaperDecoded, - weak_factory_.GetWeakPtr(), account_id, info, update_wallpaper, - base::Passed(std::move(on_finish)))); + + if (!ash::Shell::HasInstance() || ash_util::IsRunningInMash()) { + user_image_loader::StartWithFilePath( + task_runner_, wallpaper_path, ImageDecoder::ROBUST_JPEG_CODEC, + 0, // Do not crop. + base::Bind(&WallpaperManager::OnWallpaperDecoded, + weak_factory_.GetWeakPtr(), account_id, info, + update_wallpaper, base::Passed(std::move(on_finish)))); + } else { + ReadAndDecodeWallpaper( + base::Bind(&WallpaperManager::OnWallpaperDecoded, + weak_factory_.GetWeakPtr(), account_id, info, + update_wallpaper, base::Passed(std::move(on_finish))), + task_runner_, wallpaper_path); + } } void WallpaperManager::SaveLastLoadTime(const base::TimeDelta elapsed) { @@ -1811,13 +1862,21 @@ DCHECK(rescaled_files->downloaded_exists()); // Either resized images do not exist or cached version is incorrect. - // Need to start resize again. - user_image_loader::StartWithFilePath( - task_runner_, file_path, ImageDecoder::ROBUST_JPEG_CODEC, - 0, // Do not crop. - base::Bind(&WallpaperManager::OnCustomizedDefaultWallpaperDecoded, - weak_factory_.GetWeakPtr(), wallpaper_url, - base::Passed(std::move(rescaled_files)))); + // Need to start decoding again. + if (!ash::Shell::HasInstance() || ash_util::IsRunningInMash()) { + user_image_loader::StartWithFilePath( + task_runner_, file_path, ImageDecoder::ROBUST_JPEG_CODEC, + 0, // Do not crop. + base::Bind(&WallpaperManager::OnCustomizedDefaultWallpaperDecoded, + weak_factory_.GetWeakPtr(), wallpaper_url, + base::Passed(std::move(rescaled_files)))); + } else { + ReadAndDecodeWallpaper( + base::Bind(&WallpaperManager::OnCustomizedDefaultWallpaperDecoded, + weak_factory_.GetWeakPtr(), wallpaper_url, + base::Passed(std::move(rescaled_files))), + task_runner_, file_path); + } } else { SetDefaultWallpaperPath(rescaled_files->path_rescaled_small(), std::unique_ptr<gfx::ImageSkia>(), @@ -1918,6 +1977,11 @@ } *result_out = std::move(user_image); + // Make sure the file path is updated. + // TODO(crbug.com/776464): Use |ImageSkia| and |FilePath| directly to cache + // the decoded image and file path. Nothing else in |UserImage| is relevant. + (*result_out)->set_file_path(path); + if (update_wallpaper) { WallpaperInfo info(path.value(), layout, wallpaper::DEFAULT, base::Time::Now().LocalMidnight()); @@ -1931,13 +1995,22 @@ bool update_wallpaper, MovableOnDestroyCallbackHolder on_finish, std::unique_ptr<user_manager::UserImage>* result_out) { - user_image_loader::StartWithFilePath( - task_runner_, path, ImageDecoder::ROBUST_JPEG_CODEC, - 0, // Do not crop. - base::Bind(&WallpaperManager::OnDefaultWallpaperDecoded, - weak_factory_.GetWeakPtr(), path, layout, update_wallpaper, - base::Unretained(result_out), - base::Passed(std::move(on_finish)))); + if (!ash::Shell::HasInstance() || ash_util::IsRunningInMash()) { + user_image_loader::StartWithFilePath( + task_runner_, path, ImageDecoder::ROBUST_JPEG_CODEC, + 0, // Do not crop. + base::Bind(&WallpaperManager::OnDefaultWallpaperDecoded, + weak_factory_.GetWeakPtr(), path, layout, update_wallpaper, + base::Unretained(result_out), + base::Passed(std::move(on_finish)))); + } else { + ReadAndDecodeWallpaper( + base::Bind(&WallpaperManager::OnDefaultWallpaperDecoded, + weak_factory_.GetWeakPtr(), path, layout, update_wallpaper, + base::Unretained(result_out), + base::Passed(std::move(on_finish))), + task_runner_, path); + } } void WallpaperManager::RecordWallpaperAppType() { @@ -2122,12 +2195,20 @@ return; } - user_image_loader::StartWithFilePath( - task_runner_, GetDeviceWallpaperFilePath(), - ImageDecoder::ROBUST_JPEG_CODEC, - 0, // Do not crop. - base::Bind(&WallpaperManager::OnDeviceWallpaperDecoded, - weak_factory_.GetWeakPtr(), account_id)); + const base::FilePath file_path = GetDeviceWallpaperFilePath(); + if (!ash::Shell::HasInstance() || ash_util::IsRunningInMash()) { + user_image_loader::StartWithFilePath( + task_runner_, GetDeviceWallpaperFilePath(), + ImageDecoder::ROBUST_JPEG_CODEC, + 0, // Do not crop. + base::Bind(&WallpaperManager::OnDeviceWallpaperDecoded, + weak_factory_.GetWeakPtr(), account_id)); + } else { + ReadAndDecodeWallpaper( + base::Bind(&WallpaperManager::OnDeviceWallpaperDecoded, + weak_factory_.GetWeakPtr(), account_id), + task_runner_, file_path); + } } void WallpaperManager::OnDeviceWallpaperDecoded(
diff --git a/chrome/browser/resources/cryptotoken/devicestatuscodes.js b/chrome/browser/resources/cryptotoken/devicestatuscodes.js index 165102a..a15acd4 100644 --- a/chrome/browser/resources/cryptotoken/devicestatuscodes.js +++ b/chrome/browser/resources/cryptotoken/devicestatuscodes.js
@@ -45,6 +45,12 @@ DeviceStatusCodes.WRONG_DATA_STATUS = 0x6a80; /** + * Device operation file not found status. + * @const + */ +DeviceStatusCodes.FILE_NOT_FOUND_STATUS = 0x6a82; + +/** * Device operation timeout status. * @const */
diff --git a/chrome/browser/resources/cryptotoken/enroller.js b/chrome/browser/resources/cryptotoken/enroller.js index 94ae1d4..2ddd25c 100644 --- a/chrome/browser/resources/cryptotoken/enroller.js +++ b/chrome/browser/resources/cryptotoken/enroller.js
@@ -539,7 +539,7 @@ * Notifies the caller of success with the provided response data. * @param {string} u2fVersion Protocol version * @param {string} info Response data - * @param {string|undefined} opt_browserData Browser data used + * @param {string=} opt_browserData Browser data used * @private */ Enroller.prototype.notifySuccess_ = function( @@ -562,6 +562,12 @@ console.log(UTIL_fmt( 'helper reported ' + reply.code.toString(16) + ', returning ' + reportedError.errorCode)); + // Log non-expected reply codes if we have url to send them. + if (reportedError.errorCode == ErrorCodes.OTHER_ERROR) { + var logMsg = 'log=u2fenroll&rc=' + reply.code.toString(16); + if (this.logMsgUrl_) + logMessage(logMsg, this.logMsgUrl_); + } this.notifyError_(reportedError); } else { console.log(UTIL_fmt('Gnubby enrollment succeeded!!!!!'));
diff --git a/chrome/browser/resources/cryptotoken/gnubbies.js b/chrome/browser/resources/cryptotoken/gnubbies.js index d6c10791..47ac315 100644 --- a/chrome/browser/resources/cryptotoken/gnubbies.js +++ b/chrome/browser/resources/cryptotoken/gnubbies.js
@@ -170,7 +170,7 @@ } console.log(UTIL_fmt('Enumerated ' + devs.length + ' gnubbies')); - console.log(devs); + console.log(UTIL_fmt(JSON.stringify(devs))); var presentDevs = {}; var deviceIds = [];
diff --git a/chrome/browser/resources/cryptotoken/gnubby.js b/chrome/browser/resources/cryptotoken/gnubby.js index 28910ce..d11df22 100644 --- a/chrome/browser/resources/cryptotoken/gnubby.js +++ b/chrome/browser/resources/cryptotoken/gnubby.js
@@ -66,10 +66,10 @@ /** * Opens the gnubby with the given index, or the first found gnubby if no * index is specified. - * @param {GnubbyDeviceId} which The device to open. If null, the first + * @param {?GnubbyDeviceId} which The device to open. If null, the first * gnubby found is opened. * @param {GnubbyEnumerationTypes=} opt_type Which type of device to enumerate. - * @param {function(number)|undefined} opt_cb Called with result of opening the + * @param {function(number)=} opt_cb Called with result of opening the * gnubby. * @param {string=} opt_caller Identifier for the caller. */ @@ -113,22 +113,23 @@ if (self.closeHook_) { self.dev.setDestroyHook(self.closeHook_); } - cb(rc); + cb.call(self, rc); }); } if (which) { setCid(which); self.which = which; - Gnubby.gnubbies_.addClient(which, self, function(rc, device) { - if (!rc) { - self.dev = device; - if (self.closeHook_) { - self.dev.setDestroyHook(self.closeHook_); - } - } - cb(rc); - }); + Gnubby.gnubbies_.addClient( + /** @type {GnubbyDeviceId} */ (which), self, function(rc, device) { + if (!rc) { + self.dev = device; + if (self.closeHook_) { + self.dev.setDestroyHook(self.closeHook_); + } + } + cb.call(self, rc); + }); } else { Gnubby.gnubbies_.enumerate(enumerated, opt_type); } @@ -139,7 +140,7 @@ * collide within this application, but may when others simultaneously access * the device. * @param {number} gnubbyInstance An instance identifier for a gnubby. - * @param {GnubbyDeviceId} which The device identifer for the gnubby device. + * @param {GnubbyDeviceId} which The device identifier for the gnubby device. * @return {number} The channel id. * @private */ @@ -497,9 +498,8 @@ * @param {ArrayBuffer|Uint8Array} data Command data * @param {number} timeout Timeout in seconds. * @param {function(number, ArrayBuffer=)} cb Callback - * @private */ -Gnubby.prototype.exchange_ = function(cmd, data, timeout, cb) { +Gnubby.prototype.exchange = function(cmd, data, timeout, cb) { var busyWait = new CountdownTimer(Gnubby.SYS_TIMER_, this.busyMillis); var self = this; @@ -742,7 +742,7 @@ var d = new Uint8Array([data]); data = d.buffer; } - this.exchange_(GnubbyDevice.CMD_PROMPT, data, Gnubby.NORMAL_TIMEOUT, cb); + this.exchange(GnubbyDevice.CMD_PROMPT, data, Gnubby.NORMAL_TIMEOUT, cb); }; /** Lock the gnubby @@ -756,7 +756,7 @@ var d = new Uint8Array([data]); data = d.buffer; } - this.exchange_(GnubbyDevice.CMD_LOCK, data, Gnubby.NORMAL_TIMEOUT, cb); + this.exchange(GnubbyDevice.CMD_LOCK, data, Gnubby.NORMAL_TIMEOUT, cb); }; /** Unlock the gnubby @@ -766,7 +766,7 @@ if (!cb) cb = Gnubby.defaultCallback; var data = new Uint8Array([0]); - this.exchange_(GnubbyDevice.CMD_LOCK, data.buffer, Gnubby.NORMAL_TIMEOUT, cb); + this.exchange(GnubbyDevice.CMD_LOCK, data.buffer, Gnubby.NORMAL_TIMEOUT, cb); }; /** Request system information data. @@ -775,7 +775,7 @@ Gnubby.prototype.sysinfo = function(cb) { if (!cb) cb = Gnubby.defaultCallback; - this.exchange_( + this.exchange( GnubbyDevice.CMD_SYSINFO, new ArrayBuffer(0), Gnubby.NORMAL_TIMEOUT, cb); }; @@ -785,7 +785,7 @@ Gnubby.prototype.wink = function(cb) { if (!cb) cb = Gnubby.defaultCallback; - this.exchange_( + this.exchange( GnubbyDevice.CMD_WINK, new ArrayBuffer(0), Gnubby.NORMAL_TIMEOUT, cb); }; @@ -796,7 +796,7 @@ Gnubby.prototype.dfu = function(data, cb) { if (!cb) cb = Gnubby.defaultCallback; - this.exchange_(GnubbyDevice.CMD_DFU, data, Gnubby.NORMAL_TIMEOUT, cb); + this.exchange(GnubbyDevice.CMD_DFU, data, Gnubby.NORMAL_TIMEOUT, cb); }; /** Ping the gnubby @@ -811,7 +811,7 @@ window.crypto.getRandomValues(d); data = d.buffer; } - this.exchange_(GnubbyDevice.CMD_PING, data, Gnubby.NORMAL_TIMEOUT, cb); + this.exchange(GnubbyDevice.CMD_PING, data, Gnubby.NORMAL_TIMEOUT, cb); }; /** Send a raw APDU command @@ -821,7 +821,7 @@ Gnubby.prototype.apdu = function(data, cb) { if (!cb) cb = Gnubby.defaultCallback; - this.exchange_(GnubbyDevice.CMD_APDU, data, Gnubby.MAX_TIMEOUT, cb); + this.exchange(GnubbyDevice.CMD_APDU, data, Gnubby.MAX_TIMEOUT, cb); }; /** Reset gnubby @@ -830,7 +830,7 @@ Gnubby.prototype.reset = function(cb) { if (!cb) cb = Gnubby.defaultCallback; - this.exchange_( + this.exchange( GnubbyDevice.CMD_ATR, new ArrayBuffer(0), Gnubby.MAX_TIMEOUT, cb); }; @@ -845,7 +845,7 @@ if (!cb) cb = Gnubby.defaultCallback; var u8 = new Uint8Array(args); - this.exchange_( + this.exchange( GnubbyDevice.CMD_USB_TEST, u8.buffer, Gnubby.NORMAL_TIMEOUT, cb); };
diff --git a/chrome/browser/resources/cryptotoken/gnubbyfactory.js b/chrome/browser/resources/cryptotoken/gnubbyfactory.js index aca6c6d..780afc3 100644 --- a/chrome/browser/resources/cryptotoken/gnubbyfactory.js +++ b/chrome/browser/resources/cryptotoken/gnubbyfactory.js
@@ -50,3 +50,13 @@ */ GnubbyFactory.prototype.notEnrolledPrerequisiteCheck = function( gnubby, appIdHash, cb) {}; + +/** + * Called immediately after enrolling the gnubby to perform necessary actions. + * @param {Gnubby} gnubby The just-enrolled gnubby. + * @param {string} appIdHash The base64-encoded hash of the app id for which + * the gnubby was enrolled. + * @param {FactoryOpenCallback} cb Called with the result of the action. + * (A non-zero status indicates failure.) + */ +GnubbyFactory.prototype.postEnrollAction = function(gnubby, appIdHash, cb) {};
diff --git a/chrome/browser/resources/cryptotoken/logging.js b/chrome/browser/resources/cryptotoken/logging.js index 07462f8..9054731 100644 --- a/chrome/browser/resources/cryptotoken/logging.js +++ b/chrome/browser/resources/cryptotoken/logging.js
@@ -11,7 +11,7 @@ * @param {string=} opt_logMsgUrl the url to post log messages to. */ function logMessage(logMsg, opt_logMsgUrl) { - console.log(UTIL_fmt('logMessage("' + logMsg + '")')); + console.warn(UTIL_fmt('logMessage("' + logMsg + '")')); if (!opt_logMsgUrl) { return;
diff --git a/chrome/browser/resources/cryptotoken/manifest.json b/chrome/browser/resources/cryptotoken/manifest.json index b0dbce6..62614d2 100644 --- a/chrome/browser/resources/cryptotoken/manifest.json +++ b/chrome/browser/resources/cryptotoken/manifest.json
@@ -1,7 +1,7 @@ { "name": "CryptoTokenExtension", "description": "CryptoToken Component Extension", - "version": "0.9.46", + "version": "0.9.71", "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq7zRobvA+AVlvNqkHSSVhh1sEWsHSqz4oR/XptkDe/Cz3+gW9ZGumZ20NCHjaac8j1iiesdigp8B1LJsd/2WWv2Dbnto4f8GrQ5MVphKyQ9WJHwejEHN2K4vzrTcwaXqv5BSTXwxlxS/mXCmXskTfryKTLuYrcHEWK8fCHb+0gvr8b/kvsi75A1aMmb6nUnFJvETmCkOCPNX5CHTdy634Ts/x0fLhRuPlahk63rdf7agxQv5viVjQFk+tbgv6aa9kdSd11Js/RZ9yZjrFgHOBWgP4jTBqud4+HUglrzu8qynFipyNRLCZsaxhm+NItTyNgesxLdxZcwOz56KD1Q4IQIDAQAB", "manifest_version": 2, "permissions": [
diff --git a/chrome/browser/resources/cryptotoken/multiplesigner.js b/chrome/browser/resources/cryptotoken/multiplesigner.js index 1fa9903..748f404 100644 --- a/chrome/browser/resources/cryptotoken/multiplesigner.js +++ b/chrome/browser/resources/cryptotoken/multiplesigner.js
@@ -52,7 +52,7 @@ /** @private {string|undefined} */ this.logMsgUrl_ = opt_logMsgUrl; - /** @private {Array<SignHelperChallenge>} */ + /** @private {Array<DecodedSignHelperChallenge>} */ this.challenges_ = []; /** @private {boolean} */ this.challengesSet_ = false; @@ -107,12 +107,12 @@ if (challenges) { for (var i = 0; i < challenges.length; i++) { - var decodedChallenge = {}; var challenge = challenges[i]; - decodedChallenge['challengeHash'] = - B64_decode(challenge['challengeHash']); - decodedChallenge['appIdHash'] = B64_decode(challenge['appIdHash']); - decodedChallenge['keyHandle'] = B64_decode(challenge['keyHandle']); + var decodedChallenge = { + challengeHash: B64_decode(challenge['challengeHash']), + appIdHash: B64_decode(challenge['appIdHash']), + keyHandle: B64_decode(challenge['keyHandle']) + }; if (challenge['version']) { decodedChallenge['version'] = challenge['version']; }
diff --git a/chrome/browser/resources/cryptotoken/requestqueue.js b/chrome/browser/resources/cryptotoken/requestqueue.js index 356a777..d283ad8 100644 --- a/chrome/browser/resources/cryptotoken/requestqueue.js +++ b/chrome/browser/resources/cryptotoken/requestqueue.js
@@ -33,8 +33,10 @@ this.queue_ = queue; /** @private {number} */ this.id_ = id; - /** @type {function(QueuedRequestToken)} */ - this.beginCb = beginCb; + /** @private {boolean} */ + this.begun_ = false; + /** @private {function(QueuedRequestToken)} */ + this.beginCb_ = beginCb; /** @type {RequestToken} */ this.prev = null; /** @type {RequestToken} */ @@ -43,6 +45,17 @@ this.completed_ = false; } +/** Begins work on this queued request. */ +RequestToken.prototype.begin = function() { + this.begun_ = true; + this.beginCb_(this); +}; + +/** @return {boolean} Whether this token has already begun. */ +RequestToken.prototype.begun = function() { + return this.begun_; +}; + /** Completes (or cancels) this queued request. */ RequestToken.prototype.complete = function() { if (this.completed_) { @@ -59,6 +72,12 @@ return this.completed_; }; +/** @return {number} This token's id. */ +RequestToken.prototype.id = function() { + return this.id_; +}; + + /** * @param {!SystemTimer} sysTimer A system timer implementation. * @constructor @@ -96,15 +115,32 @@ /** * Removes this token from the queue. * @param {RequestToken} token Queue token + * @return {RequestToken?} The next token in the queue to run, if any. * @private */ RequestQueue.prototype.removeToken_ = function(token) { + var nextTokenToRun = null; + // If this token has been begun, find the next token to run. + if (token.begun()) { + // Find the first token in the queue which has not yet been begun, and which + // is not the token being removed. + for (var nextToken = this.head_; nextToken; nextToken = nextToken.next) { + if (nextToken !== token && !nextToken.begun()) { + nextTokenToRun = nextToken; + break; + } + } + } + + // Remove this token from the queue if (token.next) { token.next.prev = token.prev; } if (token.prev) { token.prev.next = token.next; } + + // Update head and tail of queue. if (this.head_ === token && this.tail_ === token) { this.head_ = this.tail_ = null; } else { @@ -117,7 +153,12 @@ this.tail_.next = null; } } + + // Isolate this token to prevent it from manipulating the queue, e.g. if + // complete() is called a second time with it. token.prev = token.next = null; + + return nextTokenToRun; }; /** @@ -126,11 +167,16 @@ * @param {RequestToken} token Queue token */ RequestQueue.prototype.complete = function(token) { - console.log(UTIL_fmt('token ' + this.id_ + ' completed')); - var next = token.next; - this.removeToken_(token); + var next = this.removeToken_(token); if (next) { - next.beginCb(next); + console.log( + UTIL_fmt('token ' + token.id() + ' completed, starting ' + next.id())); + next.begin(); + } else if (this.empty()) { + console.log(UTIL_fmt('token ' + token.id() + ' completed, queue empty')); + } else { + console.log(UTIL_fmt( + 'token ' + token.id() + ' completed (earlier token still running)')); } }; @@ -156,7 +202,7 @@ if (startNow) { this.sysTimer_.setTimeout(function() { if (!token.completed()) { - token.beginCb(token); + token.begin(); } }, 0); }
diff --git a/chrome/browser/resources/cryptotoken/signer.js b/chrome/browser/resources/cryptotoken/signer.js index 5a887719..8c8352f 100644 --- a/chrome/browser/resources/cryptotoken/signer.js +++ b/chrome/browser/resources/cryptotoken/signer.js
@@ -11,6 +11,9 @@ var gnubbySignRequestQueue; +/** + * Initialize request queue. + */ function initRequestQueue() { gnubbySignRequestQueue = new OriginKeyedRequestQueue(FACTORY_REGISTRY.getSystemTimer()); @@ -177,10 +180,10 @@ * @param {WebRequestSender} sender Message sender. * @param {function(U2fError)} errorCb Error callback * @param {function(SignChallenge, string, string)} successCb Success callback - * @param {string|undefined} opt_defaultChallenge A default sign challenge + * @param {string=} opt_defaultChallenge A default sign challenge * value, if a request does not provide one. - * @param {string|undefined} opt_appId The app id for the entire request. - * @param {string|undefined} opt_logMsgUrl Url to post log messages to + * @param {string=} opt_appId The app id for the entire request. + * @param {string=} opt_logMsgUrl Url to post log messages to * @constructor * @implements {Closeable} */ @@ -538,6 +541,12 @@ console.log(UTIL_fmt( 'helper reported ' + reply.code.toString(16) + ', returning ' + reportedError.errorCode)); + // Log non-expected reply codes if we have an url to send them + if (reportedError.errorCode == ErrorCodes.OTHER_ERROR) { + var logMsg = 'log=u2fsign&rc=' + reply.code.toString(16); + if (this.logMsgUrl_) + logMessage(logMsg, this.logMsgUrl_); + } this.notifyError_(reportedError); } else { if (this.logMsgUrl_ && opt_source) {
diff --git a/chrome/browser/resources/cryptotoken/singlesigner.js b/chrome/browser/resources/cryptotoken/singlesigner.js index f9e46f0..e39e4008 100644 --- a/chrome/browser/resources/cryptotoken/singlesigner.js +++ b/chrome/browser/resources/cryptotoken/singlesigner.js
@@ -13,9 +13,19 @@ /** * @typedef {{ + * challengeHash: Array<number>, + * appIdHash: Array<number>, + * keyHandle: Array<number>, + * version: (string|undefined) + * }} + */ +var DecodedSignHelperChallenge; + +/** + * @typedef {{ * code: number, * gnubby: (Gnubby|undefined), - * challenge: (SignHelperChallenge|undefined), + * challenge: (DecodedSignHelperChallenge|undefined), * info: (ArrayBuffer|undefined) * }} */ @@ -65,14 +75,14 @@ /** @private {string|undefined} */ this.logMsgUrl_ = opt_logMsgUrl; - /** @private {!Array<!SignHelperChallenge>} */ + /** @private {!Array<!DecodedSignHelperChallenge>} */ this.challenges_ = []; /** @private {number} */ this.challengeIndex_ = 0; /** @private {boolean} */ this.challengesSet_ = false; - /** @private {!Object<string, number>} */ + /** @private {!Object<Array<number>, number>} */ this.cachedError_ = []; /** @private {(function()|undefined)} */ @@ -132,7 +142,7 @@ /** * Begins signing the given challenges. - * @param {Array<SignHelperChallenge>} challenges The challenges to sign. + * @param {Array<DecodedSignHelperChallenge>} challenges The challenges to sign. * @return {boolean} Whether the challenges were accepted. */ SingleGnubbySigner.prototype.doSign = function(challenges) { @@ -481,7 +491,7 @@ /** * Switches to the success state, and notifies caller. * @param {number} code Status code - * @param {SignHelperChallenge=} opt_challenge The challenge signed + * @param {DecodedSignHelperChallenge=} opt_challenge The challenge signed * @param {ArrayBuffer=} opt_info Optional result data * @private */
diff --git a/chrome/browser/resources/cryptotoken/usbenrollhandler.js b/chrome/browser/resources/cryptotoken/usbenrollhandler.js index e9bdcc11..2d53b07 100644 --- a/chrome/browser/resources/cryptotoken/usbenrollhandler.js +++ b/chrome/browser/resources/cryptotoken/usbenrollhandler.js
@@ -284,8 +284,16 @@ break; case DeviceStatusCodes.OK_STATUS: - var info = B64_encode(new Uint8Array(infoArray || [])); - this.notifySuccess_(version, info); + var appIdHash = this.request_.enrollChallenges[0].appIdHash; + DEVICE_FACTORY_REGISTRY.getGnubbyFactory().postEnrollAction( + gnubby, appIdHash, (rc) => { + if (rc == DeviceStatusCodes.OK_STATUS) { + var info = B64_encode(new Uint8Array(infoArray || [])); + this.notifySuccess_(version, info); + } else { + this.notifyError_(rc); + } + }); break; default:
diff --git a/chrome/browser/resources/cryptotoken/usbgnubbydevice.js b/chrome/browser/resources/cryptotoken/usbgnubbydevice.js index aeaaf85d..ec100c2 100644 --- a/chrome/browser/resources/cryptotoken/usbgnubbydevice.js +++ b/chrome/browser/resources/cryptotoken/usbgnubbydevice.js
@@ -198,7 +198,7 @@ }, 0); } else { console.log(UTIL_fmt('no x.data!')); - console.log(x); + console.log(UTIL_fmt(JSON.stringify(x))); window.setTimeout(function() { self.destroy(); }, 0);
diff --git a/chrome/browser/resources/cryptotoken/usbgnubbyfactory.js b/chrome/browser/resources/cryptotoken/usbgnubbyfactory.js index dd35395..f797c6e 100644 --- a/chrome/browser/resources/cryptotoken/usbgnubbyfactory.js +++ b/chrome/browser/resources/cryptotoken/usbgnubbyfactory.js
@@ -65,3 +65,15 @@ gnubby, appIdHash, cb) { cb(DeviceStatusCodes.OK_STATUS, gnubby); }; + +/** + * No-op post enroll action. + * @param {Gnubby} gnubby The just-enrolled gnubby. + * @param {string} appIdHash The base64-encoded hash of the app id for which + * the gnubby was enrolled. + * @param {FactoryOpenCallback} cb Called with the result of the action. + * (A non-zero status indicates failure.) + */ +UsbGnubbyFactory.prototype.postEnrollAction = function(gnubby, appIdHash, cb) { + cb(DeviceStatusCodes.OK_STATUS, gnubby); +};
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index fac743cf..1fc58af 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -175,6 +175,8 @@ self.Fail('conformance2/textures/canvas_sub_rectangle/' + 'tex-2d-r16f-red-float.html', ['win', 'nvidia', 'opengl'], bug=786716) + self.Fail('conformance2/rendering/instanced-rendering-bug.html', + ['win', 'nvidia', 'opengl'], bug=791289) # Win / AMD self.Fail('conformance2/rendering/blitframebuffer-stencil-only.html',