예제 #1
1
 @Override
 public int compare(Intent i1, Intent i2) {
   if (i1 == null && i2 == null) return 0;
   if (i1 == null && i2 != null) return -1;
   if (i1 != null && i2 == null) return 1;
   if (i1.equals(i2)) return 0;
   String action1 = i1.getAction();
   String action2 = i2.getAction();
   if (action1 == null && action2 != null) return -1;
   if (action1 != null && action2 == null) return 1;
   if (action1 != null && action2 != null) {
     if (!action1.equals(action2)) {
       return action1.compareTo(action2);
     }
   }
   Uri data1 = i1.getData();
   Uri data2 = i2.getData();
   if (data1 == null && data2 != null) return -1;
   if (data1 != null && data2 == null) return 1;
   if (data1 != null && data2 != null) {
     if (!data1.equals(data2)) {
       return data1.compareTo(data2);
     }
   }
   ComponentName component1 = i1.getComponent();
   ComponentName component2 = i2.getComponent();
   if (component1 == null && component2 != null) return -1;
   if (component1 != null && component2 == null) return 1;
   if (component1 != null && component2 != null) {
     if (!component1.equals(component2)) {
       return component1.compareTo(component2);
     }
   }
   String package1 = i1.getPackage();
   String package2 = i2.getPackage();
   if (package1 == null && package2 != null) return -1;
   if (package1 != null && package2 == null) return 1;
   if (package1 != null && package2 != null) {
     if (!package1.equals(package2)) {
       return package1.compareTo(package2);
     }
   }
   Set<String> categories1 = i1.getCategories();
   Set<String> categories2 = i2.getCategories();
   if (categories1 == null) return categories2 == null ? 0 : -1;
   if (categories2 == null) return 1;
   if (categories1.size() > categories2.size()) return 1;
   if (categories1.size() < categories2.size()) return -1;
   String[] array1 = categories1.toArray(new String[0]);
   String[] array2 = categories2.toArray(new String[0]);
   Arrays.sort(array1);
   Arrays.sort(array2);
   for (int i = 0; i < array1.length; ++i) {
     int val = array1[i].compareTo(array2[i]);
     if (val != 0) return val;
   }
   return 0;
 }
예제 #2
1
  @Test
  public void shouldFillIn() throws Exception {
    Intent intentA = new Intent();
    Intent intentB = new Intent();

    intentB.setAction("foo");
    Uri uri = Uri.parse("http://www.foo.com");
    intentB.setDataAndType(uri, "text/html");
    String category = "category";
    intentB.addCategory(category);
    intentB.setPackage("com.foobar.app");
    ComponentName cn = new ComponentName("com.foobar.app", "fragmentActivity");
    intentB.setComponent(cn);
    intentB.putExtra("FOO", 23);

    int flags =
        Intent.FILL_IN_ACTION
            | Intent.FILL_IN_DATA
            | Intent.FILL_IN_CATEGORIES
            | Intent.FILL_IN_PACKAGE
            | Intent.FILL_IN_COMPONENT;

    int result = intentA.fillIn(intentB, flags);
    assertEquals("foo", intentA.getAction());
    assertSame(uri, intentA.getData());
    assertEquals("text/html", intentA.getType());
    assertTrue(intentA.getCategories().contains(category));
    assertEquals("com.foobar.app", intentA.getPackage());
    assertSame(cn, intentA.getComponent());
    assertEquals(23, intentA.getIntExtra("FOO", -1));
    assertEquals(result, flags);
  }
예제 #3
1
 @Override
 public int compare(Intent i1, Intent i2) {
   if (i1 == null && i2 == null) return 0;
   if (i1 == null && i2 != null) return -1;
   if (i1 != null && i2 == null) return 1;
   if (i1.equals(i2)) return 0;
   if (i1.getAction() == null && i2.getAction() != null) return -1;
   if (i1.getAction() != null && i2.getAction() == null) return 1;
   if (i1.getAction() != null && i2.getAction() != null) {
     if (!i1.getAction().equals(i2.getAction())) {
       return i1.getAction().compareTo(i2.getAction());
     }
   }
   if (i1.getData() == null && i2.getData() != null) return -1;
   if (i1.getData() != null && i2.getData() == null) return 1;
   if (i1.getData() != null && i2.getData() != null) {
     if (!i1.getData().equals(i2.getData())) {
       return i1.getData().compareTo(i2.getData());
     }
   }
   if (i1.getComponent() == null && i2.getComponent() != null) return -1;
   if (i1.getComponent() != null && i2.getComponent() == null) return 1;
   if (i1.getComponent() != null && i2.getComponent() != null) {
     if (!i1.getComponent().equals(i2.getComponent())) {
       return i1.getComponent().compareTo(i2.getComponent());
     }
   }
   if (i1.getPackage() == null && i2.getPackage() != null) return -1;
   if (i1.getPackage() != null && i2.getPackage() == null) return 1;
   if (i1.getPackage() != null && i2.getPackage() != null) {
     if (!i1.getPackage().equals(i2.getPackage())) {
       return i1.getPackage().compareTo(i2.getPackage());
     }
   }
   Set<String> categories1 = i1.getCategories();
   Set<String> categories2 = i2.getCategories();
   if (categories1 == null) return categories2 == null ? 0 : -1;
   if (categories2 == null) return 1;
   if (categories1.size() > categories2.size()) return 1;
   if (categories1.size() < categories2.size()) return -1;
   String[] array1 = categories1.toArray(new String[0]);
   String[] array2 = categories2.toArray(new String[0]);
   Arrays.sort(array1);
   Arrays.sort(array2);
   for (int i = 0; i < array1.length; ++i) {
     int val = array1[i].compareTo(array2[i]);
     if (val != 0) return val;
   }
   return 0;
 }
예제 #4
1
  boolean startActivityForUrl(Tab tab, String url) {
    Intent intent;
    // perform generic parsing of the URI to turn it into an Intent.
    try {
      intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
    } catch (URISyntaxException ex) {
      Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
      return false;
    }

    // check whether the intent can be resolved. If not, we will see
    // whether we can download it from the Market.
    if (mActivity.getPackageManager().resolveActivity(intent, 0) == null) {
      String packagename = intent.getPackage();
      if (packagename != null) {
        intent =
            new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:" + packagename));
        intent.addCategory(Intent.CATEGORY_BROWSABLE);
        mActivity.startActivity(intent);
        // before leaving BrowserActivity, close the empty child tab.
        // If a new tab is created through JavaScript open to load this
        // url, we would like to close it as we will load this url in a
        // different Activity.
        mController.closeEmptyTab();
        return true;
      } else {
        return false;
      }
    }

    // sanitize the Intent, ensuring web pages can not bypass browser
    // security (only access to BROWSABLE activities).
    intent.addCategory(Intent.CATEGORY_BROWSABLE);
    intent.setComponent(null);
    // Re-use the existing tab if the intent comes back to us
    if (tab != null) {
      if (tab.getAppId() == null) {
        tab.setAppId(mActivity.getPackageName() + "-" + tab.getId());
      }
      intent.putExtra(com.stockbrowser.compats.Browser.EXTRA_APPLICATION_ID, tab.getAppId());
    }
    // Make sure webkit can handle it internally before checking for specialized
    // handlers. If webkit can't handle it internally, we need to call
    // startActivityIfNeeded
    Matcher m = UrlUtils.ACCEPTED_URI_SCHEMA.matcher(url);
    if (m.matches() && !isSpecializedHandlerAvailable(intent)) {
      return false;
    }
    try {
      intent.putExtra(BrowserActivity.EXTRA_DISABLE_URL_OVERRIDE, true);
      if (mActivity.startActivityIfNeeded(intent, -1)) {
        // before leaving BrowserActivity, close the empty child tab.
        // If a new tab is created through JavaScript open to load this
        // url, we would like to close it as we will load this url in a
        // different Activity.
        mController.closeEmptyTab();
        return true;
      }
    } catch (ActivityNotFoundException ex) {
      // ignore the error. If no application can handle the URL,
      // eg about:blank, assume the browser can handle it.
    }

    return false;
  }
 public String getTargetPackage() {
   String packageName = launchIntent.getPackage();
   if (packageName == null) {
     packageName =
         launchIntent.getComponent() == null
             ? null
             : launchIntent.getComponent().getPackageName();
   }
   return packageName;
 }
예제 #6
0
 public final boolean a(Intent intent) {
   boolean flag1 = true;
   long l = e.b();
   if (l - f > 5000L) {
     c.clear();
   }
   f = l;
   if (intent == null) {
     return false;
   }
   Object obj = intent.getData();
   boolean flag;
   if (obj != null
       && "android.intent.action.VIEW".equals(intent.getAction())
       && com.shazam.b.e.a.a(intent.getPackage())
       && b.contains(((Uri) (obj)).getScheme())) {
     flag = true;
   } else {
     flag = false;
   }
   if (flag) {
     return true;
   }
   obj = intent.getPackage();
   if (intent.getPackage() == null
       && "com.amazon.mp3.action.EXTERNAL_EVENT".equals(intent.getAction())
       && "com.amazon.mp3.type.SHOW_TRACK_DETAIL"
           .equals(intent.getStringExtra("com.amazon.mp3.extra.EXTERNAL_EVENT_TYPE"))) {
     flag = flag1;
   } else {
     flag = false;
   }
   if (flag) {
     obj = a;
   }
   if (obj == null || !c.containsKey(obj)) {
     boolean flag2 = d.a(intent);
     c.put(obj, Boolean.valueOf(flag2));
     return flag2;
   } else {
     return ((Boolean) c.get(obj)).booleanValue();
   }
 }
예제 #7
0
    public void onReceive(Context context, Intent intent) {

      Log.v(
          "fengxuanyang",
          "package~~~~~~~~~~"
              + intent.getPackage()
              + "intent.getAction()~~~~"
              + intent.getAction());
      String s = intent.getAction();
      getBatteryInfo(intent, s);
    }
예제 #8
0
  @Override
  protected void onHandleIntent(Intent intent) {
    context = this.getApplicationContext();
    cdmDeviceAdmin = new ComponentName(this, ServiceDeviceAdminReceiver.class);
    devicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
    mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
    AGENT_PACKAGE_NAME = context.getPackageName();
    AUTHORIZED_PINNING_APPS = new String[] {AGENT_PACKAGE_NAME, Constants.AGENT_APP_PACKAGE_NAME};
    if (!devicePolicyManager.isAdminActive(cdmDeviceAdmin)) {
      startAdmin();
    } else {
      /*This function handles the "Execute Command on Device" Operation.
            All requests are handled on a single worker thread. They may take as long as necessary
      (and will not block the application's main thread),
      but only one request will be processed at a time.*/
      Log.d(TAG, "Entered onHandleIntent of the Command Runner Service.");
      Bundle extras = intent.getExtras();
      if (extras != null) {
        operationCode = extras.getString("code");

        if (extras.containsKey("command")) {
          command = extras.getString("command");
          if (command != null && (command.equals("true") || command.equals("false"))) {
            if (command.equals("true")) {
              restrictionCode = true;
            }
          }
        }

        if (extras.containsKey("appUri")) {
          appUri = extras.getString("appUri");
        }

        if (extras.containsKey("operationId")) {
          operationId = extras.getInt("operationId");
        }
      }

      Log.d(TAG, "EMM agent has sent a command.");
      if ((operationCode != null)) {
        Log.d(TAG, "The operation code is: " + operationCode);

        Log.i(TAG, "Will now executing the command ..." + operationCode);
        if (Constants.AGENT_APP_PACKAGE_NAME.equals(intent.getPackage())) {
          doTask(operationCode);
        } else if (Constants.Operation.GET_FIRMWARE_UPGRADE_PACKAGE_STATUS.equals(operationCode)) {
          doTask(operationCode);
        }
      }
    }
    context.registerReceiver(
        new BatteryChargingStateReceiver(), new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
  }
 private void fillIntent(@Nullable Intent intent, @NonNull TextView textView) {
   if (intent == null) {
     textView.setText(Printer.EMPTY);
     return;
   }
   Truss truss = new Truss();
   Printer.append(truss, "action", intent.getAction());
   Printer.append(truss, "categories", intent.getCategories());
   Printer.append(truss, "type", intent.getType());
   Printer.append(truss, "flags", Flags.decode(intent.getFlags()));
   Printer.append(truss, "package", intent.getPackage());
   Printer.append(truss, "component", intent.getComponent());
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
     Printer.append(truss, "referrer", getReferrer());
   }
   textView.setText(truss.build());
 }
예제 #10
0
  /**
   * Fires an Intent to open a downloaded item.
   *
   * @param context Context to use.
   * @param intent Intent that can be fired.
   * @return Whether an Activity was successfully started for the Intent.
   */
  static boolean fireOpenIntentForDownload(Context context, Intent intent) {
    try {
      if (TextUtils.equals(intent.getPackage(), context.getPackageName())) {
        IntentHandler.startActivityForTrustedIntent(intent, context);
      } else {
        context.startActivity(intent);
      }
      return true;
    } catch (ActivityNotFoundException ex) {
      Log.d(
          TAG,
          "Activity not found for " + intent.getType() + " over " + intent.getData().getScheme(),
          ex);
    } catch (SecurityException ex) {
      Log.d(TAG, "cannot open intent: " + intent, ex);
    }

    return false;
  }
예제 #11
0
 private static void dumpIntent(String prefix, Intent intent) {
   Log.v(prefix + "Flags:" + dumpFlags(intent.getFlags()));
   Log.v(prefix + "Action:" + intent.getAction());
   Log.v(prefix + "Categories:");
   if (intent.getCategories() != null) {
     for (String str : intent.getCategories()) Log.v(prefix + "  " + str);
   }
   Log.v(prefix + "Type:" + intent.getType());
   Log.v(prefix + "Data:" + intent.getDataString());
   Log.v(prefix + "Pkg:" + intent.getPackage());
   ComponentName comp = intent.getComponent();
   Log.v(prefix + "Comp:" + (comp == null ? null : intent.getComponent().flattenToString()));
   Bundle extra = intent.getExtras();
   if (extra != null) {
     for (String key : extra.keySet()) {
       dumpKeyValue(prefix + "  ", key, extra.get(key));
     }
   }
 }
예제 #12
0
  private Map<String, Object> parseIntent(Intent intent) {
    Map<String, Object> params = new HashMap<String, Object>();

    if (intent != null) {
      String action = intent.getAction();
      if (action != null) {
        params.put(HK_ACTION, action);
      }

      Set<String> categories = intent.getCategories();
      if (categories != null) {
        params.put(HK_CATEGORIES, categories);
      }

      String appName = intent.getPackage();
      if (appName != null) {
        params.put(HK_APP_NAME, appName);
      }

      String uri = intent.getDataString();
      if (uri != null) {
        uri = Uri.decode(uri);
        params.put(HK_URI, uri);
      }

      String mime = intent.getType();
      if (mime != null) {
        params.put(HK_MIME_TYPE, mime);
      }

      Bundle extras = intent.getExtras();
      if (extras != null) {
        params.put(HK_DATA, extras);
      }
    }

    return params;
  }
  public static ArrayList<String> matchPlugin(Intent intent, int type) {
    ArrayList<String> result = null;

    String packageName = intent.getPackage();
    if (packageName == null && intent.getComponent() != null) {
      packageName = intent.getComponent().getPackageName();
    }
    if (packageName != null
        && !packageName.equals(PluginLoader.getApplicatoin().getPackageName())) {
      PluginDescriptor dp = getPluginDescriptorByPluginId(packageName);
      if (dp != null) {
        List<String> list = dp.matchPlugin(intent, type);
        if (list != null && list.size() > 0) {
          if (result == null) {
            result = new ArrayList<>();
          }
          result.addAll(list);
        }
      }
    } else {
      Iterator<PluginDescriptor> itr = getPlugins().iterator();
      while (itr.hasNext()) {
        List<String> list = itr.next().matchPlugin(intent, type);
        if (list != null && list.size() > 0) {
          if (result == null) {
            result = new ArrayList<>();
          }
          result.addAll(list);
        }
        if (result != null && type != PluginDescriptor.BROADCAST) {
          break;
        }
      }
    }
    return result;
  }
  @Override
  public final void onHandleIntent(Intent intent) {

    System.out.println("Received intent " + intent);

    try {
      Context context = getApplicationContext();
      String action = intent.getAction();
      if (action.equals(INTENT_FROM_GCM_REGISTRATION_CALLBACK)) {
        GCMRegistrar.setRetryBroadcastReceiver(context);
        handleRegistration(context, intent);
      } else if (action.equals(INTENT_FROM_GCM_MESSAGE)) {
        // checks for special messages
        String messageType = intent.getStringExtra(EXTRA_SPECIAL_MESSAGE);
        if (messageType != null) {
          if (messageType.equals(VALUE_DELETED_MESSAGES)) {
            String sTotal = intent.getStringExtra(EXTRA_TOTAL_DELETED);
            if (sTotal != null) {
              try {
                int total = Integer.parseInt(sTotal);
                mLogger.log(
                    Log.VERBOSE, "Received notification for %d deleted" + "messages", total);
                onDeletedMessages(context, total);
              } catch (NumberFormatException e) {
                mLogger.log(
                    Log.ERROR, "GCM returned invalid " + "number of deleted messages (%d)", sTotal);
              }
            }
          } else {
            // application is not using the latest GCM library
            mLogger.log(Log.ERROR, "Received unknown special message: %s", messageType);
          }
        } else {
          onMessage(context, intent);
        }
      } else if (action.equals(INTENT_FROM_GCM_LIBRARY_RETRY)) {
        String packageOnIntent = intent.getPackage();
        if (packageOnIntent == null
            || !packageOnIntent.equals(getApplicationContext().getPackageName())) {
          mLogger.log(
              Log.ERROR, "Ignoring retry intent from another package (%s)", packageOnIntent);
          return;
        }
        // retry last call
        if (GCMRegistrar.isRegistered(context)) {
          GCMRegistrar.internalUnregister(context);
        } else {
          String[] senderIds = getSenderIds(context);
          GCMRegistrar.internalRegister(context, senderIds);
        }
      }
    } finally {
      // Release the power lock, so phone can get back to sleep.
      // The lock is reference-counted by default, so multiple
      // messages are ok.

      // If onMessage() needs to spawn a thread or do something else,
      // it should use its own lock.
      synchronized (LOCK) {
        // sanity check for null as this is a public method
        if (sWakeLock != null) {
          sWakeLock.release();
        } else {
          // should never happen during normal workflow
          mLogger.log(Log.ERROR, "Wakelock reference is null");
        }
      }
    }
  }
예제 #15
0
 @Override
 public IBinder onBind(Intent intent) {
   Log.d("BIND OK : " + intent.getPackage());
   return mBinder;
 }
  private void buildResolveList(
      Intent intent,
      FastImmutableArraySet<String> categories,
      boolean debug,
      boolean defaultOnly,
      String resolvedType,
      String scheme,
      F[] src,
      List<R> dest,
      int userId) {
    final String action = intent.getAction();
    final Uri data = intent.getData();
    final String packageName = intent.getPackage();

    final boolean excludingStopped = intent.isExcludingStopped();

    final Printer logPrinter;
    final PrintWriter logPrintWriter;
    if (debug) {
      logPrinter = new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM);
      logPrintWriter = new FastPrintWriter(logPrinter);
    } else {
      logPrinter = null;
      logPrintWriter = null;
    }

    final int N = src != null ? src.length : 0;
    boolean hasNonDefaults = false;
    int i;
    F filter;
    for (i = 0; i < N && (filter = src[i]) != null; i++) {
      int match;
      if (debug) Slog.v(TAG, "Matching against filter " + filter);

      if (excludingStopped && isFilterStopped(filter, userId)) {
        if (debug) {
          Slog.v(TAG, "  Filter's target is stopped; skipping");
        }
        continue;
      }

      // Is delivery being limited to filters owned by a particular package?
      if (packageName != null && !isPackageForFilter(packageName, filter)) {
        if (debug) {
          Slog.v(TAG, "  Filter is not from package " + packageName + "; skipping");
        }
        continue;
      }

      // Are we verified ?
      if (filter.getAutoVerify()) {
        if (localVerificationLOGV || debug) {
          Slog.v(TAG, "  Filter verified: " + isFilterVerified(filter));
          int authorities = filter.countDataAuthorities();
          for (int z = 0; z < authorities; z++) {
            Slog.v(TAG, "   " + filter.getDataAuthority(z).getHost());
          }
        }
      }

      // Do we already have this one?
      if (!allowFilterResult(filter, dest)) {
        if (debug) {
          Slog.v(TAG, "  Filter's target already added");
        }
        continue;
      }

      match = filter.match(action, resolvedType, scheme, data, categories, TAG);
      if (match >= 0) {
        if (debug)
          Slog.v(
              TAG,
              "  Filter matched!  match=0x"
                  + Integer.toHexString(match)
                  + " hasDefault="
                  + filter.hasCategory(Intent.CATEGORY_DEFAULT));
        if (!defaultOnly || filter.hasCategory(Intent.CATEGORY_DEFAULT)) {
          final R oneResult = newResult(filter, match, userId);
          if (oneResult != null) {
            dest.add(oneResult);
            if (debug) {
              dumpFilter(logPrintWriter, "    ", filter);
              logPrintWriter.flush();
              filter.dump(logPrinter, "    ");
            }
          }
        } else {
          hasNonDefaults = true;
        }
      } else {
        if (debug) {
          String reason;
          switch (match) {
            case IntentFilter.NO_MATCH_ACTION:
              reason = "action";
              break;
            case IntentFilter.NO_MATCH_CATEGORY:
              reason = "category";
              break;
            case IntentFilter.NO_MATCH_DATA:
              reason = "data";
              break;
            case IntentFilter.NO_MATCH_TYPE:
              reason = "type";
              break;
            default:
              reason = "unknown reason";
              break;
          }
          Slog.v(TAG, "  Filter did not match: " + reason);
        }
      }
    }

    if (debug && hasNonDefaults) {
      if (dest.size() == 0) {
        Slog.v(TAG, "resolveIntent failed: found match, but none with CATEGORY_DEFAULT");
      } else if (dest.size() > 1) {
        Slog.v(TAG, "resolveIntent: multiple matches, only some with CATEGORY_DEFAULT");
      }
    }
  }
예제 #17
0
  /**
   * Opens a URI without any valid handlers on device. In the best case, a package is specified and
   * we can bring the user directly to the application page in an app market. If a package is not
   * specified and there is a fallback url in the intent extras, we open that url. If neither is
   * present, we alert the user that we were unable to open the link.
   *
   * @param msg A message with the uri with no handlers as the value for the "uri" key
   * @param callback A callback that will be called with success & no params if Java loads a page,
   *     or with error and the uri to load if Java does not load a page
   */
  private void openNoHandler(final NativeJSObject msg, final EventCallback callback) {
    final String uri = msg.getString("uri");

    if (TextUtils.isEmpty(uri)) {
      Log.w(LOGTAG, "Received empty URL - loading about:neterror");
      callback.sendError(getUnknownProtocolErrorPageUri(""));
      return;
    }

    final Intent intent;
    try {
      // TODO (bug 1173626): This will not handle android-app uris on non 5.1 devices.
      intent = Intent.parseUri(uri, 0);
    } catch (final URISyntaxException e) {
      String errorUri;
      try {
        errorUri = getUnknownProtocolErrorPageUri(URLEncoder.encode(uri, "UTF-8"));
      } catch (final UnsupportedEncodingException encodingE) {
        errorUri = getUnknownProtocolErrorPageUri("");
      }

      // Don't log the exception to prevent leaking URIs.
      Log.w(LOGTAG, "Unable to parse Intent URI - loading about:neterror");
      callback.sendError(errorUri);
      return;
    }

    // For this flow, we follow Chrome's lead:
    //   https://developer.chrome.com/multidevice/android/intents
    if (intent.hasExtra(EXTRA_BROWSER_FALLBACK_URL)) {
      final String fallbackUrl = intent.getStringExtra(EXTRA_BROWSER_FALLBACK_URL);
      String urlToLoad;
      try {
        final String anyCaseScheme = new URI(fallbackUrl).getScheme();
        final String scheme = (anyCaseScheme == null) ? null : anyCaseScheme.toLowerCase(Locale.US);
        if ("http".equals(scheme) || "https".equals(scheme)) {
          urlToLoad = fallbackUrl;
        } else {
          Log.w(LOGTAG, "Fallback URI uses unsupported scheme: " + scheme);
          urlToLoad = GENERIC_URI_PREFIX + fallbackUrl;
        }
      } catch (final URISyntaxException e) {
        // Do not include Exception to avoid leaking uris.
        Log.w(LOGTAG, "Exception parsing fallback URI");
        urlToLoad = MALFORMED_URI_PREFIX + fallbackUrl;
      }
      callback.sendError(urlToLoad);

    } else if (intent.getPackage() != null) {
      // Note on alternative flows: we could get the intent package from a component, however, for
      // security reasons, components are ignored when opening URIs (bug 1168998) so we should
      // ignore it here too.
      //
      // Our old flow used to prompt the user to search for their app in the market by scheme and
      // while this could help the user find a new app, there is not always a correlation in
      // scheme to application name and we could end up steering the user wrong (potentially to
      // malicious software). Better to leave that one alone.
      final String marketUri = MARKET_INTENT_URI_PACKAGE_PREFIX + intent.getPackage();
      final Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(marketUri));
      marketIntent.addCategory(Intent.CATEGORY_BROWSABLE);
      marketIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

      // (Bug 1192436) We don't know if marketIntent matches any Activities (e.g. non-Play
      // Store devices). If it doesn't, clicking the link will cause no action to occur.
      activity.startActivity(marketIntent);
      callback.sendSuccess(null);

    } else {
      // Don't log the URI to prevent leaking it.
      Log.w(LOGTAG, "Unable to open URI, default case - loading about:neterror");
      callback.sendError(getUnknownProtocolErrorPageUri(intent.getData().toString()));
    }
  }