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; 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 // The IPC code will call this method asking us to assign an event target to new
// actors created by the ContentParent. // actors created by the ContentParent.
already_AddRefed<nsIEventTarget> already_AddRefed<nsIEventTarget>

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

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

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

@ -5158,6 +5158,9 @@ ContentParent::RecvRecordChildEvents(nsTArray<mozilla::Telemetry::ChildEventData
return IPC_OK(); return IPC_OK();
} }
//////////////////////////////////////////////////////////////////
// PURLClassifierParent
PURLClassifierParent* PURLClassifierParent*
ContentParent::AllocPURLClassifierParent(const Principal& aPrincipal, ContentParent::AllocPURLClassifierParent(const Principal& aPrincipal,
const bool& aUseTrackingProtection, const bool& aUseTrackingProtection,
@ -5200,6 +5203,48 @@ ContentParent::DeallocPURLClassifierParent(PURLClassifierParent* aActor)
return true; 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 mozilla::ipc::IPCResult
ContentParent::RecvClassifyLocal(const URIParams& aURI, const nsCString& aTables, ContentParent::RecvClassifyLocal(const URIParams& aURI, const nsCString& aTables,
nsresult *aRv, nsTArray<nsCString>* aResults) nsresult *aRv, nsTArray<nsCString>* aResults)

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

@ -605,6 +605,7 @@ public:
virtual int32_t Pid() const override; virtual int32_t Pid() const override;
// PURLClassifierParent.
virtual PURLClassifierParent* virtual PURLClassifierParent*
AllocPURLClassifierParent(const Principal& aPrincipal, AllocPURLClassifierParent(const Principal& aPrincipal,
const bool& aUseTrackingProtection, const bool& aUseTrackingProtection,
@ -615,6 +616,15 @@ public:
const bool& aUseTrackingProtection, const bool& aUseTrackingProtection,
bool* aSuccess) override; 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 virtual bool SendActivate(PBrowserParent* aTab) override
{ {
return PContentParent::SendActivate(aTab); return PContentParent::SendActivate(aTab);
@ -631,6 +641,9 @@ public:
return PContentParent::SendParentActivated(aTab, aActivated); return PContentParent::SendParentActivated(aTab, aActivated);
} }
virtual bool
DeallocPURLClassifierLocalParent(PURLClassifierLocalParent* aActor) override;
virtual bool virtual bool
DeallocPURLClassifierParent(PURLClassifierParent* aActor) override; DeallocPURLClassifierParent(PURLClassifierParent* aActor) override;

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

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

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

@ -5,19 +5,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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 protocol PContent;
include PURLClassifierInfo; include PURLClassifierInfo;
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
union MaybeInfo {
ClassifierInfo;
void_t;
};
protocol PURLClassifier protocol PURLClassifier
{ {
manager PContent; manager PContent;

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

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -11,6 +13,11 @@ struct ClassifierInfo {
nsCString prefix; nsCString prefix;
}; };
union MaybeInfo {
ClassifierInfo;
void_t;
};
} // namespace dom } // namespace dom
} // namespace mozilla } // 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 #define mozilla_dom_URLClassifierChild_h
#include "mozilla/dom/PURLClassifierChild.h" #include "mozilla/dom/PURLClassifierChild.h"
#include "mozilla/dom/PURLClassifierLocalChild.h"
#include "nsIURIClassifier.h" #include "nsIURIClassifier.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
class URLClassifierChild : public PURLClassifierChild template<typename BaseProtocol>
class URLClassifierChildBase : public BaseProtocol
{ {
public: public:
URLClassifierChild() = default; URLClassifierChildBase() = default;
void SetCallback(nsIURIClassifierCallback* aCallback) void SetCallback(nsIURIClassifierCallback* aCallback)
{ {
mCallback = aCallback; mCallback = aCallback;
} }
mozilla::ipc::IPCResult Recv__delete__(const MaybeInfo& aInfo,
const nsresult& aResult) override;
private: mozilla::ipc::IPCResult Recv__delete__(const MaybeInfo& aInfo,
~URLClassifierChild() = default; 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; nsCOMPtr<nsIURIClassifierCallback> mCallback;
}; };
using URLClassifierChild = URLClassifierChildBase<PURLClassifierChild>;
using URLClassifierLocalChild = URLClassifierChildBase<PURLClassifierLocalChild>;
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla

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

@ -11,6 +11,9 @@
using namespace mozilla; using namespace mozilla;
using namespace mozilla::dom; using namespace mozilla::dom;
/////////////////////////////////////////////////////////////////////
//URLClassifierParent.
NS_IMPL_ISUPPORTS(URLClassifierParent, nsIURIClassifierCallback) NS_IMPL_ISUPPORTS(URLClassifierParent, nsIURIClassifierCallback)
mozilla::ipc::IPCResult mozilla::ipc::IPCResult
@ -41,33 +44,41 @@ URLClassifierParent::StartClassify(nsIPrincipal* aPrincipal,
return IPC_OK(); 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 void
URLClassifierParent::ActorDestroy(ActorDestroyReason aWhy) URLClassifierParent::ActorDestroy(ActorDestroyReason aWhy)
{ {
mIPCOpen = false; 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 #define mozilla_dom_URLClassifierParent_h
#include "mozilla/dom/PURLClassifierParent.h" #include "mozilla/dom/PURLClassifierParent.h"
#include "mozilla/dom/PURLClassifierLocalParent.h"
#include "nsIURIClassifier.h" #include "nsIURIClassifier.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
class URLClassifierParent : public nsIURIClassifierCallback, template<typename BaseProtocol>
public PURLClassifierParent class URLClassifierParentBase : public nsIURIClassifierCallback,
public BaseProtocol
{ {
public: public:
URLClassifierParent() = default; // 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_THREADSAFE_ISUPPORTS
NS_DECL_NSIURICLASSIFIERCALLBACK
mozilla::ipc::IPCResult StartClassify(nsIPrincipal* aPrincipal, mozilla::ipc::IPCResult StartClassify(nsIPrincipal* aPrincipal,
bool aUseTrackingProtection, bool aUseTrackingProtection,
bool* aSuccess); bool* aSuccess);
void ActorDestroy(ActorDestroyReason aWhy) override; private:
void ClassificationFailed();
private:
~URLClassifierParent() = default; ~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 } // namespace dom

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

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

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

@ -725,7 +725,7 @@ SpecialPowersAPI.prototype = {
we will revert the permission back to the original. we will revert the permission back to the original.
inPermissions is an array of objects where each object has a type, action, context, ex: 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}] {'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 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); 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; this.SpecialPowersAPI = SpecialPowersAPI;

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

@ -1757,8 +1757,28 @@ nsUrlClassifierDBService::AsyncClassifyLocalWithTables(nsIURI *aURI,
"on main thread"); "on main thread");
if (XRE_IsContentProcess()) { if (XRE_IsContentProcess()) {
// TODO: e10s support. Bug 1343425. using namespace mozilla::dom;
return NS_ERROR_NOT_IMPLEMENTED; 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) { if (gShuttingDownThread) {

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

@ -144,21 +144,13 @@ function testService() {
is(errorCode, test.result, is(errorCode, test.result,
`Successful asynchronous classification of ${test.url} with TP=${test.trackingProtection}`); `Successful asynchronous classification of ${test.url} with TP=${test.trackingProtection}`);
try { // Same as classifyLocal except for the 'async' call.
// Same as classifyLocal except for the 'async' call. SpecialPowers.doUrlClassifyLocal(uri, tables, function(errorCode, tables) {
service.asyncClassifyLocalWithTables(uri, tables, function(errorCode, tables) { is(tables, test.table,
is(tables, test.table, `Successful asynchronous local classification of ${test.url} with TP=${test.trackingProtection}`);
`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");
runNextTest(); runNextTest();
} });
}); });
} }
runNextTest(resolve); runNextTest(resolve);