diff --git a/include/ui/CameraParameters.h b/include/ui/CameraParameters.h
index cae0676..2c29bfb 100644
--- a/include/ui/CameraParameters.h
+++ b/include/ui/CameraParameters.h
@@ -34,8 +34,10 @@
 
     void set(const char *key, const char *value);
     void set(const char *key, int value);
+    void setFloat(const char *key, float value);
     const char *get(const char *key) const;
     int getInt(const char *key) const;
+    float getFloat(const char *key) const;
 
     /* preview-size=176x144 */
     void setPreviewSize(int width, int height);
@@ -176,6 +178,16 @@
     // Supported focus modes.
     // Example value: "auto,macro,fixed". Read only.
     static const char KEY_SUPPORTED_FOCUS_MODES[];
+    // Focal length in millimeter.
+    // Example value: "4.31". Read only.
+    static const char KEY_FOCAL_LENGTH[];
+    // Horizontal angle of view in degrees.
+    // Example value: "54.8". Read only.
+    static const char KEY_HORIZONTAL_VIEW_ANGLE[];
+    // Vertical angle of view in degrees.
+    // Example value: "42.5". Read only.
+    static const char KEY_VERTICAL_VIEW_ANGLE[];
+
 
         // Values for white balance settings.
     static const char WHITE_BALANCE_AUTO[];
diff --git a/libs/ui/CameraParameters.cpp b/libs/ui/CameraParameters.cpp
index a94f6b9..c4958a0 100644
--- a/libs/ui/CameraParameters.cpp
+++ b/libs/ui/CameraParameters.cpp
@@ -56,6 +56,9 @@
 const char CameraParameters::KEY_SUPPORTED_FLASH_MODES[] = "flash-mode-values";
 const char CameraParameters::KEY_FOCUS_MODE[] = "focus-mode";
 const char CameraParameters::KEY_SUPPORTED_FOCUS_MODES[] = "focus-mode-values";
+const char CameraParameters::KEY_FOCAL_LENGTH[] = "focal-length";
+const char CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE[] = "horizontal-view-angle";
+const char CameraParameters::KEY_VERTICAL_VIEW_ANGLE[] = "vertical-view-angle";
 
 // Values for white balance settings.
 const char CameraParameters::WHITE_BALANCE_AUTO[] = "auto";
@@ -206,6 +209,13 @@
     set(key, str);
 }
 
+void CameraParameters::setFloat(const char *key, float value)
+{
+    char str[16];  // 14 should be enough. We overestimate to be safe.
+    snprintf(str, sizeof(str), "%g", value);
+    set(key, str);
+}
+
 const char *CameraParameters::get(const char *key) const
 {
     String8 v = mMap.valueFor(String8(key));
@@ -222,6 +232,13 @@
     return strtol(v, 0, 0);
 }
 
+float CameraParameters::getFloat(const char *key) const
+{
+    const char *v = get(key);
+    if (v == 0) return -1;
+    return strtof(v, 0);
+}
+
 static int parse_size(const char *str, int &width, int &height)
 {
     // Find the width.
diff --git a/vpn/tests/vpntests/Android.mk b/vpn/tests/vpntests/Android.mk
new file mode 100644
index 0000000..a19fb56
--- /dev/null
+++ b/vpn/tests/vpntests/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_PACKAGE_NAME := FrameworksVpnTests
+
+include $(BUILD_PACKAGE)
+
diff --git a/vpn/tests/vpntests/AndroidManifest.xml b/vpn/tests/vpntests/AndroidManifest.xml
new file mode 100644
index 0000000..d8405f6
--- /dev/null
+++ b/vpn/tests/vpntests/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.frameworks.vpntests">
+    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
+    <uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
+    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+    
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+    	android:name="android.test.InstrumentationTestRunner"
+    	android:targetPackage="com.android.frameworks.vpntests"
+    	android:label="Frameworks VPN Tests" />
+</manifest>
diff --git a/vpn/tests/vpntests/src/android/net/vpn/VpnTest.java b/vpn/tests/vpntests/src/android/net/vpn/VpnTest.java
new file mode 100755
index 0000000..46a57d3
--- /dev/null
+++ b/vpn/tests/vpntests/src/android/net/vpn/VpnTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2009 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.net.vpn;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.vpn.L2tpProfile;
+import android.net.vpn.L2tpIpsecProfile;
+import android.net.vpn.L2tpIpsecPskProfile;
+import android.net.vpn.PptpProfile;
+import android.net.vpn.VpnManager;
+import android.net.vpn.VpnProfile;
+import android.net.vpn.VpnState;
+import android.net.vpn.VpnType;
+import android.os.ConditionVariable;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.text.TextUtils;
+
+/**
+ * Unit test class to test VPN api
+ * Use the below command to run the vpn unit test only
+ * runtest vpntest or
+ * adb shell am instrument -e class 'com.android.unit_tests.VpnTest'
+ *   -w com.android.unit_tests/android.test.InstrumentationTestRunner
+ */
+public class VpnTest extends AndroidTestCase {
+    private static final String NAME = "a name";
+    private static final String SERVER_NAME = "a server name";
+    private static final String ID = "some id";
+    private static final String SUFFICES = "some suffices";
+    private static final String ROUTES = "some routes";
+    private static final String SAVED_NAME = "some name";
+
+    @Override
+    public void setUp() {
+    }
+
+    @Override
+    public void tearDown() {
+    }
+
+    @SmallTest
+    public void testVpnType() {
+        testVpnType(VpnType.L2TP);
+        testVpnType(VpnType.L2TP_IPSEC);
+        testVpnType(VpnType.L2TP_IPSEC_PSK);
+        testVpnType(VpnType.PPTP);
+    }
+
+    @SmallTest
+    public void testVpnProfile() {
+        VpnState state = VpnState.CONNECTING;
+        testVpnProfile(createTestProfile(state), state);
+    }
+
+    @SmallTest
+    public void testGetType() {
+        assertEquals(VpnType.L2TP, new L2tpProfile().getType());
+        assertEquals(VpnType.L2TP_IPSEC, new L2tpIpsecProfile().getType());
+        assertEquals(VpnType.L2TP_IPSEC_PSK, 
+                new L2tpIpsecPskProfile().getType());
+        assertEquals(VpnType.PPTP, new PptpProfile().getType());
+    }
+
+    @SmallTest
+    public void testVpnTypes() {
+        assertTrue(VpnManager.getSupportedVpnTypes().length > 0);
+    }
+
+    @SmallTest
+    public void testGetTypeFromManager() {
+        VpnManager m = new VpnManager(getContext());
+        VpnType[] types = VpnManager.getSupportedVpnTypes();
+        for (VpnType t : types) {
+            assertEquals(t, m.createVpnProfile(t).getType());
+        }
+    }
+
+    @SmallTest
+    public void testParcelable() {
+        VpnProfile p = createTestProfile(VpnState.CONNECTED);
+        Parcel parcel = Parcel.obtain();
+        p.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+
+        // VpnState is transient and not saved in the parcel
+        testVpnProfile(VpnProfile.CREATOR.createFromParcel(parcel), null);
+    }
+
+    @SmallTest
+    public void testReceiver() {
+        final String profileName = "whatever";
+        final VpnState state = VpnState.DISCONNECTING;
+        final ConditionVariable cv = new ConditionVariable();
+        cv.close();
+        BroadcastReceiver r = new BroadcastReceiver() {
+            public void onReceive(Context c, Intent i) {
+                assertEquals(profileName,
+                        i.getStringExtra(VpnManager.BROADCAST_PROFILE_NAME));
+                assertEquals(state, i.getSerializableExtra(
+                        VpnManager.BROADCAST_CONNECTION_STATE));
+                cv.open();
+            }
+        };
+
+        VpnManager m = new VpnManager(getContext());
+        m.registerConnectivityReceiver(r);
+        m.broadcastConnectivity(profileName, state);
+
+        // fail it if onReceive() doesn't get executed in 5 sec
+        assertTrue(cv.block(5000));
+    }
+
+    private void testVpnType(VpnType type) {
+        assertFalse(TextUtils.isEmpty(type.getDisplayName()));
+        assertNotNull(type.getProfileClass());
+    }
+
+    private VpnProfile createTestProfile(VpnState state) {
+        VpnProfile p = new L2tpProfile();
+        p.setName(NAME);
+        p.setServerName(SERVER_NAME);
+        p.setId(ID);
+        p.setDomainSuffices(SUFFICES);
+        p.setRouteList(ROUTES);
+        p.setSavedUsername(SAVED_NAME);
+        p.setState(state);
+        return p;
+    }
+
+    private void testVpnProfile(VpnProfile p, VpnState state) {
+        assertEquals(NAME, p.getName());
+        assertEquals(SERVER_NAME, p.getServerName());
+        assertEquals(ID, p.getId());
+        assertEquals(SUFFICES, p.getDomainSuffices());
+        assertEquals(ROUTES, p.getRouteList());
+        assertEquals(SAVED_NAME, p.getSavedUsername());
+        if (state != null) assertEquals(state, p.getState());
+    }
+}
