mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 13:23:07 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- remove PM alertTime custom (911dd825ec) - Bug 1208346 - Alert service Do Not Disturb backend. r=jaws (0047051b4e) - Bug 1208346 - Fix manualDoNotDisturb build bustage on Android. r=bustage (39275a49bd) - Add some shadow warnings back (64eb2adf55) - some window fixes by Roy (72e6a9b98e) - remove parameter of DoesD3D11DeviceWork (243dfb24f4) - Bug 1197296. Check the error code of Map. r=bas (9debd274fd) - Bug 1221348 - Part 1: Unify crash signatures. r=jrmuizel (80763d326d) - Bug 1221348 - Part 2: Fix texture sharing detection code on Intel. r=jrmuizel (fb0390850d) - Bug 1097321 - Add layers.amd-switchable-gfx.enabled pref. r=jrmuizel (3963a35cbc) - Bug 720589 - mMatchCounts may be accessed with a nonexisting index. r=neil (fdbdd7e228) - Bug 1224975 - add telemetry for font loading. r=m_kato (013a6e8fc7) - Bug 1188376: Split Hello Telemetry values from general WebRTC r=jib (3887cc3201) - Bug 1198883 - Part 1: Improve ICE candidates telemetry probes. r=bwc (2d02a3d752) - Bug 1198883 - Part 2: Added WebRTC ICE candidates to Telemetry. r+vladan (fa8032043f) - Bug 1201926 - Add support for keyed histograms to Fennec's Telemetry module, r=nalexander (8b96ebf026) - Bug 1213780 - Fix Telemetry reporting repeated hang annotations for Chrome hangs. r=aklotz (afde812b08) - Bug 1128768: Part 4 - Update telemetry to serialize BHR hang annotations; r=gfritzsche (7c1b8f5fa5) - Bug 1215540 - Fix Telemetry reporting repeated hang annotations for Thread hangs. r=aklotz (afed35f06f) - Bug 896740 - Limit the number of chrome-hangs reported to Telemetry. r=vladan (a37ba72225) - missing bits of Bug 932865 - Expose thread hang stats (c19c41ae06) - Bug 1187138 (part 1) - Replace nsBaseHashtable::Enumerate() calls in toolkit/ with iterators. r=froydnj. (ba92a8464f) - Bug 1121040 - Don't send RETURN keypresses to content while a satchel autocomplete entry is selected. r=Gijs,smaug (762efd7cc8) - Bug 1145146 - Remove offensive comment from nsFormFillController r=mak (7a6b0eb4e1) - Bug 1136085 - Part 1 - Don't store & collect subsession histograms on mobile. r=vladan (911084001c) - missing bits of Bug 1023461 - Add HangStack class to support internal string buffer; r=vladan (599bee2150) - Bug 1196381 - Eliminate breakpad dependency in ThreadStackHelper; r=nfroyd r=snorp (ff8a632975) - fix misspatch of 1157282 and 1198883 (9a216ab188) - Bug 1034138 - a. Get native stack for permahangs in BHM; r=snorp (772970d0e0) - Bug 1211411 - Limit the number of thread hang stats reported to Telemetry. r=vladan (fd72bc8b62) - Bug 1219751 - Change the the depth limit of the thread hangs stack to use the 99th percentile. r=gfritzsche (fc59bd7598) - Bug 1133521 - Enable BHR on Beta. r=vladan (2501c6a0ff) - Bug 1219216 - Fix a wrong comment in BackgroundHangMonitor.h. r=gfritzsche (e974320361) - bits of Bug 1134279 - Change Telemetry data producers to use the correct (d00e84b7f3) - bits of Bug 977026 - Part 2: B2G loader (bf1208a73a) - bug 1198450 - Firefox fails to load about:home if Firefox was installed to a folder with non-Latin name r=jimm (c4df06a69e) - Bug 1222167 - fix initialization order in GeckoChildProcessHost; r=jld (6bad274479) - Bug 1141693 - Build and use a PIE plugin-container on Android 5.0+. Based on a patch by Mike Hommey. r=me,glandium (78dc877aec) - Bug 1187533 - Change how Gtk+2 plugin-container is started on Gtk+3 builds. r=billm (93c2b8a1b0) - Bug 1063359 - Unconditionally use -Wl,--no-as-needed when building with GNU ld/gold. r=mshal (643e92ca49) - Bug 971811 - Don't prepend an empty existing DYLD_INSERT_LIBRARIES path when launching the plugin. r=smichaud (c72df0073c) - Bug 1189352: Fix NSPR_LOG_FILE with absolute paths for sandboxed child on Windows. r=bbondy (f4bb51c123) - Bug 1189967 - Be slightly more explicit about some conversions to std::wstring. r=nfroyd (7bec611359) - Bug 1201438: Add non-sandboxed Windows content processes as target peers for handle duplication. r=bbondy (1ca7f499e9) - Bug 1201438 - Fixup for builds with disabled sandbox. (de125d156e) - Bug 1165895: Add NPAPI sandbox rule for the crash server pipe and x64 Temp dir write access. r=bbondy (e9f601912d) - Bug 1202988 - Don't use GetTempPath for flash's mms.cfg hack for low integrity. r=aklotz (b4a0d7f856) - Bug 1225023: Allow Flash Player to create Adobe\Flash Player and Macromedia\Flash Player directories. r=bbondy (c5120afc1d) - Bug 1218681 - add plugin-container standalone process code. The Code associate with ARCH. r=hev (03dfb21776) - bug 1130976 - Flash context menu causes CPOW deadlock with AdBlock Plus, plugins should spin even loop in content process instead of the chrome process r=billm (52f4d33633) - Bug 1157237: Move invocation of async NPP_New to an async task; r=jimm (7b6c1a577e) - Bug 1175147 - Don't do threadsafety asserts for NPN_MemAlloc and friends, r=jimm (b4ce5b33ce) - fix strange misspatch (8a96a61819) - Bug 1219244 - use UniquePtr instead of nsAutoArrayPtr in dom/plugins/; r=aklotz (19fabc55b5) - Bug 1155503: BrowserStreamParent should null out its NPStream pointer and we should check for it; r=jimm (eddb82b8b4) - some crashrep stuff (bb2b046090) - Bug 1192077 - Convert AndroidBridge JNIEnv calls; r=esawin (821453089e) - Bug 554171 - Add plugin thread checks to functions that must only be called on the main thread. r=jimm (f2eb3822da) - Bug 1149358: Ensure that plugin streams are not manipulated by PluginAsyncSurrogate if plugin destruction is imminent; r=jimm (6dd99c94ee) - Bug 1198302 - Ensure that PluginAsyncSurrogate::NotifyAsyncInitFailed properly aborts any PluginAsyncSurrogate::WaitForInit calls. r=jimm (23c1fbfcfe) - Bug 1201239 - Add a proper null check in PluginAsyncSurrogate::NotifyAsyncInitFailed; r=jimm (5d8ff9f8aa) - Bug 1208059: Make nsNPAPIPluginInstance support WeakPtr and modify PluginAsyncSurrogate to use it; r=jimm (174a3166b1) - Bug 1171453: Make ParentNPObjects aware of AsyncNPObject wrappers; r=jimm (92e608831d) - Bug 1217726 - Fix -Wimplicit-fallthrough warnings in dom/plugins. r=jimm (32db26ede8) - Bug 1167720 - Fix invalid window ID provided to GTK3 plugin container children. r=karlt (d8c2de0c19) - Remove Windows-specific synchronous plugin drawing code. (bug 1218688 part 1, r=jimm) (5e4b60ea33) - Remove Linux-specific synchronous plugin drawing code. (bug 1218688 part 2, r=jimm) (edb29f27b8) - Remove Mac-specific synchronous plugin drawing code. (bug 1218688 part 3, r=benwa) (acc6b57b23) - Assert that we do not attempt synchronous painting of windowless Desktop plugins. (bug 1218688 part 4, r=bsmedberg) (c34094b038) - Bug 1195472 - Call Show after Enable on puppet widgets to avoid an assertion when running crash tests. r=aklotz (405ed2c1d1) - Add explicit keyword to AsyncScrollBase constructor to fix static analysis build (bug 1139220 part 6, r=shu) (4cc37b9a3b) - Bug 1146561 - Add back the visibility check for Mac plugins. r=jmuizelaar (91a4a5a8e9) - namespace (9b4919f8fa) - Bug 1217307 - Remove some unnecessary null checks in rest of dom/. r=njn (de5d69880a) - Bug 1225137 - Avoid crash on some platforms if scrollbar fading is enabled and the duration is set to zero. r=spohl (a16954de2f) - Bug 1114554 - Disable NotificationStorage debug logging. r=dholbert (c2722fa4ed) - Bug 1073551 - fix doorhangers to not steal focus unless explicitly opened using mouse or keyboard, r=jaws (be6109cf6d) - Bug 1169629: Add-on install confirmation notification appears anchored to older dismissed anchors. r=dao (684535c7cc) - Bug 1194706: make sure that the notification icons and doorhangers are shown in undocked chat windows too. r=Mossop (68e0ced913) - Bug 1207089 - Telemetry for permission notifications. r=MattN,vladan (ff421236ea) - Bug 1215526 - part 4 - make preprocess-tab-svgs.py report extra dependencies; r=glandium (98b64b5c45)
This commit is contained in:
@@ -130,7 +130,7 @@
|
||||
#endif
|
||||
#ifdef MOZ_GTK3
|
||||
@BINPATH@/@DLL_PREFIX@mozgtk@DLL_SUFFIX@
|
||||
@BINPATH@/@DLL_PREFIX@mozgtk2@DLL_SUFFIX@
|
||||
@BINPATH@/gtk2/@DLL_PREFIX@mozgtk@DLL_SUFFIX@
|
||||
#endif
|
||||
|
||||
[browser]
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
#endif
|
||||
#ifdef MOZ_GTK3
|
||||
@BINPATH@/@DLL_PREFIX@mozgtk@DLL_SUFFIX@
|
||||
@BINPATH@/@DLL_PREFIX@mozgtk2@DLL_SUFFIX@
|
||||
@BINPATH@/gtk2/@DLL_PREFIX@mozgtk@DLL_SUFFIX@
|
||||
#endif
|
||||
|
||||
[browser]
|
||||
|
||||
@@ -102,16 +102,16 @@
|
||||
}
|
||||
|
||||
.notification-anchor-icon {
|
||||
%ifdef MOZ_WIDGET_GTK
|
||||
list-style-image: url(moz-icon://stock/gtk-dialog-info?size=16);
|
||||
%else
|
||||
list-style-image: url(chrome://global/skin/icons/information-16.png);
|
||||
%endif
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.default-notification-icon,
|
||||
#default-notification-icon {
|
||||
list-style-image: url(chrome://global/skin/icons/information-16.png);
|
||||
}
|
||||
|
||||
.identity-notification-icon,
|
||||
#identity-notification-icon {
|
||||
list-style-image: url(chrome://mozapps/skin/profile/profileicon.png);
|
||||
@@ -280,19 +280,22 @@
|
||||
100% { transform: translateX(0); }
|
||||
}
|
||||
|
||||
%ifdef XP_MACOSX
|
||||
/* HiDPI notification icons */
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
@media (min-resolution: 1.1dppx) {
|
||||
#notification-popup-box {
|
||||
border-image: url("chrome://browser/skin/urlbar-arrow@2x.png") 0 16 0 0 fill;
|
||||
}
|
||||
|
||||
.default-notification-icon,
|
||||
#default-notification-icon {
|
||||
.notification-anchor-icon {
|
||||
%ifdef MOZ_WIDGET_GTK
|
||||
list-style-image: url(moz-icon://stock/gtk-dialog-info?size=dialog);
|
||||
%else
|
||||
list-style-image: url(chrome://global/skin/icons/information-32.png);
|
||||
%endif
|
||||
}
|
||||
|
||||
%ifdef XP_MACOSX
|
||||
/* OSX only until we have icons for Windows and Linux */
|
||||
.geo-notification-icon,
|
||||
#geo-notification-icon {
|
||||
list-style-image: url(chrome://browser/skin/Geolocation-16@2x.png);
|
||||
@@ -311,6 +314,7 @@
|
||||
list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
|
||||
}
|
||||
|
||||
#login-fill-notification-icon,
|
||||
#password-notification-icon {
|
||||
list-style-image: url(chrome://mozapps/skin/passwordmgr/key-16@2x.png);
|
||||
}
|
||||
@@ -451,5 +455,5 @@
|
||||
#servicesInstall-notification-icon {
|
||||
list-style-image: url(chrome://browser/skin/social/services-16@2x.png);
|
||||
}
|
||||
}
|
||||
%endif
|
||||
}
|
||||
|
||||
+3
-1
@@ -8338,7 +8338,9 @@ else
|
||||
# so if the file is named libsomething.so. The lib/ path is also required
|
||||
# because the unpacked file will be under the lib/ subdirectory and will
|
||||
# need to be executed from that path.
|
||||
MOZ_CHILD_PROCESS_NAME="lib/libplugin-container.so"
|
||||
MOZ_CHILD_PROCESS_NAME="libplugin-container.so"
|
||||
MOZ_CHILD_PROCESS_NAME_PIE="libplugin-container-pie.so"
|
||||
AC_SUBST(MOZ_CHILD_PROCESS_NAME_PIE)
|
||||
fi
|
||||
MOZ_CHILD_PROCESS_BUNDLE="plugin-container.app/Contents/MacOS/"
|
||||
|
||||
|
||||
@@ -848,7 +848,6 @@ GetSubmissionFromForm(nsGenericHTMLElement* aForm,
|
||||
*aFormSubmission = new nsFSURLEncoded(charset, method, doc,
|
||||
aOriginatingElement);
|
||||
}
|
||||
NS_ENSURE_TRUE(*aFormSubmission, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -298,8 +298,6 @@ nsJSONWriter::Write(const char16_t *aBuffer, uint32_t aLength)
|
||||
|
||||
if (!mDidWrite) {
|
||||
mBuffer = new char16_t[JSON_STREAM_BUFSIZE];
|
||||
if (!mBuffer)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
mDidWrite = true;
|
||||
}
|
||||
|
||||
@@ -481,9 +479,6 @@ nsresult
|
||||
NS_NewJSON(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
||||
{
|
||||
nsJSON* json = new nsJSON();
|
||||
if (!json)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(json);
|
||||
*aResult = json;
|
||||
|
||||
|
||||
@@ -410,8 +410,6 @@ nsresult nsJSChannel::Init(nsIURI *aURI)
|
||||
|
||||
// Create the nsIStreamIO layer used by the nsIStreamIOChannel.
|
||||
mIOThunk = new nsJSThunk();
|
||||
if (!mIOThunk)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Create a stock input stream channel...
|
||||
// Remember, until AsyncOpen is called, the script will not be evaluated
|
||||
@@ -1129,8 +1127,6 @@ nsJSProtocolHandler::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsJSProtocolHandler* ph = new nsJSProtocolHandler();
|
||||
if (!ph)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(ph);
|
||||
nsresult rv = ph->Init();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
||||
@@ -640,9 +640,6 @@ InitMediaCache()
|
||||
return;
|
||||
|
||||
gMediaCache = new MediaCache();
|
||||
if (!gMediaCache)
|
||||
return;
|
||||
|
||||
nsresult rv = gMediaCache->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
delete gMediaCache;
|
||||
|
||||
@@ -548,8 +548,6 @@ nsresult ChannelMediaResource::OpenChannel(nsIStreamListener** aStreamListener)
|
||||
}
|
||||
|
||||
mListener = new Listener(this);
|
||||
NS_ENSURE_TRUE(mListener, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (aStreamListener) {
|
||||
*aStreamListener = mListener;
|
||||
NS_ADDREF(*aStreamListener);
|
||||
|
||||
@@ -120,7 +120,9 @@ MediaEngineWebRTC::EnumerateVideoDevices(dom::MediaSourceEnum aMediaSource,
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
// get the JVM
|
||||
JavaVM *jvm = mozilla::AndroidBridge::Bridge()->GetVM();
|
||||
JavaVM* jvm;
|
||||
JNIEnv* const env = jni::GetEnvForThread();
|
||||
MOZ_ALWAYS_TRUE(!env->GetJavaVM(&jvm));
|
||||
|
||||
if (webrtc::VideoEngine::SetAndroidObjects(jvm) != 0) {
|
||||
LOG(("VieCapture:SetAndroidObjects Failed"));
|
||||
@@ -245,8 +247,9 @@ MediaEngineWebRTC::EnumerateAudioDevices(dom::MediaSourceEnum aMediaSource,
|
||||
jobject context = mozilla::AndroidBridge::Bridge()->GetGlobalContextRef();
|
||||
|
||||
// get the JVM
|
||||
JavaVM *jvm = mozilla::AndroidBridge::Bridge()->GetVM();
|
||||
JNIEnv *env = GetJNIForThread();
|
||||
JavaVM* jvm;
|
||||
JNIEnv* const env = jni::GetEnvForThread();
|
||||
MOZ_ALWAYS_TRUE(!env->GetJavaVM(&jvm));
|
||||
|
||||
if (webrtc::VoiceEngine::SetAndroidObjects(jvm, env, (void*)context) != 0) {
|
||||
LOG(("VoiceEngine:SetAndroidObjects Failed"));
|
||||
|
||||
@@ -39,7 +39,7 @@ const kMessages = [
|
||||
"Notification:GetAllCrossOrigin"
|
||||
];
|
||||
|
||||
let NotificationDB = {
|
||||
var NotificationDB = {
|
||||
|
||||
// Ensure we won't call init() while xpcom-shutdown is performed
|
||||
_shutdownInProgress: false,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const DEBUG = true;
|
||||
const DEBUG = false;
|
||||
function debug(s) { dump("-*- NotificationStorage.js: " + s + "\n"); }
|
||||
|
||||
const Cc = Components.classes;
|
||||
|
||||
@@ -37,7 +37,7 @@ nsresult
|
||||
PluginPRLibrary::NP_Initialize(NPNetscapeFuncs* bFuncs,
|
||||
NPPluginFuncs* pFuncs, NPError* error)
|
||||
{
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
JNIEnv* env = jni::GetEnvForThread();
|
||||
|
||||
mozilla::AutoLocalJNIFrame jniFrame(env);
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ AudioRunnable::Run()
|
||||
{
|
||||
PR_SetCurrentThreadName("Android Audio");
|
||||
|
||||
JNIEnv* jenv = GetJNIForThread();
|
||||
JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
|
||||
|
||||
mozilla::AutoLocalJNIFrame autoFrame(jenv, 2);
|
||||
|
||||
@@ -207,7 +207,7 @@ anp_audio_newTrack(uint32_t sampleRate, // sampling rate in Hz
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JNIEnv *jenv = GetJNIForThread();
|
||||
JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
|
||||
|
||||
s->at_class = init_jni_bindings(jenv);
|
||||
s->rate = sampleRate;
|
||||
@@ -303,7 +303,7 @@ anp_audio_start(ANPAudioTrack* s)
|
||||
return;
|
||||
}
|
||||
|
||||
JNIEnv *jenv = GetJNIForThread();
|
||||
JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
|
||||
|
||||
mozilla::AutoLocalJNIFrame autoFrame(jenv, 0);
|
||||
jenv->CallVoidMethod(s->output_unit, at.play);
|
||||
@@ -331,7 +331,7 @@ anp_audio_pause(ANPAudioTrack* s)
|
||||
return;
|
||||
}
|
||||
|
||||
JNIEnv *jenv = GetJNIForThread();
|
||||
JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
|
||||
|
||||
mozilla::AutoLocalJNIFrame autoFrame(jenv, 0);
|
||||
jenv->CallVoidMethod(s->output_unit, at.pause);
|
||||
@@ -345,7 +345,7 @@ anp_audio_stop(ANPAudioTrack* s)
|
||||
}
|
||||
|
||||
s->isStopped = true;
|
||||
JNIEnv *jenv = GetJNIForThread();
|
||||
JNIEnv* const jenv = mozilla::jni::GetEnvForThread();
|
||||
|
||||
mozilla::AutoLocalJNIFrame autoFrame(jenv, 0);
|
||||
jenv->CallVoidMethod(s->output_unit, at.stop);
|
||||
|
||||
@@ -833,7 +833,6 @@ AsyncCallbackAutoLock::~AsyncCallbackAutoLock()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NPP NPPStack::sCurrentNPP = nullptr;
|
||||
|
||||
const char *
|
||||
@@ -884,7 +883,6 @@ _geturl(NPP npp, const char* relativeURL, const char* target)
|
||||
(strncmp(relativeURL, "ftp:", 4) != 0)) {
|
||||
nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *) npp->ndata;
|
||||
|
||||
|
||||
const char *name = nullptr;
|
||||
RefPtr<nsPluginHost> host = nsPluginHost::GetInst();
|
||||
host->GetPluginName(inst, &name);
|
||||
@@ -1037,7 +1035,7 @@ NPError
|
||||
_destroystream(NPP npp, NPStream *pstream, NPError reason)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_write called from the wrong thread\n"));
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_destroystream called from the wrong thread\n"));
|
||||
return NPERR_INVALID_PARAM;
|
||||
}
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
@@ -1946,7 +1944,7 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN) || (MOZ_WIDGET_GTK == 2) || defined(MOZ_WIDGET_QT)
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
|
||||
case NPNVnetscapeWindow: {
|
||||
if (!npp || !npp->ndata)
|
||||
return NPERR_INVALID_INSTANCE_ERROR;
|
||||
@@ -2105,9 +2103,7 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
#ifndef NP_NO_QUICKDRAW
|
||||
@@ -2336,14 +2332,13 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
||||
|
||||
// we no longer hand out any XPCOM objects
|
||||
case NPNVDOMElement:
|
||||
// fall through
|
||||
case NPNVDOMWindow:
|
||||
// fall through
|
||||
case NPNVserviceManager:
|
||||
// old XPCOM objects, no longer supported, but null out the out
|
||||
// param to avoid crashing plugins that still try to use this.
|
||||
*(nsISupports**)result = nullptr;
|
||||
// fall through
|
||||
MOZ_FALLTHROUGH;
|
||||
|
||||
default:
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("NPN_getvalue unhandled get value: %d\n", variable));
|
||||
return NPERR_GENERIC_ERROR;
|
||||
@@ -2631,6 +2626,11 @@ NPError
|
||||
_getvalueforurl(NPP instance, NPNURLVariable variable, const char *url,
|
||||
char **value, uint32_t *len)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getvalueforurl called from the wrong thread\n"));
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
if (!instance) {
|
||||
return NPERR_INVALID_PARAM;
|
||||
}
|
||||
@@ -2689,6 +2689,11 @@ NPError
|
||||
_setvalueforurl(NPP instance, NPNURLVariable variable, const char *url,
|
||||
const char *value, uint32_t len)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_setvalueforurl called from the wrong thread\n"));
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
if (!instance) {
|
||||
return NPERR_INVALID_PARAM;
|
||||
}
|
||||
@@ -2700,7 +2705,7 @@ _setvalueforurl(NPP instance, NPNURLVariable variable, const char *url,
|
||||
switch (variable) {
|
||||
case NPNURLVCookie:
|
||||
{
|
||||
if (!url || !value || (0 >= len))
|
||||
if (!value || 0 == len)
|
||||
return NPERR_INVALID_PARAM;
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
@@ -2745,6 +2750,11 @@ _getauthenticationinfo(NPP instance, const char *protocol, const char *host,
|
||||
char **username, uint32_t *ulen, char **password,
|
||||
uint32_t *plen)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_getauthenticationinfo called from the wrong thread\n"));
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
if (!instance || !protocol || !host || !scheme || !realm || !username ||
|
||||
!ulen || !password || !plen)
|
||||
return NPERR_INVALID_PARAM;
|
||||
@@ -2801,6 +2811,11 @@ _getauthenticationinfo(NPP instance, const char *protocol, const char *host,
|
||||
uint32_t
|
||||
_scheduletimer(NPP instance, uint32_t interval, NPBool repeat, PluginTimerFunc timerFunc)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_scheduletimer called from the wrong thread\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
|
||||
if (!inst)
|
||||
return 0;
|
||||
@@ -2811,6 +2826,11 @@ _scheduletimer(NPP instance, uint32_t interval, NPBool repeat, PluginTimerFunc t
|
||||
void
|
||||
_unscheduletimer(NPP instance, uint32_t timerID)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_unscheduletimer called from the wrong thread\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
// Sometimes Flash calls this with a dead NPP instance. Ensure the one we have
|
||||
// here is valid and maps to a nsNPAPIPluginInstance.
|
||||
@@ -2827,6 +2847,11 @@ _unscheduletimer(NPP instance, uint32_t timerID)
|
||||
NPError
|
||||
_popupcontextmenu(NPP instance, NPMenu* menu)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_popupcontextmenu called from the wrong thread\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
|
||||
|
||||
@@ -2876,6 +2901,11 @@ _popupcontextmenu(NPP instance, NPMenu* menu)
|
||||
NPBool
|
||||
_convertpoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_convertpoint called from the wrong thread\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
|
||||
if (!inst)
|
||||
return false;
|
||||
@@ -2886,6 +2916,11 @@ _convertpoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace so
|
||||
void
|
||||
_urlredirectresponse(NPP instance, void* notifyData, NPBool allow)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_convertpoint called from the wrong thread\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
|
||||
if (!inst) {
|
||||
return;
|
||||
|
||||
@@ -582,9 +582,6 @@ nsNPAPIPluginInstance::NewStreamFromPlugin(const char* type, const char* target,
|
||||
nsIOutputStream* *result)
|
||||
{
|
||||
nsPluginStreamToFile* stream = new nsPluginStreamToFile(target, mOwner);
|
||||
if (!stream)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return stream->QueryInterface(kIOutputStreamIID, (void**)result);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ class SharedPluginTexture;
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/PluginLibrary.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
|
||||
class nsPluginStreamListenerPeer; // browser-initiated stream class
|
||||
class nsNPAPIPluginStreamListener; // plugin-initiated stream class
|
||||
@@ -77,11 +78,13 @@ public:
|
||||
};
|
||||
|
||||
class nsNPAPIPluginInstance final : public nsIAudioChannelAgentCallback
|
||||
, public mozilla::SupportsWeakPtr<nsNPAPIPluginInstance>
|
||||
{
|
||||
private:
|
||||
typedef mozilla::PluginLibrary PluginLibrary;
|
||||
|
||||
public:
|
||||
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsNPAPIPluginInstance)
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK
|
||||
|
||||
|
||||
@@ -2158,9 +2158,6 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
||||
|
||||
pluginTag = new nsPluginTag(&info, fileModTime, fromExtension);
|
||||
pluginFile.FreePluginInfo(info);
|
||||
if (!pluginTag)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
pluginTag->mLibrary = library;
|
||||
uint32_t state;
|
||||
rv = pluginTag->GetBlocklistState(&state);
|
||||
@@ -3251,8 +3248,6 @@ nsPluginHost::EnsurePrivateDirServiceProvider()
|
||||
if (!mPrivateDirServiceProvider) {
|
||||
nsresult rv;
|
||||
mPrivateDirServiceProvider = new nsPluginDirServiceProvider();
|
||||
if (!mPrivateDirServiceProvider)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsCOMPtr<nsIDirectoryService> dirService(do_GetService(kDirectoryServiceContractID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
@@ -328,13 +328,10 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
|
||||
mPluginFrame = nullptr;
|
||||
mWidgetCreationComplete = false;
|
||||
#ifdef XP_MACOSX
|
||||
memset(&mCGPluginPortCopy, 0, sizeof(NP_CGContext));
|
||||
mInCGPaintLevel = 0;
|
||||
mSentInitialTopLevelWindowEvent = false;
|
||||
mLastWindowIsActive = false;
|
||||
mLastContentFocused = false;
|
||||
mLastScaleFactor = 1.0;
|
||||
mColorProfile = nullptr;
|
||||
mShouldBlurOnActivate = false;
|
||||
#endif
|
||||
mContentFocused = false;
|
||||
@@ -1133,9 +1130,6 @@ void nsPluginInstanceOwner::AddToCARefreshTimer() {
|
||||
|
||||
if (!sCARefreshListeners) {
|
||||
sCARefreshListeners = new nsTArray<nsPluginInstanceOwner*>();
|
||||
if (!sCARefreshListeners) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sCARefreshListeners->Contains(this)) {
|
||||
@@ -1146,9 +1140,6 @@ void nsPluginInstanceOwner::AddToCARefreshTimer() {
|
||||
|
||||
if (!sCATimer) {
|
||||
sCATimer = new nsCOMPtr<nsITimer>();
|
||||
if (!sCATimer) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sCARefreshListeners->Length() == 1) {
|
||||
@@ -1176,91 +1167,6 @@ void nsPluginInstanceOwner::RemoveFromCARefreshTimer() {
|
||||
}
|
||||
}
|
||||
|
||||
void nsPluginInstanceOwner::RenderCoreAnimation(CGContextRef aCGContext,
|
||||
int aWidth, int aHeight)
|
||||
{
|
||||
if (aWidth == 0 || aHeight == 0)
|
||||
return;
|
||||
|
||||
if (!mCARenderer) {
|
||||
mCARenderer = new nsCARenderer();
|
||||
}
|
||||
|
||||
// aWidth and aHeight are in "display pixels". In non-HiDPI modes
|
||||
// "display pixels" are device pixels. But in HiDPI modes each
|
||||
// display pixel corresponds to more than one device pixel.
|
||||
double scaleFactor = 1.0;
|
||||
GetContentsScaleFactor(&scaleFactor);
|
||||
|
||||
if (!mIOSurface ||
|
||||
(mIOSurface->GetWidth() != (size_t)aWidth ||
|
||||
mIOSurface->GetHeight() != (size_t)aHeight ||
|
||||
mIOSurface->GetContentsScaleFactor() != scaleFactor)) {
|
||||
mIOSurface = nullptr;
|
||||
|
||||
// If the renderer is backed by an IOSurface, resize it as required.
|
||||
mIOSurface = MacIOSurface::CreateIOSurface(aWidth, aHeight, scaleFactor);
|
||||
if (mIOSurface) {
|
||||
RefPtr<MacIOSurface> attachSurface = MacIOSurface::LookupSurface(
|
||||
mIOSurface->GetIOSurfaceID(),
|
||||
scaleFactor);
|
||||
if (attachSurface) {
|
||||
mCARenderer->AttachIOSurface(attachSurface);
|
||||
} else {
|
||||
NS_ERROR("IOSurface attachment failed");
|
||||
mIOSurface = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mColorProfile) {
|
||||
mColorProfile = CreateSystemColorSpace();
|
||||
}
|
||||
|
||||
if (mCARenderer->isInit() == false) {
|
||||
void *caLayer = nullptr;
|
||||
nsresult rv = mInstance->GetValueFromPlugin(NPPVpluginCoreAnimationLayer, &caLayer);
|
||||
if (NS_FAILED(rv) || !caLayer) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't run Flash in-process so we can unconditionally disallow
|
||||
// the offliner renderer.
|
||||
mCARenderer->SetupRenderer(caLayer, aWidth, aHeight, scaleFactor,
|
||||
DISALLOW_OFFLINE_RENDERER);
|
||||
|
||||
// Setting up the CALayer requires resetting the painting otherwise we
|
||||
// get garbage for the first few frames.
|
||||
FixUpPluginWindow(ePluginPaintDisable);
|
||||
FixUpPluginWindow(ePluginPaintEnable);
|
||||
}
|
||||
|
||||
CGImageRef caImage = nullptr;
|
||||
nsresult rt = mCARenderer->Render(aWidth, aHeight, scaleFactor, &caImage);
|
||||
if (rt == NS_OK && mIOSurface && mColorProfile) {
|
||||
nsCARenderer::DrawSurfaceToCGContext(aCGContext, mIOSurface, mColorProfile,
|
||||
0, 0, aWidth, aHeight);
|
||||
} else if (rt == NS_OK && caImage != nullptr) {
|
||||
// Significant speed up by resetting the scaling
|
||||
::CGContextSetInterpolationQuality(aCGContext, kCGInterpolationNone );
|
||||
::CGContextTranslateCTM(aCGContext, 0, (double) aHeight * scaleFactor);
|
||||
::CGContextScaleCTM(aCGContext, scaleFactor, -scaleFactor);
|
||||
|
||||
::CGContextDrawImage(aCGContext, CGRectMake(0,0,aWidth,aHeight), caImage);
|
||||
} else {
|
||||
NS_NOTREACHED("nsCARenderer::Render failure");
|
||||
}
|
||||
}
|
||||
|
||||
void* nsPluginInstanceOwner::GetPluginPortCopy()
|
||||
{
|
||||
if (GetDrawingModel() == NPDrawingModelCoreGraphics ||
|
||||
GetDrawingModel() == NPDrawingModelCoreAnimation ||
|
||||
GetDrawingModel() == NPDrawingModelInvalidatingCoreAnimation)
|
||||
return &mCGPluginPortCopy;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void nsPluginInstanceOwner::SetPluginPort()
|
||||
{
|
||||
void* pluginPort = GetPluginPort();
|
||||
@@ -1268,18 +1174,6 @@ void nsPluginInstanceOwner::SetPluginPort()
|
||||
return;
|
||||
mPluginWindow->window = pluginPort;
|
||||
}
|
||||
|
||||
void nsPluginInstanceOwner::BeginCGPaint()
|
||||
{
|
||||
++mInCGPaintLevel;
|
||||
}
|
||||
|
||||
void nsPluginInstanceOwner::EndCGPaint()
|
||||
{
|
||||
--mInCGPaintLevel;
|
||||
NS_ASSERTION(mInCGPaintLevel >= 0, "Mismatched call to nsPluginInstanceOwner::EndCGPaint()!");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// static
|
||||
@@ -1367,7 +1261,7 @@ bool nsPluginInstanceOwner::AddPluginView(const LayoutDeviceRect& aRect /* = Lay
|
||||
if (!mJavaView)
|
||||
return false;
|
||||
|
||||
mJavaView = (void*)AndroidBridge::GetJNIEnv()->NewGlobalRef((jobject)mJavaView);
|
||||
mJavaView = (void*)jni::GetGeckoThreadEnv()->NewGlobalRef((jobject)mJavaView);
|
||||
}
|
||||
|
||||
if (AndroidBridge::Bridge())
|
||||
@@ -1386,7 +1280,7 @@ void nsPluginInstanceOwner::RemovePluginView()
|
||||
|
||||
widget::GeckoAppShell::RemovePluginView(
|
||||
jni::Object::Ref::From(jobject(mJavaView)), mFullScreen);
|
||||
AndroidBridge::GetJNIEnv()->DeleteGlobalRef((jobject)mJavaView);
|
||||
jni::GetGeckoThreadEnv()->DeleteGlobalRef((jobject)mJavaView);
|
||||
mJavaView = nullptr;
|
||||
|
||||
if (mFullScreen)
|
||||
@@ -1461,7 +1355,7 @@ void nsPluginInstanceOwner::ExitFullScreen() {
|
||||
}
|
||||
|
||||
void nsPluginInstanceOwner::ExitFullScreen(jobject view) {
|
||||
JNIEnv* env = AndroidBridge::GetJNIEnv();
|
||||
JNIEnv* env = jni::GetGeckoThreadEnv();
|
||||
|
||||
if (sFullScreenInstance && sFullScreenInstance->mInstance &&
|
||||
env->IsSameObject(view, (jobject)sFullScreenInstance->mInstance->GetJavaSurface())) {
|
||||
@@ -2506,8 +2400,6 @@ nsPluginInstanceOwner::Destroy()
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
RemoveFromCARefreshTimer();
|
||||
if (mColorProfile)
|
||||
::CGColorSpaceRelease(mColorProfile);
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
|
||||
@@ -3089,11 +2981,7 @@ void nsPluginInstanceOwner::FixUpPluginWindow(int32_t inPaintState)
|
||||
return;
|
||||
}
|
||||
|
||||
// If we've already set up a CGContext in nsPluginFrame::PaintPlugin(), we
|
||||
// don't want calls to SetPluginPort() to step on our work.
|
||||
if (mInCGPaintLevel < 1) {
|
||||
SetPluginPort();
|
||||
}
|
||||
SetPluginPort();
|
||||
|
||||
nsIntSize widgetClip = mPluginFrame->GetWidgetlessClipRect().Size();
|
||||
|
||||
|
||||
@@ -135,19 +135,9 @@ public:
|
||||
// This calls into the plugin (NPP_SetWindow) and can run script.
|
||||
void FixUpPluginWindow(int32_t inPaintState);
|
||||
void HidePluginWindow();
|
||||
// Return a pointer to the internal nsPluginPort structure that's used to
|
||||
// store a copy of plugin port info and to detect when it's been changed.
|
||||
void* GetPluginPortCopy();
|
||||
// Set plugin port info in the plugin (in the 'window' member of the
|
||||
// NPWindow structure passed to the plugin by SetWindow()).
|
||||
void SetPluginPort();
|
||||
// Flag when we've set up a Thebes (and CoreGraphics) context in
|
||||
// nsPluginFrame::PaintPlugin(). We need to know this in
|
||||
// FixUpPluginWindow() (i.e. we need to know when FixUpPluginWindow() has
|
||||
// been called from nsPluginFrame::PaintPlugin() when we're using the
|
||||
// CoreGraphics drawing model).
|
||||
void BeginCGPaint();
|
||||
void EndCGPaint();
|
||||
#else // XP_MACOSX
|
||||
void UpdateWindowPositionAndClipRect(bool aSetWindow);
|
||||
void UpdateWindowVisibility(bool aVisible);
|
||||
@@ -292,11 +282,6 @@ private:
|
||||
RefPtr<nsPluginHost> mPluginHost;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
NP_CGContext mCGPluginPortCopy;
|
||||
int32_t mInCGPaintLevel;
|
||||
RefPtr<MacIOSurface> mIOSurface;
|
||||
RefPtr<nsCARenderer> mCARenderer;
|
||||
CGColorSpaceRef mColorProfile;
|
||||
static nsCOMPtr<nsITimer> *sCATimer;
|
||||
static nsTArray<nsPluginInstanceOwner*> *sCARefreshListeners;
|
||||
bool mSentInitialTopLevelWindowEvent;
|
||||
|
||||
@@ -41,7 +41,7 @@ nsresult PLUG_NewPluginNativeWindow(nsPluginNativeWindow ** aPluginNativeWindow)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
|
||||
*aPluginNativeWindow = new nsPluginNativeWindowPLATFORM();
|
||||
return *aPluginNativeWindow ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult PLUG_DeletePluginNativeWindow(nsPluginNativeWindow * aPluginNativeWindow)
|
||||
|
||||
@@ -57,7 +57,7 @@ nsresult PLUG_NewPluginNativeWindow(nsPluginNativeWindow ** aPluginNativeWindow)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
|
||||
*aPluginNativeWindow = new nsPluginNativeWindowGtk();
|
||||
return *aPluginNativeWindow ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult PLUG_DeletePluginNativeWindow(nsPluginNativeWindow * aPluginNativeWindow)
|
||||
|
||||
@@ -62,7 +62,7 @@ nsresult PLUG_NewPluginNativeWindow(nsPluginNativeWindow **aPluginNativeWindow)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
|
||||
*aPluginNativeWindow = new nsPluginNativeWindowQt();
|
||||
return *aPluginNativeWindow ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult PLUG_DeletePluginNativeWindow(nsPluginNativeWindow * aPluginNativeWindow)
|
||||
|
||||
@@ -575,13 +575,11 @@ nsPluginNativeWindowWin::GetPluginWindowEvent(HWND aWnd, UINT aMsg, WPARAM aWPar
|
||||
if (!mCachedPluginWindowEvent)
|
||||
{
|
||||
event = new PluginWindowEvent();
|
||||
if (!event) return nullptr;
|
||||
mCachedPluginWindowEvent = event;
|
||||
}
|
||||
else if (mCachedPluginWindowEvent->InUse())
|
||||
{
|
||||
event = new PluginWindowEvent();
|
||||
if (!event) return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -739,8 +737,7 @@ nsresult PLUG_NewPluginNativeWindow(nsPluginNativeWindow ** aPluginNativeWindow)
|
||||
NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
|
||||
|
||||
*aPluginNativeWindow = new nsPluginNativeWindowWin();
|
||||
|
||||
return *aPluginNativeWindow ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult PLUG_DeletePluginNativeWindow(nsPluginNativeWindow * aPluginNativeWindow)
|
||||
|
||||
@@ -735,12 +735,7 @@ nsPluginStreamListenerPeer::RequestRead(NPByteRange* rangeList)
|
||||
} else {
|
||||
nsWeakPtr weakpeer =
|
||||
do_GetWeakReference(static_cast<nsISupportsWeakReference*>(this));
|
||||
nsPluginByteRangeStreamListener *brrListener =
|
||||
new nsPluginByteRangeStreamListener(weakpeer);
|
||||
if (brrListener)
|
||||
converter = brrListener;
|
||||
else
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
converter = new nsPluginByteRangeStreamListener(weakpeer);
|
||||
}
|
||||
|
||||
mPendingRequests += numRequests;
|
||||
|
||||
@@ -23,8 +23,12 @@
|
||||
#include "nsPluginsDirUtils.h"
|
||||
|
||||
#include "nsILocalFileMac.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "nsCocoaFeatures.h"
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
#include "nsExceptionHandler.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@@ -39,7 +43,6 @@
|
||||
typedef NS_NPAPIPLUGIN_CALLBACK(const char *, NP_GETMIMEDESCRIPTION) ();
|
||||
typedef NS_NPAPIPLUGIN_CALLBACK(OSErr, BP_GETSUPPORTEDMIMETYPES) (BPSupportedMIMETypes *mimeInfo, UInt32 flags);
|
||||
|
||||
|
||||
/*
|
||||
** Returns a CFBundleRef if the path refers to a Mac OS X bundle directory.
|
||||
** The caller is responsible for calling CFRelease() to deallocate.
|
||||
@@ -235,16 +238,16 @@ static void ParsePlistPluginInfo(nsPluginInfo& info, CFBundleRef bundle)
|
||||
memset(info.fMimeDescriptionArray, 0, mimeDataArraySize);
|
||||
|
||||
// Allocate memory for mime dictionary keys and values
|
||||
nsAutoArrayPtr<CFTypeRef> keys(new CFTypeRef[mimeDictKeyCount]);
|
||||
mozilla::UniquePtr<CFTypeRef[]> keys(new CFTypeRef[mimeDictKeyCount]);
|
||||
if (!keys)
|
||||
return;
|
||||
nsAutoArrayPtr<CFTypeRef> values(new CFTypeRef[mimeDictKeyCount]);
|
||||
mozilla::UniquePtr<CFTypeRef[]> values(new CFTypeRef[mimeDictKeyCount]);
|
||||
if (!values)
|
||||
return;
|
||||
|
||||
info.fVariantCount = 0;
|
||||
|
||||
::CFDictionaryGetKeysAndValues(mimeDict, keys, values);
|
||||
::CFDictionaryGetKeysAndValues(mimeDict, keys.get(), values.get());
|
||||
for (int i = 0; i < mimeDictKeyCount; i++) {
|
||||
CFTypeRef mimeString = keys[i];
|
||||
if (!mimeString || ::CFGetTypeID(mimeString) != ::CFStringGetTypeID()) {
|
||||
@@ -484,6 +487,14 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary)
|
||||
NS_WARNING(msg.get());
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
// The block above assumes that "fbplugin" is the filename of the plugin
|
||||
// to be blocked, or that the filename starts with "fbplugin_". But we
|
||||
// don't yet know for sure if this is always true. So for the time being
|
||||
// record extra information in our crash logs.
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Bug_1086977"),
|
||||
fileName);
|
||||
#endif
|
||||
}
|
||||
|
||||
// It's possible that our plugin has 2 entry points that'll give us mime type
|
||||
@@ -493,6 +504,14 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary)
|
||||
|
||||
// Sadly we have to load the library for this to work.
|
||||
rv = LoadPlugin(outLibrary);
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
if (nsCocoaFeatures::OnYosemiteOrLater()) {
|
||||
// If we didn't crash in LoadPlugin(), change the previous annotation so we
|
||||
// don't sow confusion.
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Bug_1086977"),
|
||||
NS_LITERAL_CSTRING("Didn't crash, please ignore"));
|
||||
}
|
||||
#endif
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "PluginInstanceParent.h"
|
||||
#include "nsNPAPIPlugin.h"
|
||||
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
// How much data are we willing to send across the wire
|
||||
@@ -35,6 +36,7 @@ BrowserStreamParent::BrowserStreamParent(PluginInstanceParent* npp,
|
||||
|
||||
BrowserStreamParent::~BrowserStreamParent()
|
||||
{
|
||||
mStream->pdata = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -51,7 +53,6 @@ BrowserStreamParent::RecvAsyncNPP_NewStreamResult(const NPError& rv,
|
||||
PluginAsyncSurrogate* surrogate = mNPP->GetAsyncSurrogate();
|
||||
MOZ_ASSERT(surrogate);
|
||||
surrogate->AsyncCallArriving();
|
||||
RefPtr<nsNPAPIPluginStreamListener> streamListener = mStreamListener.forget();
|
||||
if (mState == DEFERRING_DESTROY) {
|
||||
// We've been asked to destroy ourselves before init was complete.
|
||||
mState = DYING;
|
||||
@@ -61,10 +62,10 @@ BrowserStreamParent::RecvAsyncNPP_NewStreamResult(const NPError& rv,
|
||||
|
||||
NPError error = rv;
|
||||
if (error == NPERR_NO_ERROR) {
|
||||
if (!streamListener) {
|
||||
if (!mStreamListener) {
|
||||
return false;
|
||||
}
|
||||
if (streamListener->SetStreamType(stype)) {
|
||||
if (mStreamListener->SetStreamType(stype)) {
|
||||
mState = ALIVE;
|
||||
} else {
|
||||
error = NPERR_GENERIC_ERROR;
|
||||
@@ -109,7 +110,7 @@ BrowserStreamParent::AnswerNPN_RequestRead(const IPCByteRanges& ranges,
|
||||
if (ranges.Length() > INT32_MAX)
|
||||
return false;
|
||||
|
||||
nsAutoArrayPtr<NPByteRange> rp(new NPByteRange[ranges.Length()]);
|
||||
UniquePtr<NPByteRange[]> rp(new NPByteRange[ranges.Length()]);
|
||||
for (uint32_t i = 0; i < ranges.Length(); ++i) {
|
||||
rp[i].offset = ranges[i].offset;
|
||||
rp[i].length = ranges[i].length;
|
||||
@@ -117,7 +118,7 @@ BrowserStreamParent::AnswerNPN_RequestRead(const IPCByteRanges& ranges,
|
||||
}
|
||||
rp[ranges.Length() - 1].next = nullptr;
|
||||
|
||||
*result = mNPP->mNPNIface->requestread(mStream, rp);
|
||||
*result = mNPP->mNPNIface->requestread(mStream, rp.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ AsyncNPObject::AsyncNPObject(PluginAsyncSurrogate* aSurrogate)
|
||||
AsyncNPObject::~AsyncNPObject()
|
||||
{
|
||||
if (mRealObject) {
|
||||
--mRealObject->asyncWrapperCount;
|
||||
parent::_releaseobject(mRealObject);
|
||||
mRealObject = nullptr;
|
||||
}
|
||||
@@ -51,11 +52,19 @@ AsyncNPObject::GetRealObject()
|
||||
if (!instance) {
|
||||
return nullptr;
|
||||
}
|
||||
NPObject* realObject = nullptr;
|
||||
NPError err = instance->NPP_GetValue(NPPVpluginScriptableNPObject,
|
||||
&mRealObject);
|
||||
&realObject);
|
||||
if (err != NPERR_NO_ERROR) {
|
||||
return nullptr;
|
||||
}
|
||||
if (realObject->_class != PluginScriptableObjectParent::GetClass()) {
|
||||
NS_ERROR("Don't know what kind of object this is!");
|
||||
parent::_releaseobject(realObject);
|
||||
return nullptr;
|
||||
}
|
||||
mRealObject = static_cast<ParentNPObject*>(realObject);
|
||||
++mRealObject->asyncWrapperCount;
|
||||
return mRealObject;
|
||||
}
|
||||
|
||||
@@ -92,7 +101,6 @@ bool RecursionGuard::sHasEntered = false;
|
||||
|
||||
PluginAsyncSurrogate::PluginAsyncSurrogate(PluginModuleParent* aParent)
|
||||
: mParent(aParent)
|
||||
, mInstance(nullptr)
|
||||
, mMode(0)
|
||||
, mWindow(nullptr)
|
||||
, mAcceptCalls(false)
|
||||
@@ -114,7 +122,10 @@ PluginAsyncSurrogate::Init(NPMIMEType aPluginType, NPP aInstance, uint16_t aMode
|
||||
int16_t aArgc, char* aArgn[], char* aArgv[])
|
||||
{
|
||||
mMimeType = aPluginType;
|
||||
mInstance = aInstance;
|
||||
nsNPAPIPluginInstance* instance =
|
||||
static_cast<nsNPAPIPluginInstance*>(aInstance->ndata);
|
||||
MOZ_ASSERT(instance);
|
||||
mInstance = instance;
|
||||
mMode = aMode;
|
||||
for (int i = 0; i < aArgc; ++i) {
|
||||
mNames.AppendElement(NullableString(aArgn[i]));
|
||||
@@ -153,7 +164,11 @@ PluginAsyncSurrogate::Cast(NPP aInstance)
|
||||
nsresult
|
||||
PluginAsyncSurrogate::NPP_New(NPError* aError)
|
||||
{
|
||||
nsresult rv = mParent->NPP_NewInternal(mMimeType.BeginWriting(), mInstance,
|
||||
if (!mInstance) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
nsresult rv = mParent->NPP_NewInternal(mMimeType.BeginWriting(), GetNPP(),
|
||||
mMode, mNames, mValues, nullptr,
|
||||
aError);
|
||||
if (NS_FAILED(rv)) {
|
||||
@@ -190,11 +205,21 @@ PluginAsyncSurrogate::NotifyDestroyPending(NPP aInstance)
|
||||
surrogate->NotifyDestroyPending();
|
||||
}
|
||||
|
||||
NPP
|
||||
PluginAsyncSurrogate::GetNPP()
|
||||
{
|
||||
MOZ_ASSERT(mInstance);
|
||||
NPP npp;
|
||||
DebugOnly<nsresult> rv = mInstance->GetNPP(&npp);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
return npp;
|
||||
}
|
||||
|
||||
void
|
||||
PluginAsyncSurrogate::NotifyDestroyPending()
|
||||
{
|
||||
mDestroyPending = true;
|
||||
nsJSNPRuntime::OnPluginDestroyPending(mInstance);
|
||||
nsJSNPRuntime::OnPluginDestroyPending(GetNPP());
|
||||
}
|
||||
|
||||
NPError
|
||||
@@ -204,7 +229,7 @@ PluginAsyncSurrogate::NPP_Destroy(NPSavedData** aSave)
|
||||
if (!WaitForInit()) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
return PluginModuleParent::NPP_Destroy(mInstance, aSave);
|
||||
return PluginModuleParent::NPP_Destroy(GetNPP(), aSave);
|
||||
}
|
||||
|
||||
NPError
|
||||
@@ -214,12 +239,13 @@ PluginAsyncSurrogate::NPP_GetValue(NPPVariable aVariable, void* aRetval)
|
||||
if (!WaitForInit()) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
PluginInstanceParent* instance = PluginInstanceParent::Cast(mInstance);
|
||||
|
||||
PluginInstanceParent* instance = PluginInstanceParent::Cast(GetNPP());
|
||||
MOZ_ASSERT(instance);
|
||||
return instance->NPP_GetValue(aVariable, aRetval);
|
||||
}
|
||||
|
||||
NPObject* npobject = parent::_createobject(mInstance,
|
||||
NPObject* npobject = parent::_createobject(GetNPP(),
|
||||
const_cast<NPClass*>(GetClass()));
|
||||
MOZ_ASSERT(npobject);
|
||||
MOZ_ASSERT(npobject->_class == GetClass());
|
||||
@@ -234,7 +260,7 @@ PluginAsyncSurrogate::NPP_SetValue(NPNVariable aVariable, void* aValue)
|
||||
if (!WaitForInit()) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
return PluginModuleParent::NPP_SetValue(mInstance, aVariable, aValue);
|
||||
return PluginModuleParent::NPP_SetValue(GetNPP(), aVariable, aValue);
|
||||
}
|
||||
|
||||
NPError
|
||||
@@ -420,7 +446,10 @@ PluginAsyncSurrogate::DestroyAsyncStream(NPStream* aStream)
|
||||
// streamListener was suspended during async init. We must resume the stream
|
||||
// request prior to calling _destroystream for cleanup to work correctly.
|
||||
streamListener->ResumeRequest();
|
||||
parent::_destroystream(mInstance, aStream, NPRES_DONE);
|
||||
if (!mInstance) {
|
||||
return;
|
||||
}
|
||||
parent::_destroystream(GetNPP(), aStream, NPRES_DONE);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
@@ -436,16 +465,20 @@ PluginAsyncSurrogate::SetStreamType(NPStream* aStream, uint16_t aStreamType)
|
||||
void
|
||||
PluginAsyncSurrogate::OnInstanceCreated(PluginInstanceParent* aInstance)
|
||||
{
|
||||
for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) {
|
||||
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i];
|
||||
uint16_t streamType = NP_NORMAL;
|
||||
NPError curError = aInstance->NPP_NewStream(
|
||||
const_cast<char*>(NullableStringGet(curPendingCall.mType)),
|
||||
curPendingCall.mStream, curPendingCall.mSeekable,
|
||||
&streamType);
|
||||
if (curError != NPERR_NO_ERROR) {
|
||||
// If we failed here then the send failed and we need to clean up
|
||||
DestroyAsyncStream(curPendingCall.mStream);
|
||||
if (!mDestroyPending) {
|
||||
// If NPP_Destroy has already been called then these streams have already
|
||||
// been cleaned up on the browser side and are no longer valid.
|
||||
for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) {
|
||||
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i];
|
||||
uint16_t streamType = NP_NORMAL;
|
||||
NPError curError = aInstance->NPP_NewStream(
|
||||
const_cast<char*>(NullableStringGet(curPendingCall.mType)),
|
||||
curPendingCall.mStream, curPendingCall.mSeekable,
|
||||
&streamType);
|
||||
if (curError != NPERR_NO_ERROR) {
|
||||
// If we failed here then the send failed and we need to clean up
|
||||
DestroyAsyncStream(curPendingCall.mStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
mPendingNewStreamCalls.Clear();
|
||||
@@ -543,23 +576,26 @@ PluginAsyncSurrogate::AsyncCallArriving()
|
||||
void
|
||||
PluginAsyncSurrogate::NotifyAsyncInitFailed()
|
||||
{
|
||||
// Clean up any pending NewStream requests
|
||||
for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) {
|
||||
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i];
|
||||
DestroyAsyncStream(curPendingCall.mStream);
|
||||
if (!mDestroyPending) {
|
||||
// Clean up any pending NewStream requests
|
||||
for (uint32_t i = 0, len = mPendingNewStreamCalls.Length(); i < len; ++i) {
|
||||
PendingNewStreamCall& curPendingCall = mPendingNewStreamCalls[i];
|
||||
DestroyAsyncStream(curPendingCall.mStream);
|
||||
}
|
||||
}
|
||||
mPendingNewStreamCalls.Clear();
|
||||
|
||||
nsNPAPIPluginInstance* inst =
|
||||
static_cast<nsNPAPIPluginInstance*>(mInstance->ndata);
|
||||
if (!inst) {
|
||||
// Make sure that any WaitForInit calls on this surrogate will fail, or else
|
||||
// we'll be perma-blocked
|
||||
mInitCancelled = true;
|
||||
|
||||
if (!mInstance) {
|
||||
return;
|
||||
}
|
||||
nsPluginInstanceOwner* owner = inst->GetOwner();
|
||||
if (!owner) {
|
||||
return;
|
||||
nsPluginInstanceOwner* owner = mInstance->GetOwner();
|
||||
if (owner) {
|
||||
owner->NotifyHostAsyncInitFailed();
|
||||
}
|
||||
owner->NotifyHostAsyncInitFailed();
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -645,11 +681,11 @@ PluginAsyncSurrogate::ScriptableHasMethod(NPObject* aObject,
|
||||
// initialization, we should try again.
|
||||
const NPNetscapeFuncs* npn = object->mSurrogate->mParent->GetNetscapeFuncs();
|
||||
NPObject* pluginObject = nullptr;
|
||||
NPError nperror = npn->getvalue(object->mSurrogate->mInstance,
|
||||
NPError nperror = npn->getvalue(object->mSurrogate->GetNPP(),
|
||||
NPNVPluginElementNPObject,
|
||||
(void*)&pluginObject);
|
||||
if (nperror == NPERR_NO_ERROR) {
|
||||
NPPAutoPusher nppPusher(object->mSurrogate->mInstance);
|
||||
NPPAutoPusher nppPusher(object->mSurrogate->GetNPP());
|
||||
result = pluginObject->_class->hasMethod(pluginObject, aName);
|
||||
npn->releaseobject(pluginObject);
|
||||
NPUTF8* idstr = npn->utf8fromidentifier(aName);
|
||||
@@ -698,10 +734,10 @@ PluginAsyncSurrogate::GetPropertyHelper(NPObject* aObject, NPIdentifier aName,
|
||||
if (!success) {
|
||||
const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs();
|
||||
NPObject* pluginObject = nullptr;
|
||||
NPError nperror = npn->getvalue(mInstance, NPNVPluginElementNPObject,
|
||||
NPError nperror = npn->getvalue(GetNPP(), NPNVPluginElementNPObject,
|
||||
(void*)&pluginObject);
|
||||
if (nperror == NPERR_NO_ERROR) {
|
||||
NPPAutoPusher nppPusher(mInstance);
|
||||
NPPAutoPusher nppPusher(GetNPP());
|
||||
bool hasProperty = nsJSObjWrapper::HasOwnProperty(pluginObject, aName);
|
||||
NPUTF8* idstr = npn->utf8fromidentifier(aName);
|
||||
npn->memfree(idstr);
|
||||
@@ -806,11 +842,11 @@ PluginAsyncSurrogate::ScriptableHasProperty(NPObject* aObject,
|
||||
// object hadn't been set yet. Now that we're further along in
|
||||
// initialization, we should try again.
|
||||
NPObject* pluginObject = nullptr;
|
||||
NPError nperror = npn->getvalue(object->mSurrogate->mInstance,
|
||||
NPError nperror = npn->getvalue(object->mSurrogate->GetNPP(),
|
||||
NPNVPluginElementNPObject,
|
||||
(void*)&pluginObject);
|
||||
if (nperror == NPERR_NO_ERROR) {
|
||||
NPPAutoPusher nppPusher(object->mSurrogate->mInstance);
|
||||
NPPAutoPusher nppPusher(object->mSurrogate->GetNPP());
|
||||
result = nsJSObjWrapper::HasOwnProperty(pluginObject, aName);
|
||||
npn->releaseobject(pluginObject);
|
||||
idstr = npn->utf8fromidentifier(aName);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
struct ParentNPObject;
|
||||
class PluginInstanceParent;
|
||||
class PluginModuleParent;
|
||||
|
||||
@@ -59,7 +60,7 @@ public:
|
||||
virtual PluginInstanceParent*
|
||||
GetInstance() { return nullptr; }
|
||||
|
||||
NPP GetNPP() { return mInstance; }
|
||||
NPP GetNPP();
|
||||
|
||||
bool GetPropertyHelper(NPObject* aObject, NPIdentifier aName,
|
||||
bool* aHasProperty, bool* aHasMethod,
|
||||
@@ -140,7 +141,7 @@ private:
|
||||
PluginModuleParent* mParent;
|
||||
// These values are used to construct the plugin instance
|
||||
nsCString mMimeType;
|
||||
NPP mInstance;
|
||||
mozilla::WeakPtr<nsNPAPIPluginInstance> mInstance;
|
||||
uint16_t mMode;
|
||||
InfallibleTArray<nsCString> mNames;
|
||||
InfallibleTArray<nsCString> mValues;
|
||||
@@ -168,7 +169,7 @@ struct AsyncNPObject : NPObject
|
||||
NPObject* GetRealObject();
|
||||
|
||||
RefPtr<PluginAsyncSurrogate> mSurrogate;
|
||||
NPObject* mRealObject;
|
||||
ParentNPObject* mRealObject;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS PushSurrogateAcceptCalls
|
||||
|
||||
@@ -33,6 +33,7 @@ using mozilla::gfx::SharedDIBSurface;
|
||||
#include "mozilla/ipc/MessageChannel.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "ImageContainer.h"
|
||||
|
||||
using namespace mozilla;
|
||||
@@ -188,9 +189,6 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface,
|
||||
mWsInfo.display = DefaultXDisplay();
|
||||
#endif
|
||||
#endif // MOZ_X11 && XP_UNIX && !XP_MACOSX
|
||||
#if defined(OS_WIN)
|
||||
memset(&mAlphaExtract, 0, sizeof(mAlphaExtract));
|
||||
#endif // OS_WIN
|
||||
#if defined(OS_WIN)
|
||||
InitPopupMenuHook();
|
||||
if (GetQuirks() & QUIRK_UNITY_FIXUP_MOUSE_CAPTURE) {
|
||||
@@ -231,8 +229,8 @@ PluginInstanceChild::DoNPP_New()
|
||||
NS_ASSERTION(argc == (int) mValues.Length(),
|
||||
"argn.length != argv.length");
|
||||
|
||||
nsAutoArrayPtr<char*> argn(new char*[1 + argc]);
|
||||
nsAutoArrayPtr<char*> argv(new char*[1 + argc]);
|
||||
UniquePtr<char*[]> argn(new char*[1 + argc]);
|
||||
UniquePtr<char*[]> argv(new char*[1 + argc]);
|
||||
argn[argc] = 0;
|
||||
argv[argc] = 0;
|
||||
|
||||
@@ -244,7 +242,7 @@ PluginInstanceChild::DoNPP_New()
|
||||
NPP npp = GetNPP();
|
||||
|
||||
NPError rv = mPluginIface->newp((char*)NullableStringGet(mMimeType), npp,
|
||||
mMode, argc, argn, argv, 0);
|
||||
mMode, argc, argn.get(), argv.get(), 0);
|
||||
if (NPERR_NO_ERROR != rv) {
|
||||
return rv;
|
||||
}
|
||||
@@ -502,6 +500,7 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
|
||||
case NPNVSupportsXEmbedBool:
|
||||
case NPNVSupportsWindowless:
|
||||
NS_NOTREACHED("NPNVariable should be handled in PluginModuleChild.");
|
||||
MOZ_FALLTHROUGH;
|
||||
#endif
|
||||
|
||||
default:
|
||||
@@ -510,7 +509,6 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
|
||||
(int) aVar, NPNVariableToString(aVar)));
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
@@ -821,21 +819,6 @@ PluginInstanceChild::AnswerNPP_HandleEvent(const NPRemoteEvent& event,
|
||||
if (WM_NULL == evcopy.event)
|
||||
return true;
|
||||
|
||||
// Painting for win32. SharedSurfacePaint handles everything.
|
||||
if (mWindow.type == NPWindowTypeDrawable) {
|
||||
if (evcopy.event == WM_PAINT) {
|
||||
*handled = SharedSurfacePaint(evcopy);
|
||||
return true;
|
||||
}
|
||||
else if (DoublePassRenderingEvent() == evcopy.event) {
|
||||
// We'll render to mSharedSurfaceDib first, then render to a cached bitmap
|
||||
// we store locally. The two passes are for alpha extraction, so the second
|
||||
// pass must be to a flat white surface in order for things to work.
|
||||
mAlphaExtract.doublePass = RENDER_BACK_ONE;
|
||||
*handled = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
*handled = WinlessHandleEvent(evcopy);
|
||||
return true;
|
||||
#endif
|
||||
@@ -1296,13 +1279,6 @@ PluginInstanceChild::AnswerNPP_SetWindow(const NPRemoteWindow& aWindow)
|
||||
}
|
||||
break;
|
||||
|
||||
case NPWindowTypeDrawable:
|
||||
mWindow.type = aWindow.type;
|
||||
if (GetQuirks() & QUIRK_FLASH_THROTTLE_WMUSER_EVENTS)
|
||||
SetupFlashMsgThrottle();
|
||||
return SharedSurfaceSetWindow(aWindow);
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_NOTREACHED("Bad plugin window type.");
|
||||
return false;
|
||||
@@ -2024,187 +2000,6 @@ PluginInstanceChild::WinlessHandleEvent(NPEvent& event)
|
||||
return handled;
|
||||
}
|
||||
|
||||
/* windowless drawing helpers */
|
||||
|
||||
bool
|
||||
PluginInstanceChild::SharedSurfaceSetWindow(const NPRemoteWindow& aWindow)
|
||||
{
|
||||
// If the surfaceHandle is empty, parent is telling us we can reuse our cached
|
||||
// memory surface and hdc. Otherwise, we need to reset, usually due to a
|
||||
// expanding plugin port size.
|
||||
if (!aWindow.surfaceHandle) {
|
||||
if (!mSharedSurfaceDib.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Attach to the new shared surface parent handed us.
|
||||
if (NS_FAILED(mSharedSurfaceDib.Attach((SharedDIB::Handle)aWindow.surfaceHandle,
|
||||
aWindow.width, aWindow.height, false)))
|
||||
return false;
|
||||
// Free any alpha extraction resources if needed. This will be reset
|
||||
// the next time it's used.
|
||||
AlphaExtractCacheRelease();
|
||||
}
|
||||
|
||||
// NPRemoteWindow's origin is the origin of our shared dib.
|
||||
mWindow.x = aWindow.x;
|
||||
mWindow.y = aWindow.y;
|
||||
mWindow.width = aWindow.width;
|
||||
mWindow.height = aWindow.height;
|
||||
mWindow.type = aWindow.type;
|
||||
|
||||
mWindow.window = reinterpret_cast<void*>(mSharedSurfaceDib.GetHDC());
|
||||
::SetViewportOrgEx(mSharedSurfaceDib.GetHDC(),
|
||||
-aWindow.x, -aWindow.y, nullptr);
|
||||
|
||||
if (mPluginIface->setwindow)
|
||||
mPluginIface->setwindow(&mData, &mWindow);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::SharedSurfaceRelease()
|
||||
{
|
||||
mSharedSurfaceDib.Close();
|
||||
AlphaExtractCacheRelease();
|
||||
}
|
||||
|
||||
/* double pass cache buffer - (rarely) used in cases where alpha extraction
|
||||
* occurs for windowless plugins. */
|
||||
|
||||
bool
|
||||
PluginInstanceChild::AlphaExtractCacheSetup()
|
||||
{
|
||||
AlphaExtractCacheRelease();
|
||||
|
||||
mAlphaExtract.hdc = ::CreateCompatibleDC(nullptr);
|
||||
|
||||
if (!mAlphaExtract.hdc)
|
||||
return false;
|
||||
|
||||
BITMAPINFOHEADER bmih;
|
||||
memset((void*)&bmih, 0, sizeof(BITMAPINFOHEADER));
|
||||
bmih.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmih.biWidth = mWindow.width;
|
||||
bmih.biHeight = mWindow.height;
|
||||
bmih.biPlanes = 1;
|
||||
bmih.biBitCount = 32;
|
||||
bmih.biCompression = BI_RGB;
|
||||
|
||||
void* ppvBits = nullptr;
|
||||
mAlphaExtract.bmp = ::CreateDIBSection(mAlphaExtract.hdc,
|
||||
(BITMAPINFO*)&bmih,
|
||||
DIB_RGB_COLORS,
|
||||
(void**)&ppvBits,
|
||||
nullptr,
|
||||
(unsigned long)sizeof(BITMAPINFOHEADER));
|
||||
if (!mAlphaExtract.bmp)
|
||||
return false;
|
||||
|
||||
DeleteObject(::SelectObject(mAlphaExtract.hdc, mAlphaExtract.bmp));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::AlphaExtractCacheRelease()
|
||||
{
|
||||
if (mAlphaExtract.bmp)
|
||||
::DeleteObject(mAlphaExtract.bmp);
|
||||
|
||||
if (mAlphaExtract.hdc)
|
||||
::DeleteObject(mAlphaExtract.hdc);
|
||||
|
||||
mAlphaExtract.bmp = nullptr;
|
||||
mAlphaExtract.hdc = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceChild::UpdatePaintClipRect(RECT* aRect)
|
||||
{
|
||||
if (aRect) {
|
||||
// Update the clip rect on our internal hdc
|
||||
HRGN clip = ::CreateRectRgnIndirect(aRect);
|
||||
::SelectClipRgn(mSharedSurfaceDib.GetHDC(), clip);
|
||||
::DeleteObject(clip);
|
||||
}
|
||||
}
|
||||
|
||||
int16_t
|
||||
PluginInstanceChild::SharedSurfacePaint(NPEvent& evcopy)
|
||||
{
|
||||
if (!mPluginIface->event)
|
||||
return false;
|
||||
|
||||
RECT* pRect = reinterpret_cast<RECT*>(evcopy.lParam);
|
||||
|
||||
switch(mAlphaExtract.doublePass) {
|
||||
case RENDER_NATIVE:
|
||||
// pass the internal hdc to the plugin
|
||||
UpdatePaintClipRect(pRect);
|
||||
evcopy.wParam = WPARAM(mSharedSurfaceDib.GetHDC());
|
||||
return mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy));
|
||||
break;
|
||||
case RENDER_BACK_ONE:
|
||||
// Handle a double pass render used in alpha extraction for transparent
|
||||
// plugins. (See nsPluginFrame and gfxWindowsNativeDrawing for details.)
|
||||
// We render twice, once to the shared dib, and once to a cache which
|
||||
// we copy back on a second paint. These paints can't be spread across
|
||||
// multiple rpc messages as delays cause animation frame changes.
|
||||
if (!mAlphaExtract.bmp && !AlphaExtractCacheSetup()) {
|
||||
mAlphaExtract.doublePass = RENDER_NATIVE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// See gfxWindowsNativeDrawing, color order doesn't have to match.
|
||||
UpdatePaintClipRect(pRect);
|
||||
::FillRect(mSharedSurfaceDib.GetHDC(), pRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
|
||||
evcopy.wParam = WPARAM(mSharedSurfaceDib.GetHDC());
|
||||
if (!mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy))) {
|
||||
mAlphaExtract.doublePass = RENDER_NATIVE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy to cache. We render to shared dib so we don't have to call
|
||||
// setwindow between calls (flash issue).
|
||||
::BitBlt(mAlphaExtract.hdc,
|
||||
pRect->left,
|
||||
pRect->top,
|
||||
pRect->right - pRect->left,
|
||||
pRect->bottom - pRect->top,
|
||||
mSharedSurfaceDib.GetHDC(),
|
||||
pRect->left,
|
||||
pRect->top,
|
||||
SRCCOPY);
|
||||
|
||||
::FillRect(mSharedSurfaceDib.GetHDC(), pRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
|
||||
if (!mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy))) {
|
||||
mAlphaExtract.doublePass = RENDER_NATIVE;
|
||||
return false;
|
||||
}
|
||||
mAlphaExtract.doublePass = RENDER_BACK_TWO;
|
||||
return true;
|
||||
break;
|
||||
case RENDER_BACK_TWO:
|
||||
// copy our cached surface back
|
||||
UpdatePaintClipRect(pRect);
|
||||
::BitBlt(mSharedSurfaceDib.GetHDC(),
|
||||
pRect->left,
|
||||
pRect->top,
|
||||
pRect->right - pRect->left,
|
||||
pRect->bottom - pRect->top,
|
||||
mAlphaExtract.hdc,
|
||||
pRect->left,
|
||||
pRect->top,
|
||||
SRCCOPY);
|
||||
mAlphaExtract.doublePass = RENDER_NATIVE;
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* flash msg throttling helpers */
|
||||
|
||||
// Flash has the unfortunate habit of flooding dispatch loops with custom
|
||||
@@ -2313,7 +2108,6 @@ PluginInstanceChild::EnumThreadWindowsCallback(HWND hWnd,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PluginInstanceChild::SetupFlashMsgThrottle()
|
||||
{
|
||||
@@ -2367,9 +2161,6 @@ PluginInstanceChild::FlashThrottleMessage(HWND aWnd,
|
||||
// that's done in Destroy.
|
||||
FlashThrottleAsyncMsg* task = new FlashThrottleAsyncMsg(this,
|
||||
aWnd, aMsg, aWParam, aLParam, isWindowed);
|
||||
if (!task)
|
||||
return;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mAsyncCallMutex);
|
||||
mPendingAsyncCalls.AppendElement(task);
|
||||
@@ -2610,7 +2401,6 @@ StreamNotifyChild::ActorDestroy(ActorDestroyReason why)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StreamNotifyChild::SetAssociatedStream(BrowserStreamChild* bs)
|
||||
{
|
||||
@@ -4051,7 +3841,6 @@ PluginInstanceChild::Destroy()
|
||||
mCachedElementActor = nullptr;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
SharedSurfaceRelease();
|
||||
DestroyWinlessPopupSurrogate();
|
||||
UnhookWinlessFlashThrottle();
|
||||
DestroyPluginWindow();
|
||||
|
||||
@@ -427,29 +427,6 @@ private:
|
||||
*/
|
||||
nsAutoPtr< nsTHashtable<DeletingObjectEntry> > mDeletingHash;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
private:
|
||||
// Shared dib rendering management for windowless plugins.
|
||||
bool SharedSurfaceSetWindow(const NPRemoteWindow& aWindow);
|
||||
int16_t SharedSurfacePaint(NPEvent& evcopy);
|
||||
void SharedSurfaceRelease();
|
||||
bool AlphaExtractCacheSetup();
|
||||
void AlphaExtractCacheRelease();
|
||||
void UpdatePaintClipRect(RECT* aRect);
|
||||
|
||||
private:
|
||||
enum {
|
||||
RENDER_NATIVE,
|
||||
RENDER_BACK_ONE,
|
||||
RENDER_BACK_TWO
|
||||
};
|
||||
gfx::SharedDIBWin mSharedSurfaceDib;
|
||||
struct {
|
||||
uint16_t doublePass;
|
||||
HDC hdc;
|
||||
HBITMAP bmp;
|
||||
} mAlphaExtract;
|
||||
#endif // defined(OS_WIN)
|
||||
#if defined(MOZ_WIDGET_COCOA)
|
||||
private:
|
||||
#if defined(__i386__)
|
||||
|
||||
@@ -196,7 +196,6 @@ PluginInstanceParent::ActorDestroy(ActorDestroyReason why)
|
||||
if (why == AbnormalShutdown) {
|
||||
// If the plugin process crashes, this is the only
|
||||
// chance we get to destroy resources.
|
||||
SharedSurfaceRelease();
|
||||
UnsubclassPluginWindow();
|
||||
}
|
||||
#endif
|
||||
@@ -224,7 +223,6 @@ PluginInstanceParent::Destroy()
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
SharedSurfaceRelease();
|
||||
UnsubclassPluginWindow();
|
||||
#endif
|
||||
|
||||
@@ -957,11 +955,6 @@ PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
|
||||
#if defined(OS_WIN)
|
||||
// On windowless controls, reset the shared memory surface as needed.
|
||||
if (mWindowType == NPWindowTypeDrawable) {
|
||||
// SharedSurfaceSetWindow will take care of NPRemoteWindow.
|
||||
if (!SharedSurfaceSetWindow(aWindow, window)) {
|
||||
return NPERR_OUT_OF_MEMORY_ERROR;
|
||||
}
|
||||
|
||||
MaybeCreateChildPopupSurrogate();
|
||||
} else {
|
||||
SubclassPluginWindow(reinterpret_cast<HWND>(aWindow->window));
|
||||
@@ -1196,23 +1189,7 @@ PluginInstanceParent::NPP_HandleEvent(void* event)
|
||||
|
||||
#if defined(OS_WIN)
|
||||
if (mWindowType == NPWindowTypeDrawable) {
|
||||
if (DoublePassRenderingEvent() == npevent->event) {
|
||||
return CallPaint(npremoteevent, &handled) && handled;
|
||||
}
|
||||
|
||||
switch (npevent->event) {
|
||||
case WM_PAINT:
|
||||
{
|
||||
RECT rect;
|
||||
SharedSurfaceBeforePaint(rect, npremoteevent);
|
||||
if (!CallPaint(npremoteevent, &handled)) {
|
||||
handled = false;
|
||||
}
|
||||
SharedSurfaceAfterPaint(npevent);
|
||||
return handled;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
{
|
||||
// When the user selects fullscreen mode in Flash video players,
|
||||
@@ -1444,6 +1421,12 @@ PluginInstanceParent::NPP_DestroyStream(NPStream* stream, NPReason reason)
|
||||
FULLFUNCTION, (void*) stream, (int) reason));
|
||||
|
||||
AStream* s = static_cast<AStream*>(stream->pdata);
|
||||
if (!s) {
|
||||
// The stream has already been deleted by other means.
|
||||
// With async plugin init this could happen if async NPP_NewStream
|
||||
// returns an error code.
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
if (s->IsBrowserStream()) {
|
||||
BrowserStreamParent* sp =
|
||||
static_cast<BrowserStreamParent*>(s);
|
||||
@@ -1593,11 +1576,6 @@ PluginInstanceParent::GetActorForNPObject(NPObject* aObject)
|
||||
}
|
||||
|
||||
actor = new PluginScriptableObjectParent(LocalObject);
|
||||
if (!actor) {
|
||||
NS_ERROR("Out of memory!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!SendPPluginScriptableObjectConstructor(actor)) {
|
||||
NS_WARNING("Failed to send constructor message!");
|
||||
return nullptr;
|
||||
@@ -1764,10 +1742,17 @@ PluginInstanceParent::RecvAsyncNPP_NewResult(const NPError& aResult)
|
||||
mSurrogate->SetAcceptingCalls(true);
|
||||
}
|
||||
|
||||
// It is possible for a plugin instance to outlive its owner (eg. When a
|
||||
// PluginDestructionGuard was on the stack at the time the owner was being
|
||||
// destroyed). We need to handle that case.
|
||||
nsPluginInstanceOwner* owner = GetOwner();
|
||||
// It is possible for a plugin instance to outlive its owner when async
|
||||
// plugin init is turned on, so we need to handle that case.
|
||||
if (aResult != NPERR_NO_ERROR || !owner) {
|
||||
if (!owner) {
|
||||
// We can't do anything at this point, just return. Any pending browser
|
||||
// streams will be cleaned up when the plugin instance is destroyed.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aResult != NPERR_NO_ERROR) {
|
||||
mSurrogate->NotifyAsyncInitFailed();
|
||||
return true;
|
||||
}
|
||||
@@ -1939,108 +1924,6 @@ PluginInstanceParent::UnsubclassPluginWindow()
|
||||
* painting: mPluginPort (nsIntRect, saved in SetWindow)
|
||||
*/
|
||||
|
||||
void
|
||||
PluginInstanceParent::SharedSurfaceRelease()
|
||||
{
|
||||
mSharedSurfaceDib.Close();
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow* aWindow,
|
||||
NPRemoteWindow& aRemoteWindow)
|
||||
{
|
||||
aRemoteWindow.window = 0;
|
||||
aRemoteWindow.x = aWindow->x;
|
||||
aRemoteWindow.y = aWindow->y;
|
||||
aRemoteWindow.width = aWindow->width;
|
||||
aRemoteWindow.height = aWindow->height;
|
||||
aRemoteWindow.type = aWindow->type;
|
||||
|
||||
nsIntRect newPort(aWindow->x, aWindow->y, aWindow->width, aWindow->height);
|
||||
|
||||
// save the the rect location within the browser window.
|
||||
mPluginPort = newPort;
|
||||
|
||||
// move the port to our shared surface origin
|
||||
newPort.MoveTo(0,0);
|
||||
|
||||
// check to see if we have the room in shared surface
|
||||
if (mSharedSurfaceDib.IsValid() && mSharedSize.Contains(newPort)) {
|
||||
// ok to paint
|
||||
aRemoteWindow.surfaceHandle = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// allocate a new shared surface
|
||||
SharedSurfaceRelease();
|
||||
if (NS_FAILED(mSharedSurfaceDib.Create(reinterpret_cast<HDC>(aWindow->window),
|
||||
newPort.width, newPort.height, false)))
|
||||
return false;
|
||||
|
||||
// save the new shared surface size we just allocated
|
||||
mSharedSize = newPort;
|
||||
|
||||
base::SharedMemoryHandle handle;
|
||||
if (NS_FAILED(mSharedSurfaceDib.ShareToProcess(OtherPid(), &handle))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aRemoteWindow.surfaceHandle = handle;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceParent::SharedSurfaceBeforePaint(RECT& rect,
|
||||
NPRemoteEvent& npremoteevent)
|
||||
{
|
||||
RECT* dr = (RECT*)npremoteevent.event.lParam;
|
||||
HDC parentHdc = (HDC)npremoteevent.event.wParam;
|
||||
|
||||
nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
|
||||
dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y); // should always be smaller than dirtyRect
|
||||
|
||||
::BitBlt(mSharedSurfaceDib.GetHDC(),
|
||||
dirtyRect.x,
|
||||
dirtyRect.y,
|
||||
dirtyRect.width,
|
||||
dirtyRect.height,
|
||||
parentHdc,
|
||||
dr->left,
|
||||
dr->top,
|
||||
SRCCOPY);
|
||||
|
||||
// setup the translated dirty rect we'll send to the child
|
||||
rect.left = dirtyRect.x;
|
||||
rect.top = dirtyRect.y;
|
||||
rect.right = dirtyRect.x + dirtyRect.width;
|
||||
rect.bottom = dirtyRect.y + dirtyRect.height;
|
||||
|
||||
npremoteevent.event.wParam = WPARAM(0);
|
||||
npremoteevent.event.lParam = LPARAM(&rect);
|
||||
}
|
||||
|
||||
void
|
||||
PluginInstanceParent::SharedSurfaceAfterPaint(NPEvent* npevent)
|
||||
{
|
||||
RECT* dr = (RECT*)npevent->lParam;
|
||||
HDC parentHdc = (HDC)npevent->wParam;
|
||||
|
||||
nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
|
||||
dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y);
|
||||
|
||||
// src copy the shared dib into the parent surface we are handed.
|
||||
::BitBlt(parentHdc,
|
||||
dr->left,
|
||||
dr->top,
|
||||
dirtyRect.width,
|
||||
dirtyRect.height,
|
||||
mSharedSurfaceDib.GetHDC(),
|
||||
dirtyRect.x,
|
||||
dirtyRect.y,
|
||||
SRCCOPY);
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceParent::MaybeCreateAndParentChildPluginWindow()
|
||||
{
|
||||
|
||||
@@ -353,11 +353,6 @@ private:
|
||||
|
||||
#if defined(OS_WIN)
|
||||
private:
|
||||
// Used in rendering windowless plugins in other processes.
|
||||
bool SharedSurfaceSetWindow(const NPWindow* aWindow, NPRemoteWindow& aRemoteWindow);
|
||||
void SharedSurfaceBeforePaint(RECT &rect, NPRemoteEvent& npremoteevent);
|
||||
void SharedSurfaceAfterPaint(NPEvent* npevent);
|
||||
void SharedSurfaceRelease();
|
||||
// Used in handling parent/child forwarding of events.
|
||||
static LRESULT CALLBACK PluginWindowHookProc(HWND hWnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam);
|
||||
@@ -368,7 +363,6 @@ private:
|
||||
void MaybeCreateChildPopupSurrogate();
|
||||
|
||||
private:
|
||||
gfx::SharedDIBWin mSharedSurfaceDib;
|
||||
nsIntRect mPluginPort;
|
||||
nsIntRect mSharedSize;
|
||||
HWND mPluginHWND;
|
||||
|
||||
@@ -54,9 +54,6 @@ NPRemoteWindow::NPRemoteWindow() :
|
||||
, visualID(0)
|
||||
, colormap(0)
|
||||
#endif /* XP_UNIX */
|
||||
#if defined(XP_WIN)
|
||||
,surfaceHandle(0)
|
||||
#endif
|
||||
#if defined(XP_MACOSX)
|
||||
,contentsScaleFactor(1.0)
|
||||
#endif
|
||||
@@ -156,18 +153,5 @@ void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v)
|
||||
VOID_TO_NPVARIANT(*v);
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
||||
// The private event used for double-pass widgetless plugin rendering.
|
||||
UINT DoublePassRenderingEvent()
|
||||
{
|
||||
static UINT gEventID = 0;
|
||||
if (!gEventID)
|
||||
gEventID = ::RegisterWindowMessage(L"MozDoublePassMsg");
|
||||
return gEventID;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace plugins
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "mozilla/ipc/MessageChannel.h"
|
||||
#include "mozilla/ipc/CrossProcessMutex.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "gfxipc/ShadowLayerUtils.h"
|
||||
|
||||
#include "npapi.h"
|
||||
@@ -90,9 +91,6 @@ struct NPRemoteWindow
|
||||
VisualID visualID;
|
||||
Colormap colormap;
|
||||
#endif /* XP_UNIX */
|
||||
#if defined(XP_WIN)
|
||||
base::SharedMemoryHandle surfaceHandle;
|
||||
#endif
|
||||
#if defined(XP_MACOSX)
|
||||
double contentsScaleFactor;
|
||||
#endif
|
||||
@@ -251,11 +249,6 @@ struct DeletingObjectEntry : public nsPtrHashKey<NPObject>
|
||||
bool mDeleted;
|
||||
};
|
||||
|
||||
#ifdef XP_WIN
|
||||
// The private event used for double-pass widgetless plugin rendering.
|
||||
UINT DoublePassRenderingEvent();
|
||||
#endif
|
||||
|
||||
} /* namespace plugins */
|
||||
|
||||
} /* namespace mozilla */
|
||||
@@ -342,9 +335,6 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
|
||||
aMsg->WriteULong(aParam.visualID);
|
||||
aMsg->WriteULong(aParam.colormap);
|
||||
#endif
|
||||
#if defined(XP_WIN)
|
||||
WriteParam(aMsg, aParam.surfaceHandle);
|
||||
#endif
|
||||
#if defined(XP_MACOSX)
|
||||
aMsg->WriteDouble(aParam.contentsScaleFactor);
|
||||
#endif
|
||||
@@ -374,12 +364,6 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
base::SharedMemoryHandle surfaceHandle;
|
||||
if (!ReadParam(aMsg, aIter, &surfaceHandle))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
double contentsScaleFactor;
|
||||
if (!aMsg->ReadDouble(aIter, &contentsScaleFactor))
|
||||
@@ -397,9 +381,6 @@ struct ParamTraits<mozilla::plugins::NPRemoteWindow>
|
||||
aResult->visualID = visualID;
|
||||
aResult->colormap = colormap;
|
||||
#endif
|
||||
#if defined(XP_WIN)
|
||||
aResult->surfaceHandle = surfaceHandle;
|
||||
#endif
|
||||
#if defined(XP_MACOSX)
|
||||
aResult->contentsScaleFactor = contentsScaleFactor;
|
||||
#endif
|
||||
@@ -437,10 +418,10 @@ struct ParamTraits<NPString>
|
||||
}
|
||||
|
||||
const char* messageBuffer = nullptr;
|
||||
nsAutoArrayPtr<char> newBuffer(new char[byteCount]);
|
||||
mozilla::UniquePtr<char[]> newBuffer(new char[byteCount]);
|
||||
if (newBuffer && aMsg->ReadBytes(aIter, &messageBuffer, byteCount )) {
|
||||
memcpy((void*)messageBuffer, newBuffer.get(), byteCount);
|
||||
aResult->UTF8Characters = newBuffer.forget();
|
||||
aResult->UTF8Characters = newBuffer.release();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
#ifdef XP_WIN
|
||||
#include "nsWindowsDllInterceptor.h"
|
||||
#include "mozilla/widget/AudioSession.h"
|
||||
#include "WinUtils.h"
|
||||
#include <knownfolders.h>
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
@@ -159,7 +161,7 @@ PluginModuleChild::PluginModuleChild(bool aIsChrome)
|
||||
PluginModuleChild::~PluginModuleChild()
|
||||
{
|
||||
if (mTransport) {
|
||||
// For some reason IPDL doesn't autmatically delete the channel for a
|
||||
// For some reason IPDL doesn't automatically delete the channel for a
|
||||
// bridged protocol (bug 1090570). So we have to do it ourselves. This
|
||||
// code is only invoked for PluginModuleChild instances created via
|
||||
// bridging; otherwise mTransport is null.
|
||||
@@ -302,6 +304,8 @@ PluginModuleChild::InitForChrome(const std::string& aPluginFilename,
|
||||
return false;
|
||||
}
|
||||
|
||||
GetIPCChannel()->SetAbortOnError(true);
|
||||
|
||||
// TODO: use PluginPRLibrary here
|
||||
|
||||
#if defined(OS_LINUX) || defined(OS_BSD)
|
||||
@@ -315,10 +319,6 @@ PluginModuleChild::InitForChrome(const std::string& aPluginFilename,
|
||||
NS_ASSERTION(mInitializeFunc, "couldn't find NP_Initialize()");
|
||||
|
||||
#elif defined(OS_WIN) || defined(OS_MACOSX)
|
||||
|
||||
// no, don't do that
|
||||
//GetIPCChannel()->SetAbortOnError(true);
|
||||
|
||||
mShutdownFunc =
|
||||
(NP_PLUGINSHUTDOWN)PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
|
||||
|
||||
@@ -1336,8 +1336,6 @@ void
|
||||
_memfree(void* aPtr)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG_FUNCTION;
|
||||
// Only assert plugin thread here for consistency with in-process plugins.
|
||||
AssertPluginThread();
|
||||
NS_Free(aPtr);
|
||||
}
|
||||
|
||||
@@ -1345,8 +1343,6 @@ uint32_t
|
||||
_memflush(uint32_t aSize)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG_FUNCTION;
|
||||
// Only assert plugin thread here for consistency with in-process plugins.
|
||||
AssertPluginThread();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1405,8 +1401,6 @@ void*
|
||||
_memalloc(uint32_t aSize)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG_FUNCTION;
|
||||
// Only assert plugin thread here for consistency with in-process plugins.
|
||||
AssertPluginThread();
|
||||
return NS_Alloc(aSize);
|
||||
}
|
||||
|
||||
@@ -1819,7 +1813,7 @@ _popupcontextmenu(NPP instance, NPMenu* menu)
|
||||
if (success) {
|
||||
return mozilla::plugins::PluginUtilsOSX::ShowCocoaContextMenu(menu,
|
||||
screenX, screenY,
|
||||
PluginModuleChild::GetChrome(),
|
||||
InstCast(instance)->Manager(),
|
||||
ProcessBrowserEvents);
|
||||
} else {
|
||||
NS_WARNING("Convertpoint failed, could not created contextmenu.");
|
||||
@@ -1978,6 +1972,29 @@ CreateFileAHookFn(LPCSTR fname, DWORD access, DWORD share,
|
||||
ftemplate);
|
||||
}
|
||||
|
||||
static bool
|
||||
GetLocalLowTempPath(size_t aLen, LPWSTR aPath)
|
||||
{
|
||||
NS_NAMED_LITERAL_STRING(tempname, "\\Temp");
|
||||
LPWSTR path;
|
||||
if (SUCCEEDED(WinUtils::SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0,
|
||||
nullptr, &path))) {
|
||||
if (wcslen(path) + tempname.Length() < aLen) {
|
||||
wcscpy(aPath, path);
|
||||
wcscat(aPath, tempname.get());
|
||||
::CoTaskMemFree(path);
|
||||
return true;
|
||||
}
|
||||
::CoTaskMemFree(path);
|
||||
}
|
||||
|
||||
// XP doesn't support SHGetKnownFolderPath and LocalLow
|
||||
if (!GetTempPathW(aLen, aPath)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
HANDLE WINAPI
|
||||
CreateFileWHookFn(LPCWSTR fname, DWORD access, DWORD share,
|
||||
LPSECURITY_ATTRIBUTES security, DWORD creation, DWORD flags,
|
||||
@@ -1997,7 +2014,7 @@ CreateFileWHookFn(LPCWSTR fname, DWORD access, DWORD share,
|
||||
|
||||
// This is the config file we want to rewrite
|
||||
WCHAR tempPath[MAX_PATH+1];
|
||||
if (GetTempPathW(MAX_PATH, tempPath) == 0) {
|
||||
if (GetLocalLowTempPath(MAX_PATH, tempPath) == 0) {
|
||||
break;
|
||||
}
|
||||
WCHAR tempFile[MAX_PATH+1];
|
||||
@@ -2170,6 +2187,17 @@ private:
|
||||
NPError mResult;
|
||||
};
|
||||
|
||||
static void
|
||||
RunAsyncNPP_New(void* aChildInstance)
|
||||
{
|
||||
MOZ_ASSERT(aChildInstance);
|
||||
PluginInstanceChild* childInstance =
|
||||
static_cast<PluginInstanceChild*>(aChildInstance);
|
||||
NPError rv = childInstance->DoNPP_New();
|
||||
AsyncNewResultSender* task = new AsyncNewResultSender(childInstance, rv);
|
||||
childInstance->PostChildAsyncCall(task);
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleChild::RecvAsyncNPP_New(PPluginInstanceChild* aActor)
|
||||
{
|
||||
@@ -2177,9 +2205,8 @@ PluginModuleChild::RecvAsyncNPP_New(PPluginInstanceChild* aActor)
|
||||
PluginInstanceChild* childInstance =
|
||||
reinterpret_cast<PluginInstanceChild*>(aActor);
|
||||
AssertPluginThread();
|
||||
NPError rv = childInstance->DoNPP_New();
|
||||
AsyncNewResultSender* task = new AsyncNewResultSender(childInstance, rv);
|
||||
childInstance->PostChildAsyncCall(task);
|
||||
// We don't want to run NPP_New async from within nested calls
|
||||
childInstance->AsyncCall(&RunAsyncNPP_New, childInstance);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,14 +67,15 @@ AddSandboxAllowedFile(vector<std::wstring>& aAllowedFiles, nsIProperties* aDirSv
|
||||
if (!aSuffix.IsEmpty()) {
|
||||
userDirPath.Append(aSuffix);
|
||||
}
|
||||
aAllowedFiles.push_back(userDirPath.get());
|
||||
aAllowedFiles.push_back(std::wstring(userDirPath.get()));
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
AddSandboxAllowedFiles(int32_t aSandboxLevel,
|
||||
vector<std::wstring>& aAllowedFilesRead,
|
||||
vector<std::wstring>& aAllowedFilesReadWrite)
|
||||
vector<std::wstring>& aAllowedFilesReadWrite,
|
||||
vector<std::wstring>& aAllowedDirectories)
|
||||
{
|
||||
if (aSandboxLevel < 2) {
|
||||
return;
|
||||
@@ -95,18 +96,27 @@ AddSandboxAllowedFiles(int32_t aSandboxLevel,
|
||||
}
|
||||
|
||||
// Level 2 and above is now using low integrity, so we need to give write
|
||||
// access to the Flash directories.
|
||||
// access to the Flash directories. Access also has to be given to create
|
||||
// the parent directories as they may not exist.
|
||||
// This should be made Flash specific (Bug 1171396).
|
||||
AddSandboxAllowedFile(aAllowedFilesReadWrite, dirSvc, NS_WIN_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Macromedia\\Flash Player\\*"));
|
||||
AddSandboxAllowedFile(aAllowedDirectories, dirSvc, NS_WIN_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Macromedia\\Flash Player"));
|
||||
AddSandboxAllowedFile(aAllowedDirectories, dirSvc, NS_WIN_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Macromedia"));
|
||||
AddSandboxAllowedFile(aAllowedFilesReadWrite, dirSvc, NS_WIN_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Adobe\\Flash Player\\*"));
|
||||
AddSandboxAllowedFile(aAllowedDirectories, dirSvc, NS_WIN_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Adobe\\Flash Player"));
|
||||
AddSandboxAllowedFile(aAllowedDirectories, dirSvc, NS_WIN_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Adobe"));
|
||||
|
||||
#if defined(_X86_)
|
||||
// Write access to the Temp directory should only be needed for 32-bit as
|
||||
// it is used to turn off protected mode, which only applies to x86.
|
||||
// Write access to the Temp directory is needed in some mochitest crash
|
||||
// tests.
|
||||
// Bug 1171393 tracks removing this requirement.
|
||||
AddSandboxAllowedFile(aAllowedFilesReadWrite, dirSvc, NS_OS_TEMP_DIR,
|
||||
NS_LITERAL_STRING("\\*"));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -117,7 +127,7 @@ PluginProcessParent::Launch(mozilla::UniquePtr<LaunchCompleteTask> aLaunchComple
|
||||
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
mSandboxLevel = aSandboxLevel;
|
||||
AddSandboxAllowedFiles(mSandboxLevel, mAllowedFilesRead,
|
||||
mAllowedFilesReadWrite);
|
||||
mAllowedFilesReadWrite, mAllowedDirectories);
|
||||
#else
|
||||
if (aSandboxLevel != 0) {
|
||||
MOZ_ASSERT(false,
|
||||
@@ -153,6 +163,9 @@ PluginProcessParent::Launch(mozilla::UniquePtr<LaunchCompleteTask> aLaunchComple
|
||||
else if (base::PROCESS_ARCH_ARM & pluginLibArchitectures & containerArchitectures) {
|
||||
selectedArchitecture = base::PROCESS_ARCH_ARM;
|
||||
}
|
||||
else if (base::PROCESS_ARCH_MIPS & pluginLibArchitectures & containerArchitectures) {
|
||||
selectedArchitecture = base::PROCESS_ARCH_MIPS;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -166,6 +166,15 @@ PluginScriptableObjectParent::ScriptableDeallocate(NPObject* aObject)
|
||||
}
|
||||
|
||||
ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
|
||||
|
||||
if (object->asyncWrapperCount > 0) {
|
||||
// In this case we should just drop the refcount to the asyncWrapperCount
|
||||
// instead of deallocating because there are still some async wrappers
|
||||
// out there that are referencing this object.
|
||||
object->referenceCount = object->asyncWrapperCount;
|
||||
return;
|
||||
}
|
||||
|
||||
PluginScriptableObjectParent* actor = object->parent;
|
||||
if (actor) {
|
||||
NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
|
||||
|
||||
@@ -22,12 +22,17 @@ class PluginScriptableObjectParent;
|
||||
struct ParentNPObject : NPObject
|
||||
{
|
||||
ParentNPObject()
|
||||
: NPObject(), parent(nullptr), invalidated(false) { }
|
||||
: NPObject()
|
||||
, parent(nullptr)
|
||||
, invalidated(false)
|
||||
, asyncWrapperCount(0)
|
||||
{}
|
||||
|
||||
// |parent| is always valid as long as the actor is alive. Once the actor is
|
||||
// destroyed this will be set to null.
|
||||
PluginScriptableObjectParent* parent;
|
||||
bool invalidated;
|
||||
int32_t asyncWrapperCount;
|
||||
};
|
||||
|
||||
class PluginScriptableObjectParent : public PPluginScriptableObjectParent
|
||||
|
||||
@@ -772,8 +772,6 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char*
|
||||
|
||||
// set up our our instance data
|
||||
InstanceData* instanceData = new InstanceData;
|
||||
if (!instanceData)
|
||||
return NPERR_OUT_OF_MEMORY_ERROR;
|
||||
instanceData->npp = instance;
|
||||
instanceData->streamMode = NP_ASFILEONLY;
|
||||
instanceData->testFunction = FUNCTION_NONE;
|
||||
|
||||
@@ -175,9 +175,6 @@ MulticastDNSDeviceProvider::Init()
|
||||
}
|
||||
|
||||
mWrappedListener = new DNSServiceWrappedListener();
|
||||
if (NS_WARN_IF(!mWrappedListener)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv = mWrappedListener->SetListener(this)))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -50,8 +50,6 @@ nsXBLProtoImplMethod::AppendBodyText(const nsAString& aText)
|
||||
nsXBLUncompiledMethod* uncompiledMethod = GetUncompiledMethod();
|
||||
if (!uncompiledMethod) {
|
||||
uncompiledMethod = new nsXBLUncompiledMethod();
|
||||
if (!uncompiledMethod)
|
||||
return;
|
||||
SetUncompiledMethod(uncompiledMethod);
|
||||
}
|
||||
|
||||
@@ -72,8 +70,6 @@ nsXBLProtoImplMethod::AddParameter(const nsAString& aText)
|
||||
nsXBLUncompiledMethod* uncompiledMethod = GetUncompiledMethod();
|
||||
if (!uncompiledMethod) {
|
||||
uncompiledMethod = new nsXBLUncompiledMethod();
|
||||
if (!uncompiledMethod)
|
||||
return;
|
||||
SetUncompiledMethod(uncompiledMethod);
|
||||
}
|
||||
|
||||
@@ -89,8 +85,6 @@ nsXBLProtoImplMethod::SetLineNumber(uint32_t aLineNumber)
|
||||
nsXBLUncompiledMethod* uncompiledMethod = GetUncompiledMethod();
|
||||
if (!uncompiledMethod) {
|
||||
uncompiledMethod = new nsXBLUncompiledMethod();
|
||||
if (!uncompiledMethod)
|
||||
return;
|
||||
SetUncompiledMethod(uncompiledMethod);
|
||||
}
|
||||
|
||||
@@ -168,8 +162,6 @@ nsXBLProtoImplMethod::CompileMember(AutoJSAPI& jsapi, const nsString& aClassStr,
|
||||
char** args = nullptr;
|
||||
if (paramCount > 0) {
|
||||
args = new char*[paramCount];
|
||||
if (!args)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Add our parameters to our args array.
|
||||
int32_t argPos = 0;
|
||||
|
||||
@@ -65,8 +65,6 @@ struct nsXBLUncompiledMethod {
|
||||
|
||||
void AddParameter(const nsAString& aText) {
|
||||
nsXBLParameter* param = new nsXBLParameter(aText);
|
||||
if (!param)
|
||||
return;
|
||||
if (!mParameters)
|
||||
mParameters = param;
|
||||
else
|
||||
|
||||
@@ -197,9 +197,6 @@ void
|
||||
nsXBLResourceLoader::AddResource(nsIAtom* aResourceType, const nsAString& aSrc)
|
||||
{
|
||||
nsXBLResource* res = new nsXBLResource(aResourceType, aSrc);
|
||||
if (!res)
|
||||
return;
|
||||
|
||||
if (!mResourceList)
|
||||
mResourceList = res;
|
||||
else
|
||||
|
||||
@@ -165,7 +165,7 @@ AndroidSurfaceTexture::Init(GLContext* aContext, GLuint aTexture)
|
||||
return false;
|
||||
}
|
||||
|
||||
mNativeWindow = AndroidNativeWindow::CreateFromSurface(GetJNIForThread(),
|
||||
mNativeWindow = AndroidNativeWindow::CreateFromSurface(jni::GetEnvForThread(),
|
||||
mSurface.Get());
|
||||
MOZ_ASSERT(mNativeWindow, "Failed to create native window from surface");
|
||||
|
||||
@@ -206,7 +206,7 @@ AndroidSurfaceTexture::UpdateTexImage()
|
||||
void
|
||||
AndroidSurfaceTexture::GetTransformMatrix(gfx::Matrix4x4& aMatrix)
|
||||
{
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
JNIEnv* const env = jni::GetEnvForThread();
|
||||
|
||||
auto jarray = FloatArray::LocalRef::Adopt(env, env->NewFloatArray(16));
|
||||
mSurfaceTexture->GetTransformMatrix(jarray);
|
||||
|
||||
@@ -295,6 +295,7 @@ private:
|
||||
DECL_GFX_PREF(Live, "layers.acceleration.draw-fps.print-histogram", FPSPrintHistogram, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.acceleration.draw-fps.write-to-file", WriteFPSToFile, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.acceleration.force-enabled", LayersAccelerationForceEnabled, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.amd-switchable-gfx.enabled", LayersAMDSwitchableGfxEnabled, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.async-pan-zoom.enabled", AsyncPanZoomEnabledDoNotUseDirectly, bool, true);
|
||||
DECL_GFX_PREF(Once, "layers.async-pan-zoom.separate-event-thread", AsyncPanZoomSeparateEventThread, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.bench.enabled", LayersBenchEnabled, bool, false);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "gfxFontConstants.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "gfxPlatformFontList.h"
|
||||
|
||||
@@ -433,6 +434,8 @@ gfxUserFontEntry::LoadNextSrc()
|
||||
gfxUserFontData::kUnknownCompression);
|
||||
mPlatformFontEntry = fe;
|
||||
SetLoadState(STATUS_LOADED);
|
||||
Telemetry::Accumulate(Telemetry::WEBFONT_SRCTYPE,
|
||||
currSrc.mSourceType + 1);
|
||||
return;
|
||||
} else {
|
||||
LOG(("userfonts (%p) [src %d] failed local: (%s) for (%s)\n",
|
||||
@@ -463,6 +466,14 @@ gfxUserFontEntry::LoadNextSrc()
|
||||
if (fe) {
|
||||
mPlatformFontEntry = fe;
|
||||
SetLoadState(STATUS_LOADED);
|
||||
if (LOG_ENABLED()) {
|
||||
nsAutoCString fontURI;
|
||||
currSrc.mURI->GetSpec(fontURI);
|
||||
LOG(("userfonts (%p) [src %d] "
|
||||
"loaded uri from cache: (%s) for (%s)\n",
|
||||
mFontSet, mSrcIndex, fontURI.get(),
|
||||
NS_ConvertUTF16toUTF8(mFamilyName).get()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -488,6 +499,8 @@ gfxUserFontEntry::LoadNextSrc()
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
LoadPlatformFont(buffer, bufferLength)) {
|
||||
SetLoadState(STATUS_LOADED);
|
||||
Telemetry::Accumulate(Telemetry::WEBFONT_SRCTYPE,
|
||||
currSrc.mSourceType + 1);
|
||||
return;
|
||||
} else {
|
||||
mFontSet->LogMessage(this,
|
||||
@@ -542,6 +555,8 @@ gfxUserFontEntry::LoadNextSrc()
|
||||
// LoadPlatformFont takes ownership of the buffer, so no need
|
||||
// to free it here.
|
||||
SetLoadState(STATUS_LOADED);
|
||||
Telemetry::Accumulate(Telemetry::WEBFONT_SRCTYPE,
|
||||
currSrc.mSourceType + 1);
|
||||
return;
|
||||
} else {
|
||||
mFontSet->LogMessage(this,
|
||||
@@ -583,6 +598,7 @@ gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength)
|
||||
|
||||
gfxUserFontType fontType =
|
||||
gfxFontUtils::DetermineFontDataType(aFontData, aLength);
|
||||
Telemetry::Accumulate(Telemetry::WEBFONT_FONTTYPE, uint32_t(fontType));
|
||||
|
||||
// Unwrap/decompress/sanitize or otherwise munge the downloaded data
|
||||
// to make a usable sfnt structure.
|
||||
@@ -595,12 +611,24 @@ gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength)
|
||||
// Call the OTS sanitizer; this will also decode WOFF to sfnt
|
||||
// if necessary. The original data in aFontData is left unchanged.
|
||||
uint32_t saneLen;
|
||||
uint32_t fontCompressionRatio = 0;
|
||||
const uint8_t* saneData =
|
||||
SanitizeOpenTypeData(aFontData, aLength, saneLen, fontType);
|
||||
if (!saneData) {
|
||||
mFontSet->LogMessage(this, "rejected by sanitizer");
|
||||
}
|
||||
if (saneData) {
|
||||
if (saneLen) {
|
||||
fontCompressionRatio = uint32_t(100.0 * aLength / saneLen + 0.5);
|
||||
if (fontType == GFX_USERFONT_WOFF ||
|
||||
fontType == GFX_USERFONT_WOFF2) {
|
||||
Telemetry::Accumulate(fontType == GFX_USERFONT_WOFF ?
|
||||
Telemetry::WEBFONT_COMPRESSION_WOFF :
|
||||
Telemetry::WEBFONT_COMPRESSION_WOFF2,
|
||||
fontCompressionRatio);
|
||||
}
|
||||
}
|
||||
|
||||
// The sanitizer ensures that we have a valid sfnt and a usable
|
||||
// name table, so this should never fail unless we're out of
|
||||
// memory, and GetFullNameFromSFNT is not directly exposed to
|
||||
@@ -647,11 +675,11 @@ gfxUserFontEntry::LoadPlatformFont(const uint8_t* aFontData, uint32_t& aLength)
|
||||
if (LOG_ENABLED()) {
|
||||
nsAutoCString fontURI;
|
||||
mSrcList[mSrcIndex].mURI->GetSpec(fontURI);
|
||||
LOG(("userfonts (%p) [src %d] loaded uri: (%s) for (%s) (%p) gen: %8.8x\n",
|
||||
LOG(("userfonts (%p) [src %d] loaded uri: (%s) for (%s) "
|
||||
"(%p) gen: %8.8x compress: %d%%\n",
|
||||
mFontSet, mSrcIndex, fontURI.get(),
|
||||
NS_ConvertUTF16toUTF8(mFamilyName).get(),
|
||||
this,
|
||||
uint32_t(mFontSet->mGeneration)));
|
||||
this, uint32_t(mFontSet->mGeneration), fontCompressionRatio));
|
||||
}
|
||||
mPlatformFontEntry = fe;
|
||||
SetLoadState(STATUS_LOADED);
|
||||
@@ -744,7 +772,10 @@ gfxUserFontEntry::GetUserFontSets(nsTArray<gfxUserFontSet*>& aResult)
|
||||
}
|
||||
|
||||
gfxUserFontSet::gfxUserFontSet()
|
||||
: mFontFamilies(4), mLocalRulesUsed(false)
|
||||
: mFontFamilies(4),
|
||||
mLocalRulesUsed(false),
|
||||
mDownloadCount(0),
|
||||
mDownloadSize(0)
|
||||
{
|
||||
IncrementGeneration(true);
|
||||
gfxPlatformFontList* fp = gfxPlatformFontList::PlatformFontList();
|
||||
|
||||
@@ -468,6 +468,15 @@ public:
|
||||
|
||||
static mozilla::LogModule* GetUserFontsLog();
|
||||
|
||||
// record statistics about font completion
|
||||
virtual void RecordFontLoadDone(uint32_t aFontSize,
|
||||
mozilla::TimeStamp aDoneTime) {}
|
||||
|
||||
void GetLoadStatistics(uint32_t& aLoadCount, uint64_t& aLoadSize) const {
|
||||
aLoadCount = mDownloadCount;
|
||||
aLoadSize = mDownloadSize;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Protected destructor, to discourage deletion outside of Release():
|
||||
virtual ~gfxUserFontSet();
|
||||
@@ -513,6 +522,10 @@ protected:
|
||||
|
||||
// true when local names have been looked up, false otherwise
|
||||
bool mLocalRulesUsed;
|
||||
|
||||
// performance stats
|
||||
uint32_t mDownloadCount;
|
||||
uint64_t mDownloadSize;
|
||||
};
|
||||
|
||||
// acts a placeholder until the real font is downloaded
|
||||
|
||||
@@ -184,28 +184,6 @@ gfxWindowsNativeDrawing::BeginNativeDrawing()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
gfxWindowsNativeDrawing::IsDoublePass()
|
||||
{
|
||||
if (mContext->GetDrawTarget()->GetBackendType() != mozilla::gfx::BackendType::CAIRO ||
|
||||
mContext->GetDrawTarget()->IsDualDrawTarget()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RefPtr<gfxASurface> surf = mContext->CurrentSurface(&mDeviceOffset.x, &mDeviceOffset.y);
|
||||
if (!surf || surf->CairoStatus())
|
||||
return false;
|
||||
if (surf->GetType() != gfxSurfaceType::Win32 &&
|
||||
surf->GetType() != gfxSurfaceType::Win32Printing) {
|
||||
return true;
|
||||
}
|
||||
if ((surf->GetContentType() != gfxContentType::COLOR ||
|
||||
(surf->GetContentType() == gfxContentType::COLOR_ALPHA &&
|
||||
!(mNativeDrawFlags & CAN_DRAW_TO_COLOR_ALPHA))))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxWindowsNativeDrawing::ShouldRenderAgain()
|
||||
{
|
||||
|
||||
@@ -79,9 +79,6 @@ public:
|
||||
/* Returns true if the native drawing should be executed again */
|
||||
bool ShouldRenderAgain();
|
||||
|
||||
/* Returns true if double pass alpha extraction is taking place. */
|
||||
bool IsDoublePass();
|
||||
|
||||
/* Places the result to the context, if necessary */
|
||||
void PaintToContext();
|
||||
|
||||
|
||||
@@ -1682,7 +1682,7 @@ gfxWindowsPlatform::GetDXGIAdapter()
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
bool DoesD3D11DeviceWork(ID3D11Device *device)
|
||||
bool DoesD3D11DeviceWork()
|
||||
{
|
||||
static bool checked = false;
|
||||
static bool result = false;
|
||||
@@ -1840,7 +1840,11 @@ bool DoesRenderTargetViewNeedsRecreating(ID3D11Device *device)
|
||||
deviceContext->CopyResource(cpuTexture, offscreenTexture);
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||
deviceContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped);
|
||||
hr = deviceContext->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mapped);
|
||||
if (FAILED(hr)) {
|
||||
gfxCriticalNote << "DoesRecreatingMapFailed " << hexa(hr);
|
||||
return false;
|
||||
}
|
||||
int resultColor = *(int*)mapped.pData;
|
||||
deviceContext->Unmap(cpuTexture, 0);
|
||||
cpuTexture->Release();
|
||||
@@ -1859,6 +1863,22 @@ bool DoesRenderTargetViewNeedsRecreating(ID3D11Device *device)
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool TryCreateTexture2D(ID3D11Device *device,
|
||||
D3D11_TEXTURE2D_DESC* desc,
|
||||
D3D11_SUBRESOURCE_DATA* data,
|
||||
RefPtr<ID3D11Texture2D>& texture)
|
||||
{
|
||||
// Older Intel driver version (see bug 1221348 for version #s) crash when
|
||||
// creating a texture with shared keyed mutex and data.
|
||||
MOZ_SEH_TRY {
|
||||
return !FAILED(device->CreateTexture2D(desc, data, getter_AddRefs(texture)));
|
||||
} MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
|
||||
// For now we want to aggregrate all the crash signature to a known crash.
|
||||
MOZ_CRASH("Crash creating texture. See bug 1221348.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// See bug 1083071. On some drivers, Direct3D 11 CreateShaderResourceView fails
|
||||
// with E_OUTOFMEMORY.
|
||||
@@ -1883,6 +1903,9 @@ bool DoesD3D11TextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT forma
|
||||
gfxInfo->GetAdapterVendorID(vendorID);
|
||||
gfxInfo->GetAdapterVendorID2(vendorID2);
|
||||
if (vendorID.EqualsLiteral("0x8086") && vendorID2.IsEmpty()) {
|
||||
if (!gfxPrefs::LayersAMDSwitchableGfxEnabled()) {
|
||||
return false;
|
||||
}
|
||||
gfxCriticalError(CriticalLog::DefaultOptions(false)) << "PossiblyBrokenSurfaceSharing_UnexpectedAMDGPU";
|
||||
}
|
||||
}
|
||||
@@ -1907,12 +1930,30 @@ bool DoesD3D11TextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT forma
|
||||
for (size_t i = 0; i < sizeof(color)/sizeof(color[0]); i++) {
|
||||
color[i] = 0xff00ffff;
|
||||
}
|
||||
// We're going to check that sharing actually works with this format
|
||||
D3D11_SUBRESOURCE_DATA data;
|
||||
data.pSysMem = color;
|
||||
data.SysMemPitch = texture_size * 4;
|
||||
data.SysMemSlicePitch = 0;
|
||||
if (FAILED(device->CreateTexture2D(&desc, &data, getter_AddRefs(texture)))) {
|
||||
// XXX If we pass the data directly at texture creation time we
|
||||
// get a crash on Intel 8.5.10.[18xx-1994] drivers.
|
||||
// We can work around this issue by doing UpdateSubresource.
|
||||
if (!TryCreateTexture2D(device, &desc, nullptr, texture)) {
|
||||
gfxCriticalError() << "DoesD3D11TextureSharingWork_TryCreateTextureFailure";
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<IDXGIKeyedMutex> sourceSharedMutex;
|
||||
texture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(sourceSharedMutex));
|
||||
if (FAILED(sourceSharedMutex->AcquireSync(0, 30*1000))) {
|
||||
gfxCriticalError() << "DoesD3D11TextureSharingWork_SourceMutexTimeout";
|
||||
// only wait for 30 seconds
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<ID3D11DeviceContext> deviceContext;
|
||||
device->GetImmediateContext(getter_AddRefs(deviceContext));
|
||||
|
||||
int stride = texture_size * 4;
|
||||
deviceContext->UpdateSubresource(texture, 0, nullptr, color, stride, stride * texture_size);
|
||||
|
||||
if (FAILED(sourceSharedMutex->ReleaseSync(0))) {
|
||||
gfxCriticalError() << "DoesD3D11TextureSharingWork_SourceReleaseSyncTimeout";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1921,10 +1962,12 @@ bool DoesD3D11TextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT forma
|
||||
if (FAILED(texture->QueryInterface(__uuidof(IDXGIResource),
|
||||
getter_AddRefs(otherResource))))
|
||||
{
|
||||
gfxCriticalError() << "DoesD3D11TextureSharingWork_GetResourceFailure";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FAILED(otherResource->GetSharedHandle(&shareHandle))) {
|
||||
gfxCriticalError() << "DoesD3D11TextureSharingWork_GetSharedTextureFailure";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1940,6 +1983,7 @@ bool DoesD3D11TextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT forma
|
||||
if (FAILED(sharedResource->QueryInterface(__uuidof(ID3D11Texture2D),
|
||||
getter_AddRefs(sharedTexture))))
|
||||
{
|
||||
gfxCriticalError() << "DoesD3D11TextureSharingWork_GetSharedTextureFailure";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1950,13 +1994,12 @@ bool DoesD3D11TextureSharingWorkInternal(ID3D11Device *device, DXGI_FORMAT forma
|
||||
desc.MiscFlags = 0;
|
||||
desc.BindFlags = 0;
|
||||
if (FAILED(device->CreateTexture2D(&desc, nullptr, getter_AddRefs(cpuTexture)))) {
|
||||
gfxCriticalError() << "DoesD3D11TextureSharingWork_CreateTextureFailure";
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<IDXGIKeyedMutex> sharedMutex;
|
||||
RefPtr<ID3D11DeviceContext> deviceContext;
|
||||
sharedResource->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)getter_AddRefs(sharedMutex));
|
||||
device->GetImmediateContext(getter_AddRefs(deviceContext));
|
||||
if (FAILED(sharedMutex->AcquireSync(0, 30*1000))) {
|
||||
gfxCriticalError() << "DoesD3D11TextureSharingWork_AcquireSyncTimeout";
|
||||
// only wait for 30 seconds
|
||||
@@ -2117,7 +2160,7 @@ gfxWindowsPlatform::AttemptD3D11DeviceCreation()
|
||||
gfxCriticalError() << "D3D11 device creation failed: " << hexa(hr);
|
||||
return FeatureStatus::Failed;
|
||||
}
|
||||
if (!DoesD3D11DeviceWork(mD3D11Device)) {
|
||||
if (!DoesD3D11DeviceWork()) {
|
||||
mD3D11Device = nullptr;
|
||||
return FeatureStatus::Blocked;
|
||||
}
|
||||
@@ -2651,7 +2694,7 @@ gfxWindowsPlatform::CreateD3D11DecoderDevice()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (FAILED(hr) || !device || !DoesD3D11DeviceWork(device)) {
|
||||
if (FAILED(hr) || !device || !DoesD3D11DeviceWork()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
# 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/.
|
||||
|
||||
ifneq ($(dir $(PROGRAM)),./)
|
||||
GENERATED_DIRS = $(dir $(PROGRAM))
|
||||
endif
|
||||
|
||||
ifndef MOZ_WINCONSOLE
|
||||
ifdef MOZ_DEBUG
|
||||
MOZ_WINCONSOLE = 1
|
||||
|
||||
@@ -4,11 +4,15 @@
|
||||
# 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/.
|
||||
|
||||
# Any changes that affect Android need to be made in pie/moz.build as well.
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
||||
Program(CONFIG['MOZ_CHILD_PROCESS_NAME'])
|
||||
SOURCES += [
|
||||
'MozillaRuntimeMainAndroid.cpp',
|
||||
]
|
||||
|
||||
DIRS += ['pie']
|
||||
else:
|
||||
kwargs = {
|
||||
'linkage': None,
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
Program(CONFIG['MOZ_CHILD_PROCESS_NAME_PIE'])
|
||||
SOURCES += [
|
||||
'../MozillaRuntimeMainAndroid.cpp',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/toolkit/xre',
|
||||
'/xpcom/base',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_SANDBOX']:
|
||||
USE_LIBS += [
|
||||
'mozsandbox',
|
||||
]
|
||||
|
||||
# gcc lto likes to put the top level asm in syscall.cc in a different partition
|
||||
# from the function using it which breaks the build. Work around that by
|
||||
# forcing there to be only one partition.
|
||||
if '-flto' in CONFIG['OS_CXXFLAGS'] and not CONFIG['CLANG_CXX']:
|
||||
LDFLAGS += ['--param lto-partitions=1']
|
||||
|
||||
LDFLAGS += ['-pie']
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
@@ -119,6 +119,12 @@ class CommandLine {
|
||||
// Append a loose value to the command line.
|
||||
void AppendLooseValue(const std::wstring& value);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void AppendLooseValue(const wchar_t* value) {
|
||||
AppendLooseValue(std::wstring(value));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Append the arguments from another command line to this one.
|
||||
// If |include_program| is true, include |other|'s program as well.
|
||||
void AppendArguments(const CommandLine& other,
|
||||
|
||||
@@ -116,6 +116,10 @@ class FilePath {
|
||||
FilePath(const FilePath& that) : path_(that.path_) {}
|
||||
explicit FilePath(const StringType& path) : path_(path) {}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
explicit FilePath(const wchar_t* path) : path_(path) {}
|
||||
#endif
|
||||
|
||||
FilePath& operator=(const FilePath& that) {
|
||||
path_ = that.path_;
|
||||
return *this;
|
||||
|
||||
@@ -71,7 +71,8 @@ enum ProcessArchitecture {
|
||||
PROCESS_ARCH_I386 = 0x1,
|
||||
PROCESS_ARCH_X86_64 = 0x2,
|
||||
PROCESS_ARCH_PPC = 0x4,
|
||||
PROCESS_ARCH_ARM = 0x8
|
||||
PROCESS_ARCH_ARM = 0x8,
|
||||
PROCESS_ARCH_MIPS = 0x10
|
||||
};
|
||||
|
||||
inline ProcessArchitecture GetCurrentProcessArchitecture()
|
||||
@@ -85,6 +86,8 @@ inline ProcessArchitecture GetCurrentProcessArchitecture()
|
||||
currentArchitecture = base::PROCESS_ARCH_PPC;
|
||||
#elif defined(ARCH_CPU_ARMEL)
|
||||
currentArchitecture = base::PROCESS_ARCH_ARM;
|
||||
#elif defined(ARCH_CPU_MIPS)
|
||||
currentArchitecture = base::PROCESS_ARCH_MIPS;
|
||||
#endif
|
||||
return currentArchitecture;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,10 @@ using mozilla::ipc::GeckoChildProcessHost;
|
||||
static const int kMagicAndroidSystemPropFd = 5;
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "AndroidBridge.h"
|
||||
#endif
|
||||
|
||||
static const bool kLowRightsSubprocesses =
|
||||
// We currently only attempt to drop privileges on gonk, because we
|
||||
// have no plugins or extensions to worry about breaking.
|
||||
@@ -94,11 +98,11 @@ GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType,
|
||||
mPrivileges(aPrivileges),
|
||||
mMonitor("mozilla.ipc.GeckChildProcessHost.mMonitor"),
|
||||
mProcessState(CREATING_CHANNEL),
|
||||
mDelegate(nullptr),
|
||||
#if defined(MOZ_SANDBOX) && defined(XP_WIN)
|
||||
mEnableSandboxLogging(false),
|
||||
mSandboxLevel(0),
|
||||
#endif
|
||||
mDelegate(nullptr),
|
||||
mChildProcessHandle(0)
|
||||
#if defined(MOZ_WIDGET_COCOA)
|
||||
, mChildTask(MACH_PORT_NULL)
|
||||
@@ -168,7 +172,17 @@ GeckoChildProcessHost::GetPathToBinary(FilePath& exePath)
|
||||
exePath = exePath.DirName();
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
exePath = exePath.AppendASCII("lib");
|
||||
|
||||
// We must use the PIE binary on 5.0 and higher
|
||||
const char* processName = mozilla::AndroidBridge::Bridge()->GetAPIVersion() >= 21 ?
|
||||
MOZ_CHILD_PROCESS_NAME_PIE : MOZ_CHILD_PROCESS_NAME;
|
||||
|
||||
exePath = exePath.AppendASCII(processName);
|
||||
#else
|
||||
exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
@@ -519,12 +533,15 @@ AddAppDirToCommandLine(std::vector<std::string>& aCmdLine)
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(appDir));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
#if defined(XP_WIN)
|
||||
nsString path;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(appDir->GetPath(path)));
|
||||
aCmdLine.AppendLooseValue(UTF8ToWide("-appdir"));
|
||||
std::wstring wpath = path.get();
|
||||
aCmdLine.AppendLooseValue(wpath);
|
||||
#else
|
||||
nsAutoCString path;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(appDir->GetNativePath(path)));
|
||||
#if defined(XP_WIN)
|
||||
aCmdLine.AppendLooseValue(UTF8ToWide("-appdir"));
|
||||
aCmdLine.AppendLooseValue(UTF8ToWide(path.get()));
|
||||
#else
|
||||
aCmdLine.push_back("-appdir");
|
||||
aCmdLine.push_back(path.get());
|
||||
#endif
|
||||
@@ -542,26 +559,27 @@ MaybeAddNsprLogFileAccess(std::vector<std::wstring>& aAllowedFilesReadWrite)
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR,
|
||||
getter_AddRefs(file));
|
||||
if (NS_FAILED(rv) || !file) {
|
||||
NS_WARNING("Failed to get current working directory");
|
||||
return;
|
||||
}
|
||||
|
||||
nsDependentCString nsprLogFile(nsprLogFileEnv);
|
||||
rv = file->AppendRelativeNativePath(nsprLogFile);
|
||||
nsDependentCString nsprLogFilePath(nsprLogFileEnv);
|
||||
nsCOMPtr<nsIFile> nsprLogFile;
|
||||
nsresult rv = NS_NewNativeLocalFile(nsprLogFilePath, true,
|
||||
getter_AddRefs(nsprLogFile));
|
||||
if (NS_FAILED(rv)) {
|
||||
// Not a relative path, try it as an absolute one.
|
||||
rv = file->InitWithNativePath(nsprLogFile);
|
||||
// Not an absolute path, try it as a relative one.
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR,
|
||||
getter_AddRefs(nsprLogFile));
|
||||
if (NS_FAILED(rv) || !nsprLogFile) {
|
||||
NS_WARNING("Failed to get current working directory");
|
||||
return;
|
||||
}
|
||||
|
||||
rv = nsprLogFile->AppendRelativeNativePath(nsprLogFilePath);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString resolvedFilePath;
|
||||
rv = file->GetPath(resolvedFilePath);
|
||||
rv = nsprLogFile->GetPath(resolvedFilePath);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
@@ -570,7 +588,7 @@ MaybeAddNsprLogFileAccess(std::vector<std::wstring>& aAllowedFilesReadWrite)
|
||||
// Chromium sandbox can only allow access to fully qualified file paths. This
|
||||
// only affects the environment for the child process we're about to create,
|
||||
// because this will get reset to the original value in PerformAsyncLaunch.
|
||||
aAllowedFilesReadWrite.push_back(resolvedFilePath.get());
|
||||
aAllowedFilesReadWrite.push_back(std::wstring(resolvedFilePath.get()));
|
||||
nsAutoCString resolvedEnvVar("NSPR_LOG_FILE=");
|
||||
AppendUTF16toUTF8(resolvedFilePath, resolvedEnvVar);
|
||||
PR_SetEnv(resolvedEnvVar.get());
|
||||
@@ -624,32 +642,19 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
path += "/lib";
|
||||
# endif // MOZ_WIDGET_ANDROID
|
||||
const char *ld_library_path = PR_GetEnv("LD_LIBRARY_PATH");
|
||||
nsCString new_ld_lib_path;
|
||||
if (ld_library_path && *ld_library_path) {
|
||||
new_ld_lib_path.Assign(path.get());
|
||||
new_ld_lib_path.Append(':');
|
||||
new_ld_lib_path.Append(ld_library_path);
|
||||
newEnvVars["LD_LIBRARY_PATH"] = new_ld_lib_path.get();
|
||||
} else {
|
||||
newEnvVars["LD_LIBRARY_PATH"] = path.get();
|
||||
}
|
||||
nsCString new_ld_lib_path(path.get());
|
||||
|
||||
# if (MOZ_WIDGET_GTK == 3)
|
||||
if (mProcessType == GeckoProcessType_Plugin) {
|
||||
const char *ld_preload = PR_GetEnv("LD_PRELOAD");
|
||||
nsCString new_ld_preload;
|
||||
|
||||
new_ld_preload.Assign(path.get());
|
||||
new_ld_preload.AppendLiteral("/" DLL_PREFIX "mozgtk2" DLL_SUFFIX);
|
||||
|
||||
if (ld_preload && *ld_preload) {
|
||||
new_ld_preload.AppendLiteral(":");
|
||||
new_ld_preload.Append(ld_preload);
|
||||
}
|
||||
newEnvVars["LD_PRELOAD"] = new_ld_preload.get();
|
||||
new_ld_lib_path.Append("/gtk2:");
|
||||
new_ld_lib_path.Append(path.get());
|
||||
}
|
||||
# endif // MOZ_WIDGET_GTK
|
||||
|
||||
#endif
|
||||
if (ld_library_path && *ld_library_path) {
|
||||
new_ld_lib_path.Append(':');
|
||||
new_ld_lib_path.Append(ld_library_path);
|
||||
}
|
||||
newEnvVars["LD_LIBRARY_PATH"] = new_ld_lib_path.get();
|
||||
|
||||
# elif OS_MACOSX
|
||||
newEnvVars["DYLD_LIBRARY_PATH"] = path.get();
|
||||
@@ -665,7 +670,7 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
// been set up by whatever may have launched the browser.
|
||||
const char* prevInterpose = PR_GetEnv("DYLD_INSERT_LIBRARIES");
|
||||
nsCString interpose;
|
||||
if (prevInterpose) {
|
||||
if (prevInterpose && strlen(prevInterpose) > 0) {
|
||||
interpose.Assign(prevInterpose);
|
||||
interpose.Append(':');
|
||||
}
|
||||
@@ -919,6 +924,12 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
++it) {
|
||||
mSandboxBroker.AllowReadWriteFile(it->c_str());
|
||||
}
|
||||
|
||||
for (auto it = mAllowedDirectories.begin();
|
||||
it != mAllowedDirectories.end();
|
||||
++it) {
|
||||
mSandboxBroker.AllowDirectory(it->c_str());
|
||||
}
|
||||
}
|
||||
#endif // XP_WIN && MOZ_SANDBOX
|
||||
|
||||
@@ -948,6 +959,16 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||
#endif
|
||||
{
|
||||
base::LaunchApp(cmdLine, false, false, &process);
|
||||
|
||||
#ifdef MOZ_SANDBOX
|
||||
// We need to be able to duplicate handles to non-sandboxed content
|
||||
// processes, so add it as a target peer.
|
||||
if (mProcessType == GeckoProcessType_Content) {
|
||||
if (!mSandboxBroker.AddTargetPeer(process)) {
|
||||
NS_WARNING("Failed to add content process as target peer.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
@@ -160,6 +160,7 @@ protected:
|
||||
SandboxBroker mSandboxBroker;
|
||||
std::vector<std::wstring> mAllowedFilesRead;
|
||||
std::vector<std::wstring> mAllowedFilesReadWrite;
|
||||
std::vector<std::wstring> mAllowedDirectories;
|
||||
bool mEnableSandboxLogging;
|
||||
int32_t mSandboxLevel;
|
||||
#endif
|
||||
|
||||
+2
-2
@@ -165,8 +165,8 @@ include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
for var in ('MOZ_CHILD_PROCESS_NAME', 'MOZ_CHILD_PROCESS_BUNDLE',
|
||||
'DLL_PREFIX', 'DLL_SUFFIX'):
|
||||
for var in ('MOZ_CHILD_PROCESS_NAME', 'MOZ_CHILD_PROCESS_NAME_PIE',
|
||||
'MOZ_CHILD_PROCESS_BUNDLE', 'DLL_PREFIX', 'DLL_SUFFIX'):
|
||||
DEFINES[var] = '"%s"' % CONFIG[var]
|
||||
|
||||
if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
|
||||
|
||||
@@ -1088,6 +1088,20 @@ PresShell::Destroy()
|
||||
LogTextPerfStats(tp, this, tp->cumulative, 0.0, eLog_totals, nullptr);
|
||||
}
|
||||
}
|
||||
if (mPresContext) {
|
||||
gfxUserFontSet* fs = mPresContext->GetUserFontSet();
|
||||
if (fs) {
|
||||
uint32_t fontCount;
|
||||
uint64_t fontSize;
|
||||
fs->GetLoadStatistics(fontCount, fontSize);
|
||||
Telemetry::Accumulate(Telemetry::WEBFONT_PER_PAGE, fontCount);
|
||||
Telemetry::Accumulate(Telemetry::WEBFONT_SIZE_PER_PAGE,
|
||||
uint32_t(fontSize/1024));
|
||||
} else {
|
||||
Telemetry::Accumulate(Telemetry::WEBFONT_PER_PAGE, 0);
|
||||
Telemetry::Accumulate(Telemetry::WEBFONT_SIZE_PER_PAGE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MOZ_REFLOW_PERF
|
||||
DumpReflows();
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
typedef mozilla::TimeStamp TimeStamp;
|
||||
typedef mozilla::TimeDuration TimeDuration;
|
||||
|
||||
AsyncScrollBase(nsPoint aStartPos);
|
||||
explicit AsyncScrollBase(nsPoint aStartPos);
|
||||
|
||||
void Update(TimeStamp aTime,
|
||||
nsPoint aDestination,
|
||||
@@ -87,6 +87,6 @@ protected:
|
||||
nsSMILKeySpline mTimingFunctionY;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_layout_AsyncScrollBase_h_
|
||||
|
||||
@@ -363,7 +363,11 @@ SetOpacityOnElement(nsIContent* aContent, double aOpacity)
|
||||
bool
|
||||
ScrollbarActivity::UpdateOpacity(TimeStamp aTime)
|
||||
{
|
||||
double progress = (aTime - mFadeBeginTime) / FadeDuration();
|
||||
// Avoid division by zero if mScrollbarFadeDuration is zero, just jump
|
||||
// to the end of the fade animation
|
||||
double progress = mScrollbarFadeDuration
|
||||
? ((aTime - mFadeBeginTime) / FadeDuration())
|
||||
: 1.0;
|
||||
double opacity = 1.0 - std::max(0.0, std::min(1.0, progress));
|
||||
|
||||
// 'this' may be getting destroyed during SetOpacityOnElement calls.
|
||||
|
||||
@@ -367,6 +367,7 @@ asserts-if(winWidget,0-3) load 499885-1.xhtml
|
||||
load 501535-1.html
|
||||
load 503961-1.xhtml
|
||||
load 503961-2.html
|
||||
load 505912-1.html
|
||||
load 508168-1.html
|
||||
load 508816-1.xul
|
||||
load 508908-1.html
|
||||
|
||||
@@ -301,8 +301,8 @@ nsPluginFrame::PrepForDrawing(nsIWidget *aWidget)
|
||||
viewMan->InsertChild(view, mInnerView, nullptr, true);
|
||||
|
||||
mWidget->SetParent(parentWidget);
|
||||
mWidget->Show(true);
|
||||
mWidget->Enable(true);
|
||||
mWidget->Show(true);
|
||||
|
||||
// Set the plugin window to have an empty clip region until we know
|
||||
// what our true position, size and clip region are. These
|
||||
@@ -1090,7 +1090,7 @@ void
|
||||
nsPluginFrame::DidSetWidgetGeometry()
|
||||
{
|
||||
#if defined(XP_MACOSX)
|
||||
if (mInstanceOwner) {
|
||||
if (mInstanceOwner && !IsHidden()) {
|
||||
mInstanceOwner->FixUpPluginWindow(nsPluginInstanceOwner::ePluginPaintEnable);
|
||||
}
|
||||
#else
|
||||
@@ -1535,10 +1535,6 @@ nsPluginFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext& aRenderingContext,
|
||||
const nsRect& aDirtyRect, const nsRect& aPluginRect)
|
||||
{
|
||||
#if defined(XP_MACOSX)
|
||||
DrawTarget& aDrawTarget = *aRenderingContext.GetDrawTarget();
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
if (mInstanceOwner) {
|
||||
gfxRect frameGfxRect =
|
||||
@@ -1551,219 +1547,17 @@ nsPluginFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
|
||||
mInstanceOwner->Paint(ctx, frameGfxRect, dirtyGfxRect);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Screen painting code
|
||||
#if defined(XP_MACOSX)
|
||||
// delegate all painting to the plugin instance.
|
||||
#else
|
||||
# if defined(DEBUG)
|
||||
// On Desktop, we should have built a layer as we no longer support in-process
|
||||
// plugins or synchronous painting. We can only get here for windowed plugins
|
||||
// (which draw themselves), or via some error/unload state.
|
||||
if (mInstanceOwner) {
|
||||
if (mInstanceOwner->GetDrawingModel() == NPDrawingModelCoreGraphics ||
|
||||
mInstanceOwner->GetDrawingModel() == NPDrawingModelCoreAnimation ||
|
||||
mInstanceOwner->GetDrawingModel() ==
|
||||
NPDrawingModelInvalidatingCoreAnimation) {
|
||||
int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
|
||||
// Clip to the content area where the plugin should be drawn. If
|
||||
// we don't do this, the plugin can draw outside its bounds.
|
||||
nsIntRect contentPixels = aPluginRect.ToNearestPixels(appUnitsPerDevPixel);
|
||||
nsIntRect dirtyPixels = aDirtyRect.ToOutsidePixels(appUnitsPerDevPixel);
|
||||
nsIntRect clipPixels;
|
||||
clipPixels.IntersectRect(contentPixels, dirtyPixels);
|
||||
|
||||
// Don't invoke the drawing code if the clip is empty.
|
||||
if (clipPixels.IsEmpty())
|
||||
return;
|
||||
|
||||
gfxRect nativeClipRect(clipPixels.x, clipPixels.y,
|
||||
clipPixels.width, clipPixels.height);
|
||||
gfxContext* ctx = aRenderingContext.ThebesContext();
|
||||
|
||||
gfxContextAutoSaveRestore save(ctx);
|
||||
ctx->NewPath();
|
||||
ctx->Rectangle(nativeClipRect);
|
||||
ctx->Clip();
|
||||
gfxPoint offset(contentPixels.x, contentPixels.y);
|
||||
ctx->SetMatrix(
|
||||
ctx->CurrentMatrix().Translate(offset));
|
||||
|
||||
gfxQuartzNativeDrawing nativeDrawing(aDrawTarget,
|
||||
ToRect(nativeClipRect - offset));
|
||||
|
||||
CGContextRef cgContext = nativeDrawing.BeginNativeDrawing();
|
||||
if (!cgContext) {
|
||||
NS_WARNING("null CGContextRef during PaintPlugin");
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<nsNPAPIPluginInstance> inst;
|
||||
GetPluginInstance(getter_AddRefs(inst));
|
||||
if (!inst) {
|
||||
NS_WARNING("null plugin instance during PaintPlugin");
|
||||
nativeDrawing.EndNativeDrawing();
|
||||
return;
|
||||
}
|
||||
NPWindow* window;
|
||||
mInstanceOwner->GetWindow(window);
|
||||
if (!window) {
|
||||
NS_WARNING("null plugin window during PaintPlugin");
|
||||
nativeDrawing.EndNativeDrawing();
|
||||
return;
|
||||
}
|
||||
NP_CGContext* cgPluginPortCopy =
|
||||
static_cast<NP_CGContext*>(mInstanceOwner->GetPluginPortCopy());
|
||||
if (!cgPluginPortCopy) {
|
||||
NS_WARNING("null plugin port copy during PaintPlugin");
|
||||
nativeDrawing.EndNativeDrawing();
|
||||
return;
|
||||
}
|
||||
|
||||
mInstanceOwner->BeginCGPaint();
|
||||
if (mInstanceOwner->GetDrawingModel() == NPDrawingModelCoreAnimation ||
|
||||
mInstanceOwner->GetDrawingModel() ==
|
||||
NPDrawingModelInvalidatingCoreAnimation) {
|
||||
// CoreAnimation is updated, render the layer and perform a readback.
|
||||
mInstanceOwner->RenderCoreAnimation(cgContext, window->width, window->height);
|
||||
} else {
|
||||
mInstanceOwner->Paint(nativeClipRect - offset, cgContext);
|
||||
}
|
||||
mInstanceOwner->EndCGPaint();
|
||||
|
||||
nativeDrawing.EndNativeDrawing();
|
||||
} else {
|
||||
gfxContext* ctx = aRenderingContext.ThebesContext();
|
||||
|
||||
// Translate the context:
|
||||
gfxPoint devPixelPt =
|
||||
nsLayoutUtils::PointToGfxPoint(aPluginRect.TopLeft(),
|
||||
PresContext()->AppUnitsPerDevPixel());
|
||||
|
||||
gfxContextMatrixAutoSaveRestore autoSR(ctx);
|
||||
ctx->SetMatrix(ctx->CurrentMatrix().Translate(devPixelPt));
|
||||
|
||||
// FIXME - Bug 385435: Doesn't aDirtyRect need translating too?
|
||||
|
||||
// this rect is used only in the CoreGraphics drawing model
|
||||
gfxRect tmpRect(0, 0, 0, 0);
|
||||
mInstanceOwner->Paint(tmpRect, nullptr);
|
||||
}
|
||||
}
|
||||
#elif defined(MOZ_X11)
|
||||
if (mInstanceOwner) {
|
||||
NPWindow *window;
|
||||
NPWindow *window = nullptr;
|
||||
mInstanceOwner->GetWindow(window);
|
||||
if (window->type == NPWindowTypeDrawable) {
|
||||
gfxRect frameGfxRect =
|
||||
PresContext()->AppUnitsToGfxUnits(aPluginRect);
|
||||
gfxRect dirtyGfxRect =
|
||||
PresContext()->AppUnitsToGfxUnits(aDirtyRect);
|
||||
gfxContext* ctx = aRenderingContext.ThebesContext();
|
||||
|
||||
mInstanceOwner->Paint(ctx, frameGfxRect, dirtyGfxRect);
|
||||
}
|
||||
}
|
||||
#elif defined(XP_WIN)
|
||||
RefPtr<nsNPAPIPluginInstance> inst;
|
||||
GetPluginInstance(getter_AddRefs(inst));
|
||||
if (inst) {
|
||||
gfxRect frameGfxRect =
|
||||
PresContext()->AppUnitsToGfxUnits(aPluginRect);
|
||||
gfxRect dirtyGfxRect =
|
||||
PresContext()->AppUnitsToGfxUnits(aDirtyRect);
|
||||
gfxContext *ctx = aRenderingContext.ThebesContext();
|
||||
gfxMatrix currentMatrix = ctx->CurrentMatrix();
|
||||
|
||||
if (ctx->UserToDevicePixelSnapped(frameGfxRect, false)) {
|
||||
dirtyGfxRect = ctx->UserToDevice(dirtyGfxRect);
|
||||
ctx->SetMatrix(gfxMatrix());
|
||||
}
|
||||
dirtyGfxRect.RoundOut();
|
||||
|
||||
// Look if it's windowless
|
||||
NPWindow *window;
|
||||
mInstanceOwner->GetWindow(window);
|
||||
|
||||
if (window->type == NPWindowTypeDrawable) {
|
||||
// the offset of the DC
|
||||
nsPoint origin;
|
||||
|
||||
gfxWindowsNativeDrawing nativeDraw(ctx, frameGfxRect);
|
||||
if (nativeDraw.IsDoublePass()) {
|
||||
// OOP plugin specific: let the shim know before we paint if we are doing a
|
||||
// double pass render. If this plugin isn't oop, the register window message
|
||||
// will be ignored.
|
||||
NPEvent pluginEvent;
|
||||
pluginEvent.event = plugins::DoublePassRenderingEvent();
|
||||
pluginEvent.wParam = 0;
|
||||
pluginEvent.lParam = 0;
|
||||
if (pluginEvent.event)
|
||||
inst->HandleEvent(&pluginEvent, nullptr);
|
||||
}
|
||||
do {
|
||||
HDC hdc = nativeDraw.BeginNativeDrawing();
|
||||
if (!hdc)
|
||||
return;
|
||||
|
||||
RECT dest;
|
||||
nativeDraw.TransformToNativeRect(frameGfxRect, dest);
|
||||
RECT dirty;
|
||||
nativeDraw.TransformToNativeRect(dirtyGfxRect, dirty);
|
||||
|
||||
window->window = hdc;
|
||||
window->x = dest.left;
|
||||
window->y = dest.top;
|
||||
window->clipRect.left = 0;
|
||||
window->clipRect.top = 0;
|
||||
// if we're painting, we're visible.
|
||||
window->clipRect.right = window->width;
|
||||
window->clipRect.bottom = window->height;
|
||||
|
||||
// Windowless plugins on windows need a special event to update their location,
|
||||
// see bug 135737.
|
||||
//
|
||||
// bug 271442: note, the rectangle we send is now purely the bounds of the plugin
|
||||
// relative to the window it is contained in, which is useful for the plugin to
|
||||
// correctly translate mouse coordinates.
|
||||
//
|
||||
// this does not mesh with the comments for bug 135737 which imply that the rectangle
|
||||
// must be clipped in some way to prevent the plugin attempting to paint over areas
|
||||
// it shouldn't.
|
||||
//
|
||||
// since the two uses of the rectangle are mutually exclusive in some cases, and
|
||||
// since I don't see any incorrect painting (at least with Flash and ViewPoint -
|
||||
// the originator of bug 135737), it seems that windowless plugins are not relying
|
||||
// on information here for clipping their drawing, and we can safely use this message
|
||||
// to tell the plugin exactly where it is in all cases.
|
||||
|
||||
nsIntPoint origin = GetWindowOriginInPixels(true);
|
||||
nsIntRect winlessRect = nsIntRect(origin, nsIntSize(window->width, window->height));
|
||||
|
||||
if (!mWindowlessRect.IsEqualEdges(winlessRect)) {
|
||||
mWindowlessRect = winlessRect;
|
||||
|
||||
WINDOWPOS winpos;
|
||||
memset(&winpos, 0, sizeof(winpos));
|
||||
winpos.x = mWindowlessRect.x;
|
||||
winpos.y = mWindowlessRect.y;
|
||||
winpos.cx = mWindowlessRect.width;
|
||||
winpos.cy = mWindowlessRect.height;
|
||||
|
||||
// finally, update the plugin by sending it a WM_WINDOWPOSCHANGED event
|
||||
NPEvent pluginEvent;
|
||||
pluginEvent.event = WM_WINDOWPOSCHANGED;
|
||||
pluginEvent.wParam = 0;
|
||||
pluginEvent.lParam = (LPARAM)&winpos;
|
||||
inst->HandleEvent(&pluginEvent, nullptr);
|
||||
}
|
||||
|
||||
inst->SetWindow(window);
|
||||
|
||||
mInstanceOwner->Paint(dirty, hdc);
|
||||
nativeDraw.EndNativeDrawing();
|
||||
} while (nativeDraw.ShouldRenderAgain());
|
||||
nativeDraw.PaintToContext();
|
||||
}
|
||||
|
||||
ctx->SetMatrix(currentMatrix);
|
||||
MOZ_ASSERT(!window || window->type == NPWindowTypeWindow);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsCORSListenerProxy.h"
|
||||
#include "nsCSSParser.h"
|
||||
#include "nsDeviceContext.h"
|
||||
@@ -39,6 +40,7 @@
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsStyleSet.h"
|
||||
#include "nsUTF8Utils.h"
|
||||
#include "nsDOMNavigationTiming.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::css;
|
||||
@@ -305,6 +307,17 @@ FontFaceSet::FindMatchingFontFaces(const nsAString& aFont,
|
||||
}
|
||||
}
|
||||
|
||||
TimeStamp
|
||||
FontFaceSet::GetNavigationStartTimeStamp()
|
||||
{
|
||||
TimeStamp navStart;
|
||||
RefPtr<nsDOMNavigationTiming> timing(mDocument->GetNavigationTiming());
|
||||
if (timing) {
|
||||
navStart = timing->GetNavigationStartTimeStamp();
|
||||
}
|
||||
return navStart;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
FontFaceSet::Load(JSContext* aCx,
|
||||
const nsAString& aFont,
|
||||
@@ -1720,6 +1733,26 @@ FontFaceSet::UserFontSet::StartLoad(gfxUserFontEntry* aUserFontEntry,
|
||||
return mFontFaceSet->StartLoad(aUserFontEntry, aFontFaceSrc);
|
||||
}
|
||||
|
||||
void
|
||||
FontFaceSet::UserFontSet::RecordFontLoadDone(uint32_t aFontSize,
|
||||
TimeStamp aDoneTime)
|
||||
{
|
||||
mDownloadCount++;
|
||||
mDownloadSize += aFontSize;
|
||||
Telemetry::Accumulate(Telemetry::WEBFONT_SIZE, aFontSize / 1024);
|
||||
|
||||
if (!mFontFaceSet) {
|
||||
return;
|
||||
}
|
||||
|
||||
TimeStamp navStart = mFontFaceSet->GetNavigationStartTimeStamp();
|
||||
TimeStamp zero;
|
||||
if (navStart != zero) {
|
||||
Telemetry::AccumulateTimeDelta(Telemetry::WEBFONT_DOWNLOAD_TIME_AFTER_START,
|
||||
navStart, aDoneTime);
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ nsresult
|
||||
FontFaceSet::UserFontSet::LogMessage(gfxUserFontEntry* aUserFontEntry,
|
||||
const char* aMessage,
|
||||
|
||||
@@ -68,6 +68,9 @@ public:
|
||||
virtual nsresult StartLoad(gfxUserFontEntry* aUserFontEntry,
|
||||
const gfxFontFaceSrc* aFontFaceSrc) override;
|
||||
|
||||
void RecordFontLoadDone(uint32_t aFontSize,
|
||||
mozilla::TimeStamp aDoneTime) override;
|
||||
|
||||
protected:
|
||||
virtual bool GetPrivateBrowsing() override;
|
||||
virtual nsresult SyncLoadFontData(gfxUserFontEntry* aFontToLoad,
|
||||
@@ -293,6 +296,8 @@ private:
|
||||
nsTArray<FontFace*>& aFontFaces,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
TimeStamp GetNavigationStartTimeStamp();
|
||||
|
||||
RefPtr<UserFontSet> mUserFontSet;
|
||||
|
||||
// The document this is a FontFaceSet for.
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "nsError.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "FontFaceSet.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIPrincipal.h"
|
||||
@@ -39,6 +40,7 @@ nsFontFaceLoader::nsFontFaceLoader(gfxUserFontEntry* aUserFontEntry,
|
||||
mFontFaceSet(aFontFaceSet),
|
||||
mChannel(aChannel)
|
||||
{
|
||||
mStartTime = TimeStamp::Now();
|
||||
}
|
||||
|
||||
nsFontFaceLoader::~nsFontFaceLoader()
|
||||
@@ -148,12 +150,17 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader,
|
||||
|
||||
mFontFaceSet->RemoveLoader(this);
|
||||
|
||||
TimeStamp doneTime = TimeStamp::Now();
|
||||
TimeDuration downloadTime = doneTime - mStartTime;
|
||||
uint32_t downloadTimeMS = uint32_t(downloadTime.ToMilliseconds());
|
||||
Telemetry::Accumulate(Telemetry::WEBFONT_DOWNLOAD_TIME, downloadTimeMS);
|
||||
|
||||
if (LOG_ENABLED()) {
|
||||
nsAutoCString fontURI;
|
||||
mFontURI->GetSpec(fontURI);
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
LOG(("userfonts (%p) download completed - font uri: (%s)\n",
|
||||
this, fontURI.get()));
|
||||
LOG(("userfonts (%p) download completed - font uri: (%s) time: %d ms\n",
|
||||
this, fontURI.get(), downloadTimeMS));
|
||||
} else {
|
||||
LOG(("userfonts (%p) download failed - font uri: (%s) error: %8.8x\n",
|
||||
this, fontURI.get(), aStatus));
|
||||
@@ -188,6 +195,8 @@ nsFontFaceLoader::OnStreamComplete(nsIStreamLoader* aLoader,
|
||||
bool fontUpdate =
|
||||
mUserFontEntry->FontDataDownloadComplete(aString, aStringLen, aStatus);
|
||||
|
||||
mFontFaceSet->GetUserFontSet()->RecordFontLoadDone(aStringLen, doneTime);
|
||||
|
||||
// when new font loaded, need to reflow
|
||||
if (fontUpdate) {
|
||||
nsTArray<gfxUserFontSet*> fontSets;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#define nsFontFaceLoader_h_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIStreamLoader.h"
|
||||
#include "nsIChannel.h"
|
||||
@@ -55,7 +56,7 @@ private:
|
||||
RefPtr<mozilla::dom::FontFaceSet> mFontFaceSet;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
nsCOMPtr<nsITimer> mLoadTimer;
|
||||
|
||||
TimeStamp mStartTime;
|
||||
nsIStreamLoader* mStreamLoader;
|
||||
};
|
||||
|
||||
|
||||
@@ -205,6 +205,7 @@ EverySecondTelemetryCallback_s(nsAutoPtr<RTCStatsQueries> aQueryList) {
|
||||
for (auto q = aQueryList->begin(); q != aQueryList->end(); ++q) {
|
||||
PeerConnectionImpl::ExecuteStatsQuery_s(*q);
|
||||
auto& r = *(*q)->report;
|
||||
bool isHello = (*q)->isHello;
|
||||
if (r.mInboundRTPStreamStats.WasPassed()) {
|
||||
// First, get reports from a second ago, if any, for calculations below
|
||||
const Sequence<RTCInboundRTPStreamStats> *lastInboundStats = nullptr;
|
||||
@@ -237,9 +238,15 @@ EverySecondTelemetryCallback_s(nsAutoPtr<RTCStatsQueries> aQueryList) {
|
||||
}
|
||||
if (s.mMozRtt.WasPassed()) {
|
||||
MOZ_ASSERT(s.mIsRemote);
|
||||
Accumulate(isAudio? WEBRTC_AUDIO_QUALITY_OUTBOUND_RTT :
|
||||
WEBRTC_VIDEO_QUALITY_OUTBOUND_RTT,
|
||||
s.mMozRtt.Value());
|
||||
ID id;
|
||||
if (isAudio) {
|
||||
id = isHello ? LOOP_AUDIO_QUALITY_OUTBOUND_RTT :
|
||||
WEBRTC_AUDIO_QUALITY_OUTBOUND_RTT;
|
||||
} else {
|
||||
id = isHello ? LOOP_VIDEO_QUALITY_OUTBOUND_RTT :
|
||||
WEBRTC_VIDEO_QUALITY_OUTBOUND_RTT;
|
||||
}
|
||||
Accumulate(id, s.mMozRtt.Value());
|
||||
}
|
||||
if (lastInboundStats && s.mBytesReceived.WasPassed()) {
|
||||
auto& laststats = *lastInboundStats;
|
||||
@@ -249,15 +256,32 @@ EverySecondTelemetryCallback_s(nsAutoPtr<RTCStatsQueries> aQueryList) {
|
||||
if (lasts.mBytesReceived.WasPassed()) {
|
||||
auto delta_ms = int32_t(s.mTimestamp.Value() -
|
||||
lasts.mTimestamp.Value());
|
||||
if (delta_ms > 0 && delta_ms < 60000) {
|
||||
Accumulate(s.mIsRemote?
|
||||
(isAudio? WEBRTC_AUDIO_QUALITY_OUTBOUND_BANDWIDTH_KBITS :
|
||||
WEBRTC_VIDEO_QUALITY_OUTBOUND_BANDWIDTH_KBITS) :
|
||||
(isAudio? WEBRTC_AUDIO_QUALITY_INBOUND_BANDWIDTH_KBITS :
|
||||
WEBRTC_VIDEO_QUALITY_INBOUND_BANDWIDTH_KBITS),
|
||||
((s.mBytesReceived.Value() -
|
||||
lasts.mBytesReceived.Value()) * 8) / delta_ms);
|
||||
// In theory we're called every second, so delta *should* be in that range.
|
||||
// Small deltas could cause errors due to division
|
||||
if (delta_ms > 500 && delta_ms < 60000) {
|
||||
ID id;
|
||||
if (s.mIsRemote) {
|
||||
if (isAudio) {
|
||||
id = isHello ? LOOP_AUDIO_QUALITY_OUTBOUND_BANDWIDTH_KBITS :
|
||||
WEBRTC_AUDIO_QUALITY_OUTBOUND_BANDWIDTH_KBITS;
|
||||
} else {
|
||||
id = isHello ? LOOP_VIDEO_QUALITY_OUTBOUND_BANDWIDTH_KBITS :
|
||||
WEBRTC_VIDEO_QUALITY_OUTBOUND_BANDWIDTH_KBITS;
|
||||
}
|
||||
} else {
|
||||
if (isAudio) {
|
||||
id = isHello ? LOOP_AUDIO_QUALITY_INBOUND_BANDWIDTH_KBITS :
|
||||
WEBRTC_AUDIO_QUALITY_INBOUND_BANDWIDTH_KBITS;
|
||||
} else {
|
||||
id = isHello ? LOOP_VIDEO_QUALITY_INBOUND_BANDWIDTH_KBITS :
|
||||
WEBRTC_VIDEO_QUALITY_INBOUND_BANDWIDTH_KBITS;
|
||||
}
|
||||
}
|
||||
Accumulate(id, ((s.mBytesReceived.Value() -
|
||||
lasts.mBytesReceived.Value()) * 8) / delta_ms);
|
||||
}
|
||||
// We could accumulate values until enough time has passed
|
||||
// and then Accumulate() but this isn't that important.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,6 +381,7 @@ PeerConnectionImpl::PeerConnectionImpl(const GlobalObject* aGlobal)
|
||||
, mIdentity(nullptr)
|
||||
#endif
|
||||
, mPrivacyRequested(false)
|
||||
, mIsLoop(false)
|
||||
, mSTSThread(nullptr)
|
||||
, mAllowIceLoopback(false)
|
||||
, mAllowIceLinkLocal(false)
|
||||
@@ -698,6 +699,12 @@ PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver,
|
||||
location->Release();
|
||||
|
||||
CopyUTF16toUTF8(locationAStr, locationCStr);
|
||||
#define HELLO_CLICKER_URL_START "https://hello.firefox.com/"
|
||||
#define HELLO_INITIATOR_URL_START "about:loop"
|
||||
mIsLoop = (strncmp(HELLO_CLICKER_URL_START, locationCStr.get(),
|
||||
strlen(HELLO_CLICKER_URL_START)) == 0) ||
|
||||
(strncmp(HELLO_INITIATOR_URL_START, locationCStr.get(),
|
||||
strlen(HELLO_INITIATOR_URL_START)) == 0);
|
||||
}
|
||||
|
||||
PR_snprintf(
|
||||
@@ -2480,7 +2487,9 @@ PeerConnectionImpl::ShutdownMedia()
|
||||
// End of call to be recorded in Telemetry
|
||||
if (!mStartTime.IsNull()){
|
||||
TimeDuration timeDelta = TimeStamp::Now() - mStartTime;
|
||||
Telemetry::Accumulate(Telemetry::WEBRTC_CALL_DURATION, timeDelta.ToSeconds());
|
||||
Telemetry::Accumulate(mIsLoop ? Telemetry::LOOP_CALL_DURATION :
|
||||
Telemetry::WEBRTC_CALL_DURATION,
|
||||
timeDelta.ToSeconds());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2759,10 +2768,12 @@ void PeerConnectionImpl::IceConnectionStateChange(
|
||||
if (!mIceStartTime.IsNull()){
|
||||
TimeDuration timeDelta = TimeStamp::Now() - mIceStartTime;
|
||||
if (isSucceeded(domState)) {
|
||||
Telemetry::Accumulate(Telemetry::WEBRTC_ICE_SUCCESS_TIME,
|
||||
Telemetry::Accumulate(mIsLoop ? Telemetry::LOOP_ICE_SUCCESS_TIME :
|
||||
Telemetry::WEBRTC_ICE_SUCCESS_TIME,
|
||||
timeDelta.ToMilliseconds());
|
||||
} else if (isFailed(domState)) {
|
||||
Telemetry::Accumulate(Telemetry::WEBRTC_ICE_FAILURE_TIME,
|
||||
Telemetry::Accumulate(mIsLoop ? Telemetry::LOOP_ICE_FAILURE_TIME :
|
||||
Telemetry::WEBRTC_ICE_FAILURE_TIME,
|
||||
timeDelta.ToMilliseconds());
|
||||
}
|
||||
}
|
||||
@@ -2921,6 +2932,7 @@ PeerConnectionImpl::BuildStatsQuery_m(
|
||||
|
||||
query->iceStartTime = mIceStartTime;
|
||||
query->failed = isFailed(mIceConnectionState);
|
||||
query->isHello = mIsLoop;
|
||||
|
||||
// Populate SDP on main
|
||||
if (query->internalStats) {
|
||||
@@ -3379,8 +3391,11 @@ PeerConnectionImpl::startCallTelem() {
|
||||
mStartTime = TimeStamp::Now();
|
||||
|
||||
// Increment session call counter
|
||||
// If we want to track Loop calls independently here, we need two mConnectionCounters
|
||||
int &cnt = PeerConnectionCtx::GetInstance()->mConnectionCounter;
|
||||
Telemetry::GetHistogramById(Telemetry::WEBRTC_CALL_COUNT)->Subtract(cnt);
|
||||
if (cnt > 0) {
|
||||
Telemetry::GetHistogramById(Telemetry::WEBRTC_CALL_COUNT)->Subtract(cnt);
|
||||
}
|
||||
cnt++;
|
||||
Telemetry::GetHistogramById(Telemetry::WEBRTC_CALL_COUNT)->Add(cnt);
|
||||
}
|
||||
|
||||
@@ -214,6 +214,7 @@ class RTCStatsQuery {
|
||||
std::string error;
|
||||
// A timestamp to help with telemetry.
|
||||
mozilla::TimeStamp iceStartTime;
|
||||
bool isHello;
|
||||
// Just for convenience, maybe integrate into the report later
|
||||
bool failed;
|
||||
|
||||
@@ -476,6 +477,8 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
bool IsLoop() const { return mIsLoop; }
|
||||
|
||||
// this method checks to see if we've made a promise to protect media.
|
||||
bool PrivacyRequested() const { return mPrivacyRequested; }
|
||||
|
||||
@@ -741,6 +744,7 @@ private:
|
||||
|
||||
// A name for this PC that we are willing to expose to content.
|
||||
std::string mName;
|
||||
bool mIsLoop; // For telemetry; doesn't have to be 100% right
|
||||
|
||||
// The target to run stuff on
|
||||
nsCOMPtr<nsIEventTarget> mSTSThread;
|
||||
|
||||
@@ -819,13 +819,44 @@ MOZ_IMPLICIT WebrtcGlobalChild::~WebrtcGlobalChild()
|
||||
|
||||
struct StreamResult {
|
||||
StreamResult() : candidateTypeBitpattern(0), streamSucceeded(false) {}
|
||||
uint8_t candidateTypeBitpattern;
|
||||
uint32_t candidateTypeBitpattern;
|
||||
bool streamSucceeded;
|
||||
};
|
||||
|
||||
static uint32_t GetCandidateIpAndTransportMask(const RTCIceCandidateStats *cand) {
|
||||
|
||||
enum {
|
||||
CANDIDATE_BITMASK_UDP = 1,
|
||||
CANDIDATE_BITMASK_TCP = 1 << 1,
|
||||
CANDIDATE_BITMASK_IPV6 = 1 << 2,
|
||||
};
|
||||
|
||||
uint32_t res = 0;
|
||||
|
||||
nsAutoCString transport;
|
||||
// prefer local transport for local relay candidates
|
||||
if (cand->mMozLocalTransport.WasPassed()) {
|
||||
transport.Assign(NS_ConvertUTF16toUTF8(cand->mMozLocalTransport.Value()));
|
||||
} else {
|
||||
transport.Assign(NS_ConvertUTF16toUTF8(cand->mTransport.Value()));
|
||||
}
|
||||
if (transport == kNrIceTransportUdp) {
|
||||
res |= CANDIDATE_BITMASK_UDP;
|
||||
} else if (transport == kNrIceTransportTcp) {
|
||||
res |= CANDIDATE_BITMASK_TCP;
|
||||
}
|
||||
|
||||
if (cand->mIpAddress.Value().FindChar(':') != -1) {
|
||||
res |= CANDIDATE_BITMASK_IPV6;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
static void StoreLongTermICEStatisticsImpl_m(
|
||||
nsresult result,
|
||||
nsAutoPtr<RTCStatsQuery> query) {
|
||||
nsAutoPtr<RTCStatsQuery> query,
|
||||
bool aIsLoop) {
|
||||
|
||||
using namespace Telemetry;
|
||||
|
||||
@@ -837,17 +868,6 @@ static void StoreLongTermICEStatisticsImpl_m(
|
||||
|
||||
query->report->mClosed.Construct(true);
|
||||
|
||||
// First, store stuff in telemetry
|
||||
enum {
|
||||
REMOTE_GATHERED_SERVER_REFLEXIVE = 1,
|
||||
REMOTE_GATHERED_TURN = 1 << 1,
|
||||
LOCAL_GATHERED_SERVER_REFLEXIVE = 1 << 2,
|
||||
LOCAL_GATHERED_TURN_UDP = 1 << 3,
|
||||
LOCAL_GATHERED_TURN_TCP = 1 << 4,
|
||||
LOCAL_GATHERED_TURN_TLS = 1 << 5,
|
||||
LOCAL_GATHERED_TURN_HTTPS = 1 << 6,
|
||||
};
|
||||
|
||||
// TODO(bcampen@mozilla.com): Do we need to watch out for cases where the
|
||||
// components within a stream didn't have the same types of relayed
|
||||
// candidates? I have a feeling that late trickle could cause this, but right
|
||||
@@ -886,51 +906,74 @@ static void StoreLongTermICEStatisticsImpl_m(
|
||||
|
||||
if (!cand.mType.WasPassed() ||
|
||||
!cand.mCandidateType.WasPassed() ||
|
||||
!cand.mTransport.WasPassed() ||
|
||||
!cand.mIpAddress.WasPassed() ||
|
||||
!cand.mComponentId.WasPassed()) {
|
||||
// Crash on debug, ignore this candidate otherwise.
|
||||
MOZ_CRASH();
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The bitmask after examaning a candidate should look like this:
|
||||
* REMOTE_GATHERED_HOST_UDP = 1,
|
||||
* REMOTE_GATHERED_HOST_TCP = 1 << 1,
|
||||
* REMOTE_GATHERED_HOST_IPV6 = 1 << 2,
|
||||
* REMOTE_GATHERED_SERVER_REFLEXIVE_UDP = 1 << 3,
|
||||
* REMOTE_GATHERED_SERVER_REFLEXIVE_TCP = 1 << 4,
|
||||
* REMOTE_GATHERED_SERVER_REFLEXIVE_IPV6 = 1 << 5,
|
||||
* REMOTE_GATHERED_TURN_UDP = 1 << 6,
|
||||
* REMOTE_GATHERED_TURN_TCP = 1 << 7, // dummy place holder
|
||||
* REMOTE_GATHERED_TURN_IPV6 = 1 << 8,
|
||||
* REMOTE_GATHERED_PEER_REFLEXIVE_UDP = 1 << 9,
|
||||
* REMOTE_GATHERED_PEER_REFLEXIVE_TCP = 1 << 10,
|
||||
* REMOTE_GATHERED_PEER_REFLEXIVE_IPV6 = 1 << 11,
|
||||
* LOCAL_GATHERED_HOST_UDP = 1 << 16,
|
||||
* LOCAL_GATHERED_HOST_TCP = 1 << 17,
|
||||
* LOCAL_GATHERED_HOST_IPV6 = 1 << 18,
|
||||
* LOCAL_GATHERED_SERVER_REFLEXIVE_UDP = 1 << 19,
|
||||
* LOCAL_GATHERED_SERVER_REFLEXIVE_TCP = 1 << 20,
|
||||
* LOCAL_GATHERED_SERVER_REFLEXIVE_IPV6 = 1 << 21,
|
||||
* LOCAL_GATHERED_TURN_UDP = 1 << 22,
|
||||
* LOCAL_GATHERED_TURN_TCP = 1 << 23,
|
||||
* LOCAL_GATHERED_TURN_IPV6 = 1 << 24,
|
||||
* LOCAL_GATHERED_PEERREFLEXIVE_UDP = 1 << 25,
|
||||
* LOCAL_GATHERED_PEERREFLEXIVE_TCP = 1 << 26,
|
||||
* LOCAL_GATHERED_PEERREFLEXIVE_IPV6 = 1 << 27,
|
||||
*
|
||||
* This results in following shift values
|
||||
*/
|
||||
static const uint32_t kLocalShift = 16;
|
||||
static const uint32_t kSrflxShift = 3;
|
||||
static const uint32_t kRelayShift = 6;
|
||||
static const uint32_t kPrflxShift = 9;
|
||||
|
||||
uint32_t candBitmask = GetCandidateIpAndTransportMask(&cand);
|
||||
|
||||
// Note: shift values need to result in the above enum table
|
||||
if (cand.mType.Value() == RTCStatsType::Localcandidate) {
|
||||
candBitmask <<= kLocalShift;
|
||||
}
|
||||
|
||||
if (cand.mCandidateType.Value() == RTCStatsIceCandidateType::Serverreflexive) {
|
||||
candBitmask <<= kSrflxShift;
|
||||
} else if (cand.mCandidateType.Value() == RTCStatsIceCandidateType::Relayed) {
|
||||
candBitmask <<= kRelayShift;
|
||||
} else if (cand.mCandidateType.Value() == RTCStatsIceCandidateType::Peerreflexive) {
|
||||
candBitmask <<= kPrflxShift;
|
||||
}
|
||||
|
||||
// Note: this is not a "component" in the ICE definition, this is really a
|
||||
// stream ID. This is just the way the stats API is standardized right now
|
||||
// stream ID. This is just the way the stats API is standardized right now.
|
||||
// Very confusing.
|
||||
std::string streamId(
|
||||
NS_ConvertUTF16toUTF8(cand.mComponentId.Value()).get());
|
||||
|
||||
if (cand.mCandidateType.Value() == RTCStatsIceCandidateType::Relayed) {
|
||||
if (cand.mType.Value() == RTCStatsType::Localcandidate) {
|
||||
NS_ConvertUTF16toUTF8 transport(cand.mMozLocalTransport.Value());
|
||||
if (transport == kNrIceTransportUdp) {
|
||||
streamResults[streamId].candidateTypeBitpattern |=
|
||||
LOCAL_GATHERED_TURN_UDP;
|
||||
} else if (transport == kNrIceTransportTcp) {
|
||||
streamResults[streamId].candidateTypeBitpattern |=
|
||||
LOCAL_GATHERED_TURN_TCP;
|
||||
}
|
||||
} else {
|
||||
streamResults[streamId].candidateTypeBitpattern |= REMOTE_GATHERED_TURN;
|
||||
}
|
||||
} else if (cand.mCandidateType.Value() ==
|
||||
RTCStatsIceCandidateType::Serverreflexive) {
|
||||
if (cand.mType.Value() == RTCStatsType::Localcandidate) {
|
||||
streamResults[streamId].candidateTypeBitpattern |=
|
||||
LOCAL_GATHERED_SERVER_REFLEXIVE;
|
||||
} else {
|
||||
streamResults[streamId].candidateTypeBitpattern |=
|
||||
REMOTE_GATHERED_SERVER_REFLEXIVE;
|
||||
}
|
||||
}
|
||||
streamResults[streamId].candidateTypeBitpattern |= candBitmask;
|
||||
}
|
||||
|
||||
for (auto i = streamResults.begin(); i != streamResults.end(); ++i) {
|
||||
if (i->second.streamSucceeded) {
|
||||
Telemetry::Accumulate(Telemetry::WEBRTC_CANDIDATE_TYPES_GIVEN_SUCCESS,
|
||||
i->second.candidateTypeBitpattern);
|
||||
} else {
|
||||
Telemetry::Accumulate(Telemetry::WEBRTC_CANDIDATE_TYPES_GIVEN_FAILURE,
|
||||
i->second.candidateTypeBitpattern);
|
||||
}
|
||||
Telemetry::RecordWebrtcIceCandidates(i->second.candidateTypeBitpattern,
|
||||
i->second.streamSucceeded, aIsLoop);
|
||||
}
|
||||
|
||||
// Beyond ICE, accumulate telemetry for various PER_CALL settings here.
|
||||
@@ -944,25 +987,30 @@ static void StoreLongTermICEStatisticsImpl_m(
|
||||
continue;
|
||||
}
|
||||
if (s.mBitrateMean.WasPassed()) {
|
||||
Accumulate(WEBRTC_VIDEO_ENCODER_BITRATE_AVG_PER_CALL_KBPS,
|
||||
Accumulate(aIsLoop ? LOOP_VIDEO_ENCODER_BITRATE_AVG_PER_CALL_KBPS :
|
||||
WEBRTC_VIDEO_ENCODER_BITRATE_AVG_PER_CALL_KBPS,
|
||||
uint32_t(s.mBitrateMean.Value() / 1000));
|
||||
}
|
||||
if (s.mBitrateStdDev.WasPassed()) {
|
||||
Accumulate(WEBRTC_VIDEO_ENCODER_BITRATE_STD_DEV_PER_CALL_KBPS,
|
||||
Accumulate(aIsLoop? LOOP_VIDEO_ENCODER_BITRATE_STD_DEV_PER_CALL_KBPS :
|
||||
WEBRTC_VIDEO_ENCODER_BITRATE_STD_DEV_PER_CALL_KBPS,
|
||||
uint32_t(s.mBitrateStdDev.Value() / 1000));
|
||||
}
|
||||
if (s.mFramerateMean.WasPassed()) {
|
||||
Accumulate(WEBRTC_VIDEO_ENCODER_FRAMERATE_AVG_PER_CALL,
|
||||
Accumulate(aIsLoop ? LOOP_VIDEO_ENCODER_FRAMERATE_AVG_PER_CALL :
|
||||
WEBRTC_VIDEO_ENCODER_FRAMERATE_AVG_PER_CALL,
|
||||
uint32_t(s.mFramerateMean.Value()));
|
||||
}
|
||||
if (s.mFramerateStdDev.WasPassed()) {
|
||||
Accumulate(WEBRTC_VIDEO_ENCODER_FRAMERATE_10X_STD_DEV_PER_CALL,
|
||||
Accumulate(aIsLoop ? LOOP_VIDEO_ENCODER_FRAMERATE_10X_STD_DEV_PER_CALL :
|
||||
WEBRTC_VIDEO_ENCODER_FRAMERATE_10X_STD_DEV_PER_CALL,
|
||||
uint32_t(s.mFramerateStdDev.Value() * 10));
|
||||
}
|
||||
if (s.mDroppedFrames.WasPassed() && !query->iceStartTime.IsNull()) {
|
||||
double mins = (TimeStamp::Now() - query->iceStartTime).ToSeconds() / 60;
|
||||
if (mins > 0) {
|
||||
Accumulate(WEBRTC_VIDEO_ENCODER_DROPPED_FRAMES_PER_CALL_FPM,
|
||||
Accumulate(aIsLoop ? LOOP_VIDEO_ENCODER_DROPPED_FRAMES_PER_CALL_FPM :
|
||||
WEBRTC_VIDEO_ENCODER_DROPPED_FRAMES_PER_CALL_FPM,
|
||||
uint32_t(double(s.mDroppedFrames.Value()) / mins));
|
||||
}
|
||||
}
|
||||
@@ -978,25 +1026,30 @@ static void StoreLongTermICEStatisticsImpl_m(
|
||||
continue;
|
||||
}
|
||||
if (s.mBitrateMean.WasPassed()) {
|
||||
Accumulate(WEBRTC_VIDEO_DECODER_BITRATE_AVG_PER_CALL_KBPS,
|
||||
Accumulate(aIsLoop ? LOOP_VIDEO_DECODER_BITRATE_AVG_PER_CALL_KBPS :
|
||||
WEBRTC_VIDEO_DECODER_BITRATE_AVG_PER_CALL_KBPS,
|
||||
uint32_t(s.mBitrateMean.Value() / 1000));
|
||||
}
|
||||
if (s.mBitrateStdDev.WasPassed()) {
|
||||
Accumulate(WEBRTC_VIDEO_DECODER_BITRATE_STD_DEV_PER_CALL_KBPS,
|
||||
Accumulate(aIsLoop ? LOOP_VIDEO_DECODER_BITRATE_STD_DEV_PER_CALL_KBPS :
|
||||
WEBRTC_VIDEO_DECODER_BITRATE_STD_DEV_PER_CALL_KBPS,
|
||||
uint32_t(s.mBitrateStdDev.Value() / 1000));
|
||||
}
|
||||
if (s.mFramerateMean.WasPassed()) {
|
||||
Accumulate(WEBRTC_VIDEO_DECODER_FRAMERATE_AVG_PER_CALL,
|
||||
Accumulate(aIsLoop ? LOOP_VIDEO_DECODER_FRAMERATE_AVG_PER_CALL :
|
||||
WEBRTC_VIDEO_DECODER_FRAMERATE_AVG_PER_CALL,
|
||||
uint32_t(s.mFramerateMean.Value()));
|
||||
}
|
||||
if (s.mFramerateStdDev.WasPassed()) {
|
||||
Accumulate(WEBRTC_VIDEO_DECODER_FRAMERATE_10X_STD_DEV_PER_CALL,
|
||||
Accumulate(aIsLoop ? LOOP_VIDEO_DECODER_FRAMERATE_10X_STD_DEV_PER_CALL :
|
||||
WEBRTC_VIDEO_DECODER_FRAMERATE_10X_STD_DEV_PER_CALL,
|
||||
uint32_t(s.mFramerateStdDev.Value() * 10));
|
||||
}
|
||||
if (s.mDiscardedPackets.WasPassed() && !query->iceStartTime.IsNull()) {
|
||||
double mins = (TimeStamp::Now() - query->iceStartTime).ToSeconds() / 60;
|
||||
if (mins > 0) {
|
||||
Accumulate(WEBRTC_VIDEO_DECODER_DISCARDED_PACKETS_PER_CALL_PPM,
|
||||
Accumulate(aIsLoop ? LOOP_VIDEO_DECODER_DISCARDED_PACKETS_PER_CALL_PPM :
|
||||
WEBRTC_VIDEO_DECODER_DISCARDED_PACKETS_PER_CALL_PPM,
|
||||
uint32_t(double(s.mDiscardedPackets.Value()) / mins));
|
||||
}
|
||||
}
|
||||
@@ -1012,7 +1065,8 @@ static void StoreLongTermICEStatisticsImpl_m(
|
||||
}
|
||||
|
||||
static void GetStatsForLongTermStorage_s(
|
||||
nsAutoPtr<RTCStatsQuery> query) {
|
||||
nsAutoPtr<RTCStatsQuery> query,
|
||||
bool aIsLoop) {
|
||||
|
||||
MOZ_ASSERT(query);
|
||||
|
||||
@@ -1048,13 +1102,15 @@ static void GetStatsForLongTermStorage_s(
|
||||
WrapRunnableNM(
|
||||
&StoreLongTermICEStatisticsImpl_m,
|
||||
rv,
|
||||
query),
|
||||
query,
|
||||
aIsLoop),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void WebrtcGlobalInformation::StoreLongTermICEStatistics(
|
||||
PeerConnectionImpl& aPc) {
|
||||
Telemetry::Accumulate(Telemetry::WEBRTC_ICE_FINAL_CONNECTION_STATE,
|
||||
Telemetry::Accumulate(aPc.IsLoop() ? Telemetry::LOOP_ICE_FINAL_CONNECTION_STATE :
|
||||
Telemetry::WEBRTC_ICE_FINAL_CONNECTION_STATE,
|
||||
static_cast<uint32_t>(aPc.IceConnectionState()));
|
||||
|
||||
if (aPc.IceConnectionState() == PCImplIceConnectionState::New) {
|
||||
@@ -1071,7 +1127,7 @@ void WebrtcGlobalInformation::StoreLongTermICEStatistics(
|
||||
|
||||
RUN_ON_THREAD(aPc.GetSTSThread(),
|
||||
WrapRunnableNM(&GetStatsForLongTermStorage_s,
|
||||
query),
|
||||
query, aPc.IsLoop()),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
@@ -562,6 +562,9 @@ pref("media.video_stats.enabled", true);
|
||||
// Whether to enable the audio writing APIs on the audio element
|
||||
pref("media.audio_data.enabled", false);
|
||||
|
||||
// Weather we allow AMD switchable graphics
|
||||
pref("layers.amd-switchable-gfx.enabled", true);
|
||||
|
||||
// Whether to use async panning and zooming
|
||||
pref("layers.async-pan-zoom.enabled", false);
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "prnetdb.h"
|
||||
|
||||
#include "AndroidBridge.h"
|
||||
#include "mozilla/jni/Utils.h"
|
||||
#include "GeneratedJNIWrappers.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
@@ -80,7 +81,7 @@ Tickler::Init()
|
||||
MOZ_ASSERT(!mThread);
|
||||
MOZ_ASSERT(!mFD);
|
||||
|
||||
if (AndroidBridge::HasEnv()) {
|
||||
if (jni::IsAvailable()) {
|
||||
widget::GeckoAppShell::EnableNetworkNotifications();
|
||||
}
|
||||
|
||||
|
||||
@@ -223,6 +223,12 @@ SandboxBroker::SetSecurityLevelForPluginProcess(int32_t aSandboxLevel)
|
||||
L"\\??\\pipe\\chrome.*");
|
||||
ret = ret && (sandbox::SBOX_ALL_OK == result);
|
||||
|
||||
// Add the policy for the client side of the crash server pipe.
|
||||
result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
|
||||
sandbox::TargetPolicy::FILES_ALLOW_ANY,
|
||||
L"\\??\\pipe\\gecko-crash-server-pipe.*");
|
||||
ret = ret && (sandbox::SBOX_ALL_OK == result);
|
||||
|
||||
// The NPAPI process needs to be able to duplicate shared memory to the
|
||||
// content process and broker process, which are Section type handles.
|
||||
// Content and broker are for e10s and non-e10s cases.
|
||||
@@ -410,6 +416,13 @@ SandboxBroker::AllowDirectory(wchar_t const *dir)
|
||||
return (sandbox::SBOX_ALL_OK == result);
|
||||
}
|
||||
|
||||
bool
|
||||
SandboxBroker::AddTargetPeer(HANDLE aPeerProcess)
|
||||
{
|
||||
sandbox::ResultCode result = sBrokerService->AddTargetPeer(aPeerProcess);
|
||||
return (sandbox::SBOX_ALL_OK == result);
|
||||
}
|
||||
|
||||
SandboxBroker::~SandboxBroker()
|
||||
{
|
||||
if (mPolicy) {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <windows.h>
|
||||
|
||||
namespace sandbox {
|
||||
class BrokerServices;
|
||||
@@ -45,6 +46,9 @@ public:
|
||||
bool AllowReadWriteFile(wchar_t const *file);
|
||||
bool AllowDirectory(wchar_t const *dir);
|
||||
|
||||
// Exposes AddTargetPeer from broker services, so that none sandboxed
|
||||
// processes can be added as handle duplication targets.
|
||||
bool AddTargetPeer(HANDLE aPeerProcess);
|
||||
private:
|
||||
static sandbox::BrokerServices *sBrokerService;
|
||||
sandbox::TargetPolicy *mPolicy;
|
||||
|
||||
@@ -30,3 +30,6 @@ JAR_MANIFESTS += ['jar.mn']
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Toolkit', 'Notifications and Alerts')
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wshadow']
|
||||
|
||||
@@ -25,7 +25,7 @@ using namespace mozilla;
|
||||
|
||||
using mozilla::dom::ContentChild;
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAlertsService, nsIAlertsService, nsIAlertsProgressListener)
|
||||
NS_IMPL_ISUPPORTS(nsAlertsService, nsIAlertsService, nsIAlertsDoNotDisturb, nsIAlertsProgressListener)
|
||||
|
||||
nsAlertsService::nsAlertsService()
|
||||
{
|
||||
@@ -150,6 +150,45 @@ NS_IMETHODIMP nsAlertsService::CloseAlert(const nsAString& aAlertName,
|
||||
}
|
||||
|
||||
|
||||
// nsIAlertsDoNotDisturb
|
||||
NS_IMETHODIMP nsAlertsService::GetManualDoNotDisturb(bool* aRetVal)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#else
|
||||
// Try the system notification service.
|
||||
nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_SYSTEMALERTSERVICE_CONTRACTID));
|
||||
if (sysAlerts) {
|
||||
nsCOMPtr<nsIAlertsDoNotDisturb> alertsDND(do_GetService(NS_SYSTEMALERTSERVICE_CONTRACTID));
|
||||
if (!alertsDND) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
return alertsDND->GetManualDoNotDisturb(aRetVal);
|
||||
}
|
||||
|
||||
return mXULAlerts.GetManualDoNotDisturb(aRetVal);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAlertsService::SetManualDoNotDisturb(bool aDoNotDisturb)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#else
|
||||
// Try the system notification service.
|
||||
nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_SYSTEMALERTSERVICE_CONTRACTID));
|
||||
if (sysAlerts) {
|
||||
nsCOMPtr<nsIAlertsDoNotDisturb> alertsDND(do_GetService(NS_SYSTEMALERTSERVICE_CONTRACTID));
|
||||
if (!alertsDND) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
return alertsDND->SetManualDoNotDisturb(aDoNotDisturb);
|
||||
}
|
||||
|
||||
return mXULAlerts.SetManualDoNotDisturb(aDoNotDisturb);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAlertsService::OnProgress(const nsAString & aAlertName,
|
||||
int64_t aProgress,
|
||||
int64_t aProgressMax,
|
||||
|
||||
@@ -28,10 +28,12 @@ typedef HRESULT (__stdcall *SHQueryUserNotificationStatePtr)(MOZ_QUERY_USER_NOTI
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
class nsAlertsService : public nsIAlertsService,
|
||||
public nsIAlertsDoNotDisturb,
|
||||
public nsIAlertsProgressListener
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIALERTSPROGRESSLISTENER
|
||||
NS_DECL_NSIALERTSDONOTDISTURB
|
||||
NS_DECL_NSIALERTSSERVICE
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
* 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 "nsISupports.idl"
|
||||
#include "nsIObserver.idl"
|
||||
|
||||
@@ -12,99 +11,117 @@ interface nsIPrincipal;
|
||||
[scriptable, uuid(9d0284bf-db40-42da-8f0d-c2769dbde7aa)]
|
||||
interface nsIAlertsService : nsISupports
|
||||
{
|
||||
/**
|
||||
* Displays a sliding notification window.
|
||||
*
|
||||
* @param imageUrl A URL identifying the image to put in the alert.
|
||||
* The OS X implemenation limits the amount of time it
|
||||
* will wait for an icon to load to six seconds. After
|
||||
* that time the alert will show with no icon.
|
||||
* @param title The title for the alert.
|
||||
* @param text The contents of the alert.
|
||||
* @param textClickable If true, causes the alert text to look like a link
|
||||
* and notifies the listener when user attempts to
|
||||
* click the alert text.
|
||||
* @param cookie A blind cookie the alert will pass back to the
|
||||
* consumer during the alert listener callbacks.
|
||||
* @param alertListener Used for callbacks. May be null if the caller
|
||||
* doesn't care about callbacks.
|
||||
* @param name The name of the notification. This is currently only
|
||||
* used on Android and OS X. On Android the name is
|
||||
* hashed and used as a notification ID. Notifications
|
||||
* will replace previous notifications with the same name.
|
||||
* @param dir Bidi override for the title. Valid values are
|
||||
* "auto", "ltr" or "rtl". Only available on supported
|
||||
* platforms.
|
||||
* @param lang Language of title and text of the alert. Only available
|
||||
* on supported platforms.
|
||||
* @param inPrivateBrowsing If set to true, imageUrl will be loaded in private
|
||||
* browsing mode.
|
||||
* @throws NS_ERROR_NOT_AVAILABLE If the notification cannot be displayed.
|
||||
*
|
||||
* The following arguments will be passed to the alertListener's observe()
|
||||
* method:
|
||||
* subject - null
|
||||
* topic - "alertfinished" when the alert goes away
|
||||
* "alertclickcallback" when the text is clicked
|
||||
* "alertshow" when the alert is shown
|
||||
* data - the value of the cookie parameter passed to showAlertNotification.
|
||||
*
|
||||
* @note Depending on current circumstances (if the user's in a fullscreen
|
||||
* application, for instance), the alert might not be displayed at all.
|
||||
* In that case, if an alert listener is passed in it will receive the
|
||||
* "alertfinished" notification immediately.
|
||||
*/
|
||||
void showAlertNotification(in AString imageUrl,
|
||||
in AString title,
|
||||
in AString text,
|
||||
[optional] in boolean textClickable,
|
||||
[optional] in AString cookie,
|
||||
[optional] in nsIObserver alertListener,
|
||||
[optional] in AString name,
|
||||
[optional] in AString dir,
|
||||
[optional] in AString lang,
|
||||
[optional] in AString data,
|
||||
[optional] in nsIPrincipal principal,
|
||||
[optional] in boolean inPrivateBrowsing);
|
||||
/**
|
||||
* Displays a sliding notification window.
|
||||
*
|
||||
* @param imageUrl A URL identifying the image to put in the alert.
|
||||
* The OS X implemenation limits the amount of time it
|
||||
* will wait for an icon to load to six seconds. After
|
||||
* that time the alert will show with no icon.
|
||||
* @param title The title for the alert.
|
||||
* @param text The contents of the alert.
|
||||
* @param textClickable If true, causes the alert text to look like a link
|
||||
* and notifies the listener when user attempts to
|
||||
* click the alert text.
|
||||
* @param cookie A blind cookie the alert will pass back to the
|
||||
* consumer during the alert listener callbacks.
|
||||
* @param alertListener Used for callbacks. May be null if the caller
|
||||
* doesn't care about callbacks.
|
||||
* @param name The name of the notification. This is currently only
|
||||
* used on Android and OS X. On Android the name is
|
||||
* hashed and used as a notification ID. Notifications
|
||||
* will replace previous notifications with the same name.
|
||||
* @param dir Bidi override for the title. Valid values are
|
||||
* "auto", "ltr" or "rtl". Only available on supported
|
||||
* platforms.
|
||||
* @param lang Language of title and text of the alert. Only available
|
||||
* on supported platforms.
|
||||
* @param inPrivateBrowsing If set to true, imageUrl will be loaded in private
|
||||
* browsing mode.
|
||||
* @throws NS_ERROR_NOT_AVAILABLE If the notification cannot be displayed.
|
||||
*
|
||||
* The following arguments will be passed to the alertListener's observe()
|
||||
* method:
|
||||
* subject - null
|
||||
* topic - "alertfinished" when the alert goes away
|
||||
* "alertdisablecallback" when alerts should be disabled for the principal
|
||||
* "alertsettingscallback" when alert settings should be opened
|
||||
* "alertclickcallback" when the text is clicked
|
||||
* "alertshow" when the alert is shown
|
||||
* data - the value of the cookie parameter passed to showAlertNotification.
|
||||
*
|
||||
* @note Depending on current circumstances (if the user's in a fullscreen
|
||||
* application, for instance), the alert might not be displayed at all.
|
||||
* In that case, if an alert listener is passed in it will receive the
|
||||
* "alertfinished" notification immediately.
|
||||
*/
|
||||
void showAlertNotification(in AString imageUrl,
|
||||
in AString title,
|
||||
in AString text,
|
||||
[optional] in boolean textClickable,
|
||||
[optional] in AString cookie,
|
||||
[optional] in nsIObserver alertListener,
|
||||
[optional] in AString name,
|
||||
[optional] in AString dir,
|
||||
[optional] in AString lang,
|
||||
[optional] in AString data,
|
||||
[optional] in nsIPrincipal principal,
|
||||
[optional] in boolean inPrivateBrowsing);
|
||||
|
||||
/**
|
||||
* Close alerts created by the service.
|
||||
*
|
||||
* @param name The name of the notification to close. If no name
|
||||
* is provided then only a notification created with
|
||||
* no name (if any) will be closed.
|
||||
*/
|
||||
void closeAlert([optional] in AString name,
|
||||
[optional] in nsIPrincipal principal);
|
||||
/**
|
||||
* Close alerts created by the service.
|
||||
*
|
||||
* @param name The name of the notification to close. If no name
|
||||
* is provided then only a notification created with
|
||||
* no name (if any) will be closed.
|
||||
*/
|
||||
void closeAlert([optional] in AString name,
|
||||
[optional] in nsIPrincipal principal);
|
||||
|
||||
};
|
||||
|
||||
[scriptable, uuid(c5d63e3a-259d-45a8-b964-8377967cb4d2)]
|
||||
interface nsIAlertsDoNotDisturb : nsISupports
|
||||
{
|
||||
/**
|
||||
* Toggles a manual Do Not Disturb mode for the service to reduce the amount
|
||||
* of disruption that alerts cause the user.
|
||||
* This may mean only displaying them in a notification tray/center or not
|
||||
* displaying them at all. If a system backend already supports a similar
|
||||
* feature controlled by the user, enabling this may not have any impact on
|
||||
* code to show an alert. e.g. on OS X, the system will take care not
|
||||
* disrupting a user if we simply create a notification like usual.
|
||||
*/
|
||||
attribute bool manualDoNotDisturb;
|
||||
};
|
||||
|
||||
[scriptable, uuid(df1bd4b0-3a8c-40e6-806a-203f38b0bd9f)]
|
||||
interface nsIAlertsProgressListener : nsISupports
|
||||
{
|
||||
/**
|
||||
* Called to notify the alert service that progress has occurred for the
|
||||
* given notification previously displayed with showAlertNotification().
|
||||
*
|
||||
* @param name The name of the notification displaying the
|
||||
* progress. On Android the name is hashed and used
|
||||
* as a notification ID.
|
||||
* @param progress Numeric value in the range 0 to progressMax
|
||||
* indicating the current progress.
|
||||
* @param progressMax Numeric value indicating the maximum progress.
|
||||
* @param text The contents of the alert. If not provided,
|
||||
* the percentage will be displayed.
|
||||
*/
|
||||
void onProgress(in AString name,
|
||||
in long long progress,
|
||||
in long long progressMax,
|
||||
[optional] in AString text);
|
||||
/**
|
||||
* Called to notify the alert service that progress has occurred for the
|
||||
* given notification previously displayed with showAlertNotification().
|
||||
*
|
||||
* @param name The name of the notification displaying the
|
||||
* progress. On Android the name is hashed and used
|
||||
* as a notification ID.
|
||||
* @param progress Numeric value in the range 0 to progressMax
|
||||
* indicating the current progress.
|
||||
* @param progressMax Numeric value indicating the maximum progress.
|
||||
* @param text The contents of the alert. If not provided,
|
||||
* the percentage will be displayed.
|
||||
*/
|
||||
void onProgress(in AString name,
|
||||
in long long progress,
|
||||
in long long progressMax,
|
||||
[optional] in AString text);
|
||||
|
||||
/**
|
||||
* Called to cancel and hide the given notification previously displayed
|
||||
* with showAlertNotification().
|
||||
*
|
||||
* @param name The name of the notification.
|
||||
*/
|
||||
void onCancel(in AString name);
|
||||
/**
|
||||
* Called to cancel and hide the given notification previously displayed
|
||||
* with showAlertNotification().
|
||||
*
|
||||
* @param name The name of the notification.
|
||||
*/
|
||||
void onCancel(in AString name);
|
||||
};
|
||||
|
||||
|
||||
@@ -48,6 +48,10 @@ nsXULAlerts::ShowAlertNotification(const nsAString& aImageUrl, const nsAString&
|
||||
const nsAString& aLang, nsIPrincipal* aPrincipal,
|
||||
bool aInPrivateBrowsing)
|
||||
{
|
||||
if (mDoNotDisturb) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
|
||||
|
||||
nsCOMPtr<nsISupportsArray> argsArray;
|
||||
@@ -161,6 +165,20 @@ nsXULAlerts::ShowAlertNotification(const nsAString& aImageUrl, const nsAString&
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULAlerts::SetManualDoNotDisturb(bool aDoNotDisturb)
|
||||
{
|
||||
mDoNotDisturb = aDoNotDisturb;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULAlerts::GetManualDoNotDisturb(bool* aRetVal)
|
||||
{
|
||||
*aRetVal = mDoNotDisturb;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULAlerts::CloseAlert(const nsAString& aAlertName)
|
||||
{
|
||||
|
||||
@@ -29,8 +29,13 @@ public:
|
||||
bool aInPrivateBrowsing);
|
||||
|
||||
nsresult CloseAlert(const nsAString& aAlertName);
|
||||
|
||||
nsresult GetManualDoNotDisturb(bool* aRetVal);
|
||||
nsresult SetManualDoNotDisturb(bool aDoNotDisturb);
|
||||
|
||||
protected:
|
||||
nsInterfaceHashtable<nsStringHashKey, nsIDOMWindow> mNamedWindows;
|
||||
bool mDoNotDisturb = false;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,21 +4,7 @@
|
||||
|
||||
var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
/*
|
||||
* This indicates from which corner of the screen alerts slide in,
|
||||
* and from which direction (horizontal/vertical).
|
||||
* 0, the default, represents bottom right, sliding vertically.
|
||||
* Use any bitwise combination of the following constants:
|
||||
* NS_ALERT_HORIZONTAL (1), NS_ALERT_LEFT (2), NS_ALERT_TOP (4).
|
||||
*
|
||||
* 6 4
|
||||
* +-----------+
|
||||
* 7| |5
|
||||
* | |
|
||||
* 3| |1
|
||||
* +-----------+
|
||||
* 2 0
|
||||
*/
|
||||
// Copied from nsILookAndFeel.h, see comments on eMetric_AlertNotificationOrigin
|
||||
const NS_ALERT_HORIZONTAL = 1;
|
||||
const NS_ALERT_LEFT = 2;
|
||||
const NS_ALERT_TOP = 4;
|
||||
@@ -229,15 +215,7 @@ function moveWindowToEnd() {
|
||||
let windows = Services.wm.getEnumerator("alert:alert");
|
||||
while (windows.hasMoreElements()) {
|
||||
let alertWindow = windows.getNext();
|
||||
let alertWindowTime = Number(
|
||||
alertWindow.document.getElementById('alertTime').getAttribute('value'));
|
||||
let windowTime = Number(
|
||||
window.document.getElementById('alertTime').getAttribute('value'));
|
||||
// The time of window creation.
|
||||
// Otherwise calling the notification twice (and more) in a row
|
||||
// does not work.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1263155
|
||||
if ((alertWindow != window) && (alertWindowTime <= windowTime)) {
|
||||
if (alertWindow != window) {
|
||||
if (gOrigin & NS_ALERT_TOP) {
|
||||
y = Math.max(y, alertWindow.screenY + alertWindow.outerHeight);
|
||||
} else {
|
||||
|
||||
@@ -26,3 +26,6 @@ FINAL_LIBRARY = 'xul'
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Toolkit', 'Autocomplete')
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wshadow']
|
||||
|
||||
@@ -44,8 +44,10 @@ NS_INTERFACE_MAP_END
|
||||
|
||||
nsAutoCompleteController::nsAutoCompleteController() :
|
||||
mDefaultIndexCompleted(false),
|
||||
mBackspaced(false),
|
||||
mPopupClosedByCompositionStart(false),
|
||||
mProhibitAutoFill(false),
|
||||
mUserClearedAutoFill(false),
|
||||
mClearingAutoFillSearchesAgain(false),
|
||||
mCompositionState(eCompositionState_None),
|
||||
mSearchStatus(nsAutoCompleteController::STATUS_NONE),
|
||||
mRowCount(0),
|
||||
@@ -119,7 +121,7 @@ nsAutoCompleteController::SetInput(nsIAutoCompleteInput *aInput)
|
||||
mSearchString = newValue;
|
||||
mPlaceholderCompletionString.Truncate();
|
||||
mDefaultIndexCompleted = false;
|
||||
mBackspaced = false;
|
||||
mProhibitAutoFill = false;
|
||||
mSearchStatus = nsIAutoCompleteController::STATUS_NONE;
|
||||
mRowCount = 0;
|
||||
mSearchesOngoing = 0;
|
||||
@@ -130,11 +132,13 @@ nsAutoCompleteController::SetInput(nsIAutoCompleteInput *aInput)
|
||||
aInput->GetSearchCount(&searchCount);
|
||||
mResults.SetCapacity(searchCount);
|
||||
mSearches.SetCapacity(searchCount);
|
||||
mMatchCounts.SetLength(searchCount);
|
||||
mImmediateSearchesCount = 0;
|
||||
|
||||
const char *searchCID = kAutoCompleteSearchCID;
|
||||
|
||||
// Since the controller can be used as a service it's important to reset this.
|
||||
mClearingAutoFillSearchesAgain = false;
|
||||
|
||||
for (uint32_t i = 0; i < searchCount; ++i) {
|
||||
// Use the search name to create the contract id string for the search service
|
||||
nsAutoCString searchName;
|
||||
@@ -148,12 +152,19 @@ nsAutoCompleteController::SetInput(nsIAutoCompleteInput *aInput)
|
||||
mSearches.AppendObject(search);
|
||||
|
||||
// Count immediate searches.
|
||||
uint16_t searchType = nsIAutoCompleteSearchDescriptor::SEARCH_TYPE_DELAYED;
|
||||
nsCOMPtr<nsIAutoCompleteSearchDescriptor> searchDesc =
|
||||
do_QueryInterface(search);
|
||||
if (searchDesc && NS_SUCCEEDED(searchDesc->GetSearchType(&searchType)) &&
|
||||
searchType == nsIAutoCompleteSearchDescriptor::SEARCH_TYPE_IMMEDIATE)
|
||||
mImmediateSearchesCount++;
|
||||
if (searchDesc) {
|
||||
uint16_t searchType = nsIAutoCompleteSearchDescriptor::SEARCH_TYPE_DELAYED;
|
||||
if (NS_SUCCEEDED(searchDesc->GetSearchType(&searchType)) &&
|
||||
searchType == nsIAutoCompleteSearchDescriptor::SEARCH_TYPE_IMMEDIATE) {
|
||||
mImmediateSearchesCount++;
|
||||
}
|
||||
|
||||
if (!mClearingAutoFillSearchesAgain) {
|
||||
searchDesc->GetClearingAutoFillSearchesAgain(&mClearingAutoFillSearchesAgain);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,8 +210,8 @@ nsAutoCompleteController::HandleText()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString newValue;
|
||||
nsCOMPtr<nsIAutoCompleteInput> input(mInput);
|
||||
nsAutoString newValue;
|
||||
input->GetTextValue(newValue);
|
||||
|
||||
// Stop all searches in case they are async.
|
||||
@@ -217,25 +228,45 @@ nsAutoCompleteController::HandleText()
|
||||
input->GetDisableAutoComplete(&disabled);
|
||||
NS_ENSURE_TRUE(!disabled, NS_OK);
|
||||
|
||||
// Don't search again if the new string is the same as the last search
|
||||
// Usually we don't search again if the new string is the same as the last one.
|
||||
// However, if this is called immediately after compositionend event,
|
||||
// we need to search the same value again since the search was canceled
|
||||
// at compositionstart event handler.
|
||||
if (!handlingCompositionCommit && newValue.Length() > 0 &&
|
||||
newValue.Equals(mSearchString)) {
|
||||
// The new string might also be the same as the last search if the autofilled
|
||||
// portion was cleared. In this case, we may want to search again.
|
||||
|
||||
// Whether the user removed some text at the end.
|
||||
bool userRemovedText =
|
||||
newValue.Length() < mSearchString.Length() &&
|
||||
Substring(mSearchString, 0, newValue.Length()).Equals(newValue);
|
||||
|
||||
// Whether the user is repeating the previous search.
|
||||
bool repeatingPreviousSearch = !userRemovedText &&
|
||||
newValue.Equals(mSearchString);
|
||||
|
||||
mUserClearedAutoFill =
|
||||
repeatingPreviousSearch &&
|
||||
newValue.Length() < mPlaceholderCompletionString.Length() &&
|
||||
Substring(mPlaceholderCompletionString, 0, newValue.Length()).Equals(newValue);
|
||||
bool searchAgainOnAutoFillClear = mUserClearedAutoFill && mClearingAutoFillSearchesAgain;
|
||||
|
||||
if (!handlingCompositionCommit &&
|
||||
!searchAgainOnAutoFillClear &&
|
||||
newValue.Length() > 0 &&
|
||||
repeatingPreviousSearch) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Determine if the user has removed text from the end (probably by backspacing)
|
||||
if (newValue.Length() < mSearchString.Length() &&
|
||||
Substring(mSearchString, 0, newValue.Length()).Equals(newValue))
|
||||
{
|
||||
// We need to throw away previous results so we don't try to search through them again
|
||||
ClearResults();
|
||||
mBackspaced = true;
|
||||
if (userRemovedText || searchAgainOnAutoFillClear) {
|
||||
if (userRemovedText) {
|
||||
// We need to throw away previous results so we don't try to search
|
||||
// through them again.
|
||||
ClearResults();
|
||||
}
|
||||
mProhibitAutoFill = true;
|
||||
mPlaceholderCompletionString.Truncate();
|
||||
} else {
|
||||
mBackspaced = false;
|
||||
mProhibitAutoFill = false;
|
||||
}
|
||||
|
||||
mSearchString = newValue;
|
||||
@@ -579,7 +610,7 @@ nsAutoCompleteController::HandleDelete(bool *_retval)
|
||||
RowIndexToSearch(index, &searchIndex, &rowIndex);
|
||||
NS_ENSURE_TRUE(searchIndex >= 0 && rowIndex >= 0, NS_ERROR_FAILURE);
|
||||
|
||||
nsIAutoCompleteResult *result = mResults[searchIndex];
|
||||
nsIAutoCompleteResult *result = mResults.SafeObjectAt(searchIndex);
|
||||
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoString search;
|
||||
@@ -641,7 +672,7 @@ nsAutoCompleteController::GetResultAt(int32_t aIndex, nsIAutoCompleteResult** aR
|
||||
RowIndexToSearch(aIndex, &searchIndex, aRowIndex);
|
||||
NS_ENSURE_TRUE(searchIndex >= 0 && *aRowIndex >= 0, NS_ERROR_FAILURE);
|
||||
|
||||
*aResult = mResults[searchIndex];
|
||||
*aResult = mResults.SafeObjectAt(searchIndex);
|
||||
NS_ENSURE_TRUE(*aResult, NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1133,6 +1164,13 @@ nsAutoCompleteController::StartSearch(uint16_t aSearchType)
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// FormFill expects the searchParam to only contain the input element id,
|
||||
// other consumers may have other expectations, so this modifies it only
|
||||
// for new consumers handling autoFill by themselves.
|
||||
if (mProhibitAutoFill && mClearingAutoFillSearchesAgain) {
|
||||
searchParam.AppendLiteral(" prohibit-autofill");
|
||||
}
|
||||
|
||||
rv = search->StartSearch(mSearchString, searchParam, result, static_cast<nsIAutoCompleteObserver *>(this));
|
||||
if (NS_FAILED(rv)) {
|
||||
++mSearchesFailed;
|
||||
@@ -1207,6 +1245,7 @@ nsAutoCompleteController::MaybeCompletePlaceholder()
|
||||
// In addition, the selection must be at the end of the current input to
|
||||
// trigger the placeholder completion.
|
||||
bool usePlaceholderCompletion =
|
||||
!mUserClearedAutoFill &&
|
||||
!mPlaceholderCompletionString.IsEmpty() &&
|
||||
mPlaceholderCompletionString.Length() > mSearchString.Length() &&
|
||||
selectionEnd == selectionStart &&
|
||||
@@ -1457,39 +1496,50 @@ nsresult
|
||||
nsAutoCompleteController::ProcessResult(int32_t aSearchIndex, nsIAutoCompleteResult *aResult)
|
||||
{
|
||||
NS_ENSURE_STATE(mInput);
|
||||
MOZ_ASSERT(aResult, "ProcessResult should always receive a result");
|
||||
NS_ENSURE_ARG(aResult);
|
||||
nsCOMPtr<nsIAutoCompleteInput> input(mInput);
|
||||
|
||||
uint16_t result = 0;
|
||||
if (aResult)
|
||||
aResult->GetSearchResult(&result);
|
||||
uint16_t searchResult = 0;
|
||||
aResult->GetSearchResult(&searchResult);
|
||||
|
||||
uint32_t oldMatchCount = 0;
|
||||
uint32_t matchCount = 0;
|
||||
if (aResult)
|
||||
aResult->GetMatchCount(&matchCount);
|
||||
|
||||
int32_t resultIndex = mResults.IndexOf(aResult);
|
||||
if (resultIndex == -1) {
|
||||
// cache the result
|
||||
mResults.AppendObject(aResult);
|
||||
mMatchCounts.AppendElement(matchCount);
|
||||
resultIndex = mResults.Count() - 1;
|
||||
}
|
||||
else {
|
||||
oldMatchCount = mMatchCounts[aSearchIndex];
|
||||
mMatchCounts[resultIndex] = matchCount;
|
||||
// The following code supports incremental updating results in 2 ways:
|
||||
// * The search may reuse the same result, just by adding entries to it.
|
||||
// * The search may send a new result every time. In this case we merge
|
||||
// the results and proceed on the same code path as before.
|
||||
// This way both mSearches and mResults can be indexed by the search index,
|
||||
// cause we'll always have only one result per search.
|
||||
if (mResults.IndexOf(aResult) == -1) {
|
||||
nsIAutoCompleteResult* oldResult = mResults.SafeObjectAt(aSearchIndex);
|
||||
if (oldResult) {
|
||||
MOZ_ASSERT(false, "Passing new matches to OnSearchResult with a new "
|
||||
"nsIAutoCompleteResult every time is deprecated, please "
|
||||
"update the same result until the search is done");
|
||||
// Build a new nsIAutocompleteSimpleResult and merge results into it.
|
||||
RefPtr<nsAutoCompleteSimpleResult> mergedResult =
|
||||
new nsAutoCompleteSimpleResult();
|
||||
mergedResult->AppendResult(oldResult);
|
||||
mergedResult->AppendResult(aResult);
|
||||
mResults.ReplaceObjectAt(mergedResult, aSearchIndex);
|
||||
} else {
|
||||
// This inserts and grows the array if needed.
|
||||
mResults.ReplaceObjectAt(aResult, aSearchIndex);
|
||||
}
|
||||
}
|
||||
// When found the result should have the same index as the search.
|
||||
MOZ_ASSERT_IF(mResults.IndexOf(aResult) != -1,
|
||||
mResults.IndexOf(aResult) == aSearchIndex);
|
||||
MOZ_ASSERT(mResults.Count() >= aSearchIndex + 1,
|
||||
"aSearchIndex should always be valid for mResults");
|
||||
|
||||
bool isTypeAheadResult = false;
|
||||
if (aResult) {
|
||||
aResult->GetTypeAheadResult(&isTypeAheadResult);
|
||||
}
|
||||
aResult->GetTypeAheadResult(&isTypeAheadResult);
|
||||
|
||||
if (!isTypeAheadResult) {
|
||||
uint32_t oldRowCount = mRowCount;
|
||||
// If the search failed, increase the match count to include the error
|
||||
// description.
|
||||
if (result == nsIAutoCompleteResult::RESULT_FAILURE) {
|
||||
if (searchResult == nsIAutoCompleteResult::RESULT_FAILURE) {
|
||||
nsAutoString error;
|
||||
aResult->GetErrorDescription(error);
|
||||
if (!error.IsEmpty()) {
|
||||
@@ -1498,13 +1548,28 @@ nsAutoCompleteController::ProcessResult(int32_t aSearchIndex, nsIAutoCompleteRes
|
||||
mTree->RowCountChanged(oldRowCount, 1);
|
||||
}
|
||||
}
|
||||
} else if (result == nsIAutoCompleteResult::RESULT_SUCCESS ||
|
||||
result == nsIAutoCompleteResult::RESULT_SUCCESS_ONGOING) {
|
||||
} else if (searchResult == nsIAutoCompleteResult::RESULT_SUCCESS ||
|
||||
searchResult == nsIAutoCompleteResult::RESULT_SUCCESS_ONGOING) {
|
||||
// Increase the match count for all matches in this result.
|
||||
mRowCount += matchCount - oldMatchCount;
|
||||
uint32_t totalMatchCount = 0;
|
||||
for (uint32_t i = 0; i < mResults.Length(); i++) {
|
||||
nsIAutoCompleteResult* result = mResults.SafeObjectAt(i);
|
||||
if (result) {
|
||||
// not all results implement this, so it can likely fail.
|
||||
bool typeAhead = false;
|
||||
result->GetTypeAheadResult(&typeAhead);
|
||||
if (!typeAhead) {
|
||||
uint32_t matchCount = 0;
|
||||
result->GetMatchCount(&matchCount);
|
||||
totalMatchCount += matchCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
uint32_t delta = totalMatchCount - oldRowCount;
|
||||
|
||||
mRowCount += delta;
|
||||
if (mTree) {
|
||||
mTree->RowCountChanged(oldRowCount, matchCount - oldMatchCount);
|
||||
mTree->RowCountChanged(oldRowCount, delta);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1527,10 +1592,10 @@ nsAutoCompleteController::ProcessResult(int32_t aSearchIndex, nsIAutoCompleteRes
|
||||
}
|
||||
}
|
||||
|
||||
if (result == nsIAutoCompleteResult::RESULT_SUCCESS ||
|
||||
result == nsIAutoCompleteResult::RESULT_SUCCESS_ONGOING) {
|
||||
if (searchResult == nsIAutoCompleteResult::RESULT_SUCCESS ||
|
||||
searchResult == nsIAutoCompleteResult::RESULT_SUCCESS_ONGOING) {
|
||||
// Try to autocomplete the default index for this search.
|
||||
CompleteDefaultIndex(resultIndex);
|
||||
CompleteDefaultIndex(aSearchIndex);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@@ -1568,7 +1633,6 @@ nsAutoCompleteController::ClearResults()
|
||||
int32_t oldRowCount = mRowCount;
|
||||
mRowCount = 0;
|
||||
mResults.Clear();
|
||||
mMatchCounts.Clear();
|
||||
if (oldRowCount != 0) {
|
||||
if (mTree)
|
||||
mTree->RowCountChanged(0, -oldRowCount);
|
||||
@@ -1588,7 +1652,7 @@ nsAutoCompleteController::ClearResults()
|
||||
nsresult
|
||||
nsAutoCompleteController::CompleteDefaultIndex(int32_t aResultIndex)
|
||||
{
|
||||
if (mDefaultIndexCompleted || mBackspaced || mSearchString.Length() == 0 || !mInput)
|
||||
if (mDefaultIndexCompleted || mProhibitAutoFill || mSearchString.Length() == 0 || !mInput)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIAutoCompleteInput> input(mInput);
|
||||
@@ -1636,14 +1700,16 @@ nsAutoCompleteController::GetDefaultCompleteResult(int32_t aResultIndex,
|
||||
|
||||
// If a result index was not provided, find the first defaultIndex result.
|
||||
for (int32_t i = 0; resultIndex < 0 && i < mResults.Count(); ++i) {
|
||||
nsIAutoCompleteResult *result = mResults[i];
|
||||
nsIAutoCompleteResult *result = mResults.SafeObjectAt(i);
|
||||
if (result &&
|
||||
NS_SUCCEEDED(result->GetDefaultIndex(_defaultIndex)) &&
|
||||
*_defaultIndex >= 0) {
|
||||
resultIndex = i;
|
||||
}
|
||||
}
|
||||
NS_ENSURE_TRUE(resultIndex >= 0, NS_ERROR_FAILURE);
|
||||
if (resultIndex < 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*_result = mResults.SafeObjectAt(resultIndex);
|
||||
NS_ENSURE_TRUE(*_result, NS_ERROR_FAILURE);
|
||||
|
||||
@@ -123,10 +123,8 @@ protected:
|
||||
nsCOMPtr<nsIAutoCompleteInput> mInput;
|
||||
|
||||
nsCOMArray<nsIAutoCompleteSearch> mSearches;
|
||||
// This is used as a sparse array, always use SafeObjectAt to access it.
|
||||
nsCOMArray<nsIAutoCompleteResult> mResults;
|
||||
// Caches the match counts for the current ongoing results to allow
|
||||
// incremental results to keep the rowcount up to date.
|
||||
nsTArray<uint32_t> mMatchCounts;
|
||||
// Temporarily keeps the results alive while invoking startSearch() for each
|
||||
// search. This is needed to allow the searches to reuse the previous result,
|
||||
// since otherwise the first search clears mResults.
|
||||
@@ -139,8 +137,19 @@ protected:
|
||||
nsString mSearchString;
|
||||
nsString mPlaceholderCompletionString;
|
||||
bool mDefaultIndexCompleted;
|
||||
bool mBackspaced;
|
||||
bool mPopupClosedByCompositionStart;
|
||||
|
||||
// Whether autofill is allowed for the next search. May be retrieved by the
|
||||
// search through the "prohibit-autofill" searchParam.
|
||||
bool mProhibitAutoFill;
|
||||
|
||||
// Indicates whether the user cleared the autofilled part, returning to the
|
||||
// originally entered search string.
|
||||
bool mUserClearedAutoFill;
|
||||
|
||||
// Indicates whether clearing the autofilled string should issue a new search.
|
||||
bool mClearingAutoFillSearchesAgain;
|
||||
|
||||
enum CompositionState {
|
||||
eCompositionState_None,
|
||||
eCompositionState_Composing,
|
||||
|
||||
@@ -4,10 +4,43 @@
|
||||
|
||||
#include "nsAutoCompleteSimpleResult.h"
|
||||
|
||||
#define CHECK_MATCH_INDEX(_index, _insert) \
|
||||
if (_index < 0 || \
|
||||
static_cast<MatchesArray::size_type>(_index) > mMatches.Length() || \
|
||||
(!_insert && static_cast<MatchesArray::size_type>(_index) == mMatches.Length())) { \
|
||||
MOZ_ASSERT(false, "Trying to use an invalid index on mMatches"); \
|
||||
return NS_ERROR_ILLEGAL_VALUE; \
|
||||
} \
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAutoCompleteSimpleResult,
|
||||
nsIAutoCompleteResult,
|
||||
nsIAutoCompleteSimpleResult)
|
||||
|
||||
struct AutoCompleteSimpleResultMatch
|
||||
{
|
||||
AutoCompleteSimpleResultMatch(const nsAString& aValue,
|
||||
const nsAString& aComment,
|
||||
const nsAString& aImage,
|
||||
const nsAString& aStyle,
|
||||
const nsAString& aFinalCompleteValue,
|
||||
const nsAString& aLabel)
|
||||
: mValue(aValue)
|
||||
, mComment(aComment)
|
||||
, mImage(aImage)
|
||||
, mStyle(aStyle)
|
||||
, mFinalCompleteValue(aFinalCompleteValue)
|
||||
, mLabel(aLabel)
|
||||
{
|
||||
}
|
||||
|
||||
nsString mValue;
|
||||
nsString mComment;
|
||||
nsString mImage;
|
||||
nsString mStyle;
|
||||
nsString mFinalCompleteValue;
|
||||
nsString mLabel;
|
||||
};
|
||||
|
||||
nsAutoCompleteSimpleResult::nsAutoCompleteSimpleResult() :
|
||||
mDefaultIndex(-1),
|
||||
mSearchResult(RESULT_NOMATCH),
|
||||
@@ -15,6 +48,74 @@ nsAutoCompleteSimpleResult::nsAutoCompleteSimpleResult() :
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAutoCompleteSimpleResult::AppendResult(nsIAutoCompleteResult* aResult)
|
||||
{
|
||||
nsAutoString searchString;
|
||||
nsresult rv = aResult->GetSearchString(searchString);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mSearchString = searchString;
|
||||
|
||||
uint16_t searchResult;
|
||||
rv = aResult->GetSearchResult(&searchResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mSearchResult = searchResult;
|
||||
|
||||
nsAutoString errorDescription;
|
||||
if (NS_SUCCEEDED(aResult->GetErrorDescription(errorDescription)) &&
|
||||
!errorDescription.IsEmpty()) {
|
||||
mErrorDescription = errorDescription;
|
||||
}
|
||||
|
||||
bool typeAheadResult = false;
|
||||
if (NS_SUCCEEDED(aResult->GetTypeAheadResult(&typeAheadResult)) &&
|
||||
typeAheadResult) {
|
||||
mTypeAheadResult = typeAheadResult;
|
||||
}
|
||||
|
||||
int32_t defaultIndex = -1;
|
||||
if (NS_SUCCEEDED(aResult->GetDefaultIndex(&defaultIndex)) &&
|
||||
defaultIndex >= 0) {
|
||||
mDefaultIndex = defaultIndex;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAutoCompleteSimpleResult> simpleResult =
|
||||
do_QueryInterface(aResult);
|
||||
if (simpleResult) {
|
||||
nsCOMPtr<nsIAutoCompleteSimpleResultListener> listener;
|
||||
if (NS_SUCCEEDED(simpleResult->GetListener(getter_AddRefs(listener))) &&
|
||||
listener) {
|
||||
listener.swap(mListener);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy matches.
|
||||
uint32_t matchCount = 0;
|
||||
rv = aResult->GetMatchCount(&matchCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
for (size_t i = 0; i < matchCount; ++i) {
|
||||
nsAutoString value, comment, image, style, finalCompleteValue, label;
|
||||
|
||||
rv = aResult->GetValueAt(i, value);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aResult->GetCommentAt(i, comment);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aResult->GetImageAt(i, image);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aResult->GetStyleAt(i, style);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aResult->GetFinalCompleteValueAt(i, finalCompleteValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aResult->GetLabelAt(i, label);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = AppendMatch(value, comment, image, style, finalCompleteValue, label);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// searchString
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::GetSearchString(nsAString &aSearchString)
|
||||
@@ -86,95 +187,85 @@ nsAutoCompleteSimpleResult::SetTypeAheadResult(bool aTypeAheadResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::InsertMatchAt(int32_t aIndex,
|
||||
const nsAString& aValue,
|
||||
const nsAString& aComment,
|
||||
const nsAString& aImage,
|
||||
const nsAString& aStyle,
|
||||
const nsAString& aFinalCompleteValue,
|
||||
const nsAString& aLabel)
|
||||
{
|
||||
CHECK_MATCH_INDEX(aIndex, true);
|
||||
|
||||
AutoCompleteSimpleResultMatch match(aValue, aComment, aImage, aStyle, aFinalCompleteValue, aLabel);
|
||||
|
||||
if (!mMatches.InsertElementAt(aIndex, match)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::AppendMatch(const nsAString& aValue,
|
||||
const nsAString& aComment,
|
||||
const nsAString& aImage,
|
||||
const nsAString& aStyle,
|
||||
const nsAString& aFinalCompleteValue)
|
||||
const nsAString& aFinalCompleteValue,
|
||||
const nsAString& aLabel)
|
||||
{
|
||||
CheckInvariants();
|
||||
|
||||
if (! mValues.AppendElement(aValue))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
if (! mComments.AppendElement(aComment)) {
|
||||
mValues.RemoveElementAt(mValues.Length() - 1);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (! mImages.AppendElement(aImage)) {
|
||||
mValues.RemoveElementAt(mValues.Length() - 1);
|
||||
mComments.RemoveElementAt(mComments.Length() - 1);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (! mStyles.AppendElement(aStyle)) {
|
||||
mValues.RemoveElementAt(mValues.Length() - 1);
|
||||
mComments.RemoveElementAt(mComments.Length() - 1);
|
||||
mImages.RemoveElementAt(mImages.Length() - 1);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (!mFinalCompleteValues.AppendElement(aFinalCompleteValue)) {
|
||||
mValues.RemoveElementAt(mValues.Length() - 1);
|
||||
mComments.RemoveElementAt(mComments.Length() - 1);
|
||||
mImages.RemoveElementAt(mImages.Length() - 1);
|
||||
mStyles.RemoveElementAt(mStyles.Length() - 1);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
return InsertMatchAt(mMatches.Length(), aValue, aComment, aImage, aStyle,
|
||||
aFinalCompleteValue, aLabel);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::GetMatchCount(uint32_t *aMatchCount)
|
||||
{
|
||||
CheckInvariants();
|
||||
|
||||
*aMatchCount = mValues.Length();
|
||||
*aMatchCount = mMatches.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::GetValueAt(int32_t aIndex, nsAString& _retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(aIndex >= 0 && aIndex < int32_t(mValues.Length()),
|
||||
NS_ERROR_ILLEGAL_VALUE);
|
||||
CheckInvariants();
|
||||
|
||||
_retval = mValues[aIndex];
|
||||
CHECK_MATCH_INDEX(aIndex, false);
|
||||
_retval = mMatches[aIndex].mValue;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::GetLabelAt(int32_t aIndex, nsAString& _retval)
|
||||
{
|
||||
return GetValueAt(aIndex, _retval);
|
||||
CHECK_MATCH_INDEX(aIndex, false);
|
||||
_retval = mMatches[aIndex].mLabel;
|
||||
if (_retval.IsEmpty()) {
|
||||
_retval = mMatches[aIndex].mValue;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::GetCommentAt(int32_t aIndex, nsAString& _retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(aIndex >= 0 && aIndex < int32_t(mComments.Length()),
|
||||
NS_ERROR_ILLEGAL_VALUE);
|
||||
CheckInvariants();
|
||||
_retval = mComments[aIndex];
|
||||
CHECK_MATCH_INDEX(aIndex, false);
|
||||
_retval = mMatches[aIndex].mComment;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::GetImageAt(int32_t aIndex, nsAString& _retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(aIndex >= 0 && aIndex < int32_t(mImages.Length()),
|
||||
NS_ERROR_ILLEGAL_VALUE);
|
||||
CheckInvariants();
|
||||
_retval = mImages[aIndex];
|
||||
CHECK_MATCH_INDEX(aIndex, false);
|
||||
_retval = mMatches[aIndex].mImage;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::GetStyleAt(int32_t aIndex, nsAString& _retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(aIndex >= 0 && aIndex < int32_t(mStyles.Length()),
|
||||
NS_ERROR_ILLEGAL_VALUE);
|
||||
CheckInvariants();
|
||||
_retval = mStyles[aIndex];
|
||||
CHECK_MATCH_INDEX(aIndex, false);
|
||||
_retval = mMatches[aIndex].mStyle;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -182,12 +273,11 @@ NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::GetFinalCompleteValueAt(int32_t aIndex,
|
||||
nsAString& _retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(aIndex >= 0 && aIndex < int32_t(mFinalCompleteValues.Length()),
|
||||
NS_ERROR_ILLEGAL_VALUE);
|
||||
CheckInvariants();
|
||||
_retval = mFinalCompleteValues[aIndex];
|
||||
if (_retval.Length() == 0)
|
||||
_retval = mValues[aIndex];
|
||||
CHECK_MATCH_INDEX(aIndex, false);
|
||||
_retval = mMatches[aIndex].mFinalCompleteValue;
|
||||
if (_retval.IsEmpty()) {
|
||||
_retval = mMatches[aIndex].mValue;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -198,22 +288,26 @@ nsAutoCompleteSimpleResult::SetListener(nsIAutoCompleteSimpleResultListener* aLi
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::GetListener(nsIAutoCompleteSimpleResultListener** aListener)
|
||||
{
|
||||
nsCOMPtr<nsIAutoCompleteSimpleResultListener> listener(mListener);
|
||||
listener.forget(aListener);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteSimpleResult::RemoveValueAt(int32_t aRowIndex,
|
||||
bool aRemoveFromDb)
|
||||
{
|
||||
NS_ENSURE_TRUE(aRowIndex >= 0 && aRowIndex < int32_t(mValues.Length()),
|
||||
NS_ERROR_ILLEGAL_VALUE);
|
||||
CHECK_MATCH_INDEX(aRowIndex, false);
|
||||
|
||||
nsAutoString removedValue(mValues[aRowIndex]);
|
||||
mValues.RemoveElementAt(aRowIndex);
|
||||
mComments.RemoveElementAt(aRowIndex);
|
||||
mImages.RemoveElementAt(aRowIndex);
|
||||
mStyles.RemoveElementAt(aRowIndex);
|
||||
mFinalCompleteValues.RemoveElementAt(aRowIndex);
|
||||
nsString value = mMatches[aRowIndex].mValue;
|
||||
mMatches.RemoveElementAt(aRowIndex);
|
||||
|
||||
if (mListener)
|
||||
mListener->OnValueRemoved(this, removedValue, aRemoveFromDb);
|
||||
if (mListener) {
|
||||
mListener->OnValueRemoved(this, value, aRemoveFromDb);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -13,34 +13,25 @@
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
struct AutoCompleteSimpleResultMatch;
|
||||
|
||||
class nsAutoCompleteSimpleResult final : public nsIAutoCompleteSimpleResult
|
||||
{
|
||||
public:
|
||||
nsAutoCompleteSimpleResult();
|
||||
inline void CheckInvariants() {
|
||||
NS_ASSERTION(mValues.Length() == mComments.Length(), "Arrays out of sync");
|
||||
NS_ASSERTION(mValues.Length() == mImages.Length(), "Arrays out of sync");
|
||||
NS_ASSERTION(mValues.Length() == mStyles.Length(), "Arrays out of sync");
|
||||
NS_ASSERTION(mValues.Length() == mFinalCompleteValues.Length(), "Arrays out of sync");
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIAUTOCOMPLETERESULT
|
||||
NS_DECL_NSIAUTOCOMPLETESIMPLERESULT
|
||||
|
||||
nsresult AppendResult(nsIAutoCompleteResult* aResult);
|
||||
|
||||
private:
|
||||
~nsAutoCompleteSimpleResult() {}
|
||||
|
||||
protected:
|
||||
|
||||
// What we really want is an array of structs with value/comment/image/style contents.
|
||||
// But then we'd either have to use COM or manage object lifetimes ourselves.
|
||||
// Having four arrays of string simplifies this, but is stupid.
|
||||
nsTArray<nsString> mValues;
|
||||
nsTArray<nsString> mComments;
|
||||
nsTArray<nsString> mImages;
|
||||
nsTArray<nsString> mStyles;
|
||||
nsTArray<nsString> mFinalCompleteValues;
|
||||
typedef nsTArray<AutoCompleteSimpleResultMatch> MatchesArray;
|
||||
MatchesArray mMatches;
|
||||
|
||||
nsString mSearchString;
|
||||
nsString mErrorDescription;
|
||||
|
||||
@@ -50,7 +50,7 @@ interface nsIAutoCompleteObserver : nsISupports
|
||||
void onUpdateSearchResult(in nsIAutoCompleteSearch search, in nsIAutoCompleteResult result);
|
||||
};
|
||||
|
||||
[scriptable, uuid(02314d6e-b730-40cc-a215-221554d77064)]
|
||||
[scriptable, uuid(4c3e7462-fbfb-4310-8f4b-239238392b75)]
|
||||
interface nsIAutoCompleteSearchDescriptor : nsISupports
|
||||
{
|
||||
// The search is started after the timeout specified by the corresponding
|
||||
@@ -65,4 +65,10 @@ interface nsIAutoCompleteSearchDescriptor : nsISupports
|
||||
* Defaults to SEARCH_TYPE_DELAYED.
|
||||
*/
|
||||
readonly attribute unsigned short searchType;
|
||||
|
||||
/*
|
||||
* Whether a new search should be triggered when the user deletes the
|
||||
* autofilled part.
|
||||
*/
|
||||
readonly attribute boolean clearingAutoFillSearchesAgain;
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ interface nsIAutoCompleteSimpleResultListener;
|
||||
* an array.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(fe8802f9-c2b7-4141-8e5b-280df3f62251)]
|
||||
[scriptable, uuid(23de9c96-becb-4d0d-a9bb-1d131ce361b5)]
|
||||
interface nsIAutoCompleteSimpleResult : nsIAutoCompleteResult
|
||||
{
|
||||
/**
|
||||
@@ -47,6 +47,31 @@ interface nsIAutoCompleteSimpleResult : nsIAutoCompleteResult
|
||||
*/
|
||||
void setTypeAheadResult(in boolean aHidden);
|
||||
|
||||
/**
|
||||
* Inserts a match consisting of the given value, comment, image, style and
|
||||
* the value to use for defaultIndex completion at a given position.
|
||||
* @param aIndex
|
||||
* The index to insert at
|
||||
* @param aValue
|
||||
* The value to autocomplete to
|
||||
* @param aComment
|
||||
* Comment shown in the autocomplete widget to describe this match
|
||||
* @param aImage
|
||||
* Image shown in the autocomplete widget for this match.
|
||||
* @param aStyle
|
||||
* Describes how to style the match in the autocomplete widget
|
||||
* @param aFinalCompleteValue
|
||||
* Value used when the user confirms selecting this match. If not
|
||||
* provided, aValue will be used.
|
||||
*/
|
||||
void insertMatchAt(in long aIndex,
|
||||
in AString aValue,
|
||||
in AString aComment,
|
||||
[optional] in AString aImage,
|
||||
[optional] in AString aStyle,
|
||||
[optional] in AString aFinalCompleteValue,
|
||||
[optional] in AString aLabel);
|
||||
|
||||
/**
|
||||
* Appends a match consisting of the given value, comment, image, style and
|
||||
* the value to use for defaultIndex completion.
|
||||
@@ -66,7 +91,13 @@ interface nsIAutoCompleteSimpleResult : nsIAutoCompleteResult
|
||||
in AString aComment,
|
||||
[optional] in AString aImage,
|
||||
[optional] in AString aStyle,
|
||||
[optional] in AString aFinalCompleteValue);
|
||||
[optional] in AString aFinalCompleteValue,
|
||||
[optional] in AString aLabel);
|
||||
|
||||
/**
|
||||
* Gets the listener for changes in the result.
|
||||
*/
|
||||
nsIAutoCompleteSimpleResultListener getListener();
|
||||
|
||||
/**
|
||||
* Sets a listener for changes in the result.
|
||||
|
||||
@@ -146,6 +146,7 @@ AutoCompleteResult.prototype = {
|
||||
*/
|
||||
function AutoCompleteSearch(aName, aResult) {
|
||||
this.name = aName;
|
||||
this._result = aResult;
|
||||
}
|
||||
AutoCompleteSearch.prototype = {
|
||||
constructor: AutoCompleteSearch,
|
||||
@@ -154,7 +155,7 @@ AutoCompleteSearch.prototype = {
|
||||
name: null,
|
||||
|
||||
// AutoCompleteResult
|
||||
_result:null,
|
||||
_result: null,
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Search object that returns results at different times.
|
||||
* First, the search that returns results asynchronously.
|
||||
@@ -10,11 +7,16 @@ function AutoCompleteAsyncSearch(aName, aResult) {
|
||||
this._result = aResult;
|
||||
}
|
||||
AutoCompleteAsyncSearch.prototype = Object.create(AutoCompleteSearchBase.prototype);
|
||||
AutoCompleteAsyncSearch.prototype.startSearch = function(aSearchString,
|
||||
aSearchParam,
|
||||
aPreviousResult,
|
||||
AutoCompleteAsyncSearch.prototype.startSearch = function(aSearchString,
|
||||
aSearchParam,
|
||||
aPreviousResult,
|
||||
aListener) {
|
||||
setTimeout(this._returnResults.bind(this), 500, aListener);
|
||||
this._result.searchResult = Ci.nsIAutoCompleteResult.RESULT_NOMATCH_ONGOING;
|
||||
aListener.onSearchResult(this, this._result);
|
||||
|
||||
do_timeout(500, () => {
|
||||
this._returnResults(aListener);
|
||||
});
|
||||
};
|
||||
|
||||
AutoCompleteAsyncSearch.prototype._returnResults = function(aListener) {
|
||||
@@ -32,9 +34,9 @@ function AutoCompleteSyncSearch(aName, aResult) {
|
||||
this._result = aResult;
|
||||
}
|
||||
AutoCompleteSyncSearch.prototype = Object.create(AutoCompleteAsyncSearch.prototype);
|
||||
AutoCompleteSyncSearch.prototype.startSearch = function(aSearchString,
|
||||
aSearchParam,
|
||||
aPreviousResult,
|
||||
AutoCompleteSyncSearch.prototype.startSearch = function(aSearchString,
|
||||
aSearchParam,
|
||||
aPreviousResult,
|
||||
aListener) {
|
||||
this._returnResults(aListener);
|
||||
};
|
||||
@@ -49,7 +51,7 @@ function AutoCompleteResult(aValues, aDefaultIndex) {
|
||||
AutoCompleteResult.prototype = Object.create(AutoCompleteResultBase.prototype);
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Test AutoComplete with multiple AutoCompleteSearch sources, with one of them
|
||||
* (index != 0) returning before the rest.
|
||||
*/
|
||||
@@ -60,19 +62,19 @@ function run_test() {
|
||||
var inputStr = "moz";
|
||||
|
||||
// Async search
|
||||
var asyncSearch = new AutoCompleteAsyncSearch("Async",
|
||||
var asyncSearch = new AutoCompleteAsyncSearch("Async",
|
||||
new AutoCompleteResult(results, -1));
|
||||
// Sync search
|
||||
var syncSearch = new AutoCompleteSyncSearch("Sync",
|
||||
new AutoCompleteResult(results, 0));
|
||||
|
||||
|
||||
// Register searches so AutoCompleteController can find them
|
||||
registerAutoCompleteSearch(asyncSearch);
|
||||
registerAutoCompleteSearch(syncSearch);
|
||||
|
||||
|
||||
var controller = Cc["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
getService(Ci.nsIAutoCompleteController);
|
||||
|
||||
// Make an AutoCompleteInput that uses our searches
|
||||
// and confirms results on search complete.
|
||||
// Async search MUST be FIRST to trigger the bug this tests.
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
function run_test() {
|
||||
let result = Cc["@mozilla.org/autocomplete/simple-result;1"]
|
||||
.createInstance(Ci.nsIAutoCompleteSimpleResult);
|
||||
result.appendMatch("a", "");
|
||||
result.appendMatch("c", "");
|
||||
result.insertMatchAt(1, "b", "");
|
||||
result.insertMatchAt(3, "d", "");
|
||||
|
||||
Assert.equal(result.matchCount, 4);
|
||||
Assert.equal(result.getValueAt(0), "a");
|
||||
Assert.equal(result.getValueAt(1), "b");
|
||||
Assert.equal(result.getValueAt(2), "c");
|
||||
Assert.equal(result.getValueAt(3), "d");
|
||||
}
|
||||
@@ -18,6 +18,7 @@ skip-if = toolkit == 'gonk'
|
||||
[test_finalDefaultCompleteValue.js]
|
||||
[test_hiddenResult.js]
|
||||
[test_immediate_search.js]
|
||||
[test_insertMatchAt.js]
|
||||
[test_popupSelectionVsDefaultCompleteValue.js]
|
||||
[test_previousResult.js]
|
||||
[test_stopSearch.js]
|
||||
|
||||
@@ -32,3 +32,6 @@ if not CONFIG['MOZ_DISABLE_PARENTAL_CONTROLS']:
|
||||
LOCAL_INCLUDES += [
|
||||
'../parentalcontrols',
|
||||
]
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wshadow']
|
||||
|
||||
@@ -28,3 +28,6 @@ FINAL_LIBRARY = 'xul'
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Toolkit', 'Startup and Profile System')
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wshadow']
|
||||
|
||||
@@ -22,3 +22,6 @@ FINAL_LIBRARY = 'xul'
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Core', 'js-ctypes')
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wshadow']
|
||||
|
||||
@@ -20,3 +20,6 @@ SharedLibrary('jsctypes-test')
|
||||
LOCAL_INCLUDES += [
|
||||
'/js/src/ctypes',
|
||||
]
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wshadow']
|
||||
|
||||
@@ -21,3 +21,6 @@ SOURCES = [
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wshadow']
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user