зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1365126 - Move shortcut creation to static methods in GeckoApplication; r=droeh
Move shortcut creation code in GeckoApp to GeckoApplication, and make the methods static so that we can call them without a GeckoInterface instance. This lets us remove GeckoInterface.createShortcut. MozReview-Commit-ID: AUnQGI02Bk
This commit is contained in:
Родитель
9fe9e6e1c3
Коммит
5412475e7c
|
@ -1477,7 +1477,7 @@ public class BrowserApp extends GeckoApp
|
||||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
GeckoAppShell.createShortcut(title, url);
|
GeckoApplication.createShortcut(title, url);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2075,7 +2075,7 @@ public class BrowserApp extends GeckoApp
|
||||||
if (loadIconResult != null) {
|
if (loadIconResult != null) {
|
||||||
final Bitmap icon = loadIconResult
|
final Bitmap icon = loadIconResult
|
||||||
.getBestBitmap(GeckoAppShell.getPreferredIconSize());
|
.getBestBitmap(GeckoAppShell.getPreferredIconSize());
|
||||||
createAppShortcut(name, startUrl, manifestPath, icon);
|
GeckoApplication.createAppShortcut(name, startUrl, manifestPath, icon);
|
||||||
} else {
|
} else {
|
||||||
Log.e(LOGTAG, "Failed to load icon!");
|
Log.e(LOGTAG, "Failed to load icon!");
|
||||||
}
|
}
|
||||||
|
@ -2085,7 +2085,7 @@ public class BrowserApp extends GeckoApp
|
||||||
case "Website:AppInstallFailed":
|
case "Website:AppInstallFailed":
|
||||||
final String title = message.getString("title");
|
final String title = message.getString("title");
|
||||||
final String bookmarkUrl = message.getString("url");
|
final String bookmarkUrl = message.getString("url");
|
||||||
createBrowserShortcut(title, bookmarkUrl);
|
GeckoApplication.createBrowserShortcut(title, bookmarkUrl);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "Updater:Launch":
|
case "Updater:Launch":
|
||||||
|
|
|
@ -10,7 +10,6 @@ import org.mozilla.gecko.GeckoProfileDirectories.NoMozillaDirectoryException;
|
||||||
import org.mozilla.gecko.annotation.RobocopTarget;
|
import org.mozilla.gecko.annotation.RobocopTarget;
|
||||||
import org.mozilla.gecko.annotation.WrapForJNI;
|
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||||
import org.mozilla.gecko.db.BrowserDB;
|
import org.mozilla.gecko.db.BrowserDB;
|
||||||
import org.mozilla.gecko.db.UrlAnnotations;
|
|
||||||
import org.mozilla.gecko.gfx.BitmapUtils;
|
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||||
import org.mozilla.gecko.gfx.FullScreenState;
|
import org.mozilla.gecko.gfx.FullScreenState;
|
||||||
import org.mozilla.gecko.gfx.LayerView;
|
import org.mozilla.gecko.gfx.LayerView;
|
||||||
|
@ -18,9 +17,6 @@ import org.mozilla.gecko.health.HealthRecorder;
|
||||||
import org.mozilla.gecko.health.SessionInformation;
|
import org.mozilla.gecko.health.SessionInformation;
|
||||||
import org.mozilla.gecko.health.StubbedHealthRecorder;
|
import org.mozilla.gecko.health.StubbedHealthRecorder;
|
||||||
import org.mozilla.gecko.home.HomeConfig.PanelType;
|
import org.mozilla.gecko.home.HomeConfig.PanelType;
|
||||||
import org.mozilla.gecko.icons.IconCallback;
|
|
||||||
import org.mozilla.gecko.icons.IconResponse;
|
|
||||||
import org.mozilla.gecko.icons.Icons;
|
|
||||||
import org.mozilla.gecko.menu.GeckoMenu;
|
import org.mozilla.gecko.menu.GeckoMenu;
|
||||||
import org.mozilla.gecko.menu.GeckoMenuInflater;
|
import org.mozilla.gecko.menu.GeckoMenuInflater;
|
||||||
import org.mozilla.gecko.menu.MenuPanel;
|
import org.mozilla.gecko.menu.MenuPanel;
|
||||||
|
@ -63,11 +59,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
@ -2148,141 +2139,6 @@ public abstract class GeckoApp extends GeckoActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createShortcut(final String title, final String url) {
|
|
||||||
|
|
||||||
final Tab selectedTab = Tabs.getInstance().getSelectedTab();
|
|
||||||
final String manifestUrl = selectedTab.getManifestUrl();
|
|
||||||
|
|
||||||
if (manifestUrl != null) {
|
|
||||||
// If a page has associated manifest, lets install it
|
|
||||||
final GeckoBundle message = new GeckoBundle();
|
|
||||||
message.putInt("iconSize", GeckoAppShell.getPreferredIconSize());
|
|
||||||
message.putString("manifestUrl", manifestUrl);
|
|
||||||
message.putString("originalUrl", url);
|
|
||||||
message.putString("originalTitle", title);
|
|
||||||
EventDispatcher.getInstance().dispatch("Browser:LoadManifest", message);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
createBrowserShortcut(title, url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createBrowserShortcut(final String title, final String url) {
|
|
||||||
Icons.with(this)
|
|
||||||
.pageUrl(url)
|
|
||||||
.skipNetwork()
|
|
||||||
.skipMemory()
|
|
||||||
.forLauncherIcon()
|
|
||||||
.build()
|
|
||||||
.execute(new IconCallback() {
|
|
||||||
@Override
|
|
||||||
public void onIconResponse(IconResponse response) {
|
|
||||||
createShortcut(title, url, response.getBitmap());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createShortcut(final String aTitle, final String aURI, final Bitmap aIcon) {
|
|
||||||
Intent shortcutIntent = new Intent();
|
|
||||||
shortcutIntent.setAction(GeckoApp.ACTION_HOMESCREEN_SHORTCUT);
|
|
||||||
shortcutIntent.setData(Uri.parse(aURI));
|
|
||||||
shortcutIntent.setClassName(AppConstants.ANDROID_PACKAGE_NAME,
|
|
||||||
AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS);
|
|
||||||
createHomescreenIcon(shortcutIntent, aTitle, aURI, aIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createAppShortcut(final String aTitle, final String aURI, final String manifestPath, final Bitmap aIcon) {
|
|
||||||
Intent shortcutIntent = new Intent();
|
|
||||||
shortcutIntent.setAction(GeckoApp.ACTION_WEBAPP);
|
|
||||||
shortcutIntent.setData(Uri.parse(aURI));
|
|
||||||
shortcutIntent.putExtra("MANIFEST_PATH", manifestPath);
|
|
||||||
shortcutIntent.setClassName(AppConstants.ANDROID_PACKAGE_NAME, LauncherActivity.class.getName());
|
|
||||||
Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.CONTEXT_MENU,
|
|
||||||
"pwa_add_to_launcher");
|
|
||||||
createHomescreenIcon(shortcutIntent, aTitle, aURI, aIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createHomescreenIcon(final Intent shortcutIntent, final String aTitle,
|
|
||||||
final String aURI, final Bitmap aIcon) {
|
|
||||||
Intent intent = new Intent();
|
|
||||||
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
|
|
||||||
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, getLauncherIcon(aIcon, GeckoAppShell.getPreferredIconSize()));
|
|
||||||
|
|
||||||
if (aTitle != null) {
|
|
||||||
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, aTitle);
|
|
||||||
} else {
|
|
||||||
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, aURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not allow duplicate items.
|
|
||||||
intent.putExtra("duplicate", false);
|
|
||||||
|
|
||||||
intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
|
|
||||||
getApplicationContext().sendBroadcast(intent);
|
|
||||||
|
|
||||||
// Remember interaction
|
|
||||||
final UrlAnnotations urlAnnotations = BrowserDB.from(getApplicationContext()).getUrlAnnotations();
|
|
||||||
urlAnnotations.insertHomeScreenShortcut(getContentResolver(), aURI, true);
|
|
||||||
|
|
||||||
// After shortcut is created, show the mobile desktop.
|
|
||||||
ActivityUtils.goToHomeScreen(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Bitmap getLauncherIcon(Bitmap aSource, int size) {
|
|
||||||
final float[] DEFAULT_LAUNCHER_ICON_HSV = { 32.0f, 1.0f, 1.0f };
|
|
||||||
final int kOffset = 6;
|
|
||||||
final int kRadius = 5;
|
|
||||||
|
|
||||||
int insetSize = aSource != null ? size * 2 / 3 : size;
|
|
||||||
|
|
||||||
Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
|
||||||
Canvas canvas = new Canvas(bitmap);
|
|
||||||
|
|
||||||
// draw a base color
|
|
||||||
Paint paint = new Paint();
|
|
||||||
if (aSource == null) {
|
|
||||||
// If we aren't drawing a favicon, just use an orange color.
|
|
||||||
paint.setColor(Color.HSVToColor(DEFAULT_LAUNCHER_ICON_HSV));
|
|
||||||
canvas.drawRoundRect(new RectF(kOffset, kOffset, size - kOffset, size - kOffset), kRadius, kRadius, paint);
|
|
||||||
} else if (aSource.getWidth() >= insetSize || aSource.getHeight() >= insetSize) {
|
|
||||||
// Otherwise, if the icon is large enough, just draw it.
|
|
||||||
Rect iconBounds = new Rect(0, 0, size, size);
|
|
||||||
canvas.drawBitmap(aSource, null, iconBounds, null);
|
|
||||||
return bitmap;
|
|
||||||
} else {
|
|
||||||
// otherwise use the dominant color from the icon + a layer of transparent white to lighten it somewhat
|
|
||||||
int color = BitmapUtils.getDominantColor(aSource);
|
|
||||||
paint.setColor(color);
|
|
||||||
canvas.drawRoundRect(new RectF(kOffset, kOffset, size - kOffset, size - kOffset), kRadius, kRadius, paint);
|
|
||||||
paint.setColor(Color.argb(100, 255, 255, 255));
|
|
||||||
canvas.drawRoundRect(new RectF(kOffset, kOffset, size - kOffset, size - kOffset), kRadius, kRadius, paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw the overlay
|
|
||||||
Bitmap overlay = BitmapUtils.decodeResource(this, R.drawable.home_bg);
|
|
||||||
canvas.drawBitmap(overlay, null, new Rect(0, 0, size, size), null);
|
|
||||||
|
|
||||||
// draw the favicon
|
|
||||||
if (aSource == null)
|
|
||||||
aSource = BitmapUtils.decodeResource(this, R.drawable.home_star);
|
|
||||||
|
|
||||||
// by default, we scale the icon to this size
|
|
||||||
int sWidth = insetSize / 2;
|
|
||||||
int sHeight = sWidth;
|
|
||||||
|
|
||||||
int halfSize = size / 2;
|
|
||||||
canvas.drawBitmap(aSource,
|
|
||||||
null,
|
|
||||||
new Rect(halfSize - sWidth,
|
|
||||||
halfSize - sHeight,
|
|
||||||
halfSize + sWidth,
|
|
||||||
halfSize + sHeight),
|
|
||||||
null);
|
|
||||||
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onNewIntent(Intent externalIntent) {
|
protected void onNewIntent(Intent externalIntent) {
|
||||||
super.onNewIntent(externalIntent);
|
super.onNewIntent(externalIntent);
|
||||||
|
|
|
@ -10,6 +10,13 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -17,11 +24,17 @@ import android.util.Log;
|
||||||
import com.squareup.leakcanary.LeakCanary;
|
import com.squareup.leakcanary.LeakCanary;
|
||||||
import com.squareup.leakcanary.RefWatcher;
|
import com.squareup.leakcanary.RefWatcher;
|
||||||
|
|
||||||
|
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||||
import org.mozilla.gecko.db.BrowserContract;
|
import org.mozilla.gecko.db.BrowserContract;
|
||||||
import org.mozilla.gecko.db.BrowserDB;
|
import org.mozilla.gecko.db.BrowserDB;
|
||||||
import org.mozilla.gecko.db.LocalBrowserDB;
|
import org.mozilla.gecko.db.LocalBrowserDB;
|
||||||
|
import org.mozilla.gecko.db.UrlAnnotations;
|
||||||
import org.mozilla.gecko.distribution.Distribution;
|
import org.mozilla.gecko.distribution.Distribution;
|
||||||
|
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||||
import org.mozilla.gecko.home.HomePanelsManager;
|
import org.mozilla.gecko.home.HomePanelsManager;
|
||||||
|
import org.mozilla.gecko.icons.IconCallback;
|
||||||
|
import org.mozilla.gecko.icons.IconResponse;
|
||||||
|
import org.mozilla.gecko.icons.Icons;
|
||||||
import org.mozilla.gecko.lwt.LightweightTheme;
|
import org.mozilla.gecko.lwt.LightweightTheme;
|
||||||
import org.mozilla.gecko.mdns.MulticastDNSManager;
|
import org.mozilla.gecko.mdns.MulticastDNSManager;
|
||||||
import org.mozilla.gecko.media.AudioFocusAgent;
|
import org.mozilla.gecko.media.AudioFocusAgent;
|
||||||
|
@ -29,6 +42,7 @@ import org.mozilla.gecko.media.RemoteManager;
|
||||||
import org.mozilla.gecko.notifications.NotificationClient;
|
import org.mozilla.gecko.notifications.NotificationClient;
|
||||||
import org.mozilla.gecko.notifications.NotificationHelper;
|
import org.mozilla.gecko.notifications.NotificationHelper;
|
||||||
import org.mozilla.gecko.preferences.DistroSharedPrefsImport;
|
import org.mozilla.gecko.preferences.DistroSharedPrefsImport;
|
||||||
|
import org.mozilla.gecko.util.ActivityUtils;
|
||||||
import org.mozilla.gecko.util.BundleEventListener;
|
import org.mozilla.gecko.util.BundleEventListener;
|
||||||
import org.mozilla.gecko.util.EventCallback;
|
import org.mozilla.gecko.util.EventCallback;
|
||||||
import org.mozilla.gecko.util.GeckoBundle;
|
import org.mozilla.gecko.util.GeckoBundle;
|
||||||
|
@ -395,4 +409,151 @@ public class GeckoApplication extends Application
|
||||||
public void prepareLightweightTheme() {
|
public void prepareLightweightTheme() {
|
||||||
mLightweightTheme = new LightweightTheme(this);
|
mLightweightTheme = new LightweightTheme(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creates a homescreen shortcut for a web page.
|
||||||
|
// This is the entry point from nsIShellService.
|
||||||
|
@WrapForJNI(calledFrom = "gecko")
|
||||||
|
public static void createShortcut(final String title, final String url) {
|
||||||
|
final Tab selectedTab = Tabs.getInstance().getSelectedTab();
|
||||||
|
final String manifestUrl = selectedTab.getManifestUrl();
|
||||||
|
|
||||||
|
if (manifestUrl != null) {
|
||||||
|
// If a page has associated manifest, lets install it
|
||||||
|
final GeckoBundle message = new GeckoBundle();
|
||||||
|
message.putInt("iconSize", GeckoAppShell.getPreferredIconSize());
|
||||||
|
message.putString("manifestUrl", manifestUrl);
|
||||||
|
message.putString("originalUrl", url);
|
||||||
|
message.putString("originalTitle", title);
|
||||||
|
EventDispatcher.getInstance().dispatch("Browser:LoadManifest", message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
createBrowserShortcut(title, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createBrowserShortcut(final String title, final String url) {
|
||||||
|
Icons.with(GeckoAppShell.getApplicationContext())
|
||||||
|
.pageUrl(url)
|
||||||
|
.skipNetwork()
|
||||||
|
.skipMemory()
|
||||||
|
.forLauncherIcon()
|
||||||
|
.build()
|
||||||
|
.execute(new IconCallback() {
|
||||||
|
@Override
|
||||||
|
public void onIconResponse(final IconResponse response) {
|
||||||
|
createShortcutWithIcon(title, url, response.getBitmap());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* package */ static void createShortcutWithIcon(final String aTitle, final String aURI,
|
||||||
|
final Bitmap aIcon) {
|
||||||
|
final Intent shortcutIntent = new Intent();
|
||||||
|
shortcutIntent.setAction(GeckoApp.ACTION_HOMESCREEN_SHORTCUT);
|
||||||
|
shortcutIntent.setData(Uri.parse(aURI));
|
||||||
|
shortcutIntent.setClassName(AppConstants.ANDROID_PACKAGE_NAME,
|
||||||
|
AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS);
|
||||||
|
createHomescreenIcon(shortcutIntent, aTitle, aURI, aIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createAppShortcut(final String aTitle, final String aURI,
|
||||||
|
final String manifestPath, final Bitmap aIcon) {
|
||||||
|
final Intent shortcutIntent = new Intent();
|
||||||
|
shortcutIntent.setAction(GeckoApp.ACTION_WEBAPP);
|
||||||
|
shortcutIntent.setData(Uri.parse(aURI));
|
||||||
|
shortcutIntent.putExtra("MANIFEST_PATH", manifestPath);
|
||||||
|
shortcutIntent.setClassName(AppConstants.ANDROID_PACKAGE_NAME,
|
||||||
|
LauncherActivity.class.getName());
|
||||||
|
Telemetry.sendUIEvent(TelemetryContract.Event.ACTION,
|
||||||
|
TelemetryContract.Method.CONTEXT_MENU,
|
||||||
|
"pwa_add_to_launcher");
|
||||||
|
createHomescreenIcon(shortcutIntent, aTitle, aURI, aIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createHomescreenIcon(final Intent shortcutIntent, final String aTitle,
|
||||||
|
final String aURI, final Bitmap aIcon) {
|
||||||
|
final Intent intent = new Intent();
|
||||||
|
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
|
||||||
|
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON,
|
||||||
|
getLauncherIcon(aIcon, GeckoAppShell.getPreferredIconSize()));
|
||||||
|
|
||||||
|
if (aTitle != null) {
|
||||||
|
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, aTitle);
|
||||||
|
} else {
|
||||||
|
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, aURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Context context = GeckoAppShell.getApplicationContext();
|
||||||
|
// Do not allow duplicate items.
|
||||||
|
intent.putExtra("duplicate", false);
|
||||||
|
|
||||||
|
intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
|
||||||
|
context.sendBroadcast(intent);
|
||||||
|
|
||||||
|
// Remember interaction
|
||||||
|
final UrlAnnotations urlAnnotations = BrowserDB.from(context).getUrlAnnotations();
|
||||||
|
urlAnnotations.insertHomeScreenShortcut(context.getContentResolver(), aURI, true);
|
||||||
|
|
||||||
|
// After shortcut is created, show the mobile desktop.
|
||||||
|
ActivityUtils.goToHomeScreen(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Bitmap getLauncherIcon(Bitmap aSource, int size) {
|
||||||
|
final float[] DEFAULT_LAUNCHER_ICON_HSV = { 32.0f, 1.0f, 1.0f };
|
||||||
|
final int kOffset = 6;
|
||||||
|
final int kRadius = 5;
|
||||||
|
|
||||||
|
final int insetSize = aSource != null ? size * 2 / 3 : size;
|
||||||
|
|
||||||
|
final Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
||||||
|
final Canvas canvas = new Canvas(bitmap);
|
||||||
|
|
||||||
|
// draw a base color
|
||||||
|
final Paint paint = new Paint();
|
||||||
|
if (aSource == null) {
|
||||||
|
// If we aren't drawing a favicon, just use an orange color.
|
||||||
|
paint.setColor(Color.HSVToColor(DEFAULT_LAUNCHER_ICON_HSV));
|
||||||
|
canvas.drawRoundRect(new RectF(kOffset, kOffset, size - kOffset, size - kOffset),
|
||||||
|
kRadius, kRadius, paint);
|
||||||
|
} else if (aSource.getWidth() >= insetSize || aSource.getHeight() >= insetSize) {
|
||||||
|
// Otherwise, if the icon is large enough, just draw it.
|
||||||
|
final Rect iconBounds = new Rect(0, 0, size, size);
|
||||||
|
canvas.drawBitmap(aSource, null, iconBounds, null);
|
||||||
|
return bitmap;
|
||||||
|
} else {
|
||||||
|
// Otherwise, use the dominant color from the icon +
|
||||||
|
// a layer of transparent white to lighten it somewhat.
|
||||||
|
final int color = BitmapUtils.getDominantColor(aSource);
|
||||||
|
paint.setColor(color);
|
||||||
|
canvas.drawRoundRect(new RectF(kOffset, kOffset, size - kOffset, size - kOffset),
|
||||||
|
kRadius, kRadius, paint);
|
||||||
|
paint.setColor(Color.argb(100, 255, 255, 255));
|
||||||
|
canvas.drawRoundRect(new RectF(kOffset, kOffset, size - kOffset, size - kOffset),
|
||||||
|
kRadius, kRadius, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the overlay
|
||||||
|
final Context context = GeckoAppShell.getApplicationContext();
|
||||||
|
final Bitmap overlay = BitmapUtils.decodeResource(context, R.drawable.home_bg);
|
||||||
|
canvas.drawBitmap(overlay, null, new Rect(0, 0, size, size), null);
|
||||||
|
|
||||||
|
// draw the favicon
|
||||||
|
if (aSource == null)
|
||||||
|
aSource = BitmapUtils.decodeResource(context, R.drawable.home_star);
|
||||||
|
|
||||||
|
// by default, we scale the icon to this size
|
||||||
|
final int sWidth = insetSize / 2;
|
||||||
|
final int sHeight = sWidth;
|
||||||
|
|
||||||
|
final int halfSize = size / 2;
|
||||||
|
canvas.drawBitmap(aSource,
|
||||||
|
null,
|
||||||
|
new Rect(halfSize - sWidth,
|
||||||
|
halfSize - sHeight,
|
||||||
|
halfSize + sWidth,
|
||||||
|
halfSize + sHeight),
|
||||||
|
null);
|
||||||
|
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import android.support.design.widget.NavigationView;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import org.mozilla.gecko.GeckoAppShell;
|
import org.mozilla.gecko.GeckoApplication;
|
||||||
import org.mozilla.gecko.IntentHelper;
|
import org.mozilla.gecko.IntentHelper;
|
||||||
import org.mozilla.gecko.R;
|
import org.mozilla.gecko.R;
|
||||||
import org.mozilla.gecko.Telemetry;
|
import org.mozilla.gecko.Telemetry;
|
||||||
|
@ -262,7 +262,7 @@ public abstract class ActivityStreamContextMenu
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R.id.add_homescreen:
|
case R.id.add_homescreen:
|
||||||
GeckoAppShell.createShortcut(item.getTitle(), item.getUrl());
|
GeckoApplication.createShortcut(item.getTitle(), item.getUrl());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R.id.open_new_tab:
|
case R.id.open_new_tab:
|
||||||
|
|
|
@ -17,7 +17,7 @@ import android.widget.ListView;
|
||||||
|
|
||||||
import org.mozilla.gecko.AboutPages;
|
import org.mozilla.gecko.AboutPages;
|
||||||
import org.mozilla.gecko.BrowserApp;
|
import org.mozilla.gecko.BrowserApp;
|
||||||
import org.mozilla.gecko.GeckoAppShell;
|
import org.mozilla.gecko.GeckoApplication;
|
||||||
import org.mozilla.gecko.GeckoSharedPrefs;
|
import org.mozilla.gecko.GeckoSharedPrefs;
|
||||||
import org.mozilla.gecko.R;
|
import org.mozilla.gecko.R;
|
||||||
import org.mozilla.gecko.SnackbarBuilder;
|
import org.mozilla.gecko.SnackbarBuilder;
|
||||||
|
@ -184,7 +184,7 @@ public class BookmarkStateChangeDelegate extends BrowserAppDelegateWithReference
|
||||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
GeckoAppShell.createShortcut(title, url);
|
GeckoApplication.createShortcut(title, url);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ package org.mozilla.gecko.home;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
|
||||||
import org.mozilla.gecko.GeckoAppShell;
|
|
||||||
import org.mozilla.gecko.GeckoApplication;
|
import org.mozilla.gecko.GeckoApplication;
|
||||||
import org.mozilla.gecko.GeckoProfile;
|
import org.mozilla.gecko.GeckoProfile;
|
||||||
import org.mozilla.gecko.GeckoSharedPrefs;
|
import org.mozilla.gecko.GeckoSharedPrefs;
|
||||||
|
@ -274,7 +273,7 @@ public abstract class HomeFragment extends Fragment {
|
||||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
GeckoAppShell.createShortcut(displayTitle, info.url);
|
GeckoApplication.createShortcut(displayTitle, info.url);
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,7 @@ import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.mozilla.gecko.GeckoAppShell;
|
import org.mozilla.gecko.GeckoApplication;
|
||||||
import org.mozilla.gecko.GeckoProfile;
|
import org.mozilla.gecko.GeckoProfile;
|
||||||
import org.mozilla.gecko.Locales;
|
import org.mozilla.gecko.Locales;
|
||||||
import org.mozilla.gecko.R;
|
import org.mozilla.gecko.R;
|
||||||
|
@ -120,7 +120,7 @@ public class HomeScreenPrompt extends Locales.LocaleAwareActivity implements Ico
|
||||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
GeckoAppShell.createShortcut(title, url);
|
GeckoApplication.createShortcut(title, url);
|
||||||
|
|
||||||
Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.BUTTON, TELEMETRY_EXTRA);
|
Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.BUTTON, TELEMETRY_EXTRA);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "nsShellService.h"
|
#include "nsShellService.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
|
|
||||||
#include "GeneratedJNIWrappers.h"
|
#include "FennecJNIWrappers.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
|
@ -22,9 +22,9 @@ NS_IMETHODIMP
|
||||||
nsShellService::CreateShortcut(const nsAString& aTitle, const nsAString& aURI,
|
nsShellService::CreateShortcut(const nsAString& aTitle, const nsAString& aURI,
|
||||||
const nsAString& aIcondata, const nsAString& aIntent)
|
const nsAString& aIcondata, const nsAString& aIntent)
|
||||||
{
|
{
|
||||||
if (!aTitle.Length() || !aURI.Length())
|
if (!aTitle.Length() || !aURI.Length() || !jni::IsFennec())
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
java::GeckoAppShell::CreateShortcut(aTitle, aURI);
|
java::GeckoApplication::CreateShortcut(aTitle, aURI);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,11 +34,6 @@ public class BaseGeckoInterface implements GeckoAppShell.GeckoInterface {
|
||||||
@Override
|
@Override
|
||||||
public void removeAppStateListener(GeckoAppShell.AppStateListener listener) {}
|
public void removeAppStateListener(GeckoAppShell.AppStateListener listener) {}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void createShortcut(String title, String URI) {
|
|
||||||
// By default, do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkUriVisited(String uri) {
|
public void checkUriVisited(String uri) {
|
||||||
// By default, no URIs are considered visited.
|
// By default, no URIs are considered visited.
|
||||||
|
|
|
@ -796,17 +796,6 @@ public class GeckoAppShell
|
||||||
// This is a vestige, to be removed as full-screen support for GeckoView is implemented.
|
// This is a vestige, to be removed as full-screen support for GeckoView is implemented.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a homescreen shortcut for a web page.
|
|
||||||
// This is the entry point from nsIShellService.
|
|
||||||
@WrapForJNI(calledFrom = "gecko")
|
|
||||||
public static void createShortcut(final String aTitle, final String aURI) {
|
|
||||||
final GeckoInterface geckoInterface = getGeckoInterface();
|
|
||||||
if (geckoInterface == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
geckoInterface.createShortcut(aTitle, aURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
@JNITarget
|
@JNITarget
|
||||||
static public int getPreferredIconSize() {
|
static public int getPreferredIconSize() {
|
||||||
ActivityManager am = (ActivityManager)
|
ActivityManager am = (ActivityManager)
|
||||||
|
@ -1677,16 +1666,6 @@ public class GeckoAppShell
|
||||||
public void addAppStateListener(AppStateListener listener);
|
public void addAppStateListener(AppStateListener listener);
|
||||||
public void removeAppStateListener(AppStateListener listener);
|
public void removeAppStateListener(AppStateListener listener);
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a shortcut -- generally a home-screen icon -- linking the given title to the given URI.
|
|
||||||
* <p>
|
|
||||||
* This method is always invoked on the Gecko thread.
|
|
||||||
*
|
|
||||||
* @param title of URI to link to.
|
|
||||||
* @param URI to link to.
|
|
||||||
*/
|
|
||||||
public void createShortcut(String title, String URI);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the given URI is visited.
|
* Check if the given URI is visited.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
|
|
@ -62,12 +62,12 @@ public class ActivityUtils {
|
||||||
/**
|
/**
|
||||||
* Finish this activity and launch the default home screen activity.
|
* Finish this activity and launch the default home screen activity.
|
||||||
*/
|
*/
|
||||||
public static void goToHomeScreen(Activity activity) {
|
public static void goToHomeScreen(Context context) {
|
||||||
Intent intent = new Intent(Intent.ACTION_MAIN);
|
Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||||
|
|
||||||
intent.addCategory(Intent.CATEGORY_HOME);
|
intent.addCategory(Intent.CATEGORY_HOME);
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
activity.startActivity(intent);
|
context.startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Activity getActivityFromContext(Context context) {
|
public static Activity getActivityFromContext(Context context) {
|
||||||
|
|
|
@ -153,14 +153,6 @@ auto GeckoAppShell::CreateInputStream(mozilla::jni::Object::Param a0) -> mozilla
|
||||||
return mozilla::jni::Method<CreateInputStream_t>::Call(GeckoAppShell::Context(), nullptr, a0);
|
return mozilla::jni::Method<CreateInputStream_t>::Call(GeckoAppShell::Context(), nullptr, a0);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr char GeckoAppShell::CreateShortcut_t::name[];
|
|
||||||
constexpr char GeckoAppShell::CreateShortcut_t::signature[];
|
|
||||||
|
|
||||||
auto GeckoAppShell::CreateShortcut(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1) -> void
|
|
||||||
{
|
|
||||||
return mozilla::jni::Method<CreateShortcut_t>::Call(GeckoAppShell::Context(), nullptr, a0, a1);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr char GeckoAppShell::DisableBatteryNotifications_t::name[];
|
constexpr char GeckoAppShell::DisableBatteryNotifications_t::name[];
|
||||||
constexpr char GeckoAppShell::DisableBatteryNotifications_t::signature[];
|
constexpr char GeckoAppShell::DisableBatteryNotifications_t::signature[];
|
||||||
|
|
||||||
|
|
|
@ -493,27 +493,6 @@ public:
|
||||||
|
|
||||||
static auto CreateInputStream(mozilla::jni::Object::Param) -> mozilla::jni::Object::LocalRef;
|
static auto CreateInputStream(mozilla::jni::Object::Param) -> mozilla::jni::Object::LocalRef;
|
||||||
|
|
||||||
struct CreateShortcut_t {
|
|
||||||
typedef GeckoAppShell Owner;
|
|
||||||
typedef void ReturnType;
|
|
||||||
typedef void SetterType;
|
|
||||||
typedef mozilla::jni::Args<
|
|
||||||
mozilla::jni::String::Param,
|
|
||||||
mozilla::jni::String::Param> Args;
|
|
||||||
static constexpr char name[] = "createShortcut";
|
|
||||||
static constexpr char signature[] =
|
|
||||||
"(Ljava/lang/String;Ljava/lang/String;)V";
|
|
||||||
static const bool isStatic = true;
|
|
||||||
static const mozilla::jni::ExceptionMode exceptionMode =
|
|
||||||
mozilla::jni::ExceptionMode::ABORT;
|
|
||||||
static const mozilla::jni::CallingThread callingThread =
|
|
||||||
mozilla::jni::CallingThread::GECKO;
|
|
||||||
static const mozilla::jni::DispatchTarget dispatchTarget =
|
|
||||||
mozilla::jni::DispatchTarget::CURRENT;
|
|
||||||
};
|
|
||||||
|
|
||||||
static auto CreateShortcut(mozilla::jni::String::Param, mozilla::jni::String::Param) -> void;
|
|
||||||
|
|
||||||
struct DisableBatteryNotifications_t {
|
struct DisableBatteryNotifications_t {
|
||||||
typedef GeckoAppShell Owner;
|
typedef GeckoAppShell Owner;
|
||||||
typedef void ReturnType;
|
typedef void ReturnType;
|
||||||
|
|
|
@ -71,6 +71,17 @@ auto GeckoApp::RemovePluginView(mozilla::jni::Object::Param a0) -> void
|
||||||
return mozilla::jni::Method<RemovePluginView_t>::Call(GeckoApp::Context(), nullptr, a0);
|
return mozilla::jni::Method<RemovePluginView_t>::Call(GeckoApp::Context(), nullptr, a0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char GeckoApplication::name[] =
|
||||||
|
"org/mozilla/gecko/GeckoApplication";
|
||||||
|
|
||||||
|
constexpr char GeckoApplication::CreateShortcut_t::name[];
|
||||||
|
constexpr char GeckoApplication::CreateShortcut_t::signature[];
|
||||||
|
|
||||||
|
auto GeckoApplication::CreateShortcut(mozilla::jni::String::Param a0, mozilla::jni::String::Param a1) -> void
|
||||||
|
{
|
||||||
|
return mozilla::jni::Method<CreateShortcut_t>::Call(GeckoApplication::Context(), nullptr, a0, a1);
|
||||||
|
}
|
||||||
|
|
||||||
const char GeckoJavaSampler::name[] =
|
const char GeckoJavaSampler::name[] =
|
||||||
"org/mozilla/gecko/GeckoJavaSampler";
|
"org/mozilla/gecko/GeckoJavaSampler";
|
||||||
|
|
||||||
|
|
|
@ -219,6 +219,39 @@ public:
|
||||||
template<class Impl> class Natives;
|
template<class Impl> class Natives;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GeckoApplication : public mozilla::jni::ObjectBase<GeckoApplication>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const char name[];
|
||||||
|
|
||||||
|
explicit GeckoApplication(const Context& ctx) : ObjectBase<GeckoApplication>(ctx) {}
|
||||||
|
|
||||||
|
struct CreateShortcut_t {
|
||||||
|
typedef GeckoApplication Owner;
|
||||||
|
typedef void ReturnType;
|
||||||
|
typedef void SetterType;
|
||||||
|
typedef mozilla::jni::Args<
|
||||||
|
mozilla::jni::String::Param,
|
||||||
|
mozilla::jni::String::Param> Args;
|
||||||
|
static constexpr char name[] = "createShortcut";
|
||||||
|
static constexpr char signature[] =
|
||||||
|
"(Ljava/lang/String;Ljava/lang/String;)V";
|
||||||
|
static const bool isStatic = true;
|
||||||
|
static const mozilla::jni::ExceptionMode exceptionMode =
|
||||||
|
mozilla::jni::ExceptionMode::ABORT;
|
||||||
|
static const mozilla::jni::CallingThread callingThread =
|
||||||
|
mozilla::jni::CallingThread::GECKO;
|
||||||
|
static const mozilla::jni::DispatchTarget dispatchTarget =
|
||||||
|
mozilla::jni::DispatchTarget::CURRENT;
|
||||||
|
};
|
||||||
|
|
||||||
|
static auto CreateShortcut(mozilla::jni::String::Param, mozilla::jni::String::Param) -> void;
|
||||||
|
|
||||||
|
static const mozilla::jni::CallingThread callingThread =
|
||||||
|
mozilla::jni::CallingThread::GECKO;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class GeckoJavaSampler : public mozilla::jni::ObjectBase<GeckoJavaSampler>
|
class GeckoJavaSampler : public mozilla::jni::ObjectBase<GeckoJavaSampler>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче