Bug 1360587 - Part 2. Remove bouncer apk build config; source; docs, r=nalexander,sebastian draft
authormaliu <max@mxli.us>
Wed, 25 Oct 2017 22:51:44 +0800
changeset 686667 ae9404429cc49184390ad55e82be1d21b05e9e84
parent 686208 6bf3a03e40013f102f35e350a760c46988383cfb
child 737425 3f477eea5c6ec52690fe606133eaf841d14bbde4
push id86244
push userbmo:max@mxli.us
push dateThu, 26 Oct 2017 07:37:53 +0000
reviewersnalexander, sebastian
bugs1360587
milestone58.0a1
Bug 1360587 - Part 2. Remove bouncer apk build config; source; docs, r=nalexander,sebastian MozReview-Commit-ID: C1QJcr65yWu
mobile/android/app/build.gradle
mobile/android/base/AndroidManifest.xml.in
mobile/android/base/FennecManifest_permissions.xml.in
mobile/android/base/moz.build
mobile/android/bouncer/AndroidManifest.xml.in
mobile/android/bouncer/Makefile.in
mobile/android/bouncer/assets/example_asset.txt
mobile/android/bouncer/build.gradle
mobile/android/bouncer/java/org/mozilla/bouncer/BouncerService.java
mobile/android/bouncer/java/org/mozilla/gecko/BrowserApp.java
mobile/android/bouncer/moz.build
mobile/android/bouncer/res/drawable-v21/logo.xml
mobile/android/bouncer/res/drawable/logo.xml
mobile/android/docs/bouncer.rst
mobile/android/docs/index.rst
mobile/android/geckoview/src/main/AndroidManifest.xml
mobile/android/moz.build
mobile/android/moz.configure
settings.gradle
--- a/mobile/android/app/build.gradle
+++ b/mobile/android/app/build.gradle
@@ -168,19 +168,17 @@ android {
                 srcDir "${project.buildDir}/generated/source/preprocessed_resources" // See syncPreprocessedResources.
                 srcDir "${topsrcdir}/mobile/android/services/src/main/res"
                 if (mozconfig.substs.MOZ_CRASHREPORTER) {
                     srcDir "${topsrcdir}/mobile/android/base/crashreporter/res"
                 }
             }
 
             assets {
-                if (mozconfig.substs.MOZ_ANDROID_DISTRIBUTION_DIRECTORY && !mozconfig.substs.MOZ_ANDROID_PACKAGE_INSTALL_BOUNCER) {
-                    // If we are packaging the bouncer, it will have the distribution, so don't put
-                    // it in the main APK as well.
+                if (mozconfig.substs.MOZ_ANDROID_DISTRIBUTION_DIRECTORY) {
                     srcDir "${mozconfig.substs.MOZ_ANDROID_DISTRIBUTION_DIRECTORY}/assets"
                 }
                 srcDir "${topsrcdir}/mobile/android/app/assets"
             }
         }
 
         test {
             java {
--- a/mobile/android/base/AndroidManifest.xml.in
+++ b/mobile/android/base/AndroidManifest.xml.in
@@ -10,21 +10,21 @@
 #endif
       >
     <uses-sdk android:minSdkVersion="@MOZ_ANDROID_MIN_SDK_VERSION@"
 #ifdef MOZ_ANDROID_MAX_SDK_VERSION
               android:maxSdkVersion="@MOZ_ANDROID_MAX_SDK_VERSION@"
 #endif
               android:targetSdkVersion="@ANDROID_TARGET_SDK@"/>
 
-<!-- The bouncer APK and the main APK should define the same set of
-     <permission>, <uses-permission>, and <uses-feature> elements.  This reduces
-     the likelihood of permission-related surprises when installing the main APK
-     on top of a pre-installed bouncer APK.  Add such shared elements in the
-     fileincluded here, so that they can be referenced by both APKs. -->
+
+<!--
+    The separated permission file is for bouncer.apk. Since it's removed,
+     we can merge the permission declaration back. See Bug 1411809.
+ -->
 #include FennecManifest_permissions.xml.in
 
     <application android:label="@string/moz_app_displayname"
                  android:icon="@drawable/icon"
                  android:logo="@drawable/logo"
                  android:name="@MOZ_ANDROID_APPLICATION_CLASS@"
                  android:hardwareAccelerated="true"
                  android:supportsRtl="true"
--- a/mobile/android/base/FennecManifest_permissions.xml.in
+++ b/mobile/android/base/FennecManifest_permissions.xml.in
@@ -1,13 +1,8 @@
-<!-- The bouncer APK and the Fennec APK should define the same set of
-     <permission>, <uses-permission>, and <uses-feature> elements.  This reduces
-     the likelihood of permission-related surprises when installing the main APK
-     on top of a pre-installed bouncer APK.  Add such elements here, so that
-     they can be easily shared between the two APKs. -->
 
 #include ../services/manifests/FxAccountAndroidManifest_permissions.xml.in
 
 #ifdef MOZ_ANDROID_SEARCH_ACTIVITY
 #include ../search/manifests/SearchAndroidManifest_permissions.xml.in
 #endif
 
 <!-- Bug 1261302: we have two new permissions to request,
@@ -18,19 +13,16 @@
 #include GcmAndroidManifest_permissions.xml.in
 
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
-    <!-- READ_EXTERNAL_STORAGE was added in API 16, and is only enforced in API
-         19+.  We declare it so that the bouncer APK and the main APK have the
-         same set of permissions. -->
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
     <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
     <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
     <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
 
     <uses-permission android:name="android.permission.WAKE_LOCK"/>
     <uses-permission android:name="android.permission.VIBRATE"/>
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -1408,23 +1408,19 @@ ANDROID_GENERATED_RESFILES += [
     'res/values/strings.xml',
 ]
 
 ANDROID_ASSETS_DIRS += [
     '/mobile/android/app/assets',
 ]
 
 if CONFIG['MOZ_ANDROID_DISTRIBUTION_DIRECTORY']:
-    # If you change this, also change its equivalent in mobile/android/bouncer.
-    if not CONFIG['MOZ_ANDROID_PACKAGE_INSTALL_BOUNCER']:
-        # If we are packaging the bouncer, it will have the distribution, so don't put
-        # it in the main APK as well.
-        ANDROID_ASSETS_DIRS += [
-            '%' + CONFIG['MOZ_ANDROID_DISTRIBUTION_DIRECTORY'] + '/assets',
-        ]
+    ANDROID_ASSETS_DIRS += [
+        '%' + CONFIG['MOZ_ANDROID_DISTRIBUTION_DIRECTORY'] + '/assets',
+    ]
 
 if CONFIG['MOZ_ANDROID_SEARCH_ACTIVITY']:
     # The Search Activity is mostly independent of Fennec proper, but
     # it does depend on Geckoview.  Therefore, we build it as a jar
     # that depends on the Geckoview jars.
     search_source_dir = SRCDIR + '/../search'
     include('../search/search_activity_sources.mozbuild')
 
deleted file mode 100644
--- a/mobile/android/bouncer/AndroidManifest.xml.in
+++ /dev/null
@@ -1,96 +0,0 @@
-#filter substitution
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="@ANDROID_PACKAGE_NAME@"
-      android:installLocation="auto"
-      android:versionCode="@ANDROID_VERSION_CODE@"
-      android:versionName="@MOZ_APP_VERSION@"
-#ifdef MOZ_ANDROID_SHARED_ID
-      android:sharedUserId="@MOZ_ANDROID_SHARED_ID@"
-#endif
-      >
-    <uses-sdk android:minSdkVersion="@MOZ_ANDROID_MIN_SDK_VERSION@"
-#ifdef MOZ_ANDROID_MAX_SDK_VERSION
-              android:maxSdkVersion="@MOZ_ANDROID_MAX_SDK_VERSION@"
-#endif
-              android:targetSdkVersion="@ANDROID_TARGET_SDK@"/>
-
-<!-- The bouncer APK and the main APK should define the same set of
-     <permission>, <uses-permission>, and <uses-feature> elements.  This reduces
-     the likelihood of permission-related surprises when installing the main APK
-     on top of a pre-installed bouncer APK.  Add such shared elements in the
-     fileincluded here, so that they can be referenced by both APKs. -->
-#include ../base/FennecManifest_permissions.xml.in
-
-    <application android:label="@MOZ_APP_DISPLAYNAME@"
-                 android:icon="@drawable/icon"
-                 android:logo="@drawable/logo"
-                 android:hardwareAccelerated="true"
-                 android:allowBackup="false"
-# The preprocessor does not yet support arbitrary parentheses, so this cannot
-# be parenthesized thus to clarify that the logical AND operator has precedence:
-#   !defined(MOZILLA_OFFICIAL) || (defined(NIGHTLY_BUILD) && defined(MOZ_DEBUG))
-#if !defined(MOZILLA_OFFICIAL) || defined(NIGHTLY_BUILD) && defined(MOZ_DEBUG)
-                 android:debuggable="true">
-#else
-                 android:debuggable="false">
-#endif
-
-        <activity
-            android:name="@MOZ_ANDROID_BROWSER_INTENT_CLASS@"
-            android:label="@MOZ_APP_DISPLAYNAME@"
-            android:theme="@android:style/Theme.Translucent">
-
-            <!-- Aping org.mozilla.gecko.BrowserApp. -->
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.MULTIWINDOW_LAUNCHER"/>
-                <category android:name="android.intent.category.APP_BROWSER" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-
-            <meta-data android:name="com.sec.minimode.icon.portrait.normal"
-                       android:resource="@drawable/icon"/>
-
-            <meta-data android:name="com.sec.minimode.icon.landscape.normal"
-                       android:resource="@drawable/icon" />
-
-            <intent-filter>
-                <action android:name="android.intent.action.WEB_SEARCH" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-                <data android:scheme="" />
-                <data android:scheme="http" />
-                <data android:scheme="https" />
-            </intent-filter>
-
-            <!-- Aping org.mozilla.gecko.tabqueue.TabQueueDispatcher. -->
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-                <data android:scheme="http" />
-                <data android:scheme="https" />
-                <data android:scheme="about" />
-                <data android:scheme="javascript" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW" />
-                <category android:name="android.intent.category.BROWSABLE" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <data android:scheme="file" />
-                <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>
-
-        <service
-            android:name="org.mozilla.bouncer.BouncerService"
-            android:exported="false" />
-
-    </application>
-</manifest>
deleted file mode 100644
--- a/mobile/android/bouncer/Makefile.in
+++ /dev/null
@@ -1,20 +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/.
-
-include $(topsrcdir)/config/config.mk
-
-JAVAFILES := \
-	java/org/mozilla/bouncer/BouncerService.java \
-	java/org/mozilla/gecko/BrowserApp.java \
-  $(NULL)
-
-ANDROID_EXTRA_JARS := \
-  $(NULL)
-
-# Targets built very early during a Gradle build.
-gradle-targets: $(abspath AndroidManifest.xml)
-
-.PHONY: gradle-targets
-
-libs:: $(ANDROID_APK_NAME).apk
deleted file mode 100644
--- a/mobile/android/bouncer/assets/example_asset.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-This is an example asset.
deleted file mode 100644
--- a/mobile/android/bouncer/build.gradle
+++ /dev/null
@@ -1,78 +0,0 @@
-buildDir "${topobjdir}/gradle/build/mobile/android/bouncer"
-
-apply plugin: 'com.android.application'
-
-android {
-    compileSdkVersion project.ext.compileSdkVersion
-    buildToolsVersion project.ext.buildToolsVersion
-
-    defaultConfig {
-        targetSdkVersion project.ext.targetSdkVersion
-        minSdkVersion project.ext.minSdkVersion
-        manifestPlaceholders = project.ext.manifestPlaceholders
-
-        applicationId mozconfig.substs.ANDROID_PACKAGE_NAME
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
-    }
- 
-    dexOptions {
-        javaMaxHeapSize "2g"
-    }
-
-    lintOptions {
-        abortOnError false
-    }
-
-    buildTypes {
-        release {
-            minifyEnabled false
-        }
-    }
-
-    sourceSets {
-        main {
-            manifest.srcFile "${topobjdir}/mobile/android/bouncer/AndroidManifest.xml"
-            assets {
-                if (mozconfig.substs.MOZ_ANDROID_DISTRIBUTION_DIRECTORY) {
-                    srcDir "${mozconfig.substs.MOZ_ANDROID_DISTRIBUTION_DIRECTORY}/assets"
-                }
-            }
-            java {
-                srcDir 'java'
-            }
-            res {
-                srcDir "${topsrcdir}/${mozconfig.substs.MOZ_BRANDING_DIRECTORY}/res" // For the icon.
-                srcDir 'res'
-            }
-        }
-    }
-}
-
-task generateCodeAndResources(type:Exec) {
-    workingDir "${topobjdir}"
-
-    commandLine mozconfig.substs.GMAKE
-    args '-C'
-    args "${topobjdir}/mobile/android/bouncer"
-    args 'gradle-targets'
-
-    // Only show the output if something went wrong.
-    ignoreExitValue = true
-    standardOutput = new ByteArrayOutputStream()
-    errorOutput = standardOutput
-    doLast {
-        if (execResult.exitValue != 0) {
-            throw new GradleException("Process '${commandLine}' finished with non-zero exit value ${execResult.exitValue}:\n\n${standardOutput.toString()}")
-        }
-    }
-}
-
-afterEvaluate {
-    android.applicationVariants.all {
-        preBuild.dependsOn generateCodeAndResources
-    }
-}
deleted file mode 100644
--- a/mobile/android/bouncer/java/org/mozilla/bouncer/BouncerService.java
+++ /dev/null
@@ -1,125 +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.bouncer;
-
-import android.app.IntentService;
-import android.content.Intent;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-public class BouncerService extends IntentService {
-
-    private static final String LOGTAG = "GeckoBouncerService";
-
-    public BouncerService() {
-        super("BouncerService");
-    }
-
-    @Override
-    protected void onHandleIntent(Intent intent) {
-        final byte[] buffer = new byte[8192];
-
-        Log.d(LOGTAG, "Preparing to copy distribution files");
-
-        final List<String> files;
-        try {
-            files = getFiles("distribution");
-        } catch (IOException e) {
-            Log.e(LOGTAG, "Error getting distribution files from assets/distribution/**", e);
-            return;
-        }
-
-        InputStream in = null;
-        for (String path : files) {
-            try {
-                Log.d(LOGTAG, "Copying distribution file: " + path);
-
-                in = getAssets().open(path);
-
-                final File outFile = getDataFile(path);
-                writeStream(in, outFile, buffer);
-            } catch (IOException e) {
-                Log.e(LOGTAG, "Error opening distribution input stream from assets", e);
-            } finally {
-                if (in != null) {
-                    try {
-                        in.close();
-                    } catch (IOException e) {
-                        Log.e(LOGTAG, "Error closing distribution input stream", e);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Recursively traverse a directory to list paths to all files.
-     *
-     * @param path Directory to traverse.
-     * @return List of all files in given directory.
-     * @throws IOException
-     */
-    private List<String> getFiles(String path) throws IOException {
-        List<String> paths = new ArrayList<>();
-        getFiles(path, paths);
-        return paths;
-    }
-
-    /**
-     * Recursively traverse a directory to list paths to all files.
-     *
-     * @param path Directory to traverse.
-     * @param acc Accumulator of paths seen.
-     * @throws IOException
-     */
-    private void getFiles(String path, List<String> acc) throws IOException {
-        final String[] list = getAssets().list(path);
-        if (list.length > 0) {
-            // We're a directory -- recurse.
-            for (final String file : list) {
-                getFiles(path + "/" + file, acc);
-            }
-        } else {
-            // We're a file -- accumulate.
-            acc.add(path);
-        }
-    }
-
-    private File getDataFile(final String path) {
-        File outFile = new File(getApplicationInfo().dataDir, path);
-        File dir = outFile.getParentFile();
-
-        if (dir != null && !dir.exists()) {
-            Log.d(LOGTAG, "Creating " + dir.getAbsolutePath());
-            if (!dir.mkdirs()) {
-                Log.e(LOGTAG, "Unable to create directories: " + dir.getAbsolutePath());
-                return null;
-            }
-        }
-
-        return outFile;
-    }
-
-    private void writeStream(InputStream fileStream, File outFile, byte[] buffer)
-            throws IOException {
-        final OutputStream outStream = new FileOutputStream(outFile);
-        try {
-            int count;
-            while ((count = fileStream.read(buffer)) > 0) {
-                outStream.write(buffer, 0, count);
-            }
-        } finally {
-            outStream.close();
-        }
-    }
-}
deleted file mode 100644
--- a/mobile/android/bouncer/java/org/mozilla/gecko/BrowserApp.java
+++ /dev/null
@@ -1,46 +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;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.Log;
-
-import org.mozilla.bouncer.BouncerService;
-
-/**
- * Bouncer activity version of BrowserApp.
- *
- * This class has the same name as org.mozilla.gecko.BrowserApp to preserve
- * shortcuts created by the bouncer app.
- */
-public class BrowserApp extends Activity {
-    private static final String LOGTAG = "GeckoBouncerActivity";
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // This races distribution installation against the Play Store killing our process to
-        // install the update.  We'll live with it.  To do better, consider using an Intent to
-        // notify when the service has completed.
-        startService(new Intent(this, BouncerService.class));
-
-        final String appPackageName = Uri.encode(getPackageName());
-        final Uri uri = Uri.parse("market://details?id=" + appPackageName);
-        Log.i(LOGTAG, "Lanching activity with URL: " + uri.toString());
-
-        // It might be more correct to catch failure in case the Play Store isn't installed.  The
-        // fallback action is to open the Play Store website... but doing so may offer Firefox as
-        // browser (since even the bouncer offers to view URLs), which will be very confusing.
-        // Therefore, we don't try to be fancy here, and we just fail (silently).
-        startActivity(new Intent(Intent.ACTION_VIEW, uri));
-
-        finish();
-    }
-}
deleted file mode 100644
--- a/mobile/android/bouncer/moz.build
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEFINES['ANDROID_VERSION_CODE'] = '1'
-
-for var in ('ANDROID_PACKAGE_NAME',
-            'ANDROID_TARGET_SDK',
-            'MOZ_ANDROID_BROWSER_INTENT_CLASS',
-            'MOZ_APP_DISPLAYNAME',
-            'MOZ_APP_VERSION'):
-    DEFINES[var] = CONFIG[var]
-
-for var in ('MOZ_ANDROID_GCM',
-            'MOZ_ANDROID_MIN_SDK_VERSION',
-            'MOZ_ANDROID_MAX_SDK_VERSION',
-            'MOZ_ANDROID_DOWNLOADS_INTEGRATION',
-            'MOZ_ANDROID_BEAM',
-            'MOZ_ANDROID_SEARCH_ACTIVITY',
-            'MOZ_ANDROID_MLS_STUMBLER'):
-    if CONFIG[var]:
-        DEFINES[var] = CONFIG[var]
-
-ANDROID_APK_NAME = 'bouncer'
-ANDROID_APK_PACKAGE = CONFIG['ANDROID_PACKAGE_NAME']
-
-# Putting branding earlier allows branders to override default resources.
-ANDROID_RES_DIRS += [
-    '/' + CONFIG['MOZ_BRANDING_DIRECTORY'] + '/res', # For the icon.
-    'res',
-]
-
-ANDROID_ASSETS_DIRS += [
-    'assets',
-]
-
-if CONFIG['MOZ_ANDROID_DISTRIBUTION_DIRECTORY']:
-    # If you change this, also change its equivalent in mobile/android/base.
-    ANDROID_ASSETS_DIRS += [
-        '%' + CONFIG['MOZ_ANDROID_DISTRIBUTION_DIRECTORY'] + '/assets',
-    ]
-
-DEFINES['MOZ_ANDROID_SHARED_ID'] = CONFIG['MOZ_ANDROID_SHARED_ID']
-OBJDIR_PP_FILES.mobile.android.bouncer += [
-    'AndroidManifest.xml.in',
-]
deleted file mode 100644
--- a/mobile/android/bouncer/res/drawable-v21/logo.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?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/. -->
-
-<!-- The action bar scales the application icon to be too large (bug 1132751)
-     so add some padding to prevent it from scaling so much. -->
-<inset
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/icon"
-    android:insetTop="6dp"
-    android:insetBottom="6dp"
-    android:insetLeft="6dp"
-    android:insetRight="6dp"
-    />
deleted file mode 100644
--- a/mobile/android/bouncer/res/drawable/logo.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?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/. -->
-
-<!-- Overidden. -->
-<bitmap
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:src="@drawable/icon"/>
deleted file mode 100644
--- a/mobile/android/docs/bouncer.rst
+++ /dev/null
@@ -1,38 +0,0 @@
-.. -*- Mode: rst; fill-column: 100; -*-
-
-=========================================
- The Firefox for Android install bouncer
-=========================================
-
-`Bug 1234629 <https://bugzilla.mozilla.org/show_bug.cgi?id=1234629>`_ and `Bug 1163082
-<https://bugzilla.mozilla.org/show_bug.cgi?id=1163082>`_ combine to allow building a very small
-Fennec-like "bouncer" APK that redirects (bounces) a potential Fennec user to the marketplace of
-their choice -- usually the Google Play Store -- to install the real Firefox for Android application
-APK.
-
-The real APK should install seamlessly over top of the bouncer APK.  Care is taken to keep the
-bouncer and application APK <permission> manifest definitions identical, and to have the bouncer APK
-<activity> manifest definitions look similar to the application APK <activity> manifest definitions.
-
-In addition, the bouncer APK can carry a Fennec distribution, which it copies onto the device before
-redirecting to the marketplace.  The application APK recognizes the installed distribution and
-customizes itself accordingly on first run.
-
-The motivation is to allow partners to pre-install the very small bouncer APK on shipping devices
-and to have a smooth path to upgrade to the full application APK, with a partner-specific
-distribution in place.
-
-Technical details
-=================
-
-To build the bouncer APK, define ``MOZ_ANDROID_PACKAGE_INSTALL_BOUNCER``.  To pack a distribution
-into the bouncer APK (and *not* into the application APK), add a line like::
-
-  ac_add_options --with-android-distribution-directory=/path/to/fennec-distribution-sample
-
-to your ``mozconfig`` file.  See the `general distribution documentation on the wiki
-<https://wiki.mozilla.org/Mobile/Distribution_Files>`_ for more information.
-
-The ``distribution`` directory should end up in the ``assets/distribution`` directory of the bouncer
-APK.  It will be copied into ``/data/data/$ANDROID_PACKAGE_NAME/distribution`` when the bouncer
-executes.
--- a/mobile/android/docs/index.rst
+++ b/mobile/android/docs/index.rst
@@ -13,17 +13,16 @@ Contents:
 
    localeswitching
    uitelemetry
    activitystreamtelemetry
    downloadcontenttelemetry
    adjust
    mma
    defaultdomains
-   bouncer
    shutdown
    push
 
 Indices and tables
 ==================
 
 * :ref:`genindex`
 * :ref:`modindex`
--- a/mobile/android/geckoview/src/main/AndroidManifest.xml
+++ b/mobile/android/geckoview/src/main/AndroidManifest.xml
@@ -2,19 +2,16 @@
     package="org.mozilla.geckoview">
 
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
-    <!-- READ_EXTERNAL_STORAGE was added in API 16, and is only enforced in API
-         19+.  We declare it so that the bouncer APK and the main APK have the
-         same set of permissions. -->
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
     <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
     <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
 
     <uses-permission android:name="android.permission.WAKE_LOCK"/>
     <uses-permission android:name="android.permission.VIBRATE"/>
 
--- a/mobile/android/moz.build
+++ b/mobile/android/moz.build
@@ -3,19 +3,16 @@
 # 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/.
 
 with Files('**'):
     BUG_COMPONENT = ('Firefox for Android', 'Build Config & IDE Support')
     SCHEDULES.exclusive = ['android']
 
-with Files('bouncer/**'):
-    BUG_COMPONENT = ('Firefox for Android', 'Distributions')
-
 with Files('branding/**'):
     BUG_COMPONENT = ('Firefox for Android', 'General')
 
 with Files('build/**'):
     BUG_COMPONENT = ('Firefox for Android', 'Build Config & IDE Support')
 
 with Files('config/**'):
     BUG_COMPONENT = ('Firefox for Android', 'Build Config & IDE Support')
@@ -67,16 +64,13 @@ DIRS += [
     'extensions',
     'modules',
     'themes/core',
     'themes/geckoview',
     'app',
     'fonts',
 ]
 
-if CONFIG['MOZ_ANDROID_PACKAGE_INSTALL_BOUNCER']:
-    DIRS += ['bouncer'] # No ordering implied with respect to base.
-
 TEST_DIRS += [
     'tests',
 ]
 
 SPHINX_TREES['fennec'] = 'docs'
--- a/mobile/android/moz.configure
+++ b/mobile/android/moz.configure
@@ -95,23 +95,16 @@ set_config('MOZ_ANDROID_ACTIVITY_STREAM'
 
 option(env='MOZ_ANDROID_MOZILLA_ONLINE',
        help='Enable MozillaOnline (Mozilla China) specific Android code',
        default=False)
 
 set_config('MOZ_ANDROID_MOZILLA_ONLINE',
            depends_if('MOZ_ANDROID_MOZILLA_ONLINE')(lambda _: True))
 
-option(env='MOZ_ANDROID_PACKAGE_INSTALL_BOUNCER',
-       help='Build and package the install bouncer APK',
-       default=True)
-
-set_config('MOZ_ANDROID_PACKAGE_INSTALL_BOUNCER',
-           depends_if('MOZ_ANDROID_PACKAGE_INSTALL_BOUNCER')(lambda _: True))
-
 imply_option('MOZ_SOCIAL', False)
 imply_option('MOZ_SERVICES_HEALTHREPORT', True)
 imply_option('MOZ_ANDROID_HISTORY', True)
 
 set_config('ANDROID_SUPPORT_LIBRARY_VERSION', '23.4.0')
 add_old_configure_assignment('ANDROID_SUPPORT_LIBRARY_VERSION', '23.4.0')
 
 set_config('ANDROID_GOOGLE_PLAY_SERVICES_VERSION', '8.4.0')
--- a/settings.gradle
+++ b/settings.gradle
@@ -35,21 +35,16 @@ include ':omnijar'
 include ':thirdparty'
 
 project(':app').projectDir = new File("${json.topsrcdir}/mobile/android/app")
 project(':geckoview').projectDir = new File("${json.topsrcdir}/mobile/android/geckoview")
 project(':geckoview_example').projectDir = new File("${json.topsrcdir}/mobile/android/geckoview_example")
 project(':omnijar').projectDir = new File("${json.topsrcdir}/mobile/android/app/omnijar")
 project(':thirdparty').projectDir = new File("${json.topsrcdir}/mobile/android/thirdparty")
 
-if (json.substs.MOZ_ANDROID_PACKAGE_INSTALL_BOUNCER) {
-    include ':bouncer'
-    project(':bouncer').projectDir = new File("${json.topsrcdir}/mobile/android/bouncer")
-}
-
 // The Gradle instance is shared between settings.gradle and all the
 // other build.gradle files (see
 // http://forums.gradle.org/gradle/topics/define_extension_properties_from_settings_xml).
 // We use this ext property to pass the per-object-directory mozconfig
 // between scripts.  This lets us execute set-up code before we gradle
 // tries to configure the project even once, and as a side benefit
 // saves invoking |mach environment| multiple times.
 gradle.ext.mozconfig = json