Bug 1343425 - Supports nsIURIClassifier.asyncClassifyLocalWithTables. r=baku

We add a new "on-off" protocol PURLClassifierLocal which calls
nsIURIClassifier.asyncClassifyLocalWithTables on construction and
calls back on destruction. Pretty much the same design as PURLClassifier.

In order to avoid code duplication, the actor implementation is templatized
and |MaybeInfo| in PURLClassifier.ipdl is moved around.

Test case is included and the custom event target is not in place for labelling.
The custom event target will be done in Bug 1353701.

MozReview-Commit-ID: IdHYgdnBV7S

--HG--
extra : rebase_source : ab1c896305b9f76cab13a92c9bd88c2d356aacb7
This commit is contained in:
Henry Chang 2017-04-07 14:15:16 +08:00
Родитель 760101df05
Коммит eec96acbf0
16 изменённых файлов: 282 добавлений и 92 удалений

Просмотреть файл

@ -3143,6 +3143,21 @@ ContentChild::DeallocPURLClassifierChild(PURLClassifierChild* aActor)
return true;
}
PURLClassifierLocalChild*
ContentChild::AllocPURLClassifierLocalChild(const URIParams& aUri,
const nsCString& aTables)
{
return new URLClassifierLocalChild();
}
bool
ContentChild::DeallocPURLClassifierLocalChild(PURLClassifierLocalChild* aActor)
{
MOZ_ASSERT(aActor);
delete aActor;
return true;
}
// The IPC code will call this method asking us to assign an event target to new
// actors created by the ContentParent.
already_AddRefed<nsIEventTarget>

Просмотреть файл

@ -610,6 +610,7 @@ public:
return mFontFamilies;
}
// PURLClassifierChild
virtual PURLClassifierChild*
AllocPURLClassifierChild(const Principal& aPrincipal,
const bool& aUseTrackingProtection,
@ -617,6 +618,13 @@ public:
virtual bool
DeallocPURLClassifierChild(PURLClassifierChild* aActor) override;
// PURLClassifierLocalChild
virtual PURLClassifierLocalChild*
AllocPURLClassifierLocalChild(const URIParams& aUri,
const nsCString& aTables) override;
virtual bool
DeallocPURLClassifierLocalChild(PURLClassifierLocalChild* aActor) override;
nsTArray<LookAndFeelInt>&
LookAndFeelCache() {
return mLookAndFeelCache;

Просмотреть файл

@ -5158,6 +5158,9 @@ ContentParent::RecvRecordChildEvents(nsTArray<mozilla::Telemetry::ChildEventData
return IPC_OK();
}
//////////////////////////////////////////////////////////////////
// PURLClassifierParent
PURLClassifierParent*
ContentParent::AllocPURLClassifierParent(const Principal& aPrincipal,
const bool& aUseTrackingProtection,
@ -5200,6 +5203,48 @@ ContentParent::DeallocPURLClassifierParent(PURLClassifierParent* aActor)
return true;
}
//////////////////////////////////////////////////////////////////
// PURLClassifierLocalParent
PURLClassifierLocalParent*
ContentParent::AllocPURLClassifierLocalParent(const URIParams& aURI,
const nsCString& aTables)
{
MOZ_ASSERT(NS_IsMainThread());
RefPtr<URLClassifierLocalParent> actor = new URLClassifierLocalParent();
return actor.forget().take();
}
mozilla::ipc::IPCResult
ContentParent::RecvPURLClassifierLocalConstructor(PURLClassifierLocalParent* aActor,
const URIParams& aURI,
const nsCString& aTables)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aActor);
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
if (!uri) {
NS_WARNING("Failed to DeserializeURI");
return IPC_FAIL_NO_REASON(this);
}
auto* actor = static_cast<URLClassifierLocalParent*>(aActor);
return actor->StartClassify(uri, aTables);
}
bool
ContentParent::DeallocPURLClassifierLocalParent(PURLClassifierLocalParent* aActor)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aActor);
RefPtr<URLClassifierLocalParent> actor =
dont_AddRef(static_cast<URLClassifierLocalParent*>(aActor));
return true;
}
mozilla::ipc::IPCResult
ContentParent::RecvClassifyLocal(const URIParams& aURI, const nsCString& aTables,
nsresult *aRv, nsTArray<nsCString>* aResults)

Просмотреть файл

@ -605,6 +605,7 @@ public:
virtual int32_t Pid() const override;
// PURLClassifierParent.
virtual PURLClassifierParent*
AllocPURLClassifierParent(const Principal& aPrincipal,
const bool& aUseTrackingProtection,
@ -615,6 +616,15 @@ public:
const bool& aUseTrackingProtection,
bool* aSuccess) override;
// PURLClassifierLocalParent.
virtual PURLClassifierLocalParent*
AllocPURLClassifierLocalParent(const URIParams& aURI,
const nsCString& aTables) override;
virtual mozilla::ipc::IPCResult
RecvPURLClassifierLocalConstructor(PURLClassifierLocalParent* aActor,
const URIParams& aURI,
const nsCString& aTables) override;
virtual bool SendActivate(PBrowserParent* aTab) override
{
return PContentParent::SendActivate(aTab);
@ -631,6 +641,9 @@ public:
return PContentParent::SendParentActivated(aTab, aActivated);
}
virtual bool
DeallocPURLClassifierLocalParent(PURLClassifierLocalParent* aActor) override;
virtual bool
DeallocPURLClassifierParent(PURLClassifierParent* aActor) override;

Просмотреть файл

@ -40,6 +40,7 @@ include protocol PWebBrowserPersistDocument;
include protocol PWebrtcGlobal;
include protocol PPresentation;
include protocol PURLClassifier;
include protocol PURLClassifierLocal;
include protocol PVRManager;
include protocol PVideoDecoderManager;
include protocol PFlyWebPublishedServer;
@ -301,6 +302,7 @@ nested(upto inside_cpow) sync protocol PContent
manages PPresentation;
manages PFlyWebPublishedServer;
manages PURLClassifier;
manages PURLClassifierLocal;
both:
// Depending on exactly how the new browser is being created, it might be
@ -732,6 +734,8 @@ parent:
returns (bool success);
sync ClassifyLocal(URIParams uri, nsCString tables)
returns (nsresult rv, nsCString[] results);
// The async version of ClassifyLocal.
async PURLClassifierLocal(URIParams uri, nsCString tables);
// Services remoting

Просмотреть файл

@ -5,19 +5,12 @@
* 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/. */
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
include protocol PContent;
include PURLClassifierInfo;
namespace mozilla {
namespace dom {
union MaybeInfo {
ClassifierInfo;
void_t;
};
protocol PURLClassifier
{
manager PContent;

Просмотреть файл

@ -2,6 +2,8 @@
* 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/. */
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
namespace mozilla {
namespace dom {
@ -11,6 +13,11 @@ struct ClassifierInfo {
nsCString prefix;
};
union MaybeInfo {
ClassifierInfo;
void_t;
};
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,23 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* 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 protocol PContent;
include PURLClassifierInfo;
namespace mozilla {
namespace dom {
protocol PURLClassifierLocal
{
manager PContent;
child:
async __delete__(MaybeInfo info, nsresult errorCode);
};
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -1,24 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "URLClassifierChild.h"
#include "nsComponentManagerUtils.h"
#include "nsIURI.h"
using namespace mozilla::dom;
mozilla::ipc::IPCResult
URLClassifierChild::Recv__delete__(const MaybeInfo& aInfo,
const nsresult& aResult)
{
MOZ_ASSERT(mCallback);
if (aInfo.type() == MaybeInfo::TClassifierInfo) {
mCallback->OnClassifyComplete(aResult, aInfo.get_ClassifierInfo().list(),
aInfo.get_ClassifierInfo().provider(),
aInfo.get_ClassifierInfo().prefix());
}
return IPC_OK();
}

Просмотреть файл

@ -8,29 +8,44 @@
#define mozilla_dom_URLClassifierChild_h
#include "mozilla/dom/PURLClassifierChild.h"
#include "mozilla/dom/PURLClassifierLocalChild.h"
#include "nsIURIClassifier.h"
namespace mozilla {
namespace dom {
class URLClassifierChild : public PURLClassifierChild
template<typename BaseProtocol>
class URLClassifierChildBase : public BaseProtocol
{
public:
URLClassifierChild() = default;
public:
URLClassifierChildBase() = default;
void SetCallback(nsIURIClassifierCallback* aCallback)
{
mCallback = aCallback;
}
mozilla::ipc::IPCResult Recv__delete__(const MaybeInfo& aInfo,
const nsresult& aResult) override;
private:
~URLClassifierChild() = default;
mozilla::ipc::IPCResult Recv__delete__(const MaybeInfo& aInfo,
const nsresult& aResult) override
{
MOZ_ASSERT(mCallback);
if (aInfo.type() == MaybeInfo::TClassifierInfo) {
mCallback->OnClassifyComplete(aResult, aInfo.get_ClassifierInfo().list(),
aInfo.get_ClassifierInfo().provider(),
aInfo.get_ClassifierInfo().prefix());
}
return IPC_OK();
}
private:
~URLClassifierChildBase() = default;
nsCOMPtr<nsIURIClassifierCallback> mCallback;
};
using URLClassifierChild = URLClassifierChildBase<PURLClassifierChild>;
using URLClassifierLocalChild = URLClassifierChildBase<PURLClassifierLocalChild>;
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -11,6 +11,9 @@
using namespace mozilla;
using namespace mozilla::dom;
/////////////////////////////////////////////////////////////////////
//URLClassifierParent.
NS_IMPL_ISUPPORTS(URLClassifierParent, nsIURIClassifierCallback)
mozilla::ipc::IPCResult
@ -41,33 +44,41 @@ URLClassifierParent::StartClassify(nsIPrincipal* aPrincipal,
return IPC_OK();
}
nsresult
URLClassifierParent::OnClassifyComplete(nsresult aErrorCode,
const nsACString& aList,
const nsACString& aProvider,
const nsACString& aPrefix)
{
if (mIPCOpen) {
ClassifierInfo info;
info.list() = aList;
info.prefix() = aPrefix;
info.provider() = aProvider;
Unused << Send__delete__(this, info, aErrorCode);
}
return NS_OK;
}
void
URLClassifierParent::ClassificationFailed()
{
if (mIPCOpen) {
Unused << Send__delete__(this, void_t(), NS_ERROR_FAILURE);
}
}
void
URLClassifierParent::ActorDestroy(ActorDestroyReason aWhy)
{
mIPCOpen = false;
}
/////////////////////////////////////////////////////////////////////
//URLClassifierLocalParent.
NS_IMPL_ISUPPORTS(URLClassifierLocalParent, nsIURIClassifierCallback)
mozilla::ipc::IPCResult
URLClassifierLocalParent::StartClassify(nsIURI* aURI, const nsACString& aTables)
{
nsresult rv = NS_OK;
// Note that in safe mode, the URL classifier service isn't available, so we
// should handle the service not being present gracefully.
nsCOMPtr<nsIURIClassifier> uriClassifier =
do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
MOZ_ASSERT(aURI);
rv = uriClassifier->AsyncClassifyLocalWithTables(aURI, aTables, this);
}
if (NS_FAILED(rv)) {
// Cannot do ClassificationFailed() because the child side
// is expecting a callback. Only the second parameter will
// be used, which is the "matched list". We treat "unable
// to classify" as "not on any list".
OnClassifyComplete(NS_OK, EmptyCString(), EmptyCString(), EmptyCString());
}
return IPC_OK();
}
void
URLClassifierLocalParent::ActorDestroy(ActorDestroyReason aWhy)
{
mIPCOpen = false;
}

Просмотреть файл

@ -8,31 +8,79 @@
#define mozilla_dom_URLClassifierParent_h
#include "mozilla/dom/PURLClassifierParent.h"
#include "mozilla/dom/PURLClassifierLocalParent.h"
#include "nsIURIClassifier.h"
namespace mozilla {
namespace dom {
class URLClassifierParent : public nsIURIClassifierCallback,
public PURLClassifierParent
template<typename BaseProtocol>
class URLClassifierParentBase : public nsIURIClassifierCallback,
public BaseProtocol
{
public:
URLClassifierParent() = default;
public:
// nsIURIClassifierCallback.
NS_IMETHOD OnClassifyComplete(nsresult aErrorCode,
const nsACString& aList,
const nsACString& aProvider,
const nsACString& aPrefix)
{
if (mIPCOpen) {
ClassifierInfo info = ClassifierInfo(nsCString(aList),
nsCString(aProvider),
nsCString(aPrefix));
Unused << BaseProtocol::Send__delete__(this, info, aErrorCode);
}
return NS_OK;
}
// Custom.
void ClassificationFailed()
{
if (mIPCOpen) {
Unused << BaseProtocol::Send__delete__(this, void_t(), NS_ERROR_FAILURE);
}
}
protected:
~URLClassifierParentBase() = default;
bool mIPCOpen = true;
};
//////////////////////////////////////////////////////////////
// URLClassifierParent
class URLClassifierParent : public URLClassifierParentBase<PURLClassifierParent>
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIURICLASSIFIERCALLBACK
mozilla::ipc::IPCResult StartClassify(nsIPrincipal* aPrincipal,
bool aUseTrackingProtection,
bool* aSuccess);
void ActorDestroy(ActorDestroyReason aWhy) override;
void ClassificationFailed();
private:
private:
~URLClassifierParent() = default;
bool mIPCOpen = true;
// Override PURLClassifierParent::ActorDestroy. We seem to unable to
// override from the base template class.
void ActorDestroy(ActorDestroyReason aWhy) override;
};
//////////////////////////////////////////////////////////////
// URLClassifierLocalParent
class URLClassifierLocalParent : public URLClassifierParentBase<PURLClassifierLocalParent>
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
mozilla::ipc::IPCResult StartClassify(nsIURI* aURI, const nsACString& aTables);
private:
~URLClassifierLocalParent() = default;
// Override PURLClassifierParent::ActorDestroy.
void ActorDestroy(ActorDestroyReason aWhy) override;
};
} // namespace dom

Просмотреть файл

@ -71,7 +71,6 @@ UNIFIED_SOURCES += [
'TabMessageUtils.cpp',
'TabParent.cpp',
'TelemetryScrollProbe.cpp',
'URLClassifierChild.cpp',
'URLClassifierParent.cpp',
]
@ -99,6 +98,7 @@ IPDL_SOURCES += [
'PTabContext.ipdlh',
'PURLClassifier.ipdl',
'PURLClassifierInfo.ipdlh',
'PURLClassifierLocal.ipdl',
'ServiceWorkerConfiguration.ipdlh',
]

Просмотреть файл

@ -725,7 +725,7 @@ SpecialPowersAPI.prototype = {
we will revert the permission back to the original.
inPermissions is an array of objects where each object has a type, action, context, ex:
[{'type': 'SystemXHR', 'allow': 1, 'context': document},
[{'type': 'SystemXHR', 'allow': 1, 'context': document},
{'type': 'SystemXHR', 'allow': Ci.nsIPermissionManager.PROMPT_ACTION, 'context': document}]
Allow can be a boolean value of true/false or ALLOW_ACTION/DENY_ACTION/PROMPT_ACTION/UNKNOWN_ACTION
@ -2144,6 +2144,26 @@ SpecialPowersAPI.prototype = {
tpEnabled, wrapCallback);
},
// TODO: Bug 1353701 - Supports custom event target for labelling.
doUrlClassifyLocal(uri, tables, callback) {
let classifierService =
Cc["@mozilla.org/url-classifier/dbservice;1"].getService(Ci.nsIURIClassifier);
let wrapCallback = (...args) => {
Services.tm.mainThread.dispatch(() => {
if (typeof callback == 'function') {
callback.call(undefined, ...args);
} else {
callback.onClassifyComplete.call(undefined, ...args);
}
}, Ci.nsIThread.DISPATCH_NORMAL);
};
return classifierService.asyncClassifyLocalWithTables(unwrapIfWrapped(uri),
tables,
wrapCallback);
},
};
this.SpecialPowersAPI = SpecialPowersAPI;

Просмотреть файл

@ -1757,8 +1757,28 @@ nsUrlClassifierDBService::AsyncClassifyLocalWithTables(nsIURI *aURI,
"on main thread");
if (XRE_IsContentProcess()) {
// TODO: e10s support. Bug 1343425.
return NS_ERROR_NOT_IMPLEMENTED;
using namespace mozilla::dom;
using namespace mozilla::ipc;
ContentChild* content = ContentChild::GetSingleton();
MOZ_ASSERT(content);
auto actor = new URLClassifierLocalChild();
// TODO: Bug 1353701 - Supports custom event target for labelling.
nsCOMPtr<nsIEventTarget> systemGroupEventTarget
= mozilla::SystemGroup::EventTargetFor(mozilla::TaskCategory::Other);
content->SetEventTargetForActor(actor, systemGroupEventTarget);
URIParams uri;
SerializeURI(aURI, uri);
nsAutoCString tables(aTables);
if (!content->SendPURLClassifierLocalConstructor(actor, uri, tables)) {
return NS_ERROR_FAILURE;
}
actor->SetCallback(aCallback);
return NS_OK;
}
if (gShuttingDownThread) {

Просмотреть файл

@ -144,21 +144,13 @@ function testService() {
is(errorCode, test.result,
`Successful asynchronous classification of ${test.url} with TP=${test.trackingProtection}`);
try {
// Same as classifyLocal except for the 'async' call.
service.asyncClassifyLocalWithTables(uri, tables, function(errorCode, tables) {
is(tables, test.table,
`Successful asynchronous local classification of ${test.url} with TP=${test.trackingProtection}`);
runNextTest();
});
} catch (e) {
// TODO: asyncClassifyLocalWithTables e10s support. See Bug 1343425.
let processType = Cc["@mozilla.org/xre/app-info;1"]
.getService(Ci.nsIXULRuntime).processType;
isnot(processType, Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT,
"Local asynchronous classification is not supported in content process");
// Same as classifyLocal except for the 'async' call.
SpecialPowers.doUrlClassifyLocal(uri, tables, function(errorCode, tables) {
is(tables, test.table,
`Successful asynchronous local classification of ${test.url} with TP=${test.trackingProtection}`);
runNextTest();
}
});
});
}
runNextTest(resolve);