Merge "Fix isssue 2548710: Native AudioTrack resources never freed." into froyo
diff --git a/api/current.xml b/api/current.xml
index 6477fc4..34a0e00 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -25351,6 +25351,19 @@
 <parameter name="flags" type="int">
 </parameter>
 </method>
+<method name="enableCarMode"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="flags" type="int">
+</parameter>
+</method>
 <method name="getCurrentModeType"
  return="int"
  abstract="false"
@@ -81445,7 +81458,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<method name="onAudioFocusChanged"
+<method name="onAudioFocusChange"
  return="void"
  abstract="true"
  native="false"
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index 0007f58..a76dfb1 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -125,6 +125,22 @@
     public static final int DISABLE_CAR_MODE_GO_HOME = 0x0001;
     
     /**
+     * Force device into car mode, like it had been placed in the car dock.
+     * This will cause the device to switch to the car home UI as part of
+     * the mode switch.
+     * @param flags Must be 0.
+     */
+    public void enableCarMode(int flags) {
+        if (mService != null) {
+            try {
+                mService.enableCarMode();
+            } catch (RemoteException e) {
+                Log.e(TAG, "disableCarMode: RemoteException", e);
+            }
+        }
+    }
+
+    /**
      * Turn off special mode if currently in car mode.
      * @param flags May be 0 or {@link #DISABLE_CAR_MODE_GO_HOME}.
      */
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 7f7d207..2a3f032 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -105,6 +105,7 @@
     
     static final int KEEP_SCREEN_ON_MSG = 1;
     static final int GET_NEW_SURFACE_MSG = 2;
+    static final int UPDATE_WINDOW_MSG = 3;
     
     int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
     
@@ -120,6 +121,9 @@
                 case GET_NEW_SURFACE_MSG: {
                     handleGetNewSurface();
                 } break;
+                case UPDATE_WINDOW_MSG: {
+                    updateWindow(false);
+                } break;
             }
         }
     };
@@ -152,6 +156,9 @@
     int mFormat = -1;
     int mType = -1;
     final Rect mSurfaceFrame = new Rect();
+    int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
+    boolean mUpdateWindowNeeded;
+    boolean mReportDrawNeeded;
     private Translator mTranslator;
     
     public SurfaceView(Context context) {
@@ -369,7 +376,8 @@
                 || mNewSurfaceNeeded;
         final boolean typeChanged = mType != mRequestedType;
         if (force || creating || formatChanged || sizeChanged || visibleChanged
-            || typeChanged || mLeft != mLocation[0] || mTop != mLocation[1]) {
+            || typeChanged || mLeft != mLocation[0] || mTop != mLocation[1]
+            || mUpdateWindowNeeded || mReportDrawNeeded) {
 
             if (localLOGV) Log.i(TAG, "Changes: creating=" + creating
                     + " format=" + formatChanged + " size=" + sizeChanged
@@ -425,28 +433,47 @@
 
                 mNewSurfaceNeeded = false;
                 
-                mSurfaceLock.lock();
-                mDrawingStopped = !visible;
-
-                final int relayoutResult = mSession.relayout(
-                    mWindow, mLayout, mWidth, mHeight,
-                        visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
-                        mVisibleInsets, mConfiguration, mSurface);
-
-                if (localLOGV) Log.i(TAG, "New surface: " + mSurface
-                        + ", vis=" + visible + ", frame=" + mWinFrame);
+                boolean realSizeChanged;
+                boolean reportDrawNeeded;
                 
-                mSurfaceFrame.left = 0;
-                mSurfaceFrame.top = 0;
-                if (mTranslator == null) {
-                    mSurfaceFrame.right = mWinFrame.width();
-                    mSurfaceFrame.bottom = mWinFrame.height();
-                } else {
-                    float appInvertedScale = mTranslator.applicationInvertedScale;
-                    mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f);
-                    mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f);
+                mSurfaceLock.lock();
+                try {
+                    mUpdateWindowNeeded = false;
+                    reportDrawNeeded = mReportDrawNeeded;
+                    mReportDrawNeeded = false;
+                    mDrawingStopped = !visible;
+    
+                    final int relayoutResult = mSession.relayout(
+                        mWindow, mLayout, mWidth, mHeight,
+                            visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
+                            mVisibleInsets, mConfiguration, mSurface);
+                    if ((relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
+                        mReportDrawNeeded = true;
+                    }
+                    
+                    if (localLOGV) Log.i(TAG, "New surface: " + mSurface
+                            + ", vis=" + visible + ", frame=" + mWinFrame);
+                    
+                    mSurfaceFrame.left = 0;
+                    mSurfaceFrame.top = 0;
+                    if (mTranslator == null) {
+                        mSurfaceFrame.right = mWinFrame.width();
+                        mSurfaceFrame.bottom = mWinFrame.height();
+                    } else {
+                        float appInvertedScale = mTranslator.applicationInvertedScale;
+                        mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f);
+                        mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f);
+                    }
+                    
+                    final int surfaceWidth = mSurfaceFrame.right;
+                    final int surfaceHeight = mSurfaceFrame.bottom;
+                    realSizeChanged = mLastSurfaceWidth != surfaceWidth
+                            || mLastSurfaceHeight != surfaceHeight;
+                    mLastSurfaceWidth = surfaceWidth;
+                    mLastSurfaceHeight = surfaceHeight;
+                } finally {
+                    mSurfaceLock.unlock();
                 }
-                mSurfaceLock.unlock();
 
                 try {
                     if (visible) {
@@ -465,9 +492,9 @@
                             }
                         }
                         if (creating || formatChanged || sizeChanged
-                                || visibleChanged) {
+                                || visibleChanged || realSizeChanged) {
                             for (SurfaceHolder.Callback c : callbacks) {
-                                c.surfaceChanged(mSurfaceHolder, mFormat, mWidth, mHeight);
+                                c.surfaceChanged(mSurfaceHolder, mFormat, myWidth, myHeight);
                             }
                         }
                     } else {
@@ -475,7 +502,7 @@
                     }
                 } finally {
                     mIsCreating = false;
-                    if (creating || (relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
+                    if (creating || reportDrawNeeded) {
                         mSession.finishDrawing(mWindow);
                     }
                 }
@@ -533,17 +560,19 @@
                 if (localLOGV) Log.v(
                         "SurfaceView", surfaceView + " got resized: w=" +
                                 w + " h=" + h + ", cur w=" + mCurWidth + " h=" + mCurHeight);
-                synchronized (this) {
-                    if (mCurWidth != w || mCurHeight != h) {
-                        mCurWidth = w;
-                        mCurHeight = h;
-                    }
+                surfaceView.mSurfaceLock.lock();
+                try {
                     if (reportDraw) {
-                        try {
-                            surfaceView.mSession.finishDrawing(surfaceView.mWindow);
-                        } catch (RemoteException e) {
-                        }
+                        surfaceView.mUpdateWindowNeeded = true;
+                        surfaceView.mReportDrawNeeded = true;
+                        surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
+                    } else if (surfaceView.mWinFrame.width() != w
+                            || surfaceView.mWinFrame.height() != h) {
+                        surfaceView.mUpdateWindowNeeded = true;
+                        surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
                     }
+                } finally {
+                    surfaceView.mSurfaceLock.unlock();
                 }
             }
         }
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 8ef2aeb..66461a7 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2483,16 +2483,9 @@
                     delta = Math.max(-(getHeight() - mPaddingBottom - mPaddingTop - 1), delta);
                 }
 
-                // Check to see if we have bumped into the scroll limit
-                View motionView = getChildAt(mMotionPosition - mFirstPosition);
-                int oldTop = 0;
-                if (motionView != null) {
-                    oldTop = motionView.getTop();
-                }
+                final boolean atEnd = trackMotionScroll(delta, delta);
 
-                trackMotionScroll(delta, delta);
-
-                if (more) {
+                if (more && !atEnd) {
                     invalidate();
                     mLastFlingY = y;
                     post(this);
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 20c2fe4..32a9146 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -1022,6 +1022,7 @@
                     onScrollChanged(x, y, oldX, oldY);
                 }
             }
+            awakenScrollBars();
 
             // Keep on drawing until the animation has finished.
             postInvalidate();
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index a02aa00..873dc67 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -1023,6 +1023,7 @@
                     onScrollChanged(x, y, oldX, oldY);
                 }
             }
+            awakenScrollBars();
 
             // Keep on drawing until the animation has finished.
             postInvalidate();
diff --git a/core/jni/android_bluetooth_common.h b/core/jni/android_bluetooth_common.h
index ef9b66b..378bb6f 100644
--- a/core/jni/android_bluetooth_common.h
+++ b/core/jni/android_bluetooth_common.h
@@ -88,6 +88,8 @@
     int envVer;
     /* reference to our java self */
     jobject me;
+    /* flag to indicate if the event loop thread is running */
+    bool running;
 };
 
 struct _Properties {
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 0e7fd66..259cc01 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -548,6 +548,8 @@
     dbus_connection_set_watch_functions(nat->conn, dbusAddWatch,
             dbusRemoveWatch, dbusToggleWatch, ptr, NULL);
 
+    nat->running = true;
+
     while (1) {
         for (int i = 0; i < nat->pollMemberCount; i++) {
             if (!nat->pollData[i].revents) {
@@ -591,7 +593,7 @@
                 break;
             }
         }
-        while (dbus_connection_dispatch(nat->conn) == 
+        while (dbus_connection_dispatch(nat->conn) ==
                 DBUS_DISPATCH_DATA_REMAINS) {
         }
 
@@ -607,6 +609,8 @@
 
     pthread_mutex_lock(&(nat->thread_mutex));
 
+    nat->running = false;
+
     if (nat->pollData) {
         LOGW("trying to start EventLoop a second time!");
         pthread_mutex_unlock( &(nat->thread_mutex) );
@@ -703,6 +707,7 @@
         nat->controlFdW = 0;
         close(fd);
     }
+    nat->running = false;
     pthread_mutex_unlock(&(nat->thread_mutex));
 #endif // HAVE_BLUETOOTH
 }
@@ -713,7 +718,7 @@
     native_data_t *nat = get_native_data(env, object);
 
     pthread_mutex_lock(&(nat->thread_mutex));
-    if (nat->pollData) {
+    if (nat->running) {
         result = JNI_TRUE;
     }
     pthread_mutex_unlock(&(nat->thread_mutex));
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8eb5e96..9e3e8a4 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -562,14 +562,6 @@
         android:label="@string/permlab_changeConfiguration"
         android:description="@string/permdesc_changeConfiguration" />
 
-    <!-- Allows an application to enable the car mode.
-         @hide -->
-    <permission android:name="android.permission.ENABLE_CAR_MODE"
-        android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
-        android:protectionLevel="signature"
-        android:label="@string/permlab_enableCarMode"
-        android:description="@string/permdesc_enableCarMode" />
-
     <!-- @deprecated The {@link android.app.ActivityManager#restartPackage}
         API is no longer supported. -->
     <permission android:name="android.permission.RESTART_PACKAGES"
diff --git a/core/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
index 76b58e1..c318577 100644
--- a/core/tests/ConnectivityManagerTest/AndroidManifest.xml
+++ b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
@@ -46,5 +46,5 @@
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
 </manifest>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index badcc1b..6475655 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -32,6 +32,7 @@
 
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
+import android.net.wifi.WifiInfo;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
 
@@ -58,6 +59,11 @@
     public String mReason;
     public boolean mScanResultIsAvailable = false;
     public ConnectivityManager mCM;
+    public Object wifiObject = new Object();
+    public Object connectivityObject = new Object();
+    public int mWifiState;
+    public NetworkInfo mWifiNetworkInfo;
+    public String mBssid;
 
     /*
      * Control Wifi States
@@ -67,7 +73,7 @@
     /*
      * Verify connectivity state
      */
-    public static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE;
+    public static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1;
     NetworkState[] connectivityState = new NetworkState[NUM_NETWORK_TYPES];
 
     /**
@@ -77,6 +83,7 @@
     private class ConnectivityReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
+            Log.v(LOG_TAG, "ConnectivityReceiver: onReceive() is called with " + intent);
             String action = intent.getAction();
             if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                 Log.v("ConnectivityReceiver", "onReceive() called with " + intent);
@@ -100,10 +107,16 @@
 
             mReason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
             mIsFailOver = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
+
+            Log.v(LOG_TAG, "mNetworkInfo: " + mNetworkInfo.toString());
+            if (mOtherNetworkInfo != null) {
+                Log.v(LOG_TAG, "mOtherNetworkInfo: " + mOtherNetworkInfo.toString());
+            }
             recordNetworkState(mNetworkInfo.getType(), mNetworkInfo.getState());
             if (mOtherNetworkInfo != null) {
                 recordNetworkState(mOtherNetworkInfo.getType(), mOtherNetworkInfo.getState());
             }
+            notifyNetworkConnectivityChange();
         }
     }
 
@@ -111,11 +124,25 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
-            if (!action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
-                Log.v(LOG_TAG, "onReceive() is calleld with " + intent);
+            Log.v("WifiReceiver", "onReceive() is calleld with " + intent);
+            if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
+                notifyScanResult();
+            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+                mWifiNetworkInfo =
+                    (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+                Log.v(LOG_TAG, "mWifiNetworkInfo: " + mWifiNetworkInfo.toString());
+                if (mWifiNetworkInfo.getState() == State.CONNECTED) {
+                    mBssid = intent.getStringExtra(WifiManager.EXTRA_BSSID);
+                }
+                notifyWifiState();
+            } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+                mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+                                                WifiManager.WIFI_STATE_UNKNOWN);
+                notifyWifiState();
+            }
+            else {
                 return;
             }
-            notifyScanResult();
         }
     }
 
@@ -134,14 +161,19 @@
         setContentView(contentView);
         setTitle("ConnectivityManagerTestActivity");
 
-        mConnectivityReceiver = new ConnectivityReceiver();
+
         // register a connectivity receiver for CONNECTIVITY_ACTION;
+        mConnectivityReceiver = new ConnectivityReceiver();
         registerReceiver(mConnectivityReceiver,
                 new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
 
         mWifiReceiver = new WifiReceiver();
-        registerReceiver(mWifiReceiver,
-                new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
+        IntentFilter mIntentFilter = new IntentFilter();
+        mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+        registerReceiver(mWifiReceiver, mIntentFilter);
+
         // Get an instance of ConnectivityManager
         mCM = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
         // Get an instance of WifiManager
@@ -166,7 +198,7 @@
     // deposit a network state
     public void recordNetworkState(int networkType, State networkState) {
         Log.v(LOG_TAG, "record network state for network " +  networkType +
-                " state is " + networkState);
+                ", state is " + networkState);
         connectivityState[networkType].recordState(networkState);
     }
 
@@ -190,6 +222,12 @@
         return connectivityState[networkType].getReason();
     }
 
+    private void notifyNetworkConnectivityChange() {
+        synchronized(connectivityObject) {
+            Log.v(LOG_TAG, "notify network connectivity changed");
+            connectivityObject.notifyAll();
+        }
+    }
     private void notifyScanResult() {
         synchronized (this) {
             Log.v(LOG_TAG, "notify that scan results are available");
@@ -197,6 +235,13 @@
         }
     }
 
+    public void notifyWifiState() {
+        synchronized (wifiObject) {
+            Log.v(LOG_TAG, "notify wifi state changed");
+            wifiObject.notify();
+        }
+    }
+
     // Return true if device is currently connected to mobile network
     public boolean isConnectedToMobile() {
         return (mNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE);
@@ -259,9 +304,9 @@
                 config.SSID = sr.SSID;
                 config.allowedKeyManagement.set(KeyMgmt.NONE);
                 int networkId = mWifiManager.addNetwork(config);
-                mWifiManager.saveConfiguration();
                 // Connect to network by disabling others.
                 mWifiManager.enableNetwork(networkId, true);
+                mWifiManager.saveConfiguration();
                 mWifiManager.reconnect();
                 break;
            }
@@ -275,21 +320,17 @@
         return true;
     }
 
-    /**
-     * Disable Wifi
-     * @return true if Wifi is disabled successfully
+    /*
+     * Disconnect from the current AP
      */
-    public boolean disableWiFi() {
-        return mWifiManager.setWifiEnabled(false);
-    }
-
-    /**
-     * Disconnect from the current Wifi and clear the configuration list
-     */
-    public boolean clearWifi() {
-       if (mWifiManager.isWifiEnabled()) {
+    public boolean disconnectAP() {
+        if (mWifiManager.isWifiEnabled()) {
             //remove the current network Id
-            int curNetworkId = mWifiManager.getConnectionInfo().getNetworkId();
+            WifiInfo curWifi = mWifiManager.getConnectionInfo();
+            if (curWifi == null) {
+                return false;
+            }
+            int curNetworkId = curWifi.getNetworkId();
             mWifiManager.removeNetwork(curNetworkId);
             mWifiManager.saveConfiguration();
 
@@ -303,16 +344,33 @@
                     mWifiManager.removeNetwork(conf.networkId);
                 }
             }
-            mWifiManager.saveConfiguration();
-            // disable Wifi
+        }
+        mWifiManager.saveConfiguration();
+        return true;
+    }
+    /**
+     * Disable Wifi
+     * @return true if Wifi is disabled successfully
+     */
+    public boolean disableWifi() {
+        return mWifiManager.setWifiEnabled(false);
+    }
+
+    /**
+     * Disconnect from the current Wifi and clear the configuration list
+     */
+    public boolean clearWifi() {
+            if (!disconnectAP()) {
+                return false;
+            }
+            // Disable Wifi
             if (!mWifiManager.setWifiEnabled(false)) {
                 return false;
             }
-            // wait for the actions to be completed
+            // Wait for the actions to be completed
             try {
                 Thread.sleep(5*1000);
             } catch (InterruptedException e) {}
-        }
         return true;
     }
 
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java
index 2e5a0f8..d586396 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java
@@ -143,14 +143,14 @@
         }
         State lastState = mStateDepository.get(mStateDepository.size() - 1);
         if ( lastState != mTransitionTarget) {
-            mReason += " the last state should be CONNECTED, but it is " + lastState;
+            mReason += "The last state should be " + mTransitionTarget + ", but it is " + lastState;
             return false;
         }
         for (int i = 1; i < mStateDepository.size(); i++) {
             State preState = mStateDepository.get(i-1);
             State curState = mStateDepository.get(i);
             if ((preState == State.DISCONNECTED) && ((curState == State.CONNECTING) ||
-                    (curState == State.CONNECTED))) {
+                    (curState == State.CONNECTED) || (curState == State.DISCONNECTED))) {
                 continue;
             } else if ((preState == State.CONNECTING) && (curState == State.CONNECTED)) {
                 continue;
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index ad564ae..7641afe 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-
-
 package com.android.connectivitymanagertest.functional;
 
 import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
 
 import android.content.Intent;
 import android.content.Context;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
 import android.app.Instrumentation;
 import android.os.Handler;
 import android.os.Message;
@@ -29,23 +29,24 @@
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.State;
 import android.net.NetworkInfo.DetailedState;
+import android.net.wifi.WifiManager;
 
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.ActivityInstrumentationTestCase2;
 import com.android.connectivitymanagertest.ConnectivityManagerTestRunner;
 import com.android.connectivitymanagertest.NetworkState;
 import android.util.Log;
-import junit.framework.*;
 
 public class ConnectivityManagerMobileTest
     extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
-
     private static final String LOG_TAG = "ConnectivityManagerMobileTest";
     private static final String PKG_NAME = "com.android.connectivitymanagertest";
-    private static final long WIFI_CONNECTION_TIMEOUT = 30 * 1000;
-    private static final long WIFI_NOTIFICATION_TIMEOUT = 10 * 1000;
+    private static final long STATE_TRANSITION_SHORT_TIMEOUT = 5 * 1000;
+    private static final long STATE_TRANSITION_LONG_TIMEOUT = 30 * 1000;
+
     private String TEST_ACCESS_POINT;
     private ConnectivityManagerTestActivity cmActivity;
+    private WakeLock wl;
 
     public ConnectivityManagerMobileTest() {
         super(PKG_NAME, ConnectivityManagerTestActivity.class);
@@ -58,16 +59,22 @@
         ConnectivityManagerTestRunner mRunner =
                 (ConnectivityManagerTestRunner)getInstrumentation();
         TEST_ACCESS_POINT = mRunner.TEST_SSID;
+        PowerManager pm = (PowerManager)getInstrumentation().
+                getContext().getSystemService(Context.POWER_SERVICE);
+        wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "CMWakeLock");
+        wl.acquire();
         // Each test case will start with cellular connection
+        waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
         verifyCellularConnection();
     }
 
     @Override
     public void tearDown() throws Exception {
-        // clear Wifi after each test case
-        cmActivity.clearWifi();
         cmActivity.finish();
-        Log.v(LOG_TAG, "tear down ConnectivityManager test activity");
+        Log.v(LOG_TAG, "tear down ConnectivityManagerTestActivity");
+        wl.release();
+        cmActivity.clearWifi();
         super.tearDown();
     }
 
@@ -80,6 +87,66 @@
         assertTrue("no data connection", cmActivity.mState.equals(State.CONNECTED));
     }
 
+    // Wait for network connectivity state: CONNECTING, CONNECTED, SUSPENDED,
+    //                                      DISCONNECTING, DISCONNECTED, UNKNOWN
+    private void waitForNetworkState(int networkType, State expectedState, long timeout) {
+        long startTime = System.currentTimeMillis();
+        // In case the broadcast is already sent out, no need to wait
+        if (cmActivity.mCM.getNetworkInfo(networkType).getState() == expectedState) {
+            return;
+        } else {
+            while (true) {
+                if ((System.currentTimeMillis() - startTime) > timeout) {
+                    assertFalse("Wait for network state timeout", true);
+                }
+                Log.v(LOG_TAG, "Wait for the connectivity state for network: " + networkType +
+                        " to be " + expectedState.toString());
+                synchronized (cmActivity.connectivityObject) {
+                    try {
+                        cmActivity.connectivityObject.wait(STATE_TRANSITION_SHORT_TIMEOUT);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    if ((cmActivity.mNetworkInfo.getType() != networkType) ||
+                        (cmActivity.mNetworkInfo.getState() != expectedState)) {
+                        Log.v(LOG_TAG, "network state for " + cmActivity.mNetworkInfo.getType() +
+                                "is: " + cmActivity.mNetworkInfo.getState());
+                        continue;
+                    }
+                    break;
+                }
+            }
+        }
+    }
+
+    // Wait for Wifi state: WIFI_STATE_DISABLED, WIFI_STATE_DISABLING, WIFI_STATE_ENABLED,
+    //                      WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN
+    private void waitForWifiState(int expectedState, long timeout) {
+        long startTime = System.currentTimeMillis();
+        if (cmActivity.mWifiState == expectedState) {
+            return;
+        } else {
+            while (true) {
+                if ((System.currentTimeMillis() - startTime) > timeout) {
+                    assertFalse("Wait for Wifi state timeout", true);
+                }
+                Log.v(LOG_TAG, "Wait for wifi state to be: " + expectedState);
+                synchronized (cmActivity.wifiObject) {
+                    try {
+                        cmActivity.wifiObject.wait(5*1000);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    if (cmActivity.mWifiState != expectedState) {
+                        Log.v(LOG_TAG, "Wifi state is: " + cmActivity.mWifiNetworkInfo.getState());
+                        continue;
+                    }
+                    break;
+                }
+            }
+        }
+    }
+
     // Test case 1: Test enabling Wifi without associating with any AP
     @LargeTest
     public void test3GToWifiNotification() {
@@ -94,7 +161,7 @@
         // Eanble Wifi
         cmActivity.enableWifi();
         try {
-            Thread.sleep(WIFI_NOTIFICATION_TIMEOUT);
+            Thread.sleep(2 * STATE_TRANSITION_SHORT_TIMEOUT);
         } catch (Exception e) {
             Log.v(LOG_TAG, "exception: " + e.toString());
         }
@@ -110,7 +177,7 @@
             Log.v(LOG_TAG, "the state for MOBILE is changed");
             Log.v(LOG_TAG, "reason: " +
                     cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
-            assertTrue(false);
+            assertTrue("state validation fail", false);
         }
         // Verify that the device is still connected to MOBILE
         verifyCellularConnection();
@@ -131,11 +198,13 @@
         // Enable Wifi and connect to a test access point
         assertTrue("failed to connect to " + TEST_ACCESS_POINT,
                 cmActivity.connectToWifi(TEST_ACCESS_POINT));
-        try {
-            Thread.sleep(WIFI_CONNECTION_TIMEOUT);
-        } catch (Exception e) {
-            Log.v(LOG_TAG, "exception: " + e.toString());
-        }
+
+        waitForWifiState(WifiManager.WIFI_STATE_ENABLED, STATE_TRANSITION_LONG_TIMEOUT);
+        Log.v(LOG_TAG, "wifi state is enabled");
+        waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
+        waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.DISCONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
 
         // validate states
         if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
@@ -151,4 +220,318 @@
             assertTrue(false);
         }
     }
+
+    // Test case 3: connect to Wifi with known AP
+    @LargeTest
+    public void testConnectToWifWithKnownAP() {
+        assertNotNull("SSID is null", TEST_ACCESS_POINT);
+        // Connect to TEST_ACCESS_POINT
+        assertTrue("failed to connect to " + TEST_ACCESS_POINT,
+                cmActivity.connectToWifi(TEST_ACCESS_POINT));
+        waitForWifiState(WifiManager.WIFI_STATE_ENABLED, STATE_TRANSITION_LONG_TIMEOUT);
+        waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
+
+        try {
+            Thread.sleep(STATE_TRANSITION_SHORT_TIMEOUT);
+        } catch (Exception e) {
+            Log.v(LOG_TAG, "exception: " + e.toString());
+        }
+
+        // Disable Wifi
+        Log.v(LOG_TAG, "Disable Wifi");
+        if (!cmActivity.disableWifi()) {
+            Log.v(LOG_TAG, "disable Wifi failed");
+            return;
+        }
+
+        // Wait for the Wifi state to be DISABLED
+        waitForWifiState(WifiManager.WIFI_STATE_DISABLED, STATE_TRANSITION_LONG_TIMEOUT);
+        waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
+        waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
+
+        //Prepare for connectivity state verification
+        NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+                                              networkInfo.getState(), NetworkState.DO_NOTHING,
+                                              State.DISCONNECTED);
+        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+                NetworkState.TO_CONNECTION, State.CONNECTED);
+
+        // Enable Wifi again
+        Log.v(LOG_TAG, "Enable Wifi again");
+        cmActivity.enableWifi();
+
+        // Wait for Wifi to be connected and mobile to be disconnected
+        waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
+        waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.DISCONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
+
+        // validate wifi states
+        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+            Log.v(LOG_TAG, "Wifi state transition validation failed.");
+            Log.v(LOG_TAG, "reason: " +
+                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+            assertTrue(false);
+        }
+    }
+
+    // Test case 4:  test disconnect Wifi
+    @LargeTest
+    public void testDisconnectWifi() {
+        assertNotNull("SSID is null", TEST_ACCESS_POINT);
+
+        // connect to Wifi
+        assertTrue("failed to connect to " + TEST_ACCESS_POINT,
+                   cmActivity.connectToWifi(TEST_ACCESS_POINT));
+
+        waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+            STATE_TRANSITION_LONG_TIMEOUT);
+
+        // Wait for a few seconds to avoid the state that both Mobile and Wifi is connected
+        try {
+            Thread.sleep(STATE_TRANSITION_SHORT_TIMEOUT);
+        } catch (Exception e) {
+            Log.v(LOG_TAG, "exception: " + e.toString());
+        }
+
+        NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+                                              networkInfo.getState(),
+                                              NetworkState.TO_CONNECTION,
+                                              State.CONNECTED);
+        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+                NetworkState.TO_DISCONNECTION, State.DISCONNECTED);
+
+        // clear Wifi
+        cmActivity.clearWifi();
+
+        waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
+        waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
+
+        // validate states
+        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+            Log.v(LOG_TAG, "Wifi state transition validation failed.");
+            Log.v(LOG_TAG, "reason: " +
+                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+            assertTrue(false);
+        }
+        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+            Log.v(LOG_TAG, "Mobile state transition validation failed.");
+            Log.v(LOG_TAG, "reason: " +
+                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+            assertTrue(false);
+        }
+    }
+
+    // Test case 5: test connectivity from 3G to airplane mode, then to 3G again
+    @LargeTest
+    public void testDataConnectionWith3GToAmTo3G() {
+        //Prepare for state verification
+        NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+                                              networkInfo.getState(),
+                                              NetworkState.TO_DISCONNECTION,
+                                              State.DISCONNECTED);
+        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        assertEquals(State.DISCONNECTED, networkInfo.getState());
+        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+                NetworkState.DO_NOTHING, State.DISCONNECTED);
+
+        // Enable airplane mode
+        cmActivity.setAirplaneMode(getInstrumentation().getContext(), true);
+        try {
+            Thread.sleep(STATE_TRANSITION_SHORT_TIMEOUT);
+        } catch (Exception e) {
+            Log.v(LOG_TAG, "exception: " + e.toString());
+        }
+
+        // Validate the state transition
+        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+            Log.v(LOG_TAG, "Wifi state transition validation failed.");
+            Log.v(LOG_TAG, "reason: " +
+                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+            assertTrue(false);
+        }
+        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+            Log.v(LOG_TAG, "Mobile state transition validation failed.");
+            Log.v(LOG_TAG, "reason: " +
+                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+            assertTrue(false);
+        }
+
+        // reset state recorder
+        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+                                              networkInfo.getState(),
+                                              NetworkState.TO_CONNECTION,
+                                              State.CONNECTED);
+        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+                NetworkState.DO_NOTHING, State.DISCONNECTED);
+
+        // disable airplane mode
+        cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
+
+        waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
+
+        // Validate the state transition
+        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+            Log.v(LOG_TAG, "Mobile state transition validation failed.");
+            Log.v(LOG_TAG, "reason: " +
+                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+            assertTrue(false);
+        }
+        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+          Log.v(LOG_TAG, "Wifi state transition validation failed.");
+          Log.v(LOG_TAG, "reason: " +
+                  cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+          assertTrue(false);
+        }
+    }
+
+    // Test case 6: test connectivity with airplane mode Wifi connected
+    @LargeTest
+    public void testDataConnectionOverAMWithWifi() {
+        assertNotNull("SSID is null", TEST_ACCESS_POINT);
+        // Eanble airplane mode
+        cmActivity.setAirplaneMode(getInstrumentation().getContext(), true);
+
+        waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.DISCONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
+
+        NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+                                              networkInfo.getState(),
+                                              NetworkState.DO_NOTHING,
+                                              State.DISCONNECTED);
+        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI, networkInfo.getState(),
+                                              NetworkState.TO_CONNECTION, State.CONNECTED);
+
+        // Connect to Wifi
+        assertTrue("failed to connect to " + TEST_ACCESS_POINT,
+                   cmActivity.connectToWifi(TEST_ACCESS_POINT));
+        waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                            STATE_TRANSITION_LONG_TIMEOUT);
+
+        // validate state and broadcast
+        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+            Log.v(LOG_TAG, "state validate for Wifi failed");
+            Log.v(LOG_TAG, "reason: " +
+                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+            assertTrue("State validation failed", false);
+        }
+        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+            Log.v(LOG_TAG, "state validation for Mobile failed");
+            Log.v(LOG_TAG, "reason: " +
+                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+            assertTrue("state validation failed", false);
+        }
+        cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
+    }
+
+    // Test case 7: test connectivity while transit from Wifi->AM->Wifi
+    @LargeTest
+    public void testDataConnectionWithWifiToAMToWifi () {
+        // Connect to TEST_ACCESS_POINT
+        assertNotNull("SSID is null", TEST_ACCESS_POINT);
+        // Connect to Wifi
+        assertTrue("failed to connect to " + TEST_ACCESS_POINT,
+                cmActivity.connectToWifi(TEST_ACCESS_POINT));
+
+        waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
+
+        try {
+            Thread.sleep(STATE_TRANSITION_SHORT_TIMEOUT);
+        } catch (Exception e) {
+            Log.v(LOG_TAG, "exception: " + e.toString());
+        }
+
+        // Enable airplane mode without clearing Wifi
+        cmActivity.setAirplaneMode(getInstrumentation().getContext(), true);
+
+        waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
+
+        try {
+            Thread.sleep(STATE_TRANSITION_SHORT_TIMEOUT);
+        } catch (Exception e) {
+            Log.v(LOG_TAG, "exception: " + e.toString());
+        }
+
+        // Prepare for state validation
+        NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE,
+                networkInfo.getState(),NetworkState.DO_NOTHING,State.DISCONNECTED);
+        networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+        assertEquals(State.DISCONNECTED, networkInfo.getState());
+        cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_WIFI,
+                networkInfo.getState(), NetworkState.TO_CONNECTION, State.CONNECTED);
+
+        // Disable airplane mode
+        cmActivity.setAirplaneMode(getInstrumentation().getContext(), false);
+
+        waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+            STATE_TRANSITION_LONG_TIMEOUT);
+
+        // validate the state transition
+        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_WIFI)) {
+            Log.v(LOG_TAG, "Wifi state transition validation failed.");
+            Log.v(LOG_TAG, "reason: " +
+                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
+            assertTrue(false);
+        }
+        if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
+            Log.v(LOG_TAG, "Mobile state transition validation failed.");
+            Log.v(LOG_TAG, "reason: " +
+                    cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_MOBILE));
+            assertTrue(false);
+        }
+    }
+
+    // Test case 8: test wifi state change while connecting/disconnecting to/from an AP
+    @LargeTest
+    public void testWifiStateChange () {
+        assertNotNull("SSID is null", TEST_ACCESS_POINT);
+        //Connect to TEST_ACCESS_POINT
+        assertTrue("failed to connect to " + TEST_ACCESS_POINT,
+                   cmActivity.connectToWifi(TEST_ACCESS_POINT));
+        waitForWifiState(WifiManager.WIFI_STATE_ENABLED, STATE_TRANSITION_LONG_TIMEOUT);
+        waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
+                            STATE_TRANSITION_LONG_TIMEOUT);
+        assertNotNull("Not associated with any AP",
+                      cmActivity.mWifiManager.getConnectionInfo().getBSSID());
+
+        try {
+            Thread.sleep(STATE_TRANSITION_SHORT_TIMEOUT);
+        } catch (Exception e) {
+            Log.v(LOG_TAG, "exception: " + e.toString());
+        }
+
+        // Disconnect from the current AP
+        Log.v(LOG_TAG, "disconnect from the AP");
+        if (!cmActivity.disconnectAP()) {
+            Log.v(LOG_TAG, "failed to disconnect from " + TEST_ACCESS_POINT);
+        }
+
+        // Verify the connectivity state for Wifi is DISCONNECTED
+        waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
+                STATE_TRANSITION_LONG_TIMEOUT);
+
+        if (!cmActivity.disableWifi()) {
+            Log.v(LOG_TAG, "disable Wifi failed");
+            return;
+        }
+        waitForWifiState(WifiManager.WIFI_STATE_DISABLED, STATE_TRANSITION_LONG_TIMEOUT);
+    }
 }
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index eb005ce..9972a8c 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -15,6 +15,7 @@
 -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          android:installLocation="internalOnly"
           package="com.android.frameworks.coretests">
 
     <permission android:name="com.android.frameworks.coretests.permission.TEST_GRANTED"
diff --git a/core/tests/coretests/res/raw/install_app1_cert1 b/core/tests/coretests/res/raw/install_app1_cert1
new file mode 100644
index 0000000..67eb2de
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_app1_cert1
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app1_cert1_cert2 b/core/tests/coretests/res/raw/install_app1_cert1_cert2
new file mode 100644
index 0000000..dbafdc5
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_app1_cert1_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app1_cert2 b/core/tests/coretests/res/raw/install_app1_cert2
new file mode 100644
index 0000000..e26c2eb
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_app1_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app1_cert3 b/core/tests/coretests/res/raw/install_app1_cert3
new file mode 100644
index 0000000..fa10be7
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_app1_cert3
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app1_cert3_cert4 b/core/tests/coretests/res/raw/install_app1_cert3_cert4
new file mode 100644
index 0000000..c2f6c81
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_app1_cert3_cert4
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app1_unsigned b/core/tests/coretests/res/raw/install_app1_unsigned
new file mode 100644
index 0000000..18be5f8
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_app1_unsigned
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app2_cert1 b/core/tests/coretests/res/raw/install_app2_cert1
new file mode 100644
index 0000000..b345732
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_app2_cert1
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app2_cert1_cert2 b/core/tests/coretests/res/raw/install_app2_cert1_cert2
new file mode 100644
index 0000000..1faa257
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_app2_cert1_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app2_cert2 b/core/tests/coretests/res/raw/install_app2_cert2
new file mode 100644
index 0000000..c3d5979
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_app2_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app2_cert3 b/core/tests/coretests/res/raw/install_app2_cert3
new file mode 100644
index 0000000..ac0d9da
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_app2_cert3
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_app2_unsigned b/core/tests/coretests/res/raw/install_app2_unsigned
new file mode 100644
index 0000000..8d24e88
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_app2_unsigned
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared1_cert1 b/core/tests/coretests/res/raw/install_shared1_cert1
new file mode 100644
index 0000000..d702dab
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_shared1_cert1
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared1_cert12 b/core/tests/coretests/res/raw/install_shared1_cert12
new file mode 100644
index 0000000..b580b60
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_shared1_cert12
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared1_cert1_cert2 b/core/tests/coretests/res/raw/install_shared1_cert1_cert2
new file mode 100644
index 0000000..b580b60
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_shared1_cert1_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared1_cert2 b/core/tests/coretests/res/raw/install_shared1_cert2
new file mode 100644
index 0000000..a2de801
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_shared1_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared1_unsigned b/core/tests/coretests/res/raw/install_shared1_unsigned
new file mode 100644
index 0000000..35680be
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_shared1_unsigned
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared2_cert1 b/core/tests/coretests/res/raw/install_shared2_cert1
new file mode 100644
index 0000000..9064de7
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_shared2_cert1
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared2_cert12 b/core/tests/coretests/res/raw/install_shared2_cert12
new file mode 100644
index 0000000..26a250d
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_shared2_cert12
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared2_cert1_cert2 b/core/tests/coretests/res/raw/install_shared2_cert1_cert2
new file mode 100644
index 0000000..26a250d
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_shared2_cert1_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared2_cert2 b/core/tests/coretests/res/raw/install_shared2_cert2
new file mode 100644
index 0000000..7981308
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_shared2_cert2
Binary files differ
diff --git a/core/tests/coretests/res/raw/install_shared2_unsigned b/core/tests/coretests/res/raw/install_shared2_unsigned
new file mode 100644
index 0000000..ad909fd
--- /dev/null
+++ b/core/tests/coretests/res/raw/install_shared2_unsigned
Binary files differ
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 7b9e95a..aec82afe 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -23,10 +23,18 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 import android.content.res.Resources.NotFoundException;
 import android.net.Uri;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.Suppress;
+import android.util.DisplayMetrics;
+import android.util.Log;
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.IBinder;
@@ -497,6 +505,15 @@
         }
     }
 
+    private PackageParser.Package getParsedPackage(String outFileName, int rawResId) {
+        PackageManager pm = mContext.getPackageManager();
+        File filesDir = mContext.getFilesDir();
+        File outFile = new File(filesDir, outFileName);
+        Uri packageURI = getInstallablePackage(rawResId, outFile);
+        PackageParser.Package pkg = parsePackage(packageURI);
+        return pkg;
+    }
+
     /*
      * Utility function that reads a apk bundled as a raw resource
      * copies it into own data directory and invokes
@@ -529,7 +546,9 @@
             if (fail) {
                 assertTrue(invokeInstallPackageFail(packageURI, flags,
                         pkg.packageName, result));
-                assertNotInstalled(pkg.packageName);
+                if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) == 0) {
+                    assertNotInstalled(pkg.packageName);
+                }
             } else {
                 InstallReceiver receiver = new InstallReceiver(pkg.packageName);
                 assertTrue(invokeInstallPackage(packageURI, flags,
@@ -621,7 +640,7 @@
      * PackageManager api to install first and then replace it
      * again.
      */
-    public void replaceFromRawResource(int flags) {
+    private void sampleReplaceFromRawResource(int flags) {
         InstallParams ip = sampleInstallFromRawResource(flags, false);
         boolean replace = ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0);
         Log.i(TAG, "replace=" + replace);
@@ -648,28 +667,28 @@
     }
 
     public void testReplaceFailNormalInternal() {
-        replaceFromRawResource(0);
+        sampleReplaceFromRawResource(0);
     }
 
     public void testReplaceFailFwdLockedInternal() {
-        replaceFromRawResource(PackageManager.INSTALL_FORWARD_LOCK);
+        sampleReplaceFromRawResource(PackageManager.INSTALL_FORWARD_LOCK);
     }
 
     public void testReplaceFailSdcard() {
-        replaceFromRawResource(PackageManager.INSTALL_EXTERNAL);
+        sampleReplaceFromRawResource(PackageManager.INSTALL_EXTERNAL);
     }
 
     public void testReplaceNormalInternal() {
-        replaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING);
+        sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING);
     }
 
     public void testReplaceFwdLockedInternal() {
-        replaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
+        sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
                 PackageManager.INSTALL_FORWARD_LOCK);
     }
 
     public void testReplaceSdcard() {
-        replaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
+        sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
                 PackageManager.INSTALL_EXTERNAL);
     }
 
@@ -1014,6 +1033,19 @@
             outFile.delete();
         }
     }
+    void cleanUpInstall(String pkgName) {
+        if (pkgName == null) {
+            return;
+        }
+        Log.i(TAG, "Deleting package : " + pkgName);
+        try {
+            ApplicationInfo info = getPm().getApplicationInfo(pkgName,
+                    PackageManager.GET_UNINSTALLED_PACKAGES);
+            if (info != null) {
+                getPm().deletePackage(pkgName, null, 0);
+            }
+        } catch (NameNotFoundException e) {}
+    }
 
     public void testManifestInstallLocationInternal() {
         installFromRawResource("install.apk", R.raw.install_loc_internal,
@@ -2152,6 +2184,360 @@
 
         }
     }
+    /*
+     * The following series of tests are related to upgrading apps with
+     * different certificates. 
+     */
+    private int APP1_UNSIGNED = R.raw.install_app1_unsigned;
+    private int APP1_CERT1 = R.raw.install_app1_cert1;
+    private int APP1_CERT2 = R.raw.install_app1_cert2;
+    private int APP1_CERT1_CERT2 = R.raw.install_app1_cert1_cert2;
+    private int APP1_CERT3_CERT4 = R.raw.install_app1_cert3_cert4;
+    private int APP1_CERT3 = R.raw.install_app1_cert3;
+    private int APP2_UNSIGNED = R.raw.install_app2_unsigned;
+    private int APP2_CERT1 = R.raw.install_app2_cert1;
+    private int APP2_CERT2 = R.raw.install_app2_cert2;
+    private int APP2_CERT1_CERT2 = R.raw.install_app2_cert1_cert2;
+    private int APP2_CERT3 = R.raw.install_app2_cert3;
+
+    private InstallParams replaceCerts(int apk1, int apk2, boolean cleanUp, boolean fail, int retCode) {
+        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
+        String apk1Name = "install1.apk";
+        String apk2Name = "install2.apk";
+        PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
+        try {
+            InstallParams ip = installFromRawResource(apk1Name, apk1, 0, false,
+                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+            installFromRawResource(apk2Name, apk2, rFlags, false,
+                    fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+            return ip;
+        } catch (Exception e) {
+            failStr(e.getMessage());
+        } finally {
+            if (cleanUp) {
+                cleanUpInstall(pkg1.packageName);
+            }
+        }
+        return null;
+    }
+    /*
+     * Test that an app signed with two certificates can be upgraded by the
+     * same app signed with two certificates.
+     */
+    public void testReplaceMatchAllCerts() {
+        replaceCerts(APP1_CERT1_CERT2, APP1_CERT1_CERT2, true, false, -1);
+    }
+
+    /*
+     * Test that an app signed with two certificates cannot be upgraded
+     * by an app signed with a different certificate.
+     */
+    public void testReplaceMatchNoCerts1() {
+        replaceCerts(APP1_CERT1_CERT2, APP1_CERT3, true, true,
+                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
+    }
+    /*
+     * Test that an app signed with two certificates cannot be upgraded
+     * by an app signed with a different certificate.
+     */
+    public void testReplaceMatchNoCerts2() {
+        replaceCerts(APP1_CERT1_CERT2, APP1_CERT3_CERT4, true, true,
+                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
+    }
+    /*
+     * Test that an app signed with two certificates cannot be upgraded by
+     * an app signed with a subset of initial certificates.
+     */
+    public void testReplaceMatchSomeCerts1() {
+        replaceCerts(APP1_CERT1_CERT2, APP1_CERT1, true, true,
+                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
+    }
+    /*
+     * Test that an app signed with two certificates cannot be upgraded by
+     * an app signed with the last certificate.
+     */
+    public void testReplaceMatchSomeCerts2() {
+        replaceCerts(APP1_CERT1_CERT2, APP1_CERT2, true, true,
+                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
+    }
+    /*
+     * Test that an app signed with a certificate can be upgraded by app
+     * signed with a superset of certificates.
+     */
+    public void testReplaceMatchMoreCerts() {
+        replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, true, true,
+                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
+    }
+    /*
+     * Test that an app signed with a certificate can be upgraded by app
+     * signed with a superset of certificates. Then verify that the an app
+     * signed with the original set of certs cannot upgrade the new one.
+     */
+    public void testReplaceMatchMoreCertsReplaceSomeCerts() {
+        InstallParams ip = replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, false, true,
+                PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
+        try {
+            int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
+            installFromRawResource("install.apk", APP1_CERT1, rFlags, false,
+                    false, -1,
+                    PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+        } catch (Exception e) {
+            failStr(e.getMessage());
+        } finally {
+            if (ip != null) {
+                cleanUpInstall(ip);
+            }
+        }
+    }
+    /*
+     * The following tests are related to testing the checkSignatures
+     * api.
+     */
+    private void checkSignatures(int apk1, int apk2, int expMatchResult) {
+        checkSharedSignatures(apk1, apk2, true, false, -1, expMatchResult);
+    }
+    public void testCheckSignaturesAllMatch() {
+        int apk1 = APP1_CERT1_CERT2;
+        int apk2 = APP2_CERT1_CERT2;
+        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
+    }
+    public void testCheckSignaturesNoMatch() {
+        int apk1 = APP1_CERT1;
+        int apk2 = APP2_CERT2;
+        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
+    }
+    public void testCheckSignaturesSomeMatch1() {
+        int apk1 = APP1_CERT1_CERT2;
+        int apk2 = APP2_CERT1;
+        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
+    }
+    public void testCheckSignaturesSomeMatch2() {
+        int apk1 = APP1_CERT1_CERT2;
+        int apk2 = APP2_CERT2;
+        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
+    }
+    public void testCheckSignaturesMoreMatch() {
+        int apk1 = APP1_CERT1;
+        int apk2 = APP2_CERT1_CERT2;
+        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
+    }
+    public void testCheckSignaturesUnknown() {
+        int apk1 = APP1_CERT1_CERT2;
+        int apk2 = APP2_CERT1_CERT2;
+        String apk1Name = "install1.apk";
+        String apk2Name = "install2.apk";
+        InstallParams ip1 = null;
+
+        try {
+            ip1 = installFromRawResource(apk1Name, apk1, 0, false,
+                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+            PackageManager pm = mContext.getPackageManager();
+            // Delete app2
+            File filesDir = mContext.getFilesDir();
+            File outFile = new File(filesDir, apk2Name);
+            int rawResId = apk2;
+            Uri packageURI = getInstallablePackage(rawResId, outFile);
+            PackageParser.Package pkg = parsePackage(packageURI);
+            getPm().deletePackage(pkg.packageName, null, 0);
+            // Check signatures now
+            int match = mContext.getPackageManager().checkSignatures(
+                    ip1.pkg.packageName, pkg.packageName);
+            assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
+        } finally {
+            if (ip1 != null) {
+                cleanUpInstall(ip1);
+            }
+        }
+    }
+    public void testInstallNoCertificates() {
+        int apk1 = APP1_UNSIGNED;
+        String apk1Name = "install1.apk";
+        InstallParams ip1 = null;
+
+        try {
+            installFromRawResource(apk1Name, apk1, 0, false,
+                    true, PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES,
+                    PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+        } finally {
+        }
+    }
+    /* The following tests are related to apps using shared uids signed
+     * with different certs.
+     */
+    private int SHARED1_UNSIGNED = R.raw.install_shared1_unsigned;
+    private int SHARED1_CERT1 = R.raw.install_shared1_cert1;
+    private int SHARED1_CERT2 = R.raw.install_shared1_cert2;
+    private int SHARED1_CERT1_CERT2 = R.raw.install_shared1_cert1_cert2;
+    private int SHARED2_UNSIGNED = R.raw.install_shared2_unsigned;
+    private int SHARED2_CERT1 = R.raw.install_shared2_cert1;
+    private int SHARED2_CERT2 = R.raw.install_shared2_cert2;
+    private int SHARED2_CERT1_CERT2 = R.raw.install_shared2_cert1_cert2;
+    private void checkSharedSignatures(int apk1, int apk2, boolean cleanUp, boolean fail, int retCode, int expMatchResult) {
+        String apk1Name = "install1.apk";
+        String apk2Name = "install2.apk";
+        PackageParser.Package pkg1 = getParsedPackage(apk1Name, apk1);
+        PackageParser.Package pkg2 = getParsedPackage(apk2Name, apk2);
+
+        try {
+            // Clean up before testing first.
+            cleanUpInstall(pkg1.packageName);
+            cleanUpInstall(pkg2.packageName);
+            installFromRawResource(apk1Name, apk1, 0, false,
+                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+            if (fail) {
+                installFromRawResource(apk2Name, apk2, 0, false,
+                        true, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+            } else {
+                installFromRawResource(apk2Name, apk2, 0, false,
+                        false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+                int match = mContext.getPackageManager().checkSignatures(
+                        pkg1.packageName, pkg2.packageName);
+                assertEquals(expMatchResult, match);
+            }
+        } finally {
+            if (cleanUp) {
+                cleanUpInstall(pkg1.packageName);
+                cleanUpInstall(pkg2.packageName);
+            }
+        }
+    }
+    public void testCheckSignaturesSharedAllMatch() {
+        int apk1 = SHARED1_CERT1_CERT2;
+        int apk2 = SHARED2_CERT1_CERT2;
+        boolean fail = false;
+        int retCode = -1;
+        int expMatchResult = PackageManager.SIGNATURE_MATCH;
+        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
+    }
+    public void testCheckSignaturesSharedNoMatch() {
+        int apk1 = SHARED1_CERT1;
+        int apk2 = SHARED2_CERT2;
+        boolean fail = true;
+        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
+        int expMatchResult = -1;
+        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
+    }
+    /*
+     * Test that an app signed with cert1 and cert2 cannot be replaced when signed with cert1 alone.
+     */
+    public void testCheckSignaturesSharedSomeMatch1() {
+        int apk1 = SHARED1_CERT1_CERT2;
+        int apk2 = SHARED2_CERT1;
+        boolean fail = true;
+        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
+        int expMatchResult = -1;
+        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
+    }
+    /*
+     * Test that an app signed with cert1 and cert2 cannot be replaced when signed with cert2 alone.
+     */
+    public void testCheckSignaturesSharedSomeMatch2() {
+        int apk1 = SHARED1_CERT1_CERT2;
+        int apk2 = SHARED2_CERT2;
+        boolean fail = true;
+        int retCode = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
+        int expMatchResult = -1;
+        checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
+    }
+    public void testCheckSignaturesSharedUnknown() {
+        int apk1 = SHARED1_CERT1_CERT2;
+        int apk2 = SHARED2_CERT1_CERT2;
+        String apk1Name = "install1.apk";
+        String apk2Name = "install2.apk";
+        InstallParams ip1 = null;
+
+        try {
+            ip1 = installFromRawResource(apk1Name, apk1, 0, false,
+                    false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+            PackageManager pm = mContext.getPackageManager();
+            // Delete app2
+            PackageParser.Package pkg = getParsedPackage(apk2Name, apk2);
+            getPm().deletePackage(pkg.packageName, null, 0);
+            // Check signatures now
+            int match = mContext.getPackageManager().checkSignatures(
+                    ip1.pkg.packageName, pkg.packageName);
+            assertEquals(PackageManager.SIGNATURE_UNKNOWN_PACKAGE, match);
+        } finally {
+            if (ip1 != null) {
+                cleanUpInstall(ip1);
+            }
+        }
+    }
+    
+    public void testReplaceFirstSharedMatchAllCerts() {
+        int apk1 = SHARED1_CERT1;
+        int apk2 = SHARED2_CERT1;
+        int rapk1 = SHARED1_CERT1;
+        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
+        replaceCerts(apk1, rapk1, true, false, -1);
+    }
+    public void testReplaceSecondSharedMatchAllCerts() {
+        int apk1 = SHARED1_CERT1;
+        int apk2 = SHARED2_CERT1;
+        int rapk2 = SHARED2_CERT1;
+        checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
+        replaceCerts(apk2, rapk2, true, false, -1);
+    }
+    public void testReplaceFirstSharedMatchSomeCerts() {
+        int apk1 = SHARED1_CERT1_CERT2;
+        int apk2 = SHARED2_CERT1_CERT2;
+        int rapk1 = SHARED1_CERT1;
+        boolean fail = true;
+        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
+        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
+        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
+                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+    }
+    public void testReplaceSecondSharedMatchSomeCerts() {
+        int apk1 = SHARED1_CERT1_CERT2;
+        int apk2 = SHARED2_CERT1_CERT2;
+        int rapk2 = SHARED2_CERT1;
+        boolean fail = true;
+        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
+        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
+        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
+                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+    }
+    public void testReplaceFirstSharedMatchNoCerts() {
+        int apk1 = SHARED1_CERT1;
+        int apk2 = SHARED2_CERT1;
+        int rapk1 = SHARED1_CERT2;
+        boolean fail = true;
+        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
+        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
+        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
+                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+    }
+    public void testReplaceSecondSharedMatchNoCerts() {
+        int apk1 = SHARED1_CERT1;
+        int apk2 = SHARED2_CERT1;
+        int rapk2 = SHARED2_CERT2;
+        boolean fail = true;
+        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
+        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
+        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
+                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+    }
+    public void testReplaceFirstSharedMatchMoreCerts() {
+        int apk1 = SHARED1_CERT1;
+        int apk2 = SHARED2_CERT1;
+        int rapk1 = SHARED1_CERT1_CERT2;
+        boolean fail = true;
+        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
+        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
+        installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
+                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+    }
+    public void testReplaceSecondSharedMatchMoreCerts() {
+        int apk1 = SHARED1_CERT1;
+        int apk2 = SHARED2_CERT1;
+        int rapk2 = SHARED2_CERT1_CERT2;
+        boolean fail = true;
+        int retCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
+        checkSharedSignatures(apk1, apk2, false, false, -1, PackageManager.SIGNATURE_MATCH);
+        installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
+                fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
+    }
     /*---------- Recommended install location tests ----*/
     /*
      * TODO's
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design.jd b/docs/html/guide/practices/ui_guidelines/icon_design.jd
index e5a1b5e..26acf75 100644
--- a/docs/html/guide/practices/ui_guidelines/icon_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/icon_design.jd
@@ -1,4 +1,4 @@
-page.title=Icon Design Guidelines
+page.title=Icon Design Guidelines, Android 2.0
 @jd:body
 
 <div id="qv-wrapper">
@@ -8,9 +8,8 @@
 
 <ul>
 <li>You can use several types of icons in an Android application.</li>
-<li>Your icons should follow the specification in this document.</li>
-<li>A set of standard icons is provided by the Android platform. Your
-application can use the standard icons by referencing them as resources.</li>
+<li>Your icons should follow the general specification in this document.</li>
+<li>You should create separate icon sets for high-, medium-, and low-density screens.</li>
 </ul>
 
 <h2>In this document</h2>
@@ -23,13 +22,14 @@
 <li><a href="#dialogstructure">Dialog icon</a></li>
 <li><a href="#listviewstructure">List view icon</a></li>
 
-<li style="margin-top:4px;"><a href="#dodonts">General guidelines</a></li>
+<li style="margin-top:3px;"><a href="#design_tips">Tips for Designers</a></li>
 <li><a href="#templatespack">Using the Icon Templates Pack</a></li>
+
 <li><a href="#iconappendix">Icon appendix</a>
 	<ol>
-	<li><a href="#launcherapx">Launcher icons</a></li>
-	<li><a href="#menuapx">Menu icons</a></li>
-	<li><a href="#statusbarapx">Status bar icons</a></li>
+	<li><a href="#launcherapx">Standard Launcher icons</a></li>
+	<li><a href="#menuapx">Standard Menu icons</a></li>
+	<li><a href="#statusbarapx">Standard Status bar icons</a></li>
 	</ol>
 </li>
 
@@ -38,176 +38,560 @@
 <h2>See also</h2>
 
 <ol>
-<li><a href="{@docRoot}shareables/icon_templates-v1.0.zip">Android Icon
-Templates Pack &raquo;</a></li>
+<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a></li>
+<li><a href="{@docRoot}shareables/icon_templates-v2.0.zip">Android Icon
+Templates Pack, v2.0 &raquo;</a></li>
 </ol>
 
+<h2>Older versions</h2>
+
+<ol>
+<li style="margin-top:4px;"><a
+href="{@docRoot}guide/practices/ui_guidelines/icon_design_1.html">Icon Design
+Guidelines, Android 1.0</a></li>
+<li><a href="{@docRoot}shareables/icon_templates-v1.0.zip">Android Icon
+Templates Pack, v1.0 &raquo;</a></li>
+</ol>
+
+
 </div>
 </div>
 
 <p>Creating a unified look and feel throughout a user interface adds value to
 your product. Streamlining the graphic style will also make the UI seem more
-professional to the user.</p>
+professional to users.</p>
 
-<p>This document shows you how to create icons for various parts
-of your application’s user interface that fit the style set by the Android UI
-team. Following these guidelines will help you to create a polished and unified
-experience for the user.</p>
+<p>This document provides information to help you create icons for various parts
+of your application’s user interface that match the general styles used by the
+Android 2.x framework. Following these guidelines will help you to create a 
+polished and unified experience for the user.</p>
 
-<p>To get started creating conforming icons more quickly, you can download 
+<p>To get started creating your icons more quickly, you can download 
 the Android Icon Templates Pack. For more information, see 
 <a href="#templatespack">Using the Android Icon Template Pack</a>.</p>
 
-<h2 id="launcherstructure">Launcher icon</h2>
 
-<p>A launcher icon is the graphic that represents your application on an Android
-device’s Home screen. It is a simplified 3D icon with a fixed perspective. The
-required perspective is shown in Figure 1.</p>
+<h2 id="icon-sets">Providing Density-Specific Icon Sets</h2>
 
-<h4 id="launcherstructure">Structure</h4>
+<p>Android is designed to run on a variety of devices that offer a range of
+screen sizes and resolutions. When you design the icons for your application,
+it's important keep in mind that your application may be installed on any of
+those devices. As described in the <a 
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a> document, the Android platform makes it straightforward for you to
+provide icons in such a way that they will be displayed properly on any device,
+regardless of the device's screen size or resolution.</p>
 
-<ul>
-<li>The base of a launcher icon can face either the top view or the front
-view.</li>
+<p>In general, the recommended approach is to create a separate set of icons for
+each of the three generalized screen densities listed in Table 1, below, then
+store them in density-specific resource directories in your application. When
+your application runs, the Android platform will check the characteristics of
+the device screen and load icons from the appropriate density-specific
+resources. For more information about how to store density-specific resources in
+your application, see <a
+href="{@docRoot}guide/practices/screens_support.html#qualifiers">Resource
+directory qualifiers for screen size and density</a>. </p>
 
-<li>The majority of a launcher icon’s surface should be created using the
-launcher icon <a href="#launcherpalette">color palette</a>. To add emphasis, use
-one or more bright accent colors to highlight specific characteristics.</li>
-
-<li>All launcher icons must be created with rounded corners to make them look
-friendly and simple—as shown in Figure 2.</li>
-
-<li>All dimensions specified are based on a 250x250 pixel artboard size
-in a vector graphics editor like Adobe Illustrator, where the icon fits within
-the artboard boundaries.</li>
-
-<li><strong>Final art must be scaled down and exported as a transparent 48x48 px
-PNG file using a raster image editor such as Adobe Photoshop.</strong></li>
-
-<li>Templates for creating launcher icons in Adobe Illustrator and Photoshop are
-available in the Icon Templates Pack.</li>
-</ul>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i" style="padding-right:0">
-  <img src="{@docRoot}images/icon_design/launcher_structure.png" alt="A view of
-launcher icon corners and perspective angles" />
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 1.</strong> Perspective angles for launcher icons (90° is
-vertical).</p>
-    <div class="image-caption-nested">
-      <table style="margin-top:0;">
-      <tr><td style="padding-right:1em"><em>1.</em></td><td>92°</td></tr>
-      <tr><td><em>2.</em></td><td>92°</td></tr>
-      <tr><td><em>3.</em></td><td>173°</td></tr>
-      <tr><td><em>4.</em></td><td>171°</td></tr>
-      <tr><td><em>5.</em></td><td>49°</td></tr>
-      <tr><td><em>6.</em></td><td>171°</td></tr>
-      <tr><td><em>7.</em></td><td>64°</td></tr>
-      <tr><td><em>8.</em></td><td>97°</td></tr>
-      <tr><td><em>9.</em></td><td>75°</td></tr>
-      <tr><td><em>10.</em></td><td>93°</td></tr>
-      <tr><td><em>11.</em></td><td>169°</td></tr>
-      </table>
-    </div>
-  </div>
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 2.</strong> Rounded corners for launcher icons.</p>
-  </div>
-</td>
-</tr>
-</table>
-
-<h4 id="launcherlight">Light, effects, and shadows</h4>
-
-<p>Launcher icons are simplified 3D icons using light and shadows for
-definition. A light source is placed slightly to the left in front of the icon,
-and therefore the shadow expands to the right and back.</p>
-
-<table class="image-caption">
-<tr>
-<td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/launcher_light.png" alt="A view of
-light, effects, and shadows for launcher icons."/>
-</td>
-<td class="image-caption-c">
-  <div class="caption grad-rule-top">
-    <p><strong>Figure 3. </strong>Light, effects, and shadows for launcher icons.</p>
-    <div class="image-caption-nested">
-    <table style="margin-top:0;">
-    <tr><td style="padding-right:1em"><em>1.</em></td><td>Edge highlight:</td><td>white</td></tr>
-    <tr><td><em>2.</em></td><td>Icon shadow:</td><td>black | 20px blur<br>50% opacity | angle 67°</td></tr>
-    <tr><td><em>3.</em></td><td>Front part:</td><td>Use light gradient from color palette</td></tr>
-    <tr><td><em>4.</em></td><td>Detail shadow:</td><td>black | 10px blur<br>75% opacity</td></tr>
-    <tr><td><em>5.</em></td><td> Side part:</td><td>Use medium gradient from color palette</td></tr>
-    </table>
-    </div>
-  </div>
-</td>
-</tr>
-</table>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td style="border:0;width:350px;">
-
-<h4 id="launcherpalette">Launcher icon color palette</h4>
-
-<table style="margin:0px;padding:0px;">
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_white.png" alt="Color palette, white" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">White<br>r 0 | g 0 | b 0<br>Used for highlights on edges.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_gradient_light.png" alt="Color palette, light gradient" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Light gradient<br><em>1:&nbsp;&nbsp;</em>r 0  | g 0  | b 0<br><em>2:&nbsp;&nbsp;</em>r 217 | g 217 | b 217<br>Used on the front (lit) part of the icon.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_gradient_medium.png" alt="Color palette, medium gradien" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Medium gradient<br><em>1:&nbsp;&nbsp;</em>r 190 | g 190 | b 190<br><em>2:&nbsp;&nbsp;</em>r 115 | g 115 | b 115<br>Used on the side (shaded) part of the icon.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_gradient_dark.png" alt="Color palette, dark gradient" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Dark gradient<br><em>1:&nbsp;&nbsp;</em>r 100 | g 100 | b 100<br><em>2:&nbsp;&nbsp;</em>r 25  | g 25  | b 25<br>Used on details and parts in the shade of the icon.</td>
-</tr>
-
-<tr>
-<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_black.png" alt="Color palette, black" style="margin:.5em 0 0 0;" /></td>
-<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 255 | g 255 | b 255<br>Used as base color in shadows.</td>
-</tr>
-
-</table>
-
-</td>
-
-<td style="border:0;width:350px">
-
-<h4 id="launchersteps">Step by step</h4>
+<p>The baseline screen density for Android devices is medium
+(<code>mdpi</code>). For this reason, a recommended approach to creating icon
+sets for multiple screen densities is to:</p>
 
 <ol>
-  <li>Create the basic shapes with a tool like Adobe Illustrator, using the
-angles described in <a href="#launcherstructure">Launcher icon: structure</a>.
-The shapes and effects must fit within a 250x250 pixel artboard.</li>
-  <li>Add depth to shapes by extruding them and create the rounded corners as
-described for the launcher icon structure.</li>
-  <li>Add details and colors. Gradients should be treated as if there is a light
-source placed slightly to the left in front of the icon.</li>
-  <li>Create the shadows with the correct angle and blur effect.</li>
-  <li>Import the icon into a tool like Adobe Photoshop and scale to fit an image
-size of 48x48 px on a transparent background.</li>
-  <li>Export the icon at 48x48 as a PNG file with transparency enabled.</li>
+<li>Design the icons for the baseline density first (see Table 1 for the actual
+pixel dimensions at which to design the icons). </li>
+<li>Place the icons in the application's default drawable resources, then run
+the application on an Android Virtual Device (AVD) or an HVGA device such as the
+T-Mobile G1. </li>
+<li>Test and adjust your baseline icons as needed.</li>
+<li>When you are satisfied with the icons you've developed at the baseline
+density, create scaled copies for the other densities. </li>
+
+<ul>
+<li>Scale the baseline icons up 150% to create the high-density assets.</li>
+<li>Scale the baseline icons down 75% to create the low-density assets.</li>
+</ul></li>
+
+<li>Place the icons in density-specific resource directories in your
+application. For example:
+<ul>
+<li>Medium-density assets go in a <code>res/drawable-mdpi/</code>
+directory (or in the default <code>res/drawable/</code> directory),</li>
+<li>High-density assets go in a <code>res/drawable-hdpi/</code> directory,
+and</li>
+<li>Low-density assets go in a <code>res/drawable-ldpi/</code>
+directory.</li>
+</ul></li>
+<li>Test and adjust the high- and low-density icons if needed</li>
 </ol>
 
+<p>For tips on how to create and manage icon sets for multiple densities, see 
+<a href="#design_tips">Tips for Designers</a>.</p>
+
+
+<p class="caption"><strong>Table 1.</strong> Summary of finished icon
+dimensions for each of the three generalized screen densities, by
+icon type.</p>
+
+  <table id="screens-table" style="margin-top:2em;">
+    <tbody>
+<tr>
+<th>Icon Type</th><th colspan="3">Standard Asset Sizes (in Pixels), for
+Generalized Screen Densities</th></tr>
+    <tr>
+      <td></td>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        <nobr>Low density screen <em>(ldpi)</em></nobr>
+      </th>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        <nobr>Medium density screen <em>(mdpi)</em></nobr>
+      </th>
+      <th  style="background-color:#f3f3f3;font-weight:normal">
+        <nobr>High density screen <em>(hdpi)</em><nobr>
+      </th>
+    </tr>
+
+    <tr>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        Launcher
+      </th>
+      <td style="font-size:.9em;">
+          36 x 36 px
+      </td>
+
+      <td style="font-size:.9em;">
+         48 x 48 px
+      </td>
+      <td style="font-size:.9em;">
+          72 x 72 px
+      </td>
+    </tr>
+
+    <tr>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        Menu
+      </th>
+      <td style="font-size:.9em;">
+          36 x 36 px
+      </td>
+
+      <td style="font-size:.9em;">
+         48 x 48 px
+      </td>
+      <td style="font-size:.9em;">
+          72 x 72 px
+      </td>
+    </tr>
+
+    <tr>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        Status Bar
+      </th>
+      <td style="font-size:.9em;">
+          24 x 24 px
+      </td>
+
+      <td style="font-size:.9em;">
+         32 x 32 px
+      </td>
+      <td style="font-size:.9em;">
+          48 x 48 px
+      </td>
+    </tr>
+    <tr>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        Tab
+      </th>
+      <td style="font-size:.9em;">
+          24 x 24 px
+      </td>
+
+      <td style="font-size:.9em;">
+         32 x 32 px
+      </td>
+      <td style="font-size:.9em;">
+          48 x 48 px
+      </td>
+    </tr>
+    <tr>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        Dialog
+      </th>
+      <td style="font-size:.9em;">
+          24 x 24 px
+      </td>
+
+      <td style="font-size:.9em;">
+         32 x 32 px
+      </td>
+      <td style="font-size:.9em;">
+          48 x 48 px
+      </td>
+    </tr>
+    <tr>
+      <th style="background-color:#f3f3f3;font-weight:normal">
+        List View
+      </th>
+      <td style="font-size:.9em;">
+          24 x 24 px
+      </td>
+
+      <td style="font-size:.9em;">
+         32 x 32 px
+      </td>
+      <td style="font-size:.9em;">
+          48 x 48 px
+      </td>
+    </tr>
+    </tbody>
+  </table>
+
+<h2 id="launcherstructure">Launcher Icon</h2>
+
+<p>A Launcher icon is a graphic that represents your application on the device’s
+Home screen and in the Launcher window.  </p>
+
+<p>The user opens the Launcher by touching the icon at the bottom of the Home
+screen. The Launcher opens and exposes the icons for all of the installed 
+applications, which are arranged in a grid. The user selects an application and 
+opens it by touching the Launcher icon or by means of any hardware navigation 
+controls available, such as a trackball or d-pad. </p>
+
+<p>The user can also drag an icon out of the Launcher window and onto the Home
+screen itself, for more convenient access to the application. In this case, the
+system displays your application's Launcher icon against the Home screen
+wallpaper, rendering it at the same dimensions as it is rendered inside the
+Launcher.</p>
+
+<p>The system manages the scaling of all Launcher icons so that they rendered at
+a uniform height and width. The actual pixel dimensions of the rendered Launcher
+icons on any given device varies, based on the size and pixel-density
+characteristics of the device's screen. To ensure the best possible rendering
+for your icons, supply versions of the icons that are designed for low, medium,
+and high density screens. For information, see <a
+href="#icon_sets">Providing Density-Specific Icon Sets</a>, above, or <a
+href="#design_tips">Tips for Designers</a>, below.</p>
+
+<h3 id="style">Style</h3>
+
+<p>The launcher icons that you create should follow the general style principles
+below. The guidelines aren't meant to restrict what you can do with your icons,
+but rather they are meant to emphasize the common approaches that your icons can
+share with others on the device. Figure 1, at right, provides examples.  </p>
+
+<div class="figure" style="padding:3em">
+  <img src="{@docRoot}images/icon_design/IconGraphic_Icons_i.png" 
+    width="340">
+  <p class="caption" style="margin:0;padding:0;margin-left:36px;">
+  <strong>Figure 1.</strong> Illustration of Launcher icon style.</p>
+</div>
+
+<p>Clean and contemporary:</p>
+
+<ul>
+  <li>Launcher icons should be current and sometimes quirky, but they should not
+appear aged or ragged. You should avoid overused symbolic metaphors whenever
+possible.</li>
+</ul>
+
+<p>Simple and iconic:</p>
+<ul>
+  <li> Android Launcher icons are caricatural in nature; your icons should be
+highly simplified and exaggerated, so that they are appropriate for use at small
+sizes. Your icons should not be overly complicated. </li>
+  <li>Try featuring a single part of an application as a symbolic
+representation of the whole (for example, the Music icon features a speaker).
+</li>
+  <li>Consider using natural outlines and shapes, both geometric and organic,
+with a realistic (but never photorealistic) rendering. </li>
+  <li>Your icons <em>should not</em> present a cropped view of a larger
+image.</li>
+</ul>
+
+<p>Tactile and textured:</p>
+<ul>
+  <li>Icons should feature non-glossy, textured material. See
+  <a href="#materials-colors">Materials and colors</a>, below, for more
+  information.</li>
+</ul>
+
+<p>Forward-facing and top-lit:</p>
+<ul>
+  <li><em>New for Android 2.0 and later platforms</em>: Android Launcher
+icons should be forward-facing, with very little perspective, and they
+should be top-lit.</li>
+</ul>
+
+Additionally, note all icons will have separate text labels, so rather than
+working to include embedded text in the design of of your icons, focus your
+efforts on the icon's visual distinctiveness and memorability instead.</p>
+
+<p>To look at more examples of the Launcher icons used by built-in Android
+applications, see <a href="#launcherapx">Standard Launcher Icons</a> in the
+Icons Appendix of this document. </p>
+
+
+
+<h3 id="dodonts">Do's and Don'ts</h3>
+
+<p>Below are some "do and don't" examples to consider when creating icons for
+your application.  </p>
+
+
+<table>
+<tr>
+<td style="border:0;width:50%;">
+
+<h4>Android Launcher icons are...</h4>
+
+<ul>
+<li>Modern, minimal, matte, tactile, and textured</li>
+<li>Forward-facing and top-lit, whole, limited in color
+palette</li>
+</ul>
+</td>
+<td style="border:0;width:50%;">
+
+<h4>Android Launcher icons are not...</h4>
+
+<ul>
+<li>Antique, over-complicated, glossy, flat vector</li>
+<li>Rotated, Cropped, Over-Saturated</li>
+</ul>
+</td>
+</tr>
+<tr>
+</table>
+
+<div style="margin-left:2em">
+<img src="{@docRoot}images/icon_design/IconGraphic_DosDonts.png" alt="Side-by-side examples
+of good/bad icon design." />
+<p class="caption" style="margin-top:.5em;">
+<strong>Figure 2.</strong> Side-by-side examples of "do's and don'ts" for
+Android launcher icons. </p>
+</div>
+
+<h3 id="materials-colors">Materials and colors</h3>
+
+<p>Launcher icons should make use of tactile, top-lit, textured materials. Even
+if your icon is just a simple shape, you should try to render in a way that
+makes it appear to be sculpted from some real-world material.</p>
+
+<p>The Launcher icons for the platform's default applications use the set of
+materials shown in Figure 3, below. Your icons can use these materials or you
+can create new materials.</p>
+
+<p>Android launcher icons usually consist of a smaller shape within a
+larger base shape and combine one neutral and one primary color. Icons may
+use a combination of neutral colors but should maintain a fairly high level of
+contrast. Icons should not use more than one primary color per icon, if
+possible.</p>
+
+<p>Launcher icons should use a limited color palette that includes a range
+of neutral and primary colors. The icons should not be over-saturated.</p>
+
+<p>The recommended color palette to use for Launcher icons is shown in Figure 4.
+You can use elements of the palette for both the base color and the highlight
+color. You can use the colors of the palette in conjunction with a
+white-to-black vertical linear gradient overlay. This creates the impression
+that the icon is lit from above and keeps the color less saturated.</p>
+
+
+
+<div style="margin:2em">
+<img src="{@docRoot}images/icon_design/IconGraphic_Materials.png" width="450" style="padding-top:2px;">
+<p class="caption" style="margin-top:.5em;">
+<strong>Figure 3.</strong> Example materials that you can use to create
+your icons.</p>
+</div>
+
+<div style="margin:2em">
+<img src="{@docRoot}images/icon_design/IconGraphic_AccentColor.png" width="450">
+<p class="caption" xstyle="margin-top:.5em;">
+<strong>Figure 4.</strong> Examples of materials combined with base
+and highlight colors from the recommended palette.</p>
+</div>
+
+
+<p>When you combine the materials above with a color highlight from the
+recommended pallete, you can create materials combinations such as those shown
+in Figure 5. To get you started, the <a href="#templatespack">icons pack</a>
+includes a Photoshop template file (<code>Launcher-icon-template.psd</code>)
+that provides all of the default materials, colors, and gradients. </p>
+
+<div style="margin:2em">
+<img src="{@docRoot}images/icon_design/IconGraphic_Colors.png" width="450" style="padding-top:2px;">
+<p class="caption" style="margin-top:.5em;">
+<strong>Figure 5.</strong> Recommended color palette for icons.</p>
+</div>
+
+
+<h3 id="size">Size and positioning</h3>
+
+<p>Launcher icons should use a variety of shapes and forms and those must be
+scaled and positioned to create consistent visual weight.</p>
+
+<p>Launcher icons should use a variety of shapes and forms and those must be
+scaled and positioned inside the asset to create consistent visual weight with
+other </p>
+
+<p>Figure 6 illustrates various ways of positioning the icon inside the asset.
+As detailed in the table below, you should size the icons <em>smaller than the
+actual bounds of the asset</em>, to create a consistent visual weight and to
+allow for the inclusion of shadows. If your icon is square or nearly square, it
+should be scaled even smaller.</p>
+
+
+<ul>
+<li>The bounding box for the full asset is shown in red.</li>
+<li>The recommended bounding box for the actual icon itself is shown in blue.
+The icon box is sized smaller than the full asset box so that there is space to
+include shadows and special icon treatments. </li>
+<li>The recommended bounding box for an icon that is square is shown in orange.
+The box for square icons is smaller than that for other icons to establish a
+consistent visual weight across the two types.</li>
+</ul>
+
+<table style="margin:2.5em 0 1em 0;">
+<tr>
+
+<td style="border:0;padding-left:72;">
+<ol class="nolist">
+  <li>Icon dimensions for high-density (<code>hdpi</code>) screens:</li>
+  <ol class="nolist">
+    <li>Full Asset: 72 x 72 px</li>
+    <li>Icon: 60 x 60 px</li>
+    <li>Square Icon: 56 x 56 px</li>
+  </ol>
+  </li>
+</ol>
+</td>
+<td style="border:0;">
+  <img src="{@docRoot}images/icon_design/IconGraphic_OpticalSize_l.png"
+   style="padding:0;margin:0;" width="450">
+</td>
+</tr>
+<tr>
+<td style="border:0;">
+  <ol class="nolist">
+  <li>Icon Dimensions for medium-density (<code>mdpi</code>) screens:</li>
+    <ol class="nolist">
+      <li>Full Asset: 48 x 48 px</li>
+      <li>Icon: 40 x 40 px</li>
+      <li>Square Icon: 38 x 38 px</li>
+    </ol>
+  </li>
+</ol>
+</td>
+
+<td style="border:0;padding-left:72;">
+ <img src="{@docRoot}images/icon_design/IconGraphic_OpticalSize_s.png"
+ style="padding:0;margin:0;" width="450">
+</td>
+</tr>
+<tr>
+<td style="border:0;">
+  <ol class="nolist">
+  <li>Icon Dimensions for low-density (<code>ldpi</code>) screens:</li>
+    <ol class="nolist">
+      <li>Full Asset: 36 x 36 px</li>
+      <li>Icon: 30 x 30 px</li>
+      <li>Square Icon: 28 x 28 px</li>
+    </ol>
+  </li>
+</ol>
+</td>
+
+<td style="border:0;padding-left:72;">
+ <img src="{@docRoot}images/icon_design/IconGraphic_OpticalSize_ldpi.png"
+ style="padding:0;margin:0;" width="450">
+
+ <p class="caption" style="margin:0;padding:0;margin-top:1.5em;"><strong>Figure
+ 6.</strong> Icon sizing and positioning inside the bounds of the
+ icon asset.</p>
+</td>
+</tr>
+
+</table>
+
+
+
+<h3>Using the Launcher Icon Template</h3>
+
+<p>Included in the Android Icon Templates Pack 2.0 is a template containing
+palettes for default icon materials and colors. The template is provided in .psd
+format for Adobe Photoshop or similar raster image editor. </p>
+
+<p>To get started, first <a
+href="{@docRoot}shareables/icon_templates-v2.0.zip">download the Android Icon
+Templates Pack 2.0 &raquo;</a>. </p>
+
+<p>Once you've downloaded the pack, unzip it and open the file
+<code>Launcher-icon-template.psd</code> in Adobe Photoshop or similar raster
+image editing program. Notice the palettes for materials and colors.  You can
+use as the template as a starting point for creating your Launcher icons. </p>
+
+<p>After you create your icon, you can add a shadow effect according to the
+specification below, as appropriate for the size of image you are creating. </p>
+
+
+<table style="margin:2.5em 0 1em 0;">
+<tr>
+
+<td style="border:0;padding-left:72;">
+  <img src="{@docRoot}images/icon_design/IconGraphic_Shadow_WVGA.png"
+   style="padding:0;margin:0;" width="450">
+</td>
+<td style="border:0;">
+<p style="padding-top:.5em;">Shadow for WVGA (high density) sreens:</p>
+  <ol class="nolist">
+    <li>Effect: Drop Shadow</li>
+    <li>Color: #000000</li>
+    <li>Blend Mode: Multiply</li>
+    <li>Opacity: 75%</li>
+    <li>Angle: 90°</li>
+    <li>Distance: 2px</li>
+    <li>Spread: 0% </li>
+    <li>Size: 5px </li>
+  </ol>
+</li>
+</ol>
+</td>
+</tr>
+<tr>
+<td style="border:0;padding-left:72;">
+  <img src="{@docRoot}images/icon_design/IconGraphic_Shadow_HVGA.png"
+   style="padding:0;margin:0;" width="450">
+</td>
+
+<td style="border:0;">
+<p style="padding-top:.5em;">Shadow for HVGA (medium density) sreens:</p>
+  <ol class="nolist">
+    <li>Effect: Drop Shadow</li>
+    <li>Color: #000000</li>
+    <li>Blend Mode: Multiply</li>
+    <li>Opacity: 75%</li>
+    <li>Angle: 90°</li>
+    <li>Distance: 1px</li>
+    <li>Spread: 0% </li>
+    <li>Size: 3px </li>
+  </ol>
+</li>
+</ol>
 </td>
 </tr>
 </table>
 
+<p>When the shadow is added and the icon is complete, export it as a PNG file
+with transparency enabled, ensuring that you size the icon at 72 x 72px for
+high-density screens and 48 x 48px for medium density screens. For more
+information about why you should provide different Launcher assets for high-,
+medium, and low-density screens, see <a
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a>.</p>
+
+
+
 <h2 id="menustructure">Menu icon</h2>
 
 <p>Menu icons are graphical elements placed in the pop-up menu shown to users
@@ -222,7 +606,7 @@
 menu icon <a href="#menupalette">color palette</a>. </li>
 
 <li>Menu icons should include rounded corners, but only when logically
-appropriate. For example, in Figure 3 the logical place for rounded corners is
+appropriate. For example, in Figure 7 the logical place for rounded corners is
 the roof and not the rest of the building.</span></li>
 
 <li>All dimensions specified on this page are based on a 48x48 pixel artboard 
@@ -247,7 +631,7 @@
 </td>
 <td class="image-caption-c">
   <div class="caption grad-rule-top">
-    <p><strong>Figure 4. </strong>Safeframe and corner-rounding for menu
+    <p><strong>Figure 7. </strong>Safeframe and corner-rounding for menu
 icons. Icon size is 48x48.</p>
   </div>
 </td>
@@ -263,11 +647,11 @@
 <table class="image-caption">
 <tr>
 <td class="image-caption-i">
-  <img src="{@docRoot}images/icon_design/menu_light.png" alt="A view of light, effects, and shadows for launcher icons."/>
+  <img src="{@docRoot}images/icon_design/menu_light.png" alt="A view of light, effects, and shadows for menu icons."/>
 </td>
 <td class="image-caption-c">
   <div class="caption grad-rule-top">
-    <p><strong>Figure 5. </strong>Light, effects, and shadows for launcher icons.</p>
+    <p><strong>Figure 8. </strong>Light, effects, and shadows for menu icons.</p>
     <div class="image-caption-nested">
     <table style="margin-top:0;">
     <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>Use fill gradient from primary color palette</td></tr>
@@ -315,7 +699,7 @@
 <li>Create the basic shapes using a tool like Adobe Illustrator.</li>
 <li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
 of 48x48 px on a transparent background. Mind the safeframe.</li>
-<li>Add the effects seen as described in Figure 5.</li>
+<li>Add the effects seen as described in Figure 8.</li>
 <li>Export the icon at 48x48 as a PNG file with transparency enabled.</li>
 </ol>
 
@@ -323,6 +707,14 @@
 </tr>
 </table>
 
+<h4 id="dodonts_menu">"Do's and don'ts"</h4>
+
+<p>Below are some "do and don't" examples to consider when creating menu icons for
+your application. </p>
+
+
+<img src="{@docRoot}images/icon_design/do_dont_menuicons.png" style="padding:0;margin:0;padding-right:30%" width="400">
+
 
 <h2 id="statusbarstructure">Status bar icon</h2>
 
@@ -334,7 +726,7 @@
 
 <ul>
 <li>Rounded corners must always be applied to the base shape and to the details
-of a status bar icon shown Figure 7.</li>
+of a status bar icon shown Figure 9.</li>
 
 <li>All dimensions specified are based on a 25x25 pixel artboard size with a 2
 pixel safeframe.</li>
@@ -356,7 +748,7 @@
 </td>
 <td class="image-caption-c">
   <div class="caption grad-rule-top">
-    <p><strong>Figure 6. </strong>Safeframe and corner-rounding for status bar
+    <p><strong>Figure 9. </strong>Safeframe and corner-rounding for status bar
 icons. Icon size is 25x25.</p>
   </div>
 </td>
@@ -373,11 +765,11 @@
 <tr>
 <td class="image-caption-i">
   <img src="{@docRoot}images/icon_design/statusbar_light.png" alt="A view of
-light, effects, and shadows for launcher icons."/>
+light, effects, and shadows for status bar icons."/>
 </td>
 <td class="image-caption-c">
   <div class="caption grad-rule-top">
-    <p><strong>Figure 7. </strong>Light, effects, and shadows for launcher icons.</p>
+    <p><strong>Figure 10. </strong>Light, effects, and shadows for status bar icons.</p>
     <div class="image-caption-nested">
     <table style="margin-top:0;">
     <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>Use fill gradient from primary color palette</td></tr>
@@ -432,8 +824,8 @@
 <li>In a tool like Adobe Photoshop, create the base shape within a 25x25 px
 image on a transparent background. Mind the safeframe, and keep the upper and
 lower 2 pixels free.</li>
-<li>Add rounded corners as specified in Figure 6.</li>
-<li>Add light, effects, and shadows as specified in Figure 7.</li>
+<li>Add rounded corners as specified in Figure 9.</li>
+<li>Add light, effects, and shadows as specified in Figure 10.</li>
 <li>Export the icon at 25x25 as a PNG file with transparency enabled.</li>
 </ol>
 
@@ -442,6 +834,16 @@
 </table>
 
 
+<h4 id="dodonts_status">"Do's and don'ts"</h4>
+
+<p>Below are some "do and don't" examples to consider when creating status bar icons for
+your application. </p>
+
+
+<img src="{@docRoot}images/icon_design/do_dont_statusicons.png" style="padding:0;margin:0;padding-right:30%" width="400">
+
+
+
 <h2 id="tabstructure">Tab icon</h2>
 
 <p>Tab icons are graphical elements used to represent individual tabs in a
@@ -477,7 +879,7 @@
 </td>
 <td class="image-caption-c">
   <div class="caption grad-rule-top">
-    <p><strong>Figure 8. </strong>Safeframe and fill gradient for unselected tab
+    <p><strong>Figure 11. </strong>Safeframe and fill gradient for unselected tab
 icons. Icon size is 32x32.</p>
   </div>
 </td>
@@ -489,7 +891,7 @@
 </td>
 <td class="image-caption-c">
   <div class="caption grad-rule-top">
-    <p><strong>Figure 9. </strong>Safeframe and fill gradient for tab icons in
+    <p><strong>Figure 12. </strong>Safeframe and fill gradient for tab icons in
 selected state. Icon size is 32x32.</p>
   </div>
 </td>
@@ -511,7 +913,7 @@
 </td>
 <td class="image-caption-c">
   <div class="caption grad-rule-top">
-    <p><strong>Figure 10. </strong>Light, effects, and shadows for unselected
+    <p><strong>Figure 13. </strong>Light, effects, and shadows for unselected
 tab icons.</p>
     <div class="image-caption-nested">
     <table style="margin-top:0;">
@@ -536,7 +938,7 @@
 <li>Create the basic shapes using a tool like Adobe Illustrator.</li>
 <li>Import the shape to a tool like Adobe Photoshop and scale to fit an image of
 32x32 px on a transparent background.</li>
-<li>Add the effects seen in Figure 10 for the unselected state filter.</li>
+<li>Add the effects seen in Figure 13 for the unselected state filter.</li>
 <li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
 </ol>
 
@@ -557,7 +959,7 @@
 </td>
 <td class="image-caption-c">
   <div class="caption grad-rule-top">
-    <p><strong>Figure 11. </strong>Light, effects, and shadows for selected tab
+    <p><strong>Figure 14. </strong>Light, effects, and shadows for selected tab
 icons.</p>
     <div class="image-caption-nested">
     <table style="margin-top:0;">
@@ -595,7 +997,7 @@
 <li>Create the basic shape using a tool like Adobe Illustrator.</li>
 <li>Import the shape into a tool like Adobe Photoshop and scale to fit a 32x32
 px artboard with a transparent background. </li>
-<li>Add the effects seen in Figure 11 for the selected state filter.</li>
+<li>Add the effects seen in Figure 14 for the selected state filter.</li>
 <li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
 </ol>
 
@@ -635,7 +1037,7 @@
 </td>
 <td class="image-caption-c">
   <div class="caption grad-rule-top">
-    <p><strong>Figure 12. </strong>Safeframe and fill gradient for dialog icons.
+    <p><strong>Figure 15. </strong>Safeframe and fill gradient for dialog icons.
 Icon size is 32x32.</p>
   </div>
 </td>
@@ -656,7 +1058,7 @@
 </td>
 <td class="image-caption-c">
   <div class="caption grad-rule-top">
-    <p><strong>Figure 13. </strong>Light, effects, and shadows for dialog
+    <p><strong>Figure 16. </strong>Light, effects, and shadows for dialog
 icons.</p>
     <div class="image-caption-nested">
     <table style="margin-top:0;">
@@ -680,7 +1082,7 @@
 <li>Create the basic shapes using a tool like Adobe Illustrator.</li>
 <li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
 of 32x32 px on a transparent background. </li>
-<li>Add the effects seen in Figure 13 for the proper filter.</li>
+<li>Add the effects seen in Figure 16 for the proper filter.</li>
 <li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
 </ol>
 
@@ -693,8 +1095,9 @@
 
 <p>List view icons look a lot like dialog icons, but they use an inner shadow
 effect where the light source is above the object. They are also designed to be
-used only in a list view. Examples include the Android Market application home
-screen and the driving directions screen in the Maps application.</p>
+used only in a {@link android.widget.ListView}. Examples include the Android 
+Market application home screen and the driving directions screen in the Maps
+application.</p>
 
 <h4>Structure</h4>
 
@@ -720,7 +1123,7 @@
 </td>
 <td class="image-caption-c">
   <div class="caption grad-rule-top">
-    <p><strong>Figure 14. </strong>Safeframe and fill gradient for list view
+    <p><strong>Figure 17. </strong>Safeframe and fill gradient for list view
 icons. Icon size is 32x32.</p>
   </div>
 </td>
@@ -741,7 +1144,7 @@
 </td>
 <td class="image-caption-c">
   <div class="caption grad-rule-top">
-    <p><strong>Figure 15. </strong>Light, effects, and shadows for list view
+    <p><strong>Figure 18. </strong>Light, effects, and shadows for list view
 icons.</p>
     <div class="image-caption-nested">
     <table style="margin-top:0;">
@@ -762,7 +1165,7 @@
 <h4 id="menusteps">Step by step</h4>
 
 <ol>
-<li>Add the effects seen in Figure 15 for the proper filter.</li>
+<li>Add the effects seen in Figure 18 for the proper filter.</li>
 <li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
 <li>Create the basic shapes using a tool like Adobe Illustrator.</li>
 <li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
@@ -773,48 +1176,266 @@
 </tr>
 </table>
 
+<h2 id="design_tips">Tips for Designers</h2>
 
-<h2 id="dodonts">General guidelines</h2>
+<p>Here are some tips that you might find useful as you develop icons or other
+drawable assets for your application. The tips assume that you are using
+Photoshop or similar raster image-editing program.</p>
 
-<p>Below are some "do and don't" guidelines to consider when creating icons for
-your application. By following the guidelines, you can ensure that your icons
-will work well with other parts of the Android platform UI and will meet the
-expectations of your application's users. </p>
+<h4>Use common naming conventions for icon assets</h4>
 
-<table style="margin:0px;padding:0px;">
+<p>Try to name files so that related assets will group together inside a
+directory when they are sorted alphabetically. In particular, it helps to use a
+common prefix for each icon type. For example:</p>
+
+<table>
 <tr>
-<td style="border:0;width:350px;">
-
-<h4>Do...</h4>
-
-<ul>
-<li>Use a normal perspective. The depth of an object should be realistic.</li>
-<li>Keep it simple! By overdoing an icon, it loses it purpose and
-readability.</li>
-<li>Use colors only when necessary. Mind that the base of a launcher icon should
-be grey and feel solid. </li>
-<li>Use the correct angles for the specific icon types.</li>
-</ul>
-</td>
-<td style="border:0;width:350px;">
-
-<h4>Don’t...</h4>
-
-<ul>
-<li>Use open elements like text alone as icons. Instead place those elements on
-a base shape.</li>
-<li>Use colors for your status bar notifications. Those are reserved for
-specific phone-only functions.</li>
-</ul>
-</td>
+<th>Asset Type</th>
+<th>Prefix</th>
+<th>Example</th>
 </tr>
 <tr>
-<td colspan="2" style="border:0;">
-<img src="{@docRoot}images/icon_design/do_dont.png" alt="Side-by-side examples
-of good/bad icon design."/>
-</td>
+<td>Icons</td>
+<td><code>ic_</code></td>
+<td><code>ic_star.png</code></td>
+</tr>
+<tr>
+<td>Launcher icons</td>
+<td><code>ic_launcher</code></td>
+<td><code>ic_launcher_calendar.png</code></td>
+</tr>
+<tr>
+<td>Menu icons</td>
+<td><code>ic_menu</code></td>
+<td><code>ic_menu_archive.png</code></td>
+</tr>
+<tr>
+<td>Status bar icons</td>
+<td><code>ic_stat_sys</code> or <code>ic_stat_notify</code></td>
+<td><code>ic_stat_notify_msg.png</code></td>
+</tr>
+<tr>
+<td>Tab icons</td>
+<td><code>ic_tab</code></td>
+<td><code>ic_tab_recent.png</code></td>
+</tr>
+<tr>
+<td>Dialog icons</td>
+<td><code>ic_dialog</code></td>
+<td><code>ic_dialog_info.png</code></td>
+</tr>
 </table>
 
+<p>Note that you are not required to use a shared prefix of any type &mdash;
+doing so is for your convenience only.</p>
+
+
+<h4>Set up a working space that organizes files for multiple densities</h4>
+
+<p>Developing multiple sets of assets for different screen densities means
+creating multiple copies of files. To help keep the multiple copies of files
+safe and easier to find, we recommend creating a directory structure in your
+working space that organizes asset files per resolution. For example:</p>
+
+<pre>assets/...
+    ldpi/...
+        _pre_production/...
+            <em>working_file</em>.psd
+        <em>finished_asset</em>.png
+    mdpi/...
+        _pre_production/...
+            <em>working_file</em>.psd
+        <em>finished_asset</em>.png
+    hdpi/...
+        _pre_production/...
+            <em>working_file</em>.psd
+        <em>finished_asset</em>.png</pre>
+
+<p>This structure parallels the density-specific structure in which you will
+ultimately store the finished assets in your application's resources. Because
+the structure in your working space is similar to that of the application, you
+can quickly determine which assets should be copied to each application
+resources directory. Separating assets by density also helps you detect any
+variances in filenames across densities, which is important because
+corresponding assets for different densities must share the same filename.</p>
+
+<p>For comparison, here's the resources directory structure of a typical
+application: </p>
+
+<pre>res/...
+    drawable-ldpi/...
+        <em>finished_asset</em>.png
+    drawable-mdpi/...
+        <em>finished_asset</em>.png
+    drawable-hdpi/...
+        <em>finished_asset</em>.png</pre>
+
+
+<h4>Create medium-density assets first</h4>
+
+<p>Since medium density is the baseline for Android, begin your designing work
+by creating the <code>mdpi</code> assets. See <a href="#screens-table">Table
+1</a>, above, for the actual pixel dimensions of various icon types. When
+possible, use vector art or paths within Photoshop layers so that it will be
+easier to scale the assets up or down later.</p>
+
+<p>For each discreet asset, or set of like assets that share the same bounding
+box dimensions, create a working Photoshop file and save it in the
+<code>_pre_production</code> directory. For example:
+<code>ic_tabs_phone_mdpi.psd</code>. This will make it easier to locate and edit
+individual assets if changes are required. It's also helpful to use a
+density-specific suffix in the filename for the working file, to avoid confusion
+when editing the files. For example: <code>_mdpi.psd</code>.</p>
+
+<p>From the <code>mdpi</code> working files, save individual flattened assets to
+the corresponding density-specific resource directory (in this case,
+<code>mdpi/</code>) in your working space.</p>
+
+
+<h4>Create high- and low-density assets from the medium-density sources</h4>
+
+<p>When you are finished working with your medium-density assets, copy the
+working files from the your workspace's <code>mdpi/_pre_production</code>
+directory to the corresponding locations in the <code>ldpi</code> and
+<code>hdpi</code> directories. If any of the working files use a
+density-specific suffix, rename the suffix to match the intended density.</p>
+
+<p>Next, open each working file in the high- and low-density directories and
+scale the image up or down to match the intended density. To create an
+<code>hdpi</code> asset, scale the image by 150%. To create an <code>ldpi</code>
+asset, scale the image down by 75%. To scale the images, follow these steps:</p>
+
+<ol>
+<li>Open the working file in Photoshop or similar program.</li>
+<li>Under the <strong>Image</strong> menu, choose <strong>Image Size</strong>.</li>
+<li>On the Image Size panel, change the Width pop up menu to "percent."</li>
+<li>Change the Width value to "150" for <code>hdpi</code> assets and "75" for <code>ldpi</code> assets.</li>
+<li>Select the Scale Styles checkbox.</li>
+<li>Select the Constrain Proportions checkbox.</li>
+<li>Select the Resample Image checkbox and set the pop up menu to "Bicubic (Best for smooth gradients)."</li>
+<li>Click <strong>OK</strong>.</li>
+</ol>
+
+<p>After you scale each image, save it to the target density-specific resource
+directory.</p>
+
+<p>If you are scaling a nine-patch image, see the section below for notes on how
+to handle the tick marks at the edge of the image. </p>
+
+
+<h4>After scaling, redraw bitmap layers as needed</h4>
+
+<p>If you scaled an image up from a bitmap layer, rather than from a vector
+layer, those layers may need to be redrawn manually to accommodate the higher
+density. For example if a 60x60 circle was painted as a bitmap for
+<code>mdpi</code> it will need to be repainted as a 90x90 circle for
+<code>hdpi</code>.</p>
+
+
+<h4>When scaling a 9-patch image, crop tick marks before scaling and replace
+them after</h4>
+
+<p>Nine-patch images include tick marks at the outer edge of the image. When you
+scale a nine-patch image, the tick marks are also scaled, which produces an
+inaccurate result. The recommended way to handle the scaling of nine-patch
+images is to remove the tick marks from the source image before scaling and then
+manually replace the tick marks at the proper size after scaling.</p>
+
+<p>To more easily determine the tick marks after the working file has been
+scaled to a new resolution, first create a temporary duplicate flattened image
+which includes the tick marks: </p>
+
+<ol>
+<li>Under the <strong>Select</strong> menu choose <strong>All</strong>.</li>
+<li>Under the <strong>Edit</strong> menu choose 
+<strong>Copy Merged</strong>.</li>
+<li>Under the <strong>File</strong> menu choose <strong>New</strong> and then
+click <strong>OK</strong> on the new panel.</li>
+<li>Under the <strong>Edit</strong> choose <strong>Paste</strong>.</li>
+</ol>
+
+<p>After creating the temporary copy, go back to the working file and crop
+the tick marks out of the working file before scaling the image:</p>
+<ol>
+<li>Under the <strong>Image</strong> menu, choose the 
+<strong>Canvas Size</strong> command.</li>
+<li>On the Canvas Size panel, subtract 2 pixels from the Width and
+Height values.</li>
+<li>Set the Anchor to "Center."</li>
+<li>Click <strong>OK</strong></li>
+</ol>
+
+<p>Scale the working file to the target density. With the working file scaled
+and the canvas enlarged so that the tick marks can be repainted:</p>
+
+<ol>
+<li>Under the <strong>Image</strong> menu, choose the 
+<strong>Canvas Size</strong> command.</li>
+<li>On the <strong>Canvas Size</strong> panel, add 2 pixels to the Width
+and Height values.</li>
+<li>Set the Anchor to "Center."</li>
+<li>Click <strong>OK</strong>.</li>
+</ol>
+
+<p>To determine tick marks, go back to duplicate flattened image and scale it to
+the target resolution. </p>
+
+<p>Copy the scaled duplicate flattened image into a new layer in the working
+file to use as reference. Create a new layer in which to paint new tick marks at
+the single pixel outer edge of the image. Note tickmarks must be 100% opaque
+black, without transparency, and all other areas of the tick mark region must be
+100% transparent, otherwise the system will not interpret the 9-patch image
+correctly. </p>
+
+<p>Using the scaled duplicate flattened image as reference paint new tick marks
+in the new layer that align with the reference layer. Note round up pixels for
+tick marks. Any pixels that are partially opaque in the reference layer should
+be fully opaqe in the new layer.</p>
+
+
+<h4>Adjust stroke and drop shadow after scaling an image</h4>
+
+<p>While it is desirable to scale layer styles for the most part (such as for
+Gradient Overlay or Inner Glow), you may need to manually reset the Stroke and
+Drop Shadow in the scaled image to 1 px before saving, especially when scaling
+to <code>hdpi</code>.
+
+<h4>Save nine-patch images with the appropriate filename suffix</h4>
+
+<p>If an asset is a 9-patch asset (with tick marks), be sure to save the asset
+in PNG format with a filename that includes the <code>.9.png</code> suffix. If
+the filename does not use the suffix, the system won't recognize the image as a
+nine-patch asset and won't resize it as intended. </p>
+
+
+<h4>When saving image assets, remove the Photoshop header</h4>
+
+<p>To help keep each image asset as small as possible, make sure to remove the
+Photoshop headers from the file. To remove the Photoshop header, follow these
+steps: </p>
+
+<ol>
+<li>Under the <strong>File</strong> menu, choose the <strong>Save for Web &amp;
+Devices</strong> command </li>
+<li>On the "Save for Web &amp; Devices" panel, set the Preset pop-up to
+"PNG-24," set the pop-up under Presets to "PNG-24" as well, and select the
+Transparency box (if the image uses transparency)</li>
+<li>Select <strong>Save</strong>.</li>
+</ol>
+
+<h4>Make sure that corresponding assets for different densities use the same
+filenames</h4>
+
+<p>Corresponding icon asset files for each density must use the same filename,
+but be stored in density-specific resource directories. This allows the system
+to look up and load the proper resource according to the resource requested by
+the application and the screen characteristics of the device. For this reason,
+make sure that the set of assets in each density-specific is consistent and do
+not use density-specific suffixes in the filenames. For more information about
+how to manage density-specific resources, see <a
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a>. </p>
+
 <h2 id="templatespack">Using the Android Icon Templates Pack</h2>
 
 <p>The Android Icon Templates Pack is a collection of template designs, filters,
@@ -831,7 +1452,7 @@
 <p>You can obtain the Icon Templates Pack archive using the link below: </p>
 
 <p style="margin-left:2em"><a
-href="{@docRoot}shareables/icon_templates-v1.0.zip">Download the Icon Templates
+href="{@docRoot}shareables/icon_templates-v2.0.zip">Download the Icon Templates
 Pack &raquo;</a>
 
 
@@ -843,148 +1464,20 @@
 icons are provided for your reference only &mdash; please do not reuse these
 icons in your applications.</code>.
 
-<table class="image-caption">
-<tr>
+<img src="{@docRoot}images/icon_design/IconGraphic_Icons.png" style="margin-top:2em;" />
 
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_alarmclock.png" alt="Android asset" />
-  <div class="caption">Alarm Clock</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_browser.png" alt="Android asset" />
-  <div class="caption">Browser</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_calculator.png" alt="Android asset" />
-  <div class="caption">Calculator</div></td>
-	
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_calendar.png" alt="Android asset" />
-  <div class="caption">Calendar</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_video_camera.png" alt="Android asset" />
-  <div class="caption">Camcorder</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_camera.png" alt="Android asset" />
-  <div class="caption">Camera</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_contacts.png" alt="Android asset" />
-  <div class="caption">Contacts</div></td>
-
-</tr>
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_phone_dialer.png" alt="Android asset" />
-  <div class="caption">Dialer</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_email_generic.png" alt="Android asset" />
-  <div class="caption">Email</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_gallery.png" alt="Android asset" />
-  <div class="caption">Gallery</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_generic_application.png" alt="Android asset" />
-  <div class="caption">Generic application</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_email.png" alt="Android asset" />
-  <div class="caption">Gmail</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_google_talk.png" alt="Android asset" />
-  <div class="caption">Google Talk</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_IM.png" alt="Android asset" />
-  <div class="caption">IM</div></td>
-
-</tr>
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_maps.png" alt="Android asset" />
-  <div class="caption">Maps</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_marketplace.png" alt="Android asset" />
-  <div class="caption">Market </div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_sms_mms.png" alt="Android asset" />
-  <div class="caption">Messaging </div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_musicplayer_2.png" alt="Android asset" />
-  <div class="caption">Music</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_settings.png" alt="Android asset" />
-  <div class="caption">Settings</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_voicedial.png" alt="Android asset" />
-  <div class="caption">Voice Dialer</div></td>
-
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_voicesearch.png" alt="Android asset" />
-  <div class="caption">Voice Search</div></td>
-
-</tr>
-<tr>
-
-<td class="image-caption-i image-list">
-  <img src="{@docRoot}images/icon_design/ic_launcher_youtube.png" alt="Android asset" />
-  <div class="caption">YouTube</div></td>
-</tr>
-</table>
 
 <h3 id="menuapx">Standard menu icons</h3>
 
-<p>Shown below are standard menu icons that are included in the Android platform
-(as of Android 1.5). You can reference any of these icon resources from your
-application as needed, but make sure that the action you assign to the icon is
-consistent with that listed. Note that this is not a complete list of icons and
-that the actual appearance of standard icons may change across platform
-versions.</p>
+<p>Shown below are standard menu icons that are used in the Android
+system. Because these resources can change between platform versions, you 
+should not reference the system's copy of the resources. If you want
+use any icons or other internal drawable resources, you should store a
+local copy of those icons or drawables in your application resources, 
+then reference the local copy from your application code. In that way, you can
+maintain control over the appearance of your icons, even if the system's
+copy changes. Note that the list below is not intended to be complete.</p>
 
-<p>To reference one of the icons from your code, use
-<code>android.R.drawable.&lt;icon_resource_identifier&gt;</code>. For example,
-you can call a menu item's {@link android.view.MenuItem#setIcon(android.graphics.drawable.Drawable) setIcon()}
-method and pass the resource name:</p> 
-
-<p style="margin-left:2em"><code>.setIcon(android.R.drawable.ic_menu_more);</code>.
-
-<p>You could reference the same icon from a layout file using
-<code>android:icon="@android:drawable/ic_menu_more"></code>.</p>
-
-<p>To determine the resource ID for an icon listed below, hover over the icon or
-simply look at image filenames, which use the format
-"&lt;icon_resource_identifier&gt;.png".</p>
 
 <table class="image-caption">
 <tr>
@@ -1115,24 +1608,14 @@
 
 <h3 id="statusbarapx">Standard status bar icons</h3>
 
-<p>Shown below are standard status bar icons included in the Android platform
-(as of Android 1.5). You can reference any of these icon resources from your
-application as needed, but make sure that the meaning of the icon is consistent
-with the standard meaning listed. Note that this is not a complete list of icons
-and that the actual appearance of standard icons may change across platform
-versions.</p>
-
-<p>To reference one of the icons from your code, use
-<code>android.R.drawable.&lt;icon_resource_identifier&gt;</code>. For example,
-you can construct a simple notification that references one of the icons like
-this: </p>
-
-<p style="margin-left:2em"><code>new Notification(R.drawable.stat_notify_calendar, 
-"sample text", System.currentTimeMillis());</code></p>
-
-<p>To determine the resource ID for an icon listed below, hover over the icon 
-or simply look at the image filename, which use the format 
-"&lt;icon_resource_identifier&gt;.png".</p>
+<p>Shown below are standard status bar icons that are used in the Android
+platform. Because these resources can change between platform versions, you 
+should not reference the system's copy of the resources. If you want
+use any icons or other internal drawable resources, you should store a
+local copy of those icons or drawables in your application resources, 
+then reference the local copy from your application code. In that way, you can
+maintain control over the appearance of your icons, even if the system's
+copy changes. Note that the list below is not intended to be complete.</p>
 
 
 <table class="image-caption">
@@ -1187,4 +1670,3 @@
 </tr>
 </table>
 
-
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design_1.jd b/docs/html/guide/practices/ui_guidelines/icon_design_1.jd
new file mode 100644
index 0000000..039f301
--- /dev/null
+++ b/docs/html/guide/practices/ui_guidelines/icon_design_1.jd
@@ -0,0 +1,1200 @@
+page.title=Icon Design Guidelines, Android 1.0
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Icon design quickview</h2>
+
+<ul>
+<li>You can use several types of icons in an Android application.</li>
+<li>Your icons should follow the specification in this document.</li>
+<li>A set of standard icons is provided by the Android platform. Your
+application can use the standard icons by referencing them as resources.</li>
+</ul>
+
+<h2>In this document</h2>
+
+<ol>
+<li><a href="#launcherstructure">Launcher icon</a></li>
+<li><a href="#menustructure">Menu icon</a></li>
+<li><a href="#statusbarstructure">Status bar icon</a></li>
+<li><a href="#tabstructure">Tab icon</a></li>
+<li><a href="#dialogstructure">Dialog icon</a></li>
+<li><a href="#listviewstructure">List view icon</a></li>
+
+<li style="margin-top:4px;"><a href="#dodonts">General guidelines</a></li>
+<li><a href="#templatespack">Using the Icon Templates Pack</a></li>
+<li><a href="#iconappendix">Icon appendix</a>
+	<ol>
+	<li><a href="#launcherapx">Launcher icons</a></li>
+	<li><a href="#menuapx">Menu icons</a></li>
+	<li><a href="#statusbarapx">Status bar icons</a></li>
+	</ol>
+</li>
+
+</ol>
+
+<h2>See also</h2>
+
+<ol>
+<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li>
+<li><a href="{@docRoot}shareables/icon_templates-v1.0.zip">Android Icon
+Templates Pack, v1.0 &raquo;</a></li>
+</ol>
+
+
+<h2>Newer versions</h2>
+
+<ol>
+<li style="margin-top:4px;"><a href="{@docRoot}guide/practices/ui_guidelines/icon_design.html">Icon Design Guidelines, Android 2.0</a></li>
+<li><a href="{@docRoot}shareables/icon_templates-v2.0.zip">Android Icon
+Templates Pack, v2.0 &raquo;</a></li>
+</ol>
+
+</div>
+</div>
+
+<p>Creating a unified look and feel throughout a user interface adds value to
+your product. Streamlining the graphic style will also make the UI seem more
+professional to the user.</p>
+
+<p>This document shows you how to create icons for various parts
+of your application’s user interface that fit the style set by the Android UI
+team. Following these guidelines will help you to create a polished and unified
+experience for the user.</p>
+
+<p>To get started creating conforming icons more quickly, you can download 
+the Android Icon Templates Pack. For more information, see 
+<a href="#templatespack">Using the Android Icon Template Pack</a>.</p>
+
+<h2 id="launcherstructure">Launcher icon</h2>
+
+<p>A launcher icon is the graphic that represents your application on an Android
+device’s Home screen. It is a simplified 3D icon with a fixed perspective. The
+required perspective is shown in Figure 1.</p>
+
+<h4 id="launcherstructure">Structure</h4>
+
+<ul>
+<li>The base of a launcher icon can face either the top view or the front
+view.</li>
+
+<li>The majority of a launcher icon’s surface should be created using the
+launcher icon <a href="#launcherpalette">color palette</a>. To add emphasis, use
+one or more bright accent colors to highlight specific characteristics.</li>
+
+<li>All launcher icons must be created with rounded corners to make them look
+friendly and simple—as shown in Figure 2.</li>
+
+<li>All dimensions specified are based on a 250x250 pixel artboard size
+in a vector graphics editor like Adobe Illustrator, where the icon fits within
+the artboard boundaries.</li>
+
+<li><strong>Final art must be scaled down and exported as a transparent 48x48 px
+PNG file using a raster image editor such as Adobe Photoshop.</strong></li>
+
+<li>Templates for creating launcher icons in Adobe Illustrator and Photoshop are
+available in the Icon Templates Pack.</li>
+</ul>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i" style="padding-right:0">
+  <img src="{@docRoot}images/icon_design/launcher_structure.png" alt="A view of
+launcher icon corners and perspective angles" />
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 1.</strong> Perspective angles for launcher icons (90° is
+vertical).</p>
+    <div class="image-caption-nested">
+      <table style="margin-top:0;">
+      <tr><td style="padding-right:1em"><em>1.</em></td><td>92°</td></tr>
+      <tr><td><em>2.</em></td><td>92°</td></tr>
+      <tr><td><em>3.</em></td><td>173°</td></tr>
+      <tr><td><em>4.</em></td><td>171°</td></tr>
+      <tr><td><em>5.</em></td><td>49°</td></tr>
+      <tr><td><em>6.</em></td><td>171°</td></tr>
+      <tr><td><em>7.</em></td><td>64°</td></tr>
+      <tr><td><em>8.</em></td><td>97°</td></tr>
+      <tr><td><em>9.</em></td><td>75°</td></tr>
+      <tr><td><em>10.</em></td><td>93°</td></tr>
+      <tr><td><em>11.</em></td><td>169°</td></tr>
+      </table>
+    </div>
+  </div>
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 2.</strong> Rounded corners for launcher icons.</p>
+  </div>
+</td>
+</tr>
+</table>
+
+<h4 id="launcherlight">Light, effects, and shadows</h4>
+
+<p>Launcher icons are simplified 3D icons using light and shadows for
+definition. A light source is placed slightly to the left in front of the icon,
+and therefore the shadow expands to the right and back.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/launcher_light.png" alt="A view of
+light, effects, and shadows for launcher icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 3. </strong>Light, effects, and shadows for launcher icons.</p>
+    <div class="image-caption-nested">
+    <table style="margin-top:0;">
+    <tr><td style="padding-right:1em"><em>1.</em></td><td>Edge highlight:</td><td>white</td></tr>
+    <tr><td><em>2.</em></td><td>Icon shadow:</td><td>black | 20px blur<br>50% opacity | angle 67°</td></tr>
+    <tr><td><em>3.</em></td><td>Front part:</td><td>Use light gradient from color palette</td></tr>
+    <tr><td><em>4.</em></td><td>Detail shadow:</td><td>black | 10px blur<br>75% opacity</td></tr>
+    <tr><td><em>5.</em></td><td> Side part:</td><td>Use medium gradient from color palette</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+<table style="margin:0px;padding:0px;">
+<tr>
+<td style="border:0;width:350px;">
+
+<h4 id="launcherpalette">Launcher icon color palette</h4>
+
+<table style="margin:0px;padding:0px;">
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_white.png" alt="Color palette, white" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-c" style="padding-top:.5em;">White<br>r 0 | g 0 | b 0<br>Used for highlights on edges.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_gradient_light.png" alt="Color palette, light gradient" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-c" style="padding-top:.5em;">Light gradient<br><em>1:&nbsp;&nbsp;</em>r 0  | g 0  | b 0<br><em>2:&nbsp;&nbsp;</em>r 217 | g 217 | b 217<br>Used on the front (lit) part of the icon.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_gradient_medium.png" alt="Color palette, medium gradien" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-c" style="padding-top:.5em;">Medium gradient<br><em>1:&nbsp;&nbsp;</em>r 190 | g 190 | b 190<br><em>2:&nbsp;&nbsp;</em>r 115 | g 115 | b 115<br>Used on the side (shaded) part of the icon.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_gradient_dark.png" alt="Color palette, dark gradient" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-c" style="padding-top:.5em;">Dark gradient<br><em>1:&nbsp;&nbsp;</em>r 100 | g 100 | b 100<br><em>2:&nbsp;&nbsp;</em>r 25  | g 25  | b 25<br>Used on details and parts in the shade of the icon.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/launcher_palette_black.png" alt="Color palette, black" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 255 | g 255 | b 255<br>Used as base color in shadows.</td>
+</tr>
+
+</table>
+
+</td>
+
+<td style="border:0;width:350px">
+
+<h4 id="launchersteps">Step by step</h4>
+
+<ol>
+  <li>Create the basic shapes with a tool like Adobe Illustrator, using the
+angles described in <a href="#launcherstructure">Launcher icon: structure</a>.
+The shapes and effects must fit within a 250x250 pixel artboard.</li>
+  <li>Add depth to shapes by extruding them and create the rounded corners as
+described for the launcher icon structure.</li>
+  <li>Add details and colors. Gradients should be treated as if there is a light
+source placed slightly to the left in front of the icon.</li>
+  <li>Create the shadows with the correct angle and blur effect.</li>
+  <li>Import the icon into a tool like Adobe Photoshop and scale to fit an image
+size of 48x48 px on a transparent background.</li>
+  <li>Export the icon at 48x48 as a PNG file with transparency enabled.</li>
+</ol>
+
+</td>
+</tr>
+</table>
+
+<h2 id="menustructure">Menu icon</h2>
+
+<p>Menu icons are graphical elements placed in the pop-up menu shown to users
+when they press the Menu button. They are drawn in a flat-front perspective.
+Elements in a menu icon must not be visualized in 3D or perspective.</p>
+
+<h4>Structure</h4>
+
+<ul>
+<li>In order to maintain consistency, all menu icons must use the same
+primary palette and the same effects. For more information, see the
+menu icon <a href="#menupalette">color palette</a>. </li>
+
+<li>Menu icons should include rounded corners, but only when logically
+appropriate. For example, in Figure 3 the logical place for rounded corners is
+the roof and not the rest of the building.</span></li>
+
+<li>All dimensions specified on this page are based on a 48x48 pixel artboard 
+size with a 6 pixel safeframe.</li>
+
+<li>The menu icon effect (the outer glow) described in <a
+href="#menulight">Light, effects, and shadows</a> can overlap the 6px safeframe,
+but only when necessary. The base shape must always stay inside the
+safeframe.</li>
+
+<li><strong>Final art must be exported as a transparent PNG file.</strong></li>
+
+<li>Templates for creating menu icons in Adobe Photoshop are available in the 
+Icon Templates Pack.</li>
+</ul>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i" style="padding-right:0">
+  <img src="{@docRoot}images/icon_design/menu_structure.png" alt="A view of menu
+icon structure." />
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 4. </strong>Safeframe and corner-rounding for menu
+icons. Icon size is 48x48.</p>
+  </div>
+</td>
+</tr>
+</table>
+
+
+<h4 id="menulight">Light, effects, and shadows</h4>
+
+<p>Menu icons are flat and pictured face on. A slight deboss and some other
+effects, which are shown below, are used to create depth.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/menu_light.png" alt="A view of light, effects, and shadows for launcher icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 5. </strong>Light, effects, and shadows for launcher icons.</p>
+    <div class="image-caption-nested">
+    <table style="margin-top:0;">
+    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>Use fill gradient from primary color palette</td></tr>
+    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 20 % opacity<br>angle 90° | distance 2px<br>size 2px</td></tr>
+    <tr><td><em>3.</em></td><td>Outer glow:</td><td>white | 55% opacity <br>spread 10% | size 3px</td></tr>
+    <tr><td><em>5.</em></td><td>Inner bevel:</td><td>depth 1% | direction down size 0px<br>angle 90° | altitude 10°<br>highlight white 70% opacity<br>shadow black 25% opacity</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+<table style="margin:0px;padding:0px;">
+<tr>
+<td style="border:0;width:350px;">
+
+<h4 id="menupalette">Color palette</h4>
+
+<table style="margin:0px;padding:0px;">
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_white.png" alt="Color palette, white" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-c" style="padding-top:.5em;">White<br>r 0 | g 0 | b 0<br>Used for outer glow and bevel highlight.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_gradient_medium.png" alt="Color palette, medium gradient" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-c" style="padding-top:.5em;">Fill gradient<br><em>1:&nbsp;&nbsp;</em>r 163 | g 163 | b 163<br><em>2:&nbsp;&nbsp;</em>r 120 | g 120 | b 120<br>Used as color fill.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_black.png" alt="Color palette, black" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 255 | g 255 | b 255<br>Used for inner shadow and bevel shadow.</td>
+</tr>
+
+</table>
+
+</td>
+
+<td style="border:0;width:350px">
+
+<h4 id="menusteps">Step by step</h4>
+
+<ol>
+<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
+<li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
+of 48x48 px on a transparent background. Mind the safeframe.</li>
+<li>Add the effects seen as described in Figure 5.</li>
+<li>Export the icon at 48x48 as a PNG file with transparency enabled.</li>
+</ol>
+
+</td>
+</tr>
+</table>
+
+
+<h2 id="statusbarstructure">Status bar icon</h2>
+
+<p>Status bar icons are used to represent notifications from your application in
+the status bar. Graphically, they are very similar to menu icons, but are
+smaller and higher in contrast.</p>
+
+<h4>Structure</h4>
+
+<ul>
+<li>Rounded corners must always be applied to the base shape and to the details
+of a status bar icon shown Figure 7.</li>
+
+<li>All dimensions specified are based on a 25x25 pixel artboard size with a 2
+pixel safeframe.</li>
+
+<li>Status bar icons can overlap the safeframe to the left and right when
+necessary, but must not overlap the safeframe at the top and bottom.</li>
+
+<li><strong>Final art must be exported as a transparent PNG file.</strong></li>
+
+<li>Templates for creating status bar icons using Adobe Photoshop are available
+in the Icon Templates Pack.</li>
+</ul>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i" style="padding-right:0">
+  <img src="{@docRoot}images/icon_design/statusbar_structure.png" alt="A view of
+status bar icon structure." />
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 6. </strong>Safeframe and corner-rounding for status bar
+icons. Icon size is 25x25.</p>
+  </div>
+</td>
+</tr>
+</table>
+
+
+<h4 id="statusbarlight">Light, effects, and shadows</h4>
+
+<p>Status bar icons are slightly debossed, high in contrast, and pictured
+face-on to enhance clarity at small sizes.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/statusbar_light.png" alt="A view of
+light, effects, and shadows for launcher icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 7. </strong>Light, effects, and shadows for launcher icons.</p>
+    <div class="image-caption-nested">
+    <table style="margin-top:0;">
+    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>Use fill gradient from primary color palette</td></tr>
+    <tr><td><em>2.</em></td><td>Inner bevel:</td><td>depth 100% | direction down<br>size 0px | angle 90° |<br>altitude 30°<br>highlight white 75% opacity<br>shadow black 75% opacity</td></tr>
+    <tr><td><em>3.</em></td><td>Detail:</td><td>white</td></tr>
+    <tr><td><em>4.</em></td><td>Disabled detail:</td><td>grey gradient from palette<br>+ inner bevel: smooth | depth 1% | direction down | size 0px | angle 117° | <br>altitude 42° | highlight white 70% | no shadow</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+<table style="margin:0px;padding:0px;">
+<tr>
+<td style="border:0;width:350px;">
+
+<h4 id="menupalette">Color palette</h4>
+
+<p>Only status bar icons related to the phone function use full color; all other status bar icons should remain monochromatic.</p>
+
+<table style="margin:0px;padding:0px;">
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_white.png" alt="Color palette, white" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-c" style="padding-top:.5em;">White<br>r 0 | g 0 | b 0<br>Used for details within the icons and bevel highlight.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_fill.png" alt="Color palette, grey gradient" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-c" style="padding-top:.5em;">Grey gradient<br><em>1:&nbsp;&nbsp;</em>r 169 | g 169 | b 169<br><em>2:&nbsp;&nbsp;</em>r 126 | g 126 | b 126<br>Used for disabled details within the icon.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_grey.png" alt="Color palette, fill gradient" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-c" style="padding-top:.5em;">Fill gradient<br><em>1:&nbsp;&nbsp;</em>1 r 105 | g 105 | b 105<br><em>2:&nbsp;&nbsp;</em>r 10   | g 10   | b 10<br>Used as color fill.</td>
+</tr>
+
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/statusbar_palette_black.png" alt="Color palette, black" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-c" style="padding-top:.5em;">Black<br>r 255 | g 255 | b 255<br>Used for bevel shadow.</td>
+</tr>
+
+</table>
+
+</td>
+
+<td style="border:0;width:350px">
+
+<h4 id="menusteps">Step by step</h4>
+
+<ol>
+<li>In a tool like Adobe Photoshop, create the base shape within a 25x25 px
+image on a transparent background. Mind the safeframe, and keep the upper and
+lower 2 pixels free.</li>
+<li>Add rounded corners as specified in Figure 6.</li>
+<li>Add light, effects, and shadows as specified in Figure 7.</li>
+<li>Export the icon at 25x25 as a PNG file with transparency enabled.</li>
+</ol>
+
+</td>
+</tr>
+</table>
+
+
+<h2 id="tabstructure">Tab icon</h2>
+
+<p>Tab icons are graphical elements used to represent individual tabs in a
+multi-tab interface. Each tab icon has two states: unselected and selected.</p>
+
+<h4>Structure</h4>
+
+<ul>
+<li>Unselected tab icons have the same fill gradient and effects as menu icons,
+but with no outer glow.</li>
+
+<li>Selected tab icons look just like unselected tab icons, but with a fainter
+inner shadow, and have the same front part gradient as dialog icons.</li>
+
+<li>Tab icons have a 1 px safeframe which should only be overlapped for the edge
+of the anti-alias of a round shape.</li>
+
+<li>All dimensions specified on this page are based on a 32x32 px artboard size.
+Keep 1 px of padding around the bounding box inside the Photoshop template.</li>
+
+<li><strong>Final art must be exported as a 32x32 px transparent PNG
+file.</strong></li>
+
+<li>Templates for creating tab icons in Adobe Photoshop are available in the
+Icon Templates Pack.</li>
+</ul>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i" style="padding-right:0">
+  <img src="{@docRoot}images/icon_design/tab_icon_unselected.png" alt="A view of
+unselected tab icon structure." />
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 8. </strong>Safeframe and fill gradient for unselected tab
+icons. Icon size is 32x32.</p>
+  </div>
+</td>
+</tr>
+<tr>
+<td class="image-caption-i" style="padding-right:0">
+  <img src="{@docRoot}images/icon_design/tab_icon_selected.png" alt="A view of
+selected tab icon structure." />
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 9. </strong>Safeframe and fill gradient for tab icons in
+selected state. Icon size is 32x32.</p>
+  </div>
+</td>
+</tr>
+</table>
+
+<h3 id="unselectedtabdetails">Unselected tab icon</h3>
+
+<h4 id="unselectedtablight">Light, effects, and shadows</h4>
+
+<p>Unselected tab icons look just like the selected tab icons, but with a
+fainter inner shadow, and the same front part gradient as the dialog icons.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/tab_unselected_light.png" alt="A view
+of light, effects, and shadows for unselected tab icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 10. </strong>Light, effects, and shadows for unselected
+tab icons.</p>
+    <div class="image-caption-nested">
+    <table style="margin-top:0;">
+    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>gradient overlay | angle 90°<br>bottom color: r 223 | g 223 | b 223<br>top color: r 249 | g 249 | b 249<br>bottom color location: 0%<br>top color location: 75%</td></tr>
+    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 10 % opacity | angle 90° distance 2px | size 2px</td></tr>
+    <tr><td><em>3.</em></td><td>Inner bevel:</td><td>depth 1% | direction down | size 0px | angle 90° | altitude 10°<br>highlight white 70% opacity<br>shadow black 25% opacity</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+
+<table style="margin:0px;padding:0px;">
+<tr>
+<td style="border:0;width:350px;">
+
+<h4 id="menusteps">Step by step</h4>
+
+<ol>
+<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
+<li>Import the shape to a tool like Adobe Photoshop and scale to fit an image of
+32x32 px on a transparent background.</li>
+<li>Add the effects seen in Figure 10 for the unselected state filter.</li>
+<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
+</ol>
+
+</td>
+</tr>
+</table>
+
+<h3 id="selectedtabdetails">Selected tab icon</h3>
+
+<p>The selected tab icons have the same fill gradient and effects as the menu
+icon, but with no outer glow.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/tab_selected_light.png" alt="A view of
+light, effects, and shadows for selected tab icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 11. </strong>Light, effects, and shadows for selected tab
+icons.</p>
+    <div class="image-caption-nested">
+    <table style="margin-top:0;">
+    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>Use fill gradient from color palette.</td></tr>
+    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 20% opacity | <br>angle 90° | distance 2px | <br>size 2px</td></tr>
+    <tr><td><em>3.</em></td><td>Inner bevel:</td><td>depth 1% | direction down | size 0px | angle 90° | <br>altitude 10°<br>highlight white 70% opacity<br>shadow black 25% opacity</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+<table style="margin:0px;padding:0px;">
+<tr>
+<td style="border:0;width:350px;">
+
+<h4 id="menupalette">Color palette</h4>
+
+<table style="margin:0px;padding:0px;">
+<tr>
+<td class="image-caption-i"><img src="{@docRoot}images/icon_design/menu_palette_gradient_medium.png" alt="Color palette, fill gradient" style="margin:.5em 0 0 0;" /></td>
+<td class="image-caption-c" style="padding-top:.5em;">Fill gradient<br><em>1:&nbsp;&nbsp;</em>r 163 | g 163 | b 163<br><em>2:&nbsp;&nbsp;</em>r 120 | g 120 | b 120<br>Used as color fill on unselected tab icons.</td>
+</tr>
+
+</table>
+
+</td>
+
+<td style="border:0;width:350px">
+
+<h4 id="menusteps">Step by step</h4>
+
+<ol>
+<li>Create the basic shape using a tool like Adobe Illustrator.</li>
+<li>Import the shape into a tool like Adobe Photoshop and scale to fit a 32x32
+px artboard with a transparent background. </li>
+<li>Add the effects seen in Figure 11 for the selected state filter.</li>
+<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
+</ol>
+
+</td>
+</tr>
+</table>
+
+
+<h2 id="dialogstructure">Dialog icon</h2>
+
+<p>Dialog icons are shown in pop-up dialog boxes that prompt the user for
+interaction. They use a light gradient and inner
+shadow in order to stand out against a dark background.</p>
+
+<h4>Structure</h4>
+
+<ul>
+<li>Dialog icons have a 1 pixel safeframe. The base shape must fit within the
+safeframe, but the anti-alias of a round shape can overlap the safeframe. <span
+class="body-copy"></li>
+
+<li>All dimensions specified on this page are based on a 32x32 pixel artboard size
+in Adobe Photoshop. Keep 1 pixel of padding around the bounding box inside the
+Photoshop template.</li>
+
+<li><strong>Final art must be exported as a transparent PNG file.</strong></li>
+
+<li>Templates for creating dialog icons in Adobe Photoshop are available in the
+Icon Templates Pack.</li>
+</ul>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i" style="padding-right:0">
+  <img src="{@docRoot}images/icon_design/dialog_icon.png" alt="A view of dialog
+icon structure." />
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 12. </strong>Safeframe and fill gradient for dialog icons.
+Icon size is 32x32.</p>
+  </div>
+</td>
+</tr>
+</table>
+
+
+<h4 id="dialoglight">Light, effects, and shadows</h4>
+
+<p>Dialog icons are flat and pictured face-on. In order to stand out against a
+dark background, they are built up using a light gradient and inner shadow.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/dialog_light.png" alt="A view of light,
+effects, and shadows for dialog icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 13. </strong>Light, effects, and shadows for dialog
+icons.</p>
+    <div class="image-caption-nested">
+    <table style="margin-top:0;">
+    <tr><td style="padding-right:1em"><em>1.</em></td><td>Front part:</td><td>gradient overlay | angle 90°<br>bottom: r 223 | g 223 | b 223<br>top: r 249 | g 249 | b 249<br>bottom color location: 0%<br>top color location: 75%</td></tr>
+    <tr><td><em>2.</em></td><td>Inner shadow:</td><td>black | 25% opacity | <br>angle -90° | distance 1px | size 0px</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+
+<table style="margin:0px;padding:0px;">
+<tr>
+<td style="border:0;width:350px;">
+
+<h4 id="menusteps">Step by step</h4>
+
+<ol>
+<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
+<li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
+of 32x32 px on a transparent background. </li>
+<li>Add the effects seen in Figure 13 for the proper filter.</li>
+<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
+</ol>
+
+</td>
+</tr>
+</table>
+
+
+<h2 id="listviewstructure">List view icon</h2>
+
+<p>List view icons look a lot like dialog icons, but they use an inner shadow
+effect where the light source is above the object. They are also designed to be
+used only in a list view. Examples include the Android Market application home
+screen and the driving directions screen in the Maps application.</p>
+
+<h4>Structure</h4>
+
+<ul>
+<li>A list view icon normally has a 1 px safeframe, but it is OK to use the
+safeframe area for the edge of the anti-alias of a round shape. </li>
+
+<li>All dimensions specified are based on a 32x32 pixel artboard size in
+Photoshop. Keep 1 pixel of padding around the bounding box inside the template.
+ </li>
+
+<li><strong>Final art must be exported as a transparent PNG file.</strong></li>
+
+<li>Templates for creating list view icons in Adobe Photoshop are available in
+the Icon Templates Pack. </li>
+</ul>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i" style="padding-right:0">
+  <img src="{@docRoot}images/icon_design/listview_icon.png" alt="A view of list
+view icon structure." />
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 14. </strong>Safeframe and fill gradient for list view
+icons. Icon size is 32x32.</p>
+  </div>
+</td>
+</tr>
+</table>
+
+<h4 id="listviewlight">Light, effects, and shadows</h4>
+
+<p>List view icons are flat and pictured face-on with an inner shadow. Built up
+by a light gradient and inner shadow, they stand out well on a dark
+background.</p>
+
+<table class="image-caption">
+<tr>
+<td class="image-caption-i">
+  <img src="{@docRoot}images/icon_design/listview_icon_details.png" alt="A view
+of light, effects, and shadows for list view icons."/>
+</td>
+<td class="image-caption-c">
+  <div class="caption grad-rule-top">
+    <p><strong>Figure 15. </strong>Light, effects, and shadows for list view
+icons.</p>
+    <div class="image-caption-nested">
+    <table style="margin-top:0;">
+    <tr><td style="padding-right:1em"><em>1.</em></td><td>Inner shadow:</td><td>black | 57 % opacity | angle 120° | blend mode normal | distance 1px | size 1px <td></tr>
+    <tr><td><em>2.</em></td><td>Background:</td><td>black | standard system color <br>These icons are displayed in list views only.</td></tr>
+    <tr><td colspan="2">Note: The list view icon sits on 32x32 px artboard in Photoshop, without a safeframe.</td></tr>
+    </table>
+    </div>
+  </div>
+</td>
+</tr>
+</table>
+
+<table style="margin:0px;padding:0px;">
+<tr>
+<td style="border:0;width:350px;">
+
+<h4 id="menusteps">Step by step</h4>
+
+<ol>
+<li>Add the effects seen in Figure 15 for the proper filter.</li>
+<li>Export the icon at 32x32 as a PNG file with transparency enabled.</li>
+<li>Create the basic shapes using a tool like Adobe Illustrator.</li>
+<li>Import the shape into a tool like Adobe Photoshop and scale to fit an image
+of 32x32 px on a transparent background. </li>
+</ol>
+
+</td>
+</tr>
+</table>
+
+
+<h2 id="dodonts">General guidelines</h2>
+
+<p>Below are some "do and don't" guidelines to consider when creating icons for
+your application. By following the guidelines, you can ensure that your icons
+will work well with other parts of the Android platform UI and will meet the
+expectations of your application's users. </p>
+
+<table style="margin:0px;padding:0px;">
+<tr>
+<td style="border:0;width:350px;">
+
+<h4>Do...</h4>
+
+<ul>
+<li>Use a normal perspective. The depth of an object should be realistic.</li>
+<li>Keep it simple! By overdoing an icon, it loses it purpose and
+readability.</li>
+<li>Use colors only when necessary. Mind that the base of a launcher icon should
+be grey and feel solid. </li>
+<li>Use the correct angles for the specific icon types.</li>
+</ul>
+</td>
+<td style="border:0;width:350px;">
+
+<h4>Don’t...</h4>
+
+<ul>
+<li>Use open elements like text alone as icons. Instead place those elements on
+a base shape.</li>
+<li>Use colors for your status bar notifications. Those are reserved for
+specific phone-only functions.</li>
+</ul>
+</td>
+</tr>
+<tr>
+<td colspan="2" style="border:0;">
+<img src="{@docRoot}images/icon_design/do_dont.png" alt="Side-by-side examples
+of good/bad icon design."/>
+</td>
+</table>
+
+<h2 id="templatespack">Using the Android Icon Templates Pack</h2>
+
+<p>The Android Icon Templates Pack is a collection of template designs, filters,
+and settings that make it easier for you to create icons that conform to the
+general specifications given in this document. We recommend downloading the
+template pack archive before you get started with your icon design.</p>
+
+<p>The icon templates are provided in Adobe Photoshop and Adobe Illustrator file
+formats, which preserves the layers and design treatments we used when creating the
+standard icons for the Android platform. You can load the template files into any 
+compatible image-editing program, although your ability to work directly with the 
+layers and treatments may vary based on the program you are using.</p>
+
+<p>You can obtain the Icon Templates Pack archive using the link below: </p>
+
+<p style="margin-left:2em"><a
+href="{@docRoot}shareables/icon_templates-v1.0.zip">Download the Icon Templates
+Pack &raquo;</a>
+
+
+<h2 id="iconappendix">Icon appendix</p>
+
+<h3 id="launcherapx">Standard launcher icons</h3>
+
+<p>Shown below are examples of launcher icons used by Android applications. The
+icons are provided for your reference only &mdash; please do not reuse these
+icons in your applications.</code>.
+
+<table class="image-caption">
+<tr>
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_alarmclock.png" alt="Android asset" />
+  <div class="caption">Alarm Clock</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_browser.png" alt="Android asset" />
+  <div class="caption">Browser</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_calculator.png" alt="Android asset" />
+  <div class="caption">Calculator</div></td>
+	
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_calendar.png" alt="Android asset" />
+  <div class="caption">Calendar</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_video_camera.png" alt="Android asset" />
+  <div class="caption">Camcorder</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_camera.png" alt="Android asset" />
+  <div class="caption">Camera</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_contacts.png" alt="Android asset" />
+  <div class="caption">Contacts</div></td>
+
+</tr>
+<tr>
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_phone_dialer.png" alt="Android asset" />
+  <div class="caption">Dialer</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_email_generic.png" alt="Android asset" />
+  <div class="caption">Email</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_gallery.png" alt="Android asset" />
+  <div class="caption">Gallery</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_generic_application.png" alt="Android asset" />
+  <div class="caption">Generic application</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_email.png" alt="Android asset" />
+  <div class="caption">Gmail</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_google_talk.png" alt="Android asset" />
+  <div class="caption">Google Talk</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_IM.png" alt="Android asset" />
+  <div class="caption">IM</div></td>
+
+</tr>
+<tr>
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_maps.png" alt="Android asset" />
+  <div class="caption">Maps</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_marketplace.png" alt="Android asset" />
+  <div class="caption">Market </div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_sms_mms.png" alt="Android asset" />
+  <div class="caption">Messaging </div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_musicplayer_2.png" alt="Android asset" />
+  <div class="caption">Music</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_settings.png" alt="Android asset" />
+  <div class="caption">Settings</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_voicedial.png" alt="Android asset" />
+  <div class="caption">Voice Dialer</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_voicesearch.png" alt="Android asset" />
+  <div class="caption">Voice Search</div></td>
+
+</tr>
+<tr>
+
+<td class="image-caption-i image-list">
+  <img src="/images/icon_design/ic_launcher_youtube.png" alt="Android asset" />
+  <div class="caption">YouTube</div></td>
+</tr>
+</table>
+
+<h3 id="menuapx">Standard menu icons</h3>
+
+<p>Shown below are standard menu icons that are included in the Android platform
+(as of Android 1.5). You can reference any of these icon resources from your
+application as needed, but make sure that the action you assign to the icon is
+consistent with that listed. Note that this is not a complete list of icons and
+that the actual appearance of standard icons may change across platform
+versions.</p>
+
+<p>To reference one of the icons from your code, use
+<code>android.R.drawable.&lt;icon_resource_identifier&gt;</code>. For example,
+you can call a menu item's {@link android.view.MenuItem#setIcon(android.graphics.drawable.Drawable) setIcon()}
+method and pass the resource name:</p> 
+
+<p style="margin-left:2em"><code>.setIcon(android.R.drawable.ic_menu_more);</code>.
+
+<p>You could reference the same icon from a layout file using
+<code>android:icon="@android:drawable/ic_menu_more"></code>.</p>
+
+<p>To determine the resource ID for an icon listed below, hover over the icon or
+simply look at image filenames, which use the format
+"&lt;icon_resource_identifier&gt;.png".</p>
+
+<table class="image-caption">
+<tr>
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_add.png" title="ic_menu_add" alt="Android asset" />
+  <div class="caption">Add</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_call.png" title="ic_menu_call" alt="Android asset" />
+  <div class="caption">Call</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_camera.png" title="ic_menu_camera" alt="Android asset" />
+  <div class="caption">Camera</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_close_clear_cancel.png" title="ic_menu_close_clear_cancel" alt="Android asset" />
+  <div class="caption">Clear / Close / Cancel / Discard </div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_compass.png" title="ic_menu_compass" alt="Android asset" />
+  <div class="caption">Compass</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_delete.png" title="ic_menu_delete" alt="Android asset" />
+  <div class="caption">Delete</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_directions.png" title="ic_menu_directions" alt="Android asset" />
+  <div class="caption">Directions</div></td>
+
+</tr>
+<tr>
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_edit.png" title="ic_menu_edit" alt="Android asset" />
+  <div class="caption">Edit</div></td>
+
+
+<td class="image-caption-i image-list">	
+  <img src="{@docRoot}images/icon_design/ic_menu_gallery.png" title="ic_menu_gallery" alt="Android asset" />
+  <div class="caption">Gallery</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_help.png" title="ic_menu_help" alt="Android asset" />
+  <div class="caption">Help</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_info_details.png" title="ic_menu_info_details" alt="Android asset" />
+  <div class="caption">Info / details</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_mapmode.png" title="ic_menu_mapmode" alt="Android asset" />
+  <div class="caption">Map mode</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_mylocation.png" title="ic_menu_mylocation" alt="Android asset" />
+  <div class="caption">My Location</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_more.png" title="ic_menu_more" alt="Android asset" />
+  <div class="caption">More</div></td>
+
+</tr>
+<tr>
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_preferences.png" title="ic_menu_preferences" alt="Android asset" />
+  <div class="caption">Preferences</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_rotate.png" title="ic_menu_rotate" alt="Android asset" />
+  <div class="caption">Rotate</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_save.png" title="ic_menu_save" alt="Android asset" />
+  <div class="caption">Save</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_send.png" title="ic_menu_send" alt="Android asset" />
+  <div class="caption">Send</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_search.png" title="ic_menu_search" alt="Android asset" />
+  <div class="caption">Search</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_share.png" title="ic_menu_share" alt="Android asset" />
+  <div class="caption">Share</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_upload.png" title="ic_menu_upload" alt="Android asset" />
+  <div class="caption">Upload</div></td>
+
+</tr>
+<tr>
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_view.png" title="ic_menu_view" alt="Android asset" />
+  <div class="caption">View</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/ic_menu_zoom.png" title="ic_menu_zoom" alt="Android asset" />
+  <div class="caption">Zoom</div></td>
+
+</tr>
+</table>
+
+
+<h3 id="statusbarapx">Standard status bar icons</h3>
+
+<p>Shown below are standard status bar icons included in the Android platform
+(as of Android 1.5). You can reference any of these icon resources from your
+application as needed, but make sure that the meaning of the icon is consistent
+with the standard meaning listed. Note that this is not a complete list of icons
+and that the actual appearance of standard icons may change across platform
+versions.</p>
+
+<p>To reference one of the icons from your code, use
+<code>android.R.drawable.&lt;icon_resource_identifier&gt;</code>. For example,
+you can construct a simple notification that references one of the icons like
+this: </p>
+
+<p style="margin-left:2em"><code>new Notification(R.drawable.stat_notify_calendar, 
+"sample text", System.currentTimeMillis());</code></p>
+
+<p>To determine the resource ID for an icon listed below, hover over the icon 
+or simply look at the image filename, which use the format 
+"&lt;icon_resource_identifier&gt;.png".</p>
+
+
+<table class="image-caption">
+<tr>
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/stat_sys_data_bluetooth.png" title="stat_sys_data_bluetooth" alt="Android asset" />
+  <div class="caption">Bluetooth</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/stat_notify_email_generic.png" title="stat_notify_email_generic" alt="Android asset" />
+  <div class="caption">Email</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/stat_notify_chat.png" title="stat_notify_chat" alt="Android asset" />
+  <div class="caption">IM</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/stat_notify_voicemail.png" title="stat_notify_voicemail" alt="Android asset" />
+  <div class="caption">Voicemail</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/stat_sys_warning.png" title="stat_sys_warning" alt="Android asset" />
+  <div class="caption">Warning</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/stat_sys_phone_call.png" title="stat_sys_phone_call" alt="Android asset" />
+  <div class="caption">Call</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/stat_sys_phone_call_forward.png" title="stat_sys_phone_call_forward" alt="Android asset" />
+  <div class="caption">Call forward</div></td>
+
+</tr>
+<tr>
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/stat_sys_phone_call_on_hold.png" title="stat_sys_phone_call_on_hold" alt="Android asset" />
+  <div class="caption">Call on hold</div></td>
+
+
+<td class="image-caption-i image-list">
+  <img src="{@docRoot}images/icon_design/stat_notify_missed_call.png" title="stat_notify_missed_call" alt="Android asset" />
+  <div class="caption">Missed call</div></td>
+
+</tr>
+</table>
+
+
diff --git a/docs/html/guide/practices/ui_guidelines/index.jd b/docs/html/guide/practices/ui_guidelines/index.jd
index 2d14fa6..ea3551d 100644
--- a/docs/html/guide/practices/ui_guidelines/index.jd
+++ b/docs/html/guide/practices/ui_guidelines/index.jd
@@ -12,7 +12,7 @@
  <dl>
   <dt><a href="{@docRoot}guide/practices/ui_guidelines/icon_design.html">Icon
 Design Guidelines</a> and <a
-href="{@docRoot}shareables/icon_templates-v1.0.zip">Android Icon Templates Pack
+href="{@docRoot}shareables/icon_templates-v2.0.zip">Android Icon Templates Pack
 &raquo; </a></dt>
   <dd>Your applications need a wide variety of icons, from a launcher icon to
 icons in menus, dialogs, tabs, the status bar, and lists. The Icon Guidelines
diff --git a/docs/html/images/icon_design/IconGraphic_AccentColor.png b/docs/html/images/icon_design/IconGraphic_AccentColor.png
new file mode 100644
index 0000000..93ebf8d
--- /dev/null
+++ b/docs/html/images/icon_design/IconGraphic_AccentColor.png
Binary files differ
diff --git a/docs/html/images/icon_design/IconGraphic_Colors.png b/docs/html/images/icon_design/IconGraphic_Colors.png
new file mode 100644
index 0000000..f70eefc
--- /dev/null
+++ b/docs/html/images/icon_design/IconGraphic_Colors.png
Binary files differ
diff --git a/docs/html/images/icon_design/IconGraphic_DosDonts.png b/docs/html/images/icon_design/IconGraphic_DosDonts.png
new file mode 100644
index 0000000..db27ec1
--- /dev/null
+++ b/docs/html/images/icon_design/IconGraphic_DosDonts.png
Binary files differ
diff --git a/docs/html/images/icon_design/IconGraphic_Icons.png b/docs/html/images/icon_design/IconGraphic_Icons.png
new file mode 100644
index 0000000..ff17062
--- /dev/null
+++ b/docs/html/images/icon_design/IconGraphic_Icons.png
Binary files differ
diff --git a/docs/html/images/icon_design/IconGraphic_Icons_i.png b/docs/html/images/icon_design/IconGraphic_Icons_i.png
new file mode 100644
index 0000000..f389e14
--- /dev/null
+++ b/docs/html/images/icon_design/IconGraphic_Icons_i.png
Binary files differ
diff --git a/docs/html/images/icon_design/IconGraphic_Materials.png b/docs/html/images/icon_design/IconGraphic_Materials.png
new file mode 100644
index 0000000..52bb173
--- /dev/null
+++ b/docs/html/images/icon_design/IconGraphic_Materials.png
Binary files differ
diff --git a/docs/html/images/icon_design/IconGraphic_OpticalSize_l.png b/docs/html/images/icon_design/IconGraphic_OpticalSize_l.png
new file mode 100644
index 0000000..1572ced
--- /dev/null
+++ b/docs/html/images/icon_design/IconGraphic_OpticalSize_l.png
Binary files differ
diff --git a/docs/html/images/icon_design/IconGraphic_OpticalSize_ldpi.png b/docs/html/images/icon_design/IconGraphic_OpticalSize_ldpi.png
new file mode 100644
index 0000000..4f6fdaa
--- /dev/null
+++ b/docs/html/images/icon_design/IconGraphic_OpticalSize_ldpi.png
Binary files differ
diff --git a/docs/html/images/icon_design/IconGraphic_OpticalSize_s.png b/docs/html/images/icon_design/IconGraphic_OpticalSize_s.png
new file mode 100644
index 0000000..99704d2c
--- /dev/null
+++ b/docs/html/images/icon_design/IconGraphic_OpticalSize_s.png
Binary files differ
diff --git a/docs/html/images/icon_design/IconGraphic_Shadow_HVGA.png b/docs/html/images/icon_design/IconGraphic_Shadow_HVGA.png
new file mode 100644
index 0000000..0a7380b
--- /dev/null
+++ b/docs/html/images/icon_design/IconGraphic_Shadow_HVGA.png
Binary files differ
diff --git a/docs/html/images/icon_design/IconGraphic_Shadow_WVGA.png b/docs/html/images/icon_design/IconGraphic_Shadow_WVGA.png
new file mode 100644
index 0000000..0e9375b
--- /dev/null
+++ b/docs/html/images/icon_design/IconGraphic_Shadow_WVGA.png
Binary files differ
diff --git a/docs/html/images/icon_design/do_dont_menuicons.png b/docs/html/images/icon_design/do_dont_menuicons.png
new file mode 100644
index 0000000..b53db96
--- /dev/null
+++ b/docs/html/images/icon_design/do_dont_menuicons.png
Binary files differ
diff --git a/docs/html/images/icon_design/do_dont_statusicons.png b/docs/html/images/icon_design/do_dont_statusicons.png
new file mode 100644
index 0000000..20c6737
--- /dev/null
+++ b/docs/html/images/icon_design/do_dont_statusicons.png
Binary files differ
diff --git a/docs/html/shareables/icon_templates-v2.0.zip b/docs/html/shareables/icon_templates-v2.0.zip
new file mode 100644
index 0000000..1c4b4988
--- /dev/null
+++ b/docs/html/shareables/icon_templates-v2.0.zip
Binary files differ
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index b56e638..47a1ec3 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1245,7 +1245,7 @@
 
     /**
      * Used to indicate a gain of audio focus, or a request of audio focus, of unknown duration.
-     * @see OnAudioFocusChangeListener#onAudioFocusChanged(int)
+     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
      * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)
      */
     public static final int AUDIOFOCUS_GAIN = 1;
@@ -1253,7 +1253,7 @@
      * Used to indicate a temporary gain or request of audio focus, anticipated to last a short
      * amount of time. Examples of temporary changes are the playback of driving directions, or an
      * event notification.
-     * @see OnAudioFocusChangeListener#onAudioFocusChanged(int)
+     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
      * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)
      */
     public static final int AUDIOFOCUS_GAIN_TRANSIENT = 2;
@@ -1263,25 +1263,25 @@
      * after having lowered their output level (also referred to as "ducking").
      * Examples of temporary changes are the playback of driving directions where playback of music
      * in the background is acceptable.
-     * @see OnAudioFocusChangeListener#onAudioFocusChanged(int)
+     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
      * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)
      */
     public static final int AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK = 3;
     /**
      * Used to indicate a loss of audio focus of unknown duration.
-     * @see OnAudioFocusChangeListener#onAudioFocusChanged(int)
+     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
      */
     public static final int AUDIOFOCUS_LOSS = -1 * AUDIOFOCUS_GAIN;
     /**
      * Used to indicate a transient loss of audio focus.
-     * @see OnAudioFocusChangeListener#onAudioFocusChanged(int)
+     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
      */
     public static final int AUDIOFOCUS_LOSS_TRANSIENT = -1 * AUDIOFOCUS_GAIN_TRANSIENT;
     /**
      * Used to indicate a transient loss of audio focus where the loser of the audio focus can
      * lower its output volume if it wants to continue playing (also referred to as "ducking"), as
      * the new focus owner doesn't require others to be silent.
-     * @see OnAudioFocusChangeListener#onAudioFocusChanged(int)
+     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
      */
     public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK =
             -1 * AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK;
@@ -1303,7 +1303,7 @@
          *   {@link AudioManager#AUDIOFOCUS_LOSS}, {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT}
          *   and {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}.
          */
-        public void onAudioFocusChanged(int focusChange);
+        public void onAudioFocusChange(int focusChange);
     }
 
     /**
@@ -1350,7 +1350,7 @@
                             listener = findFocusListener((String)msg.obj);
                         }
                         if (listener != null) {
-                            listener.onAudioFocusChanged(msg.what);
+                            listener.onAudioFocusChange(msg.what);
                         }
                     }
                 };
diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java
index 1ffb427..e088417 100644
--- a/services/java/com/android/server/AlarmManagerService.java
+++ b/services/java/com/android/server/AlarmManagerService.java
@@ -400,7 +400,7 @@
     }
     
     public long timeToNextAlarm() {
-        long nextAlarm = 0xfffffffffffffffl;
+        long nextAlarm = Long.MAX_VALUE;
         synchronized (mLock) {
             for (int i=AlarmManager.RTC_WAKEUP;
                     i<=AlarmManager.ELAPSED_REALTIME; i++) {
@@ -420,7 +420,18 @@
     {
         if (mDescriptor != -1)
         {
-            set(mDescriptor, alarm.type, (alarm.when * 1000 * 1000));
+            // The kernel never triggers alarms with negative wakeup times
+            // so we ensure they are positive.
+            long alarmSeconds, alarmNanoseconds;
+            if (alarm.when < 0) {
+                alarmSeconds = 0;
+                alarmNanoseconds = 0;
+            } else {
+                alarmSeconds = alarm.when / 1000;
+                alarmNanoseconds = (alarm.when % 1000) * 1000 * 1000;
+            }
+            
+            set(mDescriptor, alarm.type, alarmSeconds, alarmNanoseconds);
         }
         else
         {
@@ -499,7 +510,7 @@
     
     private native int init();
     private native void close(int fd);
-    private native void set(int fd, int type, long nanoseconds);
+    private native void set(int fd, int type, long seconds, long nanoseconds);
     private native int waitForAlarm(int fd);
     private native int setKernelTimezone(int fd, int minuteswest);
 
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 8788cd5..ef1738b 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -1824,21 +1824,19 @@
         if (s2 == null) {
             return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
         }
-        final int N1 = s1.length;
-        final int N2 = s2.length;
-        for (int i=0; i<N1; i++) {
-            boolean match = false;
-            for (int j=0; j<N2; j++) {
-                if (s1[i].equals(s2[j])) {
-                    match = true;
-                    break;
-                }
-            }
-            if (!match) {
-                return PackageManager.SIGNATURE_NO_MATCH;
-            }
+        HashSet<Signature> set1 = new HashSet<Signature>();
+        for (Signature sig : s1) {
+            set1.add(sig);
         }
-        return PackageManager.SIGNATURE_MATCH;
+        HashSet<Signature> set2 = new HashSet<Signature>();
+        for (Signature sig : s2) {
+            set2.add(sig);
+        }
+        // Make sure s2 contains all signatures in s1.
+        if (set1.equals(set2)) {
+            return PackageManager.SIGNATURE_MATCH;
+        }
+        return PackageManager.SIGNATURE_NO_MATCH;
     }
 
     public String[] getPackagesForUid(int uid) {
@@ -2490,6 +2488,9 @@
                     mLastScanError = pp.getParseError();
                     return false;
                 }
+            } else {
+                // Lets implicitly assign existing certificates.
+                pkg.mSignatures = ps.signatures.mSignatures;
             }
         }
         return true;
@@ -2618,28 +2619,27 @@
     }
 
     private boolean verifySignaturesLP(PackageSetting pkgSetting,
-            PackageParser.Package pkg, int parseFlags, boolean updateSignature) {
-        if (pkg.mSignatures != null) {
-            if (!pkgSetting.signatures.updateSignatures(pkg.mSignatures,
-                    updateSignature)) {
-                Slog.e(TAG, "Package " + pkg.packageName
-                        + " signatures do not match the previously installed version; ignoring!");
-                mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
-                return false;
-            }
-
-            if (pkgSetting.sharedUser != null) {
-                if (!pkgSetting.sharedUser.signatures.mergeSignatures(
-                        pkg.mSignatures, updateSignature)) {
+            PackageParser.Package pkg) {
+        if (pkgSetting.signatures.mSignatures != null) {
+            // Already existing package. Make sure signatures match
+            if (checkSignaturesLP(pkgSetting.signatures.mSignatures, pkg.mSignatures) !=
+                PackageManager.SIGNATURE_MATCH) {
                     Slog.e(TAG, "Package " + pkg.packageName
-                            + " has no signatures that match those in shared user "
-                            + pkgSetting.sharedUser.name + "; ignoring!");
-                    mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
+                            + " signatures do not match the previously installed version; ignoring!");
+                    mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
                     return false;
                 }
+        }
+        // Check for shared user signatures
+        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
+            if (checkSignaturesLP(pkgSetting.sharedUser.signatures.mSignatures,
+                    pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
+                Slog.e(TAG, "Package " + pkg.packageName
+                        + " has no signatures that match those in shared user "
+                        + pkgSetting.sharedUser.name + "; ignoring!");
+                mLastScanError = PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
+                return false;
             }
-        } else {
-            pkg.mSignatures = pkgSetting.signatures.mSignatures;
         }
         return true;
     }
@@ -2973,10 +2973,8 @@
             pkg.applicationInfo.uid = pkgSetting.userId;
             pkg.mExtras = pkgSetting;
 
-            if (!verifySignaturesLP(pkgSetting, pkg, parseFlags,
-                    (scanMode&SCAN_UPDATE_SIGNATURE) != 0)) {
+            if (!verifySignaturesLP(pkgSetting, pkg)) {
                 if ((parseFlags&PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
-                    mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
                     return null;
                 }
                 // The signature has changed, but this package is in the system
@@ -2988,8 +2986,9 @@
                 // associated with an overall shared user, which doesn't seem all
                 // that unreasonable.
                 if (pkgSetting.sharedUser != null) {
-                    if (!pkgSetting.sharedUser.signatures.mergeSignatures(
-                            pkg.mSignatures, false)) {
+                    if (checkSignaturesLP(pkgSetting.sharedUser.signatures.mSignatures,
+                            pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
+                        Log.w(TAG, "Signature mismatch for shared user : " + pkgSetting.sharedUser);
                         mLastScanError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
                         return null;
                     }
@@ -5519,7 +5518,7 @@
         // First find the old package info and check signatures
         synchronized(mPackages) {
             oldPackage = mPackages.get(pkgName);
-            if (checkSignaturesLP(pkg.mSignatures, oldPackage.mSignatures)
+            if (checkSignaturesLP(oldPackage.mSignatures, pkg.mSignatures)
                     != PackageManager.SIGNATURE_MATCH) {
                 res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
                 return;
@@ -5547,7 +5546,6 @@
             oldInstallerPackageName = mSettings.getInstallerPackageName(pkgName);
         }
 
-        parseFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
         // First delete the existing package while retaining the data directory
         if (!deletePackageLI(pkgName, true, PackageManager.DONT_DELETE_DATA,
                 res.removedInfo)) {
@@ -5571,20 +5569,7 @@
             }
         }
 
-        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
-            // If we deleted an exisiting package, the old source and resource files that we
-            // were keeping around in case we needed them (see below) can now be deleted.
-            // This info will be set on the res.removedInfo to clean up later on as post
-            // install action.
-
-            //update signature on the new package setting
-            //this should always succeed, since we checked the
-            //signature earlier.
-            synchronized(mPackages) {
-                verifySignaturesLP(mSettings.mPackages.get(pkgName), pkg,
-                        parseFlags, true);
-            }
-        } else {
+        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
             // remove package from internal structures.  Note that we want deletePackageX to
             // delete the package data and cache directories that it created in
             // scanPackageLocked, unless those directories existed before we even tried to
@@ -5603,19 +5588,23 @@
                     Slog.e(TAG, "Failed allocating storage when restoring pkg : " + pkgName);
                     return;
                 }
-                PackageInstalledInfo restoreRes = new PackageInstalledInfo();
-                restoreRes.removedInfo = new PackageRemovedInfo();
                 // Parse old package
-                parseFlags &= ~PackageManager.INSTALL_REPLACE_EXISTING;
-                scanPackageLI(restoreFile, parseFlags, scanMode);
+                boolean oldOnSd = isExternal(deletedPackage);
+                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
+                        (isForwardLocked(deletedPackage) ? PackageParser.PARSE_FORWARD_LOCK : 0) |
+                        (oldOnSd ? PackageParser.PARSE_ON_SDCARD : 0);
+                int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE;
+                if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode) == null) {
+                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade");
+                    return;
+                }
+                // Restore of old package succeeded. Update permissions.
                 synchronized (mPackages) {
                     updatePermissionsLP(deletedPackage.packageName, deletedPackage,
                             true, false);
                     mSettings.writeLP();
                 }
-                if (restoreRes.returnCode != PackageManager.INSTALL_SUCCEEDED) {
-                    Slog.e(TAG, "Failed restoring pkg : " + pkgName + " after failed upgrade");
-                }
+                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
             }
         }
     }
@@ -5667,15 +5656,7 @@
             updatedSettings = true;
         }
 
-        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
-            //update signature on the new package setting
-            //this should always succeed, since we checked the
-            //signature earlier.
-            synchronized(mPackages) {
-                verifySignaturesLP(mSettings.mPackages.get(packageName), pkg,
-                        parseFlags, true);
-            }
-        } else {
+        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
             // Re installation failed. Restore old information
             // Remove new pkg information
             if (newPackage != null) {
@@ -5757,7 +5738,7 @@
         boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
         boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0);
         boolean replace = false;
-        int scanMode = SCAN_MONITOR | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE
+        int scanMode = (onSd ? 0 : SCAN_MONITOR) | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE
                 | (newInstall ? SCAN_NEW_INSTALL : 0);
         // Result object to be returned
         res.returnCode = PackageManager.INSTALL_SUCCEEDED;
@@ -5887,6 +5868,10 @@
         return  ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
     }
 
+    private boolean isExternal(PackageParser.Package pkg) {
+        return  ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
+    }
+
     private void extractPublicFiles(PackageParser.Package newPackage,
                                     File publicZipFile) throws IOException {
         final ZipOutputStream publicZipOutStream =
@@ -7316,101 +7301,6 @@
             }
         }
 
-        /**
-         * If any of the given 'sigs' is contained in the existing signatures,
-         * then completely replace the current signatures with the ones in
-         * 'sigs'.  This is used for updating an existing package to a newly
-         * installed version.
-         */
-        boolean updateSignatures(Signature[] sigs, boolean update) {
-            if (mSignatures == null) {
-                if (update) {
-                    assignSignatures(sigs);
-                }
-                return true;
-            }
-            if (sigs == null) {
-                return false;
-            }
-
-            for (int i=0; i<sigs.length; i++) {
-                Signature sig = sigs[i];
-                for (int j=0; j<mSignatures.length; j++) {
-                    if (mSignatures[j].equals(sig)) {
-                        if (update) {
-                            assignSignatures(sigs);
-                        }
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-
-        /**
-         * If any of the given 'sigs' is contained in the existing signatures,
-         * then add in any new signatures found in 'sigs'.  This is used for
-         * including a new package into an existing shared user id.
-         */
-        boolean mergeSignatures(Signature[] sigs, boolean update) {
-            if (mSignatures == null) {
-                if (update) {
-                    assignSignatures(sigs);
-                }
-                return true;
-            }
-            if (sigs == null) {
-                return false;
-            }
-
-            Signature[] added = null;
-            int addedCount = 0;
-            boolean haveMatch = false;
-            for (int i=0; i<sigs.length; i++) {
-                Signature sig = sigs[i];
-                boolean found = false;
-                for (int j=0; j<mSignatures.length; j++) {
-                    if (mSignatures[j].equals(sig)) {
-                        found = true;
-                        haveMatch = true;
-                        break;
-                    }
-                }
-
-                if (!found) {
-                    if (added == null) {
-                        added = new Signature[sigs.length];
-                    }
-                    added[i] = sig;
-                    addedCount++;
-                }
-            }
-
-            if (!haveMatch) {
-                // Nothing matched -- reject the new signatures.
-                return false;
-            }
-            if (added == null) {
-                // Completely matched -- nothing else to do.
-                return true;
-            }
-
-            // Add additional signatures in.
-            if (update) {
-                Signature[] total = new Signature[addedCount+mSignatures.length];
-                System.arraycopy(mSignatures, 0, total, 0, mSignatures.length);
-                int j = mSignatures.length;
-                for (int i=0; i<added.length; i++) {
-                    if (added[i] != null) {
-                        total[j] = added[i];
-                        j++;
-                    }
-                }
-                mSignatures = total;
-            }
-            return true;
-        }
-
         private void assignSignatures(Signature[] sigs) {
             if (sigs == null) {
                 mSignatures = null;
@@ -8191,6 +8081,15 @@
              if (pkg.mVersionCode != p.versionCode) {
                 p.versionCode = pkg.mVersionCode;
             }
+             // Update signatures if needed.
+             if (p.signatures.mSignatures == null) {
+                 p.signatures.assignSignatures(pkg.mSignatures);
+             }
+             // If this app defines a shared user id initialize
+             // the shared user signatures as well.
+             if (p.sharedUser != null && p.sharedUser.signatures.mSignatures == null) {
+                 p.sharedUser.signatures.assignSignatures(pkg.mSignatures);
+             }
             addPackageSettingLP(p, pkg.packageName, p.sharedUser);
         }
 
@@ -9619,22 +9518,12 @@
                // Parse package
                int parseFlags = PackageParser.PARSE_CHATTY |
                        PackageParser.PARSE_ON_SDCARD | mDefParseFlags;
-               PackageParser pp = new PackageParser(codePath);
-               pp.setSeparateProcesses(mSeparateProcesses);
-               final PackageParser.Package pkg = pp.parsePackage(new File(codePath),
-                       codePath, mMetrics, parseFlags);
-               pp = null;
                doGc = true;
-               // Check for parse errors
-               if (pkg == null) {
-                   Slog.e(TAG, "Parse error when installing install pkg : "
-                           + args.cid + " from " + args.cachePath);
-                   continue;
-               }
-               setApplicationInfoPaths(pkg, codePath, codePath);
                synchronized (mInstallLock) {
+                   final PackageParser.Package pkg =  scanPackageLI(new File(codePath),
+                           parseFlags, 0);
                    // Scan the package
-                   if (scanPackageLI(pkg, parseFlags, SCAN_MONITOR) != null) {
+                   if (pkg != null) {
                        synchronized (mPackages) {
                            retCode = PackageManager.INSTALL_SUCCEEDED;
                            pkgList.add(pkg.packageName);
@@ -9642,8 +9531,8 @@
                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED);
                        }
                    } else {
-                       Slog.i(TAG, "Failed to install pkg: " +
-                               pkg.packageName + " from sdcard");
+                       Slog.i(TAG, "Failed to install pkg from  " +
+                               codePath + " from sdcard");
                    }
                }
 
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index c40650a..1850b9a 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -19,14 +19,12 @@
 import android.app.Activity;
 import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
-import android.app.IActivityManager;
 import android.app.IUiModeManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
 import android.app.UiModeManager;
-import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -310,9 +308,6 @@
     }
 
     public void enableCarMode() {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.ENABLE_CAR_MODE,
-                "Need ENABLE_CAR_MODE permission");
         synchronized (mLock) {
             setCarModeLocked(true);
             if (mSystemReady) {
@@ -394,7 +389,7 @@
         } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) {
             uiMode = Configuration.UI_MODE_TYPE_DESK;
         }
-        if (uiMode != 0) {
+        if (mCarModeEnabled) {
             if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
                 updateTwilightLocked();
                 uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 0e4b38d..a1a8bf2 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -11269,6 +11269,8 @@
         float mDimTargetAlpha;
         float mDimDeltaPerMs;
         long mLastDimAnimTime;
+        
+        int mLastDimWidth, mLastDimHeight;
 
         DimAnimator (SurfaceSession session) {
             if (mDimSurface == null) {
@@ -11294,12 +11296,18 @@
                         dw + "x" + dh + ")");
                 mDimShown = true;
                 try {
+                    mLastDimWidth = dw;
+                    mLastDimHeight = dh;
                     mDimSurface.setPosition(0, 0);
                     mDimSurface.setSize(dw, dh);
                     mDimSurface.show();
                 } catch (RuntimeException e) {
                     Slog.w(TAG, "Failure showing dim surface", e);
                 }
+            } else if (mLastDimWidth != dw || mLastDimHeight != dh) {
+                mLastDimWidth = dw;
+                mLastDimHeight = dh;
+                mDimSurface.setSize(dw, dh);
             }
         }
 
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d59dd21..3b655fa 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2996,7 +2996,7 @@
                     if (!ret.finishing) {
                         int index = indexOfTokenLocked(ret);
                         if (index >= 0) {
-                            finishActivityLocked(ret, 0, Activity.RESULT_CANCELED,
+                            finishActivityLocked(ret, index, Activity.RESULT_CANCELED,
                                     null, "clear");
                         }
                         return null;
@@ -8910,6 +8910,34 @@
                 removeProcessLocked(app, false);
                 return false;
             }
+        } else {
+            HistoryRecord r = topRunningActivityLocked(null);
+            if (r.app == app) {
+                // If the top running activity is from this crashing
+                // process, then terminate it to avoid getting in a loop.
+                Slog.w(TAG, "  Force finishing activity "
+                        + r.intent.getComponent().flattenToShortString());
+                int index = indexOfTokenLocked(r);
+                finishActivityLocked(r, index,
+                        Activity.RESULT_CANCELED, null, "crashed");
+                // Also terminate an activities below it that aren't yet
+                // stopped, to avoid a situation where one will get
+                // re-start our crashing activity once it gets resumed again.
+                index--;
+                if (index >= 0) {
+                    r = (HistoryRecord)mHistory.get(index);
+                    if (r.state == ActivityState.RESUMED
+                            || r.state == ActivityState.PAUSING
+                            || r.state == ActivityState.PAUSED) {
+                        if (!r.isHomeActivity) {
+                            Slog.w(TAG, "  Force finishing activity "
+                                    + r.intent.getComponent().flattenToShortString());
+                            finishActivityLocked(r, index,
+                                    Activity.RESULT_CANCELED, null, "crashed");
+                        }
+                    }
+                }
+            }
         }
 
         // Bump up the crash count of any services currently running in the proc.
@@ -10228,12 +10256,10 @@
         int count = mHistory.size();
 
         // convert the token to an entry in the history.
-        HistoryRecord r = null;
         int index = -1;
         for (int i=count-1; i>=0; i--) {
             Object o = mHistory.get(i);
             if (o == token) {
-                r = (HistoryRecord)o;
                 index = i;
                 break;
             }
diff --git a/services/jni/com_android_server_AlarmManagerService.cpp b/services/jni/com_android_server_AlarmManagerService.cpp
index 85d63c9..0e162bd 100644
--- a/services/jni/com_android_server_AlarmManagerService.cpp
+++ b/services/jni/com_android_server_AlarmManagerService.cpp
@@ -38,10 +38,6 @@
 #include <linux/android_alarm.h>
 #endif
 
-#define ONE_NANOSECOND 1000000000LL
-#define NANOSECONDS_TO_SECONDS(x) (x / ONE_NANOSECOND)
-#define SECONDS_TO_NANOSECONDS(x) (x * ONE_NANOSECOND)
-
 namespace android {
 
 static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv* env, jobject obj, jint fd, jint minswest)
@@ -82,17 +78,17 @@
 #endif
 }
 
-static void android_server_AlarmManagerService_set(JNIEnv* env, jobject obj, jint fd, jint type, jlong nanoseconds)
+static void android_server_AlarmManagerService_set(JNIEnv* env, jobject obj, jint fd, jint type, jlong seconds, jlong nanoseconds)
 {
 #if HAVE_ANDROID_OS
     struct timespec ts;
-    ts.tv_sec = NANOSECONDS_TO_SECONDS(nanoseconds);
-    ts.tv_nsec = nanoseconds - SECONDS_TO_NANOSECONDS(ts.tv_sec);
+    ts.tv_sec = seconds;
+    ts.tv_nsec = nanoseconds;
     
 	int result = ioctl(fd, ANDROID_ALARM_SET(type), &ts);
 	if (result < 0)
 	{
-        LOGE("Unable to set alarm to %lld: %s\n", nanoseconds, strerror(errno));
+        LOGE("Unable to set alarm to %lld.%09lld: %s\n", seconds, nanoseconds, strerror(errno));
     }
 #endif
 }
@@ -121,7 +117,7 @@
      /* name, signature, funcPtr */
 	{"init", "()I", (void*)android_server_AlarmManagerService_init},
 	{"close", "(I)V", (void*)android_server_AlarmManagerService_close},
-	{"set", "(IIJ)V", (void*)android_server_AlarmManagerService_set},
+	{"set", "(IIJJ)V", (void*)android_server_AlarmManagerService_set},
     {"waitForAlarm", "(I)I", (void*)android_server_AlarmManagerService_waitForAlarm},
     {"setKernelTimezone", "(II)I", (void*)android_server_AlarmManagerService_setKernelTimezone},
 };