Bug 1235869 - Remove web runtime from android. r=myk
authorBrendan Dahl <bdahl@mozilla.com>
Mon, 29 Feb 2016 10:31:00 +0100
changeset 309197 93156962855dcdc9448fcc87f2cb337483e96f20
parent 309196 b0f74770edc6172dd4eb67a009fcac8b914197a8
child 309198 89e36be196d9dfbd5e37bb8a17fe461d825d090e
push id9214
push userraliiev@mozilla.com
push dateMon, 07 Mar 2016 14:25:21 +0000
treeherdermozilla-aurora@8849dd1a4a79 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmyk
bugs1235869
milestone47.0a1
Bug 1235869 - Remove web runtime from android. r=myk
.eslintignore
layout/reftests/font-face/reftest.list
layout/reftests/writing-mode/reftest.list
mobile/android/.eslintrc
mobile/android/app/mobile.js
mobile/android/base/AndroidManifest.xml.in
mobile/android/base/WebappFragmentRepeater.inc
mobile/android/base/WebappManifestFragment.xml.frag.in
mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java
mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
mobile/android/base/java/org/mozilla/gecko/GeckoProfile.java
mobile/android/base/java/org/mozilla/gecko/Webapp.java
mobile/android/base/java/org/mozilla/gecko/webapp/Allocator.java
mobile/android/base/java/org/mozilla/gecko/webapp/ApkResources.java
mobile/android/base/java/org/mozilla/gecko/webapp/Dispatcher.java
mobile/android/base/java/org/mozilla/gecko/webapp/EventListener.java
mobile/android/base/java/org/mozilla/gecko/webapp/InstallHelper.java
mobile/android/base/java/org/mozilla/gecko/webapp/InstallListener.java
mobile/android/base/java/org/mozilla/gecko/webapp/TaskKiller.java
mobile/android/base/java/org/mozilla/gecko/webapp/UninstallListener.java
mobile/android/base/java/org/mozilla/gecko/webapp/WebappImpl.java
mobile/android/base/java/org/mozilla/gecko/webapp/Webapps.java
mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedEditText.java
mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedFrameLayout.java
mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedImageButton.java
mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedImageView.java
mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedLinearLayout.java
mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedRelativeLayout.java
mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedTextSwitcher.java
mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedTextView.java
mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedView.java
mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedView.java.frag
mobile/android/base/locales/en-US/android_strings.dtd
mobile/android/base/moz.build
mobile/android/base/resources/layout/shared_ui_components.xml
mobile/android/base/resources/layout/web_app.xml
mobile/android/base/strings.xml.in
mobile/android/chrome/content/WebappRT.js
mobile/android/chrome/content/browser.js
mobile/android/chrome/jar.mn
mobile/android/components/MobileComponents.manifest
mobile/android/components/WebappsUpdateTimer.js
mobile/android/components/moz.build
mobile/android/installer/package-manifest.in
mobile/android/locales/en-US/chrome/webapp.properties
mobile/android/locales/jar.mn
mobile/android/modules/WebappManager.jsm
mobile/android/modules/WebappManagerWorker.js
mobile/android/modules/moz.build
--- a/.eslintignore
+++ b/.eslintignore
@@ -146,20 +146,16 @@ mobile/android/chrome/content/about.js
 
 # Not much JS to lint and non-standard at that
 mobile/android/installer/
 mobile/android/locales/
 
 # Pretty sure we're disabling this one anyway
 mobile/android/modules/ContactService.jsm
 
-# es7 proposed: array comprehensions
-#   https://github.com/eslint/espree/issues/125
-mobile/android/modules/WebappManager.jsm
-
 # Non-standard `(catch ex if ...)`
 mobile/android/components/Snippets.js
 
 # Bug 1178739: Ignore this file as a quick fix for "Illegal yield expression"
 mobile/android/modules/HomeProvider.jsm
 
 # services/ exclusions
 
--- a/layout/reftests/font-face/reftest.list
+++ b/layout/reftests/font-face/reftest.list
@@ -137,18 +137,18 @@ fails-if(cocoaWidget) fails-if(winWidget
 
 HTTP(..) != 534352-1-extra-cmap-sentinel.html 534352-1-extra-cmap-sentinel-ref.html
 HTTP(..) == bug533251.html bug533251-ref.html
 
 # Bug 875287
 HTTP(..) == font-familiy-whitespace-1.html font-familiy-whitespace-1-ref.html
 HTTP(..) != font-familiy-whitespace-1.html font-familiy-whitespace-1-notref.html
 
-skip-if(B2G||Mulet) HTTP(..) == ivs-1.html ivs-1-ref.html # bug 773482 # Initial mulet triage: parity with B2G/B2G Desktop
-skip-if(B2G||Mulet) HTTP(..) == cjkcisvs-1.html cjkcisvs-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
+skip-if(B2G||Mulet||Android) HTTP(..) == ivs-1.html ivs-1-ref.html # bug 773482 # Initial mulet triage: parity with B2G/B2G Desktop # Android bug 1250229
+skip-if(B2G||Mulet||Android) HTTP(..) == cjkcisvs-1.html cjkcisvs-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop # Android bug 1250229
 
 skip-if(B2G||Mulet) HTTP(..) == missing-names.html missing-names-ref.html # bug 773482 # Initial mulet triage: parity with B2G/B2G Desktop
 
 # Tests for bug 670900 - handling of 404 (not found) error in @font-face URL
 # (using Chunkfive font data returned from a .sjs file)
 HTTP(..) == font-error-404-1.html font-error-404-1-ref.html # HTTP status 404, don't load
 skip-if(B2G||Mulet) HTTP(..) == font-error-404-2.html font-error-404-2-ref.html # HTTP status 200, load # bug 773482 # Initial mulet triage: parity with B2G/B2G Desktop
 HTTP(..) != font-error-404-1.html font-error-404-2.html # sanity-check that the results differ
--- a/layout/reftests/writing-mode/reftest.list
+++ b/layout/reftests/writing-mode/reftest.list
@@ -164,16 +164,16 @@ fuzzy-if(gtkWidget||B2G,255,6) fuzzy-if(
 == 1196887-1-computed-display-inline-block.html 1196887-1-computed-display-inline-block-ref.html
 == 1205787-legacy-svg-values-1.html 1205787-legacy-svg-values-1-ref.html
 
 == 1216747-1.html 1216747-1-ref.html
 != 1216747-1.html 1216747-1-notref.html
 
 == 1243125-1-floats-overflowing.html 1243125-1-floats-overflowing-ref.html
 
-HTTP(..) == 1248248-1-orientation-break-glyphrun.html 1248248-1-orientation-break-glyphrun-ref.html
+skip-if(Android) HTTP(..) == 1248248-1-orientation-break-glyphrun.html 1248248-1-orientation-break-glyphrun-ref.html # Android bug 1250229
 
 # Suite of tests from Gérard Talbot in bug 1079151
 # Frequent Windows 7 load failed: timed out waiting for test to complete (waiting for onload scripts to complete), bug 1167155 and friends
 skip-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) include abspos/reftest.list
 
 # Tests for tables with vertical writing modes
 include tables/reftest.list
--- a/mobile/android/.eslintrc
+++ b/mobile/android/.eslintrc
@@ -22,17 +22,16 @@ globals:
     Services: false
     SharedPreferences: false
     strings: false
     Strings: false
     Task: false
     TelemetryStopwatch: false
     UITelemetry: false
     UserAgentOverrides: 0
-    WebappManager: false
     XPCOMUtils: false
     ctypes: false
     dump: false
     exports: false
     importScripts: false
     module: false
     require: false
     uuidgen: false
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -860,40 +860,16 @@ pref("browser.snippets.geoUrl", "https:/
 // URL used to ping metrics with stats about which snippets have been shown
 pref("browser.snippets.statsUrl", "https://snippets-stats.mozilla.org/mobile");
 
 // These prefs require a restart to take effect.
 pref("browser.snippets.enabled", true);
 pref("browser.snippets.syncPromo.enabled", true);
 pref("browser.snippets.firstrunHomepage.enabled", true);
 
-// The URL of the APK factory from which we obtain APKs for webapps.
-pref("browser.webapps.apkFactoryUrl", "https://controller.apk.firefox.com/application.apk");
-
-// How frequently to check for webapp updates, in seconds (86400 is daily).
-pref("browser.webapps.updateInterval", 86400);
-
-// Whether or not to check for updates.  Enabled by default, but the runtime
-// disables it for webapp profiles on firstrun, so only the main Fennec process
-// checks for updates (to avoid duplicate update notifications).
-//
-// In the future, we might want to make each webapp process check for updates
-// for its own webapp, in which case we'll need to have a third state for this
-// preference.  Thus it's an integer rather than a boolean.
-//
-// Possible values:
-//   0: don't check for updates
-//   1: do check for updates
-pref("browser.webapps.checkForUpdates", 1);
-
-// The URL of the service that checks for updates.
-// To test updates, set this to http://apk-update-checker.paas.allizom.org,
-// which is a test server that always reports all apps as having updates.
-pref("browser.webapps.updateCheckUrl", "https://controller.apk.firefox.com/app_updates");
-
 // The mode of home provider syncing.
 // 0: Sync always
 // 1: Sync only when on wifi
 pref("home.sync.updateMode", 0);
 
 // How frequently to check if we should sync home provider data.
 pref("home.sync.checkIntervalSecs", 3600);
 
--- a/mobile/android/base/AndroidManifest.xml.in
+++ b/mobile/android/base/AndroidManifest.xml.in
@@ -179,54 +179,22 @@
                 <data android:scheme="http" />
                 <data android:scheme="https" />
                 <data android:mimeType="text/html"/>
                 <data android:mimeType="text/plain"/>
                 <data android:mimeType="application/xhtml+xml"/>
             </intent-filter>
         </activity>
 
-        <activity android:name="org.mozilla.gecko.webapp.Dispatcher"
-            android:noHistory="true" >
-            <intent-filter>
-                <!-- catch links from synthetic apks -->
-                <action android:name="android.intent.action.VIEW" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <data android:mimeType="application/webapp" />
-            </intent-filter>
-        </activity>
-
-        <receiver android:name="org.mozilla.gecko.webapp.UninstallListener" >
-          <intent-filter>
-             <action android:name="android.intent.action.PACKAGE_REMOVED" />
-             <data android:scheme="package" />
-          </intent-filter>
-        </receiver>
-
-        <receiver android:name="org.mozilla.gecko.webapp.TaskKiller">
-          <intent-filter>
-             <action android:name="org.mozilla.webapp.TASK_REMOVED" />
-             <category android:name="android.intent.category.DEFAULT" />
-          </intent-filter>
-        </receiver>
-
         <receiver android:name="org.mozilla.gecko.restrictions.RestrictionProvider">
           <intent-filter>
             <action android:name="android.intent.action.GET_RESTRICTION_ENTRIES" />
           </intent-filter>
         </receiver>
 
-        <!-- Declare a predefined number of Webapp<num> activities. These are
-             used so that each web app can launch in its own process. Keep
-             this number in sync with the total number of web apps handled in
-             WebappAllocator. -->
-
-#define FRAGMENT WebappManifestFragment.xml.frag.in
-#include WebappFragmentRepeater.inc
-
         <!-- Masquerade as the Resolver so that we can be opened from the Marketplace. -->
         <activity-alias
             android:name="com.android.internal.app.ResolverActivity"
             android:targetActivity="@MOZ_ANDROID_BROWSER_INTENT_CLASS@"
             android:exported="true" />
 
         <receiver android:name="org.mozilla.gecko.GeckoUpdateReceiver">
             <intent-filter>
deleted file mode 100644
--- a/mobile/android/base/WebappFragmentRepeater.inc
+++ /dev/null
@@ -1,301 +0,0 @@
-#define APPNUM 0
-#include @FRAGMENT@
-
-#define APPNUM 1
-#include @FRAGMENT@
-
-#define APPNUM 2
-#include @FRAGMENT@
-
-#define APPNUM 3
-#include @FRAGMENT@
-
-#define APPNUM 4
-#include @FRAGMENT@
-
-#define APPNUM 5
-#include @FRAGMENT@
-
-#define APPNUM 6
-#include @FRAGMENT@
-
-#define APPNUM 7
-#include @FRAGMENT@
-
-#define APPNUM 8
-#include @FRAGMENT@
-
-#define APPNUM 9
-#include @FRAGMENT@
-
-#define APPNUM 10
-#include @FRAGMENT@
-
-#define APPNUM 11
-#include @FRAGMENT@
-
-#define APPNUM 12
-#include @FRAGMENT@
-
-#define APPNUM 13
-#include @FRAGMENT@
-
-#define APPNUM 14
-#include @FRAGMENT@
-
-#define APPNUM 15
-#include @FRAGMENT@
-
-#define APPNUM 16
-#include @FRAGMENT@
-
-#define APPNUM 17
-#include @FRAGMENT@
-
-#define APPNUM 18
-#include @FRAGMENT@
-
-#define APPNUM 19
-#include @FRAGMENT@
-
-#define APPNUM 20
-#include @FRAGMENT@
-
-#define APPNUM 21
-#include @FRAGMENT@
-
-#define APPNUM 22
-#include @FRAGMENT@
-
-#define APPNUM 23
-#include @FRAGMENT@
-
-#define APPNUM 24
-#include @FRAGMENT@
-
-#define APPNUM 25
-#include @FRAGMENT@
-
-#define APPNUM 26
-#include @FRAGMENT@
-
-#define APPNUM 27
-#include @FRAGMENT@
-
-#define APPNUM 28
-#include @FRAGMENT@
-
-#define APPNUM 29
-#include @FRAGMENT@
-
-#define APPNUM 30
-#include @FRAGMENT@
-
-#define APPNUM 31
-#include @FRAGMENT@
-
-#define APPNUM 32
-#include @FRAGMENT@
-
-#define APPNUM 33
-#include @FRAGMENT@
-
-#define APPNUM 34
-#include @FRAGMENT@
-
-#define APPNUM 35
-#include @FRAGMENT@
-
-#define APPNUM 36
-#include @FRAGMENT@
-
-#define APPNUM 37
-#include @FRAGMENT@
-
-#define APPNUM 38
-#include @FRAGMENT@
-
-#define APPNUM 39
-#include @FRAGMENT@
-
-#define APPNUM 40
-#include @FRAGMENT@
-
-#define APPNUM 41
-#include @FRAGMENT@
-
-#define APPNUM 42
-#include @FRAGMENT@
-
-#define APPNUM 43
-#include @FRAGMENT@
-
-#define APPNUM 44
-#include @FRAGMENT@
-
-#define APPNUM 45
-#include @FRAGMENT@
-
-#define APPNUM 46
-#include @FRAGMENT@
-
-#define APPNUM 47
-#include @FRAGMENT@
-
-#define APPNUM 48
-#include @FRAGMENT@
-
-#define APPNUM 49
-#include @FRAGMENT@
-
-#define APPNUM 50
-#include @FRAGMENT@
-
-#define APPNUM 51
-#include @FRAGMENT@
-
-#define APPNUM 52
-#include @FRAGMENT@
-
-#define APPNUM 53
-#include @FRAGMENT@
-
-#define APPNUM 54
-#include @FRAGMENT@
-
-#define APPNUM 55
-#include @FRAGMENT@
-
-#define APPNUM 56
-#include @FRAGMENT@
-
-#define APPNUM 57
-#include @FRAGMENT@
-
-#define APPNUM 58
-#include @FRAGMENT@
-
-#define APPNUM 59
-#include @FRAGMENT@
-
-#define APPNUM 60
-#include @FRAGMENT@
-
-#define APPNUM 61
-#include @FRAGMENT@
-
-#define APPNUM 62
-#include @FRAGMENT@
-
-#define APPNUM 63
-#include @FRAGMENT@
-
-#define APPNUM 64
-#include @FRAGMENT@
-
-#define APPNUM 65
-#include @FRAGMENT@
-
-#define APPNUM 66
-#include @FRAGMENT@
-
-#define APPNUM 67
-#include @FRAGMENT@
-
-#define APPNUM 68
-#include @FRAGMENT@
-
-#define APPNUM 69
-#include @FRAGMENT@
-
-#define APPNUM 70
-#include @FRAGMENT@
-
-#define APPNUM 71
-#include @FRAGMENT@
-
-#define APPNUM 72
-#include @FRAGMENT@
-
-#define APPNUM 73
-#include @FRAGMENT@
-
-#define APPNUM 74
-#include @FRAGMENT@
-
-#define APPNUM 75
-#include @FRAGMENT@
-
-#define APPNUM 76
-#include @FRAGMENT@
-
-#define APPNUM 77
-#include @FRAGMENT@
-
-#define APPNUM 78
-#include @FRAGMENT@
-
-#define APPNUM 79
-#include @FRAGMENT@
-
-#define APPNUM 80
-#include @FRAGMENT@
-
-#define APPNUM 81
-#include @FRAGMENT@
-
-#define APPNUM 82
-#include @FRAGMENT@
-
-#define APPNUM 83
-#include @FRAGMENT@
-
-#define APPNUM 84
-#include @FRAGMENT@
-
-#define APPNUM 85
-#include @FRAGMENT@
-
-#define APPNUM 86
-#include @FRAGMENT@
-
-#define APPNUM 87
-#include @FRAGMENT@
-
-#define APPNUM 88
-#include @FRAGMENT@
-
-#define APPNUM 89
-#include @FRAGMENT@
-
-#define APPNUM 90
-#include @FRAGMENT@
-
-#define APPNUM 91
-#include @FRAGMENT@
-
-#define APPNUM 92
-#include @FRAGMENT@
-
-#define APPNUM 93
-#include @FRAGMENT@
-
-#define APPNUM 94
-#include @FRAGMENT@
-
-#define APPNUM 95
-#include @FRAGMENT@
-
-#define APPNUM 96
-#include @FRAGMENT@
-
-#define APPNUM 97
-#include @FRAGMENT@
-
-#define APPNUM 98
-#include @FRAGMENT@
-
-#define APPNUM 99
-#include @FRAGMENT@
-#undef APPNUM
-#undef FRAGMENT
deleted file mode 100644
--- a/mobile/android/base/WebappManifestFragment.xml.frag.in
+++ /dev/null
@@ -1,9 +0,0 @@
-        <activity android:name="org.mozilla.gecko.webapp.Webapps$Webapp@APPNUM@"
-                  android:label="@string/webapp_generic_name"
-                  android:configChanges="keyboard|keyboardHidden|mcc|mnc|orientation|screenSize"
-                  android:windowSoftInputMode="stateUnspecified|adjustResize"
-                  android:process=":@ANDROID_PACKAGE_NAME@.Webapp@APPNUM@"
-                  android:theme="@style/Gecko.App"
-                  android:launchMode="singleTop"
-                  android:exported="true"
-        />
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -674,16 +674,17 @@ public class BrowserApp extends GeckoApp
         }
 
         setBrowserToolbarListeners();
 
         mFindInPageBar = (FindInPageBar) findViewById(R.id.find_in_page);
         mMediaCastingBar = (MediaCastingBar) findViewById(R.id.media_casting);
 
         EventDispatcher.getInstance().registerGeckoThreadListener((GeckoEventListener)this,
+            "Gecko:DelayedStartup",
             "Menu:Open",
             "Menu:Update",
             "LightweightTheme:Update",
             "Search:Keyword",
             "Prompt:ShowTop");
 
         EventDispatcher.getInstance().registerGeckoThreadListener((NativeEventListener)this,
             "CharEncoding:Data",
@@ -1385,16 +1386,17 @@ public class BrowserApp extends GeckoApp
             mAccountsHelper = null;
         }
 
         if (mZoomedView != null) {
             mZoomedView.destroy();
         }
 
         EventDispatcher.getInstance().unregisterGeckoThreadListener((GeckoEventListener) this,
+            "Gecko:DelayedStartup",
             "Menu:Open",
             "Menu:Update",
             "LightweightTheme:Update",
             "Search:Keyword",
             "Prompt:ShowTop");
 
         EventDispatcher.getInstance().unregisterGeckoThreadListener((NativeEventListener) this,
             "CharEncoding:Data",
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -38,18 +38,16 @@ import org.mozilla.gecko.util.EventCallb
 import org.mozilla.gecko.util.FileUtils;
 import org.mozilla.gecko.util.GeckoEventListener;
 import org.mozilla.gecko.util.GeckoRequest;
 import org.mozilla.gecko.util.HardwareUtils;
 import org.mozilla.gecko.util.NativeEventListener;
 import org.mozilla.gecko.util.NativeJSObject;
 import org.mozilla.gecko.util.PrefUtils;
 import org.mozilla.gecko.util.ThreadUtils;
-import org.mozilla.gecko.webapp.EventListener;
-import org.mozilla.gecko.webapp.UninstallListener;
 import org.mozilla.gecko.widget.ButtonToast;
 
 import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -139,17 +137,16 @@ public abstract class GeckoApp
 
     private static final String LOGTAG = "GeckoApp";
     private static final int ONE_DAY_MS = 1000*60*60*24;
 
     public enum StartupAction {
         NORMAL,     /* normal application start */
         URL,        /* launched with a passed URL */
         PREFETCH,   /* launched with a passed URL that we prefetch */
-        WEBAPP,     /* launched as a webapp runtime */
         GUEST,      /* launched in guest browsing */
         RESTRICTED, /* launched with restricted profile */
         SHORTCUT    /* launched from a homescreen shortcut */
     }
 
     public static final String ACTION_ALERT_CALLBACK       = "org.mozilla.gecko.ACTION_ALERT_CALLBACK";
     public static final String ACTION_HOMESCREEN_SHORTCUT  = "org.mozilla.gecko.BOOKMARK";
     public static final String ACTION_DEBUG                = "org.mozilla.gecko.DEBUG";
@@ -209,18 +206,16 @@ public abstract class GeckoApp
     private Telemetry.Timer mJavaUiStartupTimer;
     private Telemetry.Timer mGeckoReadyStartupTimer;
 
     private String mPrivateBrowsingSession;
 
     private volatile HealthRecorder mHealthRecorder;
     private volatile Locale mLastLocale;
 
-    private EventListener mWebappEventListener;
-
     private Intent mRestartIntent;
 
     abstract public int getLayout();
 
     abstract protected String getDefaultProfileName() throws NoMozillaDirectoryException;
 
     protected void processTabQueue() {};
 
@@ -686,19 +681,17 @@ public abstract class GeckoApp
                            }
                        });
         }
     }
 
     @Override
     public void handleMessage(String event, JSONObject message) {
         try {
-            if (event.equals("Gecko:DelayedStartup")) {
-                ThreadUtils.postToBackgroundThread(new UninstallListener.DelayedStartupTask(this));
-            } else if (event.equals("Gecko:Ready")) {
+            if (event.equals("Gecko:Ready")) {
                 mGeckoReadyStartupTimer.stop();
                 geckoConnected();
 
                 // This method is already running on the background thread, so we
                 // know that mHealthRecorder will exist. That doesn't stop us being
                 // paranoid.
                 // This method is cheap, so don't spawn a new runnable.
                 final HealthRecorder rec = mHealthRecorder;
@@ -706,20 +699,16 @@ public abstract class GeckoApp
                   rec.recordGeckoStartupTime(mGeckoReadyStartupTimer.getElapsed());
                 }
 
             } else if (event.equals("Gecko:Exited")) {
                 // Gecko thread exited first; let GeckoApp die too.
                 doShutdown();
                 return;
 
-            } else if ("NativeApp:IsDebuggable".equals(event)) {
-                JSONObject ret = new JSONObject();
-                ret.put("isDebuggable", getIsDebuggable());
-                EventDispatcher.sendResponse(message, ret);
             } else if (event.equals("Accessibility:Event")) {
                 GeckoAccessibility.sendAccessibilityEvent(message);
             }
         } catch (Exception e) {
             Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
         }
     }
 
@@ -1263,20 +1252,18 @@ public abstract class GeckoApp
             }
         }
 
         // GeckoThread has to register for "Gecko:Ready" first, so GeckoApp registers
         // for events after initializing GeckoThread but before launching it.
 
         EventDispatcher.getInstance().registerGeckoThreadListener((GeckoEventListener)this,
             "Gecko:Ready",
-            "Gecko:DelayedStartup",
             "Gecko:Exited",
-            "Accessibility:Event",
-            "NativeApp:IsDebuggable");
+            "Accessibility:Event");
 
         EventDispatcher.getInstance().registerGeckoThreadListener((NativeEventListener)this,
             "Accessibility:Ready",
             "Bookmark:Insert",
             "Contact:Add",
             "DevToolsAuth:Scan",
             "DOMFullScreen:Start",
             "DOMFullScreen:Stop",
@@ -1294,21 +1281,16 @@ public abstract class GeckoApp
             "ToggleChrome:Show",
             "Update:Check",
             "Update:Download",
             "Update:Install");
 
         EventDispatcher.getInstance().registerBackgroundThreadListener((BundleEventListener) this,
                 "History:GetPrePathLastVisitedTimeMilliseconds");
 
-        if (mWebappEventListener == null) {
-            mWebappEventListener = new EventListener();
-            mWebappEventListener.registerEvents();
-        }
-
         GeckoThread.launch();
 
         Bundle stateBundle = ContextUtils.getBundleExtra(getIntent(), EXTRA_STATE_BUNDLE);
         if (stateBundle != null) {
             // Use the state bundle if it was given as an intent extra. This is
             // only intended to be used internally via Robocop, so a boolean
             // is read from a private shared pref to prevent other apps from
             // injecting states.
@@ -2098,20 +2080,18 @@ public abstract class GeckoApp
             // This build does not support the Android version of the device:
             // We did not initialize anything, so skip cleaning up.
             super.onDestroy();
             return;
         }
 
         EventDispatcher.getInstance().unregisterGeckoThreadListener((GeckoEventListener)this,
             "Gecko:Ready",
-            "Gecko:DelayedStartup",
             "Gecko:Exited",
-            "Accessibility:Event",
-            "NativeApp:IsDebuggable");
+            "Accessibility:Event");
 
         EventDispatcher.getInstance().unregisterGeckoThreadListener((NativeEventListener)this,
             "Accessibility:Ready",
             "Bookmark:Insert",
             "Contact:Add",
             "DOMFullScreen:Start",
             "DOMFullScreen:Stop",
             "Image:SetAs",
@@ -2128,21 +2108,16 @@ public abstract class GeckoApp
             "ToggleChrome:Show",
             "Update:Check",
             "Update:Download",
             "Update:Install");
 
         EventDispatcher.getInstance().unregisterBackgroundThreadListener((BundleEventListener) this,
                 "History:GetPrePathLastVisitedTimeMilliseconds");
 
-        if (mWebappEventListener != null) {
-            mWebappEventListener.unregisterEvents();
-            mWebappEventListener = null;
-        }
-
         deleteTempFiles();
 
         if (mDoorHangerPopup != null)
             mDoorHangerPopup.destroy();
         if (mFormAssistPopup != null)
             mFormAssistPopup.destroy();
         if (mContactService != null)
             mContactService.destroy();
@@ -2668,33 +2643,16 @@ public abstract class GeckoApp
         try {
             versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
         } catch (NameNotFoundException e) {
             Log.wtf(LOGTAG, getPackageName() + " not found", e);
         }
         return versionCode;
     }
 
-    protected boolean getIsDebuggable() {
-        // Return false so Fennec doesn't appear to be debuggable.  WebappImpl
-        // then overrides this and returns the value of android:debuggable for
-        // the webapp APK, so webapps get the behavior supported by this method
-        // (i.e. automatic configuration and enabling of the remote debugger).
-        return false;
-
-        // If we ever want to expose this for Fennec, here's how we would do it:
-        // int flags = 0;
-        // try {
-        //     flags = getPackageManager().getPackageInfo(getPackageName(), 0).applicationInfo.flags;
-        // } catch (NameNotFoundException e) {
-        //     Log.wtf(LOGTAG, getPackageName() + " not found", e);
-        // }
-        // return (flags & android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE) != 0;
-    }
-
     // FHR reason code for a session end prior to a restart for a
     // locale change.
     private static final String SESSION_END_LOCALE_CHANGED = "L";
 
     /**
      * This exists so that a locale can be applied in two places: when saved
      * in a nested activity, and then again when we get back up to GeckoApp.
      *
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoAppShell.java
@@ -2830,14 +2830,9 @@ public class GeckoAppShell
 
     @WrapForJNI
     static Rect getScreenSize() {
         final WindowManager wm = (WindowManager)
                 getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
         final Display disp = wm.getDefaultDisplay();
         return new Rect(0, 0, disp.getWidth(), disp.getHeight());
     }
-
-    @JNITarget
-    static boolean isWebAppProcess() {
-        return GeckoProfile.get(getApplicationContext()).isWebAppProfile();
-    }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java
@@ -140,17 +140,16 @@ public class GeckoApplication extends Ap
 
         // This getInstance call will force initialization of the NotificationHelper, but does nothing with the result
         NotificationHelper.getInstance(context).init();
 
         MulticastDNSManager.getInstance(context).init();
 
         // Make sure that all browser-ish applications default to the real LocalBrowserDB.
         // GeckoView consumers use their own Application class, so this doesn't affect them.
-        // WebappImpl overrides this on creation.
         //
         // We need to do this before any access to the profile; it controls
         // which database class is used.
         //
         // As such, this needs to occur before the GeckoView in GeckoApp is inflated -- i.e., in the
         // GeckoApp constructor or earlier -- because GeckoView implicitly accesses the profile. This is earlier!
         GeckoProfile.setBrowserDBFactory(new BrowserDB.Factory() {
             @Override
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoProfile.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoProfile.java
@@ -78,17 +78,16 @@ public final class GeckoProfile {
     private static File sGuestDir;
     private static GeckoProfile sGuestProfile;
     private static boolean sShouldCheckForGuestProfile = true;
 
     public static boolean sIsUsingCustomProfile;
 
     private final String mName;
     private final File mMozillaDir;
-    private final boolean mIsWebAppProfile;
     private final Context mApplicationContext;
 
     private final BrowserDB mDB;
 
     /**
      * Access to this member should be synchronized to avoid
      * races during creation -- particularly between getDir and GeckoView#init.
      *
@@ -301,16 +300,18 @@ public final class GeckoProfile {
                 profile.setDir(profileDir);
                 return profile;
             }
 
             throw new IllegalStateException("Refusing to reuse profile with a different directory.");
         }
     }
 
+    // Currently unused outside of testing.
+    @RobocopTarget
     public static boolean removeProfile(Context context, String profileName) {
         if (profileName == null) {
             Log.w(LOGTAG, "Unable to remove profile: null profile name.");
             return false;
         }
 
         final GeckoProfile profile = get(context, profileName);
         if (profile == null) {
@@ -452,35 +453,31 @@ public final class GeckoProfile {
 
     private GeckoProfile(Context context, String profileName, File profileDir, BrowserDB.Factory dbFactory) throws NoMozillaDirectoryException {
         if (TextUtils.isEmpty(profileName)) {
             throw new IllegalArgumentException("Unable to create GeckoProfile for empty profile name.");
         }
 
         mApplicationContext = context.getApplicationContext();
         mName = profileName;
-        mIsWebAppProfile = profileName.startsWith("webapp");
         mMozillaDir = GeckoProfileDirectories.getMozillaDirectory(context);
 
         // This apes the behavior of setDir.
         if (profileDir != null && profileDir.exists() && profileDir.isDirectory()) {
             mProfileDir = profileDir;
         }
 
         // N.B., mProfileDir can be null at this point.
         mDB = dbFactory.get(profileName, mProfileDir);
     }
 
     public BrowserDB getDB() {
         return mDB;
     }
 
-    public boolean isWebAppProfile() {
-        return mIsWebAppProfile;
-    }
 
     // Warning, Changing the lock file state from outside apis will cause this to become out of sync
     public boolean locked() {
         if (mLocked != LockState.UNDEFINED) {
             return mLocked == LockState.LOCKED;
         }
 
         boolean profileExists;
@@ -999,54 +996,48 @@ public final class GeckoProfile {
         profileSection.setProperty("Path", saltedName);
 
         if (parser.getSection("General") == null) {
             INISection generalSection = new INISection("General");
             generalSection.setProperty("StartWithLastProfile", 1);
             parser.addSection(generalSection);
         }
 
-        if (!isDefaultSet && !mIsWebAppProfile) {
-            // only set as default if this is the first non-webapp
-            // profile we're creating
+        if (!isDefaultSet) {
+            // only set as default if this is the first profile we're creating
             profileSection.setProperty("Default", 1);
 
             // We have no intention of stopping this session. The FIRSTRUN session
             // ends when the browsing session/activity has ended. All events
             // during firstrun will be tagged as FIRSTRUN.
             Telemetry.startUISession(TelemetryContract.Session.FIRSTRUN);
         }
 
         parser.addSection(profileSection);
         parser.write();
 
-        // Trigger init for non-webapp profiles.
-        if (!mIsWebAppProfile) {
-            enqueueInitialization(profileDir);
-        }
+        enqueueInitialization(profileDir);
 
         // Write out profile creation time, mirroring the logic in nsToolkitProfileService.
         try {
             FileOutputStream stream = new FileOutputStream(profileDir.getAbsolutePath() + File.separator + "times.json");
             OutputStreamWriter writer = new OutputStreamWriter(stream, Charset.forName("UTF-8"));
             try {
                 writer.append("{\"created\": " + System.currentTimeMillis() + "}\n");
             } finally {
                 writer.close();
             }
         } catch (Exception e) {
             // Best-effort.
             Log.w(LOGTAG, "Couldn't write times.json.", e);
         }
 
-        // Initialize pref flag for displaying the start pane for a new non-webapp profile.
-        if (!mIsWebAppProfile) {
-            final SharedPreferences prefs = GeckoSharedPrefs.forProfile(mApplicationContext);
-            prefs.edit().putBoolean(FirstrunAnimationContainer.PREF_FIRSTRUN_ENABLED, true).apply();
-        }
+        // Initialize pref flag for displaying the start pane for a new profile.
+        final SharedPreferences prefs = GeckoSharedPrefs.forProfile(mApplicationContext);
+        prefs.edit().putBoolean(FirstrunAnimationContainer.PREF_FIRSTRUN_ENABLED, true).apply();
 
         return profileDir;
     }
 
     /**
      * This method is called once, immediately before creation of the profile
      * directory completes.
      *
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/Webapp.java
+++ /dev/null
@@ -1,13 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * 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/. */
-
-package org.mozilla.gecko;
-
-import org.mozilla.gecko.webapp.WebappImpl;
-
-/**
- * This class serves only as a namespace wrapper for WebappImpl.
- */
-public class Webapp extends WebappImpl {}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/webapp/Allocator.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
- * 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/. */
-
-package org.mozilla.gecko.webapp;
-
-import java.util.ArrayList;
-
-import org.mozilla.gecko.GeckoAppShell;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.util.Log;
-
-public class Allocator {
-
-    private final String LOGTAG = "GeckoWebappAllocator";
-
-    private static final String PREFIX_ORIGIN = "webapp-origin-";
-    private static final String PREFIX_PACKAGE_NAME = "webapp-package-name-";
-
-    // These prefixes are for prefs used by the old shortcut-based runtime.
-    // We define them here so maybeMigrateOldPrefs can migrate them to their
-    // new equivalents if this app was originally installed as a shortcut.
-    // Maybe we can remove this code in the future!
-    private static final String PREFIX_OLD_APP = "app";
-    private static final String PREFIX_OLD_ICON = "icon";
-
-    // The number of Webapp# and WEBAPP# activities/apps/intents
-    private final static int MAX_WEB_APPS = 100;
-
-    protected static Allocator sInstance;
-    public static Allocator getInstance() {
-        return getInstance(GeckoAppShell.getContext());
-    }
-
-    public static synchronized Allocator getInstance(Context cx) {
-        if (sInstance == null) {
-            sInstance = new Allocator(cx);
-        }
-
-        return sInstance;
-    }
-
-    SharedPreferences mPrefs;
-
-    @SuppressWarnings("deprecation") // Suppressing deprecation notification for Context.MODE_MULTI_PROCESS until we
-                                     // reach a timeline for removal of the whole feature. (Bug 1171213)
-    protected Allocator(Context context) {
-        mPrefs = context.getSharedPreferences("webapps", Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS);
-    }
-
-    private static String appKey(int index) {
-        return PREFIX_PACKAGE_NAME + index;
-    }
-
-    public static String iconKey(int index) {
-        return "web-app-color-" + index;
-    }
-
-    public static String originKey(int i) {
-        return PREFIX_ORIGIN + i;
-    }
-
-    private static String oldAppKey(int index) {
-        return PREFIX_OLD_APP + index;
-    }
-
-    private static String oldIconKey(int index) {
-        return PREFIX_OLD_ICON + index;
-    }
-
-    public ArrayList<String> getInstalledPackageNames() {
-        ArrayList<String> installedPackages = new ArrayList<String>();
-
-        for (int i = 0; i < MAX_WEB_APPS; ++i) {
-            if (mPrefs.contains(appKey(i))) {
-                installedPackages.add(mPrefs.getString(appKey(i), ""));
-            }
-        }
-        return installedPackages;
-    }
-
-    public synchronized int findOrAllocatePackage(final String packageName) {
-        int index = getIndexForApp(packageName);
-        if (index != -1)
-            return index;
-
-        for (int i = 0; i < MAX_WEB_APPS; ++i) {
-            if (!mPrefs.contains(appKey(i))) {
-                // found unused index i
-                putPackageName(i, packageName);
-                return i;
-            }
-        }
-
-        // no more apps!
-        return -1;
-    }
-
-    public synchronized void putPackageName(final int index, final String packageName) {
-        mPrefs.edit().putString(appKey(index), packageName).apply();
-    }
-
-    public void updateColor(int index, int color) {
-        mPrefs.edit().putInt(iconKey(index), color).apply();
-    }
-
-    public synchronized int getIndexForApp(String packageName) {
-        return findSlotForPrefix(PREFIX_PACKAGE_NAME, packageName);
-    }
-
-    protected int findSlotForPrefix(String prefix, String value) {
-        for (int i = 0; i < MAX_WEB_APPS; ++i) {
-            if (mPrefs.getString(prefix + i, "").equals(value)) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    public synchronized String getAppForIndex(int index) {
-        return mPrefs.getString(appKey(index), null);
-    }
-
-    public synchronized int releaseIndexForApp(String app) {
-        int index = getIndexForApp(app);
-        if (index == -1)
-            return -1;
-
-        releaseIndex(index);
-        return index;
-    }
-
-    public synchronized void releaseIndex(final int index) {
-        mPrefs.edit().remove(appKey(index)).remove(iconKey(index)).remove(originKey(index)).apply();
-    }
-
-    public void putOrigin(int index, String origin) {
-        mPrefs.edit().putString(originKey(index), origin).apply();
-    }
-
-    public String getOrigin(int index) {
-        return mPrefs.getString(originKey(index), null);
-    }
-
-    public int getColor(int index) {
-        return mPrefs.getInt(iconKey(index), -1);
-    }
-
-    /**
-     * Migrate old prefs to their new equivalents if this app was originally
-     * installed by the shortcut-based implementation.
-     */
-    public void maybeMigrateOldPrefs(int index) {
-        if (!mPrefs.contains(oldAppKey(index))) {
-            return;
-        }
-
-        Log.i(LOGTAG, "migrating old prefs");
-
-        // The old appKey pref stored the origin, while the new appKey pref
-        // stores the packageName, so we migrate oldAppKey to the origin pref.
-        putOrigin(index, mPrefs.getString(oldAppKey(index), null));
-
-        // The old iconKey pref actually stored the splash screen background
-        // color, so we migrate oldIconKey to the color pref.
-        updateColor(index, mPrefs.getInt(oldIconKey(index), -1));
-
-        // Remove the old prefs so we don't migrate them the next time around.
-        mPrefs.edit().remove(oldAppKey(index)).remove(oldIconKey(index)).apply();
-    }
-}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/webapp/ApkResources.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
- * 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/. */
-
-package org.mozilla.gecko.webapp;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Environment;
-import android.util.Log;
-
-public class ApkResources {
-    private static final String LOGTAG = "GeckoWebappApkResources";
-    private final String mPackageName;
-    private final ApplicationInfo mInfo;
-    private final Context mContext;
-
-    public ApkResources(Context context, String packageName) throws NameNotFoundException {
-        mPackageName = packageName;
-        mInfo = context.getPackageManager().getApplicationInfo(
-                    mPackageName, PackageManager.GET_META_DATA);
-        mContext = context;
-    }
-
-    private ApplicationInfo info() {
-        return mInfo;
-    }
-
-    public String getPackageName() {
-        return mPackageName;
-    }
-
-    private Bundle metadata() {
-        return mInfo.metaData;
-    }
-
-    public String getManifest(Context context) {
-        return readResource(context, "manifest");
-    }
-
-    public String getMiniManifest(Context context) {
-        return readResource(context, "mini");
-    }
-
-    public String getManifestUrl() {
-        return metadata().getString("manifestUrl");
-    }
-
-    public boolean isPackaged() {
-        return "packaged".equals(getWebappType());
-    }
-
-    public boolean isDebuggable() {
-        return (mInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
-    }
-
-    private String readResource(Context context, String resourceName) {
-        Uri resourceUri = Uri.parse("android.resource://" + mPackageName
-                + "/raw/" + resourceName);
-        StringBuilder fileContent = new StringBuilder();
-        try {
-            final BufferedReader r = new BufferedReader(new InputStreamReader(context
-                    .getContentResolver().openInputStream(resourceUri)));
-            try {
-                String line;
-
-                while ((line = r.readLine()) != null) {
-                    fileContent.append(line);
-                }
-            } finally {
-                r.close();
-            }
-        } catch (FileNotFoundException e) {
-            Log.e(LOGTAG, String.format("File not found: \"%s\"", resourceName));
-        } catch (IOException e) {
-            Log.e(LOGTAG, String.format("Couldn't read file: \"%s\"", resourceName));
-        }
-
-        return fileContent.toString();
-    }
-
-    public Uri getAppIconUri() {
-        return Uri.parse("android.resource://" + mPackageName + "/" + info().icon);
-    }
-
-    public Drawable getAppIcon() {
-        return info().loadIcon(mContext.getPackageManager());
-    }
-
-    public String getWebappType() {
-        return metadata().getString("webapp");
-    }
-
-    public String getAppName() {
-        return info().name;
-    }
-
-    /**
-     * Which APK installer installed this APK.
-     *
-     * For OEM backed marketplaces, this will be non-<code>null</code>. Otherwise, <code>null</code>.
-     *
-     * TODO check that the G+ package installer gives us non-null results.
-     *
-     * @return the package name of the APK that installed this.
-     */
-    public String getPackageInstallerName() {
-        return mContext.getPackageManager().getInstallerPackageName(mPackageName);
-    }
-
-    public Uri getZipFileUri() {
-        return Uri.parse("android.resource://" + mPackageName + "/raw/application");
-    }
-
-    public File getFileDirectory() {
-        File dir = mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
-        String path = dir.getAbsolutePath().replace(mContext.getPackageName(), mPackageName);
-
-        dir = new File(path);
-
-        if (!dir.exists()) {
-            dir.mkdirs();
-        }
-
-        return dir;
-    }
-}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/webapp/Dispatcher.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
- * 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/. */
-
-package org.mozilla.gecko.webapp;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-
-public class Dispatcher extends Activity {
-    private static final String LOGTAG = "GeckoWebappDispatcher";
-
-    @Override
-    protected void onCreate(Bundle bundle) {
-        super.onCreate(bundle);
-
-        Allocator allocator = Allocator.getInstance(getApplicationContext());
-
-        if (bundle == null) {
-            bundle = getIntent().getExtras();
-        }
-
-        if (bundle == null) {
-            Log.e(LOGTAG, "Passed intent data missing.");
-            return;
-        }
-
-        String packageName = bundle.getString("packageName");
-
-        if (packageName == null) {
-            Log.e(LOGTAG, "Package name data missing.");
-            return;
-        }
-
-        int index = allocator.getIndexForApp(packageName);
-        boolean isInstalled = index >= 0;
-        if (!isInstalled) {
-            index = allocator.findOrAllocatePackage(packageName);
-        }
-
-        // Copy the intent, without interfering with it.
-        Intent intent = new Intent(getIntent());
-
-        // Only change its destination.
-        intent.setClassName(getApplicationContext(), "org.mozilla.gecko.webapp.Webapps$Webapp" + index);
-
-        // If and only if we haven't seen this before.
-        intent.putExtra("isInstalled", isInstalled);
-
-        startActivity(intent);
-    }
-}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/webapp/EventListener.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
- * 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/. */
-
-package org.mozilla.gecko.webapp;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.mozilla.gecko.ActivityHandlerHelper;
-import org.mozilla.gecko.AppConstants.Versions;
-import org.mozilla.gecko.EventDispatcher;
-import org.mozilla.gecko.GeckoAppShell;
-import org.mozilla.gecko.GeckoProfile;
-import org.mozilla.gecko.util.ActivityResultHandler;
-import org.mozilla.gecko.util.EventCallback;
-import org.mozilla.gecko.util.NativeEventListener;
-import org.mozilla.gecko.util.NativeJSObject;
-import org.mozilla.gecko.util.ThreadUtils;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.net.Uri;
-import android.util.Log;
-
-public class EventListener implements NativeEventListener  {
-
-    private static final String LOGTAG = "GeckoWebappEventListener";
-
-    public void registerEvents() {
-        EventDispatcher.getInstance().registerGeckoThreadListener(this,
-            "Webapps:Preinstall",
-            "Webapps:InstallApk",
-            "Webapps:UninstallApk",
-            "Webapps:Postinstall",
-            "Webapps:Launch",
-            "Webapps:Uninstall",
-            "Webapps:GetApkVersions");
-    }
-
-    public void unregisterEvents() {
-        EventDispatcher.getInstance().unregisterGeckoThreadListener(this,
-            "Webapps:Preinstall",
-            "Webapps:InstallApk",
-            "Webapps:UninstallApk",
-            "Webapps:Postinstall",
-            "Webapps:Launch",
-            "Webapps:Uninstall",
-            "Webapps:GetApkVersions");
-    }
-
-    @Override
-    public void handleMessage(String event, NativeJSObject message, EventCallback callback) {
-        try {
-            if (event.equals("Webapps:InstallApk")) {
-                installApk(GeckoAppShell.getGeckoInterface().getActivity(), message, callback);
-            } else if (event.equals("Webapps:UninstallApk")) {
-                uninstallApk(GeckoAppShell.getGeckoInterface().getActivity(), message);
-            } else if (event.equals("Webapps:Postinstall")) {
-                postInstallWebapp(message.getString("apkPackageName"), message.getString("origin"));
-            } else if (event.equals("Webapps:Launch")) {
-                launchWebapp(message.getString("packageName"));
-            } else if (event.equals("Webapps:GetApkVersions")) {
-                JSONObject obj = new JSONObject();
-                obj.put("versions", getApkVersions(GeckoAppShell.getGeckoInterface().getActivity(),
-                                                   message.getStringArray("packageNames")));
-                callback.sendSuccess(obj);
-            }
-        } catch (Exception e) {
-            Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
-        }
-    }
-
-    public static void postInstallWebapp(String aPackageName, String aOrigin) {
-        Allocator allocator = Allocator.getInstance(GeckoAppShell.getContext());
-        int index = allocator.findOrAllocatePackage(aPackageName);
-        allocator.putOrigin(index, aOrigin);
-    }
-
-    private void launchWebapp(String aPackageName) {
-        Intent intent = GeckoAppShell.getContext().getPackageManager().getLaunchIntentForPackage(aPackageName);
-        GeckoAppShell.getGeckoInterface().getActivity().startActivity(intent);
-    }
-
-    public static void uninstallWebapp(final String packageName) {
-        // On uninstall, we need to do a couple of things:
-        //   1. nuke the running app process.
-        //   2. nuke the profile that was assigned to that webapp
-        ThreadUtils.postToBackgroundThread(new Runnable() {
-            @Override
-            public void run() {
-                int index = Allocator.getInstance(GeckoAppShell.getContext()).releaseIndexForApp(packageName);
-
-                // if -1, nothing to do; we didn't think it was installed anyway
-                if (index == -1)
-                    return;
-
-                killWebappSlot(GeckoAppShell.getContext(), index);
-
-                // then nuke the profile
-                GeckoProfile.removeProfile(GeckoAppShell.getContext(), "webapp" + index);
-            }
-        });
-    }
-
-    /**
-     * Used in both uninstall and swiping away from the recent task list.
-     *
-     * @param context
-     * @param slot
-     */
-    public static void killWebappSlot(Context context, int slot) {
-        // kill the app if it's running
-        String targetProcessName = context.getPackageName();
-        targetProcessName = targetProcessName + ":" + targetProcessName + ".Webapp" + slot;
-
-        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-        List<ActivityManager.RunningAppProcessInfo> procs = am.getRunningAppProcesses();
-        if (procs != null) {
-            for (ActivityManager.RunningAppProcessInfo proc : procs) {
-                if (proc.processName.equals(targetProcessName)) {
-                    android.os.Process.killProcess(proc.pid);
-                    break;
-                }
-            }
-        }
-    }
-
-    public static void installApk(final Activity context, NativeJSObject message, final EventCallback callback) {
-        final JSONObject messageData;
-
-        // We get the manifest url out of javascript here so we can use it as a checksum
-        // in InstallListener when a package has been installed.
-        String manifestUrl;
-        String filePath;
-
-        try {
-            filePath = message.getString("filePath");
-            messageData = new JSONObject(message.getObject("data").toString());
-            manifestUrl = messageData.getJSONObject("app").getString("manifestURL");
-        } catch (JSONException e) {
-            Log.wtf(LOGTAG, "Error getting file path and data", e);
-            callback.sendError("Error getting file path and data: " + e.toString());
-            return;
-        }
-
-        final File file = new File(filePath);
-
-        if (!file.exists()) {
-            Log.wtf(LOGTAG, "APK file doesn't exist at path " + filePath);
-            callback.sendError("APK file doesn't exist at path " + filePath);
-            return;
-        }
-
-        // We will check the manifestUrl from the one in the APK.
-        // Thus, we can have a one-to-one mapping of apk to receiver.
-        final InstallListener receiver = new InstallListener(manifestUrl, messageData, file);
-
-        // Listen for packages being installed.
-        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
-        filter.addDataScheme("package");
-
-        // As of API 19 we can do something like this to only trigger this receiver
-        // for a specific package name:
-        // int currentApiVersion = android.os.Build.VERSION.SDK_INT;
-        // if (currentApiVersion >= android.os.Build.VERSION_CODES.KITKAT){ // KITKAT == 19
-        //    filter.addDataSchemeSpecificPart("com.example.someapp", PatternMatcher.PATTERN_LITERAL);
-        // }
-        // TODO: Implement package name filtering to IntentFilter.
-
-        context.registerReceiver(receiver, filter);
-
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
-
-        // Now call the package installer.
-        ActivityHandlerHelper.startIntentForActivity(context, intent, new ActivityResultHandler() {
-            // Invoked if the user cancels installation or presses the 'Done'
-            // button once the app has been successfully installed. It may also
-            // be called when the user presses Open and then returns to Fennec.
-            @Override
-            public void onActivityResult(int resultCode, Intent data) {
-                if (!receiver.isReceived()) {
-                    callback.sendError("APK installation cancelled by user");
-                    context.unregisterReceiver(receiver);
-                }
-                if (file.delete()) {
-                    Log.i(LOGTAG, "Downloaded APK file deleted");
-                }
-            }
-        });
-    }
-
-    public static void uninstallApk(final Activity context, NativeJSObject message) {
-        final String packageName = message.getString("apkPackageName");
-        final Uri packageUri = Uri.parse("package:" + packageName);
-
-        final Intent intent;
-        if (Versions.preICS) {
-            intent = new Intent(Intent.ACTION_DELETE, packageUri);
-        } else {
-            intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri);
-        }
-
-        context.startActivity(intent);
-    }
-
-    private static final int DEFAULT_VERSION_CODE = -1;
-
-    public static JSONObject getApkVersions(Activity context, String[] packageNames) {
-        Set<String> packageNameSet = new HashSet<String>();
-        packageNameSet.addAll(Arrays.asList(packageNames));
-
-        final PackageManager pm = context.getPackageManager();
-        List<ApplicationInfo> apps = pm.getInstalledApplications(0);
-
-        JSONObject jsonMessage = new JSONObject();
-
-        for (ApplicationInfo app : apps) {
-            if (packageNameSet.contains(app.packageName)) {
-                int versionCode = DEFAULT_VERSION_CODE;
-                try {
-                    versionCode = pm.getPackageInfo(app.packageName, 0).versionCode;
-                } catch (PackageManager.NameNotFoundException e) {
-                    Log.e(LOGTAG, "couldn't get version for app " + app.packageName, e);
-                }
-                try {
-                    jsonMessage.put(app.packageName, versionCode);
-                } catch (JSONException e) {
-                    Log.e(LOGTAG, "unable to store version code field for app " + app.packageName, e);
-                }
-            }
-        }
-
-        return jsonMessage;
-    }
-}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/webapp/InstallHelper.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
- * 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/. */
-
-package org.mozilla.gecko.webapp;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.mozilla.gecko.EventDispatcher;
-import org.mozilla.gecko.GeckoAppShell;
-import org.mozilla.gecko.GeckoEvent;
-import org.mozilla.gecko.GeckoProfile;
-import org.mozilla.gecko.gfx.BitmapUtils;
-import org.mozilla.gecko.util.EventCallback;
-import org.mozilla.gecko.util.NativeEventListener;
-import org.mozilla.gecko.util.NativeJSObject;
-import org.mozilla.gecko.util.ThreadUtils;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.util.Log;
-
-public class InstallHelper implements NativeEventListener {
-    private static final String LOGTAG = "GeckoWebappInstallHelper";
-    private static final String[] INSTALL_EVENT_NAMES = new String[] {"Webapps:Postinstall"};
-    private final Context mContext;
-    private final InstallCallback mCallback;
-    private final ApkResources mApkResources;
-
-    public static interface InstallCallback {
-        // on the GeckoThread
-        void installCompleted(InstallHelper installHelper, String event, NativeJSObject message);
-
-        // on the GeckoBackgroundThread
-        void installErrored(InstallHelper installHelper, Exception exception);
-    }
-
-    public InstallHelper(Context context, ApkResources apkResources, InstallCallback cb) {
-        mContext = context;
-        mCallback = cb;
-        mApkResources = apkResources;
-    }
-
-    public void startInstall(String profileName) throws IOException {
-        startInstall(profileName, null);
-    }
-
-    public void startInstall(final String profileName, final JSONObject message) throws IOException {
-        ThreadUtils.postToBackgroundThread(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    install(profileName, message);
-                } catch (IOException e) {
-                    handleException(e);
-                }
-            }
-        });
-    }
-
-    protected void handleException(Exception e) {
-        if (mCallback != null) {
-            mCallback.installErrored(this, e);
-        } else {
-            Log.e(LOGTAG, "mozApps.install failed", e);
-        }
-    }
-
-    void install(String profileName, JSONObject message) throws IOException {
-        if (message == null) {
-            message = new JSONObject();
-        }
-
-        // we can change the profile to be in the app's area here
-        GeckoProfile profile = GeckoProfile.get(mContext, profileName);
-
-        try {
-            message.put("apkPackageName", mApkResources.getPackageName());
-            message.put("manifestURL", mApkResources.getManifestUrl());
-            message.put("title", mApkResources.getAppName());
-            message.put("manifest", new JSONObject(mApkResources.getManifest(mContext)));
-
-            String appType = mApkResources.getWebappType();
-            message.putOpt("type", appType);
-            if ("packaged".equals(appType)) {
-                message.putOpt("updateManifest", new JSONObject(mApkResources.getMiniManifest(mContext)));
-            }
-
-            message.putOpt("profilePath", profile.getDir());
-
-            if (mApkResources.isPackaged()) {
-                File zipFile = copyApplicationZipFile();
-                message.putOpt("zipFilePath", Uri.fromFile(zipFile).toString());
-            }
-        } catch (JSONException e) {
-            handleException(e);
-            return;
-        }
-
-        registerGeckoListener();
-
-        GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Webapps:AutoInstall", message.toString()));
-        calculateColor();
-    }
-
-    public File copyApplicationZipFile() throws IOException {
-        if (!mApkResources.isPackaged()) {
-            return null;
-        }
-
-        Uri uri = mApkResources.getZipFileUri();
-
-        InputStream in = null;
-        OutputStream out = null;
-        File destPath = new File(mApkResources.getFileDirectory(), "application.zip");
-        try {
-            in = mContext.getContentResolver().openInputStream(uri);
-            out = new FileOutputStream(destPath);
-            byte[] buffer = new byte[1024];
-            int read = 0;
-            while ((read = in.read(buffer)) != -1) {
-                out.write(buffer, 0, read);
-            }
-            out.flush();
-        } catch (IOException e) {
-            throw e;
-        } finally {
-            close(in);
-            close(out);
-        }
-        return destPath;
-    }
-
-    private static void close(Closeable close) {
-        if (close == null) {
-            return;
-        }
-        try {
-            close.close();
-        } catch (IOException e) {
-            // NOP
-        }
-    }
-
-    public void registerGeckoListener() {
-        EventDispatcher.getInstance().registerGeckoThreadListener(this, INSTALL_EVENT_NAMES);
-    }
-
-    private void calculateColor() {
-        ThreadUtils.assertOnBackgroundThread();
-        Allocator slots = Allocator.getInstance(mContext);
-        int index = slots.getIndexForApp(mApkResources.getPackageName());
-        Bitmap bitmap = BitmapUtils.getBitmapFromDrawable(mApkResources.getAppIcon());
-        slots.updateColor(index, BitmapUtils.getDominantColor(bitmap));
-    }
-
-    @Override
-    public void handleMessage(String event, NativeJSObject message, EventCallback callback) {
-        EventDispatcher.getInstance().unregisterGeckoThreadListener(this, INSTALL_EVENT_NAMES);
-
-        if (mCallback != null) {
-            mCallback.installCompleted(this, event, message);
-        }
-    }
-}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/webapp/InstallListener.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
- * 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/. */
-
-package org.mozilla.gecko.webapp;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.mozilla.gecko.GeckoThread;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.text.TextUtils;
-import android.util.Log;
-
-public class InstallListener extends BroadcastReceiver {
-
-    private static final String LOGTAG = "GeckoWebappInstallListener";
-    private final JSONObject mData;
-    private final String mManifestUrl;
-    private boolean mReceived;
-    private final File mApkFile;
-
-    public InstallListener(String manifestUrl, JSONObject data, File apkFile) {
-        mData = data;
-        mApkFile = apkFile;
-        mManifestUrl = manifestUrl;
-        if (mManifestUrl == null) {
-            throw new IllegalArgumentException("manifestUrl must not be null");
-        }
-        if (mApkFile == null || mApkFile.exists()) {
-            throw new IllegalArgumentException("apkFile must not be null and must exist");
-        }
-    }
-
-    public boolean isReceived() {
-        return mReceived;
-    }
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        String packageName = intent.getData().getSchemeSpecificPart();
-
-        if (TextUtils.isEmpty(packageName)) {
-            Log.i(LOGTAG, "No package name defined in intent");
-            return;
-        }
-
-        ApkResources apkResources = null;
-        try {
-            apkResources = new ApkResources(context, packageName);
-        } catch (NameNotFoundException e) {
-            Log.e(LOGTAG, "Can't find package that's just been installed");
-            return;
-        }
-
-        String manifestUrl = apkResources.getManifestUrl();
-        if (TextUtils.isEmpty(manifestUrl)) {
-            Log.i(LOGTAG, "No manifest URL present in metadata");
-            return;
-        }
-        if (!isCorrectManifest(manifestUrl)) {
-            // This happens when the updater triggers installation of multiple
-            // APK updates simultaneously.  If we're the receiver for another
-            // update, then simply ignore this intent by returning early.
-            Log.i(LOGTAG, "Manifest URL is for a different install; ignoring");
-            return;
-        }
-
-        // If we're here then everything is looking good and installation can continue.
-        mReceived = true;
-        context.unregisterReceiver(this);
-
-        if (mApkFile != null && mApkFile.delete()) {
-            Log.i(LOGTAG, "Downloaded APK file deleted");
-        }
-
-
-        if (GeckoThread.isRunning()) {
-            InstallHelper installHelper = new InstallHelper(context, apkResources, null);
-            try {
-                JSONObject dataObject = new JSONObject();
-                dataObject.put("request", mData);
-
-                Allocator slots = Allocator.getInstance(context);
-                int i = slots.findOrAllocatePackage(packageName);
-                installHelper.startInstall("webapp" + i, dataObject);
-            } catch (JSONException e) {
-                Log.e(LOGTAG, "Couldn't parse data from mozApps.install()", e);
-            } catch (IOException e) {
-                Log.e(LOGTAG, "Couldn't install packaged app", e);
-            }
-        }
-    }
-
-    public boolean isCorrectManifest(String manifestUrl) {
-        // Don't use URL and the sameFile method as this also includes the query which
-        // we want to ignore.
-        try {
-            String registeredUrl = mManifestUrl.split("\\?")[0];
-            String observedUrl = manifestUrl.split("\\?")[0];
-            return registeredUrl.equals(observedUrl);
-        } catch (NullPointerException e) {
-            Log.e(LOGTAG, "One or both of the manifest URLs is null", e);
-        }
-        return false;
-    }
-
-}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/webapp/TaskKiller.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
- * 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/. */
-
-package org.mozilla.gecko.webapp;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.util.Log;
-
-/**
- * This BroadcastReceiver is registered in the AndroidManifest.xml.in file.
- *
- * <p>It listens for intents sent by synthesized APKs when the task has been ended.
- * e.g. when the user has swiped it out of the Recent Apps List.</p>
- *
- */
-public class TaskKiller extends BroadcastReceiver {
-
-    private static final String LOGTAG = "GeckoWebappTaskKiller";
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        String packageName = intent.getStringExtra("packageName");
-        int slot = Allocator.getInstance(context).getIndexForApp(packageName);
-        if (slot >= 0) {
-            EventListener.killWebappSlot(context, slot);
-        } else {
-            Log.w(LOGTAG, "Asked to kill " + packageName + " but this runtime (" + context.getPackageName() + ") doesn't know about it.");
-        }
-    }
-
-}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/webapp/UninstallListener.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
- * 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/. */
-
-package org.mozilla.gecko.webapp;
-
-import org.mozilla.gecko.AppConstants;
-import org.mozilla.gecko.GeckoApp;
-import org.mozilla.gecko.GeckoAppShell;
-import org.mozilla.gecko.GeckoEvent;
-import org.mozilla.gecko.GeckoProfile;
-import org.mozilla.gecko.util.ThreadUtils;
-
-import android.app.ActivityManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.text.TextUtils;
-import android.util.Log;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONArray;
-
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-import java.util.ArrayList;
-
-public class UninstallListener extends BroadcastReceiver {
-
-    private static final String LOGTAG = "GeckoWebappUninstallListener";
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
-            Log.i(LOGTAG, "Package is being replaced; ignoring removal intent");
-            return;
-        }
-
-        String packageName = intent.getData().getSchemeSpecificPart();
-
-        if (TextUtils.isEmpty(packageName)) {
-            Log.i(LOGTAG, "No package name defined in intent");
-            return;
-        }
-
-        Allocator allocator = Allocator.getInstance(context);
-        ArrayList<String> installedPackages = allocator.getInstalledPackageNames();
-
-        if (installedPackages.contains(packageName)) {
-            doUninstall(context, packageName);
-        }
-    }
-
-    private static void doUninstall(Context context, String packageName) {
-        ArrayList<String> uninstalledPackages = new ArrayList<String>();
-        uninstalledPackages.add(packageName);
-        doUninstall(context, uninstalledPackages);
-    }
-
-    private static void doUninstall(Context context, ArrayList<String> packageNames) {
-        Allocator allocator = Allocator.getInstance(context);
-        JSONObject message = new JSONObject();
-        JSONArray jsonPackages = new JSONArray();
-
-        for (String packageName : packageNames) {
-            // Although its unlikely that an app is not allocated, but is installed in Gecko, it
-            // is possible. We always send the packageName to JS to be removed from Gecko's registry.
-            jsonPackages.put(packageName);
-
-            int index = allocator.getIndexForApp(packageName);
-
-            // If -1, nothing more to do; we didn't think it was installed anyway.
-            if (index == -1)
-                continue;
-
-            allocator.releaseIndex(index);
-
-            // kill the app if it's running
-            String targetProcessName = context.getPackageName();
-            targetProcessName = targetProcessName + ":" + targetProcessName + ".Webapp" + index;
-
-            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-            List<ActivityManager.RunningAppProcessInfo> procs = am.getRunningAppProcesses();
-            if (procs != null) {
-                for (ActivityManager.RunningAppProcessInfo proc : procs) {
-                    if (proc.processName.equals(targetProcessName)) {
-                        android.os.Process.killProcess(proc.pid);
-                        break;
-                    }
-                }
-            }
-
-            // then nuke the profile
-            GeckoProfile.removeProfile(context, "webapp" + index);
-        }
-
-        try {
-            message.put("apkPackageNames", jsonPackages);
-            GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Webapps:AutoUninstall", message.toString()));
-        } catch (JSONException e) {
-            Log.e(LOGTAG, "Error sending uninstall packages to Gecko", e);
-        }
-    }
-
-    public static void initUninstallPackageScan(Context context) {
-        // get list of packages we think are installed
-        Allocator allocator = Allocator.getInstance(context);
-        ArrayList<String> fennecPackages = allocator.getInstalledPackageNames();
-        ArrayList<String> uninstalledPackages = new ArrayList<String>();
-
-        final PackageManager pm = context.getPackageManager();
-        //get a list of installed apps on device
-        List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
-        Set<String> allInstalledPackages = new HashSet<String>();
-
-        for (ApplicationInfo packageInfo : packages) {
-            allInstalledPackages.add(packageInfo.packageName);
-        }
-
-        for (String packageName : fennecPackages) {
-            if (!allInstalledPackages.contains(packageName)) {
-                uninstalledPackages.add(packageName);
-            }
-        }
-
-        if (uninstalledPackages.size() > 0) {
-            doUninstall(context, uninstalledPackages);
-        }
-    }
-
-    public static class DelayedStartupTask implements Runnable {
-        private final GeckoApp mApp;
-
-        public DelayedStartupTask(GeckoApp app) {
-            mApp = app;
-        }
-
-        @Override
-        public void run() {
-            ThreadUtils.assertOnBackgroundThread();
-
-            // Perform webapp uninstalls as appropriate.
-            UninstallListener.initUninstallPackageScan(mApp.getApplicationContext());
-        }
-    }
-}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/webapp/WebappImpl.java
+++ /dev/null
@@ -1,413 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * 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/. */
-
-package org.mozilla.gecko.webapp;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.mozilla.gecko.GeckoApp;
-import org.mozilla.gecko.GeckoAppShell;
-import org.mozilla.gecko.GeckoEvent;
-import org.mozilla.gecko.GeckoProfile;
-import org.mozilla.gecko.GeckoThread;
-import org.mozilla.gecko.R;
-import org.mozilla.gecko.Tab;
-import org.mozilla.gecko.Tabs;
-import org.mozilla.gecko.db.BrowserDB;
-import org.mozilla.gecko.db.StubBrowserDB;
-import org.mozilla.gecko.mozglue.ContextUtils.SafeIntent;
-import org.mozilla.gecko.util.NativeJSObject;
-import org.mozilla.gecko.webapp.InstallHelper.InstallCallback;
-
-import android.content.Intent;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.graphics.Color;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.Display;
-import android.view.View;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-public class WebappImpl extends GeckoApp implements InstallCallback {
-    private static final String LOGTAG = "GeckoWebappImpl";
-
-    private URI mOrigin;
-    private TextView mTitlebarText;
-    private View mTitlebar;
-
-    // Must only be accessed from the UI thread.
-    View mSplashscreen;
-
-    private boolean mIsApk = true;
-    private ApkResources mApkResources;
-    private String mManifestUrl;
-    private String mAppName;
-
-    protected int getIndex() { return 0; }
-
-    @Override
-    public int getLayout() { return R.layout.web_app; }
-
-    public WebappImpl() {
-        GeckoProfile.setBrowserDBFactory(new BrowserDB.Factory() {
-            @Override
-            public BrowserDB get(String profileName, File profileDir) {
-                return new StubBrowserDB(profileName);
-            }
-        });
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstance) {
-        Bundle extras = getIntent().getExtras();
-        if (extras == null) {
-            extras = savedInstance;
-        }
-
-        if (extras == null) {
-            extras = new Bundle();
-        }
-
-        boolean isInstalled = extras.getBoolean("isInstalled", false);
-        String packageName = extras.getString("packageName");
-
-        if (packageName == null) {
-            Log.w(LOGTAG, "no package name; treating as legacy shortcut");
-
-            mIsApk = false;
-
-            // Shortcut apps are already installed.
-            isInstalled = true;
-
-            Uri data = getIntent().getData();
-            if (data == null) {
-                Log.wtf(LOGTAG, "can't get manifest URL from shortcut data");
-                setResult(RESULT_CANCELED);
-                finish();
-                return;
-            }
-            mManifestUrl = data.toString();
-
-            String shortcutName = extras.getString(Intent.EXTRA_SHORTCUT_NAME);
-            mAppName = shortcutName != null ? shortcutName : "Web App";
-        } else {
-            try {
-                mApkResources = new ApkResources(this, packageName);
-            } catch (NameNotFoundException e) {
-                Log.e(LOGTAG, "Can't find package for webapp " + packageName, e);
-                setResult(RESULT_CANCELED);
-                finish();
-                return;
-            }
-
-            mManifestUrl = mApkResources.getManifestUrl();
-            mAppName = mApkResources.getAppName();
-        }
-
-        // start Gecko.
-        super.onCreate(savedInstance);
-
-        mTitlebarText = (TextView)findViewById(R.id.webapp_title);
-        mTitlebar = findViewById(R.id.webapp_titlebar);
-        mSplashscreen = findViewById(R.id.splashscreen);
-
-        Allocator allocator = Allocator.getInstance(this);
-        int index = getIndex();
-
-        // We have to migrate old prefs before getting the origin because origin
-        // is one of the prefs we might migrate.
-        allocator.maybeMigrateOldPrefs(index);
-
-        String origin = allocator.getOrigin(index);
-        boolean isInstallCompleting = (origin == null);
-
-        if (!GeckoThread.isRunning() || !isInstalled || isInstallCompleting) {
-            // Show the splash screen if we need to start Gecko, or we need to install this.
-            overridePendingTransition(R.anim.grow_fade_in_center, android.R.anim.fade_out);
-            showSplash();
-        } else {
-            mSplashscreen.setVisibility(View.GONE);
-        }
-
-        if (!isInstalled || isInstallCompleting) {
-            InstallHelper installHelper = new InstallHelper(getApplicationContext(), mApkResources, this);
-            if (!isInstalled) {
-                // start the vanilla install.
-                try {
-                    installHelper.startInstall(getDefaultProfileName());
-                } catch (IOException e) {
-                    Log.e(LOGTAG, "Couldn't install packaged app", e);
-                }
-            } else {
-                // an install is already happening, so we should let it complete.
-                Log.i(LOGTAG, "Waiting for existing install to complete");
-                installHelper.registerGeckoListener();
-            }
-            return;
-        }
-
-        launchWebapp(origin);
-
-        setTitle(mAppName);
-    }
-
-    @Override
-    protected String getURIFromIntent(SafeIntent intent) {
-        String uri = super.getURIFromIntent(intent);
-        if (uri != null) {
-            return uri;
-        }
-        // This is where we construct the URL from the Intent from the
-        // the synthesized APK.
-
-        // TODO Translate AndroidIntents into WebActivities here.
-        if (mIsApk) {
-            return mApkResources.getManifestUrl();
-        }
-
-        // If this is a legacy shortcut, then we should have been able to get
-        // the URI from the intent data.  Otherwise, we should have been able
-        // to get it from the APK resources.  So we should never get here.
-        Log.wtf(LOGTAG, "Couldn't get URI from intent nor APK resources");
-        return null;
-    }
-
-    @Override
-    protected void loadStartupTab(final int flags) {
-        loadStartupTab(null, null, flags);
-    }
-
-    // Note: there is no support for loading with intent extras in
-    // Webapps at the moment because I don't have time to debug/test.
-    @Override
-    protected void loadStartupTab(final String uri, final SafeIntent unusedIntent, int flags) {
-        // Load a tab so it's available for any code that assumes a tab
-        // before the app tab itself is loaded in BrowserApp._loadWebapp.
-        flags = Tabs.LOADURL_NEW_TAB | Tabs.LOADURL_USER_ENTERED | Tabs.LOADURL_EXTERNAL;
-        super.loadStartupTab("about:blank", null, flags);
-    }
-
-    private void showSplash() {
-        // get the favicon dominant color, stored when the app was installed
-        int dominantColor = Allocator.getInstance().getColor(getIndex());
-
-        setBackgroundGradient(dominantColor);
-
-        ImageView image = (ImageView)findViewById(R.id.splashscreen_icon);
-        Drawable d = null;
-
-        if (mIsApk) {
-            Uri uri = mApkResources.getAppIconUri();
-            image.setImageURI(uri);
-            d = image.getDrawable();
-        } else {
-            // look for a logo.png in the profile dir and show it. If we can't find a logo show nothing
-            File profile = getProfile().getDir();
-            File logoFile = new File(profile, "logo.png");
-            if (logoFile.exists()) {
-                d = Drawable.createFromPath(logoFile.getPath());
-                image.setImageDrawable(d);
-            }
-        }
-
-        if (d != null) {
-            Animation fadein = AnimationUtils.loadAnimation(this, R.anim.grow_fade_in_center);
-            fadein.setStartOffset(500);
-            fadein.setDuration(1000);
-            image.startAnimation(fadein);
-        }
-    }
-
-    public void setBackgroundGradient(int dominantColor) {
-        int[] colors = new int[2];
-        // now lighten it, to ensure that the icon stands out in the center
-        float[] f = new float[3];
-        Color.colorToHSV(dominantColor, f);
-        f[2] = Math.min(f[2]*2, 1.0f);
-        colors[0] = Color.HSVToColor(255, f);
-
-        // now generate a second, slightly darker version of the same color
-        f[2] *= 0.75;
-        colors[1] = Color.HSVToColor(255, f);
-
-        // Draw the background gradient
-        GradientDrawable gd = new GradientDrawable(GradientDrawable.Orientation.TL_BR, colors);
-        gd.setGradientType(GradientDrawable.RADIAL_GRADIENT);
-        Display display = getWindowManager().getDefaultDisplay();
-        gd.setGradientCenter(0.5f, 0.5f);
-        gd.setGradientRadius(Math.max(display.getWidth()/2, display.getHeight()/2));
-        mSplashscreen.setBackgroundDrawable(gd);
-    }
-
-    /* (non-Javadoc)
-     * @see org.mozilla.gecko.GeckoApp#getDefaultProfileName()
-     */
-    @Override
-    protected String getDefaultProfileName() {
-        return "webapp" + getIndex();
-    }
-
-    @Override
-    protected boolean getSessionRestoreState(Bundle savedInstanceState) {
-        // for now webapps never restore your session
-        return false;
-    }
-
-    @Override
-    public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) {
-        switch(msg) {
-            case SELECTED:
-            case LOCATION_CHANGE:
-                if (Tabs.getInstance().isSelectedTab(tab)) {
-                    final String urlString = tab.getURL();
-
-                    // Don't show the titlebar for about:blank, which we load
-                    // into the initial tab we create while waiting for the app
-                    // to load.
-                    if (urlString != null && urlString.equals("about:blank")) {
-                        mTitlebar.setVisibility(View.GONE);
-                        return;
-                    }
-
-                    final URI uri;
-
-                    try {
-                        uri = new URI(urlString);
-                    } catch (java.net.URISyntaxException ex) {
-                        mTitlebarText.setText(urlString);
-
-                        // If we can't parse the url, and its an app protocol hide
-                        // the titlebar and return, otherwise show the titlebar
-                        // and the full url
-                        if (urlString != null && !urlString.startsWith("app://")) {
-                            mTitlebar.setVisibility(View.VISIBLE);
-                        } else {
-                            mTitlebar.setVisibility(View.GONE);
-                        }
-                        return;
-                    }
-
-                    if (mOrigin != null && mOrigin.getHost().equals(uri.getHost())) {
-                        mTitlebar.setVisibility(View.GONE);
-                    } else {
-                        mTitlebarText.setText(uri.getScheme() + "://" + uri.getHost());
-                        mTitlebar.setVisibility(View.VISIBLE);
-                    }
-                }
-                break;
-            case LOADED:
-                hideSplash();
-                break;
-            case START:
-                if (mSplashscreen != null && mSplashscreen.getVisibility() == View.VISIBLE) {
-                    View area = findViewById(R.id.splashscreen_progress);
-                    area.setVisibility(View.VISIBLE);
-                    Animation fadein = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
-                    fadein.setDuration(1000);
-                    area.startAnimation(fadein);
-                }
-                break;
-        }
-        super.onTabChanged(tab, msg, data);
-    }
-
-    protected void hideSplash() {
-        if (mSplashscreen != null && mSplashscreen.getVisibility() == View.VISIBLE) {
-            Animation fadeout = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
-            fadeout.setAnimationListener(new Animation.AnimationListener() {
-                @Override
-                public void onAnimationEnd(Animation animation) {
-                  mSplashscreen.setVisibility(View.GONE);
-                }
-                @Override
-                public void onAnimationRepeat(Animation animation) { }
-                @Override
-                public void onAnimationStart(Animation animation) { }
-            });
-            mSplashscreen.startAnimation(fadeout);
-        }
-    }
-
-    @Override
-    public void installCompleted(InstallHelper installHelper, String event, NativeJSObject message) {
-        if (event == null) {
-            return;
-        }
-
-        if (event.equals("Webapps:Postinstall")) {
-            String origin = message.optString("origin", null);
-            launchWebapp(origin);
-        }
-    }
-
-    @Override
-    public void installErrored(InstallHelper installHelper, Exception exception) {
-        Log.e(LOGTAG, "Install errored", exception);
-    }
-
-    private void setOrigin(String origin) {
-        try {
-            mOrigin = new URI(origin);
-        } catch (java.net.URISyntaxException ex) {
-            // If this isn't an app: URL, just settle for not having an origin.
-            if (!origin.startsWith("app://")) {
-                return;
-            }
-
-            // If that failed fall back to the origin stored in the shortcut.
-            if (!mIsApk) {
-                Log.i(LOGTAG, "Origin is app: URL; falling back to intent URL");
-                Uri data = getIntent().getData();
-                if (data != null) {
-                    try {
-                        mOrigin = new URI(data.toString());
-                    } catch (java.net.URISyntaxException ex2) {
-                        Log.e(LOGTAG, "Unable to parse intent URL: ", ex);
-                    }
-                }
-            }
-        }
-    }
-
-    public void launchWebapp(String origin) {
-        setOrigin(origin);
-
-        try {
-            JSONObject launchObject = new JSONObject();
-            launchObject.putOpt("url", mManifestUrl);
-            launchObject.putOpt("name", mAppName);
-            Log.i(LOGTAG, "Trying to launch: " + launchObject);
-            GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Webapps:Load", launchObject.toString()));
-        } catch (JSONException e) {
-            Log.e(LOGTAG, "Error populating launch message", e);
-        }
-    }
-
-    @Override
-    protected boolean getIsDebuggable() {
-        if (mIsApk) {
-            return mApkResources.isDebuggable();
-        }
-
-        // This is a legacy shortcut, which didn't provide a way to determine
-        // that the app is debuggable, so we say the app is not debuggable.
-        return false;
-    }
-
-    @Override
-    protected StartupAction getStartupAction(final String passedURL, final String action) {
-        return StartupAction.WEBAPP;
-    }
-}
deleted file mode 100644
--- a/mobile/android/base/java/org/mozilla/gecko/webapp/Webapps.java
+++ /dev/null
@@ -1,513 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * 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/. */
-
-package org.mozilla.gecko.webapp;
-
-/**
- * Declare a predefined number of Webapp<num> classes to the Webapps class.
- * These are used so that each web app can launch in its own process. Keep this
- * number in sync with the number of web apps defined in the Android manifest.
- */
-public final class Webapps {
-    public static class Webapp0 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 0; }
-    }
-
-    public static class Webapp1 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 1; }
-    }
-
-    public static class Webapp2 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 2; }
-    }
-
-    public static class Webapp3 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 3; }
-    }
-
-    public static class Webapp4 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 4; }
-    }
-
-    public static class Webapp5 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 5; }
-    }
-
-    public static class Webapp6 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 6; }
-    }
-
-    public static class Webapp7 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 7; }
-    }
-
-    public static class Webapp8 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 8; }
-    }
-
-    public static class Webapp9 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 9; }
-    }
-
-    public static class Webapp10 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 10; }
-    }
-
-    public static class Webapp11 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 11; }
-    }
-
-    public static class Webapp12 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 12; }
-    }
-
-    public static class Webapp13 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 13; }
-    }
-
-    public static class Webapp14 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 14; }
-    }
-
-    public static class Webapp15 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 15; }
-    }
-
-    public static class Webapp16 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 16; }
-    }
-
-    public static class Webapp17 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 17; }
-    }
-
-    public static class Webapp18 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 18; }
-    }
-
-    public static class Webapp19 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 19; }
-    }
-
-    public static class Webapp20 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 20; }
-    }
-
-    public static class Webapp21 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 21; }
-    }
-
-    public static class Webapp22 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 22; }
-    }
-
-    public static class Webapp23 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 23; }
-    }
-
-    public static class Webapp24 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 24; }
-    }
-
-    public static class Webapp25 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 25; }
-    }
-
-    public static class Webapp26 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 26; }
-    }
-
-    public static class Webapp27 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 27; }
-    }
-
-    public static class Webapp28 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 28; }
-    }
-
-    public static class Webapp29 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 29; }
-    }
-
-    public static class Webapp30 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 30; }
-    }
-
-    public static class Webapp31 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 31; }
-    }
-
-    public static class Webapp32 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 32; }
-    }
-
-    public static class Webapp33 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 33; }
-    }
-
-    public static class Webapp34 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 34; }
-    }
-
-    public static class Webapp35 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 35; }
-    }
-
-    public static class Webapp36 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 36; }
-    }
-
-    public static class Webapp37 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 37; }
-    }
-
-    public static class Webapp38 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 38; }
-    }
-
-    public static class Webapp39 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 39; }
-    }
-
-    public static class Webapp40 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 40; }
-    }
-
-    public static class Webapp41 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 41; }
-    }
-
-    public static class Webapp42 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 42; }
-    }
-
-    public static class Webapp43 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 43; }
-    }
-
-    public static class Webapp44 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 44; }
-    }
-
-    public static class Webapp45 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 45; }
-    }
-
-    public static class Webapp46 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 46; }
-    }
-
-    public static class Webapp47 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 47; }
-    }
-
-    public static class Webapp48 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 48; }
-    }
-
-    public static class Webapp49 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 49; }
-    }
-
-    public static class Webapp50 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 50; }
-    }
-
-    public static class Webapp51 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 51; }
-    }
-
-    public static class Webapp52 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 52; }
-    }
-
-    public static class Webapp53 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 53; }
-    }
-
-    public static class Webapp54 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 54; }
-    }
-
-    public static class Webapp55 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 55; }
-    }
-
-    public static class Webapp56 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 56; }
-    }
-
-    public static class Webapp57 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 57; }
-    }
-
-    public static class Webapp58 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 58; }
-    }
-
-    public static class Webapp59 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 59; }
-    }
-
-    public static class Webapp60 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 60; }
-    }
-
-    public static class Webapp61 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 61; }
-    }
-
-    public static class Webapp62 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 62; }
-    }
-
-    public static class Webapp63 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 63; }
-    }
-
-    public static class Webapp64 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 64; }
-    }
-
-    public static class Webapp65 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 65; }
-    }
-
-    public static class Webapp66 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 66; }
-    }
-
-    public static class Webapp67 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 67; }
-    }
-
-    public static class Webapp68 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 68; }
-    }
-
-    public static class Webapp69 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 69; }
-    }
-
-    public static class Webapp70 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 70; }
-    }
-
-    public static class Webapp71 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 71; }
-    }
-
-    public static class Webapp72 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 72; }
-    }
-
-    public static class Webapp73 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 73; }
-    }
-
-    public static class Webapp74 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 74; }
-    }
-
-    public static class Webapp75 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 75; }
-    }
-
-    public static class Webapp76 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 76; }
-    }
-
-    public static class Webapp77 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 77; }
-    }
-
-    public static class Webapp78 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 78; }
-    }
-
-    public static class Webapp79 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 79; }
-    }
-
-    public static class Webapp80 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 80; }
-    }
-
-    public static class Webapp81 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 81; }
-    }
-
-    public static class Webapp82 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 82; }
-    }
-
-    public static class Webapp83 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 83; }
-    }
-
-    public static class Webapp84 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 84; }
-    }
-
-    public static class Webapp85 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 85; }
-    }
-
-    public static class Webapp86 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 86; }
-    }
-
-    public static class Webapp87 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 87; }
-    }
-
-    public static class Webapp88 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 88; }
-    }
-
-    public static class Webapp89 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 89; }
-    }
-
-    public static class Webapp90 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 90; }
-    }
-
-    public static class Webapp91 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 91; }
-    }
-
-    public static class Webapp92 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 92; }
-    }
-
-    public static class Webapp93 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 93; }
-    }
-
-    public static class Webapp94 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 94; }
-    }
-
-    public static class Webapp95 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 95; }
-    }
-
-    public static class Webapp96 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 96; }
-    }
-
-    public static class Webapp97 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 97; }
-    }
-
-    public static class Webapp98 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 98; }
-    }
-
-    public static class Webapp99 extends WebappImpl {
-        @Override
-        protected int getIndex() { return 99; }
-    }
-}
--- a/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedEditText.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedEditText.java
@@ -44,18 +44,18 @@ public class ThemedEditText extends andr
     }
 
     public ThemedEditText(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         initialize(context, attrs, defStyle);
     }
 
     private void initialize(final Context context, final AttributeSet attrs, final int defStyle) {
-        // The theme can be null, particularly for webapps: Bug 1089266.  Or we
-        // might be instantiating this View in an IDE, with no ambient GeckoApplication.
+        // The theme can be null, particularly if we might be instantiating this
+        // View in an IDE, with no ambient GeckoApplication.
         final Context applicationContext = context.getApplicationContext();
         if (applicationContext instanceof GeckoApplication) {
             theme = ((GeckoApplication) applicationContext).getLightweightTheme();
         }
 
         final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LightweightTheme);
         autoUpdateTheme = theme != null && a.getBoolean(R.styleable.LightweightTheme_autoUpdateTheme, true);
         a.recycle();
--- a/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedFrameLayout.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedFrameLayout.java
@@ -44,18 +44,18 @@ public class ThemedFrameLayout extends a
     }
 
     public ThemedFrameLayout(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         initialize(context, attrs, defStyle);
     }
 
     private void initialize(final Context context, final AttributeSet attrs, final int defStyle) {
-        // The theme can be null, particularly for webapps: Bug 1089266.  Or we
-        // might be instantiating this View in an IDE, with no ambient GeckoApplication.
+        // The theme can be null, particularly if we might be instantiating this
+        // View in an IDE, with no ambient GeckoApplication.
         final Context applicationContext = context.getApplicationContext();
         if (applicationContext instanceof GeckoApplication) {
             theme = ((GeckoApplication) applicationContext).getLightweightTheme();
         }
 
         final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LightweightTheme);
         autoUpdateTheme = theme != null && a.getBoolean(R.styleable.LightweightTheme_autoUpdateTheme, true);
         a.recycle();
--- a/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedImageButton.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedImageButton.java
@@ -44,18 +44,18 @@ public class ThemedImageButton extends a
     }
 
     public ThemedImageButton(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         initialize(context, attrs, defStyle);
     }
 
     private void initialize(final Context context, final AttributeSet attrs, final int defStyle) {
-        // The theme can be null, particularly for webapps: Bug 1089266.  Or we
-        // might be instantiating this View in an IDE, with no ambient GeckoApplication.
+        // The theme can be null, particularly if we might be instantiating this
+        // View in an IDE, with no ambient GeckoApplication.
         final Context applicationContext = context.getApplicationContext();
         if (applicationContext instanceof GeckoApplication) {
             theme = ((GeckoApplication) applicationContext).getLightweightTheme();
         }
 
         final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LightweightTheme);
         autoUpdateTheme = theme != null && a.getBoolean(R.styleable.LightweightTheme_autoUpdateTheme, true);
         a.recycle();
--- a/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedImageView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedImageView.java
@@ -44,18 +44,18 @@ public class ThemedImageView extends and
     }
 
     public ThemedImageView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         initialize(context, attrs, defStyle);
     }
 
     private void initialize(final Context context, final AttributeSet attrs, final int defStyle) {
-        // The theme can be null, particularly for webapps: Bug 1089266.  Or we
-        // might be instantiating this View in an IDE, with no ambient GeckoApplication.
+        // The theme can be null, particularly if we might be instantiating this
+        // View in an IDE, with no ambient GeckoApplication.
         final Context applicationContext = context.getApplicationContext();
         if (applicationContext instanceof GeckoApplication) {
             theme = ((GeckoApplication) applicationContext).getLightweightTheme();
         }
 
         final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LightweightTheme);
         autoUpdateTheme = theme != null && a.getBoolean(R.styleable.LightweightTheme_autoUpdateTheme, true);
         a.recycle();
--- a/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedLinearLayout.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedLinearLayout.java
@@ -39,18 +39,18 @@ public class ThemedLinearLayout extends 
     private ColorStateList drawableColors;
 
     public ThemedLinearLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
         initialize(context, attrs, 0);
     }
 
     private void initialize(final Context context, final AttributeSet attrs, final int defStyle) {
-        // The theme can be null, particularly for webapps: Bug 1089266.  Or we
-        // might be instantiating this View in an IDE, with no ambient GeckoApplication.
+        // The theme can be null, particularly if we might be instantiating this
+        // View in an IDE, with no ambient GeckoApplication.
         final Context applicationContext = context.getApplicationContext();
         if (applicationContext instanceof GeckoApplication) {
             theme = ((GeckoApplication) applicationContext).getLightweightTheme();
         }
 
         final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LightweightTheme);
         autoUpdateTheme = theme != null && a.getBoolean(R.styleable.LightweightTheme_autoUpdateTheme, true);
         a.recycle();
--- a/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedRelativeLayout.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedRelativeLayout.java
@@ -44,18 +44,18 @@ public class ThemedRelativeLayout extend
     }
 
     public ThemedRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         initialize(context, attrs, defStyle);
     }
 
     private void initialize(final Context context, final AttributeSet attrs, final int defStyle) {
-        // The theme can be null, particularly for webapps: Bug 1089266.  Or we
-        // might be instantiating this View in an IDE, with no ambient GeckoApplication.
+        // The theme can be null, particularly if we might be instantiating this
+        // View in an IDE, with no ambient GeckoApplication.
         final Context applicationContext = context.getApplicationContext();
         if (applicationContext instanceof GeckoApplication) {
             theme = ((GeckoApplication) applicationContext).getLightweightTheme();
         }
 
         final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LightweightTheme);
         autoUpdateTheme = theme != null && a.getBoolean(R.styleable.LightweightTheme_autoUpdateTheme, true);
         a.recycle();
--- a/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedTextSwitcher.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedTextSwitcher.java
@@ -39,18 +39,18 @@ public class ThemedTextSwitcher extends 
     private ColorStateList drawableColors;
 
     public ThemedTextSwitcher(Context context, AttributeSet attrs) {
         super(context, attrs);
         initialize(context, attrs, 0);
     }
 
     private void initialize(final Context context, final AttributeSet attrs, final int defStyle) {
-        // The theme can be null, particularly for webapps: Bug 1089266.  Or we
-        // might be instantiating this View in an IDE, with no ambient GeckoApplication.
+        // The theme can be null, particularly if we might be instantiating this
+        // View in an IDE, with no ambient GeckoApplication.
         final Context applicationContext = context.getApplicationContext();
         if (applicationContext instanceof GeckoApplication) {
             theme = ((GeckoApplication) applicationContext).getLightweightTheme();
         }
 
         final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LightweightTheme);
         autoUpdateTheme = theme != null && a.getBoolean(R.styleable.LightweightTheme_autoUpdateTheme, true);
         a.recycle();
--- a/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedTextView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedTextView.java
@@ -44,18 +44,18 @@ public class ThemedTextView extends andr
     }
 
     public ThemedTextView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         initialize(context, attrs, defStyle);
     }
 
     private void initialize(final Context context, final AttributeSet attrs, final int defStyle) {
-        // The theme can be null, particularly for webapps: Bug 1089266.  Or we
-        // might be instantiating this View in an IDE, with no ambient GeckoApplication.
+        // The theme can be null, particularly if we might be instantiating this
+        // View in an IDE, with no ambient GeckoApplication.
         final Context applicationContext = context.getApplicationContext();
         if (applicationContext instanceof GeckoApplication) {
             theme = ((GeckoApplication) applicationContext).getLightweightTheme();
         }
 
         final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LightweightTheme);
         autoUpdateTheme = theme != null && a.getBoolean(R.styleable.LightweightTheme_autoUpdateTheme, true);
         a.recycle();
--- a/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedView.java
@@ -44,18 +44,18 @@ public class ThemedView extends android.
     }
 
     public ThemedView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         initialize(context, attrs, defStyle);
     }
 
     private void initialize(final Context context, final AttributeSet attrs, final int defStyle) {
-        // The theme can be null, particularly for webapps: Bug 1089266.  Or we
-        // might be instantiating this View in an IDE, with no ambient GeckoApplication.
+        // The theme can be null, particularly if we might be instantiating this
+        // View in an IDE, with no ambient GeckoApplication.
         final Context applicationContext = context.getApplicationContext();
         if (applicationContext instanceof GeckoApplication) {
             theme = ((GeckoApplication) applicationContext).getLightweightTheme();
         }
 
         final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LightweightTheme);
         autoUpdateTheme = theme != null && a.getBoolean(R.styleable.LightweightTheme_autoUpdateTheme, true);
         a.recycle();
--- a/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedView.java.frag
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/themed/ThemedView.java.frag
@@ -47,18 +47,18 @@ public class Themed@VIEW_NAME_SUFFIX@ ex
 //#ifdef STYLE_CONSTRUCTOR
     public Themed@VIEW_NAME_SUFFIX@(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         initialize(context, attrs, defStyle);
     }
 
 //#endif
     private void initialize(final Context context, final AttributeSet attrs, final int defStyle) {
-        // The theme can be null, particularly for webapps: Bug 1089266.  Or we
-        // might be instantiating this View in an IDE, with no ambient GeckoApplication.
+        // The theme can be null, particularly if we might be instantiating this
+        // View in an IDE, with no ambient GeckoApplication.
         final Context applicationContext = context.getApplicationContext();
         if (applicationContext instanceof GeckoApplication) {
             theme = ((GeckoApplication) applicationContext).getLightweightTheme();
         }
 
         final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LightweightTheme);
         autoUpdateTheme = theme != null && a.getBoolean(R.styleable.LightweightTheme_autoUpdateTheme, true);
         a.recycle();
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -645,18 +645,16 @@ just addresses the organization to follo
       replaced with the name of the currently highlighted icon. -->
 <!ENTITY search_bar_item_desc "Search with &formatS;">
 
 <!-- Localization note (suggestion_for_engine): The placeholder &formatS1; will be
      replaced with the name of the search engine. The placeholder &formatS2; will be
      replaced with the search query. -->
 <!ENTITY suggestion_for_engine "Search &formatS1; for &formatS2;">
 
-<!ENTITY webapp_generic_name "App">
-
 <!ENTITY searchable_description "Bookmarks and history">
 
  <!-- Updater notifications -->
 <!ENTITY updater_start_title2 "Update available for &brandShortName;">
 <!ENTITY updater_start_select2 "Touch to download">
 
 <!ENTITY updater_downloading_title2 "Downloading &brandShortName;">
 <!ENTITY updater_downloading_title_failed2 "Download failed">
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -575,27 +575,16 @@ gbjar.sources += ['java/org/mozilla/geck
     'toolbar/ToolbarEditText.java',
     'toolbar/ToolbarPrefs.java',
     'toolbar/ToolbarProgressView.java',
     'TouchEventInterceptor.java',
     'trackingprotection/TrackingProtectionPrompt.java',
     'updater/UpdateService.java',
     'updater/UpdateServiceHelper.java',
     'util/Experiments.java',
-    'Webapp.java',
-    'webapp/Allocator.java',
-    'webapp/ApkResources.java',
-    'webapp/Dispatcher.java',
-    'webapp/EventListener.java',
-    'webapp/InstallHelper.java',
-    'webapp/InstallListener.java',
-    'webapp/TaskKiller.java',
-    'webapp/UninstallListener.java',
-    'webapp/WebappImpl.java',
-    'webapp/Webapps.java',
     'widget/ActivityChooserModel.java',
     'widget/AllCapsTextView.java',
     'widget/AnchoredPopup.java',
     'widget/AnimatedHeightLayout.java',
     'widget/BasicColorPicker.java',
     'widget/ButtonToast.java',
     'widget/CheckableLinearLayout.java',
     'widget/ClickableWhenDisabledEditText.java',
--- a/mobile/android/base/resources/layout/shared_ui_components.xml
+++ b/mobile/android/base/resources/layout/shared_ui_components.xml
@@ -1,15 +1,15 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- 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/. -->
 
 <!-- This file is used to include shared UI components in different gecko app
-     layouts, such as gecko_app.xml and web_app.xml -->
+     layouts, such as gecko_app.xml -->
 
 <merge xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:gecko="http://schemas.android.com/apk/res-auto">
 
     <org.mozilla.gecko.GeckoView android:id="@+id/layer_view"
                                  gecko:doinit="false"
                                  android:layout_width="match_parent"
                                  android:layout_height="match_parent"
deleted file mode 100644
--- a/mobile/android/base/resources/layout/web_app.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:id="@+id/main_layout"
-              android:orientation="vertical"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent">
-
-    <LinearLayout android:id="@+id/webapp_titlebar"
-                  android:visibility="gone"
-                  style="@style/WebView.Titlebar"
-                  android:layout_width="match_parent"
-                  android:layout_height="wrap_content"
-                  android:orientation="horizontal">
-    
-        <TextView android:id="@+id/webapp_title"
-                  style="@style/WebView.Titlebar.Title"
-                  android:layout_width="match_parent"
-                  android:layout_height="wrap_content"
-                  android:singleLine="true"/>
-
-    </LinearLayout>
-
-    <RelativeLayout android:id="@+id/gecko_layout"
-                    android:layout_width="match_parent"
-                    android:layout_height="match_parent"
-                    android:layout_below="@+id/webapp_titlebar">
-
-        <include layout="@layout/shared_ui_components"/>
-
-        <RelativeLayout android:id="@+id/splashscreen"
-                        android:layout_width="match_parent"
-                        android:layout_height="match_parent" >
-
-            <ImageView android:id="@+id/splashscreen_icon"
-                      android:minWidth="128dip"
-                      android:minHeight="128dip"
-                      android:layout_width="wrap_content"
-                      android:layout_height="wrap_content"
-                      android:layout_centerHorizontal="true"
-                      android:layout_centerVertical="true"/>
-
-            <ProgressBar android:id="@+id/splashscreen_progress"
-                         android:layout_width="wrap_content"
-                         android:layout_height="wrap_content"
-                         android:gravity="center"
-                         android:layout_centerHorizontal="true"
-                         android:layout_alignParentBottom="true"
-                         android:paddingBottom="30dip"
-                         android:visibility="gone"/>
-
-        </RelativeLayout>
-
-    </RelativeLayout>
-
-    <ViewStub android:id="@+id/toast_stub"
-              android:layout="@layout/button_toast"
-              style="@style/Toast"/>
-
-</RelativeLayout>
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -518,18 +518,16 @@
 
   <!-- Bookmark import/export -->
   <string name="bookmarkhistory_button_import">&bookmarkhistory_button_import;</string>
   <string name="bookmarkhistory_import_both">&bookmarkhistory_import_both;</string>
   <string name="bookmarkhistory_import_bookmarks">&bookmarkhistory_import_bookmarks;</string>
   <string name="bookmarkhistory_import_history">&bookmarkhistory_import_history;</string>
   <string name="bookmarkhistory_import_wait">&bookmarkhistory_import_wait;</string>
 
-  <string name="webapp_generic_name">&webapp_generic_name;</string>
-
   <string name="searchable_description">&searchable_description;</string>
 
   <!-- Updater notifications -->
   <string name="updater_start_title">&updater_start_title2;</string>
   <string name="updater_start_select">&updater_start_select2;</string>
 
   <string name="updater_downloading_title">&updater_downloading_title2;</string>
   <string name="updater_downloading_title_failed">&updater_downloading_title_failed2;</string>
deleted file mode 100644
--- a/mobile/android/chrome/content/WebappRT.js
+++ /dev/null
@@ -1,218 +0,0 @@
-/* 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/. */
-
-/*globals PermissionsInstaller */
-
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-Cu.import("resource://gre/modules/PermissionsInstaller.jsm");
-Cu.import("resource://gre/modules/ContactService.jsm");
-Cu.import("resource://gre/modules/AppsUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Notifications", "resource://gre/modules/Notifications.jsm");
-
-function pref(name, value) {
-  return {
-    name: name,
-    value: value
-  }
-}
-
-var WebappRT = {
-  prefs: [
-    // Disable all add-on locations other than the profile (which can't be disabled this way)
-    pref("extensions.enabledScopes", 1),
-    // Auto-disable any add-ons that are "dropped in" to the profile
-    pref("extensions.autoDisableScopes", 1),
-    // Disable add-on installation via the web-exposed APIs
-    pref("xpinstall.enabled", false),
-    pref("media.useAudioChannelAPI", true),
-    pref("dom.mozTCPSocket.enabled", true),
-
-    // Enabled system messages for web activity support
-    pref("dom.sysmsg.enabled", true),
-  ],
-
-  init: function(aStatus, aUrl, aCallback) {
-    this.deck = document.getElementById("browsers");
-    this.deck.addEventListener("click", this, false, true);
-
-    // on first run, update any prefs
-    if (aStatus == "new") {
-      this.prefs.forEach(this.addPref);
-
-      // update the blocklist url to use a different app id
-      let blocklist = Services.prefs.getCharPref("extensions.blocklist.url");
-      blocklist = blocklist.replace(/%APP_ID%/g, "webapprt-mobile@mozilla.org");
-      Services.prefs.setCharPref("extensions.blocklist.url", blocklist);
-    }
-
-    // On firstrun, set permissions to their default values.
-    // When the webapp runtime is updated, update the permissions.
-    if (aStatus == "new" || aStatus == "upgrade") {
-      this.getManifestFor(aUrl, function (aManifest, aApp) {
-        if (aManifest) {
-          PermissionsInstaller.installPermissions(aApp, true);
-        }
-      });
-    }
-
-    // If the app is in debug mode, configure and enable the remote debugger.
-    Messaging.sendRequestForResult({ type: "NativeApp:IsDebuggable" }).then((response) => {
-      let that = this;
-      let name = this._getAppName(aUrl);
-
-       if (response.isDebuggable) {
-        Notifications.create({
-          title: Strings.browser.formatStringFromName("remoteStartNotificationTitle", [name], 1),
-          message: Strings.browser.GetStringFromName("remoteStartNotificationMessage"),
-          icon: "drawable://warning_doorhanger",
-          onClick: function(aId, aCookie) {
-            that._enableRemoteDebugger(aUrl);
-          },
-        });
-      }
-    });
-
-    this.findManifestUrlFor(aUrl, (function(aLaunchUrl) {
-      if (aStatus == "new") {
-        if (BrowserApp.manifest && BrowserApp.manifest.orientation) {
-          let orientation = BrowserApp.manifest.orientation;
-          if (Array.isArray(orientation)) {
-            orientation = orientation.join(",");
-          }
-          this.addPref(pref("app.orientation.default", orientation));
-        }
-      }
-
-      aCallback(aLaunchUrl);
-    }).bind(this));
-  },
-
-  getManifestFor: function (aUrl, aCallback) {
-    let request = navigator.mozApps.mgmt.getAll();
-    request.onsuccess = function() {
-      let apps = request.result;
-      for (let i = 0; i < apps.length; i++) {
-        let app = apps[i];
-        let manifest = new ManifestHelper(app.manifest, app.origin, app.manifestURL);
-
-        // if this is a path to the manifest, or the launch path, then we have a hit.
-        if (app.manifestURL == aUrl || manifest.fullLaunchPath() == aUrl) {
-          aCallback(manifest, app);
-          return;
-        }
-      }
-
-      // Otherwise, once we loop through all of them, we have a miss.
-      aCallback(undefined);
-    };
-
-    request.onerror = function() {
-      // Treat an error like a miss. We can't find the manifest.
-      aCallback(undefined);
-    };
-  },
-
-  findManifestUrlFor: function(aUrl, aCallback) {
-    this.getManifestFor(aUrl, function(aManifest, aApp) {
-      if (!aManifest) {
-        // we can't find the manifest, so open it like a web page
-        aCallback(aUrl);
-        return;
-      }
-
-      BrowserApp.manifest = aManifest;
-      BrowserApp.manifestUrl = aApp.manifestURL;
-
-      aCallback(aManifest.fullLaunchPath());
-    });
-  },
-
-  addPref: function(aPref) {
-    switch (typeof aPref.value) {
-      case "string":
-        Services.prefs.setCharPref(aPref.name, aPref.value);
-        break;
-      case "boolean":
-        Services.prefs.setBoolPref(aPref.name, aPref.value);
-        break;
-      case "number":
-        Services.prefs.setIntPref(aPref.name, aPref.value);
-        break;
-    }
-  },
-
-  _getAppName: function(aUrl) {
-    let name = Strings.browser.GetStringFromName("remoteNotificationGenericName");
-    let app = DOMApplicationRegistry.getAppByManifestURL(aUrl);
-
-    if (app) {
-      name = app.name;
-    }
-
-    return name;
-  },
-
-
-  _enableRemoteDebugger: function(aUrl) {
-    // Skip the connection prompt in favor of notifying the user below.
-    Services.prefs.setBoolPref("devtools.debugger.prompt-connection", false);
-
-    // Automagically find a free port and configure the debugger to use it.
-    let serv = Cc['@mozilla.org/network/server-socket;1'].createInstance(Ci.nsIServerSocket);
-    serv.init(-1, true, -1);
-    let port = serv.port;
-    serv.close();
-    Services.prefs.setIntPref("devtools.debugger.remote-port", port);
-    // Clear the UNIX domain socket path to ensure a TCP socket will be used
-    // instead.
-    Services.prefs.setCharPref("devtools.debugger.unix-domain-socket", "");
-
-    Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
-
-    // Notify the user that we enabled the debugger and which port it's using
-    // so they can use the DevTools Connect… dialog to connect the client to it.
-    DOMApplicationRegistry.registryReady.then(() => {
-      let name = this._getAppName(aUrl);
-
-      Notifications.create({
-        title: Strings.browser.formatStringFromName("remoteNotificationTitle", [name], 1),
-        message: Strings.browser.formatStringFromName("remoteNotificationMessage", [port], 1),
-        icon: "drawable://warning_doorhanger",
-      });
-    });
-  },
-
-  handleEvent: function(event) {
-    let target = event.target;
-
-    // walk up the tree to find the nearest link tag
-    while (target && !(target instanceof HTMLAnchorElement)) {
-      target = target.parentNode;
-    }
-
-    if (!target || target.getAttribute("target") != "_blank") {
-      return;
-    }
-
-    let uri = Services.io.newURI(target.href, target.ownerDocument.characterSet, null);
-
-    // Direct the URL to the browser.
-    Cc["@mozilla.org/uriloader/external-protocol-service;1"].
-      getService(Ci.nsIExternalProtocolService).
-      getProtocolHandlerInfo(uri.scheme).
-      launchWithURI(uri);
-
-    // Prevent the runtime from loading the URL.  We do this after directing it
-    // to the browser to give the runtime a shot at handling the URL if we fail
-    // to direct it to the browser for some reason.
-    event.preventDefault();
-  }
-}
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -88,19 +88,16 @@ XPCOMUtils.defineLazyServiceGetter(this,
 
 XPCOMUtils.defineLazyServiceGetter(this, "Profiler",
                                    "@mozilla.org/tools/profiler;1",
                                    "nsIProfiler");
 
 XPCOMUtils.defineLazyModuleGetter(this, "SimpleServiceDiscovery",
                                   "resource://gre/modules/SimpleServiceDiscovery.jsm");
 
-XPCOMUtils.defineLazyModuleGetter(this, "WebappManager",
-                                  "resource://gre/modules/WebappManager.jsm");
-
 XPCOMUtils.defineLazyModuleGetter(this, "CharsetMenu",
                                   "resource://gre/modules/CharsetMenu.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "NetErrorHelper",
                                   "resource://gre/modules/NetErrorHelper.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PermissionsUtils",
                                   "resource://gre/modules/PermissionsUtils.jsm");
@@ -438,25 +435,16 @@ var BrowserApp = {
     Services.obs.addObserver(this, "Viewport:Change", false);
     Services.obs.addObserver(this, "Viewport:Flush", false);
     Services.obs.addObserver(this, "Passwords:Init", false);
     Services.obs.addObserver(this, "FormHistory:Init", false);
     Services.obs.addObserver(this, "android-get-pref", false);
     Services.obs.addObserver(this, "android-set-pref", false);
     Services.obs.addObserver(this, "gather-telemetry", false);
     Services.obs.addObserver(this, "keyword-search", false);
-    Services.obs.addObserver(this, "webapps-runtime-install", false);
-    Services.obs.addObserver(this, "webapps-runtime-install-package", false);
-    Services.obs.addObserver(this, "webapps-ask-install", false);
-    Services.obs.addObserver(this, "webapps-ask-uninstall", false);
-    Services.obs.addObserver(this, "webapps-launch", false);
-    Services.obs.addObserver(this, "webapps-runtime-uninstall", false);
-    Services.obs.addObserver(this, "Webapps:AutoInstall", false);
-    Services.obs.addObserver(this, "Webapps:Load", false);
-    Services.obs.addObserver(this, "Webapps:AutoUninstall", false);
     Services.obs.addObserver(this, "sessionstore-state-purge-complete", false);
     Services.obs.addObserver(this, "Fonts:Reload", false);
 
     Messaging.addListener(this.getHistory.bind(this), "Session:GetHistory");
 
     function showFullScreenWarning() {
       Snackbars.show(Strings.browser.GetStringFromName("alertFullScreenToast"), Snackbars.LENGTH_LONG);
     }
@@ -647,23 +635,16 @@ var BrowserApp = {
   /**
    * Pass this a locale string, such as "fr" or "es_ES".
    */
   setLocale: function (locale) {
     console.log("browser.js: requesting locale set: " + locale);
     Messaging.sendRequest({ type: "Locale:Set", locale: locale });
   },
 
-  _initRuntime: function(status, url, callback) {
-    let sandbox = {};
-    Services.scriptloader.loadSubScript("chrome://browser/content/WebappRT.js", sandbox);
-    window.WebappRT = sandbox.WebappRT;
-    WebappRT.init(status, url, callback);
-  },
-
   initContextMenu: function () {
     // We pass a thunk in place of a raw label string. This allows the
     // context menu to automatically accommodate locale changes without
     // having to be rebuilt.
     let stringGetter = name => () => Strings.browser.GetStringFromName(name);
 
     // TODO: These should eventually move into more appropriate classes
     NativeWindow.contextmenus.add(stringGetter("contextmenu.openInNewTab"),
@@ -1278,25 +1259,16 @@ var BrowserApp = {
 
     let message = {
       type: "Tab:Close",
       tabID: aTab.id
     };
     Messaging.sendRequest(message);
   },
 
-  _loadWebapp: function(aMessage) {
-    // Entry point for WebApps. This is the point in which we know
-    // the code is being used as a WebApp runtime.
-    this._initRuntime(this._startupStatus, aMessage.url, aUrl => {
-      this.manifestUrl = aMessage.url;
-      this.addTab(aUrl, { title: aMessage.name });
-    });
-  },
-
   // Calling this will update the state in BrowserApp after a tab has been
   // closed in the Java UI.
   _handleTabClosed: function _handleTabClosed(aTab, aShowUndoSnackbar) {
     if (aTab == this.selectedTab)
       this.selectedTab = null;
 
     let tabIndex = this._tabs.indexOf(aTab);
 
@@ -1933,54 +1905,16 @@ var BrowserApp = {
       case "sessionstore-state-purge-complete":
         Messaging.sendRequest({ type: "Session:StatePurged" });
         break;
 
       case "gather-telemetry":
         Messaging.sendRequest({ type: "Telemetry:Gather" });
         break;
 
-      case "webapps-runtime-install":
-        WebappManager.install(JSON.parse(aData), aSubject);
-        break;
-
-      case "webapps-runtime-install-package":
-        WebappManager.installPackage(JSON.parse(aData), aSubject);
-        break;
-
-      case "webapps-ask-install":
-        WebappManager.askInstall(JSON.parse(aData));
-        break;
-
-      case "webapps-ask-uninstall":
-        WebappManager.askUninstall(JSON.parse(aData));
-        break;
-
-      case "webapps-launch": {
-        WebappManager.launch(JSON.parse(aData));
-        break;
-      }
-
-      case "webapps-runtime-uninstall": {
-        WebappManager.uninstall(JSON.parse(aData), aSubject);
-        break;
-      }
-
-      case "Webapps:AutoInstall":
-        WebappManager.autoInstall(JSON.parse(aData));
-        break;
-
-      case "Webapps:Load":
-        this._loadWebapp(JSON.parse(aData));
-        break;
-
-      case "Webapps:AutoUninstall":
-        WebappManager.autoUninstall(JSON.parse(aData));
-        break;
-
       case "Locale:OS":
         // We know the system locale. We use this for generating Accept-Language headers.
         console.log("Locale:OS: " + aData);
         let currentOSLocale = this.getOSLocalePref();
         if (currentOSLocale == aData) {
           break;
         }
 
--- a/mobile/android/chrome/jar.mn
+++ b/mobile/android/chrome/jar.mn
@@ -29,17 +29,16 @@ chrome.jar:
   content/browser.xul                  (content/browser.xul)
   content/browser.js                   (content/browser.js)
   content/bindings/checkbox.xml        (content/bindings/checkbox.xml)
   content/bindings/settings.xml        (content/bindings/settings.xml)
   content/netError.xhtml               (content/netError.xhtml)
   content/SelectHelper.js              (content/SelectHelper.js)
   content/SelectionHandler.js          (content/SelectionHandler.js)
   content/ActionBarHandler.js          (content/ActionBarHandler.js)
-  content/WebappRT.js                  (content/WebappRT.js)
   content/EmbedRT.js                   (content/EmbedRT.js)
   content/InputWidgetHelper.js         (content/InputWidgetHelper.js)
   content/WebrtcUI.js                  (content/WebrtcUI.js)
   content/MemoryObserver.js            (content/MemoryObserver.js)
   content/ConsoleAPI.js                (content/ConsoleAPI.js)
   content/PluginHelper.js              (content/PluginHelper.js)
   content/PrintHelper.js               (content/PrintHelper.js)
   content/OfflineApps.js               (content/OfflineApps.js)
--- a/mobile/android/components/MobileComponents.manifest
+++ b/mobile/android/components/MobileComponents.manifest
@@ -36,21 +36,16 @@ category agent-style-sheets browser-cont
 component {8c1f07d6-cba3-4226-a315-8bd43d67d032} SessionStore.js
 contract @mozilla.org/browser/sessionstore;1 {8c1f07d6-cba3-4226-a315-8bd43d67d032}
 category app-startup SessionStore service,@mozilla.org/browser/sessionstore;1
 
 # ContentPermissionPrompt.js
 component {C6E8C44D-9F39-4AF7-BCC0-76E38A8310F5} ContentPermissionPrompt.js
 contract @mozilla.org/content-permission/prompt;1 {C6E8C44D-9F39-4AF7-BCC0-76E38A8310F5}
 
-# WebappsUpdateTimer.js
-component {8f7002cb-e959-4f0a-a2e8-563232564385} WebappsUpdateTimer.js
-contract @mozilla.org/webapps-update-timer;1 {8f7002cb-e959-4f0a-a2e8-563232564385}
-category update-timer WebappsUpdateTimer @mozilla.org/webapps-update-timer;1,getService,webapp-background-update-timer,browser.webapps.updateInterval,86400
-
 # PromptService.js
 component {9a61149b-2276-4a0a-b79c-be994ad106cf} PromptService.js
 contract @mozilla.org/prompter;1 {9a61149b-2276-4a0a-b79c-be994ad106cf}
 contract @mozilla.org/embedcomp/prompt-service;1 {9a61149b-2276-4a0a-b79c-be994ad106cf}
 component {80dae1e9-e0d2-4974-915f-f97050fa8068} PromptService.js
 contract @mozilla.org/network/authprompt-adapter-factory;1 {80dae1e9-e0d2-4974-915f-f97050fa8068}
 #endif
 
deleted file mode 100644
--- a/mobile/android/components/WebappsUpdateTimer.js
+++ /dev/null
@@ -1,78 +0,0 @@
-/* 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/. */
-
-/**
- * This component triggers a periodic webapp update check.
- */
-
-"use strict";
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-
-Cu.import("resource://gre/modules/JNI.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/WebappManager.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-const Log = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog.bind("WebappsUpdateTimer");
-
-function isWebAppProcess() {
-  let jenv = null;
-  try {
-    jenv = JNI.GetForThread();
-
-    let GeckoAppShell = JNI.LoadClass(jenv, "org.mozilla.gecko.GeckoAppShell", {
-      static_methods: [
-        { name: "isWebAppProcess", sig: "()Z" }
-      ],
-    });
-
-    return GeckoAppShell.isWebAppProcess();
-  } finally {
-    if (jenv) {
-      JNI.UnloadClasses(jenv);
-    }
-  }
-}
-
-function WebappsUpdateTimer() {}
-
-WebappsUpdateTimer.prototype = {
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsITimerCallback,
-                                         Ci.nsISupportsWeakReference]),
-  classID: Components.ID("{8f7002cb-e959-4f0a-a2e8-563232564385}"),
-
-  notify: function(aTimer) {
-    // Ignore the timer if automatic update checks are disabled or if this
-    // is a webapp process (since we only want to bug people about updates
-    // from the browser process).
-    if (Services.prefs.getIntPref("browser.webapps.checkForUpdates") == 0 || !isWebAppProcess()) {
-      return;
-    }
-
-    // If we are offline, wait to be online to start the update check.
-    if (Services.io.offline) {
-      Log.i("network offline for webapp update check; waiting");
-      Services.obs.addObserver(this, "network:offline-status-changed", true);
-      return;
-    }
-
-    Log.i("periodic check for webapp updates");
-    WebappManager.checkForUpdates();
-  },
-
-  observe: function(aSubject, aTopic, aData) {
-    if (aTopic !== "network:offline-status-changed" || aData !== "online") {
-      return;
-    }
-
-    Log.i("network back online for webapp update check; commencing");
-    Services.obs.removeObserver(this, "network:offline-status-changed");
-    WebappManager.checkForUpdates();
-  }
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WebappsUpdateTimer]);
--- a/mobile/android/components/moz.build
+++ b/mobile/android/components/moz.build
@@ -30,17 +30,16 @@ EXTRA_COMPONENTS += [
 if not CONFIG['MOZ_B2GDROID']:
     EXTRA_COMPONENTS += [
         'ContentPermissionPrompt.js',
         'FilePicker.js',
         'HelperAppDialog.js',
         'PromptService.js',
         'SessionStore.js',
         'SiteSpecificUserAgent.js',
-        'WebappsUpdateTimer.js',
     ]
 
 # Keep it this way if at all possible.  If you need preprocessing,
 # consider adding fields to AppConstants.jsm.
 EXTRA_PP_COMPONENTS += [
     'MobileComponents.manifest',
 ]
 
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -552,16 +552,15 @@
 
 #ifdef ENABLE_MARIONETTE
 @BINPATH@/chrome/marionette@JAREXT@
 @BINPATH@/chrome/marionette.manifest
 @BINPATH@/components/MarionetteComponents.manifest
 @BINPATH@/components/marionettecomponent.js
 #endif
 
-@BINPATH@/components/WebappsUpdateTimer.js
 @BINPATH@/components/DataStore.manifest
 @BINPATH@/components/DataStoreImpl.js
 @BINPATH@/components/dom_datastore.xpt
 
 #ifdef PKG_LOCALE_MANIFEST
 #include @PKG_LOCALE_MANIFEST@
 #endif
deleted file mode 100644
--- a/mobile/android/locales/en-US/chrome/webapp.properties
+++ /dev/null
@@ -1,59 +0,0 @@
-# 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/.
-
-checkingForUpdatesTitle=Checking for updates…
-checkingForUpdatesMessage=Checking for updates to your apps
-
-noUpdatesTitle=No updates available
-noUpdatesMessage=There are no updates to your apps
-
-# LOCALIZATION NOTE (retrieveUpdateTitle): Semi-colon list of plural forms.
-# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
-# #1 is the number of updates.
-# example: 3 new updates available
-retrieveUpdateTitle=#1 new update available;#1 new updates available
-
-# LOCALIZATION NOTE (retrieveUpdateMessage): Semi-colon list of plural forms.
-# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
-# %1$S is a comma-separated list of apps for which to retrieve an update.
-# example: Touch to retrieve updates for Foo, Bar, Baz
-retrieveUpdateMessage=Touch to retrieve update for %1$S;Touch to retrieve updates for %1$S
-
-# LOCALIZATION NOTE (retrievingUpdateTitle): Semi-colon list of plural forms.
-# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
-# #1 is the number of updates.
-# example: Retrieving 3 updates…
-retrievingUpdateTitle=Retrieving #1 update…;Retrieving #1 updates…
-
-# LOCALIZATION NOTE (retrievingUpdateMessage): Semi-colon list of plural forms.
-# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
-# %1$S is a comma-separated list of apps for which we're retrieving updates.
-# example: Retrieving updates for Foo, Bar, Baz
-retrievingUpdateMessage=Retrieving update for %1$S; Retrieving updates for %1$S
-
-# LOCALIZATION NOTE (installUpdateTitle): Semi-colon list of plural forms.
-# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
-# #1 is the number of updates.
-# example: 3 updates downloaded
-installUpdateTitle=#1 update downloaded;#1 updates downloaded
-
-# LOCALIZATION NOTE (installUpdateMessage2): Semi-colon list of plural forms.
-# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
-# %1$S is a comma-separated list of apps for which to install an update.
-# example: Touch to install updates for Foo, Bar, Baz
-installUpdateMessage2=Touch to install update for %1$S;Touch to install updates for %1$S
-
-# LOCALIZATION NOTE (retrievalFailedTitle): Semi-colon list of plural forms.
-# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
-# #1 is the number of updates.
-# example: 3 updates failed
-retrievalFailedTitle=#1 update failed;#1 updates failed
-
-# LOCALIZATION NOTE (retrievalFailedMessage): Semi-colon list of plural forms.
-# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
-# %1$S is a comma-separated list of apps for which retrieval failed.
-# example: Failed to retrieve updates for Foo, Bar, Baz
-retrievalFailedMessage=Failed to retrieve update for %1$S;Failed to retrieve updates for %1$S
-
-webappsDisabled=Installing apps is disabled
--- a/mobile/android/locales/jar.mn
+++ b/mobile/android/locales/jar.mn
@@ -32,17 +32,16 @@
   locale/@AB_CD@/browser/notification.dtd         (%chrome/notification.dtd)
   locale/@AB_CD@/browser/pippki.properties        (%chrome/pippki.properties)
   locale/@AB_CD@/browser/sync.dtd                 (%chrome/sync.dtd)
   locale/@AB_CD@/browser/sync.properties          (%chrome/sync.properties)
   locale/@AB_CD@/browser/prompt.dtd               (%chrome/prompt.dtd)
   locale/@AB_CD@/browser/feedback.dtd             (%chrome/feedback.dtd)
   locale/@AB_CD@/browser/phishing.dtd             (%chrome/phishing.dtd)
   locale/@AB_CD@/browser/handling.properties      (%chrome/handling.properties)
-  locale/@AB_CD@/browser/webapp.properties        (%chrome/webapp.properties)
   locale/@AB_CD@/browser/aboutLogins.dtd          (%chrome/aboutLogins.dtd)
   locale/@AB_CD@/browser/aboutLogins.properties  (%chrome/aboutLogins.properties)
 #ifdef NIGHTLY_BUILD
   locale/@AB_CD@/browser/webcompatReporter.properties (%chrome/webcompatReporter.properties)
 #endif
 % resource search-plugins chrome://browser/locale/searchplugins/
 
 # overrides for toolkit l10n, also for en-US
deleted file mode 100644
--- a/mobile/android/modules/WebappManager.jsm
+++ /dev/null
@@ -1,659 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["WebappManager"];
-
-const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-
-const UPDATE_URL_PREF = "browser.webapps.updateCheckUrl";
-
-Cu.import("resource://gre/modules/AppsUtils.jsm");
-Cu.import("resource://gre/modules/Downloads.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
-Cu.import("resource://gre/modules/Webapps.jsm");
-Cu.import("resource://gre/modules/osfile.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Notifications", "resource://gre/modules/Notifications.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Messaging", "resource://gre/modules/Messaging.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", "resource://gre/modules/PluralForm.jsm");
-
-// Import AppsServiceChild.DOMApplicationRegistry for its getAll method.
-var AppsServiceChild = {};
-XPCOMUtils.defineLazyModuleGetter(AppsServiceChild, "DOMApplicationRegistry",
-                                  "resource://gre/modules/AppsServiceChild.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "Strings", function() {
-  return Services.strings.createBundle("chrome://browser/locale/webapp.properties");
-});
-
-XPCOMUtils.defineLazyServiceGetter(this, "ParentalControls",
-  "@mozilla.org/parental-controls-service;1", "nsIParentalControlsService");
-
-/**
- * Get the formatted plural form of a string.  Escapes semicolons in arguments
- * to provide to the formatter before formatting the string, then unescapes them
- * after getting its plural form, to avoid tripping up the plural form getter
- * with a semicolon in one of the formatter's arguments, since the plural forms
- * of localized strings are delimited by semicolons.
- *
- * Ideally, we'd get the plural form first and then format the string,
- * so we wouldn't have to escape/unescape the semicolons; but that would require
- * changes to nsIStringBundle and PluralForm.jsm.
- *
- * @param stringName {String} the string to get the formatted plural form of
- * @param formatterArgs {Array} of {String} args to provide to the formatter
- * @param pluralNum {Number} the number that determines the plural form
- * @returns {String} the formatted plural form of the string
- */
-function getFormattedPluralForm(stringName, formatterArgs, pluralNum) {
-  // Escape semicolons by replacing them with ESC characters.
-  let escapedArgs = formatterArgs.map((arg) => arg.replace(/;/g, String.fromCharCode(0x1B)));
-  let formattedString = Strings.formatStringFromName(stringName, escapedArgs, escapedArgs.length);
-  let pluralForm = PluralForm.get(pluralNum, formattedString);
-  let unescapedString = pluralForm.replace(String.fromCharCode(0x1B), ";", "g");
-  return unescapedString;
-}
-
-var Log = Cu.import("resource://gre/modules/AndroidLog.jsm", {}).AndroidLog;
-var debug = Log.d.bind(null, "WebappManager");
-
-this.WebappManager = {
-  __proto__: DOMRequestIpcHelper.prototype,
-
-  get _testing() {
-    try {
-      return Services.prefs.getBoolPref("browser.webapps.testing");
-    } catch(ex) {
-      return false;
-    }
-  },
-
-  install: function(aMessage, aMessageManager) {
-    if (this._testing) {
-      // Go directly to DOM.  Do not download/install APK, do not collect $200.
-      DOMApplicationRegistry.doInstall(aMessage, aMessageManager);
-      return;
-    }
-
-    this._installApk(aMessage, aMessageManager);
-  },
-
-  installPackage: function(aMessage, aMessageManager) {
-    if (this._testing) {
-      // Go directly to DOM.  Do not download/install APK, do not collect $200.
-      DOMApplicationRegistry.doInstallPackage(aMessage, aMessageManager);
-      return;
-    }
-
-    this._installApk(aMessage, aMessageManager);
-  },
-
-  _installApk: function(aMessage, aMessageManager) { return Task.spawn((function*() {
-    if (!ParentalControls.isAllowed(ParentalControls.INSTALL_APPS)) {
-      aMessage.error = Strings.GetStringFromName("webappsDisabled"),
-      aMessageManager.sendAsyncMessage("Webapps:Install:Return:KO", aMessage);
-      return;
-    }
-
-    let filePath;
-
-    try {
-      filePath = yield this._downloadApk(aMessage.app.manifestURL);
-    } catch(ex) {
-      aMessage.error = ex;
-      aMessageManager.sendAsyncMessage("Webapps:Install:Return:KO", aMessage);
-      debug("error downloading APK: " + ex);
-      return;
-    }
-
-    Messaging.sendRequestForResult({
-      type: "Webapps:InstallApk",
-      filePath: filePath,
-      data: aMessage,
-    }).catch(function (error) {
-      aMessage.error = error;
-      aMessageManager.sendAsyncMessage("Webapps:Install:Return:KO", aMessage);
-      debug("error downloading APK: " + error);
-    });
-  }).bind(this)); },
-
-  _downloadApk: function(aManifestUrl) {
-    debug("_downloadApk for " + aManifestUrl);
-    let deferred = Promise.defer();
-
-    // Get the endpoint URL and convert it to an nsIURI/nsIURL object.
-    const GENERATOR_URL_PREF = "browser.webapps.apkFactoryUrl";
-    const GENERATOR_URL_BASE = Services.prefs.getCharPref(GENERATOR_URL_PREF);
-    let generatorUrl = NetUtil.newURI(GENERATOR_URL_BASE).QueryInterface(Ci.nsIURL);
-
-    // Populate the query part of the URL with the manifest URL parameter.
-    let params = {
-      manifestUrl: aManifestUrl,
-    };
-    generatorUrl.query =
-      Object.keys(params).map((p) => p + "=" + encodeURIComponent(params[p])).join("&");
-    debug("downloading APK from " + generatorUrl.spec);
-
-    Downloads.getSystemDownloadsDirectory().then(function(downloadsDir) {
-      let file = new FileUtils.File(downloadsDir);
-      file.append(aManifestUrl.replace(/[^a-zA-Z0-9]/gi, "") + ".apk");
-      file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
-      debug("downloading APK to " + file.path);
-
-      let worker = new ChromeWorker("resource://gre/modules/WebappManagerWorker.js");
-      worker.onmessage = function(event) {
-        let { type, message } = event.data;
-
-        worker.terminate();
-
-        if (type == "success") {
-          deferred.resolve(file.path);
-        } else { // type == "failure"
-          debug("error downloading APK: " + message);
-          deferred.reject(message);
-        }
-      }
-
-      // Trigger the download.
-      worker.postMessage({ url: generatorUrl.spec, path: file.path });
-    });
-
-    return deferred.promise;
-  },
-
-  _deleteAppcachePath: function(aManifest) {
-    // We don't yet support pre-installing an appcache because it isn't clear
-    // how to do it without degrading the user experience (since users expect
-    // apps to be available after the system tells them they've been installed,
-    // which has already happened) and because nsCacheService shuts down
-    // when we trigger the native install dialog and doesn't re-init itself
-    // afterward (TODO: file bug about this behavior).
-    if ("appcache_path" in aManifest) {
-      debug("deleting appcache_path from manifest: " + aManifest.appcache_path);
-      delete aManifest.appcache_path;
-    }
-  },
-
-  askInstall: function(aData) {
-    let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
-    file.initWithPath(aData.profilePath);
-
-    this._deleteAppcachePath(aData.app.manifest);
-
-    DOMApplicationRegistry.registryReady.then(() => {
-      DOMApplicationRegistry.confirmInstall(aData, file, (function(aApp, aManifest) {
-        this._postInstall(aData.profilePath, aManifest, aData.app.origin,
-                          aData.app.apkPackageName, aData.app.manifestURL);
-      }).bind(this));
-    });
-  },
-
-  _postInstall: function(aProfilePath, aNewManifest, aOrigin, aApkPackageName, aManifestURL) {
-    // aOrigin may now point to the app: url that hosts this app.
-    Messaging.sendRequest({
-      type: "Webapps:Postinstall",
-      apkPackageName: aApkPackageName,
-      origin: aOrigin,
-    });
-  },
-
-  askUninstall: function(aData) {
-    // Android does not currently support automatic uninstalling of apps.
-    // See bug 1019054.
-    DOMApplicationRegistry.denyUninstall(aData, "NOT_SUPPORTED");
-  },
-
-  launch: function({ apkPackageName }) {
-    debug("launch: " + apkPackageName);
-
-    Messaging.sendRequest({
-      type: "Webapps:Launch",
-      packageName: apkPackageName,
-    });
-  },
-
-  uninstall: Task.async(function*(aData, aMessageManager) {
-    debug("uninstall: " + aData.manifestURL);
-
-    yield DOMApplicationRegistry.registryReady;
-
-    if (this._testing) {
-      // Go directly to DOM.  Do not uninstall APK, do not collect $200.
-      DOMApplicationRegistry.doUninstall(aData, aMessageManager);
-      return;
-    }
-
-    let app = DOMApplicationRegistry.getAppByManifestURL(aData.manifestURL);
-    if (!app) {
-      throw new Error("app not found in registry");
-    }
-
-    // If the APK is installed, then _getAPKVersions will return a version
-    // for it, so we can use that function to determine its install status.
-    if (app.apkPackageName && app.apkPackageName in (yield this._getAPKVersions([ app.apkPackageName ]))) {
-      debug("APK is installed; requesting uninstallation");
-      Messaging.sendRequest({
-        type: "Webapps:UninstallApk",
-        apkPackageName: app.apkPackageName,
-      });
-
-      // We don't need to call DOMApplicationRegistry.doUninstall at this point,
-      // because the APK uninstall listener will call autoUninstall once the APK
-      // is uninstalled; and if the user cancels the APK uninstallation, then we
-      // shouldn't remove the app from the registry anyway.
-
-      // But we should tell the requesting document the result of their request.
-      // TODO: tell the requesting document if uninstallation succeeds or fails
-      // by storing weak references to the message/manager pair here and then
-      // using them in autoUninstall if they're still defined when it's called;
-      // and make EventListener.uninstallApk return an error when APK uninstall
-      // fails (which it should be able to detect reliably on Android 4+),
-      // which we observe here and use to notify the requester of failure.
-    } else {
-      // The APK isn't installed, but remove the app from the registry anyway,
-      // to ensure the user can always remove an app from the registry (and thus
-      // about:apps) even if it's out of sync with installed APKs.
-      debug("APK not installed; proceeding directly to removal from registry");
-      DOMApplicationRegistry.uninstall(aData.manifestURL);
-    }
-
-  }),
-
-  autoInstall: function(aData) {
-    debug("autoInstall " + aData.manifestURL);
-
-    let mm = {
-      sendAsyncMessage: function (aMessageName, aData) {
-        // TODO hook this back to Java to report errors.
-        debug("sendAsyncMessage " + aMessageName + ": " + JSON.stringify(aData));
-      }
-    };
-
-    let origin = Services.io.newURI(aData.manifestURL, null, null).prePath;
-
-    let message = aData.request || {
-      app: {
-        origin: origin,
-        receipts: [],
-      }
-    };
-
-    if (aData.updateManifest) {
-      if (aData.zipFilePath) {
-        aData.updateManifest.package_path = aData.zipFilePath;
-      }
-      message.app.updateManifest = aData.updateManifest;
-    }
-
-    // The manifest url may be subtly different between the
-    // time the APK was built and the APK being installed.
-    // Thus, we should take the APK as the source of truth.
-    message.app.manifestURL = aData.manifestURL;
-    message.app.manifest = aData.manifest;
-    message.app.apkPackageName = aData.apkPackageName;
-    message.profilePath = aData.profilePath;
-    message.mm = mm;
-    message.apkInstall = true;
-
-    DOMApplicationRegistry.registryReady.then(() => {
-      // If the app is already installed, update the existing installation.
-      // We should be able to use DOMApplicationRegistry.getAppByManifestURL,
-      // but it returns a mozIApplication, while _autoUpdate needs the original
-      // object from DOMApplicationRegistry.webapps in order to modify it.
-      for (let [ , app] in Iterator(DOMApplicationRegistry.webapps)) {
-        if (app.manifestURL == aData.manifestURL) {
-          return this._autoUpdate(aData, app);
-        }
-      }
-
-      switch (aData.type) { // can be hosted or packaged.
-        case "hosted":
-          DOMApplicationRegistry.doInstall(message, mm);
-          break;
-
-        case "packaged":
-          message.isPackage = true;
-          DOMApplicationRegistry.doInstallPackage(message, mm);
-          break;
-      }
-    });
-  },
-
-  _autoUpdate: function(aData, aOldApp) { return Task.spawn((function*() {
-    debug("_autoUpdate app of type " + aData.type);
-
-    if (aOldApp.apkPackageName != aData.apkPackageName) {
-      // This happens when the app was installed as a shortcut via the old
-      // runtime and is now being updated to an APK.
-      debug("update apkPackageName from " + aOldApp.apkPackageName + " to " + aData.apkPackageName);
-      aOldApp.apkPackageName = aData.apkPackageName;
-    }
-
-    if (aData.type == "hosted") {
-      this._deleteAppcachePath(aData.manifest);
-      let oldManifest = yield DOMApplicationRegistry.getManifestFor(aData.manifestURL);
-      yield DOMApplicationRegistry.updateHostedApp(aData, aOldApp.id, aOldApp, oldManifest, aData.manifest);
-    } else {
-      yield this._autoUpdatePackagedApp(aData, aOldApp);
-    }
-
-    this._postInstall(aData.profilePath, aData.manifest, aOldApp.origin, aOldApp.apkPackageName, aOldApp.manifestURL);
-  }).bind(this)); },
-
-  _autoUpdatePackagedApp: Task.async(function*(aData, aOldApp) {
-    debug("_autoUpdatePackagedApp: " + aData.manifestURL);
-
-    if (aData.updateManifest && aData.zipFilePath) {
-      aData.updateManifest.package_path = aData.zipFilePath;
-    }
-
-    // updatePackagedApp just prepares the update, after which we must
-    // download the package via the misnamed startDownload and then apply it
-    // via applyDownload.
-    yield DOMApplicationRegistry.updatePackagedApp(aData, aOldApp.id, aOldApp, aData.updateManifest);
-
-    try {
-      yield DOMApplicationRegistry.startDownload(aData.manifestURL);
-    } catch (ex if ex == "PACKAGE_UNCHANGED") {
-      debug("package unchanged");
-      // If the package is unchanged, then there's nothing more to do.
-      return;
-    }
-
-    yield DOMApplicationRegistry.applyDownload(aData.manifestURL);
-  }),
-
-  _checkingForUpdates: false,
-
-  checkForUpdates: function(userInitiated) { return Task.spawn((function*() {
-    debug("checkForUpdates");
-
-    // Don't start checking for updates if we're already doing so.
-    // TODO: Consider cancelling the old one and starting a new one anyway
-    // if the user requested this one.
-    if (this._checkingForUpdates) {
-      debug("already checking for updates");
-      return;
-    }
-    this._checkingForUpdates = true;
-
-    try {
-      let installedApps = yield this._getInstalledApps();
-      if (installedApps.length === 0) {
-        return;
-      }
-
-      // Map APK names to APK versions.
-      let apkNameToVersion = yield this._getAPKVersions(installedApps.map(app =>
-        app.apkPackageName).filter(apkPackageName => !!apkPackageName)
-      );
-
-      // Map manifest URLs to APK versions, which is what the service needs
-      // in order to tell us which apps are outdated; and also map them to app
-      // objects, which the downloader/installer uses to download/install APKs.
-      // XXX Will this cause us to update apps without packages, and if so,
-      // does that satisfy the legacy migration story?
-      let manifestUrlToApkVersion = {};
-      let manifestUrlToApp = {};
-      for (let app of installedApps) {
-        manifestUrlToApkVersion[app.manifestURL] = apkNameToVersion[app.apkPackageName] || 0;
-        manifestUrlToApp[app.manifestURL] = app;
-      }
-
-      let outdatedApps = yield this._getOutdatedApps(manifestUrlToApkVersion, userInitiated);
-
-      if (outdatedApps.length === 0) {
-        // If the user asked us to check for updates, tell 'em we came up empty.
-        if (userInitiated) {
-          this._notify({
-            title: Strings.GetStringFromName("noUpdatesTitle"),
-            message: Strings.GetStringFromName("noUpdatesMessage"),
-            icon: "drawable://alert_app",
-          });
-        }
-        return;
-      }
-
-      let usingLan = function() {
-        let network = Cc["@mozilla.org/network/network-link-service;1"].getService(Ci.nsINetworkLinkService);
-        return (network.linkType == network.LINK_TYPE_WIFI || network.linkType == network.LINK_TYPE_ETHERNET);
-      };
-
-      let updateAllowed = function() {
-        let autoUpdatePref = Services.prefs.getCharPref("app.update.autodownload");
-
-        return (autoUpdatePref == "enabled") || (autoUpdatePref == "wifi" && usingLan());
-      };
-
-      if (updateAllowed()) {
-        yield this._updateApks(outdatedApps.map((url) => manifestUrlToApp[url]));
-      } else {
-        let names = outdatedApps.map((url) => manifestUrlToApp[url].name).join(", ");
-        let accepted = yield this._notify({
-          title: PluralForm.get(outdatedApps.length, Strings.GetStringFromName("retrieveUpdateTitle")).
-                 replace("#1", outdatedApps.length),
-          message: getFormattedPluralForm("retrieveUpdateMessage", [names], outdatedApps.length),
-          icon: "drawable://alert_app",
-        }).dismissed;
-
-        if (accepted) {
-          yield this._updateApks(outdatedApps.map((url) => manifestUrlToApp[url]));
-        }
-      }
-    }
-    // There isn't a catch block because we want the error to propagate through
-    // the promise chain, so callers can receive it and choose to respond to it.
-    finally {
-      // Ensure we update the _checkingForUpdates flag even if there's an error;
-      // otherwise the process will get stuck and never check for updates again.
-      this._checkingForUpdates = false;
-    }
-  }).bind(this)); },
-
-  _getAPKVersions: function(packageNames) {
-    return Messaging.sendRequestForResult({
-      type: "Webapps:GetApkVersions",
-      packageNames: packageNames 
-    }).then(data => data.versions);
-  },
-
-  _getInstalledApps: function() {
-    let deferred = Promise.defer();
-    AppsServiceChild.DOMApplicationRegistry.getAll(apps => deferred.resolve(apps));
-    return deferred.promise;
-  },
-
-  _getOutdatedApps: function(installedApps, userInitiated) {
-    let deferred = Promise.defer();
-
-    let data = JSON.stringify({ installed: installedApps });
-
-    let notification;
-    if (userInitiated) {
-      notification = this._notify({
-        title: Strings.GetStringFromName("checkingForUpdatesTitle"),
-        message: Strings.GetStringFromName("checkingForUpdatesMessage"),
-        icon: "drawable://alert_app_animation",
-        progress: NaN,
-      });
-    }
-
-    let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
-                  createInstance(Ci.nsIXMLHttpRequest).
-                  QueryInterface(Ci.nsIXMLHttpRequestEventTarget);
-    request.mozBackgroundRequest = true;
-    request.open("POST", Services.prefs.getCharPref(UPDATE_URL_PREF), true);
-    request.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS |
-                                Ci.nsIChannel.LOAD_BYPASS_CACHE |
-                                Ci.nsIChannel.INHIBIT_CACHING;
-    request.onload = function() {
-      if (userInitiated) {
-        notification.cancel();
-      }
-      deferred.resolve(JSON.parse(this.response).outdated);
-    };
-    request.onerror = function() {
-      if (userInitiated) {
-        notification.cancel();
-      }
-      deferred.reject(this.status || this.statusText);
-    };
-    request.setRequestHeader("Content-Type", "application/json");
-    request.setRequestHeader("Content-Length", data.length);
-
-    request.send(data);
-
-    return deferred.promise;
-  },
-
-  _updateApks: function(aApps) { return Task.spawn((function*() {
-    // Notify the user that we're in the progress of downloading updates.
-    let downloadingNames = aApps.map((app) => app.name).join(", ");
-    let notification = this._notify({
-      title: PluralForm.get(aApps.length, Strings.GetStringFromName("retrievingUpdateTitle")).
-             replace("#1", aApps.length),
-      message: getFormattedPluralForm("retrievingUpdateMessage", [downloadingNames], aApps.length),
-      icon: "drawable://alert_download_animation",
-      // TODO: make this a determinate progress indicator once we can determine
-      // the sizes of the APKs and observe their progress.
-      progress: NaN,
-    });
-
-    // Download the APKs for the given apps.  We do this serially to avoid
-    // saturating the user's network connection.
-    // TODO: download APKs in parallel (or at least more than one at a time)
-    // if it seems reasonable.
-    let downloadedApks = [];
-    let downloadFailedApps = [];
-    for (let app of aApps) {
-      try {
-        let filePath = yield this._downloadApk(app.manifestURL);
-        downloadedApks.push({ app: app, filePath: filePath });
-      } catch(ex) {
-        downloadFailedApps.push(app);
-      }
-    }
-
-    notification.cancel();
-
-    // Notify the user if any downloads failed, but don't do anything
-    // when the user accepts/cancels the notification.
-    // In the future, we might prompt the user to retry the download.
-    if (downloadFailedApps.length > 0) {
-      let downloadFailedNames = downloadFailedApps.map((app) => app.name).join(", ");
-      this._notify({
-        title: PluralForm.get(downloadFailedApps.length, Strings.GetStringFromName("retrievalFailedTitle")).
-               replace("#1", downloadFailedApps.length),
-        message: getFormattedPluralForm("retrievalFailedMessage", [downloadFailedNames], downloadFailedApps.length),
-        icon: "drawable://alert_app",
-      });
-    }
-
-    // If we weren't able to download any APKs, then there's nothing more to do.
-    if (downloadedApks.length === 0) {
-      return;
-    }
-
-    // Prompt the user to update the apps for which we downloaded APKs, and wait
-    // until they accept/cancel the notification.
-    let downloadedNames = downloadedApks.map((apk) => apk.app.name).join(", ");
-    let accepted = yield this._notify({
-      title: PluralForm.get(downloadedApks.length, Strings.GetStringFromName("installUpdateTitle")).
-             replace("#1", downloadedApks.length),
-      message: getFormattedPluralForm("installUpdateMessage2", [downloadedNames], downloadedApks.length),
-      icon: "drawable://alert_app",
-    }).dismissed;
-
-    if (accepted) {
-      // The user accepted the notification, so install the downloaded APKs.
-      for (let apk of downloadedApks) {
-        let msg = {
-          app: apk.app,
-          // TODO: figure out why Webapps:InstallApk needs the "from" property.
-          from: apk.app.installOrigin,
-        };
-        Messaging.sendRequestForResult({
-          type: "Webapps:InstallApk",
-          filePath: apk.filePath,
-          data: msg,
-        }).catch((error) => {
-          // There's no page to report back to so drop the error.
-          // TODO: we should notify the user about this failure.
-          debug("APK install failed : " + error);
-        });
-      }
-    } else {
-      // The user cancelled the notification, so remove the downloaded APKs.
-      for (let apk of downloadedApks) {
-        try {
-          yield OS.file.remove(apk.filePath);
-        } catch(ex) {
-          debug("error removing " + apk.filePath + " for cancelled update: " + ex);
-        }
-      }
-    }
-
-  }).bind(this)); },
-
-  _notify: function(aOptions) {
-    dump("_notify: " + aOptions.title);
-
-    // Resolves to true if the notification is "clicked" (i.e. touched)
-    // and false if the notification is "cancelled" by swiping it away.
-    let dismissed = Promise.defer();
-
-    // TODO: make notifications expandable so users can expand them to read text
-    // that gets cut off in standard notifications.
-    let id = Notifications.create({
-      title: aOptions.title,
-      message: aOptions.message,
-      icon: aOptions.icon,
-      progress: aOptions.progress,
-      onClick: function(aId, aCookie) {
-        dismissed.resolve(true);
-      },
-      onCancel: function(aId, aCookie) {
-        dismissed.resolve(false);
-      },
-    });
-
-    // Return an object with a promise that resolves when the notification
-    // is dismissed by the user along with a method for cancelling it,
-    // so callers who want to wait for user action can do so, while those
-    // who want to control the notification's lifecycle can do that instead.
-    return {
-      dismissed: dismissed.promise,
-      cancel: function() {
-        Notifications.cancel(id);
-      },
-    };
-  },
-
-  autoUninstall: function(aData) {
-    DOMApplicationRegistry.registryReady.then(() => {
-      for (let id in DOMApplicationRegistry.webapps) {
-        let app = DOMApplicationRegistry.webapps[id];
-        if (aData.apkPackageNames.indexOf(app.apkPackageName) > -1) {
-          debug("attempting to uninstall " + app.name);
-          DOMApplicationRegistry.uninstall(app.manifestURL).then(
-            function() {
-              debug("success uninstalling " + app.name);
-            },
-            function(error) {
-              debug("error uninstalling " + app.name + ": " + error);
-            }
-          );
-        }
-      }
-    });
-  },
-};
deleted file mode 100644
--- a/mobile/android/modules/WebappManagerWorker.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* 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/. */
-
-importScripts("resource://gre/modules/osfile.jsm");
-importScripts("resource://gre/modules/workers/require.js");
-var Log = require("resource://gre/modules/AndroidLog.jsm");
-
-// Define the "log" function as a binding of the Log.d function so it specifies
-// the "debug" priority and a log tag.
-var log = Log.d.bind(null, "WebappManagerWorker");
-
-// (eslint-disable: see bug 1177901)
-onmessage = function(event) { // eslint-disable-line no-undef
-  let { url, path } = event.data;
-
-  let file = OS.File.open(path, { truncate: true });
-  let request = new XMLHttpRequest({ mozSystem: true });
-
-  request.open("GET", url, true);
-  request.responseType = "moz-chunked-arraybuffer";
-
-  request.onprogress = function(event) {
-    log("onprogress: received " + request.response.byteLength + " bytes");
-    let bytesWritten = file.write(new Uint8Array(request.response));
-    log("onprogress: wrote " + bytesWritten + " bytes");
-  };
-
-  request.onreadystatechange = function(event) {
-    log("onreadystatechange: " + request.readyState);
-
-    if (request.readyState !== 4) {
-      return;
-    }
-
-    file.close();
-
-    if (request.status === 200) {
-      postMessage({ type: "success" });
-    } else {
-      try {
-        OS.File.remove(path);
-      } catch(ex) {
-        log("error removing " + path + ": " + ex);
-      }
-      let statusMessage = request.status + " - " + request.statusText;
-      postMessage({ type: "failure", message: statusMessage });
-    }
-  };
-
-  request.send(null);
-}
--- a/mobile/android/modules/moz.build
+++ b/mobile/android/modules/moz.build
@@ -25,16 +25,14 @@ EXTRA_JS_MODULES += [
     'PageActions.jsm',
     'Prompt.jsm',
     'RuntimePermissions.jsm',
     'Sanitizer.jsm',
     'SharedPreferences.jsm',
     'Snackbars.jsm',
     'SSLExceptions.jsm',
     'TabMirror.jsm',
-    'WebappManager.jsm',
-    'WebappManagerWorker.js',
 ]
 
 if not CONFIG['MOZ_B2GDROID']:
     EXTRA_JS_MODULES += [
         'FxAccountsWebChannel.jsm',
     ]