| // Copyright 2015 The Vanadium 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 io.v.android.v23.services.blessing; |
| |
| import android.app.Activity; |
| import android.content.ComponentName; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.pm.PackageManager; |
| |
| import java.security.interfaces.ECPublicKey; |
| |
| import io.v.android.v23.V; |
| import io.v.android.impl.google.services.blessing.BlessingActivity; |
| import io.v.v23.context.VContext; |
| |
| /** |
| * Provides client methods for talking to the android |
| * {@link io.v.android.impl.google.services.blessing.BlessingActivity BlessingService}. |
| */ |
| public class BlessingService { |
| public static final String EXTRA_ERROR = "ERROR"; |
| public static final String EXTRA_REPLY = "REPLY"; |
| public static final String EXTRA_PUBLIC_KEY = "PUBLIC_KEY"; |
| public static final String EXTRA_GOOGLE_ACCOUNT = "GOOGLE_ACCOUNT"; |
| |
| private static final String ACCOUNT_MANAGER_PACKAGE_NAME = "io.v.android.apps.account_manager"; |
| |
| /** |
| * Returns the intent used for obtaining a fresh set of credentials from the |
| * vanadium blessing service. |
| * |
| * @param ctx android context |
| * @param googleAccount google account name to use as the basis of the newly minted credentials |
| * (e.g., {@code myname@mymail.com}). If empty or {@code null}, user |
| * will be prompted to select one from the list of installed Google |
| * accounts |
| */ |
| public static Intent newBlessingIntent(Context ctx, String googleAccount) { |
| VContext vCtx = V.init(ctx); |
| ECPublicKey key = V.getPrincipal(vCtx).publicKey(); |
| Intent intent = null; |
| if (isAccountManagerInstalled(ctx)) { |
| // Get blessings from the account manager installed on the device. |
| intent = new Intent(); |
| intent.setComponent(new ComponentName(ACCOUNT_MANAGER_PACKAGE_NAME, |
| ACCOUNT_MANAGER_PACKAGE_NAME + ".LocalBlessingActivity")); |
| } else { |
| // Get blessings from the blessing service. |
| intent = new Intent(ctx, BlessingActivity.class); |
| intent.setAction("io.v.android.x.ref.services.blessing.BLESSING"); |
| } |
| intent.putExtra(EXTRA_PUBLIC_KEY, key); |
| intent.putExtra(EXTRA_GOOGLE_ACCOUNT, googleAccount); |
| return intent; |
| } |
| |
| /** |
| * Same as {@link #newBlessingIntent(Context, String)}, but without the explicit Google |
| * account name: the user will be prompted to select one from the list of installed Google |
| * accounts. |
| * |
| * @param ctx android context |
| */ |
| public static Intent newBlessingIntent(Context ctx) { |
| return newBlessingIntent(ctx, ""); |
| } |
| |
| /** |
| * Processes the reply from the vanadium blessing serves generated by the |
| * {@link #newBlessingIntent} intent, returning the credentials stored within. |
| * |
| * @param resultCode result code of the reply |
| * @param data reply data |
| * @return the credentials stored in the reply |
| * @throws BlessingCreationException if there was an error generating the credentials |
| */ |
| public static byte[] extractBlessingReply(int resultCode, Intent data) |
| throws BlessingCreationException { |
| if (data == null) { |
| throw new BlessingCreationException("NULL blessing response"); |
| } |
| if (resultCode != Activity.RESULT_OK) { |
| throw new BlessingCreationException("Error getting blessing: " + data.getStringExtra(EXTRA_ERROR)); |
| } |
| byte[] blessingsVom = data.getByteArrayExtra(EXTRA_REPLY); |
| if (blessingsVom == null || blessingsVom.length <= 0) { |
| throw new BlessingCreationException("Got null blessings."); |
| } |
| return blessingsVom; |
| } |
| |
| private static boolean isAccountManagerInstalled(Context ctx) { |
| PackageManager pm = ctx.getPackageManager(); |
| try { |
| pm.getPackageInfo(ACCOUNT_MANAGER_PACKAGE_NAME, PackageManager.GET_ACTIVITIES); |
| return true; |
| } catch (PackageManager.NameNotFoundException e) { |
| return false; |
| } |
| } |
| |
| private BlessingService() {} |
| } |