Bug 1356517 - Add deep links to handle events. r?grisha
MozReview-Commit-ID: 4OQTrbEdVtQ
--- a/mobile/android/base/AndroidManifest.xml.in
+++ b/mobile/android/base/AndroidManifest.xml.in
@@ -93,16 +93,17 @@
<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" />
+ <data android:scheme="firefox" />
</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" />
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -211,17 +211,17 @@ public class BrowserApp extends GeckoApp
// TODO: Replace with kinto endpoint.
private static final String SWITCHBOARD_SERVER = "https://firefox.settings.services.mozilla.com/v1/buckets/fennec/collections/experiments/records";
private static final String STATE_ABOUT_HOME_TOP_PADDING = "abouthome_top_padding";
private static final String BROWSER_SEARCH_TAG = "browser_search";
// Request ID for startActivityForResult.
- private static final int ACTIVITY_REQUEST_PREFERENCES = 1001;
+ public static final int ACTIVITY_REQUEST_PREFERENCES = 1001;
private static final int ACTIVITY_REQUEST_TAB_QUEUE = 2001;
public static final int ACTIVITY_REQUEST_FIRST_READERVIEW_BOOKMARK = 3001;
public static final int ACTIVITY_RESULT_FIRST_READERVIEW_BOOKMARKS_GOTO_BOOKMARKS = 3002;
public static final int ACTIVITY_RESULT_FIRST_READERVIEW_BOOKMARKS_IGNORE = 3003;
public static final int ACTIVITY_REQUEST_TRIPLE_READERVIEW = 4001;
public static final int ACTIVITY_RESULT_TRIPLE_READERVIEW_ADD_BOOKMARK = 4002;
public static final int ACTIVITY_RESULT_TRIPLE_READERVIEW_IGNORE = 4003;
--- a/mobile/android/base/java/org/mozilla/gecko/LauncherActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/LauncherActivity.java
@@ -1,45 +1,68 @@
/* -*- 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.Context;
import android.content.Intent;
+import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.customtabs.CustomTabsIntent;
+import android.util.Log;
+import org.mozilla.gecko.home.HomeConfig;
import org.mozilla.gecko.webapps.WebAppActivity;
import org.mozilla.gecko.webapps.WebAppIndexer;
import org.mozilla.gecko.customtabs.CustomTabsActivity;
import org.mozilla.gecko.db.BrowserContract;
import org.mozilla.gecko.mozglue.SafeIntent;
import org.mozilla.gecko.preferences.GeckoPreferences;
import org.mozilla.gecko.tabqueue.TabQueueHelper;
import org.mozilla.gecko.tabqueue.TabQueueService;
+import static org.mozilla.gecko.BrowserApp.ACTIVITY_REQUEST_PREFERENCES;
+import static org.mozilla.gecko.deeplink.DeepLinkContract.DEEP_LINK_SCHEME;
+import static org.mozilla.gecko.deeplink.DeepLinkContract.LINK_BOOKMARK_LIST;
+import static org.mozilla.gecko.deeplink.DeepLinkContract.LINK_DEFAULT_BROWSER;
+import static org.mozilla.gecko.deeplink.DeepLinkContract.LINK_HISTORY_LIST;
+import static org.mozilla.gecko.deeplink.DeepLinkContract.LINK_PREFERENCES;
+import static org.mozilla.gecko.deeplink.DeepLinkContract.LINK_PREFERENCES_ACCESSIBILITY;
+import static org.mozilla.gecko.deeplink.DeepLinkContract.LINK_PREFERENCES_NOTIFICATIONS;
+import static org.mozilla.gecko.deeplink.DeepLinkContract.LINK_PREFERENCES_PRIAVACY;
+import static org.mozilla.gecko.deeplink.DeepLinkContract.LINK_PREFERENCES_SEARCH;
+import static org.mozilla.gecko.deeplink.DeepLinkContract.LINK_SAVE_AS_PDF;
+import static org.mozilla.gecko.deeplink.DeepLinkContract.LINK_SIGN_UP;
+import static org.mozilla.gecko.deeplink.DeepLinkContract.SUMO_DEFAULT_BROWSER;
+
/**
* Activity that receives incoming Intents and dispatches them to the appropriate activities (e.g. browser, custom tabs, web app).
*/
public class LauncherActivity extends Activity {
+
+ private static final String TAG = LauncherActivity.class.getSimpleName();
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeckoAppShell.ensureCrashHandling();
final SafeIntent safeIntent = new SafeIntent(getIntent());
+ // Is this deep link?
+ if (isDeepLink(safeIntent)) {
+ dispatchDeepLink(safeIntent);
+
// Is this web app?
- if (isWebAppIntent(safeIntent)) {
+ } else if (isWebAppIntent(safeIntent)) {
dispatchWebAppIntent();
// If it's not a view intent, it won't be a custom tabs intent either. Just launch!
} else if (!isViewIntentWithURL(safeIntent)) {
dispatchNormalIntent();
// Is this a custom tabs intent, and are custom tabs enabled?
} else if (AppConstants.MOZ_ANDROID_CUSTOM_TABS && isCustomTabsIntent(safeIntent)
@@ -76,16 +99,26 @@ public class LauncherActivity extends Ac
Intent intent = new Intent(getIntent());
intent.setClassName(getApplicationContext(), AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS);
filterFlags(intent);
startActivity(intent);
}
+ private void dispatchUrlIntent(@NonNull String url) {
+ Intent intent = new Intent(getIntent());
+ intent.setData(Uri.parse(url));
+ intent.setClassName(getApplicationContext(), AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS);
+
+ filterFlags(intent);
+
+ startActivity(intent);
+ }
+
private void dispatchCustomTabsIntent() {
Intent intent = new Intent(getIntent());
intent.setClassName(getApplicationContext(), CustomTabsActivity.class.getName());
filterFlags(intent);
startActivity(intent);
}
@@ -122,9 +155,75 @@ public class LauncherActivity extends Ac
private static boolean isWebAppIntent(@NonNull final SafeIntent safeIntent) {
return GeckoApp.ACTION_WEBAPP.equals(safeIntent.getAction());
}
private boolean isCustomTabsEnabled() {
return GeckoSharedPrefs.forApp(this).getBoolean(GeckoPreferences.PREFS_CUSTOM_TABS, false);
}
+
+ private boolean isDeepLink(SafeIntent intent) {
+ if (intent == null || intent.getData() == null || intent.getData().getScheme() == null
+ || intent.getAction() == null) {
+ return false;
+ }
+ boolean schemeMatched = intent.getData().getScheme().equalsIgnoreCase(DEEP_LINK_SCHEME);
+ boolean actionMatched = intent.getAction().equals(Intent.ACTION_VIEW);
+ return schemeMatched && actionMatched;
+ }
+
+ private void dispatchDeepLink(SafeIntent intent) {
+ if (intent == null || intent.getData() == null || intent.getData().getHost() == null) {
+ return;
+ }
+ final String host = intent.getData().getHost();
+
+ switch (host) {
+ case LINK_DEFAULT_BROWSER:
+ GeckoSharedPrefs.forApp(this).edit().putBoolean(GeckoPreferences.PREFS_DEFAULT_BROWSER, true).apply();
+
+ if (AppConstants.Versions.feature24Plus) {
+ // We are special casing the link to set the default browser here: On old Android versions we
+ // link to a SUMO page but on new Android versions we can link to the default app settings where
+ // the user can actually set a default browser (Bug 1312686).
+ final Intent changeDefaultApps = new Intent("android.settings.MANAGE_DEFAULT_APPS_SETTINGS");
+ startActivity(changeDefaultApps);
+ } else {
+ dispatchUrlIntent(SUMO_DEFAULT_BROWSER);
+ }
+ break;
+ case LINK_SAVE_AS_PDF:
+ EventDispatcher.getInstance().dispatch("SaveAs:PDF", null);
+ break;
+ case LINK_BOOKMARK_LIST:
+ String bookmarks = AboutPages.getURLForBuiltinPanelType(HomeConfig.PanelType.BOOKMARKS);
+ dispatchUrlIntent(bookmarks);
+ break;
+ case LINK_HISTORY_LIST:
+ String history = AboutPages.getURLForBuiltinPanelType(HomeConfig.PanelType.COMBINED_HISTORY);
+ dispatchUrlIntent(history);
+ break;
+ case LINK_SIGN_UP:
+ dispatchUrlIntent(AboutPages.ACCOUNTS + "?action=signup");
+ break;
+ case LINK_PREFERENCES:
+ Intent settingsIntent = new Intent(this, GeckoPreferences.class);
+
+ // We want to know when the Settings activity returns, because
+ // we might need to redisplay based on a locale change.
+ startActivityForResult(settingsIntent, ACTIVITY_REQUEST_PREFERENCES);
+ break;
+ case LINK_PREFERENCES_PRIAVACY:
+ case LINK_PREFERENCES_SEARCH:
+ case LINK_PREFERENCES_NOTIFICATIONS:
+ case LINK_PREFERENCES_ACCESSIBILITY:
+ settingsIntent = new Intent(this, GeckoPreferences.class);
+ GeckoPreferences.setResourceToOpen(settingsIntent, host);
+ startActivityForResult(settingsIntent, ACTIVITY_REQUEST_PREFERENCES);
+ break;
+ default:
+ Log.w(TAG, "unrecognized deep links");
+ }
+
+ }
+
}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/deeplink/DeepLinkContract.java
@@ -0,0 +1,26 @@
+/* -*- 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.deeplink;
+
+// This class defines the contract when using deep links
+public class DeepLinkContract {
+
+ // Sumo page for setting Fennec as default browser
+ public static final String SUMO_DEFAULT_BROWSER = "https://support.mozilla.org/kb/make-firefox-default-browser-android?utm_source=inproduct&utm_medium=settings&utm_campaign=mobileandroid";
+ public static final String DEEP_LINK_SCHEME = "firefox";
+
+ public static final String LINK_DEFAULT_BROWSER = "default_browser";
+ public static final String LINK_SAVE_AS_PDF = "save_as_pdf";
+ public static final String LINK_BOOKMARK_LIST = "bookmark_list";
+ public static final String LINK_HISTORY_LIST = "history_list";
+ public static final String LINK_SIGN_UP = "sign_up";
+ public static final String LINK_PREFERENCES = "preferences";
+ public static final String LINK_PREFERENCES_PRIAVACY = "preferences_privacy";
+ public static final String LINK_PREFERENCES_SEARCH = "preferences_search";
+ public static final String LINK_PREFERENCES_NOTIFICATIONS = "preferences_notifications";
+ public static final String LINK_PREFERENCES_ACCESSIBILITY = "preferences_accessibility";
+
+}
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -520,16 +520,17 @@ gbjar.sources += ['java/org/mozilla/geck
'db/SQLiteBridgeContentProvider.java',
'db/SuggestedSites.java',
'db/Table.java',
'db/TabsAccessor.java',
'db/TabsProvider.java',
'db/UrlAnnotations.java',
'db/URLImageDataTable.java',
'db/URLMetadata.java',
+ 'deeplink/DeepLinkContract.java',
'delegates/BookmarkStateChangeDelegate.java',
'delegates/BrowserAppDelegate.java',
'delegates/BrowserAppDelegateWithReference.java',
'delegates/OfflineTabStatusDelegate.java',
'delegates/ScreenshotDelegate.java',
'delegates/TabsTrayVisibilityAwareDelegate.java',
'DevToolsAuthHelper.java',
'distribution/Distribution.java',