Skip to content

Commit

Permalink
Bug 1868410 - MSIX set to default browser takes too long r=nalexander…
Browse files Browse the repository at this point in the history
…,nrishel

This fix addresses cleanup work from https://phabricator.services.mozilla.com/D194828
It also makes it so that all file/protocol handlers get set with one launch of Powershell, to speed things up. Which it does. A lot.

It also:
* makes somethings use of nsString (where it was easy to do)
* moves the thread managing code out of SetDefaultBrowser.cpp and into DefaultAgent.cpp
* puts auto in a couple of places to make the code easier to read
* removes some logging statements in the powershell script code

Differential Revision: https://phabricator.services.mozilla.com/D195839
  • Loading branch information
mhughes-mozilla committed Dec 13, 2023
1 parent baa791e commit 92a4711
Show file tree
Hide file tree
Showing 5 changed files with 405 additions and 222 deletions.
15 changes: 15 additions & 0 deletions browser/components/shell/WindowsUserChoice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,21 @@ UniquePtr<wchar_t[]> GetAssociationKeyPath(const wchar_t* aExt) {
return keyPath;
}

nsresult AppendAssociationKeyPath(const wchar_t* aExt, nsString& output) {
if (aExt[0] == L'.') {
output.AppendLiteral(
u"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\");
} else {
output.AppendLiteral(
u"SOFTWARE\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations"
u"\\");
}

output.Append(aExt);

return NS_OK;
}

UniquePtr<wchar_t[]> GenerateUserChoiceHash(const wchar_t* aExt,
const wchar_t* aUserSid,
const wchar_t* aProgId,
Expand Down
9 changes: 9 additions & 0 deletions browser/components/shell/WindowsUserChoice.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "ErrorList.h" // for nsresult
#include "mozilla/UniquePtr.h"
#include "nsString.h"

/*
* Check the UserChoice Hashes for https, http, .html, .htm
Expand Down Expand Up @@ -60,6 +61,14 @@ CheckUserChoiceHashResult CheckUserChoiceHash(const wchar_t* aExt,
*/
mozilla::UniquePtr<wchar_t[]> GetAssociationKeyPath(const wchar_t* aExt);

/*
* Appends the registry path for the given association, file extension or
* protocol to the parameter string.
*
* @return The path, or nullptr on failure.
*/
nsresult AppendAssociationKeyPath(const wchar_t* aExt, nsString& output);

/*
* Get the current user's SID
*
Expand Down
37 changes: 27 additions & 10 deletions toolkit/mozapps/defaultagent/DefaultAgent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ NS_IMETHODIMP
DefaultAgent::SetDefaultBrowserUserChoiceAsync(
const nsAString& aAumid, const nsTArray<nsString>& aExtraFileExtensions,
JSContext* aCx, dom::Promise** aPromise) {
if (!NS_IsMainThread()) {
return NS_ERROR_NOT_SAME_THREAD;
}

ErrorResult rv;
RefPtr<dom::Promise> promise =
dom::Promise::Create(xpc::CurrentNativeGlobal(aCx), rv);
Expand All @@ -382,16 +386,29 @@ DefaultAgent::SetDefaultBrowserUserChoiceAsync(
auto promiseHolder = MakeRefPtr<nsMainThreadPtrHolder<dom::Promise>>(
"SetDefaultBrowserUserChoiceAsync promise", promise);

auto result = default_agent::SetDefaultBrowserUserChoiceAsync(
PromiseFlatString(aAumid).get(), aExtraFileExtensions,
[promiseHolder = std::move(promiseHolder)](nsresult result) {
dom::Promise* promise = promiseHolder.get()->get();
if (NS_SUCCEEDED(result)) {
promise->MaybeResolveWithUndefined();
} else {
promise->MaybeReject(result);
}
});
nsresult result = NS_DispatchBackgroundTask(
NS_NewRunnableFunction(
"SetDefaultBrowserUserChoiceAsync",
// Make a local copy of the aAudmid parameter which is a reference
// which will go out of scope
[aumid = nsString(aAumid), promiseHolder = std::move(promiseHolder),
aExtraFileExtensions =
CopyableTArray<nsString>(aExtraFileExtensions)] {
nsresult rv = default_agent::SetDefaultBrowserUserChoice(
PromiseFlatString(aumid).get(), aExtraFileExtensions);

NS_DispatchToMainThread(NS_NewRunnableFunction(
"SetDefaultBrowserUserChoiceAsync callback",
[rv, promiseHolder = std::move(promiseHolder)] {
dom::Promise* promise = promiseHolder.get()->get();
if (NS_SUCCEEDED(rv)) {
promise->MaybeResolveWithUndefined();
} else {
promise->MaybeReject(rv);
}
}));
}),
NS_DISPATCH_EVENT_MAY_BLOCK);

promise.forget(aPromise);
return result;
Expand Down
Loading

0 comments on commit 92a4711

Please sign in to comment.