Bug 1253399 - Avoid crashes by checking for QR scanner app. r=sebastian
MozReview-Commit-ID: 6bFrYyt4pzX
--- a/mobile/android/base/java/org/mozilla/gecko/DevToolsAuthHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/DevToolsAuthHelper.java
@@ -3,32 +3,45 @@
* 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.content.pm.PackageManager;
+import android.util.Log;
import org.mozilla.gecko.util.ActivityResultHandler;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.InputOptionsUtils;
/**
* Supports the DevTools WiFi debugging authentication flow by invoking a QR decoder.
*/
public class DevToolsAuthHelper {
+ private static final String LOGTAG = "GeckoDevToolsAuthHelper";
+
public static void scan(Context context, final EventCallback callback) {
final Intent intent = InputOptionsUtils.createQRCodeReaderIntent();
intent.putExtra("PROMPT_MESSAGE", context.getString(R.string.devtools_auth_scan_header));
- Activity activity = GeckoAppShell.getGeckoInterface().getActivity();
- ActivityHandlerHelper.startIntentForActivity(activity, intent, new ActivityResultHandler() {
+ // Check ahead of time if an activity exists for the intent. This
+ // avoids a case where we get both an ActivityNotFoundException *and*
+ // an activity result when the activity is missing.
+ PackageManager pm = context.getPackageManager();
+ if (pm.resolveActivity(intent, 0) == null) {
+ Log.w(LOGTAG, "PackageManager can't resolve the activity.");
+ callback.sendError("PackageManager can't resolve the activity.");
+ return;
+ }
+
+ ActivityHandlerHelper.startIntent(intent, new ActivityResultHandler() {
@Override
public void onActivityResult(int resultCode, Intent intent) {
if (resultCode == Activity.RESULT_OK) {
String text = intent.getStringExtra("SCAN_RESULT");
callback.sendSuccess(text);
} else {
callback.sendError(resultCode);
}
--- a/mobile/android/chrome/content/RemoteDebugger.js
+++ b/mobile/android/chrome/content/RemoteDebugger.js
@@ -150,16 +150,29 @@ var RemoteDebugger = {
if (this._receivingOOB) {
return this._receivingOOB;
}
this._receivingOOB = Messaging.sendRequestForResult({
type: "DevToolsAuth:Scan"
}).then(data => {
return JSON.parse(data);
+ }, () => {
+ let title = Strings.browser.GetStringFromName("remoteQRScanFailedPromptTitle");
+ let msg = Strings.browser.GetStringFromName("remoteQRScanFailedPromptMessage");
+ let ok = Strings.browser.GetStringFromName("remoteQRScanFailedPromptOK");
+ let prompt = new Prompt({
+ window: null,
+ hint: "remotedebug",
+ title: title,
+ message: msg,
+ buttons: [ ok ],
+ priority: 1
+ });
+ prompt.show();
});
this._receivingOOB.then(() => this._receivingOOB = null);
return this._receivingOOB;
},
initServer: function() {
--- a/mobile/android/locales/en-US/chrome/browser.properties
+++ b/mobile/android/locales/en-US/chrome/browser.properties
@@ -353,16 +353,28 @@ remoteIncomingPromptAllow=Allow
# connection will be allowed assuming the scan succeeds.
remoteIncomingPromptScan=Scan
# LOCALIZATION NOTE (remoteIncomingPromptScanAndRemember): This button will
# start a QR code scanner to authenticate an incoming remote debugger
# connection. The connection will be allowed assuming the scan succeeds, and
# the other endpoint's certificate will be saved to skip future scans for this
# client.
remoteIncomingPromptScanAndRemember=Scan and Remember
+# LOCALIZATION NOTE (remoteQRScanFailedPromptTitle): The title displayed in a
+# dialog when we are unable to complete the QR code scan for an incoming remote
+# debugging connection.
+remoteQRScanFailedPromptTitle=QR Scan Failed
+# LOCALIZATION NOTE (remoteQRScanFailedPromptMessage): The message displayed in
+# a dialog when we are unable to complete the QR code scan for an incoming
+# remote debugging connection.
+remoteQRScanFailedPromptMessage=Unable to scan QR code for remote debugging. Verify that the Barcode Scanner app is installed and retry connecting.
+# LOCALIZATION NOTE (remoteQRScanFailedPromptOK): This button dismisses the
+# dialog that appears when we are unable to complete the QR code scan for an
+# incoming remote debugging connection.
+remoteQRScanFailedPromptOK=OK
# LOCALIZATION NOTE (remoteNotificationTitle): %S is the name of the app.
remoteNotificationTitle=%S debugging enabled
# LOCALIZATION NOTE (remoteNotificationGenericName): a generic name to use
# if the name of the app is not available.
remoteNotificationGenericName=App
# LOCALIZATION NOTE (remoteNotificationMessage): %S is the port on which
# the remote debugger server is listening.