Merge change 20683
* changes:
Add operator name in network selection.
diff --git a/api/current.xml b/api/current.xml
index cc7dc23..69d4d5c 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -26920,6 +26920,23 @@
<exception name="IOException" type="java.io.IOException">
</exception>
</method>
+<method name="setWallpaperOffsets"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="windowToken" type="android.os.IBinder">
+</parameter>
+<parameter name="xOffset" type="float">
+</parameter>
+<parameter name="yOffset" type="float">
+</parameter>
+</method>
<method name="suggestDesiredDimensions"
return="void"
abstract="false"
@@ -29268,7 +29285,7 @@
visibility="public"
>
</method>
-<method name="newCountQuery"
+<method name="newAssertQuery"
return="android.content.ContentProviderOperation.Builder"
abstract="false"
native="false"
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 9019b54..78b6cf1 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -28,6 +28,7 @@
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.view.ViewRoot;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -312,6 +313,28 @@
}
/**
+ * Set the position of the current wallpaper within any larger space, when
+ * that wallpaper is visible behind the given window. The X and Y offsets
+ * are floating point numbers ranging from 0 to 1, representing where the
+ * wallpaper should be positioned within the screen space. These only
+ * make sense when the wallpaper is larger than the screen.
+ *
+ * @param windowToken The window who these offsets should be associated
+ * with, as returned by {@link android.view.View#getWindowVisibility()
+ * View.getWindowToken()}.
+ * @param xOffset The offset olong the X dimension, from 0 to 1.
+ * @param yOffset The offset along the Y dimension, from 0 to 1.
+ */
+ public void setWallpaperOffsets(IBinder windowToken, float xOffset, float yOffset) {
+ try {
+ ViewRoot.getWindowSession(mContext.getMainLooper()).setWallpaperPosition(
+ windowToken, xOffset, yOffset);
+ } catch (RemoteException e) {
+ // Ignore.
+ }
+ }
+
+ /**
* Remove any currently set wallpaper, reverting to the system's default
* wallpaper. On success, the intent {@link Intent#ACTION_WALLPAPER_CHANGED}
* is broadcast.
diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java
index 70ea5d0..f5a4b75 100644
--- a/core/java/android/content/ContentProviderOperation.java
+++ b/core/java/android/content/ContentProviderOperation.java
@@ -16,14 +16,15 @@
package android.content;
-import android.net.Uri;
import android.database.Cursor;
-import android.os.Parcelable;
+import android.net.Uri;
import android.os.Parcel;
-import android.os.Debug;
+import android.os.Parcelable;
+import android.text.TextUtils;
-import java.util.Map;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Map;
public class ContentProviderOperation implements Parcelable {
/** @hide exposed for unit tests */
@@ -33,7 +34,7 @@
/** @hide exposed for unit tests */
public final static int TYPE_DELETE = 3;
/** @hide exposed for unit tests */
- public final static int TYPE_COUNT = 4;
+ public final static int TYPE_ASSERT = 4;
private final int mType;
private final Uri mUri;
@@ -44,8 +45,6 @@
private final ContentValues mValuesBackReferences;
private final Map<Integer, Integer> mSelectionArgsBackReferences;
- private static final String[] COUNT_COLUMNS = new String[]{"count(*)"};
-
/**
* Creates a {@link ContentProviderOperation} by copying the contents of a
* {@link Builder}.
@@ -156,15 +155,12 @@
}
/**
- * Create a {@link Builder} suitable for building a count query. When used in conjunction
- * with {@link Builder#withExpectedCount(int)} this is useful for checking that the
- * uri/selection has the expected number of rows.
- * {@link ContentProviderOperation}.
- * @param uri The {@link Uri} to query.
- * @return a {@link Builder}
+ * Create a {@link Builder} suitable for building a
+ * {@link ContentProviderOperation} to assert a set of values as provided
+ * through {@link Builder#withValues(ContentValues)}.
*/
- public static Builder newCountQuery(Uri uri) {
- return new Builder(TYPE_COUNT, uri);
+ public static Builder newAssertQuery(Uri uri) {
+ return new Builder(TYPE_ASSERT, uri);
}
public Uri getUri() {
@@ -181,7 +177,7 @@
}
public boolean isReadOperation() {
- return mType == TYPE_COUNT;
+ return mType == TYPE_ASSERT;
}
/**
@@ -217,18 +213,30 @@
numRows = provider.delete(mUri, mSelection, selectionArgs);
} else if (mType == TYPE_UPDATE) {
numRows = provider.update(mUri, values, mSelection, selectionArgs);
- } else if (mType == TYPE_COUNT) {
- Cursor cursor = provider.query(mUri, COUNT_COLUMNS, mSelection, selectionArgs, null);
+ } else if (mType == TYPE_ASSERT) {
+ // Build projection map from expected values
+ final ArrayList<String> projectionList = new ArrayList<String>();
+ for (Map.Entry<String, Object> entry : values.valueSet()) {
+ projectionList.add(entry.getKey());
+ }
+
+ // Assert that all rows match expected values
+ final String[] projection = projectionList.toArray(new String[projectionList.size()]);
+ final Cursor cursor = provider.query(mUri, projection, mSelection, selectionArgs, null);
+ numRows = cursor.getCount();
try {
- if (!cursor.moveToNext()) {
- throw new RuntimeException("since we are doing a count query we should always "
- + "be able to move to the first row");
+ while (cursor.moveToNext()) {
+ for (int i = 0; i < projection.length; i++) {
+ final String cursorValue = cursor.getString(i);
+ final String expectedValue = values.getAsString(projection[i]);
+ if (!TextUtils.equals(cursorValue, expectedValue)) {
+ // Throw exception when expected values don't match
+ throw new OperationApplicationException("Found value " + cursorValue
+ + " when expected " + expectedValue + " for column "
+ + projection[i]);
+ }
+ }
}
- if (cursor.getCount() != 1) {
- throw new RuntimeException("since we are doing a count query there should "
- + "always be exacly row, found " + cursor.getCount());
- }
- numRows = cursor.getInt(0);
} finally {
cursor.close();
}
@@ -353,7 +361,7 @@
* first created by calling {@link ContentProviderOperation#newInsert(android.net.Uri)},
* {@link ContentProviderOperation#newUpdate(android.net.Uri)},
* {@link ContentProviderOperation#newDelete(android.net.Uri)} or
- * {@link ContentProviderOperation#newCountQuery(android.net.Uri)}. The withXXX methods
+ * {@link ContentProviderOperation#newAssertQuery(Uri)}. The withXXX methods
* can then be used to add parameters to the builder. See the specific methods to find for
* which {@link Builder} type each is allowed. Call {@link #build} to create the
* {@link ContentProviderOperation} once all the parameters have been supplied.
@@ -379,7 +387,7 @@
/** Create a ContentProviderOperation from this {@link Builder}. */
public ContentProviderOperation build() {
- if (mType == TYPE_UPDATE) {
+ if (mType == TYPE_UPDATE || mType == TYPE_ASSERT) {
if ((mValues == null || mValues.size() == 0)
&& (mValuesBackReferences == null || mValuesBackReferences.size() == 0)) {
throw new IllegalArgumentException("Empty values");
@@ -394,13 +402,13 @@
* value should be used for the column. The value is added as a {@link String}.
* A column value from the back references takes precedence over a value specified in
* {@link #withValues}.
- * This can only be used with builders of type insert or update.
+ * This can only be used with builders of type insert, update, or assert.
* @return this builder, to allow for chaining.
*/
public Builder withValueBackReferences(ContentValues backReferences) {
- if (mType != TYPE_INSERT && mType != TYPE_UPDATE) {
+ if (mType != TYPE_INSERT && mType != TYPE_UPDATE && mType != TYPE_ASSERT) {
throw new IllegalArgumentException(
- "only inserts and updates can have value back-references");
+ "only inserts, updates, and asserts can have value back-references");
}
mValuesBackReferences = backReferences;
return this;
@@ -410,13 +418,13 @@
* Add a ContentValues back reference.
* A column value from the back references takes precedence over a value specified in
* {@link #withValues}.
- * This can only be used with builders of type insert or update.
+ * This can only be used with builders of type insert, update, or assert.
* @return this builder, to allow for chaining.
*/
public Builder withValueBackReference(String key, int previousResult) {
- if (mType != TYPE_INSERT && mType != TYPE_UPDATE) {
+ if (mType != TYPE_INSERT && mType != TYPE_UPDATE && mType != TYPE_ASSERT) {
throw new IllegalArgumentException(
- "only inserts and updates can have value back-references");
+ "only inserts, updates, and asserts can have value back-references");
}
if (mValuesBackReferences == null) {
mValuesBackReferences = new ContentValues();
@@ -428,13 +436,13 @@
/**
* Add a back references as a selection arg. Any value at that index of the selection arg
* that was specified by {@link #withSelection} will be overwritten.
- * This can only be used with builders of type update, delete, or count query.
+ * This can only be used with builders of type update, delete, or assert.
* @return this builder, to allow for chaining.
*/
public Builder withSelectionBackReference(int selectionArgIndex, int previousResult) {
- if (mType != TYPE_COUNT && mType != TYPE_UPDATE && mType != TYPE_DELETE) {
- throw new IllegalArgumentException(
- "only deletes, updates and counts can have selection back-references");
+ if (mType != TYPE_UPDATE && mType != TYPE_DELETE && mType != TYPE_ASSERT) {
+ throw new IllegalArgumentException("only updates, deletes, and asserts "
+ + "can have selection back-references");
}
if (mSelectionArgsBackReferences == null) {
mSelectionArgsBackReferences = new HashMap<Integer, Integer>();
@@ -447,12 +455,13 @@
* The ContentValues to use. This may be null. These values may be overwritten by
* the corresponding value specified by {@link #withValueBackReference} or by
* future calls to {@link #withValues} or {@link #withValue}.
- * This can only be used with builders of type insert or update.
+ * This can only be used with builders of type insert, update, or assert.
* @return this builder, to allow for chaining.
*/
public Builder withValues(ContentValues values) {
- if (mType != TYPE_INSERT && mType != TYPE_UPDATE) {
- throw new IllegalArgumentException("only inserts and updates can have values");
+ if (mType != TYPE_INSERT && mType != TYPE_UPDATE && mType != TYPE_ASSERT) {
+ throw new IllegalArgumentException(
+ "only inserts, updates, and asserts can have values");
}
if (mValues == null) {
mValues = new ContentValues();
@@ -464,14 +473,14 @@
/**
* A value to insert or update. This value may be overwritten by
* the corresponding value specified by {@link #withValueBackReference}.
- * This can only be used with builders of type insert or update.
+ * This can only be used with builders of type insert, update, or assert.
* @param key the name of this value
* @param value the value itself. the type must be acceptable for insertion by
* {@link ContentValues#put}
* @return this builder, to allow for chaining.
*/
public Builder withValue(String key, Object value) {
- if (mType != TYPE_INSERT && mType != TYPE_UPDATE) {
+ if (mType != TYPE_INSERT && mType != TYPE_UPDATE && mType != TYPE_ASSERT) {
throw new IllegalArgumentException("only inserts and updates can have values");
}
if (mValues == null) {
@@ -508,13 +517,13 @@
* replaced with the corresponding occurence of the selection argument. Any of the
* selection arguments may be overwritten by a selection argument back reference as
* specified by {@link #withSelectionBackReference}.
- * This can only be used with builders of type update, delete, or count query.
+ * This can only be used with builders of type update, delete, or assert.
* @return this builder, to allow for chaining.
*/
public Builder withSelection(String selection, String[] selectionArgs) {
- if (mType != TYPE_DELETE && mType != TYPE_UPDATE && mType != TYPE_COUNT) {
+ if (mType != TYPE_UPDATE && mType != TYPE_DELETE && mType != TYPE_ASSERT) {
throw new IllegalArgumentException(
- "only deletes, updates and counts can have selections");
+ "only updates, deletes, and asserts can have selections");
}
mSelection = selection;
mSelectionArgs = selectionArgs;
@@ -524,13 +533,13 @@
/**
* If set then if the number of rows affected by this operation do not match
* this count {@link OperationApplicationException} will be throw.
- * This can only be used with builders of type update, delete, or count query.
+ * This can only be used with builders of type update, delete, or assert.
* @return this builder, to allow for chaining.
*/
public Builder withExpectedCount(int count) {
- if (mType != TYPE_DELETE && mType != TYPE_UPDATE && mType != TYPE_COUNT) {
+ if (mType != TYPE_UPDATE && mType != TYPE_DELETE && mType != TYPE_ASSERT) {
throw new IllegalArgumentException(
- "only deletes, updates and counts can have expected counts");
+ "only updates, deletes, and asserts can have expected counts");
}
mExpectedCount = count;
return this;
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 8651b4d..066401f 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -573,8 +573,8 @@
public static final String SYNC4 = "data_sync4";
/**
- * An optional update or insert URI parameter that determines if the
- * corresponding raw contact should be marked as dirty. The default
+ * An optional insert, update or delete URI parameter that determines if
+ * the corresponding raw contact should be marked as dirty. The default
* value is true.
*/
public static final String MARK_AS_DIRTY = "mark_as_dirty";
@@ -1453,6 +1453,12 @@
* merely marked as deleted.
*/
public static final String DELETE_PERMANENTLY = "delete_permanently";
+
+ /**
+ * An optional update or insert URI parameter that determines if the
+ * group should be marked as dirty. The default value is true.
+ */
+ public static final String MARK_AS_DIRTY = "mark_as_dirty";
}
/**
diff --git a/core/java/android/provider/DrmStore.java b/core/java/android/provider/DrmStore.java
index db71854..c438ac4 100644
--- a/core/java/android/provider/DrmStore.java
+++ b/core/java/android/provider/DrmStore.java
@@ -35,7 +35,7 @@
/**
* The DRM provider contains forward locked DRM content.
- *
+ *
* @hide
*/
public final class DrmStore
@@ -43,13 +43,13 @@
private static final String TAG = "DrmStore";
public static final String AUTHORITY = "drm";
-
+
/**
* This is in the Manifest class of the drm provider, but that isn't visible
* in the framework.
*/
private static final String ACCESS_DRM_PERMISSION = "android.permission.ACCESS_DRM";
-
+
/**
* Fields for DRM database
*/
@@ -82,18 +82,18 @@
}
public interface Images extends Columns {
-
+
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/images");
}
-
+
public interface Audio extends Columns {
-
+
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/audio");
}
/**
* Utility function for inserting a file into the DRM content provider.
- *
+ *
* @param cr The content resolver to use
* @param file The file to insert
* @param title The title for the content (or null)
@@ -101,12 +101,46 @@
*/
public static final Intent addDrmFile(ContentResolver cr, File file, String title) {
FileInputStream fis = null;
- OutputStream os = null;
Intent result = null;
try {
fis = new FileInputStream(file);
- DrmRawContent content = new DrmRawContent(fis, (int) file.length(),
+ if (title == null) {
+ title = file.getName();
+ int lastDot = title.lastIndexOf('.');
+ if (lastDot > 0) {
+ title = title.substring(0, lastDot);
+ }
+ }
+ result = addDrmFile(cr, fis, title);
+ } catch (Exception e) {
+ Log.e(TAG, "pushing file failed", e);
+ } finally {
+ try {
+ if (fis != null)
+ fis.close();
+ } catch (IOException e) {
+ Log.e(TAG, "IOException in DrmStore.addDrmFile()", e);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Utility function for inserting a file stream into the DRM content provider.
+ *
+ * @param cr The content resolver to use
+ * @param fileStream The FileInputStream to insert
+ * @param title The title for the content (or null)
+ * @return uri to the DRM record or null
+ */
+ public static final Intent addDrmFile(ContentResolver cr, FileInputStream fis, String title) {
+ OutputStream os = null;
+ Intent result = null;
+
+ try {
+ DrmRawContent content = new DrmRawContent(fis, (int) fis.available(),
DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING);
String mimeType = content.getContentType();
@@ -126,14 +160,6 @@
if (contentUri != null) {
ContentValues values = new ContentValues(3);
- // compute title from file name, if it is not specified
- if (title == null) {
- title = file.getName();
- int lastDot = title.lastIndexOf('.');
- if (lastDot > 0) {
- title = title.substring(0, lastDot);
- }
- }
values.put(DrmStore.Columns.TITLE, title);
values.put(DrmStore.Columns.SIZE, size);
values.put(DrmStore.Columns.MIME_TYPE, mimeType);
@@ -162,7 +188,7 @@
if (os != null)
os.close();
} catch (IOException e) {
- Log.e(TAG, "IOException in DrmTest.onCreate()", e);
+ Log.e(TAG, "IOException in DrmStore.addDrmFile()", e);
}
}
@@ -172,7 +198,7 @@
/**
* Utility function to enforce any permissions required to access DRM
* content.
- *
+ *
* @param context A context used for checking calling permission.
*/
public static void enforceAccessDrmPermission(Context context) {
@@ -181,5 +207,5 @@
throw new SecurityException("Requires DRM permission");
}
}
-
+
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7e3f3c2..cf26b1b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2728,7 +2728,14 @@
* Controls how many attempts Gmail will try to upload an uphill operations before it
* abandons the operation. Defaults to 20.
*/
- public static final String GMAIL_NUM_RETRY_UPHILL_OP = "gmail_discard_error_uphill_op";
+ public static final String GMAIL_NUM_RETRY_UPHILL_OP = "gmail_num_retry_uphill_op";
+
+ /**
+ * How much time in seconds Gmail will try to upload an uphill operations before it
+ * abandons the operation. Defaults to 36400 (one day).
+ */
+ public static final String GMAIL_WAIT_TIME_RETRY_UPHILL_OP =
+ "gmail_wait_time_retry_uphill_op";
/**
* Controls if the protocol buffer version of the protocol will use a multipart request for
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 5607d4b..3e6cdc2 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -90,7 +90,6 @@
void exitKeyguardSecurely(IOnKeyguardExitResult callback);
boolean inKeyguardRestrictedInputMode();
-
// These can only be called with the SET_ANIMATON_SCALE permission.
float getAnimationScale(int which);
float[] getAnimationScales();
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 1156856..4d662d2 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -108,4 +108,10 @@
boolean getInTouchMode();
boolean performHapticFeedback(IWindow window, int effectId, boolean always);
+
+ /**
+ * For windows with the wallpaper behind them, and the wallpaper is
+ * larger than the screen, set the offset within the screen.
+ */
+ void setWallpaperPosition(IBinder windowToken, float x, float y);
}
diff --git a/core/java/android/webkit/DateSorter.java b/core/java/android/webkit/DateSorter.java
index 750403b..c46702e 100644
--- a/core/java/android/webkit/DateSorter.java
+++ b/core/java/android/webkit/DateSorter.java
@@ -43,9 +43,6 @@
private static final int NUM_DAYS_AGO = 5;
- Date mDate = new Date();
- Calendar mCal = Calendar.getInstance();
-
/**
* @param context Application context
*/
diff --git a/core/java/android/webkit/Network.java b/core/java/android/webkit/Network.java
index fb60109..0b9e596 100644
--- a/core/java/android/webkit/Network.java
+++ b/core/java/android/webkit/Network.java
@@ -136,7 +136,7 @@
Assert.assertTrue(Thread.currentThread().
getName().equals(WebViewCore.THREAD_NAME));
}
- mSslErrorHandler = new SslErrorHandler(this);
+ mSslErrorHandler = new SslErrorHandler();
mHttpAuthHandler = new HttpAuthHandler(this);
mRequestQueue = new RequestQueue(context);
diff --git a/core/java/android/webkit/SslErrorHandler.java b/core/java/android/webkit/SslErrorHandler.java
index cc1e750..b6cfa0f 100644
--- a/core/java/android/webkit/SslErrorHandler.java
+++ b/core/java/android/webkit/SslErrorHandler.java
@@ -42,11 +42,6 @@
private static final String LOGTAG = "network";
/**
- * Network.
- */
- private Network mNetwork;
-
- /**
* Queue of loaders that experience SSL-related problems.
*/
private LinkedList<LoadListener> mLoaderQueue;
@@ -72,9 +67,7 @@
/**
* Creates a new error handler with an empty loader queue.
*/
- /* package */ SslErrorHandler(Network network) {
- mNetwork = network;
-
+ /* package */ SslErrorHandler() {
mLoaderQueue = new LinkedList<LoadListener>();
mSslPrefTable = new Bundle();
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 3092fa6..cc7a228 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2514,7 +2514,11 @@
@Override
protected void finalize() throws Throwable {
- destroy();
+ try {
+ destroy();
+ } finally {
+ super.finalize();
+ }
}
@Override
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index e4aaf38..eac5d2d 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -52,7 +52,8 @@
/* Widget that is used across system apps for displaying a header banner with contact info */
-public class ContactHeaderWidget extends FrameLayout implements View.OnClickListener {
+public class ContactHeaderWidget extends FrameLayout implements View.OnClickListener,
+ View.OnLongClickListener {
private static final String TAG = "ContactHeaderWidget";
@@ -71,6 +72,13 @@
protected ContentResolver mContentResolver;
+ public interface ContactHeaderListener {
+ public void onPhotoLongClick(View view);
+ public void onDisplayNameLongClick(View view);
+ }
+
+ private ContactHeaderListener mListener;
+
//Projection used for the summary info in the header.
protected static final String[] HEADER_PROJECTION = new String[] {
Contacts.DISPLAY_NAME,
@@ -125,6 +133,8 @@
inflater.inflate(R.layout.contact_header, this);
mDisplayNameView = (TextView) findViewById(R.id.name);
+ mDisplayNameView.setOnLongClickListener(this);
+
mPhoneticNameView = (TextView) findViewById(R.id.phonetic_name);
mStarredView = (CheckBox)findViewById(R.id.star);
@@ -132,6 +142,7 @@
mPhotoView = (ImageView)findViewById(R.id.photo);
mPhotoView.setOnClickListener(this);
+ mPhotoView.setOnLongClickListener(this);
mStatusView = (TextView)findViewById(R.id.status);
@@ -152,6 +163,35 @@
mQueryHandler = new QueryHandler(mContentResolver);
}
+ public void setContactHeaderListener(ContactHeaderListener listener) {
+ mListener = listener;
+ }
+
+ /** {@inheritDoc} */
+ public boolean onLongClick(View v) {
+ switch (v.getId()) {
+ case R.id.photo:
+ performPhotoLongClick();
+ return true;
+ case R.id.name:
+ performDisplayNameLongClick();
+ return true;
+ }
+ return false;
+ }
+
+ private void performPhotoLongClick() {
+ if (mListener != null) {
+ mListener.onPhotoLongClick(mPhotoView);
+ }
+ }
+
+ private void performDisplayNameLongClick() {
+ if (mListener != null) {
+ mListener.onDisplayNameLongClick(mDisplayNameView);
+ }
+ }
+
private class QueryHandler extends AsyncQueryHandler {
public QueryHandler(ContentResolver cr) {
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 2e947d6..77a126c 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1860,9 +1860,7 @@
mSuspended) {
if (!mStandby) {
for (size_t i = 0; i < outputTracks.size(); i++) {
- mLock.unlock();
outputTracks[i]->stop();
- mLock.lock();
}
mStandby = true;
mBytesWritten = 0;
@@ -1903,9 +1901,9 @@
if (!mSuspended) {
for (size_t i = 0; i < outputTracks.size(); i++) {
outputTracks[i]->write(curBuf, mFrameCount);
+ mustSleep = false;
}
mStandby = false;
- mustSleep = false;
mBytesWritten += mixBufferSize;
}
} else {
@@ -1935,11 +1933,14 @@
outputTracks.clear();
}
- if (!mStandby) {
- for (size_t i = 0; i < outputTracks.size(); i++) {
- mLock.unlock();
- outputTracks[i]->stop();
- mLock.lock();
+ { // scope for the mLock
+
+ Mutex::Autolock _l(mLock);
+ if (!mStandby) {
+ LOGV("DuplicatingThread() exiting out of standby");
+ for (size_t i = 0; i < mOutputTracks.size(); i++) {
+ mOutputTracks[i]->destroy();
+ }
}
}
@@ -1957,9 +1958,11 @@
mFormat,
mChannelCount,
frameCount);
- thread->setStreamVolume(AudioSystem::NUM_STREAM_TYPES, 1.0f);
- mOutputTracks.add(outputTrack);
- LOGV("addOutputTrack() track %p, on thread %p", outputTrack, thread);
+ if (outputTrack->cblk() != NULL) {
+ thread->setStreamVolume(AudioSystem::NUM_STREAM_TYPES, 1.0f);
+ mOutputTracks.add(outputTrack);
+ LOGV("addOutputTrack() track %p, on thread %p", outputTrack, thread);
+ }
}
void AudioFlinger::DuplicatingThread::removeOutputTrack(MixerThread *thread)
@@ -1967,6 +1970,7 @@
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mOutputTracks.size(); i++) {
if (mOutputTracks[i]->thread() == (ThreadBase *)thread) {
+ mOutputTracks[i]->destroy();
mOutputTracks.removeAt(i);
return;
}
@@ -2456,20 +2460,23 @@
{
PlaybackThread *playbackThread = (PlaybackThread *)thread.unsafe_get();
- mCblk->out = 1;
- mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
- mCblk->volume[0] = mCblk->volume[1] = 0x1000;
- mOutBuffer.frameCount = 0;
- mWaitTimeMs = (playbackThread->frameCount() * 2 * 1000) / playbackThread->sampleRate();
-
- LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channels %d mBufferEnd %p mWaitTimeMs %d",
- mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channels, mBufferEnd, mWaitTimeMs);
-
+ if (mCblk != NULL) {
+ mCblk->out = 1;
+ mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
+ mCblk->volume[0] = mCblk->volume[1] = 0x1000;
+ mOutBuffer.frameCount = 0;
+ mWaitTimeMs = (playbackThread->frameCount() * 2 * 1000) / playbackThread->sampleRate();
+ playbackThread->mTracks.add(this);
+ LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channels %d mBufferEnd %p mWaitTimeMs %d",
+ mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channels, mBufferEnd, mWaitTimeMs);
+ } else {
+ LOGW("Error creating output track on thread %p", playbackThread);
+ }
}
AudioFlinger::PlaybackThread::OutputTrack::~OutputTrack()
{
- stop();
+ clearBufferQueue();
}
status_t AudioFlinger::PlaybackThread::OutputTrack::start()
@@ -2908,7 +2915,7 @@
if (mReqChannelCount != mActiveTrack->channelCount()) {
mActiveTrack.clear();
} else {
- mActiveTrack->mState == TrackBase::ACTIVE;
+ mActiveTrack->mState = TrackBase::ACTIVE;
}
mStartStopCond.broadcast();
}
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 4ba5977..65c148e 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -245,6 +245,7 @@
virtual status_t start() = 0;
virtual void stop() = 0;
sp<IMemory> getCblk() const;
+ audio_track_cblk_t* cblk() const { return mCblk; }
protected:
friend class ThreadBase;
@@ -260,10 +261,6 @@
virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
- audio_track_cblk_t* cblk() const {
- return mCblk;
- }
-
int format() const {
return mFormat;
}
@@ -528,6 +525,7 @@
private:
friend class AudioFlinger;
+ friend class OutputTrack;
friend class Track;
friend class TrackBase;
friend class MixerThread;
diff --git a/libs/rs/spec.h b/libs/rs/spec.h
index b474dca..ba802f7 100644
--- a/libs/rs/spec.h
+++ b/libs/rs/spec.h
@@ -1,6 +1,9 @@
#ifndef SPEC_H
#define SPEC_H
+#include <string.h>
+#include <stdlib.h>
+
#if __cplusplus
extern "C" {
#endif
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
index 88e76dc..c4a70c8 100644
--- a/libs/surfaceflinger/Android.mk
+++ b/libs/surfaceflinger/Android.mk
@@ -24,6 +24,9 @@
ifeq ($(TARGET_BOARD_PLATFORM), msm7k)
LOCAL_CFLAGS += -DDIM_WITH_TEXTURE
endif
+ifeq ($(TARGET_BOARD_PLATFORM), qsd8k)
+ LOCAL_CFLAGS += -DDIM_WITH_TEXTURE
+endif
# need "-lrt" on Linux simulator to pick up clock_gettime
ifeq ($(TARGET_SIMULATOR),true)
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 3ea64ae..799c349 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -914,7 +914,7 @@
}
}
} else {
- mState == TONE_IDLE;
+ mState = TONE_IDLE;
}
} else {
LOGV("Delayed start\n");
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 69c48d3..641f251 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -1223,6 +1223,9 @@
// what is below it for later.
w = i > 0 ? (WindowState)localmWindows.get(i-1) : null;
+ final int dw = mDisplay.getWidth();
+ final int dh = mDisplay.getHeight();
+
// Start stepping backwards from here, ensuring that our wallpaper windows
// are correctly placed.
int curTokenIndex = mWallpaperTokens.size();
@@ -1247,6 +1250,10 @@
}
}
+ if (visible) {
+ updateWallpaperOffsetLocked(mWallpaperTarget, wallpaper, dw, dh);
+ }
+
wallpaper.mAnimLayer = wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
if (DEBUG_LAYERS) Log.v(TAG, "Wallpaper win " + wallpaper
+ " anim layer: " + wallpaper.mAnimLayer);
@@ -1279,7 +1286,7 @@
return changed;
}
- void setWallpaperAnimLayerAdjustment(int adj) {
+ void setWallpaperAnimLayerAdjustmentLocked(int adj) {
if (DEBUG_LAYERS) Log.v(TAG, "Setting wallpaper layer adj to " + adj);
mWallpaperAnimLayerAdjustment = adj;
int curTokenIndex = mWallpaperTokens.size();
@@ -1297,6 +1304,50 @@
}
}
+ boolean updateWallpaperOffsetLocked(WindowState target,
+ WindowState wallpaperWin, int dw, int dh) {
+ int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
+ int offset = availw > 0 ? -(int)(availw*target.mWallpaperX+.5f) : 0;
+ boolean changed = wallpaperWin.mXOffset != offset;
+ if (changed) {
+ wallpaperWin.mXOffset = offset;
+ }
+ int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
+ offset = availh > 0 ? -(int)(availh*target.mWallpaperY+.5f) : 0;
+ if (wallpaperWin.mYOffset != offset) {
+ changed = true;
+ wallpaperWin.mYOffset = offset;
+ }
+ return changed;
+ }
+
+ boolean updateWallpaperOffsetLocked() {
+ final int dw = mDisplay.getWidth();
+ final int dh = mDisplay.getHeight();
+
+ boolean changed = false;
+
+ WindowState target = mWallpaperTarget;
+ if (target != null) {
+ int curTokenIndex = mWallpaperTokens.size();
+ while (curTokenIndex > 0) {
+ curTokenIndex--;
+ WindowToken token = mWallpaperTokens.get(curTokenIndex);
+ int curWallpaperIndex = token.windows.size();
+ while (curWallpaperIndex > 0) {
+ curWallpaperIndex--;
+ WindowState wallpaper = token.windows.get(curWallpaperIndex);
+ if (updateWallpaperOffsetLocked(target, wallpaper, dw, dh)) {
+ wallpaper.computeShownFrameLocked();
+ changed = true;
+ }
+ }
+ }
+ }
+
+ return changed;
+ }
+
public int addWindow(Session session, IWindow client,
WindowManager.LayoutParams attrs, int viewVisibility,
Rect outContentInsets) {
@@ -1710,6 +1761,19 @@
}
}
+ public void setWindowWallpaperPositionLocked(WindowState window, float x, float y) {
+ if (window.mWallpaperX != x || window.mWallpaperY != y) {
+ window.mWallpaperX = x;
+ window.mWallpaperY = y;
+
+ if (mWallpaperTarget == window) {
+ if (updateWallpaperOffsetLocked()) {
+ performLayoutAndPlaceSurfacesLocked();
+ }
+ }
+ }
+ }
+
public int relayoutWindow(Session session, IWindow client,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, boolean insetsPending,
@@ -5810,6 +5874,18 @@
}
}
+ public void setWallpaperPosition(IBinder window, float x, float y) {
+ synchronized(mWindowMap) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ setWindowWallpaperPositionLocked(windowForClientLocked(this, window),
+ x, y);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
void windowAddedLocked() {
if (mSurfaceSession == null) {
if (localLOGV) Log.v(
@@ -5899,8 +5975,8 @@
int mRequestedHeight;
int mLastRequestedWidth;
int mLastRequestedHeight;
- int mReqXPos;
- int mReqYPos;
+ int mXOffset;
+ int mYOffset;
int mLayer;
int mAnimLayer;
int mLastLayer;
@@ -5985,6 +6061,9 @@
boolean mHasLocalTransformation;
final Transformation mTransformation = new Transformation();
+ float mWallpaperX = 0;
+ float mWallpaperY = 0;
+
// This is set after IWindowSession.relayout() has been called at
// least once for the window. It allows us to detect the situation
// where we don't yet have a surface, but should have one soon, so
@@ -6104,8 +6183,8 @@
mRequestedHeight = 0;
mLastRequestedWidth = 0;
mLastRequestedHeight = 0;
- mReqXPos = 0;
- mReqYPos = 0;
+ mXOffset = 0;
+ mYOffset = 0;
mLayer = 0;
mAnimLayer = 0;
mLastLayer = 0;
@@ -6702,8 +6781,8 @@
mDtDx = tmpFloats[Matrix.MSKEW_X];
mDsDy = tmpFloats[Matrix.MSKEW_Y];
mDtDy = tmpFloats[Matrix.MSCALE_Y];
- int x = (int)tmpFloats[Matrix.MTRANS_X];
- int y = (int)tmpFloats[Matrix.MTRANS_Y];
+ int x = (int)tmpFloats[Matrix.MTRANS_X] + mXOffset;
+ int y = (int)tmpFloats[Matrix.MTRANS_Y] + mYOffset;
int w = frame.width();
int h = frame.height();
mShownFrame.set(x, y, x+w, y+h);
@@ -6740,6 +6819,9 @@
}
mShownFrame.set(mFrame);
+ if (mXOffset != 0 || mYOffset != 0) {
+ mShownFrame.offset(mXOffset, mYOffset);
+ }
mShownAlpha = mAlpha;
mDsDx = 1;
mDtDx = 0;
@@ -7027,9 +7109,11 @@
pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
}
pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
- pw.print(" h="); pw.print(mRequestedHeight);
- pw.print(" x="); pw.print(mReqXPos);
- pw.print(" y="); pw.println(mReqYPos);
+ pw.print(" h="); pw.println(mRequestedHeight);
+ if (mXOffset != 0 || mYOffset != 0) {
+ pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
+ pw.print(" y="); pw.println(mYOffset);
+ }
pw.print(prefix); pw.print("mGivenContentInsets=");
mGivenContentInsets.printShortString(pw);
pw.print(" mGivenVisibleInsets=");
@@ -7097,6 +7181,10 @@
pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
pw.print(" mVScale="); pw.println(mVScale);
}
+ if (mWallpaperX != 0 || mWallpaperY != 0) {
+ pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
+ pw.print(" mWallpaperY="); pw.println(mWallpaperY);
+ }
}
@Override
@@ -7282,7 +7370,7 @@
setInputMethodAnimLayerAdjustment(adj);
}
if (w == mWallpaperTarget) {
- setWallpaperAnimLayerAdjustment(adj);
+ setWallpaperAnimLayerAdjustmentLocked(adj);
}
}
}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 4ed0a5c6..a877c73 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -22,6 +22,7 @@
import android.net.Uri;
import android.os.SystemProperties;
import android.provider.Contacts;
+import android.provider.ContactsContract;
import android.text.Editable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
@@ -129,15 +130,23 @@
}
String type = intent.resolveType(context);
+ String phoneColumn = null;
- Cursor c = context.getContentResolver().query(
- uri, new String[]{ Contacts.People.Phones.NUMBER },
- null, null, null);
+ // Correctly read out the phone entry based on requested provider
+ final String authority = uri.getAuthority();
+ if (Contacts.AUTHORITY.equals(authority)) {
+ phoneColumn = Contacts.People.Phones.NUMBER;
+ } else if (ContactsContract.AUTHORITY.equals(authority)) {
+ phoneColumn = ContactsContract.CommonDataKinds.Phone.NUMBER;
+ }
+
+ final Cursor c = context.getContentResolver().query(uri, new String[] {
+ phoneColumn
+ }, null, null, null);
if (c != null) {
try {
if (c.moveToFirst()) {
- number = c.getString(
- c.getColumnIndex(Contacts.People.Phones.NUMBER));
+ number = c.getString(c.getColumnIndex(phoneColumn));
}
} finally {
c.close();
diff --git a/tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java b/tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java
index e9a43d7..1ba9d66a 100644
--- a/tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java
+++ b/tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java
@@ -16,7 +16,9 @@
package android.content;
+import android.content.ContentValues;
import android.database.Cursor;
+import android.database.MatrixCursor;
import android.net.Uri;
import android.os.Parcel;
import android.test.suitebuilder.annotation.SmallTest;
@@ -28,7 +30,9 @@
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Hashtable;
+import java.util.Set;
import java.util.Map;
+import java.util.Map.Entry;
@SmallTest
public class ContentProviderOperationTest extends TestCase {
@@ -130,6 +134,46 @@
assertEquals(sTestUri1.buildUpon().appendPath("19").toString(), result.uri.toString());
}
+ public void testAssert() {
+ // Build an operation to assert values match provider
+ ContentProviderOperation op1 = ContentProviderOperation.newAssertQuery(sTestUri1)
+ .withValues(sTestValues1).build();
+
+ try {
+ // Assert that values match from cursor
+ ContentProviderResult result = op1.apply(new TestContentProvider() {
+ public Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ // Return cursor over specific set of values
+ return getCursor(sTestValues1);
+ }
+ }, null, 0);
+ } catch (OperationApplicationException e) {
+ fail("newAssert() failed");
+ }
+ }
+
+ /**
+ * Build a {@link Cursor} with a single row that contains all values
+ * provided through the given {@link ContentValues}.
+ */
+ private Cursor getCursor(ContentValues contentValues) {
+ final Set<Entry<String, Object>> valueSet = contentValues.valueSet();
+ final String[] keys = new String[valueSet.size()];
+ final Object[] values = new Object[valueSet.size()];
+
+ int i = 0;
+ for (Entry<String, Object> entry : valueSet) {
+ keys[i] = entry.getKey();
+ values[i] = entry.getValue();
+ i++;
+ }
+
+ final MatrixCursor cursor = new MatrixCursor(keys);
+ cursor.addRow(values);
+ return cursor;
+ }
+
public void testValueBackRefs() {
ContentValues values = new ContentValues();
values.put("a", "in1");
@@ -167,11 +211,15 @@
String[] selectionArgs = new String[]{"a", null, null, "b", null};
+ final ContentValues values = new ContentValues();
+ values.put("unused", "unused");
+
ContentProviderOperation op1 = ContentProviderOperation.newUpdate(sTestUri1)
.withSelectionBackReference(1, 3)
.withSelectionBackReference(2, 1)
.withSelectionBackReference(4, 2)
.withSelection("unused", selectionArgs)
+ .withValues(values)
.build();
String[] s2 = op1.resolveSelectionArgsBackReferences(
previousResults, previousResults.length);
@@ -212,7 +260,7 @@
parcel.setDataPosition(0);
op2 = ContentProviderOperation.CREATOR.createFromParcel(parcel);
- assertEquals(1 /* ContentProviderOperation.TYPE_INSERT */, operationGetType(op2));
+ assertEquals(ContentProviderOperation.TYPE_INSERT, operationGetType(op2));
assertEquals("content://goo/bar", operationGetUri(op2).toString());
assertEquals(Integer.valueOf(42), operationGetExpectedCount(op2));
assertEquals("selection", operationGetSelection(op2));
@@ -238,9 +286,8 @@
op1.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
op2 = ContentProviderOperation.CREATOR.createFromParcel(parcel);
- assertEquals(2 /* ContentProviderOperation.TYPE_UPDATE */, operationGetType(op2));
+ assertEquals(ContentProviderOperation.TYPE_UPDATE, operationGetType(op2));
assertEquals("content://goo/bar", operationGetUri(op2).toString());
- assertNull(operationGetEntity(op2));
assertNull(operationGetExpectedCount(op2));
assertNull(operationGetSelection(op2));
assertNull(operationGetSelectionArgs(op2));
@@ -261,9 +308,8 @@
op1.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
op2 = ContentProviderOperation.CREATOR.createFromParcel(parcel);
- assertEquals(3 /* ContentProviderOperation.TYPE_DELETE */, operationGetType(op2));
+ assertEquals(ContentProviderOperation.TYPE_DELETE, operationGetType(op2));
assertEquals("content://goo/bar", operationGetUri(op2).toString());
- assertNull(operationGetEntity(op2));
assertNull(operationGetExpectedCount(op2));
assertNull(operationGetSelection(op2));
assertNull(operationGetSelectionArgs(op2));
@@ -329,15 +375,6 @@
field.set(builder, values);
}
- private void builderSetEntity(
- ContentProviderOperation.Builder builder, Entity entity)
- throws NoSuchFieldException, IllegalAccessException {
- Field field;
- field = CLASS_BUILDER.getDeclaredField("mEntity");
- field.setAccessible(true);
- field.set(builder, entity);
- }
-
private void builderSetExpectedCount(
ContentProviderOperation.Builder builder, Integer expectedCount)
throws NoSuchFieldException, IllegalAccessException {
@@ -382,13 +419,6 @@
return (ContentValues) field.get(operation);
}
- private Entity operationGetEntity(ContentProviderOperation operation)
- throws NoSuchFieldException, IllegalAccessException {
- final Field field = CLASS_OPERATION.getDeclaredField("mEntity");
- field.setAccessible(true);
- return (Entity) field.get(operation);
- }
-
private Integer operationGetExpectedCount(ContentProviderOperation operation)
throws NoSuchFieldException, IllegalAccessException {
final Field field = CLASS_OPERATION.getDeclaredField("mExpectedCount");
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index fd77d51..8e7d48f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -990,6 +990,10 @@
// pass for now.
}
+ public void setWallpaperPosition(IBinder window, float x, float y) {
+ // pass for now.
+ }
+
public IBinder asBinder() {
// pass for now.
return null;