Merge change 1258 into donut

* changes:
  Fix 1840639 to support overlays with zz_ZZ. Everything but strings worked fine before but a new default string would generate a build error.
diff --git a/api/current.xml b/api/current.xml
index ec84c0d..14faadc 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -1013,6 +1013,17 @@
  visibility="public"
 >
 </field>
+<field name="SHUTDOWN"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.permission.SHUTDOWN&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="SIGNAL_PERSISTENT_PROCESSES"
  type="java.lang.String"
  transient="false"
@@ -5102,6 +5113,17 @@
  visibility="public"
 >
 </field>
+<field name="maxSdkVersion"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843377"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="maxWidth"
  type="int"
  transient="false"
@@ -7181,6 +7203,17 @@
  visibility="public"
 >
 </field>
+<field name="targetSdkVersion"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843376"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="taskAffinity"
  type="int"
  transient="false"
@@ -28790,6 +28823,17 @@
  visibility="public"
 >
 </field>
+<field name="ACTION_SHUTDOWN"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.intent.action.ACTION_SHUTDOWN&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="ACTION_SYNC"
  type="java.lang.String"
  transient="false"
@@ -31830,6 +31874,28 @@
  visibility="public"
 >
 </field>
+<field name="FLAG_TARGETS_SDK"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="256"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLAG_UPDATED_SYSTEM_APP"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="128"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="className"
  type="java.lang.String"
  transient="false"
@@ -34063,6 +34129,17 @@
  visibility="public"
 >
 </field>
+<field name="INSTALL_FAILED_NEWER_SDK"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-14"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="INSTALL_FAILED_NO_SHARED_USER"
  type="int"
  transient="false"
@@ -61016,6 +61093,30 @@
  visibility="public"
 >
 </method>
+<method name="invalidateAllKeys"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="invalidateKey"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="keyIndex" type="int">
+</parameter>
+</method>
 <method name="isPreviewEnabled"
  return="boolean"
  abstract="false"
@@ -86042,6 +86143,16 @@
  visibility="public"
 >
 </constructor>
+<field name="CODENAME"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="INCREMENTAL"
  type="java.lang.String"
  transient="false"
@@ -86068,6 +86179,66 @@
  volatile="false"
  static="true"
  final="true"
+ deprecated="deprecated"
+ visibility="public"
+>
+</field>
+<field name="SDK_INT"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="Build.VERSION_CODES"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="Build.VERSION_CODES"
+ type="android.os.Build.VERSION_CODES"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<field name="BASE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="BASE_1_1"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="CUPCAKE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
  deprecated="not deprecated"
  visibility="public"
 >
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 96ee502..f85ea9f8 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -915,24 +915,24 @@
 void CameraService::Client::postAutoFocus(bool focused)
 {
     LOGV("postAutoFocus");
-    mCameraClient->autoFocusCallback(focused);
+    mCameraClient->notifyCallback(CAMERA_MSG_FOCUS, (int32_t)focused, 0);
 }
 
 void CameraService::Client::postShutter()
 {
-    mCameraClient->shutterCallback();
+    mCameraClient->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
 }
 
 void CameraService::Client::postRaw(const sp<IMemory>& mem)
 {
     LOGD("postRaw");
-    mCameraClient->rawCallback(mem);
+    mCameraClient->dataCallback(CAMERA_MSG_RAW_IMAGE, mem);
 }
 
 void CameraService::Client::postJpeg(const sp<IMemory>& mem)
 {
     LOGD("postJpeg");
-    mCameraClient->jpegCallback(mem);
+    mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem);
 }
 
 void CameraService::Client::copyFrameAndPostCopiedFrame(sp<IMemoryHeap> heap, size_t offset, size_t size)
@@ -960,7 +960,7 @@
         LOGE("failed to allocate space for frame callback");
         return;
     }
-    mCameraClient->previewCallback(frame);
+    mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame);
 }
 
 void CameraService::Client::postRecordingFrame(const sp<IMemory>& frame)
@@ -970,7 +970,7 @@
         LOGW("frame is a null pointer");
         return;
     }
-    mCameraClient->recordingCallback(frame);
+    mCameraClient->dataCallback(CAMERA_MSG_VIDEO_FRAME, frame);
 }
 
 void CameraService::Client::postPreviewFrame(const sp<IMemory>& mem)
@@ -1004,7 +1004,7 @@
         copyFrameAndPostCopiedFrame(heap, offset, size);
     } else {
         LOGV("frame is directly sent out without copying");
-        mCameraClient->previewCallback(mem);
+        mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem);
     }
 
     // Is this is one-shot only?
@@ -1018,7 +1018,7 @@
 
 void CameraService::Client::postError(status_t error)
 {
-    mCameraClient->errorCallback(error);
+    mCameraClient->notifyCallback(CAMERA_MSG_ERROR, error, 0);
 }
 
 status_t CameraService::dump(int fd, const Vector<String16>& args)
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 161bb46..04e69e3 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -537,6 +537,9 @@
         case PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER:
             s = "INSTALL_FAILED_CONFLICTING_PROVIDER";
             break;
+        case PackageManager.INSTALL_FAILED_NEWER_SDK:
+            s = "INSTALL_FAILED_NEWER_SDK";
+            break;
         case PackageManager.INSTALL_PARSE_FAILED_NOT_APK:
             s = "INSTALL_PARSE_FAILED_NOT_APK";
             break;
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 53e6f34..541f413 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -990,6 +990,14 @@
             return true;
         }
         
+        case SHUTDOWN_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            boolean res = shutdown(data.readInt());
+            reply.writeNoException();
+            reply.writeInt(res ? 1 : 0);
+            return true;
+        }
+        
         case PEEK_SERVICE_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             Intent service = Intent.CREATOR.createFromParcel(data);
@@ -2160,5 +2168,19 @@
         return res;
     }
     
+    public boolean shutdown(int timeout) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(timeout);
+        mRemote.transact(SHUTDOWN_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean res = reply.readInt() != 0;
+        reply.recycle();
+        data.recycle();
+        return res;
+    }
+    
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 2ac6160..56b29c1 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -16,7 +16,6 @@
 
 package android.app;
 
-import android.app.ActivityManager.MemoryInfo;
 import android.content.ComponentName;
 import android.content.ContentProviderNative;
 import android.content.IContentProvider;
@@ -34,7 +33,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.ParcelFileDescriptor;
-import android.text.TextUtils;
 import android.os.Bundle;
 
 import java.util.List;
@@ -225,6 +223,8 @@
     public boolean profileControl(String process, boolean start,
             String path) throws RemoteException;
     
+    public boolean shutdown(int timeout) throws RemoteException;
+    
     /*
      * Private non-Binder interfaces
      */
@@ -370,4 +370,5 @@
     int GET_DEVICE_CONFIGURATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+83;
     int PEEK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+84;
     int PROFILE_CONTROL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+85;
+    int SHUTDOWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+86;
 }
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 8fc2447..a174843 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -171,7 +171,7 @@
                 // having windows anchored by their parent but not clipped by them.
                 ViewGroup.LayoutParams.FILL_PARENT);
         WindowManager.LayoutParams lp = theWindow.getAttributes();
-        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE;
+        lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
         theWindow.setAttributes(lp);
 
         // get the view elements for local access
@@ -325,6 +325,14 @@
         
         // show the dialog. this will call onStart().
         if (!isShowing()) {
+            // First make sure the keyboard is showing (if needed), so that we get the right height
+            // for the dropdown to respect the IME.
+            if (getContext().getResources().getConfiguration().hardKeyboardHidden ==
+                Configuration.HARDKEYBOARDHIDDEN_YES) {
+                InputMethodManager inputManager = (InputMethodManager)
+                getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+                        inputManager.showSoftInputUnchecked(0, null);
+            }
             show();
         }
 
@@ -531,9 +539,13 @@
         if (mGlobalSearchMode) {
             mSearchAutoComplete.setDropDownAlwaysVisible(true);  // fill space until results come in
             mSearchAutoComplete.setDropDownDismissedOnCompletion(false);
+            mSearchAutoComplete.setDropDownBackgroundResource(
+                    com.android.internal.R.drawable.search_dropdown_background);
         } else {
             mSearchAutoComplete.setDropDownAlwaysVisible(false);
             mSearchAutoComplete.setDropDownDismissedOnCompletion(true);
+            mSearchAutoComplete.setDropDownBackgroundResource(
+                    com.android.internal.R.drawable.search_dropdown_background_apps);
         }
 
         // attach the suggestions adapter, if suggestions are available
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 90de40d..3bf37c3 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -1184,23 +1184,32 @@
     public final static String SUGGEST_URI_PATH_QUERY = "search_suggest_query";
 
     /**
+     * MIME type for suggestions data.  You'll use this in your suggestions content provider
+     * in the getType() function.
+     */
+    public final static String SUGGEST_MIME_TYPE =
+            "vnd.android.cursor.dir/vnd.android.search.suggest";
+
+    /**
      * Uri path for shortcut validation.  This is the path that the search manager will use when
      * querying your content provider to refresh a shortcutted suggestion result and to check if it
      * is still valid.  When asked, a source may return an up to date result, or no result.  No
      * result indicates the shortcut refers to a no longer valid sugggestion.
      *
      * @see #SUGGEST_COLUMN_SHORTCUT_ID
-     * @hide
+     * 
+     * @hide pending API council approval
      */
     public final static String SUGGEST_URI_PATH_SHORTCUT = "search_suggest_shortcut";
     
     /**
-     * MIME type for suggestions data.  You'll use this in your suggestions content provider
+     * MIME type for shortcut validation.  You'll use this in your suggestions content provider
      * in the getType() function.
+     *
+     * @hide pending API council approval
      */
-    public final static String SUGGEST_MIME_TYPE = 
-                                  "vnd.android.cursor.dir/vnd.android.search.suggest";
-
+    public final static String SHORTCUT_MIME_TYPE = 
+            "vnd.android.cursor.item/vnd.android.search.suggest";
     /**
      * Column name for suggestions cursor.  <i>Unused - can be null or column can be omitted.</i>
      */
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index b3e81d7..3ebf816 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -510,6 +510,7 @@
  *     <li> {@link #ACTION_BATTERY_CHANGED}
  *     <li> {@link #ACTION_POWER_CONNECTED}
  *     <li> {@link #ACTION_POWER_DISCONNECTED} 
+ *     <li> {@link #ACTION_SHUTDOWN} 
  * </ul>
  *
  * <h3>Standard Categories</h3>
@@ -1270,6 +1271,15 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_POWER_DISCONNECTED = "android.intent.action.ACTION_POWER_DISCONNECTED";    
     /**
+     * Broadcast Action:  Device is shutting down.
+     * This is broadcast when the device is being shut down (completely turned
+     * off, not sleeping).  Once the broadcast is complete, the final shutdown
+     * will proceed and all unsaved data lost.  Apps will not normally need
+     * to handle this, since the forground activity will be paused as well.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN";    
+    /**
      * Broadcast Action:  Indicates low memory condition on the device
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index ade5f3d..4d2cce8 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -212,6 +212,14 @@
         }
     };
 
+    private BroadcastReceiver mShutdownIntentReceiver =
+            new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            Log.w(TAG, "Writing sync state before shutdown...");
+            getSyncStorageEngine().writeAllState();
+        }
+    };
+
     private static final String ACTION_SYNC_ALARM = "android.content.syncmanager.SYNC_ALARM";
     private static final String SYNC_POLL_ALARM = "android.content.syncmanager.SYNC_POLL_ALARM";
     private final SyncHandler mSyncHandler;
@@ -249,6 +257,10 @@
         intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
         context.registerReceiver(mStorageIntentReceiver, intentFilter);
 
+        intentFilter = new IntentFilter(Intent.ACTION_SHUTDOWN);
+        intentFilter.setPriority(100);
+        context.registerReceiver(mShutdownIntentReceiver, intentFilter);
+
         if (!factoryTest) {
             mNotificationMgr = (NotificationManager)
                 context.getSystemService(Context.NOTIFICATION_SERVICE);
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 1587462..3827849 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -736,7 +736,7 @@
             }
             
             boolean writeStatisticsNow = false;
-            int day = getCurrentDay();
+            int day = getCurrentDayLocked();
             if (mDayStats[0] == null) {
                 mDayStats[0] = new DayStats(day);
             } else if (day != mDayStats[0].day) {
@@ -925,7 +925,7 @@
         }
     }
     
-    private int getCurrentDay() {
+    private int getCurrentDayLocked() {
         mCal.setTimeInMillis(System.currentTimeMillis());
         final int dayOfYear = mCal.get(Calendar.DAY_OF_YEAR);
         if (mYear != mCal.get(Calendar.YEAR)) {
@@ -1005,6 +1005,21 @@
         return status;
     }
     
+    public void writeAllState() {
+        synchronized (mAuthorities) {
+            // Account info is always written so no need to do it here.
+            
+            if (mNumPendingFinished > 0) {
+                // Only write these if they are out of date.
+                writePendingOperationsLocked();
+            }
+            
+            // Just always write these...  they are likely out of date.
+            writeStatusLocked();
+            writeStatisticsLocked();
+        }
+    }
+    
     /**
      * Read all account information back in to the initial engine state.
      */
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 173057c..fa9ec6e 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -113,19 +113,25 @@
      */
     public static final int FLAG_ALLOW_CLEAR_USER_DATA = 1<<6;
     
-    
     /**
-     * Value for {@link #flags}: default value for the corresponding ActivityInfo flag.
-     *  {@hide}
+     * Value for {@link #flags}: this is set if this application has been
+     * install as an update to a built-in system application.
      */
     public static final int FLAG_UPDATED_SYSTEM_APP = 1<<7;
+    
+    /**
+     * Value for {@link #flags}: this is set of the application has set
+     * its android:targetSdkVersion to something >= the current SDK version.
+     */
+    public static final int FLAG_TARGETS_SDK = 1<<8;
 
     /**
      * Flags associated with the application.  Any combination of
      * {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE},
      * {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and
      * {@link #FLAG_ALLOW_TASK_REPARENTING}
-     * {@link #FLAG_ALLOW_CLEAR_USER_DATA}.
+     * {@link #FLAG_ALLOW_CLEAR_USER_DATA}, {@link #FLAG_UPDATED_SYSTEM_APP},
+     * {@link #FLAG_TARGETS_SDK}.
      */
     public int flags = 0;
     
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 9e06666..e2f0ce4 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -172,6 +172,14 @@
     public static final int GET_SUPPORTS_DENSITIES    = 0x00008000;
 
     /**
+     * Resolution and querying flag: if set, only filters that support the
+     * {@link android.content.Intent#CATEGORY_DEFAULT} will be considered for
+     * matching.  This is a synonym for including the CATEGORY_DEFAULT in your
+     * supplied Intent.
+     */
+    public static final int MATCH_DEFAULT_ONLY   = 0x00010000;
+
+    /**
      * Permission check result: this is returned by {@link #checkPermission}
      * if the permission has been granted to the given package.
      */
@@ -219,14 +227,6 @@
      */
     public static final int SIGNATURE_UNKNOWN_PACKAGE = -4;
 
-    /**
-     * Resolution and querying flag: if set, only filters that support the
-     * {@link android.content.Intent#CATEGORY_DEFAULT} will be considered for
-     * matching.  This is a synonym for including the CATEGORY_DEFAULT in your
-     * supplied Intent.
-     */
-    public static final int MATCH_DEFAULT_ONLY   = 0x00010000;
-
     public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0;
     public static final int COMPONENT_ENABLED_STATE_ENABLED = 1;
     public static final int COMPONENT_ENABLED_STATE_DISABLED = 2;
@@ -355,6 +355,14 @@
     public static final int INSTALL_FAILED_CONFLICTING_PROVIDER = -13;
 
     /**
+     * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+     * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+     * the new package failed because the current SDK version is newer than
+     * that required by the package.
+     */
+    public static final int INSTALL_FAILED_NEWER_SDK = -14;
+
+    /**
      * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
      * if the parser was given a path that is not a file, or does not end with the expected
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index f9c4984..12df5bd 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -59,6 +59,7 @@
     private String mArchiveSourcePath;
     private String[] mSeparateProcesses;
     private int mSdkVersion;
+    private String mSdkCodename;
 
     private int mParseError = PackageManager.INSTALL_SUCCEEDED;
 
@@ -123,8 +124,9 @@
         mSeparateProcesses = procs;
     }
 
-    public void setSdkVersion(int sdkVersion) {
+    public void setSdkVersion(int sdkVersion, String codename) {
         mSdkVersion = sdkVersion;
+        mSdkCodename = codename;
     }
 
     private static final boolean isPackageFilename(String name) {
@@ -613,9 +615,9 @@
         int type;
 
         final Package pkg = new Package(pkgName);
-        pkg.mSystem = (flags&PARSE_IS_SYSTEM) != 0;
         boolean foundApp = false;
-
+        boolean targetsSdk = false;
+        
         TypedArray sa = res.obtainAttributes(attrs,
                 com.android.internal.R.styleable.AndroidManifest);
         pkg.mVersionCode = sa.getInteger(
@@ -721,19 +723,74 @@
 
                 XmlUtils.skipCurrentTag(parser);
 
-            }  else if (tagName.equals("uses-sdk")) {
+            } else if (tagName.equals("uses-sdk")) {
                 if (mSdkVersion > 0) {
                     sa = res.obtainAttributes(attrs,
                             com.android.internal.R.styleable.AndroidManifestUsesSdk);
 
-                    int vers = sa.getInt(
-                            com.android.internal.R.styleable.AndroidManifestUsesSdk_minSdkVersion, 0);
+                    int minVers = 0;
+                    String minCode = null;
+                    int targetVers = 0;
+                    String targetCode = null;
+                    
+                    TypedValue val = sa.peekValue(
+                            com.android.internal.R.styleable.AndroidManifestUsesSdk_minSdkVersion);
+                    if (val != null) {
+                        if (val.type == TypedValue.TYPE_STRING && val.string != null) {
+                            targetCode = minCode = val.string.toString();
+                        } else {
+                            // If it's not a string, it's an integer.
+                            minVers = val.data;
+                        }
+                    }
+                    
+                    val = sa.peekValue(
+                            com.android.internal.R.styleable.AndroidManifestUsesSdk_targetSdkVersion);
+                    if (val != null) {
+                        if (val.type == TypedValue.TYPE_STRING && val.string != null) {
+                            targetCode = minCode = val.string.toString();
+                        } else {
+                            // If it's not a string, it's an integer.
+                            targetVers = val.data;
+                        }
+                    }
+                    
+                    int maxVers = sa.getInt(
+                            com.android.internal.R.styleable.AndroidManifestUsesSdk_maxSdkVersion,
+                            mSdkVersion);
 
                     sa.recycle();
 
-                    if (vers > mSdkVersion) {
-                        outError[0] = "Requires newer sdk version #" + vers
-                            + " (current version is #" + mSdkVersion + ")";
+                    if (targetCode != null) {
+                        if (!targetCode.equals(mSdkCodename)) {
+                            if (mSdkCodename != null) {
+                                outError[0] = "Requires development platform " + targetCode
+                                        + " (current platform is " + mSdkCodename + ")";
+                            } else {
+                                outError[0] = "Requires development platform " + targetCode
+                                        + " but this is a release platform.";
+                            }
+                            mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
+                            return null;
+                        }
+                        // If the code matches, it definitely targets this SDK.
+                        targetsSdk = true;
+                    } else if (targetVers >= mSdkVersion) {
+                        // If they have explicitly targeted our current version
+                        // or something after it, then note this.
+                        targetsSdk = true;
+                    }
+                    
+                    if (minVers > mSdkVersion) {
+                        outError[0] = "Requires newer sdk version #" + minVers
+                                + " (current version is #" + mSdkVersion + ")";
+                        mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
+                        return null;
+                    }
+                    
+                    if (maxVers < mSdkVersion) {
+                        outError[0] = "Requires older sdk version #" + maxVers
+                                + " (current version is #" + mSdkVersion + ")";
                         mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
                         return null;
                     }
@@ -767,6 +824,10 @@
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY;
         }
 
+        if (targetsSdk) {
+            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_TARGETS_SDK;
+        }
+        
         if (pkg.usesLibraries.size() > 0) {
             pkg.usesLibraryFiles = new String[pkg.usesLibraries.size()];
             pkg.usesLibraries.toArray(pkg.usesLibraryFiles);
@@ -2133,9 +2194,6 @@
         // If this is a 3rd party app, this is the path of the zip file.
         public String mPath;
 
-        // True if this package is part of the system image.
-        public boolean mSystem;
-
         // The version code declared for this package.
         public int mVersionCode;
         
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 65c9893..8b474d5 100755
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -407,7 +407,7 @@
         // Release buffer, just in case the new keyboard has a different size. 
         // It will be reallocated on the next draw.
         mBuffer = null;
-        invalidateAll();
+        invalidateAllKeys();
         computeProximityThreshold(keyboard);
         mMiniKeyboardCache.clear(); // Not really necessary to do every time, but will free up views
     }
@@ -431,7 +431,7 @@
         if (mKeyboard != null) {
             if (mKeyboard.setShifted(shifted)) {
                 // The whole keyboard probably needs to be redrawn
-                invalidateAll();
+                invalidateAllKeys();
                 return true;
             }
         }
@@ -573,7 +573,7 @@
         if (mBuffer == null) {
             mBuffer = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
             mCanvas = new Canvas(mBuffer);
-            invalidateAll();
+            invalidateAllKeys();
         }
         final Canvas canvas = mCanvas;
         canvas.clipRect(mDirtyRect, Op.REPLACE);
@@ -874,13 +874,27 @@
         mPreviewText.setVisibility(VISIBLE);
     }
 
-    private void invalidateAll() {
+    /**
+     * Requests a redraw of the entire keyboard. Calling {@link #invalidate} is not sufficient
+     * because the keyboard renders the keys to an off-screen buffer and an invalidate() only 
+     * draws the cached buffer.
+     * @see #invalidateKey(int)
+     */
+    public void invalidateAllKeys() {
         mDirtyRect.union(0, 0, getWidth(), getHeight());
         mDrawPending = true;
         invalidate();
     }
-    
-    private void invalidateKey(int keyIndex) {
+
+    /**
+     * Invalidates a key so that it will be redrawn on the next repaint. Use this method if only
+     * one key is changing it's content. Any changes that affect the position or size of the key
+     * may not be honored.
+     * @param keyIndex the index of the key in the attached {@link Keyboard}.
+     * @see #invalidateAllKeys
+     */
+    public void invalidateKey(int keyIndex) {
+        if (mKeys == null) return;
         if (keyIndex < 0 || keyIndex >= mKeys.length) {
             return;
         }
@@ -991,7 +1005,7 @@
             mPopupKeyboard.showAtLocation(this, Gravity.NO_GRAVITY, x, y);
             mMiniKeyboardOnScreen = true;
             //mMiniKeyboard.onTouchEvent(getTranslatedEvent(me));
-            invalidateAll();
+            invalidateAllKeys();
             return true;
         }
         return false;
@@ -1164,7 +1178,7 @@
         if (mPopupKeyboard.isShowing()) {
             mPopupKeyboard.dismiss();
             mMiniKeyboardOnScreen = false;
-            invalidateAll();
+            invalidateAllKeys();
         }
     }
 
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 467c17f..5487c54 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -59,11 +59,47 @@
         public static final String RELEASE = getString("ro.build.version.release");
 
         /**
-         * The user-visible SDK version of the framework. It is an integer starting at 1.
+         * The user-visible SDK version of the framework in its raw String
+         * representation; use {@link #SDK_INT} instead.
+         * 
+         * @deprecated Use {@link #SDK_INT} to easily get this as an integer.
          */
         public static final String SDK = getString("ro.build.version.sdk");
+
+        /**
+         * The user-visible SDK version of the framework; its possible
+         * values are defined in {@link Build.VERSION_CODES}.
+         */
+        public static final int SDK_INT = SystemProperties.getInt(
+                "ro.build.version.sdk", 0);
+
+        /**
+         * The current development codename, or the string "REL" if this is
+         * a release build.
+         */
+        public static final String CODENAME = getString("ro.build.version.codename");
     }
 
+    /**
+     * Enumeration of the currently known SDK version codes.  These are the
+     * values that can be found in {@link VERSION#SDK}.  Version numbers
+     * increment monotonically with each official platform release.
+     */
+    public static class VERSION_CODES {
+        /**
+         * October 2008: The original, first, version of Android.  Yay!
+         */
+        public static final int BASE = 1;
+        /**
+         * February 2009: First Android update, officially called 1.1.
+         */
+        public static final int BASE_1_1 = 2;
+        /**
+         * May 2009: Android 1.5.
+         */
+        public static final int CUPCAKE = 3;
+    }
+    
     /** The type of build, like "user" or "eng". */
     public static final String TYPE = getString("ro.build.type");
 
diff --git a/core/java/android/os/Power.java b/core/java/android/os/Power.java
index 47497e5..3679e47 100644
--- a/core/java/android/os/Power.java
+++ b/core/java/android/os/Power.java
@@ -80,10 +80,9 @@
     public static native int setLastUserActivityTimeout(long ms);
 
     /**
-     * Turn the device off.
-     *
-     * This method is considered deprecated in favor of
-     * {@link android.policy.ShutdownThread.shutdownAfterDisablingRadio()}.
+     * Low-level function turn the device off immediately, without trying
+     * to be clean.  Most people should use
+     * {@link android.internal.app.ShutdownThread} for a clean shutdown.
      *
      * @deprecated
      * @hide
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 9c10f0a..a1d16ea 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -208,7 +208,7 @@
                 && mPopup.isShowing()
                 && mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED) {
             mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
-            mPopup.update();
+            showDropDown();
         }
     }
 
@@ -1171,9 +1171,14 @@
             }
         }
 
-        // Max height available on the screen for a popup
-        final int maxHeight =
-                mPopup.getMaxAvailableHeight(getDropDownAnchorView(), mDropDownVerticalOffset);
+        // Max height available on the screen for a popup. If this AutoCompleteTextView has
+        // the dropDownAlwaysVisible attribute, and the input method is not currently required,
+        // we then we ask for the height ignoring any bottom decorations like the input method.
+        // Otherwise we respect the input method.
+        boolean ignoreBottomDecorations = mDropDownAlwaysVisible &&
+                mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED;
+        final int maxHeight = mPopup.getMaxAvailableHeight(
+                getDropDownAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations);
 
         final int measuredHeight = mDropDownList.measureHeightOfChildren(MeasureSpec.UNSPECIFIED,
                 0, ListView.NO_POSITION, maxHeight - otherHeights, 2) + otherHeights;
@@ -1255,7 +1260,7 @@
         public boolean onTouch(View v, MotionEvent event) {
             if (event.getAction() == MotionEvent.ACTION_DOWN) {
                 mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
-                mPopup.update();
+                showDropDown();
             }
             return false;
         }
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 2c9714e..acd25ee 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -25,6 +25,7 @@
 import android.view.Gravity;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
+import android.view.WindowManagerImpl;
 import android.view.ViewTreeObserver.OnScrollChangedListener;
 import android.view.View.OnTouchListener;
 import android.graphics.PixelFormat;
@@ -948,14 +949,38 @@
      *         shown.
      */
     public int getMaxAvailableHeight(View anchor, int yOffset) {
+        return getMaxAvailableHeight(anchor, yOffset, false);
+    }
+    
+    /**
+     * Returns the maximum height that is available for the popup to be
+     * completely shown, optionally ignoring any bottom decorations such as
+     * the input method. It is recommended that this height be the maximum for
+     * the popup's height, otherwise it is possible that the popup will be
+     * clipped.
+     * 
+     * @param anchor The view on which the popup window must be anchored.
+     * @param yOffset y offset from the view's bottom edge
+     * @param ignoreBottomDecorations if true, the height returned will be
+     *        all the way to the bottom of the display, ignoring any
+     *        bottom decorations
+     * @return The maximum available height for the popup to be completely
+     *         shown.
+     *         
+     * @hide Pending API council approval.
+     */
+    public int getMaxAvailableHeight(View anchor, int yOffset, boolean ignoreBottomDecorations) {
         final Rect displayFrame = new Rect();
         anchor.getWindowVisibleDisplayFrame(displayFrame);
 
         final int[] anchorPos = mDrawingLocation;
         anchor.getLocationOnScreen(anchorPos);
         
-        final int distanceToBottom = displayFrame.bottom -
-                (anchorPos[1] + anchor.getHeight()) - yOffset;
+        int bottomEdge = displayFrame.bottom;
+        if (ignoreBottomDecorations) {
+            bottomEdge = WindowManagerImpl.getDefault().getDefaultDisplay().getHeight();
+        }
+        final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset;
         final int distanceToTop = anchorPos[1] - displayFrame.top + yOffset;
 
         // anchorPos[1] is distance from anchor to top of screen
@@ -1116,7 +1141,7 @@
             p.flags = newFlags;
             update = true;
         }
-        
+
         if (update) {
             mWindowManager.updateViewLayout(mPopupView, p);
         }
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
new file mode 100644
index 0000000..77d6e20
--- /dev/null
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ 
+package com.android.internal.app;
+
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.app.ProgressDialog;
+import android.app.AlertDialog;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.IBluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.Power;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import com.android.internal.telephony.ITelephony;
+import android.util.Log;
+import android.view.WindowManager;
+
+public final class ShutdownThread extends Thread {
+    // constants
+    private static final String TAG = "ShutdownThread";
+    private static final int MAX_NUM_PHONE_STATE_READS = 16;
+    private static final int PHONE_STATE_POLL_SLEEP_MSEC = 500;
+    // maximum time we wait for the shutdown broadcast before going on.
+    private static final int MAX_BROADCAST_TIME = 10*1000;
+    
+    // state tracking
+    private static Object sIsStartedGuard = new Object();
+    private static boolean sIsStarted = false;
+    
+    // static instance of this thread
+    private static final ShutdownThread sInstance = new ShutdownThread();
+    
+    private final Object mBroadcastDoneSync = new Object();
+    private boolean mBroadcastDone;
+    private Context mContext;
+    private Handler mHandler;
+    
+    private ShutdownThread() {
+    }
+ 
+    /** 
+     * Request a clean shutdown, waiting for subsystems to clean up their
+     * state etc.  Must be called from a Looper thread in which its UI
+     * is shown.
+     * 
+     * @param context Context used to display the shutdown progress dialog.
+     */
+    public static void shutdown(final Context context, boolean confirm) {
+        // ensure that only one thread is trying to power down.
+        // any additional calls are just returned
+        synchronized (sIsStartedGuard){
+            if (sIsStarted) {
+                Log.d(TAG, "Request to shutdown already running, returning.");
+                return;
+            }
+        }
+
+        Log.d(TAG, "Notifying thread to start radio shutdown");
+
+        if (confirm) {
+            final AlertDialog dialog = new AlertDialog.Builder(context)
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .setTitle(com.android.internal.R.string.power_off)
+                    .setMessage(com.android.internal.R.string.shutdown_confirm)
+                    .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int which) {
+                            beginShutdownSequence(context);
+                        }
+                    })
+                    .setNegativeButton(com.android.internal.R.string.no, null)
+                    .create();
+            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+            dialog.show();
+        } else {
+            beginShutdownSequence(context);
+        }
+    }
+
+    private static void beginShutdownSequence(Context context) {
+        synchronized (sIsStartedGuard) {
+            sIsStarted = true;
+        }
+
+        // throw up an indeterminate system dialog to indicate radio is
+        // shutting down.
+        ProgressDialog pd = new ProgressDialog(context);
+        pd.setTitle(context.getText(com.android.internal.R.string.power_off));
+        pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
+        pd.setIndeterminate(true);
+        pd.setCancelable(false);
+        pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+        pd.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+
+        pd.show();
+
+        // start the thread that initiates shutdown
+        sInstance.mContext = context;
+        sInstance.mHandler = new Handler() {
+        };
+        sInstance.start();
+    }
+
+    void broadcastDone() {
+        synchronized (mBroadcastDoneSync) {
+            mBroadcastDone = true;
+            mBroadcastDoneSync.notifyAll();
+        }
+    }
+    
+    /**
+     * Makes sure we handle the shutdown gracefully.
+     * Shuts off power regardless of radio and bluetooth state if the alloted time has passed.
+     */
+    public void run() {
+        boolean bluetoothOff;
+        boolean radioOff;
+
+        BroadcastReceiver br = new BroadcastReceiver() {
+            @Override public void onReceive(Context context, Intent intent) {
+                // We don't allow apps to cancel this, so ignore the result.
+                broadcastDone();
+            }
+        };
+        
+        Log.i(TAG, "Sending shutdown broadcast...");
+        
+        // First send the high-level shut down broadcast.
+        mBroadcastDone = false;
+        mContext.sendOrderedBroadcast(new Intent(Intent.ACTION_SHUTDOWN), null,
+                br, mHandler, 0, null, null);
+        
+        final long endTime = System.currentTimeMillis() + MAX_BROADCAST_TIME;
+        synchronized (mBroadcastDoneSync) {
+            while (!mBroadcastDone) {
+                long delay = endTime - System.currentTimeMillis();
+                if (delay <= 0) {
+                    Log.w(TAG, "Shutdown broadcast timed out");
+                    break;
+                }
+                try {
+                    mBroadcastDoneSync.wait(delay);
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+        
+        Log.i(TAG, "Shutting down activity manager...");
+        
+        final IActivityManager am =
+            ActivityManagerNative.asInterface(ServiceManager.checkService("activity"));
+        if (am != null) {
+            try {
+                am.shutdown(MAX_BROADCAST_TIME);
+            } catch (RemoteException e) {
+            }
+        }
+        
+        final ITelephony phone =
+                ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
+        final IBluetoothDevice bluetooth =
+                IBluetoothDevice.Stub.asInterface(ServiceManager.checkService(
+                        Context.BLUETOOTH_SERVICE));
+        
+        try {
+            bluetoothOff = bluetooth == null ||
+                           bluetooth.getBluetoothState() == BluetoothDevice.BLUETOOTH_STATE_OFF;
+            if (!bluetoothOff) {
+                Log.w(TAG, "Disabling Bluetooth...");
+                bluetooth.disable(false);  // disable but don't persist new state
+            }
+        } catch (RemoteException ex) {
+            Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
+            bluetoothOff = true;
+        }
+
+        try {
+            radioOff = phone == null || !phone.isRadioOn();
+            if (!radioOff) {
+                Log.w(TAG, "Turning off radio...");
+                phone.setRadio(false);
+            }
+        } catch (RemoteException ex) {
+            Log.e(TAG, "RemoteException during radio shutdown", ex);
+            radioOff = true;
+        }
+
+        Log.i(TAG, "Waiting for Bluetooth and Radio...");
+        
+        // Wait a max of 32 seconds for clean shutdown
+        for (int i = 0; i < MAX_NUM_PHONE_STATE_READS; i++) {
+            if (!bluetoothOff) {
+                try {
+                    bluetoothOff =
+                            bluetooth.getBluetoothState() == BluetoothDevice.BLUETOOTH_STATE_OFF;
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
+                    bluetoothOff = true;
+                }
+            }
+            if (!radioOff) {
+                try {
+                    radioOff = !phone.isRadioOn();
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "RemoteException during radio shutdown", ex);
+                    radioOff = true;
+                }
+            }
+            if (radioOff && bluetoothOff) {
+                Log.i(TAG, "Radio and Bluetooth shutdown complete.");
+                break;
+            }
+            SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);
+        }
+
+        //shutdown power
+        Log.i(TAG, "Performing low-level shutdown...");
+        Power.shutdown();
+    }
+}
diff --git a/core/java/com/android/internal/backup/IBackupTransport.aidl b/core/java/com/android/internal/backup/IBackupTransport.aidl
index d64a303..ce39768 100644
--- a/core/java/com/android/internal/backup/IBackupTransport.aidl
+++ b/core/java/com/android/internal/backup/IBackupTransport.aidl
@@ -16,6 +16,54 @@
 
 package com.android.internal.backup;
 
+import android.os.ParcelFileDescriptor;
+
 /** {@hide} */
 interface IBackupTransport {
+/* STOPSHIP - don't ship with this comment in place
+    Things the transport interface has to do:
+    1. set up the connection to the destination
+        - set up encryption
+        - for Google cloud, log in using the user's gaia credential or whatever
+        - for sd, spin off the backup transport and establish communication with it
+    2. send each app's backup transaction
+        - parse the data file for key/value pointers etc
+        - send key/blobsize set to the Google cloud, get back quota ok/rejected response
+        - sd/adb doesn't preflight; no per-app quota
+        - app's entire change is essentially atomic
+        - cloud transaction encrypts then sends each key/value pair separately; we already
+          parsed the data when preflighting so we don't have to again here
+        - sd target streams raw data into encryption envelope then to sd?
+    3. shut down connection to destination
+        - cloud: tear down connection etc
+        - sd: close the file and shut down the writer proxy
+*/
+    /**
+     * Establish a connection to the back-end data repository, if necessary.  If the transport
+     * needs to initialize state that is not tied to individual applications' backup operations,
+     * this is where it should be done.
+     *
+     * @return Zero on success; a nonzero error code on failure.
+     */
+    int startSession();
+
+    /**
+     * Send one application's data to the backup destination.
+     *
+     * @param packageName The identity of the application whose data is being backed up.
+     * @param data The data stream that resulted from invoking the application's
+     *        BackupService.doBackup() method.  This may be a pipe rather than a
+     *        file on persistent media, so it may not be seekable.
+     * @return Zero on success; a nonzero error code on failure.
+     */
+    int performBackup(String packageName, in ParcelFileDescriptor data);
+
+    /**
+     * Terminate the backup session, closing files, freeing memory, and cleaning up whatever
+     * other state the transport required.
+     *
+     * @return Zero on success; a nonzero error code on failure.  Even on failure, the session
+     *         is torn down and must be restarted if another backup is attempted.
+     */
+    int endSession();
 }
diff --git a/core/jni/android_location_GpsLocationProvider.cpp b/core/jni/android_location_GpsLocationProvider.cpp
index 9c63fd2..004b0e3 100644
--- a/core/jni/android_location_GpsLocationProvider.cpp
+++ b/core/jni/android_location_GpsLocationProvider.cpp
@@ -31,31 +31,31 @@
 static jmethodID method_reportLocation;
 static jmethodID method_reportStatus;
 static jmethodID method_reportSvStatus;
-static jmethodID method_reportSuplStatus;
+static jmethodID method_reportAGpsStatus;
 static jmethodID method_xtraDownloadRequest;
 
 static const GpsInterface* sGpsInterface = NULL;
 static const GpsXtraInterface* sGpsXtraInterface = NULL;
-static const GpsSuplInterface* sGpsSuplInterface = NULL;
+static const AGpsInterface* sAGpsInterface = NULL;
 
 // data written to by GPS callbacks
 static GpsLocation  sGpsLocation;
 static GpsStatus    sGpsStatus;
 static GpsSvStatus  sGpsSvStatus;
-static GpsSuplStatus    sGpsSuplStatus;
+static AGpsStatus   sAGpsStatus;
 
 // a copy of the data shared by android_location_GpsLocationProvider_wait_for_event
 // and android_location_GpsLocationProvider_read_status
 static GpsLocation  sGpsLocationCopy;
 static GpsStatus    sGpsStatusCopy;
 static GpsSvStatus  sGpsSvStatusCopy;
-static GpsSuplStatus    sGpsSuplStatusCopy;
+static AGpsStatus   sAGpsStatusCopy;
 
 enum CallbackType {
     kLocation = 1,
     kStatus = 2,
     kSvStatus = 4,
-    kSuplStatus = 8,
+    kAGpsStatus = 8,
     kXtraDownloadRequest = 16,
     kDisableRequest = 32,
 }; 
@@ -96,12 +96,12 @@
     pthread_mutex_unlock(&sEventMutex);
 }
 
-static void supl_status_callback(GpsSuplStatus* supl_status)
+static void agps_status_callback(AGpsStatus* agps_status)
 {
     pthread_mutex_lock(&sEventMutex);
 
-    sPendingCallbacks |= kSuplStatus;
-    memcpy(&sGpsSuplStatus, supl_status, sizeof(GpsSuplStatus));
+    sPendingCallbacks |= kAGpsStatus;
+    memcpy(&sAGpsStatus, agps_status, sizeof(AGpsStatus));
 
     pthread_cond_signal(&sEventCond);
     pthread_mutex_unlock(&sEventMutex);
@@ -126,15 +126,15 @@
     download_request_callback,
 };
 
-GpsSuplCallbacks sGpsSuplCallbacks = {
-    supl_status_callback,
+AGpsCallbacks sAGpsCallbacks = {
+    agps_status_callback,
 };
 
 static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
     method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
     method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
     method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
-    method_reportSuplStatus = env->GetMethodID(clazz, "reportSuplStatus", "(I)V");
+    method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II)V");
     method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
 }
 
@@ -151,10 +151,10 @@
     if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
         return false;
 
-    if (!sGpsSuplInterface)
-        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
-    if (sGpsSuplInterface)
-        sGpsSuplInterface->init(&sGpsSuplCallbacks);
+    if (!sAGpsInterface)
+        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
+    if (sAGpsInterface)
+        sAGpsInterface->init(&sAGpsCallbacks);
     return true;
 }
 
@@ -187,12 +187,6 @@
     return (sGpsInterface->stop() == 0);
 }
 
-static void android_location_GpsLocationProvider_set_fix_frequency(JNIEnv* env, jobject obj, jint fixFrequency)
-{
-    if (sGpsInterface->set_fix_frequency)
-        sGpsInterface->set_fix_frequency(fixFrequency);
-}
-
 static void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* env, jobject obj, jint flags)
 {
     sGpsInterface->delete_aiding_data(flags);
@@ -212,7 +206,7 @@
     memcpy(&sGpsLocationCopy, &sGpsLocation, sizeof(sGpsLocationCopy));
     memcpy(&sGpsStatusCopy, &sGpsStatus, sizeof(sGpsStatusCopy));
     memcpy(&sGpsSvStatusCopy, &sGpsSvStatus, sizeof(sGpsSvStatusCopy));
-    memcpy(&sGpsSuplStatusCopy, &sGpsSuplStatus, sizeof(sGpsSuplStatusCopy));
+    memcpy(&sAGpsStatusCopy, &sAGpsStatus, sizeof(sAGpsStatusCopy));
     pthread_mutex_unlock(&sEventMutex);   
 
     if (pendingCallbacks & kLocation) { 
@@ -228,8 +222,8 @@
     if (pendingCallbacks & kSvStatus) {
         env->CallVoidMethod(obj, method_reportSvStatus);
     }
-    if (pendingCallbacks & kSuplStatus) {
-        env->CallVoidMethod(obj, method_reportSuplStatus, sGpsSuplStatusCopy.status);
+    if (pendingCallbacks & kAGpsStatus) {
+        env->CallVoidMethod(obj, method_reportAGpsStatus, sAGpsStatusCopy.type, sAGpsStatusCopy.status);
     }  
     if (pendingCallbacks & kXtraDownloadRequest) {    
         env->CallVoidMethod(obj, method_xtraDownloadRequest);
@@ -299,73 +293,72 @@
     env->ReleaseByteArrayElements(data, bytes, 0);
 }
 
-static void android_location_GpsLocationProvider_supl_data_conn_open(JNIEnv* env, jobject obj, jstring apn)
+static void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env, jobject obj, jstring apn)
 {
-    if (!sGpsSuplInterface) {
-        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
+    if (!sAGpsInterface) {
+        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
     }
-    if (sGpsSuplInterface) {
+    if (sAGpsInterface) {
         if (apn == NULL) {
             jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
             return;
         }
         const char *apnStr = env->GetStringUTFChars(apn, NULL);
-        sGpsSuplInterface->data_conn_open(apnStr);
+        sAGpsInterface->data_conn_open(apnStr);
         env->ReleaseStringUTFChars(apn, apnStr);
     }
 }
 
-static void android_location_GpsLocationProvider_supl_data_conn_closed(JNIEnv* env, jobject obj)
+static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* env, jobject obj)
 {
-    if (!sGpsSuplInterface) {
-        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
+    if (!sAGpsInterface) {
+        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
     }
-    if (sGpsSuplInterface) {
-        sGpsSuplInterface->data_conn_closed();
+    if (sAGpsInterface) {
+        sAGpsInterface->data_conn_closed();
     }
 }
 
-static void android_location_GpsLocationProvider_supl_data_conn_failed(JNIEnv* env, jobject obj)
+static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* env, jobject obj)
 {
-    if (!sGpsSuplInterface) {
-        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
+    if (!sAGpsInterface) {
+        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
     }
-    if (sGpsSuplInterface) {
-        sGpsSuplInterface->data_conn_failed();
+    if (sAGpsInterface) {
+        sAGpsInterface->data_conn_failed();
     }
 }
 
-static void android_location_GpsLocationProvider_set_supl_server(JNIEnv* env, jobject obj,
-        jint addr, jint port)
+static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj,
+        jint type, jint addr, jint port)
 {
-    if (!sGpsSuplInterface) {
-        sGpsSuplInterface = (const GpsSuplInterface*)sGpsInterface->get_extension(GPS_SUPL_INTERFACE);
+    if (!sAGpsInterface) {
+        sAGpsInterface = (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
     }
-    if (sGpsSuplInterface) {
-        sGpsSuplInterface->set_server(addr, port);
+    if (sAGpsInterface) {
+        sAGpsInterface->set_server(type, addr, port);
     }
 }
 
 static JNINativeMethod sMethods[] = {
      /* name, signature, funcPtr */
     {"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native},
-	{"native_is_supported", "()Z", (void*)android_location_GpsLocationProvider_is_supported},
-	{"native_init", "()Z", (void*)android_location_GpsLocationProvider_init},
-	{"native_disable", "()V", (void*)android_location_GpsLocationProvider_disable},
-	{"native_cleanup", "()V", (void*)android_location_GpsLocationProvider_cleanup},
-	{"native_start", "(IZI)Z", (void*)android_location_GpsLocationProvider_start},
-	{"native_stop", "()Z", (void*)android_location_GpsLocationProvider_stop},
-	{"native_set_fix_frequency", "(I)V", (void*)android_location_GpsLocationProvider_set_fix_frequency},
-	{"native_delete_aiding_data", "(I)V", (void*)android_location_GpsLocationProvider_delete_aiding_data},
-	{"native_wait_for_event", "()V", (void*)android_location_GpsLocationProvider_wait_for_event},
-	{"native_read_sv_status", "([I[F[F[F[I)I", (void*)android_location_GpsLocationProvider_read_sv_status},
-	{"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time},
-	{"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra},
-	{"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data},
- 	{"native_supl_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_supl_data_conn_open},
- 	{"native_supl_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_supl_data_conn_closed},
- 	{"native_supl_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_supl_data_conn_failed},
- 	{"native_set_supl_server", "(II)V", (void*)android_location_GpsLocationProvider_set_supl_server},
+    {"native_is_supported", "()Z", (void*)android_location_GpsLocationProvider_is_supported},
+    {"native_init", "()Z", (void*)android_location_GpsLocationProvider_init},
+    {"native_disable", "()V", (void*)android_location_GpsLocationProvider_disable},
+    {"native_cleanup", "()V", (void*)android_location_GpsLocationProvider_cleanup},
+    {"native_start", "(IZI)Z", (void*)android_location_GpsLocationProvider_start},
+    {"native_stop", "()Z", (void*)android_location_GpsLocationProvider_stop},
+    {"native_delete_aiding_data", "(I)V", (void*)android_location_GpsLocationProvider_delete_aiding_data},
+    {"native_wait_for_event", "()V", (void*)android_location_GpsLocationProvider_wait_for_event},
+    {"native_read_sv_status", "([I[F[F[F[I)I", (void*)android_location_GpsLocationProvider_read_sv_status},
+    {"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time},
+    {"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra},
+    {"native_inject_xtra_data", "([BI)V", (void*)android_location_GpsLocationProvider_inject_xtra_data},
+    {"native_agps_data_conn_open", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_agps_data_conn_open},
+    {"native_agps_data_conn_closed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_closed},
+    {"native_agps_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_failed},
+    {"native_set_agps_server", "(III)V", (void*)android_location_GpsLocationProvider_set_agps_server},
 };
 
 int register_android_location_GpsLocationProvider(JNIEnv* env)
diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp
index 7e388ef..482d8eb 100644
--- a/core/jni/android_opengl_GLES10.cpp
+++ b/core/jni/android_opengl_GLES10.cpp
@@ -24,6 +24,19 @@
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
+/* special calls implemented in Android's GLES wrapper used to more
+ * efficiently bound-check passed arrays */
+extern "C" {
+GL_API void GL_APIENTRY glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
+        const GLvoid *ptr, GLsizei count);
+GL_API void GL_APIENTRY glNormalPointerBounds(GLenum type, GLsizei stride,
+        const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glTexCoordPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count);
+}
+
 static int initialized = 0;
 
 static jclass nioAccessClass;
diff --git a/core/jni/android_server_BluetoothA2dpService.cpp b/core/jni/android_server_BluetoothA2dpService.cpp
index b320c09..fe94642 100644
--- a/core/jni/android_server_BluetoothA2dpService.cpp
+++ b/core/jni/android_server_BluetoothA2dpService.cpp
@@ -45,7 +45,8 @@
 static jmethodID method_onSinkStopped;
 
 typedef struct {
-    JNIEnv *env;
+    JavaVM *vm;
+    int envVer;
     DBusConnection *conn;
     jobject me;  // for callbacks to java
 } native_data_t;
@@ -70,7 +71,8 @@
         LOGE("%s: out of memory!", __FUNCTION__);
         return false;
     }
-    nat->env = env;
+    env->GetJavaVM( &(nat->vm) );
+    nat->envVer = env->GetVersion();
     nat->me = env->NewGlobalRef(object);
 
     DBusError err;
@@ -239,8 +241,14 @@
 
     char *c_path = (char *)user;
     DBusError err;
+    JNIEnv *env;
+
+    if (nat->vm->GetEnv((void**)&env, nat->envVer) < 0) {
+        LOGE("%s: error finding Env for our VM\n", __FUNCTION__);
+        return;
+    }
+
     dbus_error_init(&err);
-    JNIEnv *env = nat->env;
 
     LOGV("... path = %s", c_path);
     if (dbus_set_error_from_message(&err, msg)) {
@@ -264,8 +272,14 @@
 
     char *c_path = (char *)user;
     DBusError err;
+    JNIEnv *env;
+
+    if (nat->vm->GetEnv((void**)&env, nat->envVer) < 0) {
+        LOGE("%s: error finding Env for our VM\n", __FUNCTION__);
+        return;
+    }
+
     dbus_error_init(&err);
-    JNIEnv *env = nat->env;
 
     LOGV("... path = %s", c_path);
     if (dbus_set_error_from_message(&err, msg)) {
diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp
index 6f2a438..11822e0 100644
--- a/core/jni/com_google_android_gles_jni_GLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp
@@ -24,6 +24,19 @@
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
+/* special calls implemented in Android's GLES wrapper used to more
+ * efficiently bound-check passed arrays */
+extern "C" {
+GL_API void GL_APIENTRY glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
+        const GLvoid *ptr, GLsizei count);
+GL_API void GL_APIENTRY glNormalPointerBounds(GLenum type, GLsizei stride,
+        const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glTexCoordPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count);
+}
+
 static int initialized = 0;
 
 static jclass nioAccessClass;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7ebc896..bff6b9d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -803,6 +803,14 @@
         android:description="@string/permdesc_runSetActivityWatcher"
         android:protectionLevel="signature" />
 
+    <!-- Allows an application to watch and control how activities are
+         started globally in the system.  Only for is in debugging
+         (usually the monkey command). -->
+    <permission android:name="android.permission.SHUTDOWN"
+        android:label="@string/permlab_shutdown"
+        android:description="@string/permdesc_shutdown"
+        android:protectionLevel="signature" />
+
     <!-- Allows an application to retrieve the current state of keys and
          switches.  This is only for use by the system.-->
     <permission android:name="android.permission.READ_INPUT_STATE"
diff --git a/core/res/res/drawable/search_dropdown_background_apps.9.png b/core/res/res/drawable/search_dropdown_background_apps.9.png
new file mode 100644
index 0000000..56b697d
--- /dev/null
+++ b/core/res/res/drawable/search_dropdown_background_apps.9.png
Binary files differ
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 54da326..1319c77 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -753,9 +753,28 @@
          {@link #AndroidManifest manifest} tag. -->
     <declare-styleable name="AndroidManifestUsesSdk" parent="AndroidManifest">
         <!-- This is the minimum SDK version number that the application
-             requires.  Currently there is only one SDK version, 1.  If
-             not supplied, the application will work on any SDK. -->
-        <attr name="minSdkVersion" format="integer" />
+             requires.  This number is an abstract integer, from the list
+             in {@link android.os.Build.VERSION_CODES}  If
+             not supplied, the application will work on any SDK.  This
+             may also be string (such as "Donut") if the application was built
+             against a development branch, in which case it will only work against
+             the development builds. -->
+        <attr name="minSdkVersion" format="integer|string" />
+        <!-- This is the SDK version number that the application is targeting.
+             It is able to run on older versions (down to minSdkVersion), but
+             was explicitly tested to work with the version specified here.
+             Specifying this version allows the platform to disable compatibility
+             code that are not required or enable newer features that are not
+             available to older applications.  This may also be a string
+             (such as "Donut") if this is built against a development
+             branch, in which case minSdkVersion is also forced to be that
+             string. -->
+        <attr name="targetSdkVersion" format="integer|string" />
+        <!-- This is the maximum SDK version number that an application works
+             on.  You can use this to ensure your application is filtered out
+             of later versions of the platform when you know you have
+             incompatibility with them. -->
+        <attr name="maxSdkVersion" format="integer" />
     </declare-styleable>
     
     <!-- The <code>uses-libraries</code> specifies a shared library that this
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 9e4c6a9..df5d879 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1087,7 +1087,7 @@
   <public type="integer" name="config_longAnimTime" id="0x010e0002" />
 
 <!-- ===============================================================
-     Resources added in version 4 of the platform.
+     Resources added in Donut.
      =============================================================== -->
   <eat-comment />
 
@@ -1097,6 +1097,8 @@
    <public type="attr" name="searchSuggestThreshold" id="0x0101026d" />
    <public type="attr" name="includeInGlobalSearch" id="0x0101026e" />
    <public type="attr" name="onClick" id="0x0101026f" />
+   <public type="attr" name="targetSdkVersion" id="0x01010270" />
+   <public type="attr" name="maxSdkVersion" id="0x01010271" />
 
    <public type="anim" name="anticipate_interpolator" id="0x010a0007" />
    <public type="anim" name="overshoot_interpolator" id="0x010a0008" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 6e2da4b..331ef1a 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -467,6 +467,12 @@
         the system, and steal or corrupt any data on it.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_shutdown">partial shutdown</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_shutdown">Puts the activity manager into a shutdown
+        state.  Does not perform a complete shutdown.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_runSetActivityWatcher">monitor and control all application launching</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_runSetActivityWatcher">Allows an application to
diff --git a/include/ui/Camera.h b/include/ui/Camera.h
index 901c7a9..048bdd5 100644
--- a/include/ui/Camera.h
+++ b/include/ui/Camera.h
@@ -63,6 +63,23 @@
 #define FRAME_CALLBACK_FLAG_CAMERA                   0x05
 #define FRAME_CALLBACK_FLAG_BARCODE_SCANNER          0x07
 
+// msgType in notifyCallback function
+enum {
+    CAMERA_MSG_ERROR,
+    CAMERA_MSG_SHUTTER,
+    CAMERA_MSG_FOCUS,
+    CAMERA_MSG_ZOOM
+};
+
+// msgType in dataCallback function
+enum {
+    CAMERA_MSG_PREVIEW_FRAME,
+    CAMERA_MSG_VIDEO_FRAME,
+    CAMERA_MSG_POSTVIEW_FRAME,
+    CAMERA_MSG_RAW_IMAGE,
+    CAMERA_MSG_COMPRESSED_IMAGE
+};
+
 class ICameraService;
 class ICamera;
 class Surface;
@@ -136,15 +153,8 @@
             void        setAutoFocusCallback(autofocus_callback cb, void *cookie);
 
     // ICameraClient interface
-    virtual void        shutterCallback();
-    virtual void        rawCallback(const sp<IMemory>& picture);
-    virtual void        jpegCallback(const sp<IMemory>& picture);
-    virtual void        previewCallback(const sp<IMemory>& frame);
-    virtual void        errorCallback(status_t error);
-    virtual void        autoFocusCallback(bool focused);
-    virtual void        recordingCallback(const sp<IMemory>& frame);
     virtual void        notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);
-    virtual void        dataCallback(int32_t msgType, const sp<IMemory>& frame);
+    virtual void        dataCallback(int32_t msgType, const sp<IMemory>& dataPtr);
 
     sp<ICamera>         remote();
 
diff --git a/include/ui/ICameraClient.h b/include/ui/ICameraClient.h
index 1645ef8..c4bdd07 100644
--- a/include/ui/ICameraClient.h
+++ b/include/ui/ICameraClient.h
@@ -29,30 +29,6 @@
 public:
     DECLARE_META_INTERFACE(CameraClient);
 
-    // msgType in notifyCallback function
-    enum {
-        ERROR,
-        SHUTTER,
-        FOCUSED,
-        ZOOM
-    } notify_callback_message_type;
-
-    // msgType in dataCallback function
-    enum {
-        PREVIEW,
-        RECORD,
-        POSTVIEW,
-        RAW,
-        COMPRESSED
-    } data_callback_message_type;
-
-    virtual void            shutterCallback() = 0;
-    virtual void            rawCallback(const sp<IMemory>& picture) = 0;
-    virtual void            jpegCallback(const sp<IMemory>& picture) = 0;
-    virtual void            previewCallback(const sp<IMemory>& frame) = 0;
-    virtual void            errorCallback(status_t error) = 0;
-    virtual void            autoFocusCallback(bool focused) = 0;
-    virtual void            recordingCallback(const sp<IMemory>& frame) = 0;
     virtual void            notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
     virtual void            dataCallback(int32_t msgType, const sp<IMemory>& data) = 0;
 
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
index ed4f3b8..6613700 100644
--- a/libs/ui/Camera.cpp
+++ b/libs/ui/Camera.cpp
@@ -337,76 +337,66 @@
     mErrorCallbackCookie = cookie;
 }
 
-void Camera::autoFocusCallback(bool focused)
-{
-    LOGV("autoFocusCallback");
-    if (mAutoFocusCallback) {
-        mAutoFocusCallback(focused, mAutoFocusCallbackCookie);
-    }
-}
-
-void Camera::shutterCallback()
-{
-    LOGV("shutterCallback");
-    if (mShutterCallback) {
-        mShutterCallback(mShutterCallbackCookie);
-    }
-}
-
-void Camera::rawCallback(const sp<IMemory>& picture)
-{
-    LOGV("rawCallback");
-    if (mRawCallback) {
-        mRawCallback(picture, mRawCallbackCookie);
-    }
-}
-
-// callback from camera service when image is ready
-void Camera::jpegCallback(const sp<IMemory>& picture)
-{
-    LOGV("jpegCallback");
-    if (mJpegCallback) {
-        mJpegCallback(picture, mJpegCallbackCookie);
-    }
-}
-
-// callback from camera service when preview frame is ready
-void Camera::previewCallback(const sp<IMemory>& frame)
-{
-    LOGV("frameCallback");
-    if (mPreviewCallback) {
-        mPreviewCallback(frame, mPreviewCallbackCookie);
-    }
-}
-
-// callback from camera service when a recording frame is ready
-void Camera::recordingCallback(const sp<IMemory>& frame)
-{
-    LOGV("recordingCallback");
-    if (mRecordingCallback) {
-        mRecordingCallback(frame, mRecordingCallbackCookie);
-    }
-}
-
-// callback from camera service when an error occurs in preview or takePicture
-void Camera::errorCallback(status_t error)
-{
-    LOGV("errorCallback");
-    if (mErrorCallback) {
-        mErrorCallback(error, mErrorCallbackCookie);
-    }
-}
-
 // callback from camera service
 void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
 {
-    LOGV("notifyCallback");
+    switch(msgType) {
+    case CAMERA_MSG_ERROR:
+        LOGV("errorCallback");
+        if (mErrorCallback) {
+            mErrorCallback((status_t)ext1, mErrorCallbackCookie);
+        }
+        break;
+    case CAMERA_MSG_FOCUS:
+        LOGV("autoFocusCallback");
+        if (mAutoFocusCallback) {
+            mAutoFocusCallback((bool)ext1, mAutoFocusCallbackCookie);
+        }
+        break;
+    case CAMERA_MSG_SHUTTER:
+        LOGV("shutterCallback");
+        if (mShutterCallback) {
+            mShutterCallback(mShutterCallbackCookie);
+        }
+        break;
+    default:
+        LOGV("notifyCallback(%d, %d, %d)", msgType, ext1, ext2);
+        break;
+    }
 }
 
-// callback from camera service when image is ready
-void Camera::dataCallback(int32_t msgType, const sp<IMemory>& frame)
+// callback from camera service when frame or image is ready
+void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
 {
-    LOGV("dataCallback");
+    switch(msgType) {
+    case CAMERA_MSG_PREVIEW_FRAME:
+        LOGV("previewCallback");
+        if (mPreviewCallback) {
+            mPreviewCallback(dataPtr, mPreviewCallbackCookie);
+        }
+        break;
+    case CAMERA_MSG_VIDEO_FRAME:
+        LOGV("recordingCallback");
+        if (mRecordingCallback) {
+            mRecordingCallback(dataPtr, mRecordingCallbackCookie);
+        }
+        break;
+    case CAMERA_MSG_RAW_IMAGE:
+        LOGV("rawCallback");
+        if (mRawCallback) {
+            mRawCallback(dataPtr, mRawCallbackCookie);
+        }
+        break;
+    case CAMERA_MSG_COMPRESSED_IMAGE:
+        LOGV("jpegCallback");
+        if (mJpegCallback) {
+            mJpegCallback(dataPtr, mJpegCallbackCookie);
+        }
+        break;
+    default:
+        LOGV("dataCallback(%d, %p)", msgType, dataPtr.get());
+        break;
+    }
 }
 
 void Camera::binderDied(const wp<IBinder>& who) {
diff --git a/libs/ui/ICameraClient.cpp b/libs/ui/ICameraClient.cpp
index ae07b67..c6cf75c 100644
--- a/libs/ui/ICameraClient.cpp
+++ b/libs/ui/ICameraClient.cpp
@@ -25,14 +25,7 @@
 namespace android {
 
 enum {
-    SHUTTER_CALLBACK = IBinder::FIRST_CALL_TRANSACTION,
-    RAW_CALLBACK,
-    JPEG_CALLBACK,
-    PREVIEW_CALLBACK,
-    ERROR_CALLBACK,
-    AUTOFOCUS_CALLBACK,
-    RECORDING_CALLBACK,
-    NOTIFY_CALLBACK,
+    NOTIFY_CALLBACK = IBinder::FIRST_CALL_TRANSACTION,
     DATA_CALLBACK,
 };
 
@@ -44,75 +37,6 @@
     {
     }
 
-    // callback to let the app know the shutter has closed, ideal for playing the shutter sound
-    void shutterCallback()
-    {
-        LOGV("shutterCallback");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
-        remote()->transact(SHUTTER_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-
-    // callback from camera service to app with picture data
-    void rawCallback(const sp<IMemory>& picture)
-    {
-        LOGV("rawCallback");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
-        data.writeStrongBinder(picture->asBinder());
-        remote()->transact(RAW_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-
-    // callback from camera service to app with picture data
-    void jpegCallback(const sp<IMemory>& picture)
-    {
-        LOGV("jpegCallback");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
-        data.writeStrongBinder(picture->asBinder());
-        remote()->transact(JPEG_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-
-    // callback from camera service to app with preview frame data
-    void previewCallback(const sp<IMemory>& frame)
-    {
-        LOGV("previewCallback");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
-        data.writeStrongBinder(frame->asBinder());
-        remote()->transact(PREVIEW_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-
-    // callback from camera service to app with recording frame data
-    void recordingCallback(const sp<IMemory>& frame)
-    {
-        LOGV("recordingCallback");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
-        data.writeStrongBinder(frame->asBinder());
-        remote()->transact(RECORDING_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-
-    // callback from camera service to app to report error
-    void errorCallback(status_t error)
-    {
-        LOGV("errorCallback");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
-        data.writeInt32(error);
-        remote()->transact(ERROR_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-
-    // callback from camera service to app to report autofocus completion
-    void autoFocusCallback(bool focused)
-    {
-        LOGV("autoFocusCallback");
-        Parcel data, reply;
-        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
-        data.writeInt32(focused);
-        remote()->transact(AUTOFOCUS_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-
     // generic callback from camera service to app
     void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
     {
@@ -152,54 +76,6 @@
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
     switch(code) {
-        case SHUTTER_CALLBACK: {
-            LOGV("SHUTTER_CALLBACK");
-            CHECK_INTERFACE(ICameraClient, data, reply);
-            shutterCallback();
-            return NO_ERROR;
-        } break;
-        case RAW_CALLBACK: {
-            LOGV("RAW_CALLBACK");
-            CHECK_INTERFACE(ICameraClient, data, reply);
-            sp<IMemory> picture = interface_cast<IMemory>(data.readStrongBinder());
-            rawCallback(picture);
-            return NO_ERROR;
-        } break;
-        case JPEG_CALLBACK: {
-            LOGV("JPEG_CALLBACK");
-            CHECK_INTERFACE(ICameraClient, data, reply);
-            sp<IMemory> picture = interface_cast<IMemory>(data.readStrongBinder());
-            jpegCallback(picture);
-            return NO_ERROR;
-        } break;
-        case PREVIEW_CALLBACK: {
-            LOGV("PREVIEW_CALLBACK");
-            CHECK_INTERFACE(ICameraClient, data, reply);
-            sp<IMemory> frame = interface_cast<IMemory>(data.readStrongBinder());
-            previewCallback(frame);
-            return NO_ERROR;
-        } break;
-        case RECORDING_CALLBACK: {
-            LOGV("RECORDING_CALLBACK");
-            CHECK_INTERFACE(ICameraClient, data, reply);
-            sp<IMemory> frame = interface_cast<IMemory>(data.readStrongBinder());
-            recordingCallback(frame);
-            return NO_ERROR;
-        } break;
-        case ERROR_CALLBACK: {
-            LOGV("ERROR_CALLBACK");
-            CHECK_INTERFACE(ICameraClient, data, reply);
-            status_t error = data.readInt32();
-            errorCallback(error);
-            return NO_ERROR;
-        } break;
-        case AUTOFOCUS_CALLBACK: {
-            LOGV("AUTOFOCUS_CALLBACK");
-            CHECK_INTERFACE(ICameraClient, data, reply);
-            bool focused = (bool)data.readInt32();
-            autoFocusCallback(focused);
-            return NO_ERROR;
-        } break;
         case NOTIFY_CALLBACK: {
             LOGV("NOTIFY_CALLBACK");
             CHECK_INTERFACE(ICameraClient, data, reply);
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index 21c7adb..943d56c 100644
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -109,13 +109,13 @@
     private static final int GPS_STATUS_ENGINE_ON = 3;
     private static final int GPS_STATUS_ENGINE_OFF = 4;
 
-    // these need to match GpsSuplStatusValue defines in gps.h
-    /** SUPL status event values. */
-    private static final int GPS_REQUEST_SUPL_DATA_CONN = 1;
-    private static final int GPS_RELEASE_SUPL_DATA_CONN = 2;
-    private static final int GPS_SUPL_DATA_CONNECTED = 3;
-    private static final int GPS_SUPL_DATA_CONN_DONE = 4;
-    private static final int GPS_SUPL_DATA_CONN_FAILED = 5;
+    // these need to match GpsApgsStatusValue defines in gps.h
+    /** AGPS status event values. */
+    private static final int GPS_REQUEST_AGPS_DATA_CONN = 1;
+    private static final int GPS_RELEASE_AGPS_DATA_CONN = 2;
+    private static final int GPS_AGPS_DATA_CONNECTED = 3;
+    private static final int GPS_AGPS_DATA_CONN_DONE = 4;
+    private static final int GPS_AGPS_DATA_CONN_FAILED = 5;
 
     // these need to match GpsLocationFlags enum in gps.h
     private static final int LOCATION_INVALID = 0;
@@ -124,8 +124,8 @@
     private static final int LOCATION_HAS_SPEED = 4;
     private static final int LOCATION_HAS_BEARING = 8;
     private static final int LOCATION_HAS_ACCURACY = 16;
-    
-// IMPORTANT - the GPS_DELETE_* symbols here must match constants in GpsLocationProvider.java
+
+// IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h
     private static final int GPS_DELETE_EPHEMERIS = 0x0001;
     private static final int GPS_DELETE_ALMANAC = 0x0002;
     private static final int GPS_DELETE_POSITION = 0x0004;
@@ -140,10 +140,14 @@
     private static final int GPS_DELETE_CELLDB_INFO = 0x8000;
     private static final int GPS_DELETE_ALL = 0xFFFF;
 
-    // for mSuplDataConnectionState
-    private static final int SUPL_DATA_CONNECTION_CLOSED = 0;
-    private static final int SUPL_DATA_CONNECTION_OPENING = 1;
-    private static final int SUPL_DATA_CONNECTION_OPEN = 2;
+    // these need to match AGpsType enum in gps.h
+    private static final int AGPS_TYPE_SUPL = 1;
+    private static final int AGPS_TYPE_C2K = 2;
+
+    // for mAGpsDataConnectionState
+    private static final int AGPS_DATA_CONNECTION_CLOSED = 0;
+    private static final int AGPS_DATA_CONNECTION_OPENING = 1;
+    private static final int AGPS_DATA_CONNECTION_OPEN = 2;
 
     private static final String PROPERTIES_FILE = "/etc/gps.conf";
 
@@ -203,9 +207,12 @@
 
     private String mSuplHost;
     private int mSuplPort;
+    private String mC2KHost;
+    private int mC2KPort;
     private boolean mSetSuplServer;
-    private String mSuplApn;
-    private int mSuplDataConnectionState;
+    private boolean mSetC2KServer;
+    private String mAGpsApn;
+    private int mAGpsDataConnectionState;
     private final ConnectivityManager mConnMgr;
 
     // Wakelocks
@@ -293,11 +300,12 @@
                 if (Config.LOGD) {
                     Log.d(TAG, "state: " + state +  " apnName: " + apnName + " reason: " + reason);
                 }
+                // FIXME - might not have an APN on CDMA
                 if ("CONNECTED".equals(state) && apnName != null && apnName.length() > 0) {
-                    mSuplApn = apnName;
-                    if (mSuplDataConnectionState == SUPL_DATA_CONNECTION_OPENING) {
-                        native_supl_data_conn_open(mSuplApn);
-                        mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPEN;
+                    mAGpsApn = apnName;
+                    if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
+                        native_agps_data_conn_open(mAGpsApn);
+                        mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
                     }
                 }
             }
@@ -336,14 +344,26 @@
             mProperties.load(stream);
             stream.close();
             mNtpServer = mProperties.getProperty("NTP_SERVER", null);
+
             mSuplHost = mProperties.getProperty("SUPL_HOST");
-            String suplPortString = mProperties.getProperty("SUPL_PORT");
-            if (mSuplHost != null && suplPortString != null) {
+            String portString = mProperties.getProperty("SUPL_PORT");
+            if (mSuplHost != null && portString != null) {
                 try {
-                    mSuplPort = Integer.parseInt(suplPortString);
+                    mSuplPort = Integer.parseInt(portString);
                     mSetSuplServer = true;
                 } catch (NumberFormatException e) {
-                    Log.e(TAG, "unable to parse SUPL_PORT: " + suplPortString);
+                    Log.e(TAG, "unable to parse SUPL_PORT: " + portString);
+                }
+            }
+
+            mC2KHost = mProperties.getProperty("C2K_HOST");
+            portString = mProperties.getProperty("C2K_PORT");
+            if (mC2KHost != null && portString != null) {
+                try {
+                    mC2KPort = Integer.parseInt(portString);
+                    mSetC2KServer = true;
+                } catch (NumberFormatException e) {
+                    Log.e(TAG, "unable to parse C2K_PORT: " + portString);
                 }
             }
         } catch (IOException e) {
@@ -358,7 +378,8 @@
     public boolean requiresNetwork() {
         // We want updateNetworkState() to get called when the network state changes
         // for XTRA and NTP time injection support.
-        return (mNtpServer != null || native_supports_xtra() || mSuplHost != null);
+        return (mNtpServer != null || native_supports_xtra() ||
+                mSuplHost != null || mC2KHost != null);
     }
 
     public void updateNetworkState(int state) {
@@ -561,7 +582,6 @@
                 interval = 1;
             }
             mFixInterval = interval;
-            native_set_fix_frequency(mFixInterval);
         }
     }
 
@@ -871,38 +891,38 @@
     }
 
     /**
-     * called from native code to update SUPL status
+     * called from native code to update AGPS status
      */
-    private void reportSuplStatus(int status) {
+    private void reportAGpsStatus(int type, int status) {
         switch (status) {
-            case GPS_REQUEST_SUPL_DATA_CONN:
+            case GPS_REQUEST_AGPS_DATA_CONN:
                  int result = mConnMgr.startUsingNetworkFeature(
                         ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL);
                 if (result == Phone.APN_ALREADY_ACTIVE) {
-                    native_supl_data_conn_open(mSuplApn);
-                    mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPEN;
+                    native_agps_data_conn_open(mAGpsApn);
+                    mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
                 } else if (result == Phone.APN_REQUEST_STARTED) {
-                    mSuplDataConnectionState = SUPL_DATA_CONNECTION_OPENING;
+                    mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING;
                 } else {
-                    native_supl_data_conn_failed();
+                    native_agps_data_conn_failed();
                 }
                 break;
-            case GPS_RELEASE_SUPL_DATA_CONN:
-                if (mSuplDataConnectionState != SUPL_DATA_CONNECTION_CLOSED) {
+            case GPS_RELEASE_AGPS_DATA_CONN:
+                if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) {
                     mConnMgr.stopUsingNetworkFeature(
                             ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL);
-                    native_supl_data_conn_closed();
-                    mSuplDataConnectionState = SUPL_DATA_CONNECTION_CLOSED;
+                    native_agps_data_conn_closed();
+                    mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED;
                 }
                 break;
-            case GPS_SUPL_DATA_CONNECTED:
-                // Log.d(TAG, "GPS_SUPL_DATA_CONNECTED");
+            case GPS_AGPS_DATA_CONNECTED:
+                // Log.d(TAG, "GPS_AGPS_DATA_CONNECTED");
                 break;
-            case GPS_SUPL_DATA_CONN_DONE:
-                // Log.d(TAG, "GPS_SUPL_DATA_CONN_DONE");
+            case GPS_AGPS_DATA_CONN_DONE:
+                // Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE");
                 break;
-            case GPS_SUPL_DATA_CONN_FAILED:
-                // Log.d(TAG, "GPS_SUPL_DATA_CONN_FAILED");
+            case GPS_AGPS_DATA_CONN_FAILED:
+                // Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED");
                 break;
         }
     }
@@ -914,6 +934,29 @@
         }
     }
 
+    private boolean setAGpsServer(int type, String host, int port) {
+        try {
+            InetAddress inetAddress = InetAddress.getByName(host);
+            if (inetAddress != null) {
+                byte[] addrBytes = inetAddress.getAddress();
+                long addr = 0;
+                for (int i = 0; i < addrBytes.length; i++) {
+                    int temp = addrBytes[i];
+                    // signed -> unsigned
+                    if (temp < 0) temp = 256 + temp;
+                    addr = addr * 256 + temp;
+                }
+                // use MS-Based position mode if SUPL support is enabled
+                mPositionMode = GPS_POSITION_MODE_MS_BASED;
+                native_set_agps_server(type, (int)addr, port);
+            }
+        } catch (UnknownHostException e) {
+            Log.e(TAG, "unknown host for server " + host);
+            return false;
+        }
+        return true;
+    }
+
     private class GpsEventThread extends Thread {
 
         public GpsEventThread() {
@@ -985,7 +1028,8 @@
                         }
                     }
                     waitTime = getWaitTime();
-                } while (!mDone && ((!mXtraDownloadRequested && !mSetSuplServer && waitTime > 0)
+                } while (!mDone && ((!mXtraDownloadRequested &&
+                        !mSetSuplServer && !mSetC2KServer && waitTime > 0)
                         || !mNetworkAvailable));
                 if (Config.LOGD) Log.d(TAG, "NetworkThread out of wake loop");
                 
@@ -1012,26 +1056,15 @@
                         }
                     }
 
-                    // Set the SUPL server address if we have not yet
+                    // Set the AGPS server addresses if we have not yet
                     if (mSetSuplServer) {
-                        try {
-                            InetAddress inetAddress = InetAddress.getByName(mSuplHost);
-                            if (inetAddress != null) {
-                                byte[] addrBytes = inetAddress.getAddress();
-                                long addr = 0;
-                                for (int i = 0; i < addrBytes.length; i++) {
-                                    int temp = addrBytes[i];
-                                    // signed -> unsigned
-                                    if (temp < 0) temp = 256 + temp;
-                                    addr = addr * 256 + temp;
-                                }
-                                // use MS-Based position mode if SUPL support is enabled
-                                mPositionMode = GPS_POSITION_MODE_MS_BASED;
-                                native_set_supl_server((int)addr, mSuplPort);
-                                mSetSuplServer = false; 
-                            }
-                        } catch (UnknownHostException e) {
-                            Log.e(TAG, "unknown host for SUPL server " + mSuplHost);
+                        if (setAGpsServer(AGPS_TYPE_SUPL, mSuplHost, mSuplPort)) {
+                            mSetSuplServer = false;
+                        }
+                    }
+                    if (mSetC2KServer) {
+                        if (setAGpsServer(AGPS_TYPE_C2K, mC2KHost, mC2KPort)) {
+                            mSetC2KServer = false;
                         }
                     }
 
@@ -1125,9 +1158,9 @@
     private native boolean native_supports_xtra();
     private native void native_inject_xtra_data(byte[] data, int length);
 
-    // SUPL Support    
-    private native void native_supl_data_conn_open(String apn);
-    private native void native_supl_data_conn_closed();
-    private native void native_supl_data_conn_failed();
-    private native void native_set_supl_server(int addr, int port);
+    // AGPS Support    
+    private native void native_agps_data_conn_open(String apn);
+    private native void native_agps_data_conn_closed();
+    private native void native_agps_data_conn_failed();
+    private native void native_set_agps_server(int type, int addr, int port);
 }
diff --git a/opengl/include/GLES/glext.h b/opengl/include/GLES/glext.h
index 4c01871a..a8fe2e9 100644
--- a/opengl/include/GLES/glext.h
+++ b/opengl/include/GLES/glext.h
@@ -599,21 +599,6 @@
 #define GL_EXT_texture_filter_anisotropic 1
 #endif
 
-/*------------------------------------------------------------------------*
- * dalvik extension functions
- *------------------------------------------------------------------------*/
-#ifdef ANDROID
-void glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
-        const GLvoid *ptr, GLsizei count);
-void glNormalPointerBounds(GLenum type, GLsizei stride,
-        const GLvoid *pointer, GLsizei count);
-void glTexCoordPointerBounds(GLint size, GLenum type,
-        GLsizei stride, const GLvoid *pointer, GLsizei count);
-void glVertexPointerBounds(GLint size, GLenum type,
-        GLsizei stride, const GLvoid *pointer, GLsizei count);
-#endif
-
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/opengl/include/KHR/khrplatform.h b/opengl/include/KHR/khrplatform.h
index 4cc27c5..1660bd7 100644
--- a/opengl/include/KHR/khrplatform.h
+++ b/opengl/include/KHR/khrplatform.h
@@ -91,6 +91,8 @@
 #   define KHRONOS_APICALL __declspec(dllimport)
 #elif defined (__SYMBIAN32__)
 #   define KHRONOS_APICALL IMPORT_C
+#elif defined(ANDROID)
+#   define KHRONOS_APICALL __attribute__((visibility("default")))
 #else
 #   define KHRONOS_APICALL
 #endif
diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk
index 99efe4c..3ce0414 100644
--- a/opengl/libagl/Android.mk
+++ b/opengl/libagl/Android.mk
@@ -33,6 +33,8 @@
 endif
 
 LOCAL_SHARED_LIBRARIES := libcutils libutils libpixelflinger
+LOCAL_CFLAGS += -fvisibility=hidden
+
 LOCAL_LDLIBS := -lpthread -ldl
 LOCAL_MODULE:= libagl
 
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index d636d73..5ba6b76 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -23,6 +23,8 @@
     LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private
 endif
 
+LOCAL_CFLAGS += -fvisibility=hidden
+
 include $(BUILD_SHARED_LIBRARY)
 
 
@@ -49,4 +51,6 @@
     LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private
 endif
 
+LOCAL_CFLAGS += -fvisibility=hidden
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/opengl/libs/EGL/gpu.cpp b/opengl/libs/EGL/gpu.cpp
index 3f9fd63..f9dc5f1 100644
--- a/opengl/libs/EGL/gpu.cpp
+++ b/opengl/libs/EGL/gpu.cpp
@@ -53,7 +53,7 @@
 static Mutex                            gRegionsLock;
 static request_gpu_t                    gRegions;
 static sp<ISurfaceComposer>             gSurfaceManager;
-ISurfaceComposer*                       GLES_localSurfaceManager = 0;
+GL_API ISurfaceComposer*                GLES_localSurfaceManager = 0;
 
 extern egl_connection_t gEGLImpl[2];
 
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index 0057168..384b59a 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -37,6 +37,17 @@
 // extensions for the framework
 // ----------------------------------------------------------------------------
 
+extern "C" {
+GL_API void GL_APIENTRY glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
+        const GLvoid *ptr, GLsizei count);
+GL_API void GL_APIENTRY glNormalPointerBounds(GLenum type, GLsizei stride,
+        const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glTexCoordPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count);
+}
+
 void glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
         const GLvoid *ptr, GLsizei count) {
     glColorPointer(size, type, stride, ptr);
diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h
index 62ce3fc..312b176 100644
--- a/opengl/libs/egl_impl.h
+++ b/opengl/libs/egl_impl.h
@@ -20,6 +20,8 @@
 #include <ctype.h>
 
 #include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <EGL/eglplatform.h>
 
 // ----------------------------------------------------------------------------
 namespace android {
diff --git a/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp
index 7aa18b6..3948fd3 100644
--- a/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp
+++ b/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp
@@ -23,6 +23,19 @@
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
+/* special calls implemented in Android's GLES wrapper used to more
+ * efficiently bound-check passed arrays */
+extern "C" {
+GL_API void GL_APIENTRY glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
+        const GLvoid *ptr, GLsizei count);
+GL_API void GL_APIENTRY glNormalPointerBounds(GLenum type, GLsizei stride,
+        const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glTexCoordPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count);
+}
+
 static int initialized = 0;
 
 static jclass nioAccessClass;
diff --git a/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp b/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
index 8f174c7..11c6087 100644
--- a/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
+++ b/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
@@ -23,6 +23,19 @@
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
+/* special calls implemented in Android's GLES wrapper used to more
+ * efficiently bound-check passed arrays */
+extern "C" {
+GL_API void GL_APIENTRY glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
+        const GLvoid *ptr, GLsizei count);
+GL_API void GL_APIENTRY glNormalPointerBounds(GLenum type, GLsizei stride,
+        const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glTexCoordPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count);
+}
+
 static int initialized = 0;
 
 static jclass nioAccessClass;
diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/java/com/android/server/DeviceStorageMonitorService.java
index 85861bb..52e09ca 100644
--- a/services/java/com/android/server/DeviceStorageMonitorService.java
+++ b/services/java/com/android/server/DeviceStorageMonitorService.java
@@ -74,7 +74,7 @@
     private boolean mLowMemFlag=false;
     private Context mContext;
     private ContentResolver mContentResolver;
-    int mBlkSize;
+    long mBlkSize;
     long mTotalMemory;
     StatFs mFileStats;
     private static final String DATA_PATH="/data";
@@ -251,7 +251,7 @@
         //initialize block size
         mBlkSize = mFileStats.getBlockSize();
         //initialize total storage on device
-        mTotalMemory = (mFileStats.getBlockCount()*mBlkSize)/100;
+        mTotalMemory = ((long)mFileStats.getBlockCount()*mBlkSize)/100L;
         mStorageLowIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_LOW);
         mStorageOkIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK);
         checkMemory(true);
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 159bc76..237b70d 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -59,6 +59,7 @@
 import android.content.pm.Signature;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.HandlerThread;
 import android.os.Parcel;
@@ -140,8 +141,9 @@
             Process.THREAD_PRIORITY_BACKGROUND);
     final Handler mHandler;
 
-    final int mSdkVersion = SystemProperties.getInt(
-            "ro.build.version.sdk", 0);
+    final int mSdkVersion = Build.VERSION.SDK_INT;
+    final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME)
+            ? null : Build.VERSION.CODENAME;
     
     final Context mContext;
     final boolean mFactoryTest;
@@ -1751,7 +1753,7 @@
         parseFlags |= mDefParseFlags;
         PackageParser pp = new PackageParser(scanFile.getPath());
         pp.setSeparateProcesses(mSeparateProcesses);
-        pp.setSdkVersion(mSdkVersion);
+        pp.setSdkVersion(mSdkVersion, mSdkCodename);
         final PackageParser.Package pkg = pp.parsePackage(scanFile,
                 destCodeFile.getAbsolutePath(), mMetrics, parseFlags);
         if (pkg == null) {
@@ -1761,8 +1763,7 @@
         PackageSetting ps;
         PackageSetting updatedPkg;
         synchronized (mPackages) {
-            ps = mSettings.peekPackageLP(pkg.packageName,
-                    scanFile.toString());
+            ps = mSettings.peekPackageLP(pkg.packageName);
             updatedPkg = mSettings.mDisabledSysPackages.get(pkg.packageName);
         }
         if (updatedPkg != null) {
@@ -1771,13 +1772,21 @@
         }
         if ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
             // Check for updated system applications here
-            if ((updatedPkg != null) && (ps == null)) {
-                // The system package has been updated and the code path does not match
-                // Ignore entry. Just return
-                Log.w(TAG, "Package:" + pkg.packageName + 
-                        " has been updated. Ignoring the one from path:"+scanFile);
-                mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
-                return null;
+            if (updatedPkg != null) {
+                if ((ps != null) && (!ps.codePath.getPath().equals(scanFile.getPath()))) {
+                    if (pkg.mVersionCode <= ps.versionCode) {
+                     // The system package has been updated and the code path does not match
+                        // Ignore entry. Just return
+                        Log.w(TAG, "Package:" + pkg.packageName +
+                                " has been updated. Ignoring the one from path:"+scanFile);
+                        mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
+                        return null;
+                    } else {
+                        // Delete the older apk pointed to by ps
+                        deletePackageResourcesLI(ps.name, ps.codePathString, ps.resourcePathString);
+                        mSettings.enableSystemPackageLP(ps.name);
+                    }
+                }
             }
         }
         if (!collectCertificatesLI(pp, ps, pkg, scanFile, parseFlags)) {
@@ -3341,23 +3350,23 @@
             String destFilePath, File destPackageFile, File destResourceFile,
             PackageParser.Package pkg, boolean forwardLocked, boolean newInstall,
             PackageInstalledInfo res) {
-        PackageParser.Package deletedPackage;
+        PackageParser.Package oldPackage;
         // First find the old package info and check signatures
         synchronized(mPackages) {
-            deletedPackage = mPackages.get(pkgName);
-            if(checkSignaturesLP(pkg, deletedPackage) != PackageManager.SIGNATURE_MATCH) {
+            oldPackage = mPackages.get(pkgName);
+            if(checkSignaturesLP(pkg, oldPackage) != PackageManager.SIGNATURE_MATCH) {
                 res.returnCode = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
                 return;
             }
         }
-        boolean sysPkg = ((deletedPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
+        boolean sysPkg = ((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
         if(sysPkg) {
-            replaceSystemPackageLI(deletedPackage, 
+            replaceSystemPackageLI(oldPackage,
                     tmpPackageFile, destFilePath, 
                     destPackageFile, destResourceFile, pkg, forwardLocked,
                     newInstall, res);
         } else {
-            replaceNonSystemPackageLI(deletedPackage, tmpPackageFile, destFilePath, 
+            replaceNonSystemPackageLI(oldPackage, tmpPackageFile, destFilePath,
                     destPackageFile, destResourceFile, pkg, forwardLocked,
                     newInstall, res);
         }
@@ -3686,7 +3695,7 @@
             parseFlags |= mDefParseFlags;
             PackageParser pp = new PackageParser(tmpPackageFile.getPath());
             pp.setSeparateProcesses(mSeparateProcesses);
-            pp.setSdkVersion(mSdkVersion);
+            pp.setSdkVersion(mSdkVersion, mSdkCodename);
             final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile,
                     destPackageFile.getAbsolutePath(), mMetrics, parseFlags);
             if (pkg == null) {
@@ -3996,7 +4005,7 @@
      * Tries to delete system package.
      */
     private boolean deleteSystemPackageLI(PackageParser.Package p,
-            boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo) {
+            int flags, PackageRemovedInfo outInfo) {
         ApplicationInfo applicationInfo = p.applicationInfo;
         //applicable for non-partially installed applications only
         if (applicationInfo == null) {
@@ -4018,6 +4027,19 @@
         }
         // Delete the updated package
         outInfo.isRemovedPackageSystemUpdate = true;
+        boolean deleteCodeAndResources = false;
+        if (ps.versionCode <  p.mVersionCode) {
+            // Delete code and resources for downgrades
+            deleteCodeAndResources = true;
+            if ((flags & PackageManager.DONT_DELETE_DATA) == 0) {
+                flags &= ~PackageManager.DONT_DELETE_DATA;
+            }
+        } else {
+            // Preserve data by setting flag
+            if ((flags & PackageManager.DONT_DELETE_DATA) == 0) {
+                flags |= PackageManager.DONT_DELETE_DATA;
+            }
+        }
         boolean ret = deleteInstalledPackageLI(p, deleteCodeAndResources, flags, outInfo);
         if (!ret) {
             return false;
@@ -4041,6 +4063,28 @@
         return true;
     }
     
+    private void deletePackageResourcesLI(String packageName,
+            String sourceDir, String publicSourceDir) {
+        File sourceFile = new File(sourceDir);
+        if (!sourceFile.exists()) {
+            Log.w(TAG, "Package source " + sourceDir + " does not exist.");
+        }
+        // Delete application's code and resources
+        sourceFile.delete();
+        final File publicSourceFile = new File(publicSourceDir);
+        if (publicSourceFile.exists()) {
+            publicSourceFile.delete();
+        }
+        if (mInstaller != null) {
+            int retCode = mInstaller.rmdex(sourceFile.toString());
+            if (retCode < 0) {
+                Log.w(TAG, "Couldn't remove dex file for package: "
+                        + packageName + " at location " + sourceFile.toString() + ", retcode=" + retCode);
+                // we don't consider this to be a failure of the core package deletion
+            }
+        }
+    }
+    
     private boolean deleteInstalledPackageLI(PackageParser.Package p,
             boolean deleteCodeAndResources, int flags, PackageRemovedInfo outInfo) {
         ApplicationInfo applicationInfo = p.applicationInfo;
@@ -4048,11 +4092,6 @@
             Log.w(TAG, "Package " + p.packageName + " has no applicationInfo.");
             return false;
         }
-        // Delete application's source directory
-        File sourceFile = new File(applicationInfo.sourceDir);
-        if (!sourceFile.exists()) {
-            Log.w(TAG, "Package source " + applicationInfo.sourceDir + " does not exist.");
-        }
         outInfo.uid = applicationInfo.uid;
 
         // Delete package data from internal structures and also remove data if flag is set
@@ -4060,19 +4099,8 @@
 
         // Delete application code and resources
         if (deleteCodeAndResources) {
-            sourceFile.delete();
-            final File publicSourceFile = new File(applicationInfo.publicSourceDir);
-            if (publicSourceFile.exists()) {
-                publicSourceFile.delete();
-            }
-            if (mInstaller != null) {
-                int retCode = mInstaller.rmdex(sourceFile.toString());
-                if (retCode < 0) {
-                    Log.w(TAG, "Couldn't remove dex file for package: "
-                            + p.packageName + " at location " + sourceFile.toString() + ", retcode=" + retCode);
-                    // we don't consider this to be a failure of the core package deletion
-                }
-            }
+            deletePackageResourcesLI(applicationInfo.packageName,
+                    applicationInfo.sourceDir, applicationInfo.publicSourceDir);
         }
         return true;
     }
@@ -4120,7 +4148,7 @@
             Log.i(TAG, "Removing system package:"+p.packageName);
             // When an updated system application is deleted we delete the existing resources as well and
             // fall back to existing code in system partition
-            return deleteSystemPackageLI(p, true, flags, outInfo);
+            return deleteSystemPackageLI(p, flags, outInfo);
         }
         Log.i(TAG, "Removing non-system package:"+p.packageName);
         return deleteInstalledPackageLI (p, deleteCodeAndResources, flags, outInfo);
@@ -5152,6 +5180,7 @@
         final String resourcePathString;
         private long timeStamp;
         private String timeStampString = "0";
+        final int versionCode;
 
         PackageSignatures signatures = new PackageSignatures();
 
@@ -5165,13 +5194,14 @@
         int installStatus = PKG_INSTALL_COMPLETE;
 
         PackageSettingBase(String name, File codePath, File resourcePath,
-                int pkgFlags) {
+                int pVersionCode, int pkgFlags) {
             super(pkgFlags);
             this.name = name;
             this.codePath = codePath;
             this.codePathString = codePath.toString();
             this.resourcePath = resourcePath;
             this.resourcePathString = resourcePath.toString();
+            this.versionCode = pVersionCode;
         }
 
         public void setInstallStatus(int newStatus) {
@@ -5252,8 +5282,8 @@
         SharedUserSetting sharedUser;
 
         PackageSetting(String name, File codePath, File resourcePath,
-                 int pkgFlags) {
-            super(name, codePath, resourcePath, pkgFlags);
+                int pVersionCode, int pkgFlags) {
+            super(name, codePath, resourcePath, pVersionCode, pkgFlags);
         }
         
         @Override
@@ -5351,8 +5381,8 @@
             final int sharedId;
 
             PendingPackage(String name, File codePath, File resourcePath,
-                    int sharedId, int pkgFlags) {
-                super(name, codePath, resourcePath, pkgFlags);
+                    int sharedId, int pVersionCode, int pkgFlags) {
+                super(name, codePath, resourcePath, pVersionCode, pkgFlags);
                 this.sharedId = sharedId;
             }
         }
@@ -5376,7 +5406,7 @@
                 int pkgFlags, boolean create, boolean add) {
             final String name = pkg.packageName;
             PackageSetting p = getPackageLP(name, sharedUser, codePath,
-                    resourcePath, pkgFlags, create, add);
+                    resourcePath, pkg.mVersionCode, pkgFlags, create, add);
 
             if (p != null) {
                 p.pkg = pkg;
@@ -5384,12 +5414,15 @@
             return p;
         }
         
-        PackageSetting peekPackageLP(String name, String codePath) {
+        PackageSetting peekPackageLP(String name) {
+            return mPackages.get(name);
+            /*
             PackageSetting p = mPackages.get(name);
             if (p != null && p.codePath.getPath().equals(codePath)) {
                 return p;
             }
             return null;
+            */
         }
         
         void setInstallStatus(String pkgName, int status) {
@@ -5461,13 +5494,13 @@
                 p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
             }
             PackageSetting ret = addPackageLP(name, p.codePath,
-                    p.resourcePath, p.userId, p.pkgFlags);
+                    p.resourcePath, p.userId, p.versionCode, p.pkgFlags);
             mDisabledSysPackages.remove(name);
             return ret;
         }
         
         PackageSetting addPackageLP(String name, File codePath,
-                File resourcePath, int uid, int pkgFlags) {
+                File resourcePath, int uid, int vc, int pkgFlags) {
             PackageSetting p = mPackages.get(name);
             if (p != null) {
                 if (p.userId == uid) {
@@ -5477,7 +5510,7 @@
                         "Adding duplicate package, keeping first: " + name);
                 return null;
             }
-            p = new PackageSetting(name, codePath, resourcePath, pkgFlags);
+            p = new PackageSetting(name, codePath, resourcePath, vc, pkgFlags);
             p.userId = uid;
             if (addUserIdLP(uid, p, name)) {
                 mPackages.put(name, p);
@@ -5507,7 +5540,7 @@
 
         private PackageSetting getPackageLP(String name,
                 SharedUserSetting sharedUser, File codePath, File resourcePath,
-                int pkgFlags, boolean create, boolean add) {
+                int vc, int pkgFlags, boolean create, boolean add) {
             PackageSetting p = mPackages.get(name);
             if (p != null) {
                 if (!p.codePath.equals(codePath)) {
@@ -5549,7 +5582,7 @@
                 if (!create) {
                     return null;
                 }
-                p = new PackageSetting(name, codePath, resourcePath, pkgFlags);
+                p = new PackageSetting(name, codePath, resourcePath, vc, pkgFlags);
                 p.setTimeStamp(codePath.lastModified());
                 if (sharedUser != null) {
                     p.userId = sharedUser.userId;
@@ -5816,6 +5849,7 @@
             serializer.attribute(null, "name", pkg.name);
             serializer.attribute(null, "codePath", pkg.codePathString);
             serializer.attribute(null, "ts", pkg.getTimeStampStr());
+            serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
             if (!pkg.resourcePathString.equals(pkg.codePathString)) {
                 serializer.attribute(null, "resourcePath", pkg.resourcePathString);
             }
@@ -5859,6 +5893,7 @@
                     (pkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0
                     ? "true" : "false");
             serializer.attribute(null, "ts", pkg.getTimeStampStr());
+            serializer.attribute(null, "version", String.valueOf(pkg.versionCode));
             if (pkg.sharedUser == null) {
                 serializer.attribute(null, "userId",
                         Integer.toString(pkg.userId));
@@ -6050,7 +6085,7 @@
                 if (idObj != null && idObj instanceof SharedUserSetting) {
                     PackageSetting p = getPackageLP(pp.name,
                             (SharedUserSetting)idObj, pp.codePath, pp.resourcePath,
-                            pp.pkgFlags, true, true);
+                            pp.versionCode, pp.pkgFlags, true, true);
                     if (p == null) {
                         Log.w(TAG, "Unable to create application package for "
                                 + pp.name);
@@ -6169,12 +6204,20 @@
             if(resourcePathStr == null) {
                 resourcePathStr = codePathStr;
             }
+            String version = parser.getAttributeValue(null, "version");
+            int versionCode = 0;
+            if (version != null) {
+                try {
+                    versionCode = Integer.parseInt(version);
+                } catch (NumberFormatException e) {
+                }
+            }
             
             int pkgFlags = 0;
             pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
             PackageSetting ps = new PackageSetting(name, 
                     new File(codePathStr), 
-                    new File(resourcePathStr), pkgFlags);
+                    new File(resourcePathStr), versionCode, pkgFlags);
             String timeStampStr = parser.getAttributeValue(null, "ts");
             if (timeStampStr != null) {
                 try {
@@ -6225,12 +6268,21 @@
             String timeStampStr;
             long timeStamp = 0;
             PackageSettingBase packageSetting = null;
+            String version = null;
+            int versionCode = 0;
             try {
                 name = parser.getAttributeValue(null, "name");
                 idStr = parser.getAttributeValue(null, "userId");
                 sharedIdStr = parser.getAttributeValue(null, "sharedUserId");
                 codePathStr = parser.getAttributeValue(null, "codePath");
                 resourcePathStr = parser.getAttributeValue(null, "resourcePath");
+                version = parser.getAttributeValue(null, "version");
+                if (version != null) {
+                    try {
+                        versionCode = Integer.parseInt(version);
+                    } catch (NumberFormatException e) {
+                    }
+                }
                 systemStr = parser.getAttributeValue(null, "system");
                 if (systemStr != null) {
                     if ("true".equals(systemStr)) {
@@ -6264,7 +6316,7 @@
                             + parser.getPositionDescription());
                 } else if (userId > 0) {
                     packageSetting = addPackageLP(name.intern(), new File(codePathStr), 
-                            new File(resourcePathStr), userId, pkgFlags);
+                            new File(resourcePathStr), userId, versionCode, pkgFlags);
                     if (DEBUG_SETTINGS) Log.i(TAG, "Reading package " + name
                             + ": userId=" + userId + " pkg=" + packageSetting);
                     if (packageSetting == null) {
@@ -6280,7 +6332,7 @@
                             ? Integer.parseInt(sharedIdStr) : 0;
                     if (userId > 0) {
                         packageSetting = new PendingPackage(name.intern(), new File(codePathStr),
-                                new File(resourcePathStr), userId, pkgFlags);
+                                new File(resourcePathStr), userId, versionCode, pkgFlags);
                         packageSetting.setTimeStamp(timeStamp, timeStampStr);
                         mPendingPackages.add((PendingPackage) packageSetting);
                         if (DEBUG_SETTINGS) Log.i(TAG, "Reading package " + name
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index b04f5a8..9471eff 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -169,6 +169,10 @@
     static final int LOG_BOOT_PROGRESS_AMS_READY = 3040;
     static final int LOG_BOOT_PROGRESS_ENABLE_SCREEN = 3050;
 
+    // The flags that are set for all calls we make to the package manager.
+    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES
+            | PackageManager.GET_SUPPORTS_DENSITIES;
+    
     private static final String SYSTEM_SECURE = "ro.secure";
 
     // This is the maximum number of application processes we would like
@@ -707,6 +711,11 @@
     boolean mSleeping = false;
 
     /**
+     * Set if we are shutting down the system, similar to sleeping.
+     */
+    boolean mShuttingDown = false;
+    
+    /**
      * Set when the system is going to sleep, until we have
      * successfully paused the current activity and released our wake lock.
      * At that point the system is allowed to actually sleep.
@@ -868,7 +877,7 @@
                         return;
                     }
                     AppErrorResult res = (AppErrorResult) data.get("result");
-                    if (!mSleeping) {
+                    if (!mSleeping && !mShuttingDown) {
                         Dialog d = new AppErrorDialog(
                                 mContext, res, proc,
                                 (Integer)data.get("flags"),
@@ -1053,7 +1062,7 @@
 
             ApplicationInfo info =
                 mSelf.mContext.getPackageManager().getApplicationInfo(
-                        "android", PackageManager.GET_SHARED_LIBRARY_FILES);
+                        "android", STOCK_PM_FLAGS);
             synchronized (mSelf) {
                 ProcessRecord app = mSelf.newProcessRecordLocked(
                         mSystemThread.getApplicationThread(), info,
@@ -1893,7 +1902,7 @@
 
         // If we are not going to sleep, we want to ensure the device is
         // awake until the next activity is started.
-        if (!mSleeping) {
+        if (!mSleeping && !mShuttingDown) {
             mLaunchingActivity.acquire();
             if (!mHandler.hasMessages(LAUNCH_TIMEOUT_MSG)) {
                 // To be safe, don't allow the wake lock to be held for too long.
@@ -1972,12 +1981,15 @@
             mPausingActivity = null;
         }
 
-        if (!mSleeping) {
+        if (!mSleeping && !mShuttingDown) {
             resumeTopActivityLocked(prev);
         } else {
             if (mGoingToSleep.isHeld()) {
                 mGoingToSleep.release();
             }
+            if (mShuttingDown) {
+                notifyAll();
+            }
         }
         
         if (prev != null) {
@@ -2216,7 +2228,7 @@
             }
             ActivityInfo aInfo =
                 intent.resolveActivityInfo(mContext.getPackageManager(),
-                        PackageManager.GET_SHARED_LIBRARY_FILES);
+                        STOCK_PM_FLAGS);
             if (aInfo != null) {
                 intent.setComponent(new ComponentName(
                         aInfo.applicationInfo.packageName, aInfo.name));
@@ -2243,7 +2255,8 @@
 
         // If we are sleeping, and there is no resumed activity, and the top
         // activity is paused, well that is the state we want.
-        if (mSleeping && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
+        if ((mSleeping || mShuttingDown)
+                && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
             // Make sure we have executed any pending transitions, since there
             // should be nothing left to do at this point.
             mWindowManager.executeAppTransition();
@@ -3172,7 +3185,7 @@
                 ActivityThread.getPackageManager().resolveIntent(
                         intent, resolvedType,
                         PackageManager.MATCH_DEFAULT_ONLY
-                        | PackageManager.GET_SHARED_LIBRARY_FILES);
+                        | STOCK_PM_FLAGS);
             aInfo = rInfo != null ? rInfo.activityInfo : null;
         } catch (RemoteException e) {
             aInfo = null;
@@ -3233,8 +3246,7 @@
                 List<ResolveInfo> resolves =
                     ActivityThread.getPackageManager().queryIntentActivities(
                             intent, r.resolvedType,
-                            PackageManager.MATCH_DEFAULT_ONLY
-                            | PackageManager.GET_SHARED_LIBRARY_FILES);
+                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
 
                 // Look for the original activity in the list...
                 final int N = resolves != null ? resolves.size() : 0;
@@ -3316,8 +3328,7 @@
             ResolveInfo rInfo =
                 ActivityThread.getPackageManager().resolveIntent(
                         intent, resolvedType,
-                        PackageManager.MATCH_DEFAULT_ONLY
-                        | PackageManager.GET_SHARED_LIBRARY_FILES);
+                        PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
             aInfo = rInfo != null ? rInfo.activityInfo : null;
         } catch (RemoteException e) {
             aInfo = null;
@@ -4599,7 +4610,8 @@
                     mWaitForDebugger = mOrigWaitForDebugger;
                 }
             }
-            thread.bindApplication(processName, app.info, providers,
+            thread.bindApplication(processName, app.instrumentationInfo != null
+                    ? app.instrumentationInfo : app.info, providers,
                     app.instrumentationClass, app.instrumentationProfileFile,
                     app.instrumentationArguments, app.instrumentationWatcher, testMode, 
                     mConfiguration, getCommonServicesLocked());
@@ -6642,8 +6654,7 @@
         try {
             providers = ActivityThread.getPackageManager().
                 queryContentProviders(app.processName, app.info.uid,
-                        PackageManager.GET_SHARED_LIBRARY_FILES
-                        | PackageManager.GET_URI_PERMISSION_PATTERNS);
+                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
         } catch (RemoteException ex) {
         }
         if (providers != null) {
@@ -6747,7 +6758,8 @@
             } else {
                 try {
                     cpi = ActivityThread.getPackageManager().
-                        resolveContentProvider(name, PackageManager.GET_URI_PERMISSION_PATTERNS);
+                        resolveContentProvider(name,
+                                STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
                 } catch (RemoteException ex) {
                 }
                 if (cpi == null) {
@@ -6768,7 +6780,7 @@
                             ActivityThread.getPackageManager().
                                 getApplicationInfo(
                                         cpi.applicationInfo.packageName,
-                                        PackageManager.GET_SHARED_LIBRARY_FILES);
+                                        STOCK_PM_FLAGS);
                         if (ai == null) {
                             Log.w(TAG, "No package info for content provider "
                                     + cpi.name);
@@ -7098,8 +7110,45 @@
         }
     }
 
+    public boolean shutdown(int timeout) {
+        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Requires permission "
+                    + android.Manifest.permission.SHUTDOWN);
+        }
+        
+        boolean timedout = false;
+        
+        synchronized(this) {
+            mShuttingDown = true;
+            mWindowManager.setEventDispatching(false);
+
+            if (mResumedActivity != null) {
+                pauseIfSleepingLocked();
+                final long endTime = System.currentTimeMillis() + timeout;
+                while (mResumedActivity != null || mPausingActivity != null) {
+                    long delay = endTime - System.currentTimeMillis();
+                    if (delay <= 0) {
+                        Log.w(TAG, "Activity manager shutdown timed out");
+                        timedout = true;
+                        break;
+                    }
+                    try {
+                        this.wait();
+                    } catch (InterruptedException e) {
+                    }
+                }
+            }
+        }
+        
+        mUsageStatsService.shutdown();
+        mBatteryStatsService.shutdown();
+        
+        return timedout;
+    }
+    
     void pauseIfSleepingLocked() {
-        if (mSleeping) {
+        if (mSleeping || mShuttingDown) {
             if (!mGoingToSleep.isHeld()) {
                 mGoingToSleep.acquire();
                 if (mLaunchingActivity.isHeld()) {
@@ -7467,7 +7516,7 @@
             if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
                 ResolveInfo ri = mContext.getPackageManager()
                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
-                                0);
+                                STOCK_PM_FLAGS);
                 CharSequence errorMsg = null;
                 if (ri != null) {
                     ActivityInfo ai = ri.activityInfo;
@@ -7503,7 +7552,7 @@
             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
                 try {
                     List apps = ActivityThread.getPackageManager().
-                        getPersistentApplications(PackageManager.GET_SHARED_LIBRARY_FILES);
+                        getPersistentApplications(STOCK_PM_FLAGS);
                     if (apps != null) {
                         int N = apps.size();
                         int i;
@@ -8064,7 +8113,7 @@
                     + " mBooting=" + mBooting
                     + " mBooted=" + mBooted
                     + " mFactoryTest=" + mFactoryTest);
-            pw.println("  mSleeping=" + mSleeping);
+            pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
             pw.println("  mGoingToSleep=" + mGoingToSleep);
             pw.println("  mLaunchingActivity=" + mLaunchingActivity);
             pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
@@ -8918,7 +8967,7 @@
             try {
                 ResolveInfo rInfo =
                     ActivityThread.getPackageManager().resolveService(
-                            service, resolvedType, PackageManager.GET_SHARED_LIBRARY_FILES);
+                            service, resolvedType, STOCK_PM_FLAGS);
                 ServiceInfo sInfo =
                     rInfo != null ? rInfo.serviceInfo : null;
                 if (sInfo == null) {
@@ -10136,7 +10185,7 @@
             if (intent.getComponent() != null) {
                 // Broadcast is going to one specific receiver class...
                 ActivityInfo ai = ActivityThread.getPackageManager().
-                    getReceiverInfo(intent.getComponent(), 0);
+                    getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
                 if (ai != null) {
                     receivers = new ArrayList();
                     ResolveInfo ri = new ResolveInfo();
@@ -10149,7 +10198,7 @@
                          == 0) {
                     receivers =
                         ActivityThread.getPackageManager().queryIntentReceivers(
-                                intent, resolvedType, PackageManager.GET_SHARED_LIBRARY_FILES);
+                                intent, resolvedType, STOCK_PM_FLAGS);
                 }
                 registeredReceivers = mReceiverResolver.queryIntent(resolver,
                         intent, resolvedType, false);
@@ -10886,9 +10935,9 @@
             ApplicationInfo ai = null;
             try {
                 ii = mContext.getPackageManager().getInstrumentationInfo(
-                    className, 0);
+                    className, STOCK_PM_FLAGS);
                 ai = mContext.getPackageManager().getApplicationInfo(
-                    ii.targetPackage, PackageManager.GET_SHARED_LIBRARY_FILES);
+                    ii.targetPackage, STOCK_PM_FLAGS);
             } catch (PackageManager.NameNotFoundException e) {
             }
             if (ii == null) {
@@ -10920,6 +10969,7 @@
             uninstallPackageLocked(ii.targetPackage, -1, true);
             ProcessRecord app = addAppLocked(ai);
             app.instrumentationClass = className;
+            app.instrumentationInfo = ai;
             app.instrumentationProfileFile = profileFile;
             app.instrumentationArguments = arguments;
             app.instrumentationWatcher = watcher;
@@ -10967,6 +11017,7 @@
         }
         app.instrumentationWatcher = null;
         app.instrumentationClass = null;
+        app.instrumentationInfo = null;
         app.instrumentationProfileFile = null;
         app.instrumentationArguments = null;
 
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index ddc3e68..a21893b 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -25,8 +25,7 @@
 import android.os.Parcel;
 import android.os.Process;
 import android.os.ServiceManager;
-import android.telephony.TelephonyManager;
-import android.util.PrintWriterPrinter;
+import android.util.Log;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -50,6 +49,13 @@
         ServiceManager.addService("batteryinfo", asBinder());
     }
     
+    public void shutdown() {
+        Log.w("BatteryStats", "Writing battery stats before shutdown...");
+        synchronized (mStats) {
+            mStats.writeLocked();
+        }
+    }
+    
     public static IBatteryStats getService() {
         if (sService != null) {
             return sService;
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index b76547a..68aebc3 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -28,6 +28,7 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.util.PrintWriterPrinter;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -62,6 +63,7 @@
     IBinder forcingToForeground;// Token that is forcing this process to be foreground
     int adjSeq;                 // Sequence id for identifying repeated trav
     ComponentName instrumentationClass;// class installed to instrument app
+    ApplicationInfo instrumentationInfo; // the application being instrumented
     String instrumentationProfileFile; // where to save profiling
     IInstrumentationWatcher instrumentationWatcher; // who is waiting
     Bundle instrumentationArguments;// as given to us
@@ -125,6 +127,11 @@
                     pw.println(instrumentationProfileFile);
             pw.print(prefix); pw.print("instrumentationArguments=");
                     pw.println(instrumentationArguments);
+            pw.print(prefix); pw.print("instrumentationInfo=");
+                    pw.println(instrumentationInfo);
+            if (instrumentationInfo != null) {
+                instrumentationInfo.dump(new PrintWriterPrinter(pw), prefix + "  ");
+            }
         }
         pw.print(prefix); pw.print("thread="); pw.print(thread);
                 pw.print(" curReceiver="); pw.println(curReceiver);
diff --git a/services/java/com/android/server/am/UsageStatsService.java b/services/java/com/android/server/am/UsageStatsService.java
index b6f9158..866334b 100755
--- a/services/java/com/android/server/am/UsageStatsService.java
+++ b/services/java/com/android/server/am/UsageStatsService.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import com.android.internal.app.IUsageStats;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.Binder;
@@ -418,6 +419,11 @@
         ServiceManager.addService(SERVICE_NAME, asBinder());
     }
     
+    public void shutdown() {
+        Log.w(TAG, "Writing usage stats before shutdown...");
+        writeStatsToFile(true);
+    }
+    
     public static IUsageStats getService() {
         if (sService != null) {
             return sService;
diff --git a/tests/CoreTests/android/core/SocketTest.java b/tests/CoreTests/android/core/SocketTest.java
index b64c156..9db6077 100644
--- a/tests/CoreTests/android/core/SocketTest.java
+++ b/tests/CoreTests/android/core/SocketTest.java
@@ -178,29 +178,35 @@
         SocketChannel.open();
     }
 
-    // Regression test for issue 1018016, connecting ignored a set timeout.
-    @LargeTest
-    public void testSocketSetSOTimeout() throws IOException {
-        Socket sock = new Socket();
-        int timeout = 5000;
-        long start = System.currentTimeMillis();
-        try {
-            sock.connect(new InetSocketAddress(NON_EXISTING_ADDRESS, 80), timeout);
-        } catch (SocketTimeoutException e) {
-            // expected
-            long delay = System.currentTimeMillis() - start;
-            if (Math.abs(delay - timeout) > 1000) {
-                fail("timeout was not accurate. expected: " + timeout
-                        + " actual: " + delay + " miliseconds.");
-            }
-        } finally {
-            try {
-                sock.close();
-            } catch (IOException ioe) {
-                // ignore
-            }
-        }
-    }
+// Regression test for issue 1018016, connecting ignored a set timeout.
+//
+// Disabled because test behaves differently depending on networking
+// environment. It works fine in the emulator and one the device with
+// WLAN, but when 3G comes into play, the possible existence of a
+// proxy makes it fail.
+//
+//    @LargeTest
+//    public void testSocketSetSOTimeout() throws IOException {
+//        Socket sock = new Socket();
+//        int timeout = 5000;
+//        long start = System.currentTimeMillis();
+//        try {
+//            sock.connect(new InetSocketAddress(NON_EXISTING_ADDRESS, 80), timeout);
+//        } catch (SocketTimeoutException e) {
+//            // expected
+//            long delay = System.currentTimeMillis() - start;
+//            if (Math.abs(delay - timeout) > 1000) {
+//                fail("timeout was not accurate. expected: " + timeout
+//                        + " actual: " + delay + " miliseconds.");
+//            }
+//        } finally {
+//            try {
+//                sock.close();
+//            } catch (IOException ioe) {
+//                // ignore
+//            }
+//        }
+//    }
     
     /**
      * Regression test for 1062928: Dotted IP addresses (e.g., 192.168.100.1)