Merge "Action bar tab layout"
diff --git a/Android.mk b/Android.mk
index 0cf30df..e3406ea 100644
--- a/Android.mk
+++ b/Android.mk
@@ -162,6 +162,7 @@
 	core/java/com/android/internal/view/IInputMethodSession.aidl \
 	core/java/com/android/internal/widget/IRemoteViewsFactory.aidl \
 	core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl \
+	keystore/java/android/security/IKeyChainAliasResponse.aidl \
 	keystore/java/android/security/IKeyChainService.aidl \
 	location/java/android/location/ICountryDetector.aidl \
 	location/java/android/location/ICountryListener.aidl \
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 845fbc3..61a24a0 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -17,7 +17,6 @@
 
 package android.view;
 
-import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
@@ -137,14 +136,14 @@
          * 
          * @param canvas The Canvas used to render the view.
          */
-        void onHardwarePreDraw(Canvas canvas);
+        void onHardwarePreDraw(HardwareCanvas canvas);
 
         /**
          * Invoked after a view is drawn by a hardware renderer.
          * 
          * @param canvas The Canvas used to render the view.
          */
-        void onHardwarePostDraw(Canvas canvas);
+        void onHardwarePostDraw(HardwareCanvas canvas);
     }
 
     /**
diff --git a/core/java/android/view/ViewAncestor.java b/core/java/android/view/ViewAncestor.java
index ccba894..bf04502 100644
--- a/core/java/android/view/ViewAncestor.java
+++ b/core/java/android/view/ViewAncestor.java
@@ -26,7 +26,6 @@
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
@@ -229,9 +228,9 @@
     int mScrollY;
     int mCurScrollY;
     Scroller mScroller;
-    Bitmap mResizeBitmap;
-    long mResizeBitmapStartTime;
-    int mResizeBitmapDuration;
+    HardwareLayer mResizeBuffer;
+    long mResizeBufferStartTime;
+    int mResizeBufferDuration;
     static final Interpolator mResizeInterpolator = new AccelerateDecelerateInterpolator();
     private ArrayList<LayoutTransition> mPendingTransitions;
 
@@ -695,10 +694,10 @@
         return mAppVisible ? mView.getVisibility() : View.GONE;
     }
 
-    void disposeResizeBitmap() {
-        if (mResizeBitmap != null) {
-            mResizeBitmap.recycle();
-            mResizeBitmap = null;
+    void disposeResizeBuffer() {
+        if (mResizeBuffer != null) {
+            mResizeBuffer.destroy();
+            mResizeBuffer = null;
         }
     }
 
@@ -842,15 +841,25 @@
                             mAttachInfo.mHardwareRenderer.isEnabled() &&
                             lp != null && !PixelFormat.formatHasAlpha(lp.format)) {
 
-                        disposeResizeBitmap();
+                        disposeResizeBuffer();
 
                         boolean completed = false;
+                        HardwareCanvas canvas = null;
                         try {
-                            mResizeBitmap = Bitmap.createBitmap(mWidth, mHeight,
-                                    Bitmap.Config.ARGB_8888);
-                            mResizeBitmap.setHasAlpha(false);
-                            Canvas canvas = new Canvas(mResizeBitmap);
+                            if (mResizeBuffer == null) {
+                                mResizeBuffer = mAttachInfo.mHardwareRenderer.createHardwareLayer(
+                                        mWidth, mHeight, false);
+                            } else if (mResizeBuffer.getWidth() != mWidth ||
+                                    mResizeBuffer.getHeight() != mHeight) {
+                                mResizeBuffer.resize(mWidth, mHeight);
+                            }
+                            canvas = mResizeBuffer.start(mAttachInfo.mHardwareCanvas);
+                            canvas.setViewport(mWidth, mHeight);
+                            canvas.onPreDraw(null);
+                            final int restoreCount = canvas.save();
+                            
                             canvas.drawColor(0xff000000, PorterDuff.Mode.SRC);
+
                             int yoff;
                             final boolean scrolling = mScroller != null
                                     && mScroller.computeScrollOffset();
@@ -860,22 +869,32 @@
                             } else {
                                 yoff = mScrollY;
                             }
+
                             canvas.translate(0, -yoff);
                             if (mTranslator != null) {
                                 mTranslator.translateCanvas(canvas);
                             }
-                            canvas.setScreenDensity(mAttachInfo.mScalingRequired
-                                    ? DisplayMetrics.DENSITY_DEVICE : 0);
+
                             mView.draw(canvas);
-                            mResizeBitmapStartTime = SystemClock.uptimeMillis();
-                            mResizeBitmapDuration = mView.getResources().getInteger(
+
+                            mResizeBufferStartTime = SystemClock.uptimeMillis();
+                            mResizeBufferDuration = mView.getResources().getInteger(
                                     com.android.internal.R.integer.config_mediumAnimTime);
                             completed = true;
+
+                            canvas.restoreToCount(restoreCount);
                         } catch (OutOfMemoryError e) {
                             Log.w(TAG, "Not enough memory for content change anim buffer", e);
                         } finally {
-                            if (!completed) {
-                                mResizeBitmap = null;
+                            if (canvas != null) {
+                                canvas.onPostDraw();
+                            }
+                            if (mResizeBuffer != null) {
+                                mResizeBuffer.end(mAttachInfo.mHardwareCanvas);
+                                if (!completed) {
+                                    mResizeBuffer.destroy();
+                                    mResizeBuffer = null;
+                                }
                             }
                         }
                     }
@@ -1137,7 +1156,7 @@
                     if (mScroller != null) {
                         mScroller.abortAnimation();
                     }
-                    disposeResizeBitmap();
+                    disposeResizeBuffer();
                 } else if (surfaceGenerationId != mSurface.getGenerationId() &&
                         mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) {
                     fullRedrawNeeded = true;
@@ -1524,15 +1543,14 @@
     int mResizeAlpha;
     final Paint mResizePaint = new Paint();
 
-    public void onHardwarePreDraw(Canvas canvas) {
+    public void onHardwarePreDraw(HardwareCanvas canvas) {
         canvas.translate(0, -mHardwareYOffset);
     }
 
-    public void onHardwarePostDraw(Canvas canvas) {
-        if (mResizeBitmap != null) {
-            canvas.translate(0, mHardwareYOffset);
+    public void onHardwarePostDraw(HardwareCanvas canvas) {
+        if (mResizeBuffer != null) {
             mResizePaint.setAlpha(mResizeAlpha);
-            canvas.drawBitmap(mResizeBitmap, 0, 0, mResizePaint);
+            canvas.drawHardwareLayer(mResizeBuffer, 0.0f, mHardwareYOffset, mResizePaint);
         }
     }
 
@@ -1588,15 +1606,15 @@
         boolean scalingRequired = mAttachInfo.mScalingRequired;
 
         int resizeAlpha = 0;
-        if (mResizeBitmap != null) {
-            long deltaTime = SystemClock.uptimeMillis() - mResizeBitmapStartTime;
-            if (deltaTime < mResizeBitmapDuration) {
-                float amt = deltaTime/(float)mResizeBitmapDuration;
+        if (mResizeBuffer != null) {
+            long deltaTime = SystemClock.uptimeMillis() - mResizeBufferStartTime;
+            if (deltaTime < mResizeBufferDuration) {
+                float amt = deltaTime/(float) mResizeBufferDuration;
                 amt = mResizeInterpolator.getInterpolation(amt);
                 animating = true;
                 resizeAlpha = 255 - (int)(amt*255);
             } else {
-                disposeResizeBitmap();
+                disposeResizeBuffer();
             }
         }
 
@@ -1608,7 +1626,7 @@
                 if (mScroller != null) {
                     mScroller.abortAnimation();
                 }
-                disposeResizeBitmap();
+                disposeResizeBuffer();
             }
             return;
         }
@@ -1892,7 +1910,7 @@
         if (scrollY != mScrollY) {
             if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Pan scroll changed: old="
                     + mScrollY + " , new=" + scrollY);
-            if (!immediate && mResizeBitmap == null) {
+            if (!immediate && mResizeBuffer == null) {
                 if (mScroller == null) {
                     mScroller = new Scroller(mView.getContext());
                 }
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 5902745..db5ff54 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -2002,7 +2002,8 @@
         if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw start");
         draw.mBaseLayer = nativeRecordContent(draw.mInvalRegion, draw.mContentSize);
         if (draw.mBaseLayer == 0) {
-            if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw abort");
+            if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "webkitDraw abort, resending draw message");
+            mEventHub.sendMessage(Message.obtain(null, EventHub.WEBKIT_DRAW));
             return;
         }
         webkitDraw(draw);
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 71c91e1..c4ba7c8 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -116,7 +116,7 @@
 
     private static final int MIN_TIME_BETWEEN_INTERACTION_AND_AUTOADVANCE = 5000;
 
-    private static long MIN_TIME_BETWEEN_SCROLLS = 100;
+    private static final long MIN_TIME_BETWEEN_SCROLLS = 100;
 
     /**
      * These variables are all related to the current state of touch interaction
@@ -213,8 +213,7 @@
      * Animate the views between different relative indexes within the {@link AdapterViewAnimator}
      */
     void transformViewForTransition(int fromIndex, int toIndex, final View view, boolean animate) {
-        ObjectAnimator alphaOa = null;
-        ObjectAnimator oldAlphaOa = null;
+        ObjectAnimator alphaOa;
 
         if (!animate) {
             ((StackFrame) view).cancelSliderAnimator();
@@ -1276,13 +1275,11 @@
 
             boolean firstPass = true;
             parentRect.set(0, 0, 0, 0);
-            int depth = 0;
             while (p.getParent() != null && p.getParent() instanceof View
                     && !parentRect.contains(globalInvalidateRect)) {
                 if (!firstPass) {
                     globalInvalidateRect.offset(p.getLeft() - p.getScrollX(), p.getTop()
                             - p.getScrollY());
-                    depth++;
                 }
                 firstPass = false;
                 p = (View) p.getParent();
diff --git a/keystore/java/android/security/IKeyChainAliasResponse.aidl b/keystore/java/android/security/IKeyChainAliasResponse.aidl
new file mode 100644
index 0000000..e042001
--- /dev/null
+++ b/keystore/java/android/security/IKeyChainAliasResponse.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * 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 android.security;
+
+/**
+ * Used by the {@code KeyChainActivity} to return alias for {@link KeyStore#chooseAlias}.
+ *
+ * @hide
+ */
+interface IKeyChainAliasResponse {
+
+    void alias(String alias);
+}
diff --git a/keystore/java/android/security/IKeyChainService.aidl b/keystore/java/android/security/IKeyChainService.aidl
index be59f23..2763e46 100644
--- a/keystore/java/android/security/IKeyChainService.aidl
+++ b/keystore/java/android/security/IKeyChainService.aidl
@@ -15,8 +15,6 @@
  */
 package android.security;
 
-import android.os.Bundle;
-
 /**
  * Caller is required to ensure that {@link KeyStore#unlock
  * KeyStore.unlock} was successful.
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 08e05ef..ec820cf 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -17,9 +17,11 @@
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
+import android.accounts.AccountManagerCallback;
 import android.accounts.AccountManagerFuture;
 import android.accounts.AuthenticatorException;
 import android.accounts.OperationCanceledException;
+import android.app.Activity;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -56,64 +58,123 @@
     public static final String ACCOUNT_TYPE = "com.android.keychain";
 
     /**
-     * Returns an {@code Intent} for use with {@link
-     * android.app.Activity#startActivityForResult
-     * startActivityForResult}. The result will be returned via {@link
-     * android.app.Activity#onActivityResult onActivityResult} with
-     * {@link android.app.Activity#RESULT_OK RESULT_OK} and the alias
-     * in the returned {@code Intent}'s extra data with key {@link
-     * android.content.Intent#EXTRA_TEXT Intent.EXTRA_TEXT}.
+     * @hide Also used by KeyChainActivity implementation
      */
-    public static Intent chooseAlias() {
-        return new Intent("com.android.keychain.CHOOSER");
+    public static final String EXTRA_RESPONSE = "response";
+
+    /**
+     * Launches an {@code Activity} for the user to select the alias
+     * for a private key and certificate pair for authentication. The
+     * selected alias or null will be returned via the
+     * IKeyChainAliasResponse callback.
+     */
+    public static void choosePrivateKeyAlias(Activity activity, KeyChainAliasResponse response) {
+        if (activity == null) {
+            throw new NullPointerException("activity == null");
+        }
+        if (response == null) {
+            throw new NullPointerException("response == null");
+        }
+        Intent intent = new Intent("com.android.keychain.CHOOSER");
+        intent.putExtra(EXTRA_RESPONSE, new AliasResponse(activity, response));
+        activity.startActivity(intent);
+    }
+
+    private static class AliasResponse extends IKeyChainAliasResponse.Stub {
+        private final Activity activity;
+        private final KeyChainAliasResponse keyChainAliasResponse;
+        private AliasResponse(Activity activity, KeyChainAliasResponse keyChainAliasResponse) {
+            this.activity = activity;
+            this.keyChainAliasResponse = keyChainAliasResponse;
+        }
+        @Override public void alias(String alias) {
+            if (alias == null) {
+                keyChainAliasResponse.alias(null);
+                return;
+            }
+            AccountManager accountManager = AccountManager.get(activity);
+            accountManager.getAuthToken(getAccount(activity),
+                                        alias,
+                                        null,
+                                        activity,
+                                        new AliasAccountManagerCallback(keyChainAliasResponse,
+                                                                        alias),
+                                        null);
+        }
+    }
+
+    private static class AliasAccountManagerCallback implements AccountManagerCallback<Bundle> {
+        private final KeyChainAliasResponse keyChainAliasResponse;
+        private final String alias;
+        private AliasAccountManagerCallback(KeyChainAliasResponse keyChainAliasResponse,
+                                            String alias) {
+            this.keyChainAliasResponse = keyChainAliasResponse;
+            this.alias = alias;
+        }
+        @Override public void run(AccountManagerFuture<Bundle> future) {
+            Bundle bundle;
+            try {
+                bundle = future.getResult();
+            } catch (OperationCanceledException e) {
+                keyChainAliasResponse.alias(null);
+                return;
+            } catch (IOException e) {
+                keyChainAliasResponse.alias(null);
+                return;
+            } catch (AuthenticatorException e) {
+                keyChainAliasResponse.alias(null);
+                return;
+            }
+            String authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
+            if (authToken != null) {
+                keyChainAliasResponse.alias(alias);
+            } else {
+                keyChainAliasResponse.alias(null);
+            }
+        }
     }
 
     /**
-     * Returns a new {@code KeyChainResult} instance.
+     * Returns the {@code PrivateKey} for the requested alias, or null
+     * if no there is no result.
      */
-    public static KeyChainResult get(Context context, String alias)
+    public static PrivateKey getPrivateKey(Context context, String alias)
             throws InterruptedException, RemoteException {
         if (alias == null) {
             throw new NullPointerException("alias == null");
         }
         KeyChainConnection keyChainConnection = bind(context);
         try {
-            // Account is created if necessary during binding of the IKeyChainService
-            AccountManager accountManager = AccountManager.get(context);
-            Account account = accountManager.getAccountsByType(ACCOUNT_TYPE)[0];
-            AccountManagerFuture<Bundle> future = accountManager.getAuthToken(account,
-                                                                              alias,
-                                                                              false,
-                                                                              null,
-                                                                              null);
-            Bundle bundle;
-            try {
-                bundle = future.getResult();
-            } catch (OperationCanceledException e) {
-                throw new AssertionError(e);
-            } catch (IOException e) {
-                throw new AssertionError(e);
-            } catch (AuthenticatorException e) {
-                throw new AssertionError(e);
-            }
-            Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
-            if (intent != null) {
-                Bundle result = new Bundle();
-                // we don't want this Eclair compatability flag,
-                // it will prevent onActivityResult from being called
-                intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK);
-                return new KeyChainResult(intent);
-            }
-
-            String authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
+            String authToken = authToken(context, alias);
             if (authToken == null) {
-                throw new AssertionError("Invalid authtoken");
+                return null;
             }
             IKeyChainService keyChainService = keyChainConnection.getService();
             byte[] privateKeyBytes = keyChainService.getPrivateKey(alias, authToken);
+            return toPrivateKey(privateKeyBytes);
+        } finally {
+            keyChainConnection.close();
+        }
+    }
+
+    /**
+     * Returns the {@code X509Certificate} chain for the requested
+     * alias, or null if no there is no result.
+     */
+    public static X509Certificate[] getCertificateChain(Context context, String alias)
+            throws InterruptedException, RemoteException {
+        if (alias == null) {
+            throw new NullPointerException("alias == null");
+        }
+        KeyChainConnection keyChainConnection = bind(context);
+        try {
+            String authToken = authToken(context, alias);
+            if (authToken == null) {
+                return null;
+            }
+            IKeyChainService keyChainService = keyChainConnection.getService();
             byte[] certificateBytes = keyChainService.getCertificate(alias, authToken);
-            return new KeyChainResult(toPrivateKey(privateKeyBytes),
-                                      toCertificate(certificateBytes));
+            return new X509Certificate[] { toCertificate(certificateBytes) };
         } finally {
             keyChainConnection.close();
         }
@@ -146,6 +207,50 @@
         }
     }
 
+    private static String authToken(Context context, String alias) {
+        AccountManager accountManager = AccountManager.get(context);
+        AccountManagerFuture<Bundle> future = accountManager.getAuthToken(getAccount(context),
+                                                                          alias,
+                                                                          false,
+                                                                          null,
+                                                                          null);
+        Bundle bundle;
+        try {
+            bundle = future.getResult();
+        } catch (OperationCanceledException e) {
+            throw new AssertionError(e);
+        } catch (IOException e) {
+            // KeyChainAccountAuthenticator doesn't do I/O
+            throw new AssertionError(e);
+        } catch (AuthenticatorException e) {
+            throw new AssertionError(e);
+        }
+        Intent intent = bundle.getParcelable(AccountManager.KEY_INTENT);
+        if (intent != null) {
+            return null;
+        }
+        String authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
+        if (authToken == null) {
+            throw new AssertionError("Invalid authtoken");
+        }
+        return authToken;
+    }
+
+    private static Account getAccount(Context context) {
+        AccountManager accountManager = AccountManager.get(context);
+        Account[] accounts = accountManager.getAccountsByType(ACCOUNT_TYPE);
+        if (accounts.length == 0) {
+            try {
+                // Account is created if necessary during binding of the IKeyChainService
+                bind(context).close();
+            } catch (InterruptedException e) {
+                throw new AssertionError(e);
+            }
+            accounts = accountManager.getAccountsByType(ACCOUNT_TYPE);
+        }
+        return accounts[0];
+    }
+
     /**
      * @hide for reuse by CertInstaller and Settings.
      * @see KeyChain#bind
diff --git a/keystore/java/android/security/KeyChainAliasResponse.java b/keystore/java/android/security/KeyChainAliasResponse.java
new file mode 100644
index 0000000..bcca123
--- /dev/null
+++ b/keystore/java/android/security/KeyChainAliasResponse.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * 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 android.security;
+
+import android.content.Intent;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+/**
+ * The KeyChainAliasResponse is the callback for {@link
+ * KeyChain#chooseAlias}.
+ *
+ * @hide
+ */
+public interface KeyChainAliasResponse {
+
+    /**
+     * Called with the alias of the certificate chosen by the user, or
+     * null if no value was chosen.
+     */
+    public void alias(String alias);
+}
diff --git a/keystore/java/android/security/KeyChainResult.java b/keystore/java/android/security/KeyChainResult.java
deleted file mode 100644
index 85a2921..0000000
--- a/keystore/java/android/security/KeyChainResult.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * 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 android.security;
-
-import android.content.Intent;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
-/**
- * The KeyChainResult is the complex result value from {@link
- * KeyChain#get}. The caller should first inspect {@link #getIntent}
- * to determine if the user needs to grant the application access to
- * the protected contents. If {@code getIntent} returns null, access
- * has been granted and the methods {@link #getPrivateKey} and {@link
- * #getCertificate} can be used to access the credentials.
- *
- * @hide
- */
-public final class KeyChainResult {
-
-    private final Intent intent;
-    private final PrivateKey privateKey;
-    private final X509Certificate certificate;
-
-    KeyChainResult(Intent intent) {
-        this(intent, null, null);
-    }
-
-    KeyChainResult(PrivateKey privateKey, X509Certificate certificate) {
-        this(null, privateKey, certificate);
-    }
-
-    private KeyChainResult(Intent intent, PrivateKey privateKey, X509Certificate certificate) {
-        this.intent = intent;
-        this.privateKey = privateKey;
-        this.certificate = certificate;
-    }
-
-    public Intent getIntent() {
-        return intent;
-    }
-
-    public PrivateKey getPrivateKey() {
-        checkIntent();
-        return privateKey;
-    }
-
-    public X509Certificate getCertificate() {
-        checkIntent();
-        return certificate;
-    }
-
-    private void checkIntent() {
-        if (intent != null) {
-            throw new IllegalStateException("non-null Intent, check getIntent()");
-        }
-    }
-
-}