mobile/android/base/webapp/InstallHelper.java

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 package org.mozilla.gecko.webapp;
michael@0 7
michael@0 8 import java.io.Closeable;
michael@0 9 import java.io.File;
michael@0 10 import java.io.FileOutputStream;
michael@0 11 import java.io.IOException;
michael@0 12 import java.io.InputStream;
michael@0 13 import java.io.OutputStream;
michael@0 14
michael@0 15 import org.json.JSONException;
michael@0 16 import org.json.JSONObject;
michael@0 17 import org.mozilla.gecko.GeckoAppShell;
michael@0 18 import org.mozilla.gecko.GeckoEvent;
michael@0 19 import org.mozilla.gecko.GeckoProfile;
michael@0 20 import org.mozilla.gecko.gfx.BitmapUtils;
michael@0 21 import org.mozilla.gecko.util.GeckoEventListener;
michael@0 22 import org.mozilla.gecko.util.ThreadUtils;
michael@0 23
michael@0 24 import android.content.Context;
michael@0 25 import android.graphics.Bitmap;
michael@0 26 import android.net.Uri;
michael@0 27 import android.util.Log;
michael@0 28
michael@0 29 public class InstallHelper implements GeckoEventListener {
michael@0 30 private static final String LOGTAG = "GeckoWebappInstallHelper";
michael@0 31 private static final String[] INSTALL_EVENT_NAMES = new String[] {"Webapps:Postinstall"};
michael@0 32 private final Context mContext;
michael@0 33 private final InstallCallback mCallback;
michael@0 34 private final ApkResources mApkResources;
michael@0 35
michael@0 36 public static interface InstallCallback {
michael@0 37 // on the GeckoThread
michael@0 38 void installCompleted(InstallHelper installHelper, String event, JSONObject message);
michael@0 39
michael@0 40 // on the GeckoBackgroundThread
michael@0 41 void installErrored(InstallHelper installHelper, Exception exception);
michael@0 42 }
michael@0 43
michael@0 44 public InstallHelper(Context context, ApkResources apkResources, InstallCallback cb) {
michael@0 45 mContext = context;
michael@0 46 mCallback = cb;
michael@0 47 mApkResources = apkResources;
michael@0 48 }
michael@0 49
michael@0 50 public void startInstall(String profileName) throws IOException {
michael@0 51 startInstall(profileName, null);
michael@0 52 }
michael@0 53
michael@0 54 public void startInstall(final String profileName, final JSONObject message) throws IOException {
michael@0 55 ThreadUtils.postToBackgroundThread(new Runnable() {
michael@0 56 @Override
michael@0 57 public void run() {
michael@0 58 try {
michael@0 59 install(profileName, message);
michael@0 60 } catch (IOException e) {
michael@0 61 handleException(e);
michael@0 62 }
michael@0 63 }
michael@0 64 });
michael@0 65 }
michael@0 66
michael@0 67 protected void handleException(Exception e) {
michael@0 68 if (mCallback != null) {
michael@0 69 mCallback.installErrored(this, e);
michael@0 70 } else {
michael@0 71 Log.e(LOGTAG, "mozApps.install failed", e);
michael@0 72 }
michael@0 73 }
michael@0 74
michael@0 75 private void install(String profileName, JSONObject message) throws IOException {
michael@0 76 if (message == null) {
michael@0 77 message = new JSONObject();
michael@0 78 }
michael@0 79
michael@0 80 // we can change the profile to be in the app's area here
michael@0 81 GeckoProfile profile = GeckoProfile.get(mContext, profileName);
michael@0 82
michael@0 83 try {
michael@0 84 message.put("apkPackageName", mApkResources.getPackageName());
michael@0 85 message.put("manifestURL", mApkResources.getManifestUrl());
michael@0 86 message.put("title", mApkResources.getAppName());
michael@0 87 message.put("manifest", new JSONObject(mApkResources.getManifest(mContext)));
michael@0 88
michael@0 89 String appType = mApkResources.getWebappType();
michael@0 90 message.putOpt("type", appType);
michael@0 91 if ("packaged".equals(appType)) {
michael@0 92 message.putOpt("updateManifest", new JSONObject(mApkResources.getMiniManifest(mContext)));
michael@0 93 }
michael@0 94
michael@0 95 message.putOpt("profilePath", profile.getDir());
michael@0 96
michael@0 97 if (mApkResources.isPackaged()) {
michael@0 98 File zipFile = copyApplicationZipFile();
michael@0 99 message.putOpt("zipFilePath", Uri.fromFile(zipFile).toString());
michael@0 100 }
michael@0 101 } catch (JSONException e) {
michael@0 102 handleException(e);
michael@0 103 return;
michael@0 104 }
michael@0 105
michael@0 106 registerGeckoListener();
michael@0 107
michael@0 108 GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Webapps:AutoInstall", message.toString()));
michael@0 109 calculateColor();
michael@0 110 }
michael@0 111
michael@0 112 public File copyApplicationZipFile() throws IOException {
michael@0 113 if (!mApkResources.isPackaged()) {
michael@0 114 return null;
michael@0 115 }
michael@0 116
michael@0 117 Uri uri = mApkResources.getZipFileUri();
michael@0 118
michael@0 119 InputStream in = null;
michael@0 120 OutputStream out = null;
michael@0 121 File destPath = new File(mApkResources.getFileDirectory(), "application.zip");
michael@0 122 try {
michael@0 123 in = mContext.getContentResolver().openInputStream(uri);
michael@0 124 out = new FileOutputStream(destPath);
michael@0 125 byte[] buffer = new byte[1024];
michael@0 126 int read = 0;
michael@0 127 while ((read = in.read(buffer)) != -1) {
michael@0 128 out.write(buffer, 0, read);
michael@0 129 }
michael@0 130 out.flush();
michael@0 131 } catch (IOException e) {
michael@0 132 throw e;
michael@0 133 } finally {
michael@0 134 close(in);
michael@0 135 close(out);
michael@0 136 }
michael@0 137 return destPath;
michael@0 138 }
michael@0 139
michael@0 140 private static void close(Closeable close) {
michael@0 141 if (close == null) {
michael@0 142 return;
michael@0 143 }
michael@0 144 try {
michael@0 145 close.close();
michael@0 146 } catch (IOException e) {
michael@0 147 // NOP
michael@0 148 }
michael@0 149 }
michael@0 150
michael@0 151 public void registerGeckoListener() {
michael@0 152 for (String eventName : INSTALL_EVENT_NAMES) {
michael@0 153 GeckoAppShell.registerEventListener(eventName, this);
michael@0 154 }
michael@0 155 }
michael@0 156
michael@0 157 private void calculateColor() {
michael@0 158 ThreadUtils.assertOnBackgroundThread();
michael@0 159 Allocator slots = Allocator.getInstance(mContext);
michael@0 160 int index = slots.getIndexForApp(mApkResources.getPackageName());
michael@0 161 Bitmap bitmap = BitmapUtils.getBitmapFromDrawable(mApkResources.getAppIcon());
michael@0 162 slots.updateColor(index, BitmapUtils.getDominantColor(bitmap));
michael@0 163 }
michael@0 164
michael@0 165 @Override
michael@0 166 public void handleMessage(String event, JSONObject message) {
michael@0 167 for (String eventName : INSTALL_EVENT_NAMES) {
michael@0 168 GeckoAppShell.unregisterEventListener(eventName, this);
michael@0 169 }
michael@0 170
michael@0 171 if (mCallback != null) {
michael@0 172 mCallback.installCompleted(this, event, message);
michael@0 173 }
michael@0 174 }
michael@0 175 }

mercurial