Merge change 3536

* changes:
  Add getRawData() method for AggregationService.
diff --git a/tts/java/android/tts/ITts.aidl b/tts/java/android/tts/ITts.aidl
index 1fe4a6a..3558f5a 100755
--- a/tts/java/android/tts/ITts.aidl
+++ b/tts/java/android/tts/ITts.aidl
@@ -1,59 +1,57 @@
-/*
- * 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.tts;
-
-import android.tts.ITtsCallback;
-
-import android.content.Intent;
-
-/**
- * AIDL for the TTS Service
- * ITts.java is autogenerated from this.
- *
- * {@hide}
- */
-interface ITts {
-    void setEngine(in String engineName, in String[] requestedLanguages, in int strictness);
-
-    void setEngineWithIntent(in Intent engineIntent);
-
-    void setSpeechRate(in int speechRate);
-
-    void speak(in String text, in int queueMode, in String[] params);
-
-    boolean isSpeaking();
-
-    void stop();
-
-    void addSpeech(in String text, in String packageName, in int resId);
-
-    void addSpeechFile(in String text, in String filename);
-
-    void setLanguage(in String language);
-
-    boolean synthesizeToFile(in String text, in String[] params, in String outputDirectory);
-
-    void playEarcon(in String earcon, in int queueMode, in String[] params);
-
-    void addEarcon(in String earcon, in String packageName, in int resId);
-
-    void addEarconFile(in String earcon, in String filename);
-
-    void registerCallback(ITtsCallback cb);
-
-    void unregisterCallback(ITtsCallback cb);
-}
+/*

+ * 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.tts;

+

+import android.tts.ITtsCallback;

+

+import android.content.Intent;

+

+/**

+ * AIDL for the TTS Service

+ * ITts.java is autogenerated from this.

+ *

+ * {@hide}

+ */

+interface ITts {

+    void setSpeechRate(in int speechRate);

+

+    void speak(in String text, in int queueMode, in String[] params);

+

+    boolean isSpeaking();

+

+    void stop();

+

+    void addSpeech(in String text, in String packageName, in int resId);

+

+    void addSpeechFile(in String text, in String filename);

+

+    void setLanguage(in String language);

+

+    boolean synthesizeToFile(in String text, in String[] params, in String outputDirectory);

+

+    void playEarcon(in String earcon, in int queueMode, in String[] params);

+

+    void addEarcon(in String earcon, in String packageName, in int resId);

+

+    void addEarconFile(in String earcon, in String filename);

+

+    void registerCallback(ITtsCallback cb);

+

+    void unregisterCallback(ITtsCallback cb);

+

+    void playSilence(in long duration, in int queueMode, in String[] params);

+}

diff --git a/tts/java/android/tts/TtsService.java b/tts/java/android/tts/TtsService.java
index d317181..2373e96 100755
--- a/tts/java/android/tts/TtsService.java
+++ b/tts/java/android/tts/TtsService.java
@@ -22,7 +22,6 @@
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.media.MediaPlayer;
 import android.media.MediaPlayer.OnCompletionListener;
@@ -106,7 +105,6 @@
     private final ReentrantLock speechQueueLock = new ReentrantLock();
     private final ReentrantLock synthesizerLock = new ReentrantLock();
 
-    // TODO support multiple SpeechSynthesis objects
     private SynthProxy nativeSynth;
 
     @Override
@@ -114,15 +112,21 @@
         super.onCreate();
         Log.i("TTS", "TTS starting");
 
-
         // TODO: Make this work when the settings are done in the main Settings
         // app.
         prefs = PreferenceManager.getDefaultSharedPreferences(this);
 
-        // TODO: This should be changed to work by requesting the path
-        // from the default engine.
-        nativeSynth = new SynthProxy(prefs.getString("engine_pref", ""));
-
+        PackageManager pm = this.getPackageManager();
+        String soLibPath = "";
+        try {
+            soLibPath = pm.getApplicationInfo("com.svox.pico", 0).dataDir;
+        } catch (NameNotFoundException e) {
+            // This exception cannot actually happen as com.svox.pico is
+            // included with the system image.
+            e.printStackTrace();
+        }
+        soLibPath = soLibPath + "/lib/libttspico.so";
+        nativeSynth = new SynthProxy(soLibPath);
 
         mSelf = this;
         mIsSpeaking = false;
@@ -170,35 +174,6 @@
         nativeSynth.setLanguage(lang);
     }
 
-    private void setEngine(String engineName, String[] requestedLanguages,
-            int strictness) {
-        // TODO: Implement engine selection code here.
-        Intent engineIntent = new Intent(
-        "android.intent.action.START_TTS_ENGINE");
-        if (engineName != null) {
-            engineIntent.addCategory("android.intent.action.tts_engine."
-                    + engineName);
-        }
-        for (int i = 0; i < requestedLanguages.length; i++) {
-            engineIntent.addCategory("android.intent.action.tts_lang."
-                    + requestedLanguages[i]);
-        }
-        ResolveInfo[] enginesArray = new ResolveInfo[0];
-        PackageManager pm = getPackageManager();
-        enginesArray = pm.queryIntentActivities(engineIntent, 0).toArray(
-                enginesArray);
-    }
-
-    private void setEngine(Intent engineIntent) {
-        // TODO: Implement engine selection code here.
-    }
-
-    private int getEngineStatus() {
-        // TODO: Proposal - add a sanity check method that
-        // TTS engine plugins must implement.
-        return 0;
-    }
-
     /**
      * Adds a sound resource to the TTS.
      *
@@ -436,8 +411,7 @@
             if (sr == null) {
                 if (currentSpeechItem.mType == SpeechItem.SPEECH) {
                     // TODO: Split text up into smaller chunks before accepting
-                    // them
-                    // for processing.
+                    // them for processing.
                     speakInternalOnly(currentSpeechItem.mText,
                             currentSpeechItem.mParams);
                 } else {
@@ -576,30 +550,6 @@
         }
 
         /**
-         * Gives a hint about the type of engine that is preferred.
-         *
-         * @param selectedEngine
-         *            The TTS engine that should be used
-         */
-        public void setEngine(String engineName, String[] supportedLanguages,
-                int strictness) {
-            mSelf.setEngine(engineName, supportedLanguages, strictness);
-        }
-
-        /**
-         * Specifies exactly what the engine has to support. Will always be
-         * considered "strict"; can be used for implementing
-         * optional/experimental features that are not supported by all engines.
-         *
-         * @param engineIntent
-         *            An intent that specifies exactly what the engine has to
-         *            support.
-         */
-        public void setEngineWithIntent(Intent engineIntent) {
-            mSelf.setEngine(engineIntent);
-        }
-
-        /**
          * Speaks the given text using the specified queueing mode and
          * parameters.
          *
@@ -658,7 +608,6 @@
             mSelf.playSilence(duration, queueMode, speakingParams);
         }
 
-
         /**
          * Stops all speech output and removes any utterances still in the
          * queue.
@@ -741,16 +690,18 @@
             mSelf.setSpeechRate(speechRate);
         }
 
-        // TODO: Fix comment about language
         /**
          * Sets the speech rate for the TTS. Note that this will only have an
          * effect on synthesized speech; it will not affect pre-recorded speech.
          *
          * @param language
-         *            The language to be used. The languages are specified by
-         *            their IETF language tags as defined by BCP 47. This is the
-         *            same standard used for the lang attribute in HTML. See:
-         *            http://en.wikipedia.org/wiki/IETF_language_tag
+         *            Language values are based on the Android conventions for
+         *            localization as described in the Android platform
+         *            documentation on internationalization. This implies that
+         *            language data is specified in the format xx-rYY, where xx
+         *            is a two letter ISO 639-1 language code in lowercase and
+         *            rYY is a two letter ISO 3166-1-alpha-2 language code in
+         *            uppercase preceded by a lowercase "r".
          */
         public void setLanguage(String language) {
             mSelf.setLanguage(language);
diff --git a/vpn/java/android/net/vpn/IVpnService.aidl b/vpn/java/android/net/vpn/IVpnService.aidl
new file mode 100644
index 0000000..0e658df
--- /dev/null
+++ b/vpn/java/android/net/vpn/IVpnService.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007, 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.net.vpn.VpnProfile;
+
+/**
+ * Interface to access a VPN service.
+ * {@hide}
+ */
+interface IVpnService {
+    /**
+     * Sets up the VPN connection.
+     * @param profile the profile object
+     * @param username the username for authentication
+     * @param password the corresponding password for authentication
+     */
+    boolean connect(in VpnProfile profile, String username, String password);
+
+    /**
+     * Tears down the VPN connection.
+     */
+    void disconnect();
+
+    /**
+     * Makes the service broadcast the connectivity state.
+     */
+    void checkStatus(in VpnProfile profile);
+}
diff --git a/vpn/java/android/net/vpn/L2tpIpsecProfile.java b/vpn/java/android/net/vpn/L2tpIpsecProfile.java
new file mode 100644
index 0000000..a7e53d1
--- /dev/null
+++ b/vpn/java/android/net/vpn/L2tpIpsecProfile.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007, 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.os.Parcel;
+
+/**
+ * The profile for L2TP-over-IPSec type of VPN.
+ * {@hide}
+ */
+public class L2tpIpsecProfile extends SingleServerProfile {
+    private String mUserCertificate;
+    private String mCaCertificate;
+    private String mUserkey;
+
+    @Override
+    public VpnType getType() {
+        return VpnType.L2TP_IPSEC;
+    }
+
+    public void setCaCertificate(String name) {
+        mCaCertificate = name;
+    }
+
+    public String getCaCertificate() {
+        return mCaCertificate;
+    }
+
+    public void setUserCertificate(String name) {
+        mUserCertificate = name;
+    }
+
+    public String getUserCertificate() {
+        return mUserCertificate;
+    }
+
+    public void setUserkey(String name) {
+        mUserkey = name;
+    }
+
+    public String getUserkey() {
+        return mUserkey;
+    }
+
+    @Override
+    protected void readFromParcel(Parcel in) {
+        super.readFromParcel(in);
+        mCaCertificate = in.readString();
+        mUserCertificate = in.readString();
+        mUserkey = in.readString();
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        super.writeToParcel(parcel, flags);
+        parcel.writeString(mCaCertificate);
+        parcel.writeString(mUserCertificate);
+        parcel.writeString(mUserkey);
+    }
+}
diff --git a/vpn/java/android/net/vpn/L2tpProfile.java b/vpn/java/android/net/vpn/L2tpProfile.java
new file mode 100644
index 0000000..ca4ef75
--- /dev/null
+++ b/vpn/java/android/net/vpn/L2tpProfile.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2007, 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;
+
+/**
+ * The profile for L2TP type of VPN.
+ * {@hide}
+ */
+public class L2tpProfile extends SingleServerProfile {
+    @Override
+    public VpnType getType() {
+        return VpnType.L2TP;
+    }
+}
diff --git a/vpn/java/android/net/vpn/SingleServerProfile.java b/vpn/java/android/net/vpn/SingleServerProfile.java
new file mode 100644
index 0000000..59b5a7b
--- /dev/null
+++ b/vpn/java/android/net/vpn/SingleServerProfile.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007, 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.os.Parcel;
+
+/**
+ * The profile for single-server type of VPN.
+ * {@hide}
+ */
+public abstract class SingleServerProfile extends VpnProfile {
+    private String mServerName;
+
+    public void setServerName(String name) {
+        mServerName = name;
+    }
+
+    public String getServerName() {
+        return mServerName;
+    }
+
+    @Override
+    protected void readFromParcel(Parcel in) {
+        super.readFromParcel(in);
+        mServerName = in.readString();
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        super.writeToParcel(parcel, flags);
+        parcel.writeString(mServerName);
+    }
+}
diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java
new file mode 100644
index 0000000..6c6e52a
--- /dev/null
+++ b/vpn/java/android/net/vpn/VpnManager.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2007, 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.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.util.Log;
+
+/**
+ * The class provides interface to manage all VPN-related tasks, including:
+ * <ul>
+ * <li>The list of supported VPN types.
+ * <li>API's to start/stop the service of a particular type.
+ * <li>API's to start the settings activity.
+ * <li>API's to create a profile.
+ * <li>API's to register/unregister a connectivity receiver and the keys to
+ *      access the fields in a connectivity broadcast event.
+ * </ul>
+ * {@hide}
+ */
+public class VpnManager {
+    // Action for broadcasting a connectivity state.
+    private static final String ACTION_VPN_CONNECTIVITY = "vpn.connectivity";
+    /** Key to the profile name of a connectivity broadcast event. */
+    public static final String BROADCAST_PROFILE_NAME = "profile_name";
+    /** Key to the connectivity state of a connectivity broadcast event. */
+    public static final String BROADCAST_CONNECTION_STATE = "connection_state";
+
+    public static final String PROFILES_PATH = "/data/misc/vpn/profiles";
+
+    private static final String PACKAGE_PREFIX =
+            VpnManager.class.getPackage().getName() + ".";
+
+    /** Action to start the activity of installing a new profile. */
+    public static final String ACTION_VPN_INSTALL_PROFILE =
+            PACKAGE_PREFIX + "INSTALL_PROFILE";
+    /**
+     * Key to the installation path in the intent of installing a new profile.
+     */
+    public static final String KEY_INSTALLATION_PATH = "install_path";
+    public static final String DEFAULT_INSTALLATION_PATH =
+            "/data/local/tmp/vpn";
+
+    // Action to start VPN installation monitor service
+    private static final String SERVICE_VPN_INSTALL_MONITOR =
+            PACKAGE_PREFIX + "INSTALLATION_MONITOR";
+
+    // Action to start VPN settings
+    private static final String ACTION_VPN_SETTINGS = PACKAGE_PREFIX + "SETTINGS";
+
+    private static final String TAG = VpnManager.class.getSimpleName();
+
+    /**
+     * Returns all supported VPN types.
+     */
+    public static VpnType[] getSupportedVpnTypes() {
+        return VpnType.values();
+    }
+
+    private Context mContext;
+
+    /**
+     * Creates a manager object with the specified context.
+     */
+    public VpnManager(Context c) {
+        mContext = c;
+    }
+
+    /**
+     * Creates a VPN profile of the specified type.
+     *
+     * @param type the VPN type
+     * @return the profile object
+     */
+    public VpnProfile createVpnProfile(VpnType type) {
+        return createVpnProfile(type, false);
+    }
+
+    /**
+     * Creates a VPN profile of the specified type.
+     *
+     * @param type the VPN type
+     * @param customized true if the profile is custom made
+     * @return the profile object
+     */
+    public VpnProfile createVpnProfile(VpnType type, boolean customized) {
+        try {
+            VpnProfile p = (VpnProfile) type.getProfileClass().newInstance();
+            p.setCustomized(customized);
+            return p;
+        } catch (InstantiationException e) {
+            return null;
+        } catch (IllegalAccessException e) {
+            return null;
+        }
+    }
+
+    private String getServiceActionName(VpnType type) {
+        return PACKAGE_PREFIX + type.getServiceName();
+    }
+
+    /**
+     * Starts the VPN service of the specified type.
+     */
+    public boolean startService(VpnType type) {
+        String serviceAction = getServiceActionName(type);
+        if (serviceAction != null) {
+            Log.i(TAG, "start service: " + serviceAction);
+            mContext.startService(new Intent(serviceAction));
+            return true;
+        } else {
+            Log.w(TAG, "unknown vpn type to start service for: " + type);
+            return false;
+        }
+    }
+
+    /**
+     * Stops the VPN service of the specified type.
+     */
+    public void stopService(VpnType type) {
+        String serviceAction = getServiceActionName(type);
+        if (serviceAction != null) {
+            Log.i(TAG, "stop service for: " + type);
+            mContext.stopService(new Intent(serviceAction));
+        } else {
+            Log.w(TAG, "unknown vpn type to stop service for: " + type);
+        }
+    }
+
+    /**
+     * Binds the specified ServiceConnection with the VPN service of the
+     * specified type.
+     */
+    public boolean bindService(VpnType type, ServiceConnection c) {
+        String serviceAction = getServiceActionName(type);
+        if (serviceAction == null) {
+            Log.w(TAG, "unknown vpn type to bind service for: " + type);
+            return false;
+        }
+        if (!mContext.bindService(new Intent(serviceAction), c, 0)) {
+            Log.w(TAG, "failed to connect to service: " + type);
+            return false;
+        } else {
+            Log.v(TAG, "succeeded to connect to service: " + type);
+            return true;
+        }
+    }
+
+    /** Broadcasts the connectivity state of the specified profile. */
+    public void broadcastConnectivity(String profileName, VpnState s) {
+        Intent intent = new Intent(ACTION_VPN_CONNECTIVITY);
+        intent.putExtra(BROADCAST_PROFILE_NAME, profileName);
+        intent.putExtra(BROADCAST_CONNECTION_STATE, s);
+        mContext.sendBroadcast(intent);
+    }
+
+    public void registerConnectivityReceiver(BroadcastReceiver r) {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(VpnManager.ACTION_VPN_CONNECTIVITY);
+        mContext.registerReceiver(r, filter);
+    }
+
+    public void unregisterConnectivityReceiver(BroadcastReceiver r) {
+        mContext.unregisterReceiver(r);
+    }
+
+    /**
+     * Starts the installation monitor service.
+     * The service monitors the default installtion path (under /data/local/tmp)
+     * and automatically starts the activity to create a new profile when new
+     * configuration files appear in that path.
+     */
+    public void startInstallationMonitorService() {
+        mContext.startService(new Intent(SERVICE_VPN_INSTALL_MONITOR));
+    }
+
+    /** Stops the installation monitor service. */
+    public void stopInstallationMonitorService() {
+        mContext.stopService(new Intent(SERVICE_VPN_INSTALL_MONITOR));
+    }
+
+    /** Starts the VPN settings activity. */
+    public void startSettingsActivity() {
+        Intent intent = new Intent(ACTION_VPN_SETTINGS);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+    }
+
+    /**
+     * Starts the activity to install a customized profile.
+     * @param installPath the path where all the configuration files are located
+     */
+    public void startInstallProfileActivity(String installPath) {
+        Intent intent = new Intent(ACTION_VPN_INSTALL_PROFILE);
+        intent.putExtra(KEY_INSTALLATION_PATH, installPath);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+    }
+}
diff --git a/vpn/java/android/net/vpn/VpnProfile.aidl b/vpn/java/android/net/vpn/VpnProfile.aidl
new file mode 100644
index 0000000..ad34bfc
--- /dev/null
+++ b/vpn/java/android/net/vpn/VpnProfile.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2007, 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;
+
+parcelable VpnProfile;
diff --git a/vpn/java/android/net/vpn/VpnProfile.java b/vpn/java/android/net/vpn/VpnProfile.java
new file mode 100644
index 0000000..7cf2608
--- /dev/null
+++ b/vpn/java/android/net/vpn/VpnProfile.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2007, 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.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * A VPN profile.
+ * {@hide}
+ */
+public abstract class VpnProfile implements Parcelable {
+    private String mName; // unique display name
+    private String mId; // unique identifier
+    private String mDomainSuffices; // space separated list
+    private String mRouteList; // space separated list
+    private boolean mIsCustomized;
+    private transient VpnState mState = VpnState.IDLE;
+
+    /** Sets a user-friendly name for this profile. */
+    public void setName(String name) {
+        mName = name;
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * Sets an ID for this profile.  The caller should make sure the
+     * uniqueness of the ID.
+     */
+    public void setId(String id) {
+        mId = id;
+    }
+
+    public String getId() {
+        return mId;
+    }
+
+    /**
+     * Sets the domain suffices for DNS resolution.
+     *
+     * @param entries a comma-separated list of domain suffices
+     */
+    public void setDomainSuffices(String entries) {
+        mDomainSuffices = entries;
+    }
+
+    public String getDomainSuffices() {
+        return mDomainSuffices;
+    }
+
+    /**
+     * Sets the routing info for this VPN connection.
+     *
+     * @param entries a comma-separated list of routes; each entry is in the
+     *      format of "(network address)/(network mask)"
+     */
+    public void setRouteList(String entries) {
+        mRouteList = entries;
+    }
+
+    public String getRouteList() {
+        return mRouteList;
+    }
+
+    public void setState(VpnState state) {
+        mState = state;
+    }
+
+    public VpnState getState() {
+        return ((mState == null) ? VpnState.IDLE : mState);
+    }
+
+    public boolean isIdle() {
+        return (mState == VpnState.IDLE);
+    }
+
+    /**
+     * Returns whether this profile is custom made (as opposed to being
+     * created by provided user interface).
+     */
+    public boolean isCustomized() {
+        return mIsCustomized;
+    }
+
+    /**
+     * Returns the VPN type of the profile.
+     */
+    public abstract VpnType getType();
+
+    void setCustomized(boolean customized) {
+        mIsCustomized = customized;
+    }
+
+    protected void readFromParcel(Parcel in) {
+        mName = in.readString();
+        mId = in.readString();
+        mDomainSuffices = in.readString();
+        mRouteList = in.readString();
+    }
+
+    public static final Parcelable.Creator<VpnProfile> CREATOR =
+            new Parcelable.Creator<VpnProfile>() {
+                public VpnProfile createFromParcel(Parcel in) {
+                    VpnType type = Enum.valueOf(VpnType.class, in.readString());
+                    boolean customized = in.readInt() > 0;
+                    VpnProfile p = new VpnManager(null).createVpnProfile(type,
+                            customized);
+                    if (p == null) return null;
+                    p.readFromParcel(in);
+                    return p;
+                }
+
+                public VpnProfile[] newArray(int size) {
+                    return new VpnProfile[size];
+                }
+            };
+
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeString(getType().toString());
+        parcel.writeInt(mIsCustomized ? 1 : 0);
+        parcel.writeString(mName);
+        parcel.writeString(mId);
+        parcel.writeString(mDomainSuffices);
+        parcel.writeString(mRouteList);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/vpn/java/android/net/vpn/VpnState.java b/vpn/java/android/net/vpn/VpnState.java
new file mode 100644
index 0000000..78117e0
--- /dev/null
+++ b/vpn/java/android/net/vpn/VpnState.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2007, 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;
+
+/**
+ * Enumeration of all VPN states.
+ *
+ * A normal VPN connection lifetime starts in {@link IDLE}. When a new
+ * connection is about to be set up, it goes to {@link CONNECTING} and then
+ * {@link CONNECTED} if successful; back to {@link IDLE} if failed.
+ * When the connection is about to be torn down, it goes to
+ * {@link DISCONNECTING} and then {@link IDLE}.
+ * {@hide}
+ */
+public enum VpnState {
+    CONNECTING, DISCONNECTING, CONNECTED, IDLE
+}
diff --git a/vpn/java/android/net/vpn/VpnType.java b/vpn/java/android/net/vpn/VpnType.java
new file mode 100644
index 0000000..dcf2078
--- /dev/null
+++ b/vpn/java/android/net/vpn/VpnType.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007, 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;
+
+/**
+ * Enumeration of all supported VPN types.
+ * {@hide}
+ */
+public enum VpnType {
+    L2TP_IPSEC("L2TP/IPSec", L2tpIpsecProfile.class),
+    L2TP("L2TP", L2tpProfile.class);
+
+    private String mDisplayName;
+    private Class<? extends VpnProfile> mClass;
+
+    VpnType(String displayName, Class<? extends VpnProfile> klass) {
+        mDisplayName = displayName;
+        mClass = klass;
+    }
+
+    public String getDisplayName() {
+        return mDisplayName;
+    }
+
+    public Class<? extends VpnProfile> getProfileClass() {
+        return mClass;
+    }
+
+    public String getServiceName() {
+        return this.toString();
+    }
+}