mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 957070 - move webapp event listeners/handlers from GeckoAppShell to webapp/ class; r=wesj
--HG-- rename : mobile/android/base/webapp/WebAppAllocator.java => mobile/android/base/webapp/Allocator.java rename : mobile/android/base/webapp/WebAppDispatcher.java => mobile/android/base/webapp/Dispatcher.java extra : rebase_source : a7e66abdf7738d1ae96a167bf6df7a58c208efa1
This commit is contained in:
parent
9caeb09454
commit
14abcba732
2
CLOBBER
2
CLOBBER
@ -22,4 +22,4 @@
|
|||||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||||
# don't change CLOBBER for WebIDL changes any more.
|
# don't change CLOBBER for WebIDL changes any more.
|
||||||
|
|
||||||
Bug 948583, first part, apparently requires a clobber. (Ideas for fixing this involve removing jsopcode.tbl, which is a bit too big to do while holding up this patch.)
|
Bug 957070 requires a clobber to resolve a reference to a program class member.
|
||||||
|
@ -159,7 +159,7 @@
|
|||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
#ifdef MOZ_ANDROID_SYNTHAPKS
|
#ifdef MOZ_ANDROID_SYNTHAPKS
|
||||||
<activity android:name="org.mozilla.gecko.webapp.WebAppDispatcher"
|
<activity android:name="org.mozilla.gecko.webapp.Dispatcher"
|
||||||
android:noHistory="true" >
|
android:noHistory="true" >
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<!-- catch links from synthetic apks -->
|
<!-- catch links from synthetic apks -->
|
||||||
|
@ -29,6 +29,7 @@ import org.mozilla.gecko.util.HardwareUtils;
|
|||||||
import org.mozilla.gecko.util.ThreadUtils;
|
import org.mozilla.gecko.util.ThreadUtils;
|
||||||
import org.mozilla.gecko.util.UiAsyncTask;
|
import org.mozilla.gecko.util.UiAsyncTask;
|
||||||
import org.mozilla.gecko.webapp.UninstallListener;
|
import org.mozilla.gecko.webapp.UninstallListener;
|
||||||
|
import org.mozilla.gecko.webapp.EventListener;
|
||||||
import org.mozilla.gecko.widget.ButtonToast;
|
import org.mozilla.gecko.widget.ButtonToast;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
@ -633,34 +634,13 @@ public abstract class GeckoApp
|
|||||||
final String title = message.getString("title");
|
final String title = message.getString("title");
|
||||||
final String type = message.getString("shortcutType");
|
final String type = message.getString("shortcutType");
|
||||||
GeckoAppShell.removeShortcut(title, url, origin, type);
|
GeckoAppShell.removeShortcut(title, url, origin, type);
|
||||||
} else if (AppConstants.MOZ_ANDROID_SYNTHAPKS && event.equals("WebApps:InstallApk")) {
|
|
||||||
GeckoAppShell.installApk(this, message.getString("filePath"), message.getString("data"));
|
|
||||||
} else if (!AppConstants.MOZ_ANDROID_SYNTHAPKS && event.equals("WebApps:PreInstall")) {
|
} else if (!AppConstants.MOZ_ANDROID_SYNTHAPKS && event.equals("WebApps:PreInstall")) {
|
||||||
String name = message.getString("name");
|
String name = message.getString("name");
|
||||||
String manifestURL = message.getString("manifestURL");
|
String manifestURL = message.getString("manifestURL");
|
||||||
String origin = message.getString("origin");
|
String origin = message.getString("origin");
|
||||||
|
|
||||||
// preInstallWebapp will return a File object pointing to the profile directory of the webapp
|
// preInstallWebapp will return a File object pointing to the profile directory of the webapp
|
||||||
mCurrentResponse = GeckoAppShell.preInstallWebApp(name, manifestURL, origin).toString();
|
mCurrentResponse = EventListener.preInstallWebApp(name, manifestURL, origin).toString();
|
||||||
} else if (event.equals("WebApps:PostInstall")) {
|
|
||||||
if (AppConstants.MOZ_ANDROID_SYNTHAPKS) {
|
|
||||||
GeckoAppShell.postInstallWebApp(message.getString("apkPackageName"), message.getString("origin"));
|
|
||||||
} else {
|
|
||||||
String name = message.getString("name");
|
|
||||||
String manifestURL = message.getString("manifestURL");
|
|
||||||
String iconURL = message.getString("iconURL");
|
|
||||||
String originalOrigin = message.getString("originalOrigin");
|
|
||||||
String origin = message.getString("origin");
|
|
||||||
GeckoAppShell.postInstallWebApp(name, manifestURL, origin, iconURL, originalOrigin);
|
|
||||||
}
|
|
||||||
} else if (event.equals("WebApps:Open")) {
|
|
||||||
String manifestURL = message.getString("manifestURL");
|
|
||||||
String origin = message.getString("origin");
|
|
||||||
Intent intent = GeckoAppShell.getWebAppIntent(manifestURL, origin, "", null);
|
|
||||||
if (intent == null)
|
|
||||||
return;
|
|
||||||
startActivity(intent);
|
|
||||||
} else if (!AppConstants.MOZ_ANDROID_SYNTHAPKS && event.equals("WebApps:Uninstall")) {
|
|
||||||
GeckoAppShell.uninstallWebApp(message.getString("origin"));
|
|
||||||
} else if (event.equals("Share:Text")) {
|
} else if (event.equals("Share:Text")) {
|
||||||
String text = message.getString("text");
|
String text = message.getString("text");
|
||||||
GeckoAppShell.openUriExternal(text, "text/plain", "", "", Intent.ACTION_SEND, "");
|
GeckoAppShell.openUriExternal(text, "text/plain", "", "", Intent.ACTION_SEND, "");
|
||||||
@ -1564,12 +1544,6 @@ public abstract class GeckoApp
|
|||||||
registerEventListener("Accessibility:Event");
|
registerEventListener("Accessibility:Event");
|
||||||
registerEventListener("Accessibility:Ready");
|
registerEventListener("Accessibility:Ready");
|
||||||
registerEventListener("Shortcut:Remove");
|
registerEventListener("Shortcut:Remove");
|
||||||
// TODO Consider moving webapp install-related things into InstallHelper.
|
|
||||||
registerEventListener("WebApps:InstallApk");
|
|
||||||
registerEventListener("WebApps:PreInstall");
|
|
||||||
registerEventListener("WebApps:PostInstall");
|
|
||||||
registerEventListener("WebApps:Open");
|
|
||||||
registerEventListener("WebApps:Uninstall");
|
|
||||||
registerEventListener("Share:Text");
|
registerEventListener("Share:Text");
|
||||||
registerEventListener("Share:Image");
|
registerEventListener("Share:Image");
|
||||||
registerEventListener("Image:SetAs");
|
registerEventListener("Image:SetAs");
|
||||||
@ -1583,6 +1557,9 @@ public abstract class GeckoApp
|
|||||||
registerEventListener("Intent:GetHandlers");
|
registerEventListener("Intent:GetHandlers");
|
||||||
registerEventListener("Locale:Set");
|
registerEventListener("Locale:Set");
|
||||||
registerEventListener("SystemUI:Visibility");
|
registerEventListener("SystemUI:Visibility");
|
||||||
|
registerEventListener("WebApps:PreInstall");
|
||||||
|
|
||||||
|
EventListener.registerEvents();
|
||||||
|
|
||||||
if (SmsManager.getInstance() != null) {
|
if (SmsManager.getInstance() != null) {
|
||||||
SmsManager.getInstance().start();
|
SmsManager.getInstance().start();
|
||||||
@ -2095,11 +2072,6 @@ public abstract class GeckoApp
|
|||||||
unregisterEventListener("Accessibility:Event");
|
unregisterEventListener("Accessibility:Event");
|
||||||
unregisterEventListener("Accessibility:Ready");
|
unregisterEventListener("Accessibility:Ready");
|
||||||
unregisterEventListener("Shortcut:Remove");
|
unregisterEventListener("Shortcut:Remove");
|
||||||
unregisterEventListener("WebApps:InstallApk");
|
|
||||||
unregisterEventListener("WebApps:PreInstall");
|
|
||||||
unregisterEventListener("WebApps:PostInstall");
|
|
||||||
unregisterEventListener("WebApps:Open");
|
|
||||||
unregisterEventListener("WebApps:Uninstall");
|
|
||||||
unregisterEventListener("Share:Text");
|
unregisterEventListener("Share:Text");
|
||||||
unregisterEventListener("Share:Image");
|
unregisterEventListener("Share:Image");
|
||||||
unregisterEventListener("Image:SetAs");
|
unregisterEventListener("Image:SetAs");
|
||||||
@ -2113,6 +2085,9 @@ public abstract class GeckoApp
|
|||||||
unregisterEventListener("Intent:GetHandlers");
|
unregisterEventListener("Intent:GetHandlers");
|
||||||
unregisterEventListener("Locale:Set");
|
unregisterEventListener("Locale:Set");
|
||||||
unregisterEventListener("SystemUI:Visibility");
|
unregisterEventListener("SystemUI:Visibility");
|
||||||
|
unregisterEventListener("WebApps:PreInstall");
|
||||||
|
|
||||||
|
EventListener.unregisterEvents();
|
||||||
|
|
||||||
deleteTempFiles();
|
deleteTempFiles();
|
||||||
|
|
||||||
|
@ -10,18 +10,19 @@ import org.mozilla.gecko.gfx.BitmapUtils;
|
|||||||
import org.mozilla.gecko.gfx.GeckoLayerClient;
|
import org.mozilla.gecko.gfx.GeckoLayerClient;
|
||||||
import org.mozilla.gecko.gfx.LayerView;
|
import org.mozilla.gecko.gfx.LayerView;
|
||||||
import org.mozilla.gecko.gfx.PanZoomController;
|
import org.mozilla.gecko.gfx.PanZoomController;
|
||||||
import org.mozilla.gecko.mozglue.JNITarget;
|
import org.mozilla.gecko.mozglue.GeckoLoader;
|
||||||
import org.mozilla.gecko.mozglue.generatorannotations.OptionalGeneratedParameter;
|
import org.mozilla.gecko.mozglue.generatorannotations.OptionalGeneratedParameter;
|
||||||
import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
|
import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
|
||||||
import org.mozilla.gecko.prompts.PromptService;
|
import org.mozilla.gecko.mozglue.JNITarget;
|
||||||
import org.mozilla.gecko.mozglue.GeckoLoader;
|
|
||||||
import org.mozilla.gecko.mozglue.RobocopTarget;
|
import org.mozilla.gecko.mozglue.RobocopTarget;
|
||||||
|
import org.mozilla.gecko.prompts.PromptService;
|
||||||
import org.mozilla.gecko.util.ActivityResultHandler;
|
import org.mozilla.gecko.util.ActivityResultHandler;
|
||||||
import org.mozilla.gecko.util.EventDispatcher;
|
import org.mozilla.gecko.util.EventDispatcher;
|
||||||
import org.mozilla.gecko.util.GeckoEventListener;
|
import org.mozilla.gecko.util.GeckoEventListener;
|
||||||
import org.mozilla.gecko.util.HardwareUtils;
|
import org.mozilla.gecko.util.HardwareUtils;
|
||||||
import org.mozilla.gecko.util.ProxySelector;
|
import org.mozilla.gecko.util.ProxySelector;
|
||||||
import org.mozilla.gecko.util.ThreadUtils;
|
import org.mozilla.gecko.util.ThreadUtils;
|
||||||
|
import org.mozilla.gecko.webapp.Allocator;
|
||||||
import org.mozilla.gecko.webapp.InstallListener;
|
import org.mozilla.gecko.webapp.InstallListener;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@ -718,34 +719,11 @@ public class GeckoAppShell
|
|||||||
gRestartScheduled = true;
|
gRestartScheduled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The old implementation of preInstallWebApp. Not used by MOZ_ANDROID_SYNTHAPKS.
|
|
||||||
public static File preInstallWebApp(String aTitle, String aURI, String aOrigin) {
|
|
||||||
int index = WebAppAllocator.getInstance(getContext()).findAndAllocateIndex(aOrigin, aTitle, (String) null);
|
|
||||||
GeckoProfile profile = GeckoProfile.get(getContext(), "webapp" + index);
|
|
||||||
return profile.getDir();
|
|
||||||
}
|
|
||||||
|
|
||||||
// The old implementation of postInstallWebApp. Not used by MOZ_ANDROID_SYNTHAPKS.
|
|
||||||
public static void postInstallWebApp(String aTitle, String aURI, String aOrigin, String aIconURL, String aOriginalOrigin) {
|
|
||||||
WebAppAllocator allocator = WebAppAllocator.getInstance(getContext());
|
|
||||||
int index = allocator.getIndexForApp(aOriginalOrigin);
|
|
||||||
assert index != -1 && aIconURL != null;
|
|
||||||
allocator.updateAppAllocation(aOrigin, index, BitmapUtils.getBitmapFromDataURI(aIconURL));
|
|
||||||
createShortcut(aTitle, aURI, aOrigin, aIconURL, "webapp");
|
|
||||||
}
|
|
||||||
|
|
||||||
// The new implementation of postInstallWebApp. Used by MOZ_ANDROID_SYNTHAPKS.
|
|
||||||
public static void postInstallWebApp(String aPackageName, String aOrigin) {
|
|
||||||
org.mozilla.gecko.webapp.WebAppAllocator allocator = org.mozilla.gecko.webapp.WebAppAllocator.getInstance(getContext());
|
|
||||||
int index = allocator.findOrAllocatePackage(aPackageName);
|
|
||||||
allocator.putOrigin(index, aOrigin);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Intent getWebAppIntent(String aURI, String aOrigin, String aTitle, Bitmap aIcon) {
|
public static Intent getWebAppIntent(String aURI, String aOrigin, String aTitle, Bitmap aIcon) {
|
||||||
Intent intent;
|
Intent intent;
|
||||||
|
|
||||||
if (AppConstants.MOZ_ANDROID_SYNTHAPKS) {
|
if (AppConstants.MOZ_ANDROID_SYNTHAPKS) {
|
||||||
org.mozilla.gecko.webapp.WebAppAllocator slots = org.mozilla.gecko.webapp.WebAppAllocator.getInstance(getContext());
|
Allocator slots = Allocator.getInstance(getContext());
|
||||||
int index = slots.getIndexForOrigin(aOrigin);
|
int index = slots.getIndexForOrigin(aOrigin);
|
||||||
|
|
||||||
if (index == -1) {
|
if (index == -1) {
|
||||||
@ -873,45 +851,6 @@ public class GeckoAppShell
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void uninstallWebApp(final String uniqueURI) {
|
|
||||||
// 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;
|
|
||||||
if (AppConstants.MOZ_ANDROID_SYNTHAPKS) {
|
|
||||||
index = org.mozilla.gecko.webapp.WebAppAllocator.getInstance(getContext()).releaseIndexForApp(uniqueURI);
|
|
||||||
} else {
|
|
||||||
index = WebAppAllocator.getInstance(getContext()).releaseIndexForApp(uniqueURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if -1, nothing to do; we didn't think it was installed anyway
|
|
||||||
if (index == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// kill the app if it's running
|
|
||||||
String targetProcessName = getContext().getPackageName();
|
|
||||||
targetProcessName = targetProcessName + ":" + targetProcessName + ".WebApp" + index;
|
|
||||||
|
|
||||||
ActivityManager am = (ActivityManager) getContext().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(getContext(), "webapp" + index);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@JNITarget
|
@JNITarget
|
||||||
static public int getPreferredIconSize() {
|
static public int getPreferredIconSize() {
|
||||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||||
@ -2739,54 +2678,4 @@ public class GeckoAppShell
|
|||||||
return "DIRECT";
|
return "DIRECT";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void installApk(final Activity context, String filePath, String data) {
|
|
||||||
// This is the data that mozApps.install sent to Webapps.jsm.
|
|
||||||
JSONObject argsObj = null;
|
|
||||||
|
|
||||||
// We get the manifest url out of javascript here so we can use it as a checksum
|
|
||||||
// in a minute, when a package has been installed.
|
|
||||||
String manifestUrl = null;
|
|
||||||
try {
|
|
||||||
argsObj = new JSONObject(data);
|
|
||||||
manifestUrl = argsObj.getJSONObject("app").getString("manifestURL");
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.e(LOGTAG, "can't get manifest URL from JSON data", e);
|
|
||||||
// TODO: propagate the error back to the mozApps.install caller.
|
|
||||||
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, argsObj);
|
|
||||||
|
|
||||||
// Listen for packages being installed.
|
|
||||||
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
|
|
||||||
filter.addDataScheme("package");
|
|
||||||
context.registerReceiver(receiver, filter);
|
|
||||||
|
|
||||||
// Now call the package installer.
|
|
||||||
File file = new File(filePath);
|
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
||||||
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
|
|
||||||
|
|
||||||
sActivityHelper.startIntentForActivity(context, intent, new ActivityResultHandler() {
|
|
||||||
@Override
|
|
||||||
public void onActivityResult(int resultCode, Intent data) {
|
|
||||||
// The InstallListener will catch the case where the user pressed install.
|
|
||||||
// Now deal with if the user pressed cancel.
|
|
||||||
if (resultCode == Activity.RESULT_CANCELED) {
|
|
||||||
try {
|
|
||||||
context.unregisterReceiver(receiver);
|
|
||||||
receiver.cleanup();
|
|
||||||
} catch (java.lang.IllegalArgumentException e) {
|
|
||||||
// IllegalArgumentException happens because resultCode is RESULT_CANCELED
|
|
||||||
// when the user presses the Done button in the install confirmation dialog,
|
|
||||||
// even though the install has been successful (and InstallListener already
|
|
||||||
// unregistered the receiver).
|
|
||||||
Log.e(LOGTAG, "error unregistering install receiver: ", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -331,12 +331,13 @@ gbjar.sources += [
|
|||||||
'updater/UpdateService.java',
|
'updater/UpdateService.java',
|
||||||
'updater/UpdateServiceHelper.java',
|
'updater/UpdateServiceHelper.java',
|
||||||
'VideoPlayer.java',
|
'VideoPlayer.java',
|
||||||
|
'webapp/Allocator.java',
|
||||||
'webapp/ApkResources.java',
|
'webapp/ApkResources.java',
|
||||||
|
'webapp/Dispatcher.java',
|
||||||
|
'webapp/EventListener.java',
|
||||||
'webapp/InstallHelper.java',
|
'webapp/InstallHelper.java',
|
||||||
'webapp/InstallListener.java',
|
'webapp/InstallListener.java',
|
||||||
'webapp/UninstallListener.java',
|
'webapp/UninstallListener.java',
|
||||||
'webapp/WebAppAllocator.java',
|
|
||||||
'webapp/WebAppDispatcher.java',
|
|
||||||
'webapp/WebAppImpl.java',
|
'webapp/WebAppImpl.java',
|
||||||
'WebAppAllocator.java',
|
'WebAppAllocator.java',
|
||||||
'WebAppImpl.java',
|
'WebAppImpl.java',
|
||||||
|
@ -16,7 +16,7 @@ import java.util.ArrayList;
|
|||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
public class WebAppAllocator {
|
public class Allocator {
|
||||||
|
|
||||||
private final String LOGTAG = "GeckoWebAppAllocator";
|
private final String LOGTAG = "GeckoWebAppAllocator";
|
||||||
|
|
||||||
@ -26,14 +26,14 @@ public class WebAppAllocator {
|
|||||||
// The number of WebApp# and WEBAPP# activites/apps/intents
|
// The number of WebApp# and WEBAPP# activites/apps/intents
|
||||||
private final static int MAX_WEB_APPS = 100;
|
private final static int MAX_WEB_APPS = 100;
|
||||||
|
|
||||||
protected static WebAppAllocator sInstance = null;
|
protected static Allocator sInstance = null;
|
||||||
public static WebAppAllocator getInstance() {
|
public static Allocator getInstance() {
|
||||||
return getInstance(GeckoAppShell.getContext());
|
return getInstance(GeckoAppShell.getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized WebAppAllocator getInstance(Context cx) {
|
public static synchronized Allocator getInstance(Context cx) {
|
||||||
if (sInstance == null) {
|
if (sInstance == null) {
|
||||||
sInstance = new WebAppAllocator(cx);
|
sInstance = new Allocator(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sInstance;
|
return sInstance;
|
||||||
@ -41,7 +41,7 @@ public class WebAppAllocator {
|
|||||||
|
|
||||||
SharedPreferences mPrefs;
|
SharedPreferences mPrefs;
|
||||||
|
|
||||||
protected WebAppAllocator(Context context) {
|
protected Allocator(Context context) {
|
||||||
mPrefs = context.getSharedPreferences("webapps", Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS);
|
mPrefs = context.getSharedPreferences("webapps", Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS);
|
||||||
}
|
}
|
||||||
|
|
@ -21,7 +21,7 @@ import android.os.Environment;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
public class ApkResources {
|
public class ApkResources {
|
||||||
private static final String LOGTAG = "GeckoApkResources";
|
private static final String LOGTAG = "GeckoWebAppApkResources";
|
||||||
private final String mPackageName;
|
private final String mPackageName;
|
||||||
private final ApplicationInfo mInfo;
|
private final ApplicationInfo mInfo;
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
@ -8,20 +8,25 @@ package org.mozilla.gecko.webapp;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
public class WebAppDispatcher extends Activity {
|
public class Dispatcher extends Activity {
|
||||||
private static final String LOGTAG = "GeckoWebAppDispatcher";
|
private static final String LOGTAG = "GeckoWebAppDispatcher";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle bundle) {
|
protected void onCreate(Bundle bundle) {
|
||||||
super.onCreate(bundle);
|
super.onCreate(bundle);
|
||||||
|
|
||||||
WebAppAllocator allocator = WebAppAllocator.getInstance(getApplicationContext());
|
Allocator allocator = Allocator.getInstance(getApplicationContext());
|
||||||
|
|
||||||
if (bundle == null) {
|
if (bundle == null) {
|
||||||
bundle = getIntent().getExtras();
|
bundle = getIntent().getExtras();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bundle == null) {
|
||||||
|
Log.e(LOGTAG, "Passed intent data missing.");
|
||||||
|
}
|
||||||
|
|
||||||
String packageName = bundle.getString("packageName");
|
String packageName = bundle.getString("packageName");
|
||||||
|
|
||||||
int index = allocator.getIndexForApp(packageName);
|
int index = allocator.getIndexForApp(packageName);
|
217
mobile/android/base/webapp/EventListener.java
Normal file
217
mobile/android/base/webapp/EventListener.java
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
/* -*- 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.GeckoAppShell;
|
||||||
|
import org.mozilla.gecko.GeckoProfile;
|
||||||
|
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||||
|
import org.mozilla.gecko.util.ActivityResultHandler;
|
||||||
|
import org.mozilla.gecko.util.EventDispatcher;
|
||||||
|
import org.mozilla.gecko.util.GeckoEventListener;
|
||||||
|
import org.mozilla.gecko.util.ThreadUtils;
|
||||||
|
import org.mozilla.gecko.WebAppAllocator;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.ActivityManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
public class EventListener implements GeckoEventListener {
|
||||||
|
|
||||||
|
private static final String LOGTAG = "GeckoWebAppEventListener";
|
||||||
|
|
||||||
|
private EventListener() { }
|
||||||
|
|
||||||
|
private static EventListener mEventListener;
|
||||||
|
|
||||||
|
private static EventListener getEventListener() {
|
||||||
|
if (mEventListener == null) {
|
||||||
|
mEventListener = new EventListener();
|
||||||
|
}
|
||||||
|
return mEventListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void registerEventListener(String event) {
|
||||||
|
GeckoAppShell.getEventDispatcher().registerEventListener(event, EventListener.getEventListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void unregisterEventListener(String event) {
|
||||||
|
GeckoAppShell.getEventDispatcher().unregisterEventListener(event, EventListener.getEventListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void registerEvents() {
|
||||||
|
registerEventListener("WebApps:PreInstall");
|
||||||
|
registerEventListener("WebApps:InstallApk");
|
||||||
|
registerEventListener("WebApps:PostInstall");
|
||||||
|
registerEventListener("WebApps:Open");
|
||||||
|
registerEventListener("WebApps:Uninstall");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unregisterEvents() {
|
||||||
|
unregisterEventListener("WebApps:PreInstall");
|
||||||
|
unregisterEventListener("WebApps:InstallApk");
|
||||||
|
unregisterEventListener("WebApps:PostInstall");
|
||||||
|
unregisterEventListener("WebApps:Open");
|
||||||
|
unregisterEventListener("WebApps:Uninstall");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(String event, JSONObject message) {
|
||||||
|
try {
|
||||||
|
if (AppConstants.MOZ_ANDROID_SYNTHAPKS && event.equals("WebApps:InstallApk")) {
|
||||||
|
installApk(GeckoAppShell.getGeckoInterface().getActivity(), message.getString("filePath"), message.getString("data"));
|
||||||
|
} else if (event.equals("WebApps:PostInstall")) {
|
||||||
|
if (AppConstants.MOZ_ANDROID_SYNTHAPKS) {
|
||||||
|
postInstallWebApp(message.getString("apkPackageName"), message.getString("origin"));
|
||||||
|
} else {
|
||||||
|
postInstallWebApp(message.getString("name"),
|
||||||
|
message.getString("manifestURL"),
|
||||||
|
message.getString("origin"),
|
||||||
|
message.getString("iconURL"),
|
||||||
|
message.getString("originalOrigin"));
|
||||||
|
}
|
||||||
|
} else if (event.equals("WebApps:Open")) {
|
||||||
|
Intent intent = GeckoAppShell.getWebAppIntent(message.getString("manifestURL"),
|
||||||
|
message.getString("origin"),
|
||||||
|
"", null);
|
||||||
|
if (intent == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GeckoAppShell.getGeckoInterface().getActivity().startActivity(intent);
|
||||||
|
} else if (!AppConstants.MOZ_ANDROID_SYNTHAPKS && event.equals("WebApps:Uninstall")) {
|
||||||
|
uninstallWebApp(message.getString("origin"));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not used by MOZ_ANDROID_SYNTHAPKS.
|
||||||
|
public static File preInstallWebApp(String aTitle, String aURI, String aOrigin) {
|
||||||
|
int index = WebAppAllocator.getInstance(GeckoAppShell.getContext()).findAndAllocateIndex(aOrigin, aTitle, (String) null);
|
||||||
|
GeckoProfile profile = GeckoProfile.get(GeckoAppShell.getContext(), "webapp" + index);
|
||||||
|
return profile.getDir();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not used by MOZ_ANDROID_SYNTHAPKS.
|
||||||
|
public static void postInstallWebApp(String aTitle, String aURI, String aOrigin, String aIconURL, String aOriginalOrigin) {
|
||||||
|
WebAppAllocator allocator = WebAppAllocator.getInstance(GeckoAppShell.getContext());
|
||||||
|
int index = allocator.getIndexForApp(aOriginalOrigin);
|
||||||
|
|
||||||
|
assert aIconURL != null;
|
||||||
|
Bitmap icon = BitmapUtils.getBitmapFromDataURI(aIconURL);
|
||||||
|
|
||||||
|
assert aOrigin != null && index != -1;
|
||||||
|
allocator.updateAppAllocation(aOrigin, index, icon);
|
||||||
|
|
||||||
|
GeckoAppShell.createShortcut(aTitle, aURI, aOrigin, icon, "webapp");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used by MOZ_ANDROID_SYNTHAPKS.
|
||||||
|
public static void postInstallWebApp(String aPackageName, String aOrigin) {
|
||||||
|
Allocator allocator = Allocator.getInstance(GeckoAppShell.getContext());
|
||||||
|
int index = allocator.findOrAllocatePackage(aPackageName);
|
||||||
|
allocator.putOrigin(index, aOrigin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void uninstallWebApp(final String uniqueURI) {
|
||||||
|
// 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;
|
||||||
|
index = Allocator.getInstance(GeckoAppShell.getContext()).releaseIndexForApp(uniqueURI);
|
||||||
|
|
||||||
|
// if -1, nothing to do; we didn't think it was installed anyway
|
||||||
|
if (index == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// kill the app if it's running
|
||||||
|
String targetProcessName = GeckoAppShell.getContext().getPackageName();
|
||||||
|
targetProcessName = targetProcessName + ":" + targetProcessName + ".WebApp" + index;
|
||||||
|
|
||||||
|
ActivityManager am = (ActivityManager) GeckoAppShell.getContext().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(GeckoAppShell.getContext(), "webapp" + index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void installApk(final Activity context, String filePath, String data) {
|
||||||
|
// This is the data that mozApps.install sent to Webapps.jsm.
|
||||||
|
JSONObject argsObj = null;
|
||||||
|
|
||||||
|
// We get the manifest url out of javascript here so we can use it as a checksum
|
||||||
|
// in a minute, when a package has been installed.
|
||||||
|
String manifestUrl = null;
|
||||||
|
try {
|
||||||
|
argsObj = new JSONObject(data);
|
||||||
|
manifestUrl = argsObj.getJSONObject("app").getString("manifestURL");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(LOGTAG, "can't get manifest URL from JSON data", e);
|
||||||
|
// TODO: propagate the error back to the mozApps.install caller.
|
||||||
|
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, argsObj);
|
||||||
|
|
||||||
|
// Listen for packages being installed.
|
||||||
|
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
|
||||||
|
filter.addDataScheme("package");
|
||||||
|
context.registerReceiver(receiver, filter);
|
||||||
|
|
||||||
|
// Now call the package installer.
|
||||||
|
File file = new File(filePath);
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
|
||||||
|
|
||||||
|
GeckoAppShell.sActivityHelper.startIntentForActivity(context, intent, new ActivityResultHandler() {
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(int resultCode, Intent data) {
|
||||||
|
// The InstallListener will catch the case where the user pressed install.
|
||||||
|
// Now deal with if the user pressed cancel.
|
||||||
|
if (resultCode == Activity.RESULT_CANCELED) {
|
||||||
|
try {
|
||||||
|
context.unregisterReceiver(receiver);
|
||||||
|
receiver.cleanup();
|
||||||
|
} catch (java.lang.IllegalArgumentException e) {
|
||||||
|
// IllegalArgumentException happens because resultCode is RESULT_CANCELED
|
||||||
|
// when the user presses the Done button in the install confirmation dialog,
|
||||||
|
// even though the install has been successful (and InstallListener already
|
||||||
|
// unregistered the receiver).
|
||||||
|
Log.e(LOGTAG, "error unregistering install receiver: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -27,7 +27,7 @@ import android.net.Uri;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
public class InstallHelper implements GeckoEventListener {
|
public class InstallHelper implements GeckoEventListener {
|
||||||
private static final String LOGTAG = "GeckoInstallHelper";
|
private static final String LOGTAG = "GeckoWebAppInstallHelper";
|
||||||
private static final String[] INSTALL_EVENT_NAMES = new String[] {"WebApps:PostInstall"};
|
private static final String[] INSTALL_EVENT_NAMES = new String[] {"WebApps:PostInstall"};
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final InstallCallback mCallback;
|
private final InstallCallback mCallback;
|
||||||
@ -156,7 +156,7 @@ public class InstallHelper implements GeckoEventListener {
|
|||||||
|
|
||||||
private void calculateColor() {
|
private void calculateColor() {
|
||||||
ThreadUtils.assertOnBackgroundThread();
|
ThreadUtils.assertOnBackgroundThread();
|
||||||
WebAppAllocator slots = WebAppAllocator.getInstance(mContext);
|
Allocator slots = Allocator.getInstance(mContext);
|
||||||
int index = slots.getIndexForApp(mApkResources.getPackageName());
|
int index = slots.getIndexForApp(mApkResources.getPackageName());
|
||||||
Bitmap bitmap = BitmapUtils.getBitmapFromDrawable(mApkResources.getAppIcon());
|
Bitmap bitmap = BitmapUtils.getBitmapFromDrawable(mApkResources.getAppIcon());
|
||||||
slots.updateColor(index, BitmapUtils.getDominantColor(bitmap));
|
slots.updateColor(index, BitmapUtils.getDominantColor(bitmap));
|
||||||
|
@ -24,7 +24,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
public class InstallListener extends BroadcastReceiver {
|
public class InstallListener extends BroadcastReceiver {
|
||||||
|
|
||||||
private static String LOGTAG = "GeckoInstallListener";
|
private static String LOGTAG = "GeckoWebAppInstallListener";
|
||||||
private JSONObject mData = null;
|
private JSONObject mData = null;
|
||||||
private String mManifestUrl;
|
private String mManifestUrl;
|
||||||
|
|
||||||
@ -63,9 +63,10 @@ public class InstallListener extends BroadcastReceiver {
|
|||||||
if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) {
|
if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) {
|
||||||
InstallHelper installHelper = new InstallHelper(context, apkResources, null);
|
InstallHelper installHelper = new InstallHelper(context, apkResources, null);
|
||||||
try {
|
try {
|
||||||
JSONObject dataObject = mData;
|
JSONObject dataObject = new JSONObject();
|
||||||
dataObject = new JSONObject().put("request", dataObject);
|
dataObject.put("request", mData);
|
||||||
WebAppAllocator slots = WebAppAllocator.getInstance(context);
|
|
||||||
|
Allocator slots = Allocator.getInstance(context);
|
||||||
int i = slots.findOrAllocatePackage(packageName);
|
int i = slots.findOrAllocatePackage(packageName);
|
||||||
installHelper.startInstall("webapp" + i, dataObject);
|
installHelper.startInstall("webapp" + i, dataObject);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
@ -28,7 +28,7 @@ import java.util.ArrayList;
|
|||||||
|
|
||||||
public class UninstallListener extends BroadcastReceiver {
|
public class UninstallListener extends BroadcastReceiver {
|
||||||
|
|
||||||
private static String LOGTAG = "GeckoUninstallListener";
|
private static String LOGTAG = "GeckoWebAppUninstallListener";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
@ -39,7 +39,7 @@ public class UninstallListener extends BroadcastReceiver {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebAppAllocator allocator = WebAppAllocator.getInstance(context);
|
Allocator allocator = Allocator.getInstance(context);
|
||||||
ArrayList<String> installedPackages = allocator.getInstalledPackageNames();
|
ArrayList<String> installedPackages = allocator.getInstalledPackageNames();
|
||||||
|
|
||||||
if (installedPackages.contains(packageName)) {
|
if (installedPackages.contains(packageName)) {
|
||||||
@ -57,7 +57,7 @@ public class UninstallListener extends BroadcastReceiver {
|
|||||||
|
|
||||||
public static void initUninstallPackageScan(Context context) {
|
public static void initUninstallPackageScan(Context context) {
|
||||||
// get list of packages we think are installed
|
// get list of packages we think are installed
|
||||||
WebAppAllocator allocator = WebAppAllocator.getInstance(context);
|
Allocator allocator = Allocator.getInstance(context);
|
||||||
ArrayList<String> fennecPackages = allocator.getInstalledPackageNames();
|
ArrayList<String> fennecPackages = allocator.getInstalledPackageNames();
|
||||||
ArrayList<String> uninstalledPackages = new ArrayList<String>();
|
ArrayList<String> uninstalledPackages = new ArrayList<String>();
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ public class WebAppImpl extends GeckoApp implements InstallCallback {
|
|||||||
mTitlebar = findViewById(R.id.webapp_titlebar);
|
mTitlebar = findViewById(R.id.webapp_titlebar);
|
||||||
mSplashscreen = findViewById(R.id.splashscreen);
|
mSplashscreen = findViewById(R.id.splashscreen);
|
||||||
|
|
||||||
String origin = WebAppAllocator.getInstance(this).getOrigin(getIndex());
|
String origin = Allocator.getInstance(this).getOrigin(getIndex());
|
||||||
boolean isInstallCompleting = (origin == null);
|
boolean isInstallCompleting = (origin == null);
|
||||||
|
|
||||||
if (!GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning) || !isInstalled || isInstallCompleting) {
|
if (!GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning) || !isInstalled || isInstallCompleting) {
|
||||||
@ -154,7 +154,7 @@ public class WebAppImpl extends GeckoApp implements InstallCallback {
|
|||||||
private void showSplash(boolean isApk) {
|
private void showSplash(boolean isApk) {
|
||||||
|
|
||||||
// get the favicon dominant color, stored when the app was installed
|
// get the favicon dominant color, stored when the app was installed
|
||||||
int dominantColor = WebAppAllocator.getInstance().getColor(getIndex());
|
int dominantColor = Allocator.getInstance().getColor(getIndex());
|
||||||
|
|
||||||
setBackgroundGradient(dominantColor);
|
setBackgroundGradient(dominantColor);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user