зеркало из https://github.com/mozilla/gecko-dev.git
Bug 836654 - Part 7: Hold a CPU wake lock while a "critical" process that's expecting a system message loads. r=cjones,fabrice
This commit is contained in:
Родитель
f44d60c8cc
Коммит
fb22e05f5c
|
@ -584,6 +584,11 @@ pref("dom.ipc.processPrelaunch.enabled", true);
|
|||
pref("dom.ipc.processPrelaunch.delayMs", 5000);
|
||||
#endif
|
||||
|
||||
// When a process receives a system message, we hold a CPU wake lock on its
|
||||
// behalf for this many seconds, or until it handles the system message,
|
||||
// whichever comes first.
|
||||
pref("dom.ipc.systemMessageCPULockTimeoutSec", 30);
|
||||
|
||||
// Ignore the "dialog=1" feature in window.open.
|
||||
pref("dom.disable_window_open_dialog_feature", true);
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@
|
|||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::hal;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::ipc;
|
||||
using namespace mozilla::layers;
|
||||
|
@ -2044,11 +2045,9 @@ nsFrameLoader::TryRemoteBrowser()
|
|||
context.SetTabContextForBrowserFrame(containingApp, scrollingBehavior);
|
||||
}
|
||||
|
||||
mRemoteBrowser = ContentParent::CreateBrowserOrApp(context);
|
||||
nsCOMPtr<nsIDOMElement> ownerElement = do_QueryInterface(mOwnerContent);
|
||||
mRemoteBrowser = ContentParent::CreateBrowserOrApp(context, ownerElement);
|
||||
if (mRemoteBrowser) {
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent);
|
||||
mRemoteBrowser->SetOwnerElement(element);
|
||||
|
||||
// If we're an app, send the frame element's mozapptype down to the child
|
||||
// process. This ends up in TabChild::GetAppType().
|
||||
if (ownApp) {
|
||||
|
|
|
@ -235,6 +235,39 @@ ConsoleListener::Observe(nsIConsoleMessage* aMessage)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
class SystemMessageHandledObserver MOZ_FINAL : public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
void Init();
|
||||
};
|
||||
|
||||
void SystemMessageHandledObserver::Init()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> os =
|
||||
mozilla::services::GetObserverService();
|
||||
|
||||
if (os) {
|
||||
os->AddObserver(this, "SystemMessageManager:HandleMessageDone",
|
||||
/* ownsWeak */ false);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SystemMessageHandledObserver::Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const PRUnichar* aData)
|
||||
{
|
||||
if (ContentChild::GetSingleton()) {
|
||||
ContentChild::GetSingleton()->SendSystemMessageHandled();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(SystemMessageHandledObserver, nsIObserver)
|
||||
|
||||
ContentChild* ContentChild::sSingleton;
|
||||
|
||||
ContentChild::ContentChild()
|
||||
|
@ -340,6 +373,11 @@ ContentChild::InitXPCOM()
|
|||
|
||||
DebugOnly<FileUpdateDispatcher*> observer = FileUpdateDispatcher::GetSingleton();
|
||||
NS_ASSERTION(observer, "FileUpdateDispatcher is null");
|
||||
|
||||
// This object is held alive by the observer service.
|
||||
nsRefPtr<SystemMessageHandledObserver> sysMsgObserver =
|
||||
new SystemMessageHandledObserver();
|
||||
sysMsgObserver->Init();
|
||||
}
|
||||
|
||||
PMemoryReportRequestChild*
|
||||
|
@ -524,11 +562,12 @@ ContentChild::AllocPBrowser(const IPCTabContext& aContext,
|
|||
sFirstIdleTask = NewRunnableFunction(FirstIdle);
|
||||
MessageLoop::current()->PostIdleTask(FROM_HERE, sFirstIdleTask);
|
||||
|
||||
// If we are the preallocated process transforming into an app process,
|
||||
// we'll have background priority at this point. Give ourselves a
|
||||
// priority boost for a few seconds, so we don't get killed while we're
|
||||
// loading our first TabChild.
|
||||
TemporarilySetProcessPriorityToForeground();
|
||||
// We are either a brand-new process loading its first PBrowser, or we
|
||||
// are the preallocated process transforming into a particular
|
||||
// app/browser. Either way, our parent has already set our process
|
||||
// priority, and we want to leave it there for a few seconds while we
|
||||
// start up.
|
||||
TemporarilyLockProcessPriority();
|
||||
}
|
||||
|
||||
// We'll happily accept any kind of IPCTabContext here; we don't need to
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/dom/ExternalHelperAppParent.h"
|
||||
#include "mozilla/dom/PMemoryReportRequestParent.h"
|
||||
#include "mozilla/dom/power/PowerManagerService.h"
|
||||
#include "mozilla/dom/StorageParent.h"
|
||||
#include "mozilla/dom/bluetooth/PBluetoothParent.h"
|
||||
#include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h"
|
||||
|
@ -61,9 +62,11 @@
|
|||
#include "nsIConsoleService.h"
|
||||
#include "nsIDOMApplicationRegistry.h"
|
||||
#include "nsIDOMGeoGeolocation.h"
|
||||
#include "nsIDOMWakeLock.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIFilePicker.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "nsIMozBrowserFrame.h"
|
||||
#include "nsIMutable.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIPresShell.h"
|
||||
|
@ -123,8 +126,9 @@ using base::ChildPrivileges;
|
|||
using base::KillProcess;
|
||||
using namespace mozilla::dom::bluetooth;
|
||||
using namespace mozilla::dom::devicestorage;
|
||||
using namespace mozilla::dom::sms;
|
||||
using namespace mozilla::dom::indexedDB;
|
||||
using namespace mozilla::dom::power;
|
||||
using namespace mozilla::dom::sms;
|
||||
using namespace mozilla::hal;
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::layers;
|
||||
|
@ -208,7 +212,8 @@ ContentParent::PreallocateAppProcess()
|
|||
/*isBrowserElement=*/false,
|
||||
// Final privileges are set when we
|
||||
// transform into our app.
|
||||
base::PRIVILEGES_INHERIT);
|
||||
base::PRIVILEGES_INHERIT,
|
||||
PROCESS_PRIORITY_BACKGROUND);
|
||||
sPreallocatedAppProcess->Init();
|
||||
}
|
||||
|
||||
|
@ -235,7 +240,8 @@ ContentParent::ScheduleDelayedPreallocateAppProcess()
|
|||
|
||||
/*static*/ already_AddRefed<ContentParent>
|
||||
ContentParent::MaybeTakePreallocatedAppProcess(const nsAString& aAppManifestURL,
|
||||
ChildPrivileges aPrivs)
|
||||
ChildPrivileges aPrivs,
|
||||
ProcessPriority aInitialPriority)
|
||||
{
|
||||
nsRefPtr<ContentParent> process = sPreallocatedAppProcess.get();
|
||||
sPreallocatedAppProcess = nullptr;
|
||||
|
@ -244,10 +250,8 @@ ContentParent::MaybeTakePreallocatedAppProcess(const nsAString& aAppManifestURL,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (!process->TransformPreallocatedIntoApp(aAppManifestURL, aPrivs)) {
|
||||
NS_WARNING("Can't TransformPrealocatedIntoApp. Maybe "
|
||||
"the preallocated process died?");
|
||||
|
||||
if (!process->TransformPreallocatedIntoApp(aAppManifestURL, aPrivs,
|
||||
aInitialPriority)) {
|
||||
// Kill the process just in case it's not actually dead; we don't want
|
||||
// to "leak" this process!
|
||||
process->KillHard();
|
||||
|
@ -365,7 +369,9 @@ ContentParent::GetNewOrUsed(bool aForBrowserElement)
|
|||
|
||||
nsRefPtr<ContentParent> p =
|
||||
new ContentParent(/* appManifestURL = */ EmptyString(),
|
||||
aForBrowserElement);
|
||||
aForBrowserElement,
|
||||
base::PRIVILEGES_DEFAULT,
|
||||
PROCESS_PRIORITY_FOREGROUND);
|
||||
p->Init();
|
||||
gNonAppContentParents->AppendElement(p);
|
||||
return p;
|
||||
|
@ -402,8 +408,37 @@ PrivilegesForApp(mozIApplication* aApp)
|
|||
return base::PRIVILEGES_DEFAULT;
|
||||
}
|
||||
|
||||
/*static*/ ProcessPriority
|
||||
ContentParent::GetInitialProcessPriority(nsIDOMElement* aFrameElement)
|
||||
{
|
||||
// Frames with mozapptype == critical which are expecting a system message
|
||||
// get FOREGROUND_HIGH priority. All other frames get FOREGROUND priority.
|
||||
|
||||
if (!aFrameElement) {
|
||||
return PROCESS_PRIORITY_FOREGROUND;
|
||||
}
|
||||
|
||||
nsAutoString appType;
|
||||
nsCOMPtr<Element> frameElement = do_QueryInterface(aFrameElement);
|
||||
frameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::mozapptype, appType);
|
||||
if (appType != NS_LITERAL_STRING("critical")) {
|
||||
return PROCESS_PRIORITY_FOREGROUND;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIMozBrowserFrame> browserFrame =
|
||||
do_QueryInterface(aFrameElement);
|
||||
if (!browserFrame) {
|
||||
return PROCESS_PRIORITY_FOREGROUND;
|
||||
}
|
||||
|
||||
return browserFrame->GetIsExpectingSystemMessage() ?
|
||||
PROCESS_PRIORITY_FOREGROUND_HIGH :
|
||||
PROCESS_PRIORITY_FOREGROUND;
|
||||
}
|
||||
|
||||
/*static*/ TabParent*
|
||||
ContentParent::CreateBrowserOrApp(const TabContext& aContext)
|
||||
ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
||||
nsIDOMElement* aFrameElement)
|
||||
{
|
||||
if (!sCanLaunchSubprocesses) {
|
||||
return nullptr;
|
||||
|
@ -412,6 +447,7 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext)
|
|||
if (aContext.IsBrowserElement() || !aContext.HasOwnApp()) {
|
||||
if (ContentParent* cp = GetNewOrUsed(aContext.IsBrowserElement())) {
|
||||
nsRefPtr<TabParent> tp(new TabParent(aContext));
|
||||
tp->SetOwnerElement(aFrameElement);
|
||||
PBrowserParent* browser = cp->SendPBrowserConstructor(
|
||||
tp.forget().get(), // DeallocPBrowserParent() releases this ref.
|
||||
aContext.AsIPCTabContext(),
|
||||
|
@ -441,18 +477,24 @@ ContentParent::CreateBrowserOrApp(const TabContext& aContext)
|
|||
|
||||
nsRefPtr<ContentParent> p = gAppContentParents->Get(manifestURL);
|
||||
if (!p) {
|
||||
ProcessPriority initialPriority = GetInitialProcessPriority(aFrameElement);
|
||||
|
||||
ChildPrivileges privs = PrivilegesForApp(ownApp);
|
||||
p = MaybeTakePreallocatedAppProcess(manifestURL, privs);
|
||||
p = MaybeTakePreallocatedAppProcess(manifestURL, privs,
|
||||
initialPriority);
|
||||
if (!p) {
|
||||
NS_WARNING("Unable to use pre-allocated app process");
|
||||
p = new ContentParent(manifestURL, /* isBrowserElement = */ false,
|
||||
privs);
|
||||
privs, initialPriority);
|
||||
p->Init();
|
||||
}
|
||||
gAppContentParents->Put(manifestURL, p);
|
||||
}
|
||||
|
||||
p->MaybeTakeCPUWakeLock(aFrameElement);
|
||||
|
||||
nsRefPtr<TabParent> tp = new TabParent(aContext);
|
||||
tp->SetOwnerElement(aFrameElement);
|
||||
PBrowserParent* browser = p->SendPBrowserConstructor(
|
||||
tp.forget().get(), // DeallocPBrowserParent() releases this ref.
|
||||
aContext.AsIPCTabContext(),
|
||||
|
@ -529,23 +571,136 @@ ContentParent::Init()
|
|||
NS_ASSERTION(observer, "FileUpdateDispatcher is null");
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class SystemMessageHandledListener MOZ_FINAL
|
||||
: public nsITimerCallback
|
||||
, public LinkedListElement<SystemMessageHandledListener>
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
SystemMessageHandledListener() {}
|
||||
|
||||
static void OnSystemMessageHandled()
|
||||
{
|
||||
if (!sListeners) {
|
||||
return;
|
||||
}
|
||||
|
||||
SystemMessageHandledListener* listener = sListeners->popFirst();
|
||||
if (!listener) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Careful: ShutDown() may delete |this|.
|
||||
listener->ShutDown();
|
||||
}
|
||||
|
||||
void Init(nsIDOMMozWakeLock* aWakeLock)
|
||||
{
|
||||
MOZ_ASSERT(!mWakeLock);
|
||||
MOZ_ASSERT(!mTimer);
|
||||
|
||||
// mTimer keeps a strong reference to |this|. When this object's
|
||||
// destructor runs, it will remove itself from the LinkedList.
|
||||
|
||||
if (!sListeners) {
|
||||
sListeners = new LinkedList<SystemMessageHandledListener>();
|
||||
ClearOnShutdown(&sListeners);
|
||||
}
|
||||
sListeners->insertBack(this);
|
||||
|
||||
mWakeLock = aWakeLock;
|
||||
|
||||
mTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
|
||||
uint32_t timeoutSec =
|
||||
Preferences::GetInt("dom.ipc.systemMessageCPULockTimeoutSec", 30);
|
||||
mTimer->InitWithCallback(this, timeoutSec * 1000,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
NS_IMETHOD Notify(nsITimer* aTimer)
|
||||
{
|
||||
// Careful: ShutDown() may delete |this|.
|
||||
ShutDown();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
static StaticAutoPtr<LinkedList<SystemMessageHandledListener> > sListeners;
|
||||
|
||||
void ShutDown()
|
||||
{
|
||||
nsRefPtr<SystemMessageHandledListener> kungFuDeathGrip = this;
|
||||
|
||||
mWakeLock->Unlock();
|
||||
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
mTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMMozWakeLock> mWakeLock;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
};
|
||||
|
||||
StaticAutoPtr<LinkedList<SystemMessageHandledListener> >
|
||||
SystemMessageHandledListener::sListeners;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(SystemMessageHandledListener,
|
||||
nsITimerCallback)
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void
|
||||
ContentParent::SetProcessInitialPriority(ProcessPriority aInitialPriority)
|
||||
{
|
||||
if (!Preferences::GetBool("dom.ipc.processPriorityManager.enabled")) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetProcessPriority(base::GetProcId(mSubprocess->GetChildProcessHandle()),
|
||||
aInitialPriority);
|
||||
}
|
||||
|
||||
void
|
||||
ContentParent::MaybeTakeCPUWakeLock(nsIDOMElement* aFrameElement)
|
||||
{
|
||||
// Take the CPU wake lock on behalf of this processs if it's expecting a
|
||||
// system message. We'll release the CPU lock once the message is
|
||||
// delivered, or after some period of time, which ever comes first.
|
||||
|
||||
nsCOMPtr<nsIMozBrowserFrame> browserFrame =
|
||||
do_QueryInterface(aFrameElement);
|
||||
if (!browserFrame ||
|
||||
!browserFrame->GetIsExpectingSystemMessage()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<PowerManagerService> pms = PowerManagerService::GetInstance();
|
||||
nsCOMPtr<nsIDOMMozWakeLock> lock =
|
||||
pms->NewWakeLockOnBehalfOfProcess(NS_LITERAL_STRING("cpu"), this);
|
||||
|
||||
// This object's Init() function keeps it alive.
|
||||
nsRefPtr<SystemMessageHandledListener> listener =
|
||||
new SystemMessageHandledListener();
|
||||
listener->Init(lock);
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::TransformPreallocatedIntoApp(const nsAString& aAppManifestURL,
|
||||
ChildPrivileges aPrivs)
|
||||
ChildPrivileges aPrivs,
|
||||
ProcessPriority aInitialPriority)
|
||||
{
|
||||
MOZ_ASSERT(mAppManifestURL == MAGIC_PREALLOCATED_APP_MANIFEST_URL);
|
||||
// Clients should think of mAppManifestURL as const ... we're
|
||||
// bending the rules here just for the preallocation hack.
|
||||
const_cast<nsString&>(mAppManifestURL) = aAppManifestURL;
|
||||
|
||||
// Boost this process's priority. The subprocess will call
|
||||
// TemporarilySetProcessPriorityToForeground() from within
|
||||
// ContentChild::AllocPBrowser, but this happens earlier, thus reducing the
|
||||
// window in which the child might be killed due to low memory.
|
||||
if (Preferences::GetBool("dom.ipc.processPriorityManager.enabled")) {
|
||||
SetProcessPriority(base::GetProcId(mSubprocess->GetChildProcessHandle()),
|
||||
PROCESS_PRIORITY_FOREGROUND);
|
||||
}
|
||||
SetProcessInitialPriority(aInitialPriority);
|
||||
|
||||
// Now that we've increased the process's priority from BACKGROUND (where
|
||||
// the preallocated app sits) to something higher, check whether the process
|
||||
|
@ -870,7 +1025,8 @@ ContentParent::GetTestShellSingleton()
|
|||
|
||||
ContentParent::ContentParent(const nsAString& aAppManifestURL,
|
||||
bool aIsForBrowser,
|
||||
ChildOSPrivileges aOSPrivileges)
|
||||
ChildOSPrivileges aOSPrivileges,
|
||||
ProcessPriority aInitialPriority /* = PROCESS_PRIORITY_FOREGROUND */)
|
||||
: mSubprocess(nullptr)
|
||||
, mOSPrivileges(aOSPrivileges)
|
||||
, mChildID(CONTENT_PROCESS_ID_UNKNOWN)
|
||||
|
@ -895,20 +1051,10 @@ ContentParent::ContentParent(const nsAString& aAppManifestURL,
|
|||
|
||||
mSubprocess->LaunchAndWaitForProcessHandle();
|
||||
|
||||
// Set the subprocess's priority (bg if we're a preallocated process, fg
|
||||
// otherwise). We do this first because we're likely /lowering/ its CPU and
|
||||
// memory priority, which it has inherited from this process.
|
||||
if (Preferences::GetBool("dom.ipc.processPriorityManager.enabled")) {
|
||||
ProcessPriority priority;
|
||||
if (aAppManifestURL == MAGIC_PREALLOCATED_APP_MANIFEST_URL) {
|
||||
priority = PROCESS_PRIORITY_BACKGROUND;
|
||||
} else {
|
||||
priority = PROCESS_PRIORITY_FOREGROUND;
|
||||
}
|
||||
|
||||
SetProcessPriority(base::GetProcId(mSubprocess->GetChildProcessHandle()),
|
||||
priority);
|
||||
}
|
||||
// Set the subprocess's priority. We do this first because we're likely
|
||||
// /lowering/ its CPU and memory priority, which it has inherited from this
|
||||
// process.
|
||||
SetProcessInitialPriority(aInitialPriority);
|
||||
|
||||
Open(mSubprocess->GetChannel(), mSubprocess->GetChildProcessHandle());
|
||||
|
||||
|
@ -2428,5 +2574,12 @@ ContentParent::CheckAppHasPermission(const nsAString& aPermission)
|
|||
return AssertAppHasPermission(this, NS_ConvertUTF16toUTF8(aPermission).get());
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvSystemMessageHandled()
|
||||
{
|
||||
SystemMessageHandledListener::OnSystemMessageHandled();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -85,9 +85,13 @@ public:
|
|||
static ContentParent* GetNewOrUsed(bool aForBrowserElement = false);
|
||||
|
||||
/**
|
||||
* Get or create a content process for the given TabContext.
|
||||
* Get or create a content process for the given TabContext. aFrameElement
|
||||
* should be the frame/iframe element with which this process will
|
||||
* associated.
|
||||
*/
|
||||
static TabParent* CreateBrowserOrApp(const TabContext& aContext);
|
||||
static TabParent*
|
||||
CreateBrowserOrApp(const TabContext& aContext,
|
||||
nsIDOMElement* aFrameElement);
|
||||
|
||||
static void GetAll(nsTArray<ContentParent*>& aArray);
|
||||
|
||||
|
@ -166,7 +170,10 @@ private:
|
|||
// if it's dead), this returns false.
|
||||
static already_AddRefed<ContentParent>
|
||||
MaybeTakePreallocatedAppProcess(const nsAString& aAppManifestURL,
|
||||
ChildPrivileges aPrivs);
|
||||
ChildPrivileges aPrivs,
|
||||
hal::ProcessPriority aInitialPriority);
|
||||
|
||||
static hal::ProcessPriority GetInitialProcessPriority(nsIDOMElement* aFrameElement);
|
||||
|
||||
static void FirstIdle();
|
||||
|
||||
|
@ -176,15 +183,27 @@ private:
|
|||
using PContentParent::SendPTestShellConstructor;
|
||||
|
||||
ContentParent(const nsAString& aAppManifestURL, bool aIsForBrowser,
|
||||
ChildOSPrivileges aOSPrivileges = base::PRIVILEGES_DEFAULT);
|
||||
ChildOSPrivileges aOSPrivileges = base::PRIVILEGES_DEFAULT,
|
||||
hal::ProcessPriority aInitialPriority = hal::PROCESS_PRIORITY_FOREGROUND);
|
||||
virtual ~ContentParent();
|
||||
|
||||
void Init();
|
||||
|
||||
// Set the child process's priority. Once the child starts up, it will
|
||||
// manage its own priority via the ProcessPriorityManager.
|
||||
void SetProcessInitialPriority(hal::ProcessPriority aInitialPriority);
|
||||
|
||||
// If the frame element indicates that the child process is "critical" and
|
||||
// has a pending system message, this function acquires the CPU wake lock on
|
||||
// behalf of the child. We'll release the lock when the system message is
|
||||
// handled or after a timeout, whichever comes first.
|
||||
void MaybeTakeCPUWakeLock(nsIDOMElement* aFrameElement);
|
||||
|
||||
// Transform a pre-allocated app process into a "real" app
|
||||
// process, for the specified manifest URL.
|
||||
bool TransformPreallocatedIntoApp(const nsAString& aAppManifestURL,
|
||||
ChildPrivileges aPrivs);
|
||||
ChildPrivileges aPrivs,
|
||||
hal::ProcessPriority aInitialPriority);
|
||||
|
||||
/**
|
||||
* Mark this ContentParent as dead for the purposes of Get*().
|
||||
|
@ -355,6 +374,8 @@ private:
|
|||
|
||||
virtual bool RecvRecordingDeviceEvents(const nsString& aRecordingStatus);
|
||||
|
||||
virtual bool RecvSystemMessageHandled() MOZ_OVERRIDE;
|
||||
|
||||
virtual void ProcessingError(Result what) MOZ_OVERRIDE;
|
||||
|
||||
GeckoChildProcessHost* mSubprocess;
|
||||
|
|
|
@ -455,6 +455,9 @@ parent:
|
|||
|
||||
async RecordingDeviceEvents(nsString recordingStatus);
|
||||
|
||||
// Notify the parent that the child has finished handling a system message.
|
||||
async SystemMessageHandled();
|
||||
|
||||
both:
|
||||
AsyncMessage(nsString aMessage, ClonedMessageData aData);
|
||||
};
|
||||
|
|
|
@ -75,10 +75,9 @@ SystemMessageManager.prototype = {
|
|||
aHandler.handleMessage(wrapped ? aMessage
|
||||
: ObjectWrapper.wrap(aMessage, this._window));
|
||||
|
||||
// Notify the parent process the message is handled.
|
||||
cpmm.sendAsyncMessage("SystemMessageManager:HandleMessageDone",
|
||||
{ type: aType,
|
||||
message: aMessage });
|
||||
Services.obs.notifyObservers(/* aSubject */ null,
|
||||
"SystemMessageManager:HandleMessageDone",
|
||||
/* aData */ null);
|
||||
},
|
||||
|
||||
mozSetMessageHandler: function sysMessMgr_setMessageHandler(aType, aHandler) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче