Skip to content

Commit

Permalink
Bug 1869417 - Trim included CPP in `toolkit/mozapps/defaultagent/prox…
Browse files Browse the repository at this point in the history
…y`. r=mhughes,nshukla

By splitting `ScheduledTask.cpp`, the proxy can include less CPP code.
In turn, this makes it easier to depend on Gecko in `toolkit/mozapps/defaultagent`.

Differential Revision: https://phabricator.services.mozilla.com/D196119
  • Loading branch information
ncalexan committed Dec 13, 2023
1 parent 16a289d commit 65ee268
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 130 deletions.
1 change: 1 addition & 0 deletions toolkit/mozapps/defaultagent/DefaultAgent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "Policy.h"
#include "Registry.h"
#include "ScheduledTask.h"
#include "ScheduledTaskRemove.h"
#include "SetDefaultBrowser.h"
#include "Telemetry.h"
#include "xpcpublic.h"
Expand Down
123 changes: 5 additions & 118 deletions toolkit/mozapps/defaultagent/ScheduledTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "ScheduledTask.h"
#include "ScheduledTaskRemove.h"

#include <string>
#include <time.h>
Expand All @@ -23,20 +24,14 @@

#include "DefaultBrowser.h"

#ifdef IMPL_LIBXUL
# include "mozilla/ErrorResult.h"
# include "mozilla/intl/Localization.h"
# include "nsString.h"
# include "nsTArray.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/intl/Localization.h"
#include "nsString.h"
#include "nsTArray.h"
using mozilla::intl::Localization;
#endif

namespace mozilla::default_agent {

const wchar_t* kTaskVendor = L"" MOZ_APP_VENDOR;
// kTaskName should have the unique token appended before being used.
const wchar_t* kTaskName = L"" MOZ_APP_DISPLAYNAME " Default Browser Agent ";

// The task scheduler requires its time values to come in the form of a string
// in the format YYYY-MM-DDTHH:MM:SSZ. This format string is used to get that
// out of the C library wcsftime function.
Expand All @@ -51,19 +46,13 @@ const size_t kTimeStrMaxLen = 20;
return hr; \
}

struct SysFreeStringDeleter {
void operator()(BSTR aPtr) { ::SysFreeString(aPtr); }
};
using BStrPtr = mozilla::UniquePtr<OLECHAR, SysFreeStringDeleter>;

bool GetTaskDescription(mozilla::UniquePtr<wchar_t[]>& description) {
mozilla::UniquePtr<wchar_t[]> installPath;
bool success = GetInstallDirectory(installPath);
if (!success) {
LOG_ERROR_MESSAGE(L"Failed to get install directory");
return false;
}
#ifdef IMPL_LIBXUL
nsTArray<nsCString> resIds = {"branding/brand.ftl"_ns,
"browser/backgroundtasks/defaultagent.ftl"_ns};
RefPtr<Localization> l10n = Localization::Create(resIds, true);
Expand All @@ -78,7 +67,6 @@ bool GetTaskDescription(mozilla::UniquePtr<wchar_t[]>& description) {
NS_ConvertUTF8toUTF16 daTaskDescW(daTaskDesc);
description = mozilla::MakeUnique<wchar_t[]>(daTaskDescW.Length() + 1);
wcsncpy(description.get(), daTaskDescW.get(), daTaskDescW.Length() + 1);
#endif
return true;
}

Expand Down Expand Up @@ -337,105 +325,4 @@ HRESULT UpdateTask(const wchar_t* uniqueToken) {
return RegisterTask(uniqueToken, startTime.get());
}

bool EndsWith(const wchar_t* string, const wchar_t* suffix) {
size_t string_len = wcslen(string);
size_t suffix_len = wcslen(suffix);
if (suffix_len > string_len) {
return false;
}
const wchar_t* substring = string + string_len - suffix_len;
return wcscmp(substring, suffix) == 0;
}

HRESULT RemoveTasks(const wchar_t* uniqueToken, WhichTasks tasksToRemove) {
if (!uniqueToken || wcslen(uniqueToken) == 0) {
return E_INVALIDARG;
}

RefPtr<ITaskService> scheduler;
HRESULT hr = S_OK;
ENSURE(CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER,
IID_ITaskService, getter_AddRefs(scheduler)));

ENSURE(scheduler->Connect(VARIANT{}, VARIANT{}, VARIANT{}, VARIANT{}));

RefPtr<ITaskFolder> taskFolder;
BStrPtr folderBStr(SysAllocString(kTaskVendor));

hr = scheduler->GetFolder(folderBStr.get(), getter_AddRefs(taskFolder));
if (FAILED(hr)) {
if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) {
// Don't return an error code if our folder doesn't exist,
// because that just means it's been removed already.
return S_OK;
} else {
return hr;
}
}

RefPtr<IRegisteredTaskCollection> tasksInFolder;
ENSURE(taskFolder->GetTasks(TASK_ENUM_HIDDEN, getter_AddRefs(tasksInFolder)));

LONG numTasks = 0;
ENSURE(tasksInFolder->get_Count(&numTasks));

std::wstring WdbaTaskName(kTaskName);
WdbaTaskName += uniqueToken;

// This will be set to the last error that we encounter while deleting tasks.
// This allows us to keep attempting to remove the remaining tasks, even if
// we encounter an error, while still preserving what error we encountered so
// we can return it from this function.
HRESULT deleteResult = S_OK;
// Set to true if we intentionally skip any tasks.
bool tasksSkipped = false;

for (LONG i = 0; i < numTasks; ++i) {
RefPtr<IRegisteredTask> task;
// IRegisteredTaskCollection's are 1-indexed.
hr = tasksInFolder->get_Item(_variant_t(i + 1), getter_AddRefs(task));
if (FAILED(hr)) {
deleteResult = hr;
continue;
}

BSTR taskName;
hr = task->get_Name(&taskName);
if (FAILED(hr)) {
deleteResult = hr;
continue;
}
// Automatically free taskName when we are done with it.
BStrPtr uniqueTaskName(taskName);

if (tasksToRemove == WhichTasks::WdbaTaskOnly) {
if (WdbaTaskName.compare(taskName) != 0) {
tasksSkipped = true;
continue;
}
} else { // tasksToRemove == WhichTasks::AllTasksForInstallation
if (!EndsWith(taskName, uniqueToken)) {
tasksSkipped = true;
continue;
}
}

hr = taskFolder->DeleteTask(taskName, 0 /* flags */);
if (FAILED(hr)) {
deleteResult = hr;
}
}

// If we successfully removed all the tasks, delete the folder too.
if (!tasksSkipped && SUCCEEDED(deleteResult)) {
RefPtr<ITaskFolder> rootFolder;
BStrPtr rootFolderBStr = BStrPtr(SysAllocString(L"\\"));
ENSURE(
scheduler->GetFolder(rootFolderBStr.get(), getter_AddRefs(rootFolder)));
ENSURE(rootFolder->DeleteFolder(folderBStr.get(), 0));
}

return deleteResult;
}

} // namespace mozilla::default_agent
6 changes: 0 additions & 6 deletions toolkit/mozapps/defaultagent/ScheduledTask.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@ namespace mozilla::default_agent {
HRESULT RegisterTask(const wchar_t* uniqueToken, BSTR startTime = nullptr);
HRESULT UpdateTask(const wchar_t* uniqueToken);

enum class WhichTasks {
WdbaTaskOnly,
AllTasksForInstallation,
};
HRESULT RemoveTasks(const wchar_t* uniqueToken, WhichTasks tasksToRemove);

} // namespace mozilla::default_agent

#endif // __DEFAULT_BROWSER_AGENT_SCHEDULED_TASK_H__
126 changes: 126 additions & 0 deletions toolkit/mozapps/defaultagent/ScheduledTaskRemove.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */

#include "ScheduledTaskRemove.h"

#include <string>

#include <comutil.h>
#include <taskschd.h>

#include "EventLog.h"
#include "mozilla/RefPtr.h"

namespace mozilla::default_agent {

#define ENSURE(x) \
if (FAILED(hr = (x))) { \
LOG_ERROR(hr); \
return hr; \
}

bool EndsWith(const wchar_t* string, const wchar_t* suffix) {
size_t string_len = wcslen(string);
size_t suffix_len = wcslen(suffix);
if (suffix_len > string_len) {
return false;
}
const wchar_t* substring = string + string_len - suffix_len;
return wcscmp(substring, suffix) == 0;
}

HRESULT RemoveTasks(const wchar_t* uniqueToken, WhichTasks tasksToRemove) {
if (!uniqueToken || wcslen(uniqueToken) == 0) {
return E_INVALIDARG;
}

RefPtr<ITaskService> scheduler;
HRESULT hr = S_OK;
ENSURE(CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER,
IID_ITaskService, getter_AddRefs(scheduler)));

ENSURE(scheduler->Connect(VARIANT{}, VARIANT{}, VARIANT{}, VARIANT{}));

RefPtr<ITaskFolder> taskFolder;
BStrPtr folderBStr(SysAllocString(kTaskVendor));

hr = scheduler->GetFolder(folderBStr.get(), getter_AddRefs(taskFolder));
if (FAILED(hr)) {
if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) {
// Don't return an error code if our folder doesn't exist,
// because that just means it's been removed already.
return S_OK;
} else {
return hr;
}
}

RefPtr<IRegisteredTaskCollection> tasksInFolder;
ENSURE(taskFolder->GetTasks(TASK_ENUM_HIDDEN, getter_AddRefs(tasksInFolder)));

LONG numTasks = 0;
ENSURE(tasksInFolder->get_Count(&numTasks));

std::wstring WdbaTaskName(kTaskName);
WdbaTaskName += uniqueToken;

// This will be set to the last error that we encounter while deleting tasks.
// This allows us to keep attempting to remove the remaining tasks, even if
// we encounter an error, while still preserving what error we encountered so
// we can return it from this function.
HRESULT deleteResult = S_OK;
// Set to true if we intentionally skip any tasks.
bool tasksSkipped = false;

for (LONG i = 0; i < numTasks; ++i) {
RefPtr<IRegisteredTask> task;
// IRegisteredTaskCollection's are 1-indexed.
hr = tasksInFolder->get_Item(_variant_t(i + 1), getter_AddRefs(task));
if (FAILED(hr)) {
deleteResult = hr;
continue;
}

BSTR taskName;
hr = task->get_Name(&taskName);
if (FAILED(hr)) {
deleteResult = hr;
continue;
}
// Automatically free taskName when we are done with it.
BStrPtr uniqueTaskName(taskName);

if (tasksToRemove == WhichTasks::WdbaTaskOnly) {
if (WdbaTaskName.compare(taskName) != 0) {
tasksSkipped = true;
continue;
}
} else { // tasksToRemove == WhichTasks::AllTasksForInstallation
if (!EndsWith(taskName, uniqueToken)) {
tasksSkipped = true;
continue;
}
}

hr = taskFolder->DeleteTask(taskName, 0 /* flags */);
if (FAILED(hr)) {
deleteResult = hr;
}
}

// If we successfully removed all the tasks, delete the folder too.
if (!tasksSkipped && SUCCEEDED(deleteResult)) {
RefPtr<ITaskFolder> rootFolder;
BStrPtr rootFolderBStr = BStrPtr(SysAllocString(L"\\"));
ENSURE(
scheduler->GetFolder(rootFolderBStr.get(), getter_AddRefs(rootFolder)));
ENSURE(rootFolder->DeleteFolder(folderBStr.get(), 0));
}

return deleteResult;
}

} // namespace mozilla::default_agent
37 changes: 37 additions & 0 deletions toolkit/mozapps/defaultagent/ScheduledTaskRemove.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */

#ifndef __DEFAULT_BROWSER_AGENT_SCHEDULED_TASK_REMOVE_H__
#define __DEFAULT_BROWSER_AGENT_SCHEDULED_TASK_REMOVE_H__

#include <windows.h>
#include <wtypes.h>

#include <oleauto.h>

#include "mozilla/UniquePtr.h"

namespace mozilla::default_agent {

struct SysFreeStringDeleter {
void operator()(BSTR aPtr) { ::SysFreeString(aPtr); }
};
using BStrPtr = mozilla::UniquePtr<OLECHAR, SysFreeStringDeleter>;

static const wchar_t* kTaskVendor = L"" MOZ_APP_VENDOR;
// kTaskName should have the unique token appended before being used.
static const wchar_t* kTaskName =
L"" MOZ_APP_DISPLAYNAME " Default Browser Agent ";

enum class WhichTasks {
WdbaTaskOnly,
AllTasksForInstallation,
};
HRESULT RemoveTasks(const wchar_t* uniqueToken, WhichTasks tasksToRemove);

} // namespace mozilla::default_agent

#endif // __DEFAULT_BROWSER_AGENT_SCHEDULED_TASK_REMOVE_H__
1 change: 1 addition & 0 deletions toolkit/mozapps/defaultagent/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ UNIFIED_SOURCES += [
"Policy.cpp",
"Registry.cpp",
"ScheduledTask.cpp",
"ScheduledTaskRemove.cpp",
"SetDefaultBrowser.cpp",
"Telemetry.cpp",
"UtfConvert.cpp",
Expand Down
1 change: 1 addition & 0 deletions toolkit/mozapps/defaultagent/proxy/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <filesystem>

#include "../ScheduledTask.h"
#include "../ScheduledTaskRemove.h"
#include "mozilla/CmdLineAndEnvUtils.h"

using namespace mozilla::default_agent;
Expand Down
7 changes: 1 addition & 6 deletions toolkit/mozapps/defaultagent/proxy/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,8 @@ Program("default-browser-agent")
SPHINX_TREES["default-browser-agent"] = "docs"

UNIFIED_SOURCES += [
"../DefaultBrowser.cpp",
"../EventLog.cpp",
"../Registry.cpp",
"../ScheduledTask.cpp",
"../UtfConvert.cpp",
"/mfbt/Poison.cpp",
"/mfbt/Unused.cpp",
"../ScheduledTaskRemove.cpp",
"main.cpp",
]

Expand Down

0 comments on commit 65ee268

Please sign in to comment.