Chromium Code Reviews| 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() {} |
| +} |