diff options
60 files changed, 723 insertions, 251 deletions
diff --git a/api/current.xml b/api/current.xml index cc7dc23255d6..69d4d5c43289 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 9019b54693bd..78b6cf1bce58 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -28,6 +28,7 @@ import android.os.IBinder; 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 @@ public class WallpaperManager { } /** + * 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/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index 9799ac44059a..cced338a8e0d 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -24,16 +24,17 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.SystemClock; +import android.os.Parcelable; +import android.os.Parcel; import android.util.AttributeSet; import android.util.Log; +import android.util.SparseArray; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.RemoteViews; import android.widget.TextView; -import android.widget.FrameLayout.LayoutParams; /** * Provides the glue to show AppWidget views. This class offers automatic animation @@ -108,6 +109,24 @@ public class AppWidgetHostView extends FrameLayout { return mInfo; } + @Override + protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) { + final ParcelableSparseArray jail = new ParcelableSparseArray(); + super.dispatchSaveInstanceState(jail); + container.put(generateId(), jail); + } + + private int generateId() { + final int id = getId(); + return id == View.NO_ID ? mAppWidgetId : id; + } + + @Override + protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) { + final ParcelableSparseArray jail = (ParcelableSparseArray) container.get(generateId()); + super.dispatchRestoreInstanceState(jail); + } + /** {@inheritDoc} */ @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { @@ -339,4 +358,36 @@ public class AppWidgetHostView extends FrameLayout { tv.setBackgroundColor(Color.argb(127, 0, 0, 0)); return tv; } + + private static class ParcelableSparseArray extends SparseArray<Parcelable> implements Parcelable { + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + final int count = size(); + dest.writeInt(count); + for (int i = 0; i < count; i++) { + dest.writeInt(keyAt(i)); + dest.writeParcelable(valueAt(i), 0); + } + } + + public static final Parcelable.Creator<ParcelableSparseArray> CREATOR = + new Parcelable.Creator<ParcelableSparseArray>() { + public ParcelableSparseArray createFromParcel(Parcel source) { + final ParcelableSparseArray array = new ParcelableSparseArray(); + final ClassLoader loader = array.getClass().getClassLoader(); + final int count = source.readInt(); + for (int i = 0; i < count; i++) { + array.put(source.readInt(), source.readParcelable(loader)); + } + return array; + } + + public ParcelableSparseArray[] newArray(int size) { + return new ParcelableSparseArray[size]; + } + }; + } } diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java index 70ea5d00d42f..f5a4b756c219 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 @@ public class ContentProviderOperation implements Parcelable { /** @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 @@ public class ContentProviderOperation implements Parcelable { 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 @@ public class ContentProviderOperation implements Parcelable { } /** - * 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 class ContentProviderOperation implements Parcelable { } public boolean isReadOperation() { - return mType == TYPE_COUNT; + return mType == TYPE_ASSERT; } /** @@ -217,18 +213,30 @@ public class ContentProviderOperation implements Parcelable { 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"); - } - if (cursor.getCount() != 1) { - throw new RuntimeException("since we are doing a count query there should " - + "always be exacly row, found " + cursor.getCount()); + 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]); + } + } } - numRows = cursor.getInt(0); } finally { cursor.close(); } @@ -353,7 +361,7 @@ public class ContentProviderOperation implements Parcelable { * 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 @@ public class ContentProviderOperation implements Parcelable { /** 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 @@ public class ContentProviderOperation implements Parcelable { * 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 @@ public class ContentProviderOperation implements Parcelable { * 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 @@ public class ContentProviderOperation implements Parcelable { /** * 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 @@ public class ContentProviderOperation implements Parcelable { * 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 @@ public class ContentProviderOperation implements Parcelable { /** * 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 @@ public class ContentProviderOperation implements Parcelable { * 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 @@ public class ContentProviderOperation implements Parcelable { /** * 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/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java index dff7cae22861..9e966cd7abee 100755 --- a/core/java/android/inputmethodservice/KeyboardView.java +++ b/core/java/android/inputmethodservice/KeyboardView.java @@ -163,8 +163,8 @@ public class KeyboardView extends View implements View.OnClickListener { private static final int MSG_REPEAT = 3; private static final int MSG_LONGPRESS = 4; - private static final int DELAY_BEFORE_PREVIEW = 40; - private static final int DELAY_AFTER_PREVIEW = 60; + private static final int DELAY_BEFORE_PREVIEW = 0; + private static final int DELAY_AFTER_PREVIEW = 70; private int mVerticalCorrection; private int mProximityThreshold; diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 9b0c70ead0ce..066401f456d0 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -573,8 +573,8 @@ public final class ContactsContract { 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"; @@ -1401,6 +1401,17 @@ public final class ContactsContract { * Type: INTEGER */ public static final String GROUP_VISIBLE = "group_visible"; + + /** + * The "deleted" flag: "0" by default, "1" if the row has been marked + * for deletion. When {@link android.content.ContentResolver#delete} is + * called on a raw contact, it is marked for deletion and removed from its + * aggregate contact. The sync adaptor deletes the raw contact on the server and + * then calls ContactResolver.delete once more, this time passing the + * {@link RawContacts#DELETE_PERMANENTLY} query parameter to finalize the data removal. + * <P>Type: INTEGER</P> + */ + public static final String DELETED = "deleted"; } /** @@ -1434,6 +1445,20 @@ public final class ContactsContract { * The MIME type of a single group. */ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/group"; + + /** + * Query parameter that can be passed with the {@link #CONTENT_URI} URI + * to the {@link android.content.ContentResolver#delete} method to + * indicate that the raw contact can be deleted physically, rather than + * 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 db71854c469d..c438ac4aa599 100644 --- a/core/java/android/provider/DrmStore.java +++ b/core/java/android/provider/DrmStore.java @@ -35,7 +35,7 @@ import java.io.OutputStream; /** * The DRM provider contains forward locked DRM content. - * + * * @hide */ public final class DrmStore @@ -43,13 +43,13 @@ public final class DrmStore 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 final class DrmStore } 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 final class DrmStore */ 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 @@ public final class DrmStore 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 @@ public final class DrmStore 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 @@ public final class DrmStore /** * 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 @@ public final class DrmStore throw new SecurityException("Requires DRM permission"); } } - + } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 7e3f3c2192ed..cf26b1bf08f9 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2728,7 +2728,14 @@ public final class Settings { * 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 5607d4bb6783..3e6cdc267c72 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -90,7 +90,6 @@ interface IWindowManager 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 115685669406..4d662d252a7f 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -108,4 +108,10 @@ interface IWindowSession { 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/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java index 2ac77ac86d5e..afa2c35479da 100644 --- a/core/java/android/webkit/BrowserFrame.java +++ b/core/java/android/webkit/BrowserFrame.java @@ -685,7 +685,7 @@ class BrowserFrame extends Handler { default: Log.e(LOGTAG, "getRawResFilename got incompatible resource ID"); - return new String(); + return ""; } TypedValue value = new TypedValue(); mContext.getResources().getValue(resid, value, true); diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java index 7b32a262ce49..d8f87cf39101 100644 --- a/core/java/android/webkit/CacheManager.java +++ b/core/java/android/webkit/CacheManager.java @@ -429,7 +429,7 @@ public final class CacheManager { if (checkCacheRedirect(cacheRet.httpStatusCode)) { // location is in database, no need to keep the file cacheRet.contentLength = 0; - cacheRet.localPath = new String(); + cacheRet.localPath = ""; cacheRet.outFile.delete(); } else if (cacheRet.contentLength == 0) { cacheRet.outFile.delete(); diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java index b2277cb4824e..96bf46ec9a29 100644 --- a/core/java/android/webkit/CallbackProxy.java +++ b/core/java/android/webkit/CallbackProxy.java @@ -111,7 +111,7 @@ class CallbackProxy extends Handler { // Result transportation object for returning results across thread // boundaries. - private class ResultTransport<E> { + private static class ResultTransport<E> { // Private result object private E mResult; diff --git a/core/java/android/webkit/DateSorter.java b/core/java/android/webkit/DateSorter.java index 750403b49817..c46702e70509 100644 --- a/core/java/android/webkit/DateSorter.java +++ b/core/java/android/webkit/DateSorter.java @@ -43,9 +43,6 @@ public class DateSorter { 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/HttpAuthHandler.java b/core/java/android/webkit/HttpAuthHandler.java index 84dc9f0ae0e8..1c17575033fe 100644 --- a/core/java/android/webkit/HttpAuthHandler.java +++ b/core/java/android/webkit/HttpAuthHandler.java @@ -49,8 +49,8 @@ public class HttpAuthHandler extends Handler { // Message id for handling the user response - private final int AUTH_PROCEED = 100; - private final int AUTH_CANCEL = 200; + private static final int AUTH_PROCEED = 100; + private static final int AUTH_CANCEL = 200; /** * Creates a new HTTP authentication handler with an empty diff --git a/core/java/android/webkit/Network.java b/core/java/android/webkit/Network.java index fb601098bd5a..0b9e596e4868 100644 --- a/core/java/android/webkit/Network.java +++ b/core/java/android/webkit/Network.java @@ -136,7 +136,7 @@ class Network { 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 cc1e7501b1ad..5011244767d1 100644 --- a/core/java/android/webkit/SslErrorHandler.java +++ b/core/java/android/webkit/SslErrorHandler.java @@ -42,11 +42,6 @@ public class SslErrorHandler extends Handler { private static final String LOGTAG = "network"; /** - * Network. - */ - private Network mNetwork; - - /** * Queue of loaders that experience SSL-related problems. */ private LinkedList<LoadListener> mLoaderQueue; @@ -57,7 +52,7 @@ public class SslErrorHandler extends Handler { private Bundle mSslPrefTable; // Message id for handling the response - private final int HANDLE_RESPONSE = 100; + private static final int HANDLE_RESPONSE = 100; @Override public void handleMessage(Message msg) { @@ -72,9 +67,7 @@ public class SslErrorHandler extends Handler { /** * 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/WebIconDatabase.java b/core/java/android/webkit/WebIconDatabase.java index d284f5e85831..6cc6bb4c5575 100644 --- a/core/java/android/webkit/WebIconDatabase.java +++ b/core/java/android/webkit/WebIconDatabase.java @@ -37,7 +37,7 @@ public final class WebIconDatabase { private final EventHandler mEventHandler = new EventHandler(); // Class to handle messages before WebCore is ready - private class EventHandler extends Handler { + private static class EventHandler extends Handler { // Message ids static final int OPEN = 0; static final int CLOSE = 1; diff --git a/core/java/android/webkit/WebStorage.java b/core/java/android/webkit/WebStorage.java index c3b359eb64e2..ae560fb591ce 100644 --- a/core/java/android/webkit/WebStorage.java +++ b/core/java/android/webkit/WebStorage.java @@ -70,7 +70,7 @@ public final class WebStorage { private Handler mHandler = null; - private class Origin { + private static class Origin { String mOrigin = null; long mQuota = 0; diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 3092fa6ace9e..cc7a228f56d2 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -2514,7 +2514,11 @@ public class WebView extends AbsoluteLayout @Override protected void finalize() throws Throwable { - destroy(); + try { + destroy(); + } finally { + super.finalize(); + } } @Override diff --git a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java index 7aa4f470f54c..b9b07a84c733 100644 --- a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java +++ b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java @@ -99,32 +99,36 @@ public class ImageWallpaper extends WallpaperService { void drawFrame(boolean drawText) { SurfaceHolder sh = getSurfaceHolder(); - Canvas c = sh.lockCanvas(); - if (c != null) { - final Rect frame = sh.getSurfaceFrame(); - mBackground.setBounds(frame); - mBackground.draw(c); - - if (drawText) { - // Figure out animation. - long now = SystemClock.uptimeMillis(); - while (mAnimStartTime < (now-1000)) { - mAnimStartTime += 1000; - mAnimLarger = !mAnimLarger; + Canvas c = null; + try { + c = sh.lockCanvas(); + if (c != null) { + final Rect frame = sh.getSurfaceFrame(); + mBackground.setBounds(frame); + mBackground.draw(c); + + if (drawText) { + // Figure out animation. + long now = SystemClock.uptimeMillis(); + while (mAnimStartTime < (now-1000)) { + mAnimStartTime += 1000; + mAnimLarger = !mAnimLarger; + } + float size = (now-mAnimStartTime) / (float)1000; + if (!mAnimLarger) size = 1-size; + int alpha = (int)(255*(size*size)); + mTextPaint.setARGB(alpha, 255, 255, 255); + mTextPaint.setShadowLayer(5*mDensity, 3*mDensity, 3*mDensity, + alpha<<24); + mTextPaint.setTextSize(100 * mDensity * size); + c.drawText("Am I live?", + frame.left + (frame.right-frame.left)/2, + frame.top + (frame.bottom-frame.top)/2, mTextPaint); } - float size = (now-mAnimStartTime) / (float)1000; - if (!mAnimLarger) size = 1-size; - int alpha = (int)(255*(size*size)); - mTextPaint.setARGB(alpha, 255, 255, 255); - mTextPaint.setShadowLayer(5*mDensity, 3*mDensity, 3*mDensity, - alpha<<24); - mTextPaint.setTextSize(100 * mDensity * size); - c.drawText("Am I live?", - frame.left + (frame.right-frame.left)/2, - frame.top + (frame.bottom-frame.top)/2, mTextPaint); } + } finally { + if (c != null) sh.unlockCanvasAndPost(c); } - sh.unlockCanvasAndPost(c); } } diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java index e4aaf3819193..eac5d2df5d4c 100644 --- a/core/java/com/android/internal/widget/ContactHeaderWidget.java +++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java @@ -52,7 +52,8 @@ import com.android.internal.R; /* 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 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList 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 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList 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 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList mPhotoView = (ImageView)findViewById(R.id.photo); mPhotoView.setOnClickListener(this); + mPhotoView.setOnLongClickListener(this); mStatusView = (TextView)findViewById(R.id.status); @@ -152,6 +163,35 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList 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/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h index cb9bf940e23a..68144b5944a5 100644 --- a/include/ui/FramebufferNativeWindow.h +++ b/include/ui/FramebufferNativeWindow.h @@ -63,6 +63,7 @@ private: static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer); static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer); static int query(android_native_window_t* window, int what, int* value); + static int perform(android_native_window_t* window, int operation, ...); framebuffer_device_t* fbDev; alloc_device_t* grDev; diff --git a/include/ui/ISurface.h b/include/ui/ISurface.h index adba45a48cb4..7909c2f41d4a 100644 --- a/include/ui/ISurface.h +++ b/include/ui/ISurface.h @@ -50,7 +50,7 @@ protected: public: DECLARE_META_INTERFACE(Surface); - virtual sp<SurfaceBuffer> getBuffer() = 0; + virtual sp<SurfaceBuffer> getBuffer(int usage) = 0; class BufferHeap { public: diff --git a/include/ui/Surface.h b/include/ui/Surface.h index d5dad31d00b6..4ff0e4abd807 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -184,7 +184,7 @@ private: friend class IOMX; const sp<ISurface>& getISurface() const { return mSurface; } - status_t getBufferLocked(int index); + status_t getBufferLocked(int index, int usage); status_t validate(per_client_cblk_t const* cblk) const; static void _send_dirty_region(layer_cblk_t* lcblk, const Region& dirty); @@ -197,11 +197,13 @@ private: static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer); static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer); static int query(android_native_window_t* window, int what, int* value); + static int perform(android_native_window_t* window, int operation, ...); int dequeueBuffer(android_native_buffer_t** buffer); int lockBuffer(android_native_buffer_t* buffer); int queueBuffer(android_native_buffer_t* buffer); int query(int what, int* value); + int perform(int operation, va_list args); status_t dequeueBuffer(sp<SurfaceBuffer>* buffer); status_t lockBuffer(const sp<SurfaceBuffer>& buffer); @@ -217,6 +219,7 @@ private: uint32_t mIdentity; uint32_t mWidth; uint32_t mHeight; + uint32_t mUsage; PixelFormat mFormat; uint32_t mFlags; mutable Region mDirtyRegion; diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h index 7da69b144a49..4c58e474c67d 100644 --- a/include/ui/egl/android_natives.h +++ b/include/ui/egl/android_natives.h @@ -67,6 +67,11 @@ enum { NATIVE_WINDOW_FORMAT = 2, }; +/* valid operations for the (*perform)() hook */ +enum { + NATIVE_WINDOW_SET_USAGE = 0 +}; + struct android_native_window_t { #ifdef __cplusplus @@ -142,11 +147,45 @@ struct android_native_window_t * Returns 0 on success or -errno on error. */ int (*query)(struct android_native_window_t* window, - int what, int* value); + int what, int* value); + + /* + * hook used to perform various operations on the surface. + * (*perform)() is a generic mechanism to add functionality to + * android_native_window_t while keeping backward binary compatibility. + * + * This hook should not be called directly, instead use the helper functions + * defined below. + * + * The valid operations are: + * NATIVE_WINDOW_SET_USAGE + * + */ + + int (*perform)(struct android_native_window_t* window, + int operation, ... ); - void* reserved_proc[4]; + void* reserved_proc[3]; }; + +/* + * native_window_set_usage() sets the intended usage flags for the next + * buffers acquired with (*lockBuffer)() and on. + * By default (if this function is never called), a usage of + * GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE + * is assumed. + * Calling this function will usually cause following buffers to be + * reallocated. + */ + +inline int native_window_set_usage( + struct android_native_window_t* window, int usage) +{ + return window->perform(window, NATIVE_WINDOW_SET_USAGE, usage); +} + + // --------------------------------------------------------------------------- /* FIXME: this is legacy for pixmaps */ diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp index d019097c5c9d..77a126c72409 100644 --- a/libs/audioflinger/AudioFlinger.cpp +++ b/libs/audioflinger/AudioFlinger.cpp @@ -1512,6 +1512,10 @@ bool AudioFlinger::MixerThread::checkForNewParameters_l() int name = getTrackName_l(); if (name < 0) break; mTracks[i]->mName = name; + // limit track sample rate to 2 x new output sample rate + if (mTracks[i]->mCblk->sampleRate > 2 * sampleRate()) { + mTracks[i]->mCblk->sampleRate = 2 * sampleRate(); + } } sendConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED); } @@ -1856,9 +1860,7 @@ bool AudioFlinger::DuplicatingThread::threadLoop() mSuspended) { if (!mStandby) { for (size_t i = 0; i < outputTracks.size(); i++) { - mLock.unlock(); outputTracks[i]->stop(); - mLock.lock(); } mStandby = true; mBytesWritten = 0; @@ -1899,9 +1901,9 @@ bool AudioFlinger::DuplicatingThread::threadLoop() 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 { @@ -1931,11 +1933,14 @@ bool AudioFlinger::DuplicatingThread::threadLoop() 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(); + } } } @@ -1953,9 +1958,11 @@ void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread) 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) @@ -1963,6 +1970,7 @@ void AudioFlinger::DuplicatingThread::removeOutputTrack(MixerThread *thread) 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; } @@ -2452,20 +2460,23 @@ AudioFlinger::PlaybackThread::OutputTrack::OutputTrack( { 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() @@ -2904,7 +2915,7 @@ bool AudioFlinger::RecordThread::threadLoop() 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 4ba5977bd6f0..65c148ea8edb 100644 --- a/libs/audioflinger/AudioFlinger.h +++ b/libs/audioflinger/AudioFlinger.h @@ -245,6 +245,7 @@ private: 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 @@ private: 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: 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 b474dca97dcb..ba802f7f0bdd 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 88e76dcbba40..c4a70c8fbbfd 100644 --- a/libs/surfaceflinger/Android.mk +++ b/libs/surfaceflinger/Android.mk @@ -24,6 +24,9 @@ LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES 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/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index d1142cca86da..8c0b40d9e471 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -217,7 +217,7 @@ void Layer::onDraw(const Region& clip) const drawWithOpenGL(clip, mTextures[index]); } -sp<SurfaceBuffer> Layer::peekBuffer() +sp<SurfaceBuffer> Layer::peekBuffer(int usage) { /* * This is called from the client's Surface::lock(), after it locked @@ -250,7 +250,7 @@ sp<SurfaceBuffer> Layer::peekBuffer() } LayerBitmap& layerBitmap(mBuffers[backBufferIndex]); - sp<SurfaceBuffer> buffer = layerBitmap.allocate(); + sp<SurfaceBuffer> buffer = layerBitmap.allocate(usage); LOGD_IF(DEBUG_RESIZE, "Layer::getBuffer(this=%p), index=%d, (%d,%d), (%d,%d)", @@ -649,12 +649,12 @@ Layer::SurfaceLayer::~SurfaceLayer() { } -sp<SurfaceBuffer> Layer::SurfaceLayer::getBuffer() +sp<SurfaceBuffer> Layer::SurfaceLayer::getBuffer(int usage) { sp<SurfaceBuffer> buffer = 0; sp<Layer> owner(getOwner()); if (owner != 0) { - buffer = owner->peekBuffer(); + buffer = owner->peekBuffer(usage); } return buffer; } diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h index 4c13d6ea2887..add5d5074741 100644 --- a/libs/surfaceflinger/Layer.h +++ b/libs/surfaceflinger/Layer.h @@ -101,7 +101,7 @@ private: status_t resize(int32_t index, uint32_t w, uint32_t h, const char* what); Region post(uint32_t* oldState, bool& recomputeVisibleRegions); - sp<SurfaceBuffer> peekBuffer(); + sp<SurfaceBuffer> peekBuffer(int usage); void destroy(); void scheduleBroadcast(); @@ -114,7 +114,7 @@ private: ~SurfaceLayer(); private: - virtual sp<SurfaceBuffer> getBuffer(); + virtual sp<SurfaceBuffer> getBuffer(int usage); sp<Layer> getOwner() const { return static_cast<Layer*>(Surface::getOwner().get()); diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index fbce73ddd3be..419574c7def1 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -759,7 +759,7 @@ status_t LayerBaseClient::Surface::onTransact( return BnSurface::onTransact(code, data, reply, flags); } -sp<SurfaceBuffer> LayerBaseClient::Surface::getBuffer() +sp<SurfaceBuffer> LayerBaseClient::Surface::getBuffer(int) { return NULL; } diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index 6fb1d1c50cab..65bf55b51b42 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -335,7 +335,7 @@ public: sp<LayerBaseClient> getOwner() const; private: - virtual sp<SurfaceBuffer> getBuffer(); + virtual sp<SurfaceBuffer> getBuffer(int usage); virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); virtual void postBuffer(ssize_t offset); virtual void unregisterBuffers(); diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp index 5221fed56f4d..5e74451d5f04 100644 --- a/libs/surfaceflinger/LayerBitmap.cpp +++ b/libs/surfaceflinger/LayerBitmap.cpp @@ -38,13 +38,14 @@ namespace android { // Buffer and implementation of android_native_buffer_t // =========================================================================== -Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) +Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, + uint32_t reqUsage, uint32_t flags) : SurfaceBuffer(), mInitCheck(NO_INIT), mFlags(flags), mVStride(0) { this->format = format; if (w>0 && h>0) { - mInitCheck = initSize(w, h); + mInitCheck = initSize(w, h, reqUsage); } } @@ -65,7 +66,7 @@ android_native_buffer_t* Buffer::getNativeBuffer() const return static_cast<android_native_buffer_t*>(const_cast<Buffer*>(this)); } -status_t Buffer::initSize(uint32_t w, uint32_t h) +status_t Buffer::initSize(uint32_t w, uint32_t h, uint32_t reqUsage) { status_t err = NO_ERROR; @@ -88,16 +89,9 @@ status_t Buffer::initSize(uint32_t w, uint32_t h) usage = BufferAllocator::USAGE_SW_READ_OFTEN | BufferAllocator::USAGE_SW_WRITE_OFTEN; } else { - if (mFlags & Buffer::GPU) { - // the client wants to do GL rendering - usage = BufferAllocator::USAGE_HW_RENDER | - BufferAllocator::USAGE_HW_TEXTURE; - } else { - // software rendering-client, h/w composition - usage = BufferAllocator::USAGE_SW_READ_OFTEN | - BufferAllocator::USAGE_SW_WRITE_OFTEN | - BufferAllocator::USAGE_HW_TEXTURE; - } + // it's allowed to modify the usage flags here, but generally + // the requested flags should be honored. + usage = reqUsage | BufferAllocator::USAGE_HW_TEXTURE; } err = allocator.alloc(w, h, format, usage, &handle, &stride); @@ -174,12 +168,12 @@ status_t LayerBitmap::setSize(uint32_t w, uint32_t h) return NO_ERROR; } -sp<Buffer> LayerBitmap::allocate() +sp<Buffer> LayerBitmap::allocate(uint32_t reqUsage) { Mutex::Autolock _l(mLock); surface_info_t* info = mInfo; mBuffer.clear(); // free buffer before allocating a new one - sp<Buffer> buffer = new Buffer(mWidth, mHeight, mFormat, mFlags); + sp<Buffer> buffer = new Buffer(mWidth, mHeight, mFormat, reqUsage, mFlags); status_t err = buffer->initCheck(); if (LIKELY(err == NO_ERROR)) { info->flags = surface_info_t::eBufferDirty; diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h index 22525cebdfc5..48ee553e523a 100644 --- a/libs/surfaceflinger/LayerBitmap.h +++ b/libs/surfaceflinger/LayerBitmap.h @@ -58,7 +58,8 @@ public: }; // creates w * h buffer - Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags = 0); + Buffer(uint32_t w, uint32_t h, PixelFormat format, + uint32_t reqUsage, uint32_t flags = 0); // return status status_t initCheck() const; @@ -81,7 +82,7 @@ private: Buffer& operator = (const Buffer& rhs); const Buffer& operator = (const Buffer& rhs) const; - status_t initSize(uint32_t w, uint32_t h); + status_t initSize(uint32_t w, uint32_t h, uint32_t reqUsage); ssize_t mInitCheck; uint32_t mFlags; @@ -108,7 +109,7 @@ public: status_t setSize(uint32_t w, uint32_t h); - sp<Buffer> allocate(); + sp<Buffer> allocate(uint32_t reqUsage); status_t free(); sp<const Buffer> getBuffer() const { return mBuffer; } diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 90e7f5048067..e1f4bea228c5 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -28,6 +28,7 @@ #include <hardware/copybit.h> +#include "BufferAllocator.h" #include "LayerBuffer.h" #include "SurfaceFlinger.h" #include "DisplayHardware/DisplayHardware.h" @@ -464,7 +465,10 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const mTempBitmap->getWidth() < tmp_w || mTempBitmap->getHeight() < tmp_h) { mTempBitmap.clear(); - mTempBitmap = new android::Buffer(tmp_w, tmp_h, src.img.format); + mTempBitmap = new android::Buffer( + tmp_w, tmp_h, src.img.format, + BufferAllocator::USAGE_HW_TEXTURE | + BufferAllocator::USAGE_HW_2D); err = mTempBitmap->initCheck(); } diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp index 8e9df9cc9bcc..6ebb49f64ca2 100644 --- a/libs/surfaceflinger/LayerDim.cpp +++ b/libs/surfaceflinger/LayerDim.cpp @@ -21,6 +21,7 @@ #include <utils/Errors.h> #include <utils/Log.h> +#include "BufferAllocator.h" #include "LayerDim.h" #include "SurfaceFlinger.h" #include "DisplayHardware/DisplayHardware.h" @@ -68,7 +69,11 @@ void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h) if (LIKELY(flags & DisplayHardware::DIRECT_TEXTURE)) { // TODO: api to pass the usage flags - sp<Buffer> buffer = new Buffer(w, h, PIXEL_FORMAT_RGB_565); + sp<Buffer> buffer = new Buffer(w, h, PIXEL_FORMAT_RGB_565, + BufferAllocator::USAGE_SW_WRITE_OFTEN | + BufferAllocator::USAGE_HW_TEXTURE | + BufferAllocator::USAGE_HW_2D); + android_native_buffer_t* clientBuf = buffer->getNativeBuffer(); glGenTextures(1, &sTexId); diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index f6c666df4263..90b51634c60c 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -132,6 +132,7 @@ FramebufferNativeWindow::FramebufferNativeWindow() android_native_window_t::lockBuffer = lockBuffer; android_native_window_t::queueBuffer = queueBuffer; android_native_window_t::query = query; + android_native_window_t::perform = perform; } FramebufferNativeWindow::~FramebufferNativeWindow() @@ -235,6 +236,18 @@ int FramebufferNativeWindow::query(android_native_window_t* window, return BAD_VALUE; } +int FramebufferNativeWindow::perform(android_native_window_t* window, + int operation, ...) +{ + switch (operation) { + case NATIVE_WINDOW_SET_USAGE: + break; + default: + return NAME_NOT_FOUND; + } + return NO_ERROR; +} + // ---------------------------------------------------------------------------- }; // namespace android // ---------------------------------------------------------------------------- diff --git a/libs/ui/ISurface.cpp b/libs/ui/ISurface.cpp index 9fbae1ebafe1..b78e8b5ab5a1 100644 --- a/libs/ui/ISurface.cpp +++ b/libs/ui/ISurface.cpp @@ -71,10 +71,11 @@ public: { } - virtual sp<SurfaceBuffer> getBuffer() + virtual sp<SurfaceBuffer> getBuffer(int usage) { Parcel data, reply; data.writeInterfaceToken(ISurface::getInterfaceDescriptor()); + data.writeInt32(usage); remote()->transact(GET_BUFFER, data, &reply); sp<SurfaceBuffer> buffer = new SurfaceBuffer(reply); return buffer; @@ -135,7 +136,8 @@ status_t BnSurface::onTransact( switch(code) { case GET_BUFFER: { CHECK_INTERFACE(ISurface, data, reply); - sp<SurfaceBuffer> buffer(getBuffer()); + int usage = data.readInt32(); + sp<SurfaceBuffer> buffer(getBuffer(usage)); return SurfaceBuffer::writeToParcel(reply, buffer.get()); } case REGISTER_BUFFERS: { diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index 4abb7f62ad44..2b6905f33fc2 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -414,6 +414,7 @@ void Surface::init() android_native_window_t::lockBuffer = lockBuffer; android_native_window_t::queueBuffer = queueBuffer; android_native_window_t::query = query; + android_native_window_t::perform = perform; mSwapRectangle.makeInvalid(); DisplayInfo dinfo; SurfaceComposerClient::getDisplayInfo(0, &dinfo); @@ -423,6 +424,8 @@ void Surface::init() const_cast<int&>(android_native_window_t::minSwapInterval) = 1; const_cast<int&>(android_native_window_t::maxSwapInterval) = 1; const_cast<uint32_t&>(android_native_window_t::flags) = 0; + // be default we request a hardware surface + mUsage = GRALLOC_USAGE_HW_RENDER; } @@ -512,6 +515,17 @@ int Surface::query(android_native_window_t* window, return self->query(what, value); } +int Surface::perform(android_native_window_t* window, + int operation, ...) +{ + va_list args; + va_start(args, operation); + Surface* self = getSelf(window); + int res = self->perform(operation, args); + va_end(args); + return res; +} + // ---------------------------------------------------------------------------- status_t Surface::dequeueBuffer(sp<SurfaceBuffer>* buffer) @@ -561,7 +575,7 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer) volatile const surface_info_t* const back = lcblk->surface + backIdx; if (back->flags & surface_info_t::eNeedNewBuffer) { - err = getBufferLocked(backIdx); + err = getBufferLocked(backIdx, mUsage); } if (err == NO_ERROR) { @@ -627,6 +641,20 @@ int Surface::query(int what, int* value) return BAD_VALUE; } +int Surface::perform(int operation, va_list args) +{ + int res = NO_ERROR; + switch (operation) { + case NATIVE_WINDOW_SET_USAGE: + mUsage = va_arg(args, int); + break; + default: + res = NAME_NOT_FOUND; + break; + } + return res; +} + // ---------------------------------------------------------------------------- status_t Surface::lock(SurfaceInfo* info, bool blocking) { @@ -636,6 +664,9 @@ status_t Surface::lock(SurfaceInfo* info, bool blocking) { status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) { // FIXME: needs some locking here + + // we're intending to do software rendering from this point + mUsage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; sp<SurfaceBuffer> backBuffer; status_t err = dequeueBuffer(&backBuffer); @@ -725,10 +756,10 @@ void Surface::setSwapRectangle(const Rect& r) { mSwapRectangle = r; } -status_t Surface::getBufferLocked(int index) +status_t Surface::getBufferLocked(int index, int usage) { status_t err = NO_MEMORY; - sp<SurfaceBuffer> buffer = mSurface->getBuffer(); + sp<SurfaceBuffer> buffer = mSurface->getBuffer(usage); LOGE_IF(buffer==0, "ISurface::getBuffer() returned NULL"); if (buffer != 0) { sp<SurfaceBuffer>& currentBuffer(mBuffers[index]); diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp index 3ea64ae67728..799c349fd781 100644 --- a/media/libmedia/ToneGenerator.cpp +++ b/media/libmedia/ToneGenerator.cpp @@ -914,7 +914,7 @@ bool ToneGenerator::startTone(int toneType) { } } } else { - mState == TONE_IDLE; + mState = TONE_IDLE; } } else { LOGV("Delayed start\n"); diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index cf66be33729f..0762ebf605fc 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -384,6 +384,10 @@ egl_window_surface_v2_t::~egl_window_surface_v2_t() { EGLBoolean egl_window_surface_v2_t::connect() { + // we're intending to do software rendering + native_window_set_usage(nativeWindow, + GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); + // dequeue a buffer if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) != NO_ERROR) { return setError(EGL_BAD_ALLOC, EGL_FALSE); diff --git a/opengl/tests/angeles/app-linux.cpp b/opengl/tests/angeles/app-linux.cpp index 9c71693f6d6d..06fa0c2bd711 100644 --- a/opengl/tests/angeles/app-linux.cpp +++ b/opengl/tests/angeles/app-linux.cpp @@ -133,11 +133,11 @@ static int initGraphics() EGLint w, h; EGLDisplay dpy; + EGLNativeWindowType window = android_createDisplaySurface(); + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(dpy, &majorVersion, &minorVersion); - EGLNativeWindowType window = android_createDisplaySurface(); - status_t err = EGLUtils::selectConfigForNativeWindow( dpy, configAttribs, window, &config); if (err) { diff --git a/opengl/tests/copybits/copybits.cpp b/opengl/tests/copybits/copybits.cpp index f8ca9b2e0eee..11dfb6e78474 100644 --- a/opengl/tests/copybits/copybits.cpp +++ b/opengl/tests/copybits/copybits.cpp @@ -23,6 +23,9 @@ #include <hardware/gralloc.h> #include <hardware/hardware.h> +#include <ui/FramebufferNativeWindow.h> +#include <ui/EGLUtils.h> + #define EGL_EGLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES @@ -32,8 +35,6 @@ #include <GLES/gl.h> #include <GLES/glext.h> -extern "C" EGLNativeWindowType android_createDisplaySurface(void); - using namespace android; EGLDisplay eglDisplay; @@ -268,6 +269,8 @@ int init_gl_surface(void) EGL_NONE }; + EGLNativeWindowType window = android_createDisplaySurface(); + printf("init_gl_surface\n"); if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY ) { @@ -281,14 +284,15 @@ int init_gl_surface(void) return 0; } - if ( eglChooseConfig(eglDisplay, attrib, &myConfig, 1, &numConfigs) != EGL_TRUE ) + if ( EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig) != 0) { - printf("eglChooseConfig failed\n"); + printf("EGLUtils::selectConfigForNativeWindow failed\n"); return 0; } + if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig, - android_createDisplaySurface(), 0)) == EGL_NO_SURFACE ) + window, 0)) == EGL_NO_SURFACE ) { printf("eglCreateWindowSurface failed\n"); return 0; diff --git a/opengl/tests/fillrate/fillrate.cpp b/opengl/tests/fillrate/fillrate.cpp index 4ffbc8b3ef99..911d35469b1e 100644 --- a/opengl/tests/fillrate/fillrate.cpp +++ b/opengl/tests/fillrate/fillrate.cpp @@ -45,11 +45,11 @@ int main(int argc, char** argv) EGLint w, h; EGLDisplay dpy; + EGLNativeWindowType window = android_createDisplaySurface(); + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(dpy, &majorVersion, &minorVersion); - EGLNativeWindowType window = android_createDisplaySurface(); - status_t err = EGLUtils::selectConfigForNativeWindow( dpy, configAttribs, window, &config); if (err) { diff --git a/opengl/tests/filter/filter.cpp b/opengl/tests/filter/filter.cpp index e82b12d301c6..82aafbf84136 100644 --- a/opengl/tests/filter/filter.cpp +++ b/opengl/tests/filter/filter.cpp @@ -37,10 +37,14 @@ int main(int argc, char** argv) EGLDisplay dpy; + EGLNativeWindowType window = 0; + if (!usePbuffer) { + window = android_createDisplaySurface(); + } + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(dpy, &majorVersion, &minorVersion); if (!usePbuffer) { - EGLNativeWindowType window = android_createDisplaySurface(); surface = eglCreateWindowSurface(dpy, config, window, NULL); EGLUtils::selectConfigForNativeWindow( dpy, s_configAttribs, window, &config); diff --git a/opengl/tests/finish/finish.cpp b/opengl/tests/finish/finish.cpp index b5b8142f6cad..91f5c45dde8f 100644 --- a/opengl/tests/finish/finish.cpp +++ b/opengl/tests/finish/finish.cpp @@ -46,11 +46,11 @@ int main(int argc, char** argv) EGLint w, h; EGLDisplay dpy; + EGLNativeWindowType window = android_createDisplaySurface(); + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(dpy, &majorVersion, &minorVersion); - EGLNativeWindowType window = android_createDisplaySurface(); - status_t err = EGLUtils::selectConfigForNativeWindow( dpy, configAttribs, window, &config); if (err) { diff --git a/opengl/tests/swapinterval/swapinterval.cpp b/opengl/tests/swapinterval/swapinterval.cpp index 80a6c21b4e49..df53b6269925 100644 --- a/opengl/tests/swapinterval/swapinterval.cpp +++ b/opengl/tests/swapinterval/swapinterval.cpp @@ -44,12 +44,13 @@ int main(int argc, char** argv) EGLint w, h; EGLDisplay dpy; + + EGLNativeWindowType window = android_createDisplaySurface(); + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(dpy, 0 ,0) ;//&majorVersion, &minorVersion); eglGetConfigs(dpy, NULL, 0, &numConfigs); printf("# configs = %d\n", numConfigs); - - EGLNativeWindowType window = android_createDisplaySurface(); status_t err = EGLUtils::selectConfigForNativeWindow( dpy, configAttribs, window, &config); diff --git a/opengl/tests/textures/textures.cpp b/opengl/tests/textures/textures.cpp index ee92e7922dcb..cbe8ffddc941 100644 --- a/opengl/tests/textures/textures.cpp +++ b/opengl/tests/textures/textures.cpp @@ -42,11 +42,11 @@ int main(int argc, char** argv) EGLint w, h; EGLDisplay dpy; + EGLNativeWindowType window = android_createDisplaySurface(); + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(dpy, &majorVersion, &minorVersion); - EGLNativeWindowType window = android_createDisplaySurface(); - status_t err = EGLUtils::selectConfigForNativeWindow( dpy, configAttribs, window, &config); if (err) { diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 69c48d39457b..641f251da5eb 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -1223,6 +1223,9 @@ public class WindowManagerService extends IWindowManager.Stub // 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 @@ public class WindowManagerService extends IWindowManager.Stub } } + 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub } } + 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 class WindowManagerService extends IWindowManager.Stub } } + 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 class WindowManagerService extends IWindowManager.Stub } } + 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 @@ public class WindowManagerService extends IWindowManager.Stub int mRequestedHeight; int mLastRequestedWidth; int mLastRequestedHeight; - int mReqXPos; - int mReqYPos; + int mXOffset; + int mYOffset; int mLayer; int mAnimLayer; int mLastLayer; @@ -5985,6 +6061,9 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub mRequestedHeight = 0; mLastRequestedWidth = 0; mLastRequestedHeight = 0; - mReqXPos = 0; - mReqYPos = 0; + mXOffset = 0; + mYOffset = 0; mLayer = 0; mAnimLayer = 0; mLastLayer = 0; @@ -6702,8 +6781,8 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub } mShownFrame.set(mFrame); + if (mXOffset != 0 || mYOffset != 0) { + mShownFrame.offset(mXOffset, mYOffset); + } mShownAlpha = mAlpha; mDsDx = 1; mDtDx = 0; @@ -7027,9 +7109,11 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 4ed0a5c6198a..a877c738b726 100644 --- a/telephony/java/android/telephony/PhoneNumberUtils.java +++ b/telephony/java/android/telephony/PhoneNumberUtils.java @@ -22,6 +22,7 @@ import android.database.Cursor; 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 @@ public class PhoneNumberUtils } String type = intent.resolveType(context); + String phoneColumn = 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; + } - Cursor c = context.getContentResolver().query( - uri, new String[]{ Contacts.People.Phones.NUMBER }, - null, null, null); + 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/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java index 6e2b3f3f762d..b2795270ae50 100644 --- a/telephony/java/com/android/internal/telephony/PhoneBase.java +++ b/telephony/java/com/android/internal/telephony/PhoneBase.java @@ -59,10 +59,13 @@ public abstract class PhoneBase implements Phone { private static final String LOG_TAG = "PHONE"; private static final boolean LOCAL_DEBUG = true; - // Key used to read and write the saved network selection value + // Key used to read and write the saved network selection numeric value public static final String NETWORK_SELECTION_KEY = "network_selection_key"; + // Key used to read and write the saved network selection operator name + public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key"; - // Key used to read/write "disable data connection on boot" pref (used for testing) + + // Key used to read/write "disable data connection on boot" pref (used for testing) public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key"; //***** Event Constants diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java index 8a1e928ad136..60e0a44cb3d5 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java +++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java @@ -115,4 +115,9 @@ public interface TelephonyProperties */ static final String PROPERTY_OTASP_NUM_SCHEMA = "ro.cdma.otaspnumschema"; + /** + * Disable all calls including Emergency call when it set to true. + */ + static final String PROPERTY_DISABLE_CALL = "ro.telephony.disable-call"; + } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java index 3997639bf502..be4763cfd0fe 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java @@ -321,13 +321,16 @@ public final class CdmaCallTracker extends CallTracker { canDial() { boolean ret; int serviceState = phone.getServiceState().getState(); + String disableCall = SystemProperties.get( + TelephonyProperties.PROPERTY_DISABLE_CALL, "false"); - ret = (serviceState != ServiceState.STATE_POWER_OFF) && - pendingMO == null + ret = (serviceState != ServiceState.STATE_POWER_OFF) + && pendingMO == null && !ringingCall.isRinging() + && !disableCall.equals("true") && (!foregroundCall.getState().isAlive() - || (foregroundCall.getState() == CdmaCall.State.ACTIVE) - || !backgroundCall.getState().isAlive()); + || (foregroundCall.getState() == CdmaCall.State.ACTIVE) + || !backgroundCall.getState().isAlive()); return ret; } diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java index 6f8928830a9b..94d43441ff61 100755 --- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java +++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java @@ -1032,11 +1032,13 @@ public class GSMPhone extends PhoneBase { /** * Small container class used to hold information relevant to * the carrier selection process. operatorNumeric can be "" - * if we are looking for automatic selection. + * if we are looking for automatic selection. operatorAlphaLong is the + * corresponding operator name. */ private static class NetworkSelectMessage { public Message message; public String operatorNumeric; + public String operatorAlphaLong; } public void @@ -1047,6 +1049,7 @@ public class GSMPhone extends PhoneBase { NetworkSelectMessage nsm = new NetworkSelectMessage(); nsm.message = response; nsm.operatorNumeric = ""; + nsm.operatorAlphaLong = ""; // get the message Message msg = h.obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm); @@ -1064,6 +1067,7 @@ public class GSMPhone extends PhoneBase { NetworkSelectMessage nsm = new NetworkSelectMessage(); nsm.message = response; nsm.operatorNumeric = network.operatorNumeric; + nsm.operatorAlphaLong = network.operatorAlphaLong; // get the message Message msg = h.obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm); @@ -1499,6 +1503,7 @@ public class GSMPhone extends PhoneBase { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); SharedPreferences.Editor editor = sp.edit(); editor.putString(NETWORK_SELECTION_KEY, nsm.operatorNumeric); + editor.putString(NETWORK_SELECTION_NAME_KEY, nsm.operatorAlphaLong); // commit and log the result. if (! editor.commit()) { diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java index db6e33902574..91c089e3c55a 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java @@ -294,12 +294,15 @@ public final class GsmCallTracker extends CallTracker { canDial() { boolean ret; int serviceState = phone.getServiceState().getState(); + String disableCall = SystemProperties.get( + TelephonyProperties.PROPERTY_DISABLE_CALL, "false"); - ret = (serviceState != ServiceState.STATE_POWER_OFF) && - pendingMO == null + ret = (serviceState != ServiceState.STATE_POWER_OFF) + && pendingMO == null && !ringingCall.isRinging() + && !disableCall.equals("true") && (!foregroundCall.getState().isAlive() - || !backgroundCall.getState().isAlive()); + || !backgroundCall.getState().isAlive()); return ret; } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java index 69d36954a885..7e80370110af 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java @@ -630,7 +630,7 @@ public class TestShellActivity extends Activity implements LayoutTestController settings.setDatabaseEnabled(true); settings.setDatabasePath(getDir("databases",0).getAbsolutePath()); settings.setDomStorageEnabled(true); - settings.setWorkersEnabled(true); + settings.setWorkersEnabled(false); webview.addJavascriptInterface(callbackProxy, "layoutTestController"); webview.addJavascriptInterface(callbackProxy, "eventSender"); diff --git a/tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java b/tests/FrameworkTest/tests/src/android/content/ContentProviderOperationTest.java index e9a43d787ffe..1ba9d66a48b0 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.Field; 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 @@ public class ContentProviderOperationTest extends TestCase { 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 @@ public class ContentProviderOperationTest extends TestCase { 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 @@ public class ContentProviderOperationTest extends TestCase { 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 @@ public class ContentProviderOperationTest extends TestCase { 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 @@ public class ContentProviderOperationTest extends TestCase { 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 @@ public class ContentProviderOperationTest extends TestCase { 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 @@ public class ContentProviderOperationTest extends TestCase { 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 fd77d5143d9e..8e7d48f78d96 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 @@ public final class Bridge implements ILayoutBridge { // pass for now. } + public void setWallpaperPosition(IBinder window, float x, float y) { + // pass for now. + } + public IBinder asBinder() { // pass for now. return null; |