/** * Copyright 2016 Jan Petendi <[email protected]> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.petendi.ethereum.android; import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.util.Log; import java.security.MessageDigest; import java.util.List; public class EthereumAndroidFactory { final static String PACKAGENAME = "de.petendi.ethereum.android"; final static String FINGERPRINT = "2F91D2BEC39D37D4409855EFB9D856674D81A070"; final static String SERVICE_ACTION = PACKAGENAME + ".action.REQUEST"; static boolean DEV = false; private static final String TAG = EthereumAndroid.class.getSimpleName(); private final Context context; public EthereumAndroidFactory(Context context) { this.context = context; } public boolean isInstalled() { PackageManager pm = context.getPackageManager(); Intent intent = new Intent(SERVICE_ACTION); intent.setPackage(PACKAGENAME); List<ResolveInfo> services = pm.queryIntentServices(intent, 0); if (services == null) { return false; } else if (services.size() == 1) { if (DEV) { return true; } else { ResolveInfo resolveInfo = services.get(0); try { PackageInfo packageInfo = pm.getPackageInfo(resolveInfo.serviceInfo.packageName, PackageManager.GET_SIGNATURES); final byte[] rawCert = packageInfo.signatures[0].toByteArray(); if (sha1Hash(rawCert).equals(FINGERPRINT)) { return true; } else { Log.w(TAG, "found package is wrongly signed: " + packageInfo); } } catch (PackageManager.NameNotFoundException e) { throw new IllegalStateException(e); } } } else if (services.size() > 0) { throw new IllegalStateException("more than one suitable service found"); } return false; } public boolean showInstallationDialog() { Intent playIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=de.petendi.ethereum.android")); final PackageManager pm = context.getPackageManager(); if (pm.resolveActivity(playIntent, 0) != null) { context.startActivity(playIntent); return true; } else { return false; } } public EthereumAndroid create() throws EthereumNotInstalledException{ if(isInstalled()) { return new EthereumAndroid(context); } else { throw new EthereumNotInstalledException(); } } public EthereumAndroid create(EthereumAndroidCallback callback) throws EthereumNotInstalledException{ if(isInstalled()) { return new EthereumAndroid(context,callback); } else { throw new EthereumNotInstalledException(); } } private final static String sha1Hash(byte[] bytes) { try { MessageDigest digest = MessageDigest.getInstance("SHA-1"); digest.update(bytes, 0, bytes.length); bytes = digest.digest(); return Utils.bytesToHex(bytes); } catch (Exception e) { throw new IllegalStateException(e); } } }