am 62437b99: Windows SDK: copy SDK Setup.exe at root of SDK.

Merge commit '62437b9984649c80aa3a7d93750efdc5ff206d07' into eclair-mr2

* commit '62437b9984649c80aa3a7d93750efdc5ff206d07':
  Windows SDK: copy SDK Setup.exe at root of SDK.
diff --git a/apps/Development/AndroidManifest.xml b/apps/Development/AndroidManifest.xml
index 0bdd26e..1fff629 100644
--- a/apps/Development/AndroidManifest.xml
+++ b/apps/Development/AndroidManifest.xml
@@ -34,6 +34,11 @@
     <uses-permission android:name="android.permission.GET_ACCOUNTS" />
     <uses-permission android:name="android.permission.USE_CREDENTIALS" />
     <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.DEVICE_POWER" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
 
     <application android:label="Dev Tools"
             android:icon="@drawable/ic_launcher_devtools">
@@ -88,6 +93,12 @@
         </activity>
         <activity android:name="Details">
         </activity>
+        <activity android:name="Connectivity" android:label="Connectivity" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.TEST" />
+            </intent-filter>
+        </activity>
         <activity android:name="DevelopmentSettings" android:label="Development Settings" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/apps/Development/res/layout/connectivity.xml b/apps/Development/res/layout/connectivity.xml
new file mode 100644
index 0000000..b603496
--- /dev/null
+++ b/apps/Development/res/layout/connectivity.xml
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/Settings/assets/res/any/layout/keyboard_version.xml
+**
+** Copyright 2006, 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.
+*/
+-->
+<LinearLayout
+  xmlns:android="http://schemas.android.com/apk/res/android"
+  android:orientation="vertical"
+  android:layout_width="fill_parent"
+  android:layout_height="fill_parent">
+
+    <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content">
+        <Button android:id="@+id/enableWifi"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/enable_wifi" />
+        <Button android:id="@+id/disableWifi"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/disable_wifi" />
+    </LinearLayout>
+
+    <!-- divider line -->
+    <View android:background="#FFFFFFFF"
+      android:layout_width="fill_parent"
+      android:layout_height="3dip" />
+
+    <LinearLayout
+      android:orientation="horizontal"
+      android:paddingTop="4dip"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content">
+        <Button android:id="@+id/startDelayedCycle"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/start_toggling" />
+        <Button android:id="@+id/stopDelayedCycle"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/stop_toggling" />
+    </LinearLayout>
+
+    <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content">
+        <TextView
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/wifi_on_duration" />
+        <EditText android:id="@+id/dc_wifi_on_duration"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:minEms="15" />
+    </LinearLayout>
+
+    <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content">
+        <TextView
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/wifi_off_duration" />
+        <EditText android:id="@+id/dc_wifi_off_duration"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:minEms="15"/>
+    </LinearLayout>
+
+    <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content">
+        <TextView
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/wifi_cycles_done" />
+        <TextView android:id="@+id/dc_wifi_cycles_done"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:minEms="15"/>
+    </LinearLayout>
+
+    <!-- divider line -->
+    <View android:background="#FFFFFFFF"
+      android:layout_width="fill_parent"
+      android:layout_height="3dip" />
+
+    <LinearLayout
+      android:orientation="horizontal"
+      android:paddingTop="4dip"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content">
+        <Button android:id="@+id/startScreenCycle"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/start_screen_toggling" />
+        <Button android:id="@+id/stopScreenCycle"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/stop_screen_toggling" />
+    </LinearLayout>
+
+    <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content">
+        <TextView
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/wifi_on_duration" />
+        <EditText android:id="@+id/sc_wifi_on_duration"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:minEms="15" />
+    </LinearLayout>
+
+    <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content">
+        <TextView
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/wifi_off_duration" />
+        <EditText android:id="@+id/sc_wifi_off_duration"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:minEms="15"/>
+    </LinearLayout>
+
+    <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content">
+        <TextView
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/wifi_cycles_done" />
+        <TextView android:id="@+id/sc_wifi_cycles_done"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:minEms="15"/>
+    </LinearLayout>
+
+    <!-- divider line -->
+    <View android:background="#FFFFFFFF"
+      android:layout_width="fill_parent"
+      android:layout_height="3dip" />
+
+    <LinearLayout
+      android:orientation="horizontal"
+      android:paddingTop="4dip"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content">
+        <Button android:id="@+id/start_mms"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/start_mms" />
+        <Button android:id="@+id/stop_mms"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/stop_mms" />
+    </LinearLayout>
+    <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content">
+        <Button android:id="@+id/start_hipri"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/start_hipri" />
+        <Button android:id="@+id/stop_hipri"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/stop_hipri" />
+    </LinearLayout>
+    <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="fill_parent"
+      android:layout_height="wrap_content">
+        <Button android:id="@+id/crash"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/crash" />
+    </LinearLayout>
+</LinearLayout>
+
diff --git a/apps/Development/res/values/strings.xml b/apps/Development/res/values/strings.xml
index ad70fbe..9eaec68 100644
--- a/apps/Development/res/values/strings.xml
+++ b/apps/Development/res/values/strings.xml
@@ -21,6 +21,23 @@
     <string name="menu_upload_exceptions">Upload Exceptions</string>
     <string name="menu_clear_exceptions">Clear Exceptions</string>
 
+    <string name="enable_wifi">Enable Wifi</string>
+    <string name="disable_wifi">Disable Wifi</string>
+    <string name="wifi_on_duration">Wifi on (ms): </string>
+    <string name="wifi_off_duration">Wifi off (ms): </string>
+    <string name="wifi_cycles_done">Cycles done: </string>
+    <string name="start_toggling">Start Wifi Toggle</string>
+    <string name="stop_toggling">Stop Wifi Toggle</string>
+    <string name="start_screen_toggling">Start Screen Toggle</string>
+    <string name="stop_screen_toggling">Stop Screen Toggle</string>
+
+    <string name="start_mms">Start MMS</string>
+    <string name="stop_mms">Stop MMS</string>
+    <string name="start_hipri">Start HiPri</string>
+    <string name="stop_hipri">Stop HiPri</string>
+    <string name="crash">CRASH</string>
+
+
         <string name="device_info_default">unknown</string>
         <string name="device_info_uptime">Uptime</string>
         <string name="device_info_awaketime">Awake Time</string>
diff --git a/apps/Development/src/com/android/development/Connectivity.java b/apps/Development/src/com/android/development/Connectivity.java
new file mode 100644
index 0000000..59157bf
--- /dev/null
+++ b/apps/Development/src/com/android/development/Connectivity.java
@@ -0,0 +1,351 @@
+/* //device/apps/Settings/src/com/android/settings/Keyguard.java
+**
+** Copyright 2006, 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 com.android.development;
+
+import android.app.Activity;
+import android.app.ActivityManagerNative;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiManager;
+import android.os.RemoteException;
+import android.os.Handler;
+import android.os.Message;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.os.ServiceManager;
+import android.os.ServiceManagerNative;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.IWindowManager;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.widget.AdapterView.OnItemSelectedListener;
+
+import com.android.internal.telephony.Phone;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.Map;
+
+public class Connectivity extends Activity {
+    private static final String TAG = "Connectivity";
+
+    private static final int EVENT_TOGGLE_WIFI = 1;
+    private static final int EVENT_TOGGLE_SCREEN = 2;
+
+    private Button mEnableWifiButton;
+    private Button mDisableWifiButton;
+
+    private Button mStartDelayedCycleButton;
+    private Button mStopDelayedCycleButton;
+    private EditText mDCOnDurationEdit;
+    private EditText mDCOffDurationEdit;
+    private TextView mDCCycleCountView;
+    private long mDCOnDuration = 120000;
+    private long mDCOffDuration = 120000;
+    private int mDCCycleCount = 0;
+
+    private Button mStartScreenCycleButton;
+    private Button mStopScreenCycleButton;
+    private EditText mSCOnDurationEdit;
+    private EditText mSCOffDurationEdit;
+    private TextView mSCCycleCountView;
+    private long mSCOnDuration = 120000;
+    private long mSCOffDuration = 12000;
+    private int mSCCycleCount = 0;
+
+    private Button mStartMmsButton;
+    private Button mStopMmsButton;
+    private Button mStartHiPriButton;
+    private Button mStopHiPriButton;
+    private Button mCrashButton;
+
+    private boolean mDelayedCycleStarted = false;
+
+    private WifiManager mWm;
+    private PowerManager mPm;
+    private ConnectivityManager mCm;
+
+    private WakeLock mWakeLock = null;
+    private WakeLock mScreenonWakeLock = null;
+
+    private boolean mScreenOffToggleRunning = false;
+    private boolean mScreenOff = false;
+
+    private static final String CONNECTIVITY_TEST_ALARM =
+            "com.android.development.CONNECTIVITY_TEST_ALARM";
+    private static final String TEST_ALARM_EXTRA = "CONNECTIVITY_TEST_EXTRA";
+    private static final String TEST_ALARM_ON_EXTRA = "CONNECTIVITY_TEST_ON_EXTRA";
+    private static final String TEST_ALARM_OFF_EXTRA = "CONNECTIVITY_TEST_OFF_EXTRA";
+    private static final String TEST_ALARM_CYCLE_EXTRA = "CONNECTIVITY_TEST_CYCLE_EXTRA";
+    private static final String SCREEN_ON = "SCREEN_ON";
+    private static final String SCREEN_OFF = "SCREEN_OFF";
+    public BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(CONNECTIVITY_TEST_ALARM)) {
+                String extra = (String)intent.getExtra(TEST_ALARM_EXTRA);
+                PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+                Long on = new Long(120000);
+                Long off = new Long(120000);
+                int cycle = 0;
+                try {
+                    on = Long.parseLong((String)intent.getExtra(TEST_ALARM_ON_EXTRA));
+                    off = Long.parseLong((String)intent.getExtra(TEST_ALARM_OFF_EXTRA));
+                    cycle = Integer.parseInt((String)intent.getExtra(TEST_ALARM_CYCLE_EXTRA));
+                } catch (Exception e) {}
+
+                if (extra.equals(SCREEN_ON)) {
+                    mScreenonWakeLock = mPm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
+                            PowerManager.ACQUIRE_CAUSES_WAKEUP,
+                            "ConnectivityTest");
+                    mScreenonWakeLock.acquire();
+
+                    mSCCycleCount = cycle+1;
+                    mSCOnDuration = on;
+                    mSCOffDuration = off;
+                    mSCCycleCountView.setText(Integer.toString(mSCCycleCount));
+
+                    scheduleAlarm(mSCOnDuration, SCREEN_OFF);
+                } else if (extra.equals(SCREEN_OFF)) {
+
+                    mSCCycleCount = cycle;
+                    mSCOnDuration = on;
+                    mSCOffDuration = off;
+
+                    mScreenonWakeLock.release();
+                    mScreenonWakeLock = null;
+                    scheduleAlarm(mSCOffDuration, SCREEN_ON);
+                    pm.goToSleep(SystemClock.uptimeMillis());
+                }
+            }
+        }
+    };
+
+    public Handler mHandler2 = new Handler() {
+        public void handleMessage(Message msg) {
+            switch(msg.what) {
+                case EVENT_TOGGLE_WIFI:
+                    Log.e(TAG, "EVENT_TOGGLE_WIFI");
+                    if (mDelayedCycleStarted && mWm != null) {
+                        long delay;
+                        switch (mWm.getWifiState()) {
+                            case WifiManager.WIFI_STATE_ENABLED:
+                            case WifiManager.WIFI_STATE_ENABLING:
+                                mWm.setWifiEnabled(false);
+                                delay = mDCOffDuration;
+                                break;
+                            default:
+                                mWm.setWifiEnabled(true);
+                                delay = mDCOnDuration;
+                                mDCCycleCount++;
+                                mDCCycleCountView.setText(Integer.toString(mDCCycleCount));
+                        }
+                        sendMessageDelayed(obtainMessage(EVENT_TOGGLE_WIFI),
+                                delay);
+                    }
+                    break;
+            }
+        }
+    };
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        setContentView(R.layout.connectivity);
+
+        mWm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
+        mPm = (PowerManager)getSystemService(Context.POWER_SERVICE);
+        mCm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+
+        mEnableWifiButton = (Button)findViewById(R.id.enableWifi);
+        mEnableWifiButton.setOnClickListener(mEnableWifiClicked);
+        mDisableWifiButton = (Button)findViewById(R.id.disableWifi);
+        mDisableWifiButton.setOnClickListener(mDisableWifiClicked);
+
+        mStartDelayedCycleButton = (Button)findViewById(R.id.startDelayedCycle);
+        mStartDelayedCycleButton.setOnClickListener(mStartDelayedCycleClicked);
+        mStopDelayedCycleButton = (Button)findViewById(R.id.stopDelayedCycle);
+        mStopDelayedCycleButton.setOnClickListener(mStopDelayedCycleClicked);
+        mDCOnDurationEdit = (EditText)findViewById(R.id.dc_wifi_on_duration);
+        mDCOnDurationEdit.setText(Long.toString(mDCOnDuration));
+        mDCOffDurationEdit = (EditText)findViewById(R.id.dc_wifi_off_duration);
+        mDCOffDurationEdit.setText(Long.toString(mDCOffDuration));
+        mDCCycleCountView = (TextView)findViewById(R.id.dc_wifi_cycles_done);
+        mDCCycleCountView.setText(Integer.toString(mDCCycleCount));
+
+        mStartScreenCycleButton = (Button)findViewById(R.id.startScreenCycle);
+        mStartScreenCycleButton.setOnClickListener(mStartScreenCycleClicked);
+        mStopScreenCycleButton = (Button)findViewById(R.id.stopScreenCycle);
+        mStopScreenCycleButton.setOnClickListener(mStopScreenCycleClicked);
+        mSCOnDurationEdit = (EditText)findViewById(R.id.sc_wifi_on_duration);
+        mSCOnDurationEdit.setText(Long.toString(mSCOnDuration));
+        mSCOffDurationEdit = (EditText)findViewById(R.id.sc_wifi_off_duration);
+        mSCOffDurationEdit.setText(Long.toString(mSCOffDuration));
+        mSCCycleCountView = (TextView)findViewById(R.id.sc_wifi_cycles_done);
+        mSCCycleCountView.setText(Integer.toString(mSCCycleCount));
+
+        mStartMmsButton = (Button)findViewById(R.id.start_mms);
+        mStartMmsButton.setOnClickListener(mStartMmsClicked);
+        mStopMmsButton = (Button)findViewById(R.id.stop_mms);
+        mStopMmsButton.setOnClickListener(mStopMmsClicked);
+        mStartHiPriButton = (Button)findViewById(R.id.start_hipri);
+        mStartHiPriButton.setOnClickListener(mStartHiPriClicked);
+        mStopHiPriButton = (Button)findViewById(R.id.stop_hipri);
+        mStopHiPriButton.setOnClickListener(mStopHiPriClicked);
+        mCrashButton = (Button)findViewById(R.id.crash);
+        mCrashButton.setOnClickListener(mCrashClicked);
+
+        registerReceiver(mReceiver, new IntentFilter(CONNECTIVITY_TEST_ALARM));
+    }
+
+
+
+    @Override
+    public void onResume() {
+        super.onResume();
+    }
+
+    private View.OnClickListener mStartDelayedCycleClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+            if (!mDelayedCycleStarted) {
+                mDelayedCycleStarted = true;
+                try {
+                    mDCOnDuration = Long.parseLong(mDCOnDurationEdit.getText().toString());
+                    mDCOffDuration = Long.parseLong(mDCOffDurationEdit.getText().toString());
+                } catch (Exception e) { };
+                mDCCycleCount = 0;
+
+                mWakeLock = mPm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "ConnectivityTest");
+                mWakeLock.acquire();
+                mHandler2.sendMessage(mHandler2.obtainMessage(EVENT_TOGGLE_WIFI));
+            }
+        }
+    };
+    private View.OnClickListener mStopDelayedCycleClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+            if (mDelayedCycleStarted) {
+                mDelayedCycleStarted = false;
+                mWakeLock.release();
+                mWakeLock = null;
+                if(mHandler2.hasMessages(EVENT_TOGGLE_WIFI)) {
+                    mHandler2.removeMessages(EVENT_TOGGLE_WIFI);
+                }
+            }
+        }
+    };
+
+    private View.OnClickListener mEnableWifiClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+            mWm.setWifiEnabled(true);
+        }
+    };
+    private View.OnClickListener mDisableWifiClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+            mWm.setWifiEnabled(false);
+        }
+    };
+
+    private View.OnClickListener mStartScreenCycleClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+
+            try {
+                mSCOnDuration = Long.parseLong(mSCOnDurationEdit.getText().toString());
+                mSCOffDuration = Long.parseLong(mSCOffDurationEdit.getText().toString());
+            } catch (Exception e) { };
+            mSCCycleCount = 0;
+
+            mScreenonWakeLock = mPm.newWakeLock(PowerManager.FULL_WAKE_LOCK,
+                    "ConnectivityTest");
+            mScreenonWakeLock.acquire();
+
+            scheduleAlarm(10, SCREEN_OFF);
+        }
+    };
+
+    private void scheduleAlarm(long delayMs, String eventType) {
+        AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
+        Intent i = new Intent(CONNECTIVITY_TEST_ALARM);
+
+        i.putExtra(TEST_ALARM_EXTRA, eventType);
+        i.putExtra(TEST_ALARM_ON_EXTRA, Long.toString(mSCOnDuration));
+        i.putExtra(TEST_ALARM_OFF_EXTRA, Long.toString(mSCOffDuration));
+        i.putExtra(TEST_ALARM_CYCLE_EXTRA, Integer.toString(mSCCycleCount));
+
+        PendingIntent p = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
+
+        am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + delayMs, p);
+    }
+
+    private View.OnClickListener mStopScreenCycleClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+        }
+    };
+
+    private View.OnClickListener mStartMmsClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+            mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_MMS);
+        }
+    };
+
+    private View.OnClickListener mStopMmsClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+            mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_MMS);
+        }
+    };
+
+    private View.OnClickListener mStartHiPriClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+            mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                    Phone.FEATURE_ENABLE_HIPRI);
+        }
+    };
+
+    private View.OnClickListener mStopHiPriClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+            mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                    Phone.FEATURE_ENABLE_HIPRI);
+        }
+    };
+
+    private View.OnClickListener mCrashClicked = new View.OnClickListener() {
+        public void onClick(View v) {
+            ConnectivityManager foo = null;
+            foo.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
+                    Phone.FEATURE_ENABLE_MMS);
+        }
+    };
+}
diff --git a/apps/Term/res/values/strings.xml b/apps/Term/res/values/strings.xml
index e3f8fcf..b5d622b 100644
--- a/apps/Term/res/values/strings.xml
+++ b/apps/Term/res/values/strings.xml
@@ -25,7 +25,7 @@
    <string name="text_preferences">Text</string>
 
    <string name="title_fontsize_preference">Font size</string>
-   <string name="summary_fontsize_preference">Choose character height in pixels.</string>
+   <string name="summary_fontsize_preference">Choose character height in points.</string>
    <string name="dialog_title_fontsize_preference">Font size</string>
 
    <string name="title_color_preference">Colors</string>
diff --git a/apps/Term/src/com/android/term/Term.java b/apps/Term/src/com/android/term/Term.java
index 6041baf..cbf94cf 100644
--- a/apps/Term/src/com/android/term/Term.java
+++ b/apps/Term/src/com/android/term/Term.java
@@ -45,6 +45,7 @@
 import android.os.Message;
 import android.preference.PreferenceManager;
 import android.util.AttributeSet;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.GestureDetector;
 import android.view.KeyEvent;
@@ -158,14 +159,6 @@
         super.onCreate(icicle);
         Log.e(Term.LOG_TAG, "onCreate");
         mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
-        mPrefs.registerOnSharedPreferenceChangeListener(
-                new SharedPreferences.OnSharedPreferenceChangeListener(){
-
-                    public void onSharedPreferenceChanged(
-                            SharedPreferences sharedPreferences, String key) {
-                        readPrefs();
-                        updatePrefs();
-                    }});
         readPrefs();
 
         setContentView(R.layout.term_activity);
@@ -227,7 +220,7 @@
 
     private void sendInitialCommand() {
         String initialCommand = mInitialCommand;
-        if (initialCommand == null) {
+        if (initialCommand == null || initialCommand.equals("")) {
             initialCommand = DEFAULT_INITIAL_COMMAND;
         }
         if (initialCommand.length() > 0) {
@@ -253,7 +246,7 @@
 
     private void createSubprocess(int[] processId) {
         String shell = mShell;
-        if (shell == null) {
+        if (shell == null || shell.equals("")) {
             shell = DEFAULT_SHELL;
         }
         ArrayList<String> args = parse(shell);
@@ -347,7 +340,9 @@
     }
 
     private void updatePrefs() {
-        mEmulatorView.setTextSize(mFontSize);
+        DisplayMetrics metrics = new DisplayMetrics();
+        getWindowManager().getDefaultDisplay().getMetrics(metrics);
+        mEmulatorView.setTextSize((int) (mFontSize * metrics.density));
         setColors();
         mControlKeyCode = CONTROL_KEY_SCHEMES[mControlKeyId];
     }
@@ -369,17 +364,10 @@
     }
 
     @Override
-    public void onPause() {
-        SharedPreferences.Editor e = mPrefs.edit();
-        e.clear();
-        e.putString(FONTSIZE_KEY, Integer.toString(mFontSize));
-        e.putString(COLOR_KEY, Integer.toString(mColorId));
-        e.putString(CONTROLKEY_KEY, Integer.toString(mControlKeyId));
-        e.putString(SHELL_KEY, mShell);
-        e.putString(INITIALCOMMAND_KEY, mInitialCommand);
-        e.commit();
-
-        super.onPause();
+    public void onResume() {
+        super.onResume();
+        readPrefs();
+        updatePrefs();
     }
 
     @Override
diff --git a/samples/ApiDemos/res/drawable-hdpi/robot.png b/samples/ApiDemos/res/drawable-hdpi/robot.png
deleted file mode 100755
index 3e4fd21..0000000
--- a/samples/ApiDemos/res/drawable-hdpi/robot.png
+++ /dev/null
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-mdpi/robot.png b/samples/ApiDemos/res/raw/robot.png
similarity index 100%
rename from samples/ApiDemos/res/drawable-mdpi/robot.png
rename to samples/ApiDemos/res/raw/robot.png
Binary files differ
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/StaticTriangleRenderer.java b/samples/ApiDemos/src/com/example/android/apis/graphics/StaticTriangleRenderer.java
index c492e3f..c7e7e64 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/StaticTriangleRenderer.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/StaticTriangleRenderer.java
@@ -101,7 +101,7 @@
                 GL_REPLACE);
 
         InputStream is = mContext.getResources()
-                .openRawResource(R.drawable.robot);
+                .openRawResource(R.raw.robot);
         Bitmap bitmap;
         try {
             bitmap = BitmapFactory.decodeStream(is);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java
index e5299b3..ede6ef5 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleRenderer.java
@@ -90,7 +90,7 @@
                 GL10.GL_REPLACE);
 
         InputStream is = mContext.getResources()
-                .openRawResource(R.drawable.robot);
+                .openRawResource(R.raw.robot);
         Bitmap bitmap;
         try {
             bitmap = BitmapFactory.decodeStream(is);
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/SpriteTextRenderer.java b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/SpriteTextRenderer.java
index 223300a..e01d6ef 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/SpriteTextRenderer.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/spritetext/SpriteTextRenderer.java
@@ -35,6 +35,7 @@
 import android.opengl.GLU;
 import android.opengl.GLUtils;
 import android.os.SystemClock;
+import android.util.Log;
 
 import com.example.android.apis.R;
 
@@ -96,7 +97,7 @@
                 GL10.GL_REPLACE);
 
         InputStream is = mContext.getResources()
-                .openRawResource(R.drawable.robot);
+                .openRawResource(R.raw.robot);
         Bitmap bitmap;
         try {
             bitmap = BitmapFactory.decodeStream(is);
@@ -172,6 +173,15 @@
         gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                 GL10.GL_REPEAT);
 
+        if (false) {
+            long time = SystemClock.uptimeMillis();
+            if (mLastTime != 0) {
+                long delta = time - mLastTime;
+                Log.w("time", Long.toString(delta));
+            }
+            mLastTime = time;
+        }
+
         long time = SystemClock.uptimeMillis() % 4000L;
         float angle = 0.090f * ((int) time);
 
@@ -266,6 +276,7 @@
     private Projector mProjector;
     private NumericSprite mNumericSprite;
     private float[] mScratch = new float[8];
+    private long mLastTime;
 }
 
 class Triangle {
diff --git a/samples/BrowserPlugin/jni/Android.mk b/samples/BrowserPlugin/jni/Android.mk
index cbd8a15..b93e4a6 100644
--- a/samples/BrowserPlugin/jni/Android.mk
+++ b/samples/BrowserPlugin/jni/Android.mk
@@ -35,6 +35,7 @@
 	background/BackgroundPlugin.cpp \
 	form/FormPlugin.cpp \
 	paint/PaintPlugin.cpp \
+	video/VideoPlugin.cpp \
 	jni-bridge.cpp \
 
 LOCAL_C_INCLUDES += \
@@ -45,6 +46,7 @@
 	$(LOCAL_PATH)/background \
 	$(LOCAL_PATH)/form \
 	$(LOCAL_PATH)/paint \
+	$(LOCAL_PATH)/video \
 	external/webkit/WebCore/bridge \
 	external/webkit/WebCore/plugins \
 	external/webkit/WebCore/platform/android/JavaVM \
diff --git a/samples/BrowserPlugin/jni/PluginObject.cpp b/samples/BrowserPlugin/jni/PluginObject.cpp
index 80f5e7c..7d92f7d 100644
--- a/samples/BrowserPlugin/jni/PluginObject.cpp
+++ b/samples/BrowserPlugin/jni/PluginObject.cpp
@@ -35,6 +35,16 @@
 #include "main.h"
 #include "PluginObject.h"
 
+int SubPlugin::getPluginWidth() {
+    PluginObject *obj = (PluginObject*) inst()->pdata;
+    return obj->window->width;
+}
+
+int SubPlugin::getPluginHeight() {
+    PluginObject *obj = (PluginObject*) inst()->pdata;
+    return obj->window->height;
+}
+
 static void pluginInvalidate(NPObject *obj);
 static bool pluginHasProperty(NPObject *obj, NPIdentifier name);
 static bool pluginHasMethod(NPObject *obj, NPIdentifier name);
diff --git a/samples/BrowserPlugin/jni/PluginObject.h b/samples/BrowserPlugin/jni/PluginObject.h
index 61486d5..21b7707 100644
--- a/samples/BrowserPlugin/jni/PluginObject.h
+++ b/samples/BrowserPlugin/jni/PluginObject.h
@@ -44,6 +44,9 @@
     virtual int16 handleEvent(const ANPEvent* evt) = 0;
     virtual bool supportsDrawingModel(ANPDrawingModel) = 0;
 
+    int getPluginWidth();
+    int getPluginHeight();
+
     NPP inst() const { return m_inst; }
 
 private:
@@ -55,7 +58,7 @@
     SurfaceSubPlugin(NPP inst) : SubPlugin(inst) {}
     virtual ~SurfaceSubPlugin() {}
     virtual bool isFixedSurface() = 0;
-    virtual void surfaceCreated(JNIEnv*, jobject) = 0;
+    virtual void surfaceCreated(jobject) = 0;
     virtual void surfaceChanged(int format, int width, int height) = 0;
     virtual void surfaceDestroyed() = 0;
 };
@@ -67,6 +70,7 @@
     kForm_PluginType       = 4,
     kText_PluginType       = 5,
     kPaint_PluginType      = 6,
+    kVideo_PluginType      = 7,
 };
 typedef uint32_t PluginType;
 
diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
index 2a65b4f..af518a9 100644
--- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
+++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.cpp
@@ -54,7 +54,6 @@
 
     // initialize the drawing surface
     m_surface = NULL;
-    m_vm = NULL;
 
     //initialize bitmap transparency variables
     mFinishedStageOne   = false;
@@ -69,7 +68,9 @@
     test_javascript();
 }
 
-BackgroundPlugin::~BackgroundPlugin() { }
+BackgroundPlugin::~BackgroundPlugin() {
+    surfaceDestroyed();
+}
 
 bool BackgroundPlugin::supportsDrawingModel(ANPDrawingModel model) {
     return (model == kSurface_ANPDrawingModel);
@@ -79,9 +80,8 @@
     return false;
 }
 
-void BackgroundPlugin::surfaceCreated(JNIEnv* env, jobject surface) {
-    env->GetJavaVM(&m_vm);
-    m_surface = env->NewGlobalRef(surface);
+void BackgroundPlugin::surfaceCreated(jobject surface) {
+    m_surface = surface;
 }
 
 void BackgroundPlugin::surfaceChanged(int format, int width, int height) {
@@ -90,7 +90,7 @@
 
 void BackgroundPlugin::surfaceDestroyed() {
     JNIEnv* env = NULL;
-    if (m_surface && m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+    if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
         env->DeleteGlobalRef(m_surface);
         m_surface = NULL;
     }
@@ -119,7 +119,7 @@
     // lock the surface
     ANPBitmap bitmap;
     JNIEnv* env = NULL;
-    if (!m_surface || m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
+    if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
         !gSurfaceI.lock(env, m_surface, &bitmap, NULL)) {
         gLogI.log(inst(), kError_ANPLogType, " ------ %p unable to lock the plugin", inst());
         return;
diff --git a/samples/BrowserPlugin/jni/background/BackgroundPlugin.h b/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
index 3b9c7ba..d370810 100644
--- a/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
+++ b/samples/BrowserPlugin/jni/background/BackgroundPlugin.h
@@ -34,7 +34,7 @@
     virtual ~BackgroundPlugin();
     virtual bool supportsDrawingModel(ANPDrawingModel);
     virtual int16 handleEvent(const ANPEvent* evt);
-    virtual void surfaceCreated(JNIEnv* env, jobject surface);
+    virtual void surfaceCreated(jobject surface);
     virtual void surfaceChanged(int format, int width, int height);
     virtual void surfaceDestroyed();
     virtual bool isFixedSurface();
@@ -55,7 +55,6 @@
     void drawPlugin(int surfaceWidth, int surfaceHeight);
 
     jobject     m_surface;
-    JavaVM*     m_vm;
 
     void test_logging();
     void test_timers();
diff --git a/samples/BrowserPlugin/jni/hello-jni.cpp b/samples/BrowserPlugin/jni/hello-jni.cpp
deleted file mode 100644
index 0789b7e..0000000
--- a/samples/BrowserPlugin/jni/hello-jni.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.
- *
- */
-#include <string.h>
-#include <jni.h>
-#include <JNIHelp.h>
-#include <utils/Log.h>
-
-#define EXPORT __attribute__((visibility("default")))
-
-static jstring stringFromJNI( JNIEnv* env, jobject thiz )
-{
-    return env->NewStringUTF("Hello from JNI !");
-}
-
-/*
- * JNI registration.
- */
-static JNINativeMethod gJavaSamplePluginStubMethods[] = {
-    { "nativeStringFromJNI", "()Ljava/lang/String;", (void*) stringFromJNI },
-};
-
-EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
-
-    JNIEnv* env = NULL;
-
-    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
-        return -1;
-    }
-
-    jniRegisterNativeMethods(env, "com/android/sampleplugin/SamplePluginStub",
-                             gJavaSamplePluginStubMethods, NELEM(gJavaSamplePluginStubMethods));
-
-    return JNI_VERSION_1_4;
-}
diff --git a/samples/BrowserPlugin/jni/jni-bridge.cpp b/samples/BrowserPlugin/jni/jni-bridge.cpp
index 45ecd54..08e7f5a 100644
--- a/samples/BrowserPlugin/jni/jni-bridge.cpp
+++ b/samples/BrowserPlugin/jni/jni-bridge.cpp
@@ -35,12 +35,8 @@
 
 static void surfaceCreated(JNIEnv* env, jobject thiz, jint npp, jobject surface) {
     SurfaceSubPlugin* obj = getPluginObject(npp);
-
-    //TODO why is this VM different from the one in NP_INIT...
-    JavaVM* vm = NULL;
-    env->GetJavaVM(&vm);
-
-    obj->surfaceCreated(env, surface);
+    jobject globalSurface = env->NewGlobalRef(surface);
+    obj->surfaceCreated(globalSurface);
 }
 
 static void surfaceChanged(JNIEnv* env, jobject thiz, jint npp, jint format, jint width, jint height) {
@@ -55,6 +51,16 @@
     }
 }
 
+static jint getSurfaceWidth(JNIEnv* env, jobject thiz, jint npp) {
+    SurfaceSubPlugin* obj = getPluginObject(npp);
+    return obj->getPluginWidth();
+}
+
+static jint getSurfaceHeight(JNIEnv* env, jobject thiz, jint npp) {
+    SurfaceSubPlugin* obj = getPluginObject(npp);
+    return obj->getPluginHeight();
+}
+
 static jboolean isFixedSurface(JNIEnv* env, jobject thiz, jint npp) {
     SurfaceSubPlugin* obj = getPluginObject(npp);
     return obj->isFixedSurface();
@@ -67,6 +73,8 @@
     { "nativeSurfaceCreated", "(ILandroid/view/View;)V", (void*) surfaceCreated },
     { "nativeSurfaceChanged", "(IIII)V", (void*) surfaceChanged },
     { "nativeSurfaceDestroyed", "(I)V", (void*) surfaceDestroyed },
+    { "nativeGetSurfaceWidth", "(I)I", (void*) getSurfaceWidth },
+    { "nativeGetSurfaceHeight", "(I)I", (void*) getSurfaceHeight },
     { "nativeIsFixedSurface", "(I)Z", (void*) isFixedSurface },
 };
 
diff --git a/samples/BrowserPlugin/jni/main.cpp b/samples/BrowserPlugin/jni/main.cpp
index d00091f..6f0ed96 100644
--- a/samples/BrowserPlugin/jni/main.cpp
+++ b/samples/BrowserPlugin/jni/main.cpp
@@ -33,8 +33,11 @@
 #include "BackgroundPlugin.h"
 #include "FormPlugin.h"
 #include "PaintPlugin.h"
+#include "VideoPlugin.h"
 
 NPNetscapeFuncs* browser;
+JavaVM* gVM;
+
 #define EXPORT __attribute__((visibility("default")))
 
 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
@@ -128,6 +131,10 @@
         }
     }
 
+    // store the JavaVM for the plugin
+    JNIEnv* env = (JNIEnv*)java_env;
+    env->GetJavaVM(&gVM);
+
     return NPERR_NO_ERROR;
 }
 
@@ -220,6 +227,10 @@
                 obj->pluginType = kPaint_PluginType;
                 obj->activePlugin = new PaintPlugin(instance);
             }
+            else if (!strcmp(argv[i], "Video")) {
+                obj->pluginType = kVideo_PluginType;
+                obj->activePlugin = new VideoPlugin(instance);
+            }
             gLogI.log(instance, kDebug_ANPLogType, "------ %p PluginType is %d", instance, obj->pluginType);
             break;
         }
diff --git a/samples/BrowserPlugin/jni/main.h b/samples/BrowserPlugin/jni/main.h
index 8ad2cce..5906b0b 100644
--- a/samples/BrowserPlugin/jni/main.h
+++ b/samples/BrowserPlugin/jni/main.h
@@ -30,3 +30,4 @@
 #include "ANPSurface_npapi.h"
 
 extern NPNetscapeFuncs* browser;
+extern JavaVM* gVM;
diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
index 5b00dba..11f00fe 100644
--- a/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
+++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.cpp
@@ -52,7 +52,6 @@
 
     // initialize the drawing surface
     m_surface = NULL;
-    m_vm = NULL;
 
     // initialize the path
     m_touchPath = gPathI.newPath();
@@ -97,7 +96,7 @@
 
     ANPBitmap bitmap;
     JNIEnv* env = NULL;
-    if (!m_surface || m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
+    if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
         !gSurfaceI.lock(env, m_surface, &bitmap, dirtyRect)) {
             return NULL;
         }
@@ -132,7 +131,7 @@
 
 void PaintPlugin::releaseCanvas(ANPCanvas* canvas) {
     JNIEnv* env = NULL;
-    if (m_surface && m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+    if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
         gSurfaceI.unlock(env, m_surface);
     }
     gCanvasI.deleteCanvas(canvas);
@@ -216,9 +215,8 @@
     return true;
 }
 
-void PaintPlugin::surfaceCreated(JNIEnv* env, jobject surface) {
-    env->GetJavaVM(&m_vm);
-    m_surface = env->NewGlobalRef(surface);
+void PaintPlugin::surfaceCreated(jobject surface) {
+    m_surface = surface;
     drawCleanPlugin();
 }
 
@@ -235,7 +233,7 @@
 }
 void PaintPlugin::surfaceDestroyed() {
     JNIEnv* env = NULL;
-    if (m_surface && m_vm->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+    if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
         env->DeleteGlobalRef(m_surface);
         m_surface = NULL;
     }
diff --git a/samples/BrowserPlugin/jni/paint/PaintPlugin.h b/samples/BrowserPlugin/jni/paint/PaintPlugin.h
index 8ff561c..a917ffb 100644
--- a/samples/BrowserPlugin/jni/paint/PaintPlugin.h
+++ b/samples/BrowserPlugin/jni/paint/PaintPlugin.h
@@ -35,7 +35,7 @@
     virtual ~PaintPlugin();
     virtual bool supportsDrawingModel(ANPDrawingModel);
     virtual int16 handleEvent(const ANPEvent* evt);
-    virtual void surfaceCreated(JNIEnv* env, jobject surface);
+    virtual void surfaceCreated(jobject surface);
     virtual void surfaceChanged(int format, int width, int height);
     virtual void surfaceDestroyed();
     virtual bool isFixedSurface();
@@ -55,7 +55,6 @@
     bool        m_isTouchActive;
     bool        m_isTouchCurrentInput;
 
-    JavaVM*     m_vm;
     jobject     m_surface;
     ANPPath*    m_touchPath;
 
diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.cpp b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
new file mode 100644
index 0000000..2609af6
--- /dev/null
+++ b/samples/BrowserPlugin/jni/video/VideoPlugin.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "VideoPlugin.h"
+#include "android_npapi.h"
+
+#include <stdio.h>
+#include <sys/time.h>
+#include <time.h>
+#include <math.h>
+#include <string.h>
+
+extern NPNetscapeFuncs*        browser;
+extern ANPBitmapInterfaceV0    gBitmapI;
+extern ANPCanvasInterfaceV0    gCanvasI;
+extern ANPLogInterfaceV0       gLogI;
+extern ANPPaintInterfaceV0     gPaintI;
+extern ANPSurfaceInterfaceV0   gSurfaceI;
+extern ANPTypefaceInterfaceV0  gTypefaceI;
+extern ANPWindowInterfaceV0  gWindowI;
+
+///////////////////////////////////////////////////////////////////////////////
+
+VideoPlugin::VideoPlugin(NPP inst) : SurfaceSubPlugin(inst) {
+
+    // initialize the drawing surface
+    m_surface = NULL;
+
+    //register for touch events
+    ANPEventFlags flags = kTouch_ANPEventFlag;
+    NPError err = browser->setvalue(inst, kAcceptEvents_ANPSetValue, &flags);
+    if (err != NPERR_NO_ERROR) {
+        gLogI.log(inst, kError_ANPLogType, "Error selecting input events.");
+    }
+}
+
+VideoPlugin::~VideoPlugin() {
+    surfaceDestroyed();
+}
+
+bool VideoPlugin::supportsDrawingModel(ANPDrawingModel model) {
+    return (model == kSurface_ANPDrawingModel);
+}
+
+bool VideoPlugin::isFixedSurface() {
+    return true;
+}
+
+void VideoPlugin::surfaceCreated(jobject surface) {
+    m_surface = surface;
+    drawPlugin();
+}
+
+void VideoPlugin::surfaceChanged(int format, int width, int height) {
+    gLogI.log(inst(), kDebug_ANPLogType, "----%p SurfaceChanged Event: %d",
+              inst(), format);
+    drawPlugin();
+}
+
+void VideoPlugin::surfaceDestroyed() {
+    JNIEnv* env = NULL;
+    if (m_surface && gVM->GetEnv((void**) &env, JNI_VERSION_1_4) == JNI_OK) {
+        env->DeleteGlobalRef(m_surface);
+        m_surface = NULL;
+    }
+}
+
+void VideoPlugin::drawPlugin() {
+
+    ANPBitmap bitmap;
+    JNIEnv* env = NULL;
+    if (!m_surface || gVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK ||
+        !gSurfaceI.lock(env, m_surface, &bitmap, NULL)) {
+            gLogI.log(inst(), kError_ANPLogType, "----%p Unable to Lock Surface", inst());
+            return;
+    }
+
+    ANPCanvas* canvas = gCanvasI.newCanvas(&bitmap);
+
+    // get the plugin's dimensions according to the DOM
+    PluginObject *obj = (PluginObject*) inst()->pdata;
+    const int pW = obj->window->width;
+    const int pH = obj->window->height;
+
+    // compare DOM dimensions to the plugin's surface dimensions
+    if (pW != bitmap.width || pH != bitmap.height)
+        gLogI.log(inst(), kError_ANPLogType,
+                  "----%p Invalid Surface Dimensions (%d,%d):(%d,%d)",
+                  inst(), pW, pH, bitmap.width, bitmap.height);
+
+    // set constants
+    const int fontSize = 16;
+    const int leftMargin = 10;
+
+    gCanvasI.drawColor(canvas, 0xFFCDCDCD);
+
+    ANPPaint* paint = gPaintI.newPaint();
+    gPaintI.setFlags(paint, gPaintI.getFlags(paint) | kAntiAlias_ANPPaintFlag);
+    gPaintI.setColor(paint, 0xFFFF0000);
+    gPaintI.setTextSize(paint, fontSize);
+
+    ANPTypeface* tf = gTypefaceI.createFromName("serif", kItalic_ANPTypefaceStyle);
+    gPaintI.setTypeface(paint, tf);
+    gTypefaceI.unref(tf);
+
+    ANPFontMetrics fm;
+    gPaintI.getFontMetrics(paint, &fm);
+
+    gPaintI.setColor(paint, 0xFF0000FF);
+    const char c[] = "Touch anywhere on the plugin to begin video playback!";
+    gCanvasI.drawText(canvas, c, sizeof(c)-1, leftMargin, -fm.fTop, paint);
+
+    // clean up variables and unlock the surface
+    gPaintI.deletePaint(paint);
+    gCanvasI.deleteCanvas(canvas);
+    gSurfaceI.unlock(env, m_surface);
+}
+
+int16 VideoPlugin::handleEvent(const ANPEvent* evt) {
+    switch (evt->eventType) {
+        case kDraw_ANPEventType:
+            gLogI.log(inst(), kError_ANPLogType, " ------ %p the plugin did not request draw events", inst());
+            break;
+        case kTouch_ANPEventType:
+            if (kDown_ANPTouchAction == evt->data.touch.action) {
+                gLogI.log(inst(), kDebug_ANPLogType, " ------ %p requesting fullscreen mode", inst());
+                gWindowI.requestFullScreen(inst());
+            }
+            return 1;
+        case kKey_ANPEventType:
+            gLogI.log(inst(), kError_ANPLogType, " ------ %p the plugin did not request key events", inst());
+            break;
+        default:
+            break;
+    }
+    return 0;   // unknown or unhandled event
+}
diff --git a/samples/BrowserPlugin/jni/video/VideoPlugin.h b/samples/BrowserPlugin/jni/video/VideoPlugin.h
new file mode 100644
index 0000000..dd6859d
--- /dev/null
+++ b/samples/BrowserPlugin/jni/video/VideoPlugin.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "PluginObject.h"
+
+#ifndef videoPlugin__DEFINED
+#define videoPlugin__DEFINED
+
+class VideoPlugin : public SurfaceSubPlugin {
+public:
+    VideoPlugin(NPP inst);
+    virtual ~VideoPlugin();
+    virtual bool supportsDrawingModel(ANPDrawingModel);
+    virtual int16 handleEvent(const ANPEvent* evt);
+    virtual void surfaceCreated(jobject surface);
+    virtual void surfaceChanged(int format, int width, int height);
+    virtual void surfaceDestroyed();
+    virtual bool isFixedSurface();
+
+private:
+    void drawPlugin();
+
+    jobject     m_surface;
+};
+
+#endif // videoPlugin__DEFINED
diff --git a/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePluginStub.java b/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePluginStub.java
index 3c0a0c7..22b7b44 100644
--- a/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePluginStub.java
+++ b/samples/BrowserPlugin/src/com/android/sampleplugin/SamplePluginStub.java
@@ -63,10 +63,12 @@
             }
             
         });
-        
+
+        // TODO provide way for native plugin code to reset the size
         if (nativeIsFixedSurface(npp)) {
-            //TODO get the fixed dimensions from the plugin 
-            //view.getHolder().setFixedSize(width, height);
+            int width = nativeGetSurfaceWidth(npp);
+            int height = nativeGetSurfaceHeight(npp);
+            view.getHolder().setFixedSize(width, height);
         }
         
         return view;
@@ -114,5 +116,7 @@
     private native void nativeSurfaceCreated(int npp, View surfaceView);
     private native void nativeSurfaceChanged(int npp, int format, int width, int height);
     private native void nativeSurfaceDestroyed(int npp);
+    private native int nativeGetSurfaceWidth(int npp);
+    private native int nativeGetSurfaceHeight(int npp);
     private native boolean nativeIsFixedSurface(int npp);
 }