/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim:expandtab:shiftwidth=2:tabstop=2:cin: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// XXX why does nsMIMEInfoImpl have a threadsafe nsISupports? do we need one // here too?
NS_IMPL_ISUPPORTS(nsLocalHandlerApp, nsILocalHandlerApp, nsIHandlerApp)
NS_IMETHODIMP nsLocalHandlerApp::GetName(nsAString& aName) { if (mName.IsEmpty() && mExecutable) { // Don't want to cache this, just in case someone resets the app // without changing the description....
mExecutable->GetLeafName(aName);
} else {
aName.Assign(mName);
}
return NS_OK;
}
/** * This method returns a std::function that will be executed on a thread other * than the main thread. To facilitate things, it should effectively be a global * function that does not maintain a reference to the this pointer. There should * be no reference to any objects that will be shared across threads. Sub-class * implementations should make local copies of everything they need and capture * those in the callback.
*/
std::function<nsresult(nsString&)>
nsLocalHandlerApp::GetPrettyNameOnNonMainThreadCallback() {
nsString name;
// Calculate the name now, on the main thread, so as to avoid // doing anything with the this pointer on the other thread auto result = GetName(name);
nsAutoString executablePath;
nsresult result = mExecutable->GetPath(executablePath);
if (NS_FAILED(result) || executablePath.IsEmpty()) {
(*aPromise)->MaybeReject(result); return NS_OK;
}
nsMainThreadPtrHandle<dom::Promise> promiseHolder( new nsMainThreadPtrHolder<dom::Promise>( "nsLocalHandlerApp::prettyExecutableName Promise", *aPromise));
auto prettyNameGetter = GetPrettyNameOnNonMainThreadCallback();
result = NS_DispatchBackgroundTask(
NS_NewRunnableFunction(
__func__,
[promiseHolder /* can't move this because if the dispatch fails, we
call reject on the promiseHolder */
,
prettyNameGetter = std::move(prettyNameGetter)]() mutable -> void {
nsAutoString prettyExecutableName;
nsresult result = prettyNameGetter(prettyExecutableName);
// If the handler app isn't a local handler app, then it's not the same app.
nsCOMPtr<nsILocalHandlerApp> localHandlerApp = do_QueryInterface(aHandlerApp); if (!localHandlerApp) return NS_OK;
// If either handler app doesn't have an executable, then they aren't // the same app.
nsCOMPtr<nsIFile> executable;
nsresult rv = localHandlerApp->GetExecutable(getter_AddRefs(executable)); if (NS_FAILED(rv)) return rv;
// Equality for two empty nsIHandlerApp if (!executable && !mExecutable) {
*_retval = true; return NS_OK;
}
// At least one is set so they are not equal if (!mExecutable || !executable) return NS_OK;
// Check the command line parameter list lengths
uint32_t len;
localHandlerApp->GetParameterCount(&len); if (mParameters.Length() != len) return NS_OK;
// Check the command line params lists for (uint32_t idx = 0; idx < mParameters.Length(); idx++) {
nsAutoString param; if (NS_FAILED(localHandlerApp->GetParameter(idx, param)) ||
!param.Equals(mParameters[idx])) return NS_OK;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.