Bug 1234629 - Copy distribution files in bouncer APK. f?rnewman
--- a/mobile/android/bouncer/AndroidManifest.xml.in
+++ b/mobile/android/bouncer/AndroidManifest.xml.in
@@ -10,25 +10,36 @@
#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="22"/>
-
<application android:label="@string/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="@string/moz_app_displayname"
+ android:theme="@android:style/Theme.Translucent">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <service android:name="org.mozilla.bouncer.BouncerService"/>
+
</application>
</manifest>
--- a/mobile/android/bouncer/Makefile.in
+++ b/mobile/android/bouncer/Makefile.in
@@ -1,16 +1,17 @@
# 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/BouncerActivity.java \
+ java/org/mozilla/bouncer/BouncerService.java \
+ java/org/mozilla/gecko/BrowserApp.java \
$(NULL)
ANDROID_EXTRA_JARS := \
$(NULL)
PP_TARGETS += manifest
manifest := $(srcdir)/AndroidManifest.xml.in
manifest_TARGET := export
deleted file mode 100644
--- a/mobile/android/bouncer/java/org/mozilla/bouncer/BouncerActivity.java
+++ /dev/null
@@ -1,11 +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.Activity;
-
-public class BouncerActivity extends Activity {
-}
new file mode 100644
--- /dev/null
+++ b/mobile/android/bouncer/java/org/mozilla/bouncer/BouncerService.java
@@ -0,0 +1,119 @@
+/* -*- 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[1024];
+
+ 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", e);
+ return;
+ }
+
+ InputStream in = null;
+ for (String path : files) {
+ try {
+ Log.d(LOGTAG, "Copying distribution file: " + path);
+
+ in = getAssets().open(path);
+
+ final File out = getDataFile(path);
+ writeStream(in, out, 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<>();
+
+ String[] list = getAssets().list(path);
+ for (String file : list) {
+ String newPath = path + "/" + file;
+ if (getAssets().list(newPath).length > 0) {
+ paths.addAll(getFiles(newPath));
+ } else {
+ paths.add(newPath);
+ }
+ }
+
+ return paths;
+ }
+
+ private String getDataDir() {
+ return getApplicationInfo().dataDir;
+ }
+
+ private File getDataFile(final String path) {
+ File outFile = new File(getDataDir(), path);
+ File dir = outFile.getParentFile();
+
+ if (!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();
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/bouncer/java/org/mozilla/gecko/BrowserApp.java
@@ -0,0 +1,35 @@
+/* -*- 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 org.mozilla.bouncer.BouncerService;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * 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);
+ startService(new Intent(this, BouncerService.class));
+ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getPackageName())));
+ finish();
+ }
+}
--- a/mobile/android/bouncer/moz.build
+++ b/mobile/android/bouncer/moz.build
@@ -2,16 +2,18 @@
# 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',
+ 'MOZ_ANDROID_BROWSER_INTENT_CLASS',
+ 'MOZ_APP_DISPLAYNAME',
'MOZ_APP_VERSION'):
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 += [