Merge "Fix bug 2835056 - ActionBar doesn't update title properly when set in onCreate"
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 20272df..a1cf233 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1567,6 +1567,12 @@
         return new BackStackEntry(mFragments);
     }
     
+    void invalidateFragmentIndex(int index) {
+        if (mAllLoaderManagers != null) {
+            mAllLoaderManagers.remove(index);
+        }
+    }
+    
     /**
      * Called when a Fragment is being attached to this activity, immediately
      * after the call to its {@link Fragment#onAttach Fragment.onAttach()}
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 50307d4..4f3043c 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -316,7 +316,6 @@
                             throw new SuperNotCalledException("Fragment " + f
                                     + " did not call through to super.onDetach()");
                         }
-                        f.mActivity.mAllLoaderManagers.remove(f.mIndex);
                         f.mActivity = null;
                     }
             }
@@ -377,6 +376,7 @@
             mAvailIndices = new ArrayList<Integer>();
         }
         mAvailIndices.add(f.mIndex);
+        mActivity.invalidateFragmentIndex(f.mIndex);
         f.clearIndex();
     }
     
diff --git a/core/java/android/net/DownloadManager.java b/core/java/android/net/DownloadManager.java
index b2a214c..02b6210 100644
--- a/core/java/android/net/DownloadManager.java
+++ b/core/java/android/net/DownloadManager.java
@@ -24,6 +24,7 @@
 import android.provider.Downloads;
 import android.util.Log;
 
+import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -112,10 +113,10 @@
     public final static String COLUMN_BYTES_DOWNLOADED_SO_FAR = "bytes_so_far";
 
     /**
-     * Timestamp when the download was requested, in {@link System#currentTimeMillis
+     * Timestamp when the download was last modified, in {@link System#currentTimeMillis
      * System.currentTimeMillis()} (wall clock time in UTC).
      */
-    public final static String COLUMN_REQUESTED_TIMESTAMP = "requested_timestamp";
+    public final static String COLUMN_LAST_MODIFIED_TIMESTAMP = "last_modified_timestamp";
 
 
     /**
@@ -199,7 +200,7 @@
         COLUMN_STATUS,
         COLUMN_ERROR_CODE,
         COLUMN_BYTES_DOWNLOADED_SO_FAR,
-        COLUMN_REQUESTED_TIMESTAMP
+        COLUMN_LAST_MODIFIED_TIMESTAMP
     };
 
     // columns to request from DownloadProvider
@@ -212,12 +213,13 @@
         Downloads.COLUMN_TOTAL_BYTES,
         Downloads._DATA,
         Downloads.COLUMN_STATUS,
-        Downloads.COLUMN_CURRENT_BYTES
+        Downloads.COLUMN_CURRENT_BYTES,
+        Downloads.COLUMN_LAST_MODIFICATION,
     };
 
     private static final Set<String> LONG_COLUMNS = new HashSet<String>(
             Arrays.asList(COLUMN_ID, COLUMN_TOTAL_SIZE_BYTES, COLUMN_STATUS, COLUMN_ERROR_CODE,
-                          COLUMN_BYTES_DOWNLOADED_SO_FAR, COLUMN_REQUESTED_TIMESTAMP));
+                          COLUMN_BYTES_DOWNLOADED_SO_FAR, COLUMN_LAST_MODIFIED_TIMESTAMP));
 
     /**
      * This class contains all the information necessary to request a new download.  The URI is the
@@ -340,8 +342,8 @@
             values.put(Downloads.COLUMN_URI, mUri.toString());
 
             if (mDestinationUri != null) {
-                // TODO destination support
-                throw new UnsupportedOperationException();
+                values.put(Downloads.COLUMN_DESTINATION, Downloads.Impl.DESTINATION_FILE_URI);
+                values.put(Downloads.COLUMN_FILE_NAME_HINT, mDestinationUri.toString());
             } else {
                 values.put(Downloads.COLUMN_DESTINATION,
                            Downloads.DESTINATION_CACHE_PARTITION_PURGEABLE);
@@ -433,8 +435,8 @@
                 selection = joinStrings(" OR ", parts);
                 Log.w("DownloadManagerPublic", selection);
             }
-            // TODO: ordering
-            return resolver.query(uri, projection, selection, null, null);
+            String orderBy = Downloads.COLUMN_LAST_MODIFICATION + " DESC";
+            return resolver.query(uri, projection, selection, null, orderBy);
         }
 
         private String joinStrings(String joiner, Iterable<String> parts) {
@@ -625,7 +627,7 @@
                 return getUnderlyingString(Downloads.COLUMN_MIME_TYPE);
             }
             assert column.equals(COLUMN_LOCAL_URI);
-            return Uri.fromParts("file", getUnderlyingString(Downloads._DATA), null).toString();
+            return Uri.fromFile(new File(getUnderlyingString(Downloads._DATA))).toString();
         }
 
         private long translateLong(String column) {
@@ -649,8 +651,8 @@
             if (column.equals(COLUMN_BYTES_DOWNLOADED_SO_FAR)) {
                 return getUnderlyingLong(Downloads.COLUMN_CURRENT_BYTES);
             }
-            assert column.equals(COLUMN_REQUESTED_TIMESTAMP);
-            throw new UnsupportedOperationException(); // TODO
+            assert column.equals(COLUMN_LAST_MODIFIED_TIMESTAMP);
+            return getUnderlyingLong(Downloads.COLUMN_LAST_MODIFICATION);
         }
 
         private long translateErrorCode(int status) {
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index 348e9e8..1a4f8c0 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -899,6 +899,12 @@
         public static final int DESTINATION_CACHE_PARTITION_NOROAMING = 3;
 
         /**
+         * This download will be saved to the location given by the file URI in
+         * {@link #COLUMN_FILE_NAME_HINT}.
+         */
+        public static final int DESTINATION_FILE_URI = 4;
+
+        /**
          * This download is allowed to run.
          */
         public static final int CONTROL_RUN = 0;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index e051fbd..70c1e15 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -4287,7 +4287,7 @@
                     final ArrayList<View> scrap = mScrapViews[i];
                     final int scrapCount = scrap.size();
                     for (int j = 0; j < scrapCount; j++) {
-                        scrap.get(i).setDrawingCacheBackgroundColor(color);
+                        scrap.get(j).setDrawingCacheBackgroundColor(color);
                     }
                 }
             }
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 6cf455c..c6be7c2 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -70,6 +70,8 @@
     
     private int mContextDisplayMode;
 
+    private boolean mClosingContext;
+
     final Handler mHandler = new Handler();
     final Runnable mCloseContext = new Runnable() {
         public void run() {
@@ -77,6 +79,7 @@
             if (mLowerContextView != null) {
                 mLowerContextView.removeAllViews();
             }
+            mClosingContext = false;
         }
     };
 
@@ -195,6 +198,14 @@
         if (mContextMode != null) {
             mContextMode.finish();
         }
+
+        // Don't wait for the close context mode animation to finish.
+        if (mClosingContext) {
+            mAnimatorView.clearAnimation();
+            mHandler.removeCallbacks(mCloseContext);
+            mCloseContext.run();
+        }
+
         mContextMode = new ContextMode(callback);
         if (callback.onCreateContextMode(mContextMode, mContextMode.getMenu())) {
             mContextMode.invalidate();
@@ -344,6 +355,7 @@
             mAnimatorView.setDisplayedChild(NORMAL_VIEW);
 
             // Clear out the context mode views after the animation finishes
+            mClosingContext = true;
             mHandler.postDelayed(mCloseContext, mAnimatorView.getOutAnimation().getDuration());
 
             if (mLowerContextView != null && mLowerContextView.getVisibility() != View.GONE) {
diff --git a/include/media/EffectEqualizerApi.h b/include/media/EffectEqualizerApi.h
index e3069d5..cb05b32 100644
--- a/include/media/EffectEqualizerApi.h
+++ b/include/media/EffectEqualizerApi.h
@@ -19,14 +19,13 @@
 
 #include <media/EffectApi.h>
 
+// for the definition of SL_IID_EQUALIZER
+#include "OpenSLES.h"
+
 #if __cplusplus
 extern "C" {
 #endif
 
-//TODO replace by openSL ES include when available
-static const effect_uuid_t SL_IID_EQUALIZER_ = { 0x0bed4300, 0xddd6, 0x11db, 0x8f34, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
-const effect_uuid_t * const SL_IID_EQUALIZER = &SL_IID_EQUALIZER_;
-
 /* enumerated parameters for Equalizer effect */
 typedef enum
 {
diff --git a/media/java/android/media/MtpDatabase.java b/media/java/android/media/MtpDatabase.java
index 758999e..2b311f5 100644
--- a/media/java/android/media/MtpDatabase.java
+++ b/media/java/android/media/MtpDatabase.java
@@ -36,6 +36,9 @@
     private final String mVolumeName;
     private final Uri mObjectsUri;
 
+    // FIXME - this should be passed in via the constructor
+    private final int mStorageID = 0x00010001;
+
     private static final String[] ID_PROJECTION = new String[] {
             MtpObjects.ObjectColumns._ID, // 0
     };
@@ -60,6 +63,20 @@
 
     private final MediaScanner mMediaScanner;
 
+    // MTP property codes
+    private static final int MTP_PROPERTY_STORAGE_ID = 0xDC01;
+    private static final int MTP_PROPERTY_OBJECT_FORMAT = 0xDC02;
+    private static final int MTP_PROPERTY_OBJECT_SIZE = 0xDC04;
+    private static final int MTP_PROPERTY_OBJECT_FILE_NAME = 0xDC07;
+    private static final int MTP_PROPERTY_DATE_MODIFIED = 0xDC09;
+    private static final int MTP_PROPERTY_PARENT_OBJECT = 0xDC0B;
+
+    // MTP response codes
+    private static final int MTP_RESPONSE_OK = 0x2001;
+    private static final int MTP_RESPONSE_GENERAL_ERROR = 0x2002;
+    private static final int MTP_RESPONSE_INVALID_OBJECT_HANDLE = 0x2009;
+    private static final int MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED = 0xA80A;
+
     static {
         System.loadLibrary("media_jni");
     }
@@ -150,7 +167,71 @@
     private int getObjectProperty(int handle, int property,
                             long[] outIntValue, char[] outStringValue) {
         Log.d(TAG, "getObjectProperty: " + property);
-        return 0;
+        String column = null;
+        boolean isString = false;
+
+        switch (property) {
+            case MTP_PROPERTY_STORAGE_ID:
+                outIntValue[0] = mStorageID;
+                return MTP_RESPONSE_OK;
+            case MTP_PROPERTY_OBJECT_FORMAT:
+                column = MtpObjects.ObjectColumns.FORMAT;
+                break;
+            case MTP_PROPERTY_OBJECT_SIZE:
+                column = MtpObjects.ObjectColumns.SIZE;
+                break;
+            case MTP_PROPERTY_OBJECT_FILE_NAME:
+                column = MtpObjects.ObjectColumns.DATA;
+                isString = true;
+                break;
+            case MTP_PROPERTY_DATE_MODIFIED:
+                column = MtpObjects.ObjectColumns.DATE_MODIFIED;
+                break;
+            case MTP_PROPERTY_PARENT_OBJECT:
+                column = MtpObjects.ObjectColumns.PARENT;
+                break;
+            default:
+                return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
+        }
+
+        Cursor c = null;
+        try {
+            // for now we are only reading properties from the "objects" table
+            c = mMediaProvider.query(mObjectsUri,
+                            new String [] { MtpObjects.ObjectColumns._ID, column },
+                            ID_WHERE, new String[] { Integer.toString(handle) }, null);
+            if (c != null && c.moveToNext()) {
+                if (isString) {
+                    String value = c.getString(1);
+                    int start = 0;
+
+                    if (property == MTP_PROPERTY_OBJECT_FILE_NAME) {
+                        // extract name from full path
+                        int lastSlash = value.lastIndexOf('/');
+                        if (lastSlash >= 0) {
+                            start = lastSlash + 1;
+                        }
+                    }
+                    int end = value.length();
+                    if (end - start > 255) {
+                        end = start + 255;
+                    }
+                    value.getChars(start, end, outStringValue, 0);
+                    outStringValue[end - start] = 0;
+                } else {
+                    outIntValue[0] = c.getLong(1);
+                }
+                return MTP_RESPONSE_OK;
+            }
+        } catch (Exception e) {
+            return MTP_RESPONSE_GENERAL_ERROR;
+        } finally {
+            if (c != null) {
+                c.close();
+            }
+        }
+        // query failed if we get here
+        return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
     }
 
     private boolean getObjectInfo(int handle, int[] outStorageFormatParent,
@@ -161,7 +242,7 @@
             c = mMediaProvider.query(mObjectsUri, OBJECT_INFO_PROJECTION,
                             ID_WHERE, new String[] {  Integer.toString(handle) }, null);
             if (c != null && c.moveToNext()) {
-                outStorageFormatParent[0] = 0x00010001;
+                outStorageFormatParent[0] = mStorageID;
                 outStorageFormatParent[1] = c.getInt(2);
                 outStorageFormatParent[2] = c.getInt(3);
 
diff --git a/media/libeffects/Android.mk b/media/libeffects/Android.mk
index 54e87f3..fc4ceb6 100644
--- a/media/libeffects/Android.mk
+++ b/media/libeffects/Android.mk
@@ -87,7 +87,8 @@
 endif
 
 LOCAL_C_INCLUDES := \
-	$(call include-path-for, graphics corecg)
+	$(call include-path-for, graphics corecg) \
+	system/media/opensles/include
 
 LOCAL_PRELINK_MODULE := false
 
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 487372e..278e1ba 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -932,6 +932,8 @@
         // TP-Message-Type-Indicator
         // 9.2.3
         case 0:
+        case 3: //GSM 03.40 9.2.3.1: MTI == 3 is Reserved.
+                //This should be processed in the same way as MTI == 0 (Deliver)
             parseSmsDeliver(p, firstByte);
             break;
         case 2:
diff --git a/tests/HwAccelerationTest/src/com/google/android/test/hwui/MultisamplingActivity.java b/tests/HwAccelerationTest/src/com/google/android/test/hwui/MultisamplingActivity.java
new file mode 100644
index 0000000..95b14aa
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/google/android/test/hwui/MultisamplingActivity.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2010 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.google.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.widget.FrameLayout;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class MultisamplingActivity extends Activity {
+    private static final String LOG_TAG = "HwUi";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        DirtyBitmapView container = new DirtyBitmapView(this);
+
+        ColorView color = new ColorView(this);
+        container.addView(color, new DirtyBitmapView.LayoutParams(
+                dipToPx(this, 100), dipToPx(this, 100), Gravity.CENTER));
+
+        AlphaAnimation a = new AlphaAnimation(1.0f, 0.0f);
+        a.setDuration(2000);
+        a.setRepeatCount(Animation.INFINITE);
+        a.setRepeatMode(Animation.REVERSE);
+        color.startAnimation(a);
+
+        setContentView(container);
+    }
+    
+    @SuppressWarnings({"UnusedDeclaration"})
+    static int dipToPx(Context c, int dip) {
+        return (int) (c.getResources().getDisplayMetrics().density * dip + 0.5f);
+    }
+
+    static class ColorView extends View {
+        ColorView(Context c) {
+            super(c);
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            super.onDraw(canvas);
+            canvas.drawRGB(0, 255, 0);
+        }
+    }
+
+    static class DirtyBitmapView extends FrameLayout {
+        private final Paint mPaint;
+
+        DirtyBitmapView(Context c) {
+            super(c);
+            mPaint = new Paint();
+        }
+
+        @Override
+        public void dispatchDraw(Canvas canvas) {
+            canvas.drawRGB(255, 255, 255);
+
+            mPaint.setColor(0xffff0000);
+            canvas.drawRect(200.0f, 0.0f, 220.0f, 20.0f, mPaint);
+
+            canvas.save();
+            canvas.clipRect(20.0f, 0.0f, 40.0f, 20.0f);
+            Log.d(LOG_TAG, "clipRect = " + canvas.getClipBounds());
+            Log.d(LOG_TAG, "rejected = " + canvas.quickReject(100.0f, 100.0f, 110.0f, 110.0f,
+                    Canvas.EdgeType.BW));
+            Log.d(LOG_TAG, "rejected = " + canvas.quickReject(25.0f, 5.0f, 30.0f, 10.0f,
+                    Canvas.EdgeType.BW));
+            canvas.restore();
+            
+            canvas.save();
+            canvas.scale(2.0f, 2.0f);
+            canvas.clipRect(20.0f, 0.0f, 40.0f, 20.0f);
+            Log.d(LOG_TAG, "clipRect = " + canvas.getClipBounds());
+            Log.d(LOG_TAG, "rejected = " + canvas.quickReject(50.0f, 50.0f, 60.0f, 60.0f,
+                    Canvas.EdgeType.BW));
+            Log.d(LOG_TAG, "rejected = " + canvas.quickReject(25.0f, 5.0f, 30.0f, 10.0f,
+                    Canvas.EdgeType.BW));
+            canvas.restore();
+
+            canvas.save();
+            canvas.translate(20.0f, 20.0f);
+            canvas.clipRect(20.0f, 0.0f, 40.0f, 20.0f);
+            Log.d(LOG_TAG, "clipRect = " + canvas.getClipBounds());
+            Log.d(LOG_TAG, "rejected = " + canvas.quickReject(80.0f, 80.0f, 90.0f, 90.0f,
+                    Canvas.EdgeType.BW));
+            Log.d(LOG_TAG, "rejected = " + canvas.quickReject(25.0f, 5.0f, 30.0f, 10.0f,
+                    Canvas.EdgeType.BW));
+            canvas.restore();
+
+            canvas.save();
+            canvas.scale(2.0f, 2.0f);            
+            canvas.clipRect(20.0f, 0.0f, 40.0f, 20.0f);
+
+            mPaint.setColor(0xff00ff00);
+            canvas.drawRect(0.0f, 0.0f, 20.0f, 20.0f, mPaint);
+            
+            mPaint.setColor(0xff0000ff);
+            canvas.drawRect(20.0f, 0.0f, 40.0f, 20.0f, mPaint);
+            
+            canvas.restore();
+
+            final int restoreTo = canvas.save();
+            canvas.saveLayerAlpha(0.0f, 100.0f, getWidth(), 150.0f, 127,
+                    Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
+            mPaint.setColor(0xff0000ff);
+            canvas.drawRect(0.0f, 100.0f, 40.0f, 150.0f, mPaint);
+            mPaint.setColor(0xff00ffff);
+            canvas.drawRect(40.0f, 100.0f, 140.0f, 150.0f, mPaint);
+            mPaint.setColor(0xffff00ff);
+            canvas.drawRect(140.0f, 100.0f, 240.0f, 150.0f, mPaint);
+            canvas.restoreToCount(restoreTo);
+
+            super.dispatchDraw(canvas);
+        }
+    }
+}
\ No newline at end of file