зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 24 changesets (bug 1567341) for causing xpcshell failures in test_telemetry.js
CLOSED TREE Backed out changeset deb795c7d0ed (bug 1567341) Backed out changeset 62d24a3e5e33 (bug 1567341) Backed out changeset 1185cabd94e0 (bug 1567341) Backed out changeset 73a4ae419261 (bug 1567341) Backed out changeset b6eb111329f3 (bug 1567341) Backed out changeset 0dc0bfedc042 (bug 1567341) Backed out changeset 9dca635e41d7 (bug 1567341) Backed out changeset c34928580933 (bug 1567341) Backed out changeset f9ba384bb407 (bug 1567341) Backed out changeset ec25c2df380e (bug 1567341) Backed out changeset 9e8ea542b51e (bug 1567341) Backed out changeset 3dc62863a028 (bug 1567341) Backed out changeset 6c104f865540 (bug 1567341) Backed out changeset c422ca4207ea (bug 1567341) Backed out changeset e3df748ed62f (bug 1567341) Backed out changeset 9d1f27796a97 (bug 1567341) Backed out changeset 1d93ba23f809 (bug 1567341) Backed out changeset 55652f6af6ed (bug 1567341) Backed out changeset 9fb892955a88 (bug 1567341) Backed out changeset 1cdd95c43416 (bug 1567341) Backed out changeset 5a839d5e3e33 (bug 1567341) Backed out changeset ea84b5749a27 (bug 1567341) Backed out changeset dcb1ae146475 (bug 1567341) Backed out changeset d72accc274ac (bug 1567341)
This commit is contained in:
Родитель
2586a80626
Коммит
497409d76e
|
@ -49,7 +49,6 @@
|
|||
|
||||
#ifdef ANDROID
|
||||
# include <android/log.h>
|
||||
# include "XREShellData.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
@ -1041,13 +1040,8 @@ int XRE_XPCShellMain(int argc, char** argv, char** envp,
|
|||
int result = 0;
|
||||
nsresult rv;
|
||||
|
||||
#ifdef ANDROID
|
||||
gOutFile = aShellData->outFile;
|
||||
gErrFile = aShellData->errFile;
|
||||
#else
|
||||
gOutFile = stdout;
|
||||
gErrFile = stderr;
|
||||
#endif
|
||||
gOutFile = stdout;
|
||||
gInFile = stdin;
|
||||
|
||||
NS_LogInit();
|
||||
|
@ -1201,7 +1195,8 @@ int XRE_XPCShellMain(int argc, char** argv, char** envp,
|
|||
argv += 2;
|
||||
}
|
||||
|
||||
rv = NS_InitXPCOM(nullptr, appDir, &dirprovider);
|
||||
nsCOMPtr<nsIServiceManager> servMan;
|
||||
rv = NS_InitXPCOM(getter_AddRefs(servMan), appDir, &dirprovider);
|
||||
if (NS_FAILED(rv)) {
|
||||
printf("NS_InitXPCOM failed!\n");
|
||||
return 1;
|
||||
|
|
|
@ -19,7 +19,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
GeckoViewSettings: "resource://gre/modules/GeckoViewSettings.jsm",
|
||||
GeckoViewUtils: "resource://gre/modules/GeckoViewUtils.jsm",
|
||||
HistogramStopwatch: "resource://gre/modules/GeckoViewTelemetry.jsm",
|
||||
SafeBrowsing: "resource://gre/modules/SafeBrowsing.jsm",
|
||||
RemoteSecuritySettings:
|
||||
"resource://gre/modules/psm/RemoteSecuritySettings.jsm",
|
||||
});
|
||||
|
@ -724,12 +723,6 @@ function startup() {
|
|||
RemoteSecuritySettings.init();
|
||||
});
|
||||
|
||||
InitLater(() => {
|
||||
// Initialize safe browsing module. This is required for content
|
||||
// blocking features and manages blocklist downloads and updates.
|
||||
SafeBrowsing.init();
|
||||
});
|
||||
|
||||
// This should always go last, since the idle tasks (except for the ones with
|
||||
// timeouts) should execute in order. Note that this observer notification is
|
||||
// not guaranteed to fire, since the window could close before we get here.
|
||||
|
|
|
@ -16,6 +16,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
ActorManagerParent: "resource://gre/modules/ActorManagerParent.jsm",
|
||||
EventDispatcher: "resource://gre/modules/Messaging.jsm",
|
||||
Preferences: "resource://gre/modules/Preferences.jsm",
|
||||
SafeBrowsing: "resource://gre/modules/SafeBrowsing.jsm",
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
});
|
||||
|
||||
|
@ -94,11 +95,6 @@ class GeckoViewStartup {
|
|||
"GeckoView:WebExtension:Uninstall",
|
||||
"GeckoView:WebExtension:Update",
|
||||
],
|
||||
observers: [
|
||||
"devtools-installed-addon",
|
||||
"testing-installed-addon",
|
||||
"testing-uninstalled-addon",
|
||||
],
|
||||
});
|
||||
|
||||
GeckoViewUtils.addLazyGetter(this, "GeckoViewStorageController", {
|
||||
|
@ -211,6 +207,10 @@ class GeckoViewStartup {
|
|||
|
||||
ChromeUtils.import("resource://gre/modules/NotificationDB.jsm");
|
||||
|
||||
// Initialize safe browsing module. This is required for content
|
||||
// blocking features and manages blocklist downloads and updates.
|
||||
SafeBrowsing.init();
|
||||
|
||||
// Listen for global EventDispatcher messages
|
||||
EventDispatcher.instance.registerListener(this, [
|
||||
"GeckoView:ResetUserPrefs",
|
||||
|
@ -218,7 +218,6 @@ class GeckoViewStartup {
|
|||
"GeckoView:SetLocale",
|
||||
]);
|
||||
|
||||
Services.obs.addObserver(this, "xpcom-shutdown");
|
||||
Services.obs.notifyObservers(null, "geckoview-startup-complete");
|
||||
break;
|
||||
}
|
||||
|
@ -230,16 +229,6 @@ class GeckoViewStartup {
|
|||
Services.startup.trackStartupCrashEnd();
|
||||
break;
|
||||
}
|
||||
case "xpcom-shutdown": {
|
||||
Services.obs.removeObserver(this, "xpcom-shutdown");
|
||||
EventDispatcher.instance.unregisterListener(this, [
|
||||
"GeckoView:ResetUserPrefs",
|
||||
"GeckoView:SetDefaultPrefs",
|
||||
"GeckoView:SetLocale",
|
||||
]);
|
||||
EventDispatcher.instance.shutdown();
|
||||
delete EventDispatcher.instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
<activity-alias android:name=".App" android:targetActivity=".TestRunnerActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<action android:name="org.mozilla.geckoview.test.XPCSHELL_TEST"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
|
@ -48,18 +47,6 @@
|
|||
<!-- This is needed for ProfileLockedTest -->
|
||||
<service android:name=".TestProfileLockService$p0" android:enabled="true" android:exported="false" android:process=":profiletest0" />
|
||||
<service android:name=".TestProfileLockService$p1" android:enabled="true" android:exported="false" android:process=":profiletest1" />
|
||||
|
||||
<!-- This is used to run xpcshell tests -->
|
||||
<service android:name=".XpcshellTestRunnerService$i0" android:enabled="true" android:exported="true" android:process=":xpcshell0"/>
|
||||
<service android:name=".XpcshellTestRunnerService$i1" android:enabled="true" android:exported="true" android:process=":xpcshell1"/>
|
||||
<service android:name=".XpcshellTestRunnerService$i2" android:enabled="true" android:exported="true" android:process=":xpcshell2"/>
|
||||
<service android:name=".XpcshellTestRunnerService$i3" android:enabled="true" android:exported="true" android:process=":xpcshell3"/>
|
||||
<service android:name=".XpcshellTestRunnerService$i4" android:enabled="true" android:exported="true" android:process=":xpcshell4"/>
|
||||
<service android:name=".XpcshellTestRunnerService$i5" android:enabled="true" android:exported="true" android:process=":xpcshell5"/>
|
||||
<service android:name=".XpcshellTestRunnerService$i6" android:enabled="true" android:exported="true" android:process=":xpcshell6"/>
|
||||
<service android:name=".XpcshellTestRunnerService$i7" android:enabled="true" android:exported="true" android:process=":xpcshell7"/>
|
||||
<service android:name=".XpcshellTestRunnerService$i8" android:enabled="true" android:exported="true" android:process=":xpcshell8"/>
|
||||
<service android:name=".XpcshellTestRunnerService$i9" android:enabled="true" android:exported="true" android:process=":xpcshell9"/>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
|
@ -340,11 +340,6 @@ public class TestRunnerActivity extends Activity {
|
|||
|
||||
final Intent intent = getIntent();
|
||||
|
||||
if ("org.mozilla.geckoview.test.XPCSHELL_TEST_MAIN".equals(intent.getAction())) {
|
||||
// This activity is just a stub to run xpcshell tests in a service
|
||||
return;
|
||||
}
|
||||
|
||||
if (sRuntime == null) {
|
||||
final GeckoRuntimeSettings.Builder runtimeSettingsBuilder =
|
||||
new GeckoRuntimeSettings.Builder();
|
||||
|
@ -503,9 +498,6 @@ public class TestRunnerActivity extends Activity {
|
|||
}
|
||||
}
|
||||
|
||||
// Random start timestamp for the BrowsingDataDelegate API.
|
||||
private static final int CLEAR_DATA_START_TIMESTAMP = 1234;
|
||||
|
||||
private void refreshExtensionList() {
|
||||
webExtensionController().list().accept(extensions -> {
|
||||
mExtensions.clear();
|
||||
|
@ -524,8 +516,7 @@ public class TestRunnerActivity extends Activity {
|
|||
Type.HISTORY |
|
||||
Type.FORM_DATA |
|
||||
Type.DOWNLOADS;
|
||||
return GeckoResult.fromValue(new Settings(
|
||||
CLEAR_DATA_START_TIMESTAMP, types, types));
|
||||
return GeckoResult.fromValue(new Settings(1234, types, types ));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
package org.mozilla.geckoview.test;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.Process;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.mozilla.geckoview.ContentBlocking;
|
||||
import org.mozilla.geckoview.GeckoResult;
|
||||
import org.mozilla.geckoview.GeckoRuntime;
|
||||
import org.mozilla.geckoview.GeckoRuntimeSettings;
|
||||
import org.mozilla.geckoview.WebExtension;
|
||||
import org.mozilla.geckoview.WebExtensionController;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class XpcshellTestRunnerService extends Service {
|
||||
public static final class i0 extends XpcshellTestRunnerService {}
|
||||
public static final class i1 extends XpcshellTestRunnerService {}
|
||||
public static final class i2 extends XpcshellTestRunnerService {}
|
||||
public static final class i3 extends XpcshellTestRunnerService {}
|
||||
public static final class i4 extends XpcshellTestRunnerService {}
|
||||
public static final class i5 extends XpcshellTestRunnerService {}
|
||||
public static final class i6 extends XpcshellTestRunnerService {}
|
||||
public static final class i7 extends XpcshellTestRunnerService {}
|
||||
public static final class i8 extends XpcshellTestRunnerService {}
|
||||
public static final class i9 extends XpcshellTestRunnerService {}
|
||||
|
||||
private static final String LOGTAG = "XpcshellTestRunner";
|
||||
static GeckoRuntime sRuntime;
|
||||
|
||||
private HashMap<String, WebExtension> mExtensions = new HashMap<>();
|
||||
|
||||
private static WebExtensionController webExtensionController() {
|
||||
return sRuntime.getWebExtensionController();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if (sRuntime != null) {
|
||||
// We don't support restarting GeckoRuntime
|
||||
throw new RuntimeException("Cannot start more than once");
|
||||
}
|
||||
|
||||
final Bundle extras = intent.getExtras();
|
||||
for (final String key : extras.keySet()) {
|
||||
Log.i(LOGTAG, "Got extras " + key + "=" + extras.get(key));
|
||||
}
|
||||
|
||||
final ContentBlocking.SafeBrowsingProvider googleLegacy = ContentBlocking.SafeBrowsingProvider
|
||||
.from(ContentBlocking.GOOGLE_LEGACY_SAFE_BROWSING_PROVIDER)
|
||||
.getHashUrl("http://mochi.test:8888/safebrowsing-dummy/gethash")
|
||||
.updateUrl("http://mochi.test:8888/safebrowsing-dummy/update")
|
||||
.build();
|
||||
|
||||
final ContentBlocking.SafeBrowsingProvider google = ContentBlocking.SafeBrowsingProvider
|
||||
.from(ContentBlocking.GOOGLE_SAFE_BROWSING_PROVIDER)
|
||||
.getHashUrl("http://mochi.test:8888/safebrowsing4-dummy/gethash")
|
||||
.updateUrl("http://mochi.test:8888/safebrowsing4-dummy/update")
|
||||
.build();
|
||||
|
||||
final GeckoRuntimeSettings runtimeSettings =
|
||||
new GeckoRuntimeSettings.Builder()
|
||||
.arguments(new String[] { "-xpcshell" })
|
||||
.extras(extras)
|
||||
.consoleOutput(true)
|
||||
.contentBlocking(new ContentBlocking.Settings.Builder()
|
||||
.safeBrowsingProviders(google, googleLegacy)
|
||||
.build())
|
||||
.crashHandler(TestCrashHandler.class)
|
||||
.build();
|
||||
|
||||
sRuntime = GeckoRuntime.create(this, runtimeSettings);
|
||||
|
||||
webExtensionController().setDebuggerDelegate(new WebExtensionController.DebuggerDelegate() {
|
||||
@Override
|
||||
public void onExtensionListUpdated() {
|
||||
refreshExtensionList();
|
||||
}
|
||||
});
|
||||
|
||||
sRuntime.setDelegate(() -> {
|
||||
stopSelf();
|
||||
System.exit(0);
|
||||
});
|
||||
|
||||
return Service.START_NOT_STICKY;
|
||||
}
|
||||
|
||||
// Random start timestamp for the BrowsingDataDelegate API.
|
||||
private static final int CLEAR_DATA_START_TIMESTAMP = 1234;
|
||||
|
||||
private void refreshExtensionList() {
|
||||
webExtensionController().list().accept(extensions -> {
|
||||
mExtensions.clear();
|
||||
for (final WebExtension extension : extensions) {
|
||||
mExtensions.put(extension.id, extension);
|
||||
|
||||
extension.setBrowsingDataDelegate(new WebExtension.BrowsingDataDelegate() {
|
||||
@Nullable
|
||||
@Override
|
||||
public GeckoResult<Settings> onGetSettings() {
|
||||
final long types =
|
||||
Type.CACHE |
|
||||
Type.COOKIES |
|
||||
Type.HISTORY |
|
||||
Type.FORM_DATA |
|
||||
Type.DOWNLOADS;
|
||||
return GeckoResult.fromValue(
|
||||
new Settings(CLEAR_DATA_START_TIMESTAMP, types, types));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -125,7 +125,7 @@ public final class EventDispatcher extends JNIObject {
|
|||
@WrapForJNI @Override // JNIObject
|
||||
protected native void disposeNative();
|
||||
|
||||
@WrapForJNI(stubName = "ShutdownFromJava", dispatchTo = "gecko")
|
||||
@WrapForJNI(stubName = "Shutdown")
|
||||
protected native void shutdownNative();
|
||||
|
||||
@WrapForJNI private static final int DETACHED = 0;
|
||||
|
|
|
@ -154,8 +154,6 @@ public class GeckoThread extends Thread {
|
|||
public Map<String, Object> prefs;
|
||||
public String userSerialNumber;
|
||||
|
||||
public boolean xpcshell;
|
||||
public String outFilePath;
|
||||
public int prefsFd;
|
||||
public int prefMapFd;
|
||||
public int ipcFd;
|
||||
|
@ -276,27 +274,23 @@ public class GeckoThread extends Thread {
|
|||
|
||||
// argv[0] is the program name, which for us is the package name.
|
||||
args.add(context.getPackageName());
|
||||
args.add("-greomni");
|
||||
args.add(context.getPackageResourcePath());
|
||||
|
||||
if (!mInitInfo.xpcshell) {
|
||||
args.add("-greomni");
|
||||
args.add(context.getPackageResourcePath());
|
||||
|
||||
final GeckoProfile profile = getProfile();
|
||||
if (profile.isCustomProfile()) {
|
||||
args.add("-profile");
|
||||
args.add(profile.getDir().getAbsolutePath());
|
||||
} else {
|
||||
profile.getDir(); // Make sure the profile dir exists.
|
||||
args.add("-P");
|
||||
args.add(profile.getName());
|
||||
}
|
||||
final GeckoProfile profile = getProfile();
|
||||
if (profile.isCustomProfile()) {
|
||||
args.add("-profile");
|
||||
args.add(profile.getDir().getAbsolutePath());
|
||||
} else {
|
||||
profile.getDir(); // Make sure the profile dir exists.
|
||||
args.add("-P");
|
||||
args.add(profile.getName());
|
||||
}
|
||||
|
||||
if (mInitInfo.args != null) {
|
||||
args.addAll(Arrays.asList(mInitInfo.args));
|
||||
}
|
||||
|
||||
// Legacy "args" parameter
|
||||
final String extraArgs = mInitInfo.extras.getString(EXTRA_ARGS, null);
|
||||
if (extraArgs != null) {
|
||||
final StringTokenizer st = new StringTokenizer(extraArgs);
|
||||
|
@ -313,12 +307,6 @@ public class GeckoThread extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
// "argX" parameters
|
||||
for (int i = 0; mInitInfo.extras.containsKey("arg" + i); i++) {
|
||||
final String arg = mInitInfo.extras.getString("arg" + i);
|
||||
args.add(arg);
|
||||
}
|
||||
|
||||
return args.toArray(new String[args.size()]);
|
||||
}
|
||||
|
||||
|
@ -440,8 +428,7 @@ public class GeckoThread extends Thread {
|
|||
final boolean isChildProcess = isChildProcess();
|
||||
|
||||
GeckoLoader.setupGeckoEnvironment(context, isChildProcess,
|
||||
context.getFilesDir().getPath(), env, mInitInfo.prefs,
|
||||
mInitInfo.xpcshell);
|
||||
context.getFilesDir().getPath(), env, mInitInfo.prefs);
|
||||
|
||||
initGeckoEnvironment();
|
||||
|
||||
|
@ -471,9 +458,7 @@ public class GeckoThread extends Thread {
|
|||
mInitInfo.extras.getInt(EXTRA_PREF_MAP_FD, -1),
|
||||
mInitInfo.extras.getInt(EXTRA_IPC_FD, -1),
|
||||
mInitInfo.extras.getInt(EXTRA_CRASH_FD, -1),
|
||||
mInitInfo.extras.getInt(EXTRA_CRASH_ANNOTATION_FD, -1),
|
||||
isChildProcess ? false : mInitInfo.xpcshell,
|
||||
isChildProcess ? null : mInitInfo.outFilePath);
|
||||
mInitInfo.extras.getInt(EXTRA_CRASH_ANNOTATION_FD, -1));
|
||||
|
||||
// And... we're done.
|
||||
final boolean restarting = isState(State.RESTARTING);
|
||||
|
@ -485,12 +470,6 @@ public class GeckoThread extends Thread {
|
|||
|
||||
// Remove pumpMessageLoop() idle handler
|
||||
Looper.myQueue().removeIdleHandler(idleHandler);
|
||||
|
||||
if (isChildProcess) {
|
||||
// The child process is completely controlled by Gecko so we don't really need to keep
|
||||
// it alive after Gecko exits.
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
// This may start the gecko profiler early by looking at the environment variables.
|
||||
|
|
|
@ -118,8 +118,7 @@ public final class GeckoLoader {
|
|||
final boolean isChildProcess,
|
||||
final String profilePath,
|
||||
final Collection<String> env,
|
||||
final Map<String, Object> prefs,
|
||||
final boolean xpcshell) {
|
||||
final Map<String, Object> prefs) {
|
||||
for (final String e : env) {
|
||||
putenv(e);
|
||||
}
|
||||
|
@ -157,15 +156,12 @@ public final class GeckoLoader {
|
|||
setupInitialPrefs(prefs);
|
||||
}
|
||||
|
||||
// Xpcshell tests set up their own temp directory
|
||||
if (!xpcshell) {
|
||||
// setup the tmp path
|
||||
final File f = getTmpDir(context);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
putenv("TMPDIR=" + f.getPath());
|
||||
// setup the tmp path
|
||||
final File f = getTmpDir(context);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
putenv("TMPDIR=" + f.getPath());
|
||||
|
||||
putenv("LANG=" + Locale.getDefault().toString());
|
||||
|
||||
|
@ -500,7 +496,7 @@ public final class GeckoLoader {
|
|||
private static native void putenv(String map);
|
||||
|
||||
// These methods are implemented in mozglue/android/APKOpen.cpp
|
||||
public static native void nativeRun(String[] args, int prefsFd, int prefMapFd, int ipcFd, int crashFd, int crashAnnotationFd, boolean xpcshell, String outFilePath);
|
||||
public static native void nativeRun(String[] args, int prefsFd, int prefMapFd, int ipcFd, int crashFd, int crashAnnotationFd);
|
||||
private static native void loadGeckoLibsNative();
|
||||
private static native void loadSQLiteLibsNative();
|
||||
private static native void loadNSSLibsNative();
|
||||
|
|
|
@ -438,10 +438,9 @@ public final class GeckoProcessManager extends IProcessManager.Stub {
|
|||
}
|
||||
|
||||
private void removeContentConnection(@NonNull final ChildConnection conn) {
|
||||
if (!mContentConnections.remove(conn)) {
|
||||
if (!mContentConnections.remove(conn) && !mNonStartedContentConnections.remove(conn)) {
|
||||
throw new RuntimeException("Attempt to remove non-registered connection");
|
||||
}
|
||||
mNonStartedContentConnections.remove(conn);
|
||||
|
||||
final int pid;
|
||||
|
||||
|
@ -800,9 +799,8 @@ public final class GeckoProcessManager extends IProcessManager.Stub {
|
|||
// for now, so that's ok. We can improve on this if we eventually
|
||||
// end up needing something fancier.
|
||||
Log.w(LOGTAG, "Trying a different process");
|
||||
connection.unbind().accept(unused ->
|
||||
start(result, type, args, extras, flags, prefsFd, prefMapFd, ipcFd,
|
||||
crashFd, crashAnnotationFd, /* isRetry */ false));
|
||||
start(result, type, args, extras, flags, prefsFd, prefMapFd, ipcFd,
|
||||
crashFd, crashAnnotationFd, /* isRetry */ false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,13 +19,9 @@ import android.os.IBinder;
|
|||
import androidx.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.BitSet;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/* package */ final class ServiceAllocator {
|
||||
private static final String LOGTAG = "ServiceAllocator";
|
||||
|
@ -120,7 +116,7 @@ import java.util.UUID;
|
|||
final Intent intent = new Intent();
|
||||
intent.setClassName(context, getServiceName());
|
||||
return bindServiceIsolated(context, intent, getAndroidFlags(priority),
|
||||
getIdInternal(), binding);
|
||||
getIdAsString(), binding);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -131,7 +127,7 @@ import java.util.UUID;
|
|||
|
||||
private final ServiceAllocator mAllocator;
|
||||
private final GeckoProcessType mType;
|
||||
private final String mId;
|
||||
private final Integer mId;
|
||||
private final EnumMap<PriorityLevel, Binding> mBindings;
|
||||
private final BindServiceDelegate mBindDelegate;
|
||||
|
||||
|
@ -191,19 +187,19 @@ import java.util.UUID;
|
|||
* Only content services have unique IDs. This method throws if called for a non-content
|
||||
* service type.
|
||||
*/
|
||||
public String getId() {
|
||||
public int getId() {
|
||||
if (mId == null) {
|
||||
throw new RuntimeException("This service does not have a unique id");
|
||||
}
|
||||
|
||||
return mId;
|
||||
return mId.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is infallible and returns an empty string for non-content services.
|
||||
*/
|
||||
private String getIdInternal() {
|
||||
return mId == null ? "" : mId;
|
||||
private String getIdAsString() {
|
||||
return mId == null ? "" : mId.toString();
|
||||
}
|
||||
|
||||
public boolean isContent() {
|
||||
|
@ -386,13 +382,13 @@ import java.util.UUID;
|
|||
* Allocate an unused service ID for use by the caller.
|
||||
* @return The new service id.
|
||||
*/
|
||||
String allocate();
|
||||
int allocate();
|
||||
|
||||
/**
|
||||
* Release a previously used service ID.
|
||||
* @param id The service id being released.
|
||||
*/
|
||||
void release(final String id);
|
||||
void release(final int id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -403,12 +399,10 @@ import java.util.UUID;
|
|||
private static final class DefaultContentPolicy implements ContentAllocationPolicy {
|
||||
private final int mMaxNumSvcs;
|
||||
private final BitSet mAllocator;
|
||||
private final SecureRandom mRandom;
|
||||
|
||||
public DefaultContentPolicy() {
|
||||
mMaxNumSvcs = getContentServiceCount();
|
||||
mAllocator = new BitSet(mMaxNumSvcs);
|
||||
mRandom = new SecureRandom();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -417,30 +411,20 @@ import java.util.UUID;
|
|||
}
|
||||
|
||||
@Override
|
||||
public String allocate() {
|
||||
final int[] available = new int[mMaxNumSvcs];
|
||||
int size = 0;
|
||||
for (int i = 0; i < mMaxNumSvcs; i++) {
|
||||
if (!mAllocator.get(i)) {
|
||||
available[size] = i;
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
public int allocate() {
|
||||
final int next = mAllocator.nextClearBit(0);
|
||||
if (next >= mMaxNumSvcs) {
|
||||
throw new RuntimeException("No more content services available");
|
||||
}
|
||||
|
||||
final int next = available[mRandom.nextInt(size)];
|
||||
mAllocator.set(next);
|
||||
return Integer.toString(next);
|
||||
return next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(final String stringId) {
|
||||
final int id = Integer.valueOf(stringId);
|
||||
public void release(final int id) {
|
||||
if (!mAllocator.get(id)) {
|
||||
throw new IllegalStateException("Releasing an unallocated id=" + id);
|
||||
throw new IllegalStateException("Releasing an unallocated id!");
|
||||
}
|
||||
|
||||
mAllocator.clear(id);
|
||||
|
@ -462,7 +446,8 @@ import java.util.UUID;
|
|||
* generate unique instance IDs in this case.
|
||||
*/
|
||||
private static final class IsolatedContentPolicy implements ContentAllocationPolicy {
|
||||
private final Set<String> mRunningServiceIds = new HashSet<>();
|
||||
private int mNextIsolatedSvcId = 0;
|
||||
private int mCurNumIsolatedSvcs = 0;
|
||||
|
||||
@Override
|
||||
public BindServiceDelegate getBindServiceDelegate(@NonNull final InstanceInfo info) {
|
||||
|
@ -475,24 +460,25 @@ import java.util.UUID;
|
|||
* limit on number of simultaneous content processes.
|
||||
*/
|
||||
@Override
|
||||
public String allocate() {
|
||||
if (mRunningServiceIds.size() >= MAX_NUM_ISOLATED_CONTENT_SERVICES) {
|
||||
public int allocate() {
|
||||
if (mCurNumIsolatedSvcs >= MAX_NUM_ISOLATED_CONTENT_SERVICES) {
|
||||
throw new RuntimeException("No more content services available");
|
||||
}
|
||||
|
||||
final String newId = UUID.randomUUID().toString();
|
||||
mRunningServiceIds.add(newId);
|
||||
return newId;
|
||||
++mCurNumIsolatedSvcs;
|
||||
return mNextIsolatedSvcId++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just drop the count of active services.
|
||||
*/
|
||||
@Override
|
||||
public void release(final String id) {
|
||||
if (!mRunningServiceIds.remove(id)) {
|
||||
public void release(final int id) {
|
||||
if (mCurNumIsolatedSvcs <= 0) {
|
||||
throw new IllegalStateException("Releasing an unallocated id");
|
||||
}
|
||||
|
||||
--mCurNumIsolatedSvcs;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -506,7 +492,7 @@ import java.util.UUID;
|
|||
* @param type The type of service.
|
||||
* @return Integer encapsulating the service ID, or null if no ID is necessary.
|
||||
*/
|
||||
private String allocate(@NonNull final GeckoProcessType type) {
|
||||
private Integer allocate(@NonNull final GeckoProcessType type) {
|
||||
XPCOMEventTarget.assertOnLauncherThread();
|
||||
if (type != GeckoProcessType.CONTENT) {
|
||||
// No unique id necessary
|
||||
|
@ -523,7 +509,7 @@ import java.util.UUID;
|
|||
}
|
||||
}
|
||||
|
||||
return mContentAllocPolicy.allocate();
|
||||
return Integer.valueOf(mContentAllocPolicy.allocate());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -567,7 +553,7 @@ import java.util.UUID;
|
|||
* Obtain the class name to use for service binding in the default (ie, non-isolated) case.
|
||||
*/
|
||||
private static String getSvcClassNameDefault(@NonNull final InstanceInfo info) {
|
||||
return ServiceUtils.buildSvcName(info.getType(), info.getIdInternal());
|
||||
return ServiceUtils.buildSvcName(info.getType(), info.getIdAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -49,7 +49,6 @@ import org.mozilla.gecko.util.ThreadUtils;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -290,27 +289,6 @@ public final class GeckoRuntime implements Parcelable {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void setArguments(final Context context, final GeckoThread.InitInfo initInfo,
|
||||
final String[] arguments) {
|
||||
final List<String> result = new ArrayList<>(arguments.length);
|
||||
for (final String argument : arguments) {
|
||||
if ("-xpcshell".equals(argument)) {
|
||||
// Only debug builds of the test app can run an xpcshell
|
||||
if (!BuildConfig.DEBUG
|
||||
|| !"org.mozilla.geckoview.test".equals(
|
||||
context.getApplicationContext().getPackageName())) {
|
||||
throw new IllegalArgumentException("Only the test app can run -xpcshell.");
|
||||
}
|
||||
|
||||
initInfo.xpcshell = true;
|
||||
} else {
|
||||
result.add(argument);
|
||||
}
|
||||
}
|
||||
|
||||
initInfo.args = result.toArray(new String[]{});
|
||||
}
|
||||
|
||||
/* package */ boolean init(final @NonNull Context context, final @NonNull GeckoRuntimeSettings settings) {
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "init");
|
||||
|
@ -351,10 +329,7 @@ public final class GeckoRuntime implements Parcelable {
|
|||
GeckoFontScaleListener.getInstance().attachToContext(context, settings);
|
||||
|
||||
final GeckoThread.InitInfo info = new GeckoThread.InitInfo();
|
||||
setArguments(context, info, settings.getArguments());
|
||||
if (info.xpcshell) {
|
||||
info.outFilePath = settings.getExtras().getString("out_file");
|
||||
}
|
||||
info.args = settings.getArguments();
|
||||
info.extras = settings.getExtras();
|
||||
info.flags = flags;
|
||||
|
||||
|
|
|
@ -48,25 +48,6 @@ XPCOMUtils.defineLazyServiceGetter(
|
|||
|
||||
const { debug, warn } = GeckoViewUtils.initLogging("Console");
|
||||
|
||||
// Allows to |await| for AddonManager to startup
|
||||
// mostly useful in tests that run super-early when AddonManager is not
|
||||
// available yet.
|
||||
XPCOMUtils.defineLazyGetter(this, "gAddonManagerStartup", function() {
|
||||
if (AddonManager.isReady) {
|
||||
// Already started up, nothing to do
|
||||
return true;
|
||||
}
|
||||
|
||||
// Wait until AddonManager is ready to accept calls
|
||||
return new Promise(resolve => {
|
||||
AddonManager.addManagerListener({
|
||||
onStartup() {
|
||||
resolve(true);
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const DOWNLOAD_CHANGED_MESSAGE = "GeckoView:WebExtension:DownloadChanged";
|
||||
|
||||
var DownloadTracker = new (class extends EventEmitter {
|
||||
|
@ -654,7 +635,6 @@ var GeckoViewWebExtension = {
|
|||
},
|
||||
|
||||
async ensureBuiltIn(aUri, aId) {
|
||||
await gAddonManagerStartup;
|
||||
const extensionData = new ExtensionData(aUri);
|
||||
const [manifest, extension] = await Promise.all([
|
||||
extensionData.loadManifest(),
|
||||
|
@ -674,7 +654,6 @@ var GeckoViewWebExtension = {
|
|||
},
|
||||
|
||||
async installBuiltIn(aUri) {
|
||||
await gAddonManagerStartup;
|
||||
const addon = await AddonManager.installBuiltinAddon(aUri.spec);
|
||||
const exported = await exportExtension(addon, addon.userPermissions, aUri);
|
||||
return { extension: exported };
|
||||
|
@ -1049,7 +1028,6 @@ var GeckoViewWebExtension = {
|
|||
|
||||
case "GeckoView:WebExtension:List": {
|
||||
try {
|
||||
await gAddonManagerStartup;
|
||||
const addons = await AddonManager.getAddonsByTypes(["extension"]);
|
||||
const extensions = await Promise.all(
|
||||
addons.map(addon =>
|
||||
|
@ -1088,3 +1066,6 @@ var GeckoViewWebExtension = {
|
|||
GeckoViewWebExtension.browserActions = new WeakMap();
|
||||
// WeakMap[Extension -> PageAction]
|
||||
GeckoViewWebExtension.pageActions = new WeakMap();
|
||||
Services.obs.addObserver(GeckoViewWebExtension, "devtools-installed-addon");
|
||||
Services.obs.addObserver(GeckoViewWebExtension, "testing-installed-addon");
|
||||
Services.obs.addObserver(GeckoViewWebExtension, "testing-uninstalled-addon");
|
||||
|
|
|
@ -151,10 +151,6 @@ DispatcherDelegate.prototype = {
|
|||
this._replies.clear();
|
||||
},
|
||||
|
||||
shutdown() {
|
||||
this._dispatcher.shutdown();
|
||||
},
|
||||
|
||||
receiveMessage(aMsg) {
|
||||
const { uuid, type } = aMsg.data;
|
||||
const reply = this._replies.get(uuid);
|
||||
|
@ -286,12 +282,4 @@ var EventDispatcher = {
|
|||
if (IS_PARENT_PROCESS) {
|
||||
Services.mm.addMessageListener("GeckoView:Messaging", EventDispatcher);
|
||||
Services.ppmm.addMessageListener("GeckoView:Messaging", EventDispatcher);
|
||||
|
||||
function xpcomShutdown() {
|
||||
Services.mm.removeMessageListener("GeckoView:Messaging", EventDispatcher);
|
||||
Services.ppmm.removeMessageListener("GeckoView:Messaging", EventDispatcher);
|
||||
Services.obs.removeObserver(xpcomShutdown, "xpcom-shutdown");
|
||||
}
|
||||
|
||||
Services.obs.addObserver(xpcomShutdown, "xpcom-shutdown");
|
||||
}
|
||||
|
|
|
@ -362,10 +362,11 @@ static void FreeArgv(char** argv, int argc) {
|
|||
}
|
||||
|
||||
extern "C" APKOPEN_EXPORT void MOZ_JNICALL
|
||||
Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(
|
||||
JNIEnv* jenv, jclass jc, jobjectArray jargs, int prefsFd, int prefMapFd,
|
||||
int ipcFd, int crashFd, int crashAnnotationFd, bool xpcshell,
|
||||
jstring outFilePath) {
|
||||
Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv* jenv, jclass jc,
|
||||
jobjectArray jargs,
|
||||
int prefsFd, int prefMapFd,
|
||||
int ipcFd, int crashFd,
|
||||
int crashAnnotationFd) {
|
||||
EnsureBaseProfilerInitialized();
|
||||
|
||||
int argc = 0;
|
||||
|
@ -380,15 +381,7 @@ Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(
|
|||
#ifdef MOZ_LINKER
|
||||
ElfLoader::Singleton.ExpectShutdown(false);
|
||||
#endif
|
||||
const char* outFilePathRaw = nullptr;
|
||||
if (xpcshell) {
|
||||
MOZ_ASSERT(outFilePath);
|
||||
outFilePathRaw = jenv->GetStringUTFChars(outFilePath, nullptr);
|
||||
}
|
||||
gBootstrap->GeckoStart(jenv, argv, argc, sAppData, xpcshell, outFilePathRaw);
|
||||
if (outFilePathRaw) {
|
||||
jenv->ReleaseStringUTFChars(outFilePath, outFilePathRaw);
|
||||
}
|
||||
gBootstrap->GeckoStart(jenv, argv, argc, sAppData);
|
||||
#ifdef MOZ_LINKER
|
||||
ElfLoader::Singleton.ExpectShutdown(true);
|
||||
#endif
|
||||
|
|
|
@ -194,7 +194,6 @@ skip-if = bits != 32
|
|||
skip-if = true # Bug 863738
|
||||
[test_cookies_privatebrowsing.js]
|
||||
[test_cookies_profile_close.js]
|
||||
skip-if = os == "android" # Bug 1700483
|
||||
[test_cookies_read.js]
|
||||
[test_cookies_sync_failure.js]
|
||||
[test_cookies_thirdparty.js]
|
||||
|
@ -394,7 +393,6 @@ skip-if = (verify && !debug && (os == 'win'))
|
|||
[test_channel_priority.js]
|
||||
[test_bug1312774_http1.js]
|
||||
[test_bug1312782_http1.js]
|
||||
skip-if = os == "android" # Bug 1700483
|
||||
[test_bug1355539_http1.js]
|
||||
[test_bug1378385_http1.js]
|
||||
[test_tls_flags_separate_connections.js]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
[DEFAULT]
|
||||
head = head_channels_clone.js head_trr_clone.js
|
||||
skip-if = toolkit == 'android'
|
||||
support-files =
|
||||
child_channel_id.js
|
||||
!/netwerk/test/unit/test_XHR_redirects.js
|
||||
|
|
|
@ -3957,7 +3957,6 @@ class ADBDevice(ADBCommand):
|
|||
fail_if_running=True,
|
||||
grant_runtime_permissions=True,
|
||||
timeout=None,
|
||||
is_service=False,
|
||||
):
|
||||
"""Launches an Android application
|
||||
|
||||
|
@ -3978,7 +3977,6 @@ class ADBDevice(ADBCommand):
|
|||
This timeout is per adb call. The total time spent
|
||||
may exceed this value. If it is not specified, the value
|
||||
set in the ADB constructor is used.
|
||||
:param bool is_service: Whether we want to launch a service or not.
|
||||
:raises: :exc:`ADBTimeoutError`
|
||||
:exc:`ADBError`
|
||||
"""
|
||||
|
@ -3994,8 +3992,7 @@ class ADBDevice(ADBCommand):
|
|||
if grant_runtime_permissions:
|
||||
self.grant_runtime_permissions(app_name)
|
||||
|
||||
acmd = ["am"] + [
|
||||
"startservice" if is_service else "start",
|
||||
acmd = ["am", "start"] + [
|
||||
"-W" if wait else "",
|
||||
"-n",
|
||||
"%s/%s" % (app_name, activity_name),
|
||||
|
@ -4087,76 +4084,6 @@ class ADBDevice(ADBCommand):
|
|||
timeout=timeout,
|
||||
)
|
||||
|
||||
def launch_service(
|
||||
self,
|
||||
app_name,
|
||||
activity_name=None,
|
||||
intent="android.intent.action.MAIN",
|
||||
moz_env=None,
|
||||
extra_args=None,
|
||||
url=None,
|
||||
e10s=False,
|
||||
wait=True,
|
||||
grant_runtime_permissions=False,
|
||||
out_file=None,
|
||||
timeout=None,
|
||||
):
|
||||
"""Convenience method to launch a service on Android with various
|
||||
debugging arguments; convenient for geckoview apps.
|
||||
|
||||
:param str app_name: Name of application (e.g.
|
||||
`org.mozilla.geckoview_example` or `org.mozilla.geckoview.test`)
|
||||
:param str activity_name: Activity name, like `GeckoViewActivity`, or
|
||||
`TestRunnerActivity`.
|
||||
:param str intent: Intent to launch application.
|
||||
:param str moz_env: Mozilla specific environment to pass into
|
||||
application.
|
||||
:param str extra_args: Extra arguments to be parsed by the app.
|
||||
:param str url: URL to open
|
||||
:param bool e10s: If True, run in multiprocess mode.
|
||||
:param bool wait: If True, wait for application to start before
|
||||
returning.
|
||||
:param bool grant_runtime_permissions: Grant special runtime
|
||||
permissions.
|
||||
:param str out_file: File where to redirect the output to
|
||||
:param int timeout: The maximum time in
|
||||
seconds for any spawned adb process to complete before
|
||||
throwing an ADBTimeoutError.
|
||||
This timeout is per adb call. The total time spent
|
||||
may exceed this value. If it is not specified, the value
|
||||
set in the ADB constructor is used.
|
||||
:raises: :exc:`ADBTimeoutError`
|
||||
:exc:`ADBError`
|
||||
"""
|
||||
extras = {}
|
||||
|
||||
if moz_env:
|
||||
# moz_env is expected to be a dictionary of environment variables:
|
||||
# geckoview_example itself will set them when launched
|
||||
for (env_count, (env_key, env_val)) in enumerate(moz_env.items()):
|
||||
extras["env" + str(env_count)] = env_key + "=" + env_val
|
||||
|
||||
# Additional command line arguments that the app will read and use (e.g.
|
||||
# with a custom profile)
|
||||
if extra_args:
|
||||
for (arg_count, arg) in enumerate(extra_args):
|
||||
extras["arg" + str(arg_count)] = arg
|
||||
|
||||
extras["use_multiprocess"] = e10s
|
||||
extras["out_file"] = out_file
|
||||
self.launch_application(
|
||||
app_name,
|
||||
"%s.%s" % (app_name, activity_name),
|
||||
intent,
|
||||
url=url,
|
||||
extras=extras,
|
||||
wait=wait,
|
||||
grant_runtime_permissions=grant_runtime_permissions,
|
||||
timeout=timeout,
|
||||
is_service=True,
|
||||
fail_if_running=False,
|
||||
)
|
||||
|
||||
def launch_activity(
|
||||
self,
|
||||
app_name,
|
||||
|
@ -4207,9 +4134,7 @@ class ADBDevice(ADBCommand):
|
|||
# Additional command line arguments that the app will read and use (e.g.
|
||||
# with a custom profile)
|
||||
if extra_args:
|
||||
for (arg_count, arg) in enumerate(extra_args):
|
||||
extras["arg" + str(arg_count)] = arg
|
||||
|
||||
extras["args"] = " ".join(extra_args)
|
||||
extras["use_multiprocess"] = e10s
|
||||
self.launch_application(
|
||||
app_name,
|
||||
|
|
|
@ -291,6 +291,7 @@ config = {
|
|||
"xpcshell": {
|
||||
"run_filename": "remotexpcshelltests.py",
|
||||
"testsdir": "xpcshell",
|
||||
"install": False,
|
||||
"options": [
|
||||
"--xre-path=%(xre_path)s",
|
||||
"--testing-modules-dir=%(modules_dir)s",
|
||||
|
@ -303,7 +304,6 @@ config = {
|
|||
"--log-errorsummary=%(error_summary_file)s",
|
||||
"--log-tbpl-level=%(log_tbpl_level)s",
|
||||
"--test-plugin-path=none",
|
||||
"--threads=4",
|
||||
"--deviceSerial=%(device_serial)s",
|
||||
"%(xpcshell_extra)s",
|
||||
],
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
/* defined by the harness */
|
||||
/* globals _HEAD_FILES, _HEAD_JS_PATH, _JSDEBUGGER_PORT, _JSCOV_DIR,
|
||||
_MOZINFO_JS_PATH, _TEST_FILE, _TEST_NAME, _TEST_CWD, _TESTING_MODULES_DIR:true,
|
||||
_MOZINFO_JS_PATH, _TEST_FILE, _TEST_NAME, _TESTING_MODULES_DIR:true,
|
||||
_PREFS_FILE */
|
||||
|
||||
/* defined by XPCShellImpl.cpp */
|
||||
|
@ -64,8 +64,6 @@ let _XPCOMUtils = ChromeUtils.import(
|
|||
null
|
||||
).XPCOMUtils;
|
||||
|
||||
let _OS = ChromeUtils.import("resource://gre/modules/osfile.jsm", null).OS;
|
||||
|
||||
// Support a common assertion library, Assert.jsm.
|
||||
var AssertCls = ChromeUtils.import("resource://testing-common/Assert.jsm", null)
|
||||
.Assert;
|
||||
|
@ -505,30 +503,6 @@ function _initDebugging(port) {
|
|||
}
|
||||
|
||||
function _execute_test() {
|
||||
if (typeof _TEST_CWD != "undefined") {
|
||||
let cwd_complete = false;
|
||||
_OS.File.setCurrentDirectory(_TEST_CWD)
|
||||
.then(_ => (cwd_complete = true))
|
||||
.catch(e => {
|
||||
_testLogger.error(_exception_message(e));
|
||||
cwd_complete = true;
|
||||
});
|
||||
_Services.tm.spinEventLoopUntil(
|
||||
"Test(xpcshell/head.js:setCurrentDirectory)",
|
||||
() => cwd_complete
|
||||
);
|
||||
}
|
||||
|
||||
if (runningInParent && _AppConstants.platform == "android") {
|
||||
_Services.obs.notifyObservers(null, "profile-after-change");
|
||||
// Wake up GeckoViewStartup
|
||||
let geckoViewStartup = Cc["@mozilla.org/geckoview/startup;1"].getService(
|
||||
Ci.nsIObserver
|
||||
);
|
||||
geckoViewStartup.observe(null, "profile-after-change", null);
|
||||
geckoViewStartup.observe(null, "app-startup", null);
|
||||
}
|
||||
|
||||
// _JSDEBUGGER_PORT is dynamically defined by <runxpcshelltests.py>.
|
||||
if (_JSDEBUGGER_PORT) {
|
||||
try {
|
||||
|
@ -667,7 +641,7 @@ function _execute_test() {
|
|||
.catch(reportCleanupError)
|
||||
.then(() => (complete = true));
|
||||
_Services.tm.spinEventLoopUntil(
|
||||
"Test(xpcshell/head.js:_execute_test)",
|
||||
"Test(xpcshel/head.js:_execute_test)",
|
||||
() => complete
|
||||
);
|
||||
if (cleanupStartTime) {
|
||||
|
@ -1384,10 +1358,6 @@ function do_load_child_test_harness() {
|
|||
command += " const _JSCOV_DIR=" + uneval(_JSCOV_DIR) + ";";
|
||||
}
|
||||
|
||||
if (typeof _TEST_CWD != "undefined") {
|
||||
command += " const _TEST_CWD=" + uneval(_TEST_CWD) + ";";
|
||||
}
|
||||
|
||||
if (_TESTING_MODULES_DIR) {
|
||||
command +=
|
||||
" const _TESTING_MODULES_DIR=" + uneval(_TESTING_MODULES_DIR) + ";";
|
||||
|
|
|
@ -195,6 +195,9 @@ class AndroidXPCShellRunner(MozbuildObject):
|
|||
else:
|
||||
raise Exception("APK not found in objdir. You must specify an APK.")
|
||||
|
||||
if not kwargs["sequential"]:
|
||||
kwargs["sequential"] = True
|
||||
|
||||
xpcshell = remotexpcshelltests.XPCShellRemote(kwargs, log)
|
||||
|
||||
result = xpcshell.runTests(
|
||||
|
@ -264,14 +267,10 @@ class MachCommands(MachCommandBase):
|
|||
from mozrunner.devices.android_device import (
|
||||
verify_android_device,
|
||||
get_adb_path,
|
||||
InstallIntent,
|
||||
)
|
||||
|
||||
install = InstallIntent.YES if params["setup"] else InstallIntent.NO
|
||||
device_serial = params.get("deviceSerial")
|
||||
verify_android_device(
|
||||
self, network=True, install=install, device_serial=device_serial
|
||||
)
|
||||
verify_android_device(self, network=True, device_serial=device_serial)
|
||||
if not params["adbPath"]:
|
||||
params["adbPath"] = get_adb_path(self)
|
||||
xpcshell = self._spawn(AndroidXPCShellRunner)
|
||||
|
|
|
@ -7,17 +7,13 @@
|
|||
from __future__ import absolute_import, print_function
|
||||
|
||||
from argparse import Namespace
|
||||
import datetime
|
||||
import os
|
||||
import posixpath
|
||||
import mozdevice
|
||||
import shutil
|
||||
import six
|
||||
import sys
|
||||
import runxpcshelltests as xpcshell
|
||||
import tempfile
|
||||
import time
|
||||
import uuid
|
||||
from zipfile import ZipFile
|
||||
|
||||
import mozcrash
|
||||
|
@ -31,95 +27,6 @@ from xpcshellcommandline import parser_remote
|
|||
here = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
class RemoteProcessMonitor(object):
|
||||
processStatus = []
|
||||
|
||||
def __init__(self, package, device, log, remoteLogFile):
|
||||
self.package = package
|
||||
self.device = device
|
||||
self.log = log
|
||||
self.remoteLogFile = remoteLogFile
|
||||
self.selectedProcess = -1
|
||||
|
||||
@classmethod
|
||||
def pickUnusedProcess(cls):
|
||||
for i in range(len(cls.processStatus)):
|
||||
if not cls.processStatus[i]:
|
||||
cls.processStatus[i] = True
|
||||
return i
|
||||
# No more free processes :(
|
||||
return -1
|
||||
|
||||
@classmethod
|
||||
def freeProcess(cls, processId):
|
||||
cls.processStatus[processId] = False
|
||||
|
||||
def kill(self):
|
||||
self.device.pkill(self.process_name, sig=9, attempts=1)
|
||||
|
||||
def launch_service(self, extra_args, env, selectedProcess):
|
||||
if not self.device.process_exist(self.package):
|
||||
# Make sure the main app is running, this should help making the
|
||||
# tests get foreground priority scheduling.
|
||||
self.device.launch_activity(
|
||||
self.package,
|
||||
intent="org.mozilla.geckoview.test.XPCSHELL_TEST_MAIN",
|
||||
activity_name="TestRunnerActivity",
|
||||
e10s=True,
|
||||
)
|
||||
|
||||
self.process_name = self.package + (":xpcshell%d" % selectedProcess)
|
||||
self.device.launch_service(
|
||||
self.package,
|
||||
activity_name=("XpcshellTestRunnerService$i%d" % selectedProcess),
|
||||
e10s=True,
|
||||
moz_env=env,
|
||||
grant_runtime_permissions=False,
|
||||
extra_args=extra_args,
|
||||
out_file=self.remoteLogFile,
|
||||
)
|
||||
return self.pid
|
||||
|
||||
def wait(self, timeout, interval=0.1):
|
||||
timer = 0
|
||||
status = True
|
||||
|
||||
# wait for log creation on startup
|
||||
retries = 0
|
||||
while retries < 20 / interval and not self.device.is_file(self.remoteLogFile):
|
||||
retries += 1
|
||||
time.sleep(interval)
|
||||
if not self.device.is_file(self.remoteLogFile):
|
||||
self.log.warning(
|
||||
"Failed wait for remote log: %s missing?" % self.remoteLogFile
|
||||
)
|
||||
|
||||
while self.device.process_exist(self.process_name):
|
||||
time.sleep(interval)
|
||||
timer += interval
|
||||
interval *= 1.5
|
||||
if timeout and timer > timeout:
|
||||
status = False
|
||||
self.log.info("Timing out...")
|
||||
self.kill()
|
||||
break
|
||||
return status
|
||||
|
||||
@property
|
||||
def pid(self):
|
||||
"""
|
||||
Determine the pid of the remote process (or the first process with
|
||||
the same name).
|
||||
"""
|
||||
procs = self.device.get_process_list()
|
||||
# limit the comparison to the first 75 characters due to a
|
||||
# limitation in processname length in android.
|
||||
pids = [proc[0] for proc in procs if proc[1] == self.process_name[:75]]
|
||||
if pids is None or len(pids) < 1:
|
||||
return 0
|
||||
return pids[0]
|
||||
|
||||
|
||||
class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
||||
def __init__(self, *args, **kwargs):
|
||||
xpcshell.XPCShellTestThread.__init__(self, *args, **kwargs)
|
||||
|
@ -129,9 +36,6 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
mobileArgs = kwargs.get("mobileArgs")
|
||||
for key in mobileArgs:
|
||||
setattr(self, key, mobileArgs[key])
|
||||
self.remoteLogFile = posixpath.join(
|
||||
mobileArgs["remoteLogFolder"], "xpcshell-%s.log" % str(uuid.uuid4())
|
||||
)
|
||||
|
||||
def initDir(self, path, mask="777", timeout=None):
|
||||
"""Initialize a directory by removing it if it exists, creating it
|
||||
|
@ -159,12 +63,7 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
remoteName = os.path.basename(name)
|
||||
else:
|
||||
remoteName = posixpath.join(remoteDir, os.path.basename(name))
|
||||
return [
|
||||
"-e",
|
||||
'const _TEST_CWD = "%s";' % self.remoteHere,
|
||||
"-e",
|
||||
'const _TEST_FILE = ["%s"];' % remoteName.replace("\\", "/"),
|
||||
]
|
||||
return ["-e", 'const _TEST_FILE = ["%s"];' % remoteName.replace("\\", "/")]
|
||||
|
||||
def remoteForLocal(self, local):
|
||||
for mapping in self.pathMapping:
|
||||
|
@ -173,11 +72,9 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
return local
|
||||
|
||||
def setupTempDir(self):
|
||||
self.remoteTmpDir = posixpath.join(self.remoteTmpDir, str(uuid.uuid4()))
|
||||
# make sure the temp dir exists
|
||||
self.initDir(self.remoteTmpDir)
|
||||
# env var is set in buildEnvironment
|
||||
self.env["XPCSHELL_TEST_TEMP_DIR"] = self.remoteTmpDir
|
||||
return self.remoteTmpDir
|
||||
|
||||
def setupPluginsDir(self):
|
||||
|
@ -195,24 +92,11 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
return pluginsDir
|
||||
|
||||
def setupProfileDir(self):
|
||||
profileId = str(uuid.uuid4())
|
||||
self.profileDir = posixpath.join(self.profileDir, profileId)
|
||||
self.initDir(self.profileDir)
|
||||
if self.interactive or self.singleFile:
|
||||
self.log.info("profile dir is %s" % self.profileDir)
|
||||
self.env["XPCSHELL_TEST_PROFILE_DIR"] = self.profileDir
|
||||
self.env["TMPDIR"] = self.profileDir
|
||||
self.remoteMinidumpDir = posixpath.join(self.remoteMinidumpRootDir, profileId)
|
||||
self.initDir(self.remoteMinidumpDir)
|
||||
self.env["XPCSHELL_MINIDUMP_DIR"] = self.remoteMinidumpDir
|
||||
return self.profileDir
|
||||
|
||||
def clean_temp_dirs(self, name):
|
||||
self.log.info("Cleaning up profile for %s folder: %s" % (name, self.profileDir))
|
||||
self.device.rm(self.profileDir, force=True, recursive=True)
|
||||
self.device.rm(self.remoteTmpDir, force=True, recursive=True)
|
||||
self.device.rm(self.remoteMinidumpDir, force=True, recursive=True)
|
||||
|
||||
def setupMozinfoJS(self):
|
||||
local = tempfile.mktemp()
|
||||
mozinfo.output_to_file(local)
|
||||
|
@ -264,8 +148,9 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
if self.options["localAPK"]:
|
||||
xpcsCmd.insert(1, "--greomni")
|
||||
xpcsCmd.insert(2, self.remoteAPK)
|
||||
xpcsCmd.insert(1, "-g")
|
||||
xpcsCmd.insert(2, self.remoteBinDir)
|
||||
else:
|
||||
xpcsCmd.insert(1, "-g")
|
||||
xpcsCmd.insert(2, self.remoteBinDir)
|
||||
|
||||
if self.remoteDebugger:
|
||||
# for example, "/data/local/gdbserver" "localhost:12345"
|
||||
|
@ -276,37 +161,31 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
self.kill(proc)
|
||||
|
||||
def launchProcess(self, cmd, stdout, stderr, env, cwd, timeout=None):
|
||||
rpm = RemoteProcessMonitor(
|
||||
"org.mozilla.geckoview.test",
|
||||
self.device,
|
||||
self.log,
|
||||
self.remoteLogFile,
|
||||
)
|
||||
|
||||
startTime = datetime.datetime.now()
|
||||
|
||||
pid = rpm.launch_service(cmd[1:], self.env, self.selectedProcess)
|
||||
|
||||
self.log.info("remotexpcshelltests.py | Launched Test App PID=%s" % str(pid))
|
||||
|
||||
if rpm.wait(timeout):
|
||||
self.shellReturnCode = 0
|
||||
else:
|
||||
self.shellReturnCode = 1
|
||||
self.log.info(
|
||||
"remotexpcshelltests.py | Application ran for: %s"
|
||||
% str(datetime.datetime.now() - startTime)
|
||||
)
|
||||
|
||||
self.timedout = False
|
||||
cmd.insert(1, self.remoteHere)
|
||||
cmd = ADBDevice._escape_command_line(cmd)
|
||||
try:
|
||||
return self.device.get_file(self.remoteLogFile)
|
||||
except mozdevice.ADBTimeoutError:
|
||||
# env is ignored here since the environment has already been
|
||||
# set for the command via the pushWrapper method.
|
||||
adb_process = self.device.shell(cmd, timeout=timeout + 10)
|
||||
output_file = adb_process.stdout_file
|
||||
self.shellReturnCode = adb_process.exitcode
|
||||
except ADBTimeoutError:
|
||||
raise
|
||||
except Exception as e:
|
||||
self.log.info(
|
||||
"remotexpcshelltests.py | Could not read log file: %s" % str(e)
|
||||
)
|
||||
return ""
|
||||
if self.timedout:
|
||||
# If the test timed out, there is a good chance the shell
|
||||
# call also timed out and raised this Exception.
|
||||
# Ignore this exception to simplify the error report.
|
||||
self.shellReturnCode = None
|
||||
else:
|
||||
raise e
|
||||
# The device manager may have timed out waiting for xpcshell.
|
||||
# Guard against an accumulation of hung processes by killing
|
||||
# them here. Note also that IPC tests may spawn new instances
|
||||
# of xpcshell.
|
||||
self.device.pkill("xpcshell")
|
||||
return output_file
|
||||
|
||||
def checkForCrashes(self, dump_directory, symbols_path, test_name=None):
|
||||
with mozfile.TemporaryDirectory() as dumpDir:
|
||||
|
@ -314,10 +193,14 @@ class RemoteXPCShellTestThread(xpcshell.XPCShellTestThread):
|
|||
crashed = mozcrash.log_crashes(
|
||||
self.log, dumpDir, symbols_path, test=test_name
|
||||
)
|
||||
self.initDir(self.remoteMinidumpDir)
|
||||
return crashed
|
||||
|
||||
def communicate(self, proc):
|
||||
return proc, ""
|
||||
f = proc
|
||||
contents = f.read()
|
||||
f.close()
|
||||
return contents, ""
|
||||
|
||||
def poll(self, proc):
|
||||
if not self.device.process_exist("xpcshell"):
|
||||
|
@ -353,8 +236,6 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
def __init__(self, options, log):
|
||||
xpcshell.XPCShellTests.__init__(self, log)
|
||||
|
||||
options["threadCount"] = min(options["threadCount"] or 4, 4)
|
||||
|
||||
self.options = options
|
||||
verbose = False
|
||||
if options["log_tbpl_level"] == "debug" or options["log_mach_level"] == "debug":
|
||||
|
@ -366,7 +247,6 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
verbose=verbose,
|
||||
)
|
||||
self.remoteTestRoot = posixpath.join(self.device.test_root, "xpc")
|
||||
self.remoteLogFolder = posixpath.join(self.remoteTestRoot, "logs")
|
||||
# Add Android version (SDK level) to mozinfo so that manifest entries
|
||||
# can be conditional on android_version.
|
||||
mozinfo.info["android_version"] = str(self.device.version)
|
||||
|
@ -388,21 +268,12 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
self.remoteScriptsDir = self.remoteTestRoot
|
||||
self.remoteComponentsDir = posixpath.join(self.remoteTestRoot, "c")
|
||||
self.remoteModulesDir = posixpath.join(self.remoteTestRoot, "m")
|
||||
self.remoteMinidumpRootDir = posixpath.join(self.remoteTestRoot, "minidumps")
|
||||
self.remoteMinidumpDir = posixpath.join(self.remoteTestRoot, "minidumps")
|
||||
self.profileDir = posixpath.join(self.remoteTestRoot, "p")
|
||||
self.remoteDebugger = options["debugger"]
|
||||
self.remoteDebuggerArgs = options["debuggerArgs"]
|
||||
self.testingModulesDir = options["testingModulesDir"]
|
||||
|
||||
self.initDir(self.remoteTmpDir)
|
||||
self.initDir(self.profileDir)
|
||||
|
||||
# Make sure we get a fresh start
|
||||
self.device.stop_application("org.mozilla.geckoview.test")
|
||||
|
||||
for i in range(options["threadCount"]):
|
||||
RemoteProcessMonitor.processStatus += [False]
|
||||
|
||||
self.env = {}
|
||||
|
||||
if options["objdir"]:
|
||||
|
@ -425,8 +296,7 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
self.setupTestDir()
|
||||
self.setupUtilities()
|
||||
self.setupModules()
|
||||
self.initDir(self.remoteMinidumpRootDir)
|
||||
self.initDir(self.remoteLogFolder)
|
||||
self.initDir(self.remoteMinidumpDir)
|
||||
|
||||
# data that needs to be passed to the RemoteXPCShellTestThread
|
||||
self.mobileArgs = {
|
||||
|
@ -440,9 +310,8 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
"remoteDebuggerArgs": self.remoteDebuggerArgs,
|
||||
"pathMapping": self.pathMapping,
|
||||
"profileDir": self.profileDir,
|
||||
"remoteLogFolder": self.remoteLogFolder,
|
||||
"remoteTmpDir": self.remoteTmpDir,
|
||||
"remoteMinidumpRootDir": self.remoteMinidumpRootDir,
|
||||
"remoteMinidumpDir": self.remoteMinidumpDir,
|
||||
}
|
||||
if self.remoteAPK:
|
||||
self.mobileArgs["remoteAPK"] = self.remoteAPK
|
||||
|
@ -481,20 +350,9 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
self.device.chmod(remoteWrapper)
|
||||
os.remove(localWrapper)
|
||||
|
||||
def start_test(self, test):
|
||||
test.selectedProcess = RemoteProcessMonitor.pickUnusedProcess()
|
||||
if test.selectedProcess == -1:
|
||||
self.log.error(
|
||||
"TEST-UNEXPECTED-FAIL | remotexpcshelltests.py | "
|
||||
"no more free processes"
|
||||
)
|
||||
test.start()
|
||||
|
||||
def test_ended(self, test):
|
||||
RemoteProcessMonitor.freeProcess(test.selectedProcess)
|
||||
|
||||
def buildPrefsFile(self, extraPrefs):
|
||||
prefs = super(XPCShellRemote, self).buildPrefsFile(extraPrefs)
|
||||
|
||||
remotePrefsFile = posixpath.join(self.remoteTestRoot, "user.js")
|
||||
self.device.push(self.prefsFile, remotePrefsFile)
|
||||
self.device.chmod(remotePrefsFile)
|
||||
|
@ -508,9 +366,12 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
self.env["MOZ_LINKER_CACHE"] = self.remoteBinDir
|
||||
self.env["GRE_HOME"] = self.remoteBinDir
|
||||
self.env["XPCSHELL_TEST_PROFILE_DIR"] = self.profileDir
|
||||
self.env["TMPDIR"] = self.remoteTmpDir
|
||||
self.env["HOME"] = self.profileDir
|
||||
self.env["XPCSHELL_TEST_TEMP_DIR"] = self.remoteTmpDir
|
||||
self.env["XPCSHELL_MINIDUMP_DIR"] = self.remoteMinidumpDir
|
||||
self.env["MOZ_ANDROID_DATA_DIR"] = self.remoteBinDir
|
||||
self.env["MOZ_FORCE_DISABLE_E10S"] = "1"
|
||||
|
||||
# Guard against intermittent failures to retrieve abi property;
|
||||
# without an abi, xpcshell cannot find greprefs.js and crashes.
|
||||
|
@ -567,9 +428,11 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
|||
self.device.push(local, remoteFile)
|
||||
self.device.chmod(remoteFile)
|
||||
|
||||
# Additional binaries are required for some tests. This list should be
|
||||
# similar to TEST_HARNESS_BINS in testing/mochitest/Makefile.in.
|
||||
# The xpcshell binary is required for all tests. Additional binaries
|
||||
# are required for some tests. This list should be similar to
|
||||
# TEST_HARNESS_BINS in testing/mochitest/Makefile.in.
|
||||
binaries = [
|
||||
"xpcshell",
|
||||
"ssltunnel",
|
||||
"certutil",
|
||||
"pk12util",
|
||||
|
@ -729,12 +592,11 @@ def main():
|
|||
if options["xpcshell"] is None:
|
||||
options["xpcshell"] = "xpcshell"
|
||||
|
||||
# The threadCount depends on the emulator rather than the host machine and
|
||||
# empirically 10 seems to yield the best performance.
|
||||
options["threadCount"] = min(options["threadCount"], 10)
|
||||
|
||||
xpcsh = XPCShellRemote(options, log)
|
||||
|
||||
# we don't run concurrent tests on mobile
|
||||
options["sequential"] = True
|
||||
|
||||
if not xpcsh.runTests(
|
||||
options, testClass=RemoteXPCShellTestThread, mobileArgs=xpcsh.mobileArgs
|
||||
):
|
||||
|
|
|
@ -1917,12 +1917,6 @@ class XPCShellTests(object):
|
|||
|
||||
return status
|
||||
|
||||
def start_test(self, test):
|
||||
test.start()
|
||||
|
||||
def test_ended(self, test):
|
||||
pass
|
||||
|
||||
def runTestList(
|
||||
self, tests_queue, sequential_tests, testClass, mobileArgs, **kwargs
|
||||
):
|
||||
|
@ -1964,7 +1958,7 @@ class XPCShellTests(object):
|
|||
):
|
||||
test = tests_queue.popleft()
|
||||
running_tests.add(test)
|
||||
self.start_test(test)
|
||||
test.start()
|
||||
|
||||
# queue is full (for now) or no more new tests,
|
||||
# process the finished tests so far
|
||||
|
@ -1977,7 +1971,6 @@ class XPCShellTests(object):
|
|||
done_tests = set()
|
||||
for test in running_tests:
|
||||
if test.done:
|
||||
self.test_ended(test)
|
||||
done_tests.add(test)
|
||||
test.join(
|
||||
1
|
||||
|
@ -2013,9 +2006,8 @@ class XPCShellTests(object):
|
|||
break
|
||||
# we don't want to retry these tests
|
||||
test.retry = False
|
||||
self.start_test(test)
|
||||
test.start()
|
||||
test.join()
|
||||
self.test_ended(test)
|
||||
self.addTestResults(test)
|
||||
# did the test encounter any exception?
|
||||
if test.exception:
|
||||
|
@ -2035,9 +2027,8 @@ class XPCShellTests(object):
|
|||
mobileArgs=mobileArgs,
|
||||
**kwargs
|
||||
)
|
||||
self.start_test(test)
|
||||
test.start()
|
||||
test.join()
|
||||
self.test_ended(test)
|
||||
self.addTestResults(test)
|
||||
# did the test encounter any exception?
|
||||
if test.exception:
|
||||
|
|
|
@ -366,14 +366,6 @@ def add_remote_arguments(parser):
|
|||
help="Do not copy any files to device (to be used only if "
|
||||
"device is already setup).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-install",
|
||||
action="store_false",
|
||||
dest="setup",
|
||||
default=True,
|
||||
help="Don't install the app or any files to the device (to be used if "
|
||||
"the device is already set up)",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--local-bin-dir",
|
||||
|
|
|
@ -5,14 +5,19 @@ head = head.js ../../../../components/url-classifier/tests/unit/head_urlclassifi
|
|||
[test_purge_trackers.js]
|
||||
[test_purge_trackers_telemetry.js]
|
||||
[test_tracking_db_service.js]
|
||||
skip-if = toolkit == "android" # Bug 1697936
|
||||
[test_rejectForeignAllowList.js]
|
||||
skip-if = toolkit == 'android' # Bug 1567341
|
||||
[test_staticPartition_font.js]
|
||||
support-files =
|
||||
data/font.woff
|
||||
skip-if = toolkit == 'android' # Bug 1567341
|
||||
[test_staticPartition_image.js]
|
||||
skip-if = toolkit == 'android' # Bug 1567341
|
||||
[test_staticPartition_authhttp.js]
|
||||
skip-if = toolkit == 'android' # Bug 1567341
|
||||
[test_staticPartition_prefetch.js]
|
||||
skip-if = toolkit == 'android' # Bug 1567341
|
||||
[test_staticPartition_preload.js]
|
||||
skip-if = toolkit == 'android' # Bug 1567341
|
||||
[test_ExceptionListService.js]
|
||||
[test_view_source.js]
|
||||
|
|
|
@ -15,7 +15,6 @@ skip-if = os == 'android' # Bug 1545439
|
|||
[test_ext_alarms_replaces.js]
|
||||
[test_ext_api_permissions.js]
|
||||
[test_ext_background_api_injection.js]
|
||||
skip-if = os == "android" # Bug 1700482
|
||||
[test_ext_background_early_shutdown.js]
|
||||
[test_ext_background_generated_load_events.js]
|
||||
[test_ext_background_generated_reload.js]
|
||||
|
@ -43,7 +42,7 @@ run-sequentially = node server exceptions dont replay well
|
|||
skip-if = appname == "thunderbird" || os == "android" || (os == "mac" && debug) # CP service is disabled on Android, macosx1014/debug due to 1564534
|
||||
run-sequentially = node server exceptions dont replay well
|
||||
[test_ext_cookieBehaviors.js]
|
||||
skip-if = appname == "thunderbird" || tsan || os == "android" # Bug 1683730, Android: Bug 1700482
|
||||
skip-if = appname == "thunderbird" || tsan # Bug 1683730
|
||||
[test_ext_cookies_firstParty.js]
|
||||
skip-if = appname == "thunderbird" || os == "android" || tsan # Android: Bug 1680132. tsan: Bug 1683730
|
||||
[test_ext_cookies_samesite.js]
|
||||
|
@ -62,7 +61,6 @@ skip-if = tsan # Bug 1683730
|
|||
[test_ext_contentscript_css.js]
|
||||
[test_ext_contentscript_exporthelpers.js]
|
||||
[test_ext_contentscript_in_background.js]
|
||||
skip-if = os == "android" # Bug 1700482
|
||||
[test_ext_contentscript_module_import.js]
|
||||
[test_ext_contentscript_restrictSchemes.js]
|
||||
[test_ext_contentscript_teardown.js]
|
||||
|
@ -159,7 +157,6 @@ skip-if = ccov && os == 'linux' # bug 1607581
|
|||
[test_ext_runtime_sendMessage_no_receiver.js]
|
||||
[test_ext_same_site_cookies.js]
|
||||
[test_ext_same_site_redirects.js]
|
||||
skip-if = os == "android" # Android: Bug 1700482
|
||||
[test_ext_sandbox_var.js]
|
||||
[test_ext_schema.js]
|
||||
skip-if = os == "android" # Android: Bug 1680132
|
||||
|
@ -172,7 +169,6 @@ skip-if = os == "android" # Android: Bug 1680132
|
|||
skip-if = os == "android"
|
||||
[test_ext_startup_perf.js]
|
||||
[test_ext_startup_request_handler.js]
|
||||
skip-if = os == "android" # Bug 1700482
|
||||
[test_ext_storage_local.js]
|
||||
skip-if = os == "android" && debug
|
||||
[test_ext_storage_idb_data_migration.js]
|
||||
|
@ -208,10 +204,8 @@ skip-if = os == 'android' # Bug 1258975 on android.
|
|||
[test_ext_unload_frame.js]
|
||||
skip-if = true # Too frequent intermittent failures
|
||||
[test_ext_userScripts.js]
|
||||
skip-if = os == "android" # Bug 1700482
|
||||
[test_ext_userScripts_exports.js]
|
||||
[test_ext_userScripts_telemetry.js]
|
||||
skip-if = os == "android" # Bug 1700482
|
||||
[test_ext_webRequest_auth.js]
|
||||
skip-if = os == "android" && debug
|
||||
[test_ext_webRequest_cached.js]
|
||||
|
|
|
@ -73,9 +73,8 @@ class BootstrapImpl final : public Bootstrap {
|
|||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
virtual void GeckoStart(JNIEnv* aEnv, char** argv, int argc,
|
||||
const StaticXREAppData& aAppData,
|
||||
bool xpcshell, const char* outFilePath) override {
|
||||
::GeckoStart(aEnv, argv, argc, aAppData, xpcshell, outFilePath);
|
||||
const StaticXREAppData& aAppData) override {
|
||||
::GeckoStart(aEnv, argv, argc, aAppData);
|
||||
}
|
||||
|
||||
virtual void XRE_SetAndroidChildFds(
|
||||
|
|
|
@ -28,8 +28,7 @@ struct StaticXREAppData;
|
|||
}
|
||||
|
||||
extern "C" NS_EXPORT void GeckoStart(JNIEnv* aEnv, char** argv, int argc,
|
||||
const mozilla::StaticXREAppData& aAppData,
|
||||
bool xpcshell, const char* outFilePath);
|
||||
const mozilla::StaticXREAppData& aAppData);
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
|
@ -121,8 +120,7 @@ class Bootstrap {
|
|||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
virtual void GeckoStart(JNIEnv* aEnv, char** argv, int argc,
|
||||
const StaticXREAppData& aAppData, bool xpcshell,
|
||||
const char* outFilePath) = 0;
|
||||
const StaticXREAppData& aAppData) = 0;
|
||||
|
||||
virtual void XRE_SetAndroidChildFds(JNIEnv* aEnv,
|
||||
const XRE_AndroidChildFds& fds) = 0;
|
||||
|
|
|
@ -17,15 +17,13 @@
|
|||
#include "nsAppRunner.h"
|
||||
#include "nsExceptionHandler.h"
|
||||
#include "mozilla/Bootstrap.h"
|
||||
#include "XREShellData.h"
|
||||
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, MOZ_APP_NAME, args)
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
extern "C" NS_EXPORT void GeckoStart(JNIEnv* env, char** argv, int argc,
|
||||
const StaticXREAppData& aAppData,
|
||||
bool xpcshell, const char* outFilePath) {
|
||||
const StaticXREAppData& aAppData) {
|
||||
mozilla::jni::SetGeckoThreadEnv(env);
|
||||
|
||||
if (!argv) {
|
||||
|
@ -33,26 +31,11 @@ extern "C" NS_EXPORT void GeckoStart(JNIEnv* env, char** argv, int argc,
|
|||
return;
|
||||
}
|
||||
|
||||
if (xpcshell) {
|
||||
XREShellData shellData;
|
||||
FILE* outFile = fopen(outFilePath, "w");
|
||||
if (!outFile) {
|
||||
LOG("XRE_XPCShellMain cannot open %s", outFilePath);
|
||||
return;
|
||||
}
|
||||
// We redirect both stdout and stderr to the same file, to conform with
|
||||
// what runxpcshell.py does on Desktop.
|
||||
shellData.outFile = outFile;
|
||||
shellData.errFile = outFile;
|
||||
int result = XRE_XPCShellMain(argc, argv, nullptr, &shellData);
|
||||
fclose(shellData.outFile);
|
||||
if (result) LOG("XRE_XPCShellMain returned %d", result);
|
||||
} else {
|
||||
BootstrapConfig config;
|
||||
config.appData = &aAppData;
|
||||
config.appDataPath = nullptr;
|
||||
BootstrapConfig config;
|
||||
config.appData = &aAppData;
|
||||
config.appDataPath = nullptr;
|
||||
|
||||
int result = XRE_main(argc, argv, config);
|
||||
if (result) LOG("XRE_main returned %d", result);
|
||||
}
|
||||
int result = XRE_main(argc, argv, config);
|
||||
|
||||
if (result) LOG("XRE_main returned %d", result);
|
||||
}
|
||||
|
|
|
@ -949,13 +949,9 @@ void EventDispatcher::Attach(java::EventDispatcher::Param aDispatcher,
|
|||
dispatcher->SetAttachedToGecko(java::EventDispatcher::ATTACHED);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
EventDispatcher::Shutdown() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
void EventDispatcher::Shutdown() {
|
||||
mDispatcher = nullptr;
|
||||
mDOMWindow = nullptr;
|
||||
mListenersMap.Clear();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void EventDispatcher::Detach() {
|
||||
|
|
|
@ -65,7 +65,7 @@ class EventDispatcher final
|
|||
|
||||
virtual ~EventDispatcher() {}
|
||||
|
||||
void ShutdownFromJava() { Shutdown(); }
|
||||
void Shutdown();
|
||||
|
||||
struct ListenersList {
|
||||
nsCOMArray<nsIAndroidEventListener> listeners{/* count */ 1};
|
||||
|
|
|
@ -483,6 +483,7 @@ nsresult nsAppShell::Init() {
|
|||
obsServ->AddObserver(this, "profile-after-change", false);
|
||||
obsServ->AddObserver(this, "quit-application", false);
|
||||
obsServ->AddObserver(this, "quit-application-granted", false);
|
||||
obsServ->AddObserver(this, "xpcom-shutdown", false);
|
||||
|
||||
if (XRE_IsParentProcess()) {
|
||||
obsServ->AddObserver(this, "chrome-document-loaded", false);
|
||||
|
@ -498,26 +499,24 @@ nsresult nsAppShell::Init() {
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAppShell::Exit(void) {
|
||||
{
|
||||
// Release any thread waiting for a sync call to finish.
|
||||
mozilla::MutexAutoLock shellLock(*sAppShellLock);
|
||||
mSyncRunQuit = true;
|
||||
mSyncRunFinished.NotifyAll();
|
||||
}
|
||||
// We need to ensure no observers stick around after XPCOM shuts down
|
||||
// or we'll see crashes, as the app shell outlives XPConnect.
|
||||
mObserversHash.Clear();
|
||||
return nsBaseAppShell::Exit();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAppShell::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData) {
|
||||
bool removeObserver = false;
|
||||
|
||||
if (!strcmp(aTopic, "browser-delayed-startup-finished")) {
|
||||
if (!strcmp(aTopic, "xpcom-shutdown")) {
|
||||
{
|
||||
// Release any thread waiting for a sync call to finish.
|
||||
mozilla::MutexAutoLock shellLock(*sAppShellLock);
|
||||
mSyncRunQuit = true;
|
||||
mSyncRunFinished.NotifyAll();
|
||||
}
|
||||
// We need to ensure no observers stick around after XPCOM shuts down
|
||||
// or we'll see crashes, as the app shell outlives XPConnect.
|
||||
mObserversHash.Clear();
|
||||
return nsBaseAppShell::Observe(aSubject, aTopic, aData);
|
||||
|
||||
} else if (!strcmp(aTopic, "browser-delayed-startup-finished")) {
|
||||
NS_CreateServicesFromCategory("browser-delayed-startup-finished", nullptr,
|
||||
"browser-delayed-startup-finished");
|
||||
} else if (!strcmp(aTopic, "geckoview-startup-complete")) {
|
||||
|
@ -596,8 +595,6 @@ nsAppShell::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aSubject);
|
||||
widget::GeckoEditableSupport::SetOnBrowserChild(
|
||||
dom::BrowserChild::GetFrom(docShell));
|
||||
} else {
|
||||
return nsBaseAppShell::Observe(aSubject, aTopic, aData);
|
||||
}
|
||||
|
||||
if (removeObserver) {
|
||||
|
|
|
@ -145,7 +145,6 @@ class nsAppShell : public nsBaseAppShell {
|
|||
|
||||
virtual ~nsAppShell();
|
||||
|
||||
NS_IMETHOD Exit() override;
|
||||
nsresult AddObserver(const nsAString& aObserverKey, nsIObserver* aObserver);
|
||||
|
||||
class NativeCallbackEvent : public Event {
|
||||
|
|
|
@ -43,7 +43,6 @@ interface nsIAndroidEventDispatcher : nsISupports
|
|||
[implicit_jscontext]
|
||||
void unregisterListener(in nsIAndroidEventListener listener,
|
||||
in jsval events);
|
||||
void shutdown();
|
||||
};
|
||||
|
||||
[scriptable, uuid(60a78a94-6117-432f-9d49-304913a931c5)]
|
||||
|
|
|
@ -23,10 +23,6 @@ struct XREShellData {
|
|||
*/
|
||||
sandbox::BrokerServices* sandboxBrokerServices;
|
||||
#endif
|
||||
#if defined(ANDROID)
|
||||
FILE* outFile;
|
||||
FILE* errFile;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // XREShellData_h
|
||||
|
|
Загрузка…
Ссылка в новой задаче