Commit 6e639979 authored by Luciano Pacheco's avatar Luciano Pacheco Committed by Commit Bot

Files app: Refactor AppWindowWrapper to use async and await

Change AppWindowWrapper.launch() to be an async function and to use
await when waiting for asynchronous APIs.

This allows to change the task queue from running the calls to async
APIs to only be used as a lock to synchronize these async calls between
AppWindowWrapper.launch() and SingletonAppWindowWrapper.launch().

Bug: 1067478
Change-Id: I04ab4caec274c48e9661d577970b8a09c173d866
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2143187
Commit-Queue: Luciano Pacheco <lucmult@chromium.org>
Reviewed-by: default avatarAlex Danilo <adanilo@chromium.org>
Reviewed-by: default avatarNoel Gordon <noel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#759510}
parent 325bfa42
...@@ -31,7 +31,7 @@ class AppWindowWrapper { ...@@ -31,7 +31,7 @@ class AppWindowWrapper {
this.openingOrOpened_ = false; this.openingOrOpened_ = false;
/** @protected {AsyncUtil.Queue} */ /** @protected {AsyncUtil.Queue} */
this.queue = new AsyncUtil.Queue(); this.queue_ = new AsyncUtil.Queue();
} }
/** /**
...@@ -49,6 +49,17 @@ class AppWindowWrapper { ...@@ -49,6 +49,17 @@ class AppWindowWrapper {
this.window_.setIcon(iconPath); this.window_.setIcon(iconPath);
} }
/**
* Gets the launch lock, used to synchronize the asynchronous initialization
* steps.
*
* @return {Promise<function()>} A function to be called to release the lock.
*/
async getLaunchLock() {
return this.queue_.lock();
}
/** /**
* @param {Array<chrome.app.window.AppWindow>} similarWindows * @param {Array<chrome.app.window.AppWindow>} similarWindows
* @return {!Promise} * @return {!Promise}
...@@ -104,8 +115,7 @@ class AppWindowWrapper { ...@@ -104,8 +115,7 @@ class AppWindowWrapper {
chrome.app.window.create(this.url_, this.options_, appWindow => { chrome.app.window.create(this.url_, this.options_, appWindow => {
this.window_ = appWindow; this.window_ = appWindow;
if (!appWindow) { if (!appWindow) {
console.error(`Failed to create window for ${this.url_}`); throw new Error(`Failed to create window for ${this.url_}`);
return resolve(null);
} }
// Save the properties. // Save the properties.
...@@ -170,7 +180,7 @@ class AppWindowWrapper { ...@@ -170,7 +180,7 @@ class AppWindowWrapper {
* False otherwise. * False otherwise.
* @param {function()=} opt_callback Completion callback. * @param {function()=} opt_callback Completion callback.
*/ */
launch(appState, reopen, opt_callback) { async launch(appState, reopen, opt_callback) {
// Check if the window is opened or not. // Check if the window is opened or not.
if (this.openingOrOpened_) { if (this.openingOrOpened_) {
console.error('The window is already opened.'); console.error('The window is already opened.');
...@@ -188,74 +198,50 @@ class AppWindowWrapper { ...@@ -188,74 +198,50 @@ class AppWindowWrapper {
// main windows of the Files app. // main windows of the Files app.
const similarWindows = window.getSimilarWindows(this.url_); const similarWindows = window.getSimilarWindows(this.url_);
// Restore maximized windows, to avoid hiding them to tray, which can be const unlock = await this.getLaunchLock();
// confusing for users. try {
this.queue.run(callback => { // Restore maximized windows, to avoid hiding them to tray, which can be
this.restoreMaximizedWindow_(similarWindows).then(callback); // confusing for users.
}); await this.restoreMaximizedWindow_(similarWindows);
// Obtains the last geometry and window state (maximized or not).
this.queue.run(callback => {
this.getWindowPreferences_().then(prefs => {
// Overwrite maximized state with remembered last window state.
if (prefs.isMaximized !== undefined) {
this.options_.state = prefs.isMaximized ? 'maximized' : undefined;
}
// Apply the last bounds.
if (prefs.lastBounds) {
this.options_.bounds = prefs.lastBounds;
}
callback();
});
});
// Closure creating the window, once all preprocessing tasks are finished. // Obtains the last geometry and window state (maximized or not).
this.queue.run(callback => { const prefs = await this.getWindowPreferences_();
this.createWindow_(reopen).then(appWindow => { if (prefs.isMaximized !== undefined) {
if (!appWindow) { this.options_.state = prefs.isMaximized ? 'maximized' : undefined;
opt_callback && opt_callback(); }
callback(); if (prefs.lastBounds) {
return; this.options_.bounds = prefs.lastBounds;
} }
// Exit full screen state if it's created as a full screen window.
if (appWindow.isFullscreen()) {
appWindow.restore();
}
// This is a temporary workaround for crbug.com/452737. // Closure creating the window, once all preprocessing tasks are finished.
// {state: 'maximized'} in CreateWindowOptions is ignored when a window const appWindow = await this.createWindow_(reopen);
// is launched with hidden option, so we maximize the window manually
// here.
if (this.options_.hidden && this.options_.state === 'maximized') {
appWindow.maximize();
}
callback(); // Exit full screen state if it's created as a full screen window.
}); if (appWindow.isFullscreen()) {
}); appWindow.restore();
}
// After creating. // This is a temporary workaround for crbug.com/452737.
this.queue.run(callback => { // {state: 'maximized'} in CreateWindowOptions is ignored when a window is
if (!this.window_) { // launched with hidden option, so we maximize the window manually here.
opt_callback && opt_callback(); if (this.options_.hidden && this.options_.state === 'maximized') {
callback(); appWindow.maximize();
} }
this.positionWindow_(this.window_, similarWindows); this.positionWindow_(appWindow, similarWindows);
// Register event listeners. // Register event listeners.
this.window_.onBoundsChanged.addListener( appWindow.onBoundsChanged.addListener(this.onBoundsChanged_.bind(this));
this.onBoundsChanged_.bind(this)); appWindow.onClosed.addListener(this.onClosed_.bind(this));
this.window_.onClosed.addListener(this.onClosed_.bind(this)); } catch (error) {
console.error(error);
} finally {
unlock();
}
// Callback. if (opt_callback) {
if (opt_callback) { opt_callback();
opt_callback(); }
}
callback();
});
} }
/** /**
...@@ -353,17 +339,18 @@ class SingletonAppWindowWrapper extends AppWindowWrapper { ...@@ -353,17 +339,18 @@ class SingletonAppWindowWrapper extends AppWindowWrapper {
* False otherwise. * False otherwise.
* @param {function()=} opt_callback Completion callback. * @param {function()=} opt_callback Completion callback.
*/ */
launch(appState, reopen, opt_callback) { async launch(appState, reopen, opt_callback) {
// If the window is not opened yet, just call the parent method. // If the window is not opened yet, just call the parent method.
if (!this.openingOrOpened_) { if (!this.openingOrOpened_) {
AppWindowWrapper.prototype.launch.call( return super.launch(appState, reopen, opt_callback);
this, appState, reopen, opt_callback);
return;
} }
// If the window is already opened, reload the window. // The lock is used to wait until the window is opened and set in
// The queue is used to wait until the window is opened. // this.window_.
this.queue.run(nextStep => { const unlock = await this.getLaunchLock();
try {
// If the window is already opened, reload the window.
this.window_.contentWindow.appState = appState; this.window_.contentWindow.appState = appState;
this.window_.contentWindow.appReopen = reopen; this.window_.contentWindow.appReopen = reopen;
if (!this.window_.contentWindow.reload) { if (!this.window_.contentWindow.reload) {
...@@ -375,11 +362,13 @@ class SingletonAppWindowWrapper extends AppWindowWrapper { ...@@ -375,11 +362,13 @@ class SingletonAppWindowWrapper extends AppWindowWrapper {
} else { } else {
this.window_.contentWindow.reload(); this.window_.contentWindow.reload();
} }
if (opt_callback) { if (opt_callback) {
opt_callback(); opt_callback();
} }
nextStep(); } finally {
}); unlock();
}
} }
/** /**
......
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