Chromium Code Reviews| Index: chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java | 
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java | 
| index 0269372a91fe45d29b372fdb1dc5b7bfda8af30a..0ea4ba28f96ba0ca716b75d8a2fe0c5883037a4e 100644 | 
| --- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java | 
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java | 
| @@ -14,6 +14,7 @@ import android.content.Intent; | 
| import android.content.IntentFilter; | 
| import android.content.pm.PackageManager; | 
| import android.content.pm.ResolveInfo; | 
| +import android.content.pm.Signature; | 
| import android.net.Uri; | 
| import android.os.Build; | 
| import android.os.StrictMode; | 
| @@ -49,8 +50,12 @@ import org.chromium.ui.base.WindowAndroid; | 
| import org.chromium.ui.base.WindowAndroid.PermissionCallback; | 
| import org.chromium.webapk.lib.client.WebApkValidator; | 
| +import java.security.MessageDigest; | 
| +import java.security.NoSuchAlgorithmException; | 
| import java.util.ArrayList; | 
| +import java.util.HashSet; | 
| import java.util.List; | 
| +import java.util.Set; | 
| /** | 
| * The main implementation of the {@link ExternalNavigationDelegate}. | 
| @@ -542,4 +547,63 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat | 
| intent.putExtra(IntentHandler.EXTRA_EXTERNAL_NAV_PACKAGES, | 
| getSpecializedHandlersWithFilter(infos, null)); | 
| } | 
| + | 
| + | 
| + @Override | 
| + public Set<String> getPackageSHA256Fingerprints(String pkgName) { | 
| + PackageManager pm = getAvailableContext().getPackageManager(); | 
| + try { | 
| + Signature[] signatures = pm.getPackageInfo(pkgName, | 
| + PackageManager.GET_SIGNATURES).signatures; | 
| 
 
please use gerrit instead
2016/08/01 21:05:24
Move the "catch" to this line. This is the only me
 
 | 
| + HashSet<String> fingerPrint256Set = new HashSet<String>(); | 
| 
 
please use gerrit instead
2016/08/01 21:05:24
Set<String> fingerprints = new HashSet<>();
 
 | 
| + if (signatures.length > 0) { | 
| 
 
please use gerrit instead
2016/08/01 21:05:24
No need to check the length of "signatures" here.
 
 | 
| + for (Signature each : signatures) { | 
| 
 
please use gerrit instead
2016/08/01 21:05:24
Range loops are inefficient. Use integer loops ins
 
 | 
| + String fingerPrint = getSha256(each.toByteArray()); | 
| + if (fingerPrint == null) { | 
| + return null; | 
| + } | 
| + fingerPrint256Set.add(fingerPrint); | 
| + } | 
| + } | 
| + return fingerPrint256Set; | 
| + } catch (PackageManager.NameNotFoundException e) { | 
| + return null; | 
| + } | 
| + } | 
| + | 
| + /** | 
| + * Compute sha256 fingerprint from signature using MessageDigest. | 
| + * | 
| + * @param signature The signature to process. | 
| + * @return The hex string for the fingerprint or null on failure. | 
| + */ | 
| + private String getSha256(byte[] signature) { | 
| + MessageDigest digester; | 
| + try { | 
| + digester = MessageDigest.getInstance("SHA-256"); | 
| + } catch (NoSuchAlgorithmException e) { | 
| + return null; | 
| + } | 
| + digester.update(signature); | 
| + return byteArrayToHexString(digester.digest()); | 
| + } | 
| + | 
| + /** | 
| + * Convert bytes to a hex string. | 
| + * | 
| + * @param bytes The bytes to convert into a string. | 
| + * @return The hex string for the bytes. | 
| + */ | 
| + private String byteArrayToHexString(byte[] bytes) { | 
| + if (bytes.length == 0) { | 
| + return ""; | 
| + } | 
| + StringBuilder data = new StringBuilder(); | 
| + for (byte b : bytes) { | 
| + data.append(Integer.toHexString((b >> 4) & 0x0f)); | 
| + data.append(Integer.toHexString(b & 0x0f)); | 
| + } | 
| + return data.toString().toUpperCase(); | 
| + } | 
| + | 
| } |