Index: chrome/android/java/src/org/chromium/chrome/browser/payments/ManifestParser.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ManifestParser.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ManifestParser.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..bc7a928dbef86a49166543804b9b15a0fd2bf200 |
--- /dev/null |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ManifestParser.java |
@@ -0,0 +1,150 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.chrome.browser.payments; |
+ |
+import android.text.TextUtils; |
+ |
+import org.json.JSONArray; |
+import org.json.JSONException; |
+import org.json.JSONObject; |
+ |
+import java.util.ArrayList; |
+import java.util.HashSet; |
+import java.util.List; |
+import java.util.Set; |
+ |
+/** |
+ * Parses the payment method manifest for information specific to native Android payment apps. |
+ * Example of a valid manifest that has no restrictions on payment apps: |
+ * |
+ * { |
+ * "android": [ |
+ * { |
+ * "package": "*" |
+ * } |
+ * ] |
+ * } |
+ * |
+ * Example of a valid manifest that restricts to a single app that can handle this payment method: |
+ * |
+ * { |
+ * "android": [ |
+ * { |
+ * "package": "com.bobpay", |
+ * "version": 1, |
+ * "sha256_cert_fingerprints": [ |
+ * "146DE983C5730650146DE983C5730650146DE983C5730650146DE983C5730650", |
+ * "F0FD6C5B410F25CBF0FD6C5B410F25CBF0FD6C5B410F25CBF0FD6C5B410F25CB"] |
+ * } |
+ * ] |
+ * } |
+ */ |
+public class ManifestParser { |
+ /** A parsed manifest section. */ |
+ public static class Manifest { |
+ /** |
+ * The name of the package of the native Android payment app, e.g., "*" or "com.bobpay". |
+ * Never null. |
+ */ |
+ public String packageName; |
+ |
+ /** |
+ * The minimum version code of the native Android payment app, e.g., 123. By default, this |
+ * is 0. |
+ */ |
+ public long version; |
+ |
+ /** |
+ * The unordered collection of SHA256 certificate fingerprints, e.g., |
+ * ["308201dd30820146020101300d06092a864886f70d01010505003037311630140"]. Null if {@see |
+ * packageName} is "*". Otherwise, never null and never empty. Every element is a non-empty |
+ * string. |
+ */ |
+ public Set<String> sha256CertFingerprints; |
+ } |
+ |
+ /** Interface for the callback to invoke when parsing is complete. */ |
+ public interface ManifestParseCallback { |
+ /** |
+ * Called on successful parsing of a payment method manifest. |
+ * |
+ * @param manifests Sections of the successfully parsed manifest. |
+ */ |
+ void onManifestParseSuccess(List<Manifest> manifests); |
+ |
+ /** Called on failed parsing of a payment method manifest. */ |
+ void onManifestParseFailure(); |
+ } |
+ |
+ /** |
+ * Parses the manifest. |
+ * |
+ * @param content The data to parse. |
+ * @param callack The callback to invoke when done. |
+ */ |
+ public static void parse(String content, ManifestParseCallback callback) { |
+ JSONObject json = null; |
+ try { |
+ json = new JSONObject(content); |
+ } catch (JSONException e) { |
+ callback.onManifestParseFailure(); |
+ return; |
+ } |
+ |
+ JSONArray androids = json.optJSONArray("android"); |
+ if (androids == null) { |
+ callback.onManifestParseFailure(); |
+ return; |
+ } |
+ |
+ List<Manifest> result = new ArrayList<>(); |
+ for (int i = 0; i < androids.length(); i++) { |
+ JSONObject androidSection = androids.optJSONObject(i); |
+ if (androidSection == null) { |
+ callback.onManifestParseFailure(); |
+ return; |
+ } |
+ |
+ Manifest manifest = new Manifest(); |
+ |
+ manifest.packageName = androidSection.optString("package"); |
+ if (TextUtils.isEmpty(manifest.packageName)) { |
+ callback.onManifestParseFailure(); |
+ return; |
+ } |
+ |
+ // All apps allowed. |
+ if ("*".equals(manifest.packageName)) break; |
gogerald1
2017/01/23 17:18:35
Do you need result.add(manifest) here, otherwise r
please use gerrit instead
2017/02/23 19:57:50
Done. Great catch!
|
+ |
+ manifest.version = androidSection.optLong("version"); |
+ |
+ JSONArray fingerprints = androidSection.optJSONArray("sha256_cert_fingerprints"); |
+ if (fingerprints == null || fingerprints.length() == 0) { |
+ callback.onManifestParseFailure(); |
+ return; |
+ } |
+ |
+ manifest.sha256CertFingerprints = new HashSet<>(); |
+ for (int j = 0; j < fingerprints.length(); j++) { |
+ String fingerprint = fingerprints.optString(j); |
+ if (TextUtils.isEmpty(fingerprint)) { |
+ callback.onManifestParseFailure(); |
+ return; |
+ } |
+ manifest.sha256CertFingerprints.add(fingerprint); |
+ } |
+ |
+ result.add(manifest); |
+ } |
+ |
+ if (result.isEmpty()) { |
+ callback.onManifestParseFailure(); |
+ } else { |
+ callback.onManifestParseSuccess(result); |
+ } |
+ } |
+ |
+ private ManifestParser() {} |
+} |