diff options
62 files changed, 776 insertions, 454 deletions
diff --git a/CleanSpec.mk b/CleanSpec.mk index 9381437f5dd0..fb334fce090e 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -116,6 +116,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts/DroidSans*) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts/DroidSans*) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/) # ************************************************ # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST # ************************************************ diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index d2facdcc172c..8afe9bf0468e 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -490,6 +490,15 @@ public final class ActivityThread { // Formatting for checkin service - update version if row format changes private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1; + private void updatePendingConfiguration(Configuration config) { + synchronized (mPackages) { + if (mPendingConfiguration == null || + mPendingConfiguration.isOtherSeqNewer(config)) { + mPendingConfiguration = config; + } + } + } + public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges) { queueOrSendMessage( @@ -530,8 +539,8 @@ public final class ActivityThread { // we use token to identify this activity without having to send the // activity itself back to the activity manager. (matters more with ipc) public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, - ActivityInfo info, CompatibilityInfo compatInfo, Bundle state, - List<ResultInfo> pendingResults, + ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, + Bundle state, List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) { ActivityClientRecord r = new ActivityClientRecord(); @@ -553,6 +562,8 @@ public final class ActivityThread { r.profileFd = profileFd; r.autoStopProfiler = autoStopProfiler; + updatePendingConfiguration(curConfig); + queueOrSendMessage(H.LAUNCH_ACTIVITY, r); } @@ -697,12 +708,7 @@ public final class ActivityThread { } public void scheduleConfigurationChanged(Configuration config) { - synchronized (mPackages) { - if (mPendingConfiguration == null || - mPendingConfiguration.isOtherSeqNewer(config)) { - mPendingConfiguration = config; - } - } + updatePendingConfiguration(config); queueOrSendMessage(H.CONFIGURATION_CHANGED, config); } @@ -1966,6 +1972,9 @@ public final class ActivityThread { mProfiler.autoStopProfiler = r.autoStopProfiler; } + // Make sure we are running with the most recent config. + handleConfigurationChanged(null, null); + if (localLOGV) Slog.v( TAG, "Handling launch of " + r); Activity a = performLaunchActivity(r, customIntent); diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index cde06cd891de..c4a4feaff611 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -132,6 +132,7 @@ public abstract class ApplicationThreadNative extends Binder IBinder b = data.readStrongBinder(); int ident = data.readInt(); ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data); + Configuration curConfig = Configuration.CREATOR.createFromParcel(data); CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data); Bundle state = data.readBundle(); List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR); @@ -142,7 +143,7 @@ public abstract class ApplicationThreadNative extends Binder ParcelFileDescriptor profileFd = data.readInt() != 0 ? data.readFileDescriptor() : null; boolean autoStopProfiler = data.readInt() != 0; - scheduleLaunchActivity(intent, b, ident, info, compatInfo, state, ri, pi, + scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, state, ri, pi, notResumed, isForward, profileName, profileFd, autoStopProfiler); return true; } @@ -630,10 +631,10 @@ class ApplicationThreadProxy implements IApplicationThread { } public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, - ActivityInfo info, CompatibilityInfo compatInfo, Bundle state, - List<ResultInfo> pendingResults, - List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, - String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) + ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, + Bundle state, List<ResultInfo> pendingResults, + List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, + String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); @@ -641,6 +642,7 @@ class ApplicationThreadProxy implements IApplicationThread { data.writeStrongBinder(token); data.writeInt(ident); info.writeToParcel(data, 0); + curConfig.writeToParcel(data, 0); compatInfo.writeToParcel(data, 0); data.writeBundle(state); data.writeTypedList(pendingResults); diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java index 5d200b46a4e0..1253fe7896c4 100644 --- a/core/java/android/app/IApplicationThread.java +++ b/core/java/android/app/IApplicationThread.java @@ -53,10 +53,10 @@ public interface IApplicationThread extends IInterface { void scheduleResumeActivity(IBinder token, boolean isForward) throws RemoteException; void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException; void scheduleLaunchActivity(Intent intent, IBinder token, int ident, - ActivityInfo info, CompatibilityInfo compatInfo, Bundle state, - List<ResultInfo> pendingResults, - List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, - String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) + ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, + Bundle state, List<ResultInfo> pendingResults, + List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, + String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) throws RemoteException; void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, int configChanges, diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 8057d4bd260f..e452f1fa3162 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -22,10 +22,6 @@ import android.content.pm.ProviderInfo; import android.content.res.AssetFileDescriptor; import android.content.res.Configuration; import android.database.Cursor; -import android.database.CursorToBulkCursorAdaptor; -import android.database.CursorWindow; -import android.database.IBulkCursor; -import android.database.IContentObserver; import android.database.SQLException; import android.net.Uri; import android.os.AsyncTask; @@ -168,22 +164,9 @@ public abstract class ContentProvider implements ComponentCallbacks2 { return ContentProvider.this; } - /** - * Remote version of a query, which returns an IBulkCursor. The bulk - * cursor should be wrapped with BulkCursorToCursorAdaptor before use. - */ - public IBulkCursor bulkQuery(Uri uri, String[] projection, - String selection, String[] selectionArgs, String sortOrder, - IContentObserver observer, CursorWindow window) { - enforceReadPermission(uri); - Cursor cursor = ContentProvider.this.query(uri, projection, - selection, selectionArgs, sortOrder); - if (cursor == null) { - return null; - } - return new CursorToBulkCursorAdaptor(cursor, observer, - ContentProvider.this.getClass().getName(), - hasWritePermission(uri), window); + @Override + public String getProviderName() { + return getContentProvider().getClass().getName(); } public Cursor query(Uri uri, String[] projection, diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java index 9a20951b8a99..064755e95fbd 100644 --- a/core/java/android/content/ContentProviderNative.java +++ b/core/java/android/content/ContentProviderNative.java @@ -20,6 +20,7 @@ import android.content.res.AssetFileDescriptor; import android.database.BulkCursorNative; import android.database.BulkCursorToCursorAdaptor; import android.database.Cursor; +import android.database.CursorToBulkCursorAdaptor; import android.database.CursorWindow; import android.database.DatabaseUtils; import android.database.IBulkCursor; @@ -65,6 +66,13 @@ abstract public class ContentProviderNative extends Binder implements IContentPr return new ContentProviderProxy(obj); } + /** + * Gets the name of the content provider. + * Should probably be part of the {@link IContentProvider} interface. + * @return The content provider name. + */ + public abstract String getProviderName(); + @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { @@ -98,33 +106,23 @@ abstract public class ContentProviderNative extends Binder implements IContentPr } String sortOrder = data.readString(); - IContentObserver observer = IContentObserver.Stub. - asInterface(data.readStrongBinder()); + IContentObserver observer = IContentObserver.Stub.asInterface( + data.readStrongBinder()); CursorWindow window = CursorWindow.CREATOR.createFromParcel(data); - // Flag for whether caller wants the number of - // rows in the cursor and the position of the - // "_id" column index (or -1 if non-existent) - // Only to be returned if binder != null. - boolean wantsCursorMetadata = data.readInt() != 0; - - IBulkCursor bulkCursor = bulkQuery(url, projection, selection, - selectionArgs, sortOrder, observer, window); - if (bulkCursor != null) { - final IBinder binder = bulkCursor.asBinder(); - if (wantsCursorMetadata) { - final int count = bulkCursor.count(); - final int index = BulkCursorToCursorAdaptor.findRowIdColumnIndex( - bulkCursor.getColumnNames()); - - reply.writeNoException(); - reply.writeStrongBinder(binder); - reply.writeInt(count); - reply.writeInt(index); - } else { - reply.writeNoException(); - reply.writeStrongBinder(binder); - } + Cursor cursor = query(url, projection, selection, selectionArgs, sortOrder); + if (cursor != null) { + CursorToBulkCursorAdaptor adaptor = new CursorToBulkCursorAdaptor( + cursor, observer, getProviderName(), window); + final IBinder binder = adaptor.asBinder(); + final int count = adaptor.count(); + final int index = BulkCursorToCursorAdaptor.findRowIdColumnIndex( + adaptor.getColumnNames()); + + reply.writeNoException(); + reply.writeStrongBinder(binder); + reply.writeInt(count); + reply.writeInt(index); } else { reply.writeNoException(); reply.writeStrongBinder(null); @@ -324,92 +322,70 @@ final class ContentProviderProxy implements IContentProvider return mRemote; } - // Like bulkQuery() but sets up provided 'adaptor' if not null. - private IBulkCursor bulkQueryInternal( - Uri url, String[] projection, - String selection, String[] selectionArgs, String sortOrder, - IContentObserver observer, CursorWindow window, - BulkCursorToCursorAdaptor adaptor) throws RemoteException { - Parcel data = Parcel.obtain(); - Parcel reply = Parcel.obtain(); + public Cursor query(Uri url, String[] projection, String selection, + String[] selectionArgs, String sortOrder) throws RemoteException { + CursorWindow window = new CursorWindow(false /* window will be used remotely */); try { - data.writeInterfaceToken(IContentProvider.descriptor); - - url.writeToParcel(data, 0); - int length = 0; - if (projection != null) { - length = projection.length; - } - data.writeInt(length); - for (int i = 0; i < length; i++) { - data.writeString(projection[i]); - } - data.writeString(selection); - if (selectionArgs != null) { - length = selectionArgs.length; - } else { - length = 0; - } - data.writeInt(length); - for (int i = 0; i < length; i++) { - data.writeString(selectionArgs[i]); - } - data.writeString(sortOrder); - data.writeStrongBinder(observer.asBinder()); - window.writeToParcel(data, 0); - - // Flag for whether or not we want the number of rows in the - // cursor and the position of the "_id" column index (or -1 if - // non-existent). Only to be returned if binder != null. - final boolean wantsCursorMetadata = (adaptor != null); - data.writeInt(wantsCursorMetadata ? 1 : 0); - - mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0); + BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor(); + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + try { + data.writeInterfaceToken(IContentProvider.descriptor); + + url.writeToParcel(data, 0); + int length = 0; + if (projection != null) { + length = projection.length; + } + data.writeInt(length); + for (int i = 0; i < length; i++) { + data.writeString(projection[i]); + } + data.writeString(selection); + if (selectionArgs != null) { + length = selectionArgs.length; + } else { + length = 0; + } + data.writeInt(length); + for (int i = 0; i < length; i++) { + data.writeString(selectionArgs[i]); + } + data.writeString(sortOrder); + data.writeStrongBinder(adaptor.getObserver().asBinder()); + window.writeToParcel(data, 0); - DatabaseUtils.readExceptionFromParcel(reply); + mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0); - IBulkCursor bulkCursor = null; - IBinder bulkCursorBinder = reply.readStrongBinder(); - if (bulkCursorBinder != null) { - bulkCursor = BulkCursorNative.asInterface(bulkCursorBinder); + DatabaseUtils.readExceptionFromParcel(reply); - if (wantsCursorMetadata) { + IBulkCursor bulkCursor = BulkCursorNative.asInterface(reply.readStrongBinder()); + if (bulkCursor != null) { int rowCount = reply.readInt(); int idColumnPosition = reply.readInt(); - if (bulkCursor != null) { - adaptor.set(bulkCursor, rowCount, idColumnPosition); - } + adaptor.initialize(bulkCursor, rowCount, idColumnPosition); + } else { + adaptor.close(); + adaptor = null; } + return adaptor; + } catch (RemoteException ex) { + adaptor.close(); + throw ex; + } catch (RuntimeException ex) { + adaptor.close(); + throw ex; + } finally { + data.recycle(); + reply.recycle(); } - return bulkCursor; } finally { - data.recycle(); - reply.recycle(); - } - } - - public IBulkCursor bulkQuery(Uri url, String[] projection, - String selection, String[] selectionArgs, String sortOrder, IContentObserver observer, - CursorWindow window) throws RemoteException { - return bulkQueryInternal( - url, projection, selection, selectionArgs, sortOrder, - observer, window, - null /* BulkCursorToCursorAdaptor */); - } - - public Cursor query(Uri url, String[] projection, String selection, - String[] selectionArgs, String sortOrder) throws RemoteException { - //TODO make a pool of windows so we can reuse memory dealers - CursorWindow window = new CursorWindow(false /* window will be used remotely */); - BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor(); - IBulkCursor bulkCursor = bulkQueryInternal( - url, projection, selection, selectionArgs, sortOrder, - adaptor.getObserver(), window, - adaptor); - if (bulkCursor == null) { - return null; + // We close the window now because the cursor adaptor does not + // take ownership of the window until the first call to onMove. + // The adaptor will obtain a fresh reference to the window when + // it is filled. + window.close(); } - return adaptor; } public String getType(Uri url) throws RemoteException diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java index 72bc9c2f69f9..2a67ff8dac54 100644 --- a/core/java/android/content/IContentProvider.java +++ b/core/java/android/content/IContentProvider.java @@ -18,9 +18,6 @@ package android.content; import android.content.res.AssetFileDescriptor; import android.database.Cursor; -import android.database.CursorWindow; -import android.database.IBulkCursor; -import android.database.IContentObserver; import android.net.Uri; import android.os.Bundle; import android.os.IBinder; @@ -36,13 +33,6 @@ import java.util.ArrayList; * @hide */ public interface IContentProvider extends IInterface { - /** - * @hide - hide this because return type IBulkCursor and parameter - * IContentObserver are system private classes. - */ - public IBulkCursor bulkQuery(Uri url, String[] projection, - String selection, String[] selectionArgs, String sortOrder, IContentObserver observer, - CursorWindow window) throws RemoteException; public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs, String sortOrder) throws RemoteException; public String getType(Uri url) throws RemoteException; diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index a3bcc287e021..decb974bded8 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -362,4 +362,6 @@ interface IPackageManager { void verifyPendingInstall(int id, int verificationCode); VerifierDeviceIdentity getVerifierDeviceIdentity(); + + boolean isFirstBoot(); } diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java index 3f23b8900c5f..ee6aec6f0d2d 100644 --- a/core/java/android/database/AbstractCursor.java +++ b/core/java/android/database/AbstractCursor.java @@ -78,13 +78,11 @@ public abstract class AbstractCursor implements CrossProcessCursor { } public void deactivate() { - deactivateInternal(); + onDeactivateOrClose(); } - /** - * @hide - */ - public void deactivateInternal() { + /** @hide */ + protected void onDeactivateOrClose() { if (mSelfObserver != null) { mContentResolver.unregisterContentObserver(mSelfObserver); mSelfObserverRegistered = false; @@ -108,7 +106,7 @@ public abstract class AbstractCursor implements CrossProcessCursor { public void close() { mClosed = true; mContentObservable.unregisterAll(); - deactivateInternal(); + onDeactivateOrClose(); } /** diff --git a/core/java/android/database/AbstractWindowedCursor.java b/core/java/android/database/AbstractWindowedCursor.java index bfc8123e07fd..5836265c4945 100644 --- a/core/java/android/database/AbstractWindowedCursor.java +++ b/core/java/android/database/AbstractWindowedCursor.java @@ -19,6 +19,11 @@ package android.database; /** * A base class for Cursors that store their data in {@link CursorWindow}s. * <p> + * The cursor owns the cursor window it uses. When the cursor is closed, + * its window is also closed. Likewise, when the window used by the cursor is + * changed, its old window is closed. This policy of strict ownership ensures + * that cursor windows are not leaked. + * </p><p> * Subclasses are responsible for filling the cursor window with data during * {@link #onMove(int, int)}, allocating a new cursor window if necessary. * During {@link #requery()}, the existing cursor window should be cleared and @@ -180,4 +185,25 @@ public abstract class AbstractWindowedCursor extends AbstractCursor { mWindow = null; } } + + /** + * If there is a window, clear it. + * Otherwise, creates a local window. + * @hide + */ + protected void clearOrCreateLocalWindow() { + if (mWindow == null) { + // If there isn't a window set already it will only be accessed locally + mWindow = new CursorWindow(true /* the window is local only */); + } else { + mWindow.clear(); + } + } + + /** @hide */ + @Override + protected void onDeactivateOrClose() { + super.onDeactivateOrClose(); + closeWindow(); + } } diff --git a/core/java/android/database/BulkCursorNative.java b/core/java/android/database/BulkCursorNative.java index 9925a9ab7c0d..4fada8c2fd29 100644 --- a/core/java/android/database/BulkCursorNative.java +++ b/core/java/android/database/BulkCursorNative.java @@ -62,13 +62,13 @@ public abstract class BulkCursorNative extends Binder implements IBulkCursor data.enforceInterface(IBulkCursor.descriptor); int startPos = data.readInt(); CursorWindow window = getWindow(startPos); + reply.writeNoException(); if (window == null) { reply.writeInt(0); - return true; + } else { + reply.writeInt(1); + window.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } - reply.writeNoException(); - reply.writeInt(1); - window.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); return true; } diff --git a/core/java/android/database/BulkCursorToCursorAdaptor.java b/core/java/android/database/BulkCursorToCursorAdaptor.java index 9c1b26d0a648..cbdd07fb29d3 100644 --- a/core/java/android/database/BulkCursorToCursorAdaptor.java +++ b/core/java/android/database/BulkCursorToCursorAdaptor.java @@ -21,40 +21,24 @@ import android.os.RemoteException; import android.util.Log; /** - * Adapts an {@link IBulkCursor} to a {@link Cursor} for use in the local - * process. + * Adapts an {@link IBulkCursor} to a {@link Cursor} for use in the local process. * * {@hide} */ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { private static final String TAG = "BulkCursor"; - private SelfContentObserver mObserverBridge; + private SelfContentObserver mObserverBridge = new SelfContentObserver(this); private IBulkCursor mBulkCursor; private int mCount; private String[] mColumns; private boolean mWantsAllOnMoveCalls; - public void set(IBulkCursor bulkCursor) { - mBulkCursor = bulkCursor; - - try { - mCount = mBulkCursor.count(); - mWantsAllOnMoveCalls = mBulkCursor.getWantsAllOnMoveCalls(); - - // Search for the rowID column index and set it for our parent - mColumns = mBulkCursor.getColumnNames(); - mRowIdColumnIndex = findRowIdColumnIndex(mColumns); - } catch (RemoteException ex) { - Log.e(TAG, "Setup failed because the remote process is dead"); - } - } - /** - * Version of set() that does fewer Binder calls if the caller - * already knows BulkCursorToCursorAdaptor's properties. + * Initializes the adaptor. + * Must be called before first use. */ - public void set(IBulkCursor bulkCursor, int count, int idIndex) { + public void initialize(IBulkCursor bulkCursor, int count, int idIndex) { mBulkCursor = bulkCursor; mColumns = null; // lazily retrieved mCount = count; @@ -80,31 +64,37 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { * * @return A SelfContentObserver hooked up to this Cursor */ - public synchronized IContentObserver getObserver() { - if (mObserverBridge == null) { - mObserverBridge = new SelfContentObserver(this); - } + public IContentObserver getObserver() { return mObserverBridge.getContentObserver(); } + private void throwIfCursorIsClosed() { + if (mBulkCursor == null) { + throw new StaleDataException("Attempted to access a cursor after it has been closed."); + } + } + @Override public int getCount() { + throwIfCursorIsClosed(); return mCount; } @Override public boolean onMove(int oldPosition, int newPosition) { + throwIfCursorIsClosed(); + try { // Make sure we have the proper window if (mWindow != null) { if (newPosition < mWindow.getStartPosition() || newPosition >= (mWindow.getStartPosition() + mWindow.getNumRows())) { - mWindow = mBulkCursor.getWindow(newPosition); + setWindow(mBulkCursor.getWindow(newPosition)); } else if (mWantsAllOnMoveCalls) { mBulkCursor.onMove(newPosition); } } else { - mWindow = mBulkCursor.getWindow(newPosition); + setWindow(mBulkCursor.getWindow(newPosition)); } } catch (RemoteException ex) { // We tried to get a window and failed @@ -126,44 +116,54 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { // which is what actually makes the data set invalid. super.deactivate(); - try { - mBulkCursor.deactivate(); - } catch (RemoteException ex) { - Log.w(TAG, "Remote process exception when deactivating"); + if (mBulkCursor != null) { + try { + mBulkCursor.deactivate(); + } catch (RemoteException ex) { + Log.w(TAG, "Remote process exception when deactivating"); + } } - mWindow = null; } @Override public void close() { super.close(); - try { - mBulkCursor.close(); - } catch (RemoteException ex) { - Log.w(TAG, "Remote process exception when closing"); + + if (mBulkCursor != null) { + try { + mBulkCursor.close(); + } catch (RemoteException ex) { + Log.w(TAG, "Remote process exception when closing"); + } finally { + mBulkCursor = null; + } } - mWindow = null; } @Override public boolean requery() { + throwIfCursorIsClosed(); + try { - int oldCount = mCount; - //TODO get the window from a pool somewhere to avoid creating the memory dealer - mCount = mBulkCursor.requery(getObserver(), new CursorWindow( - false /* the window will be accessed across processes */)); - if (mCount != -1) { - mPos = -1; - closeWindow(); - - // super.requery() will call onChanged. Do it here instead of relying on the - // observer from the far side so that observers can see a correct value for mCount - // when responding to onChanged. - super.requery(); - return true; - } else { - deactivate(); - return false; + CursorWindow newWindow = new CursorWindow(false /* create a remote window */); + try { + mCount = mBulkCursor.requery(getObserver(), newWindow); + if (mCount != -1) { + mPos = -1; + closeWindow(); + + // super.requery() will call onChanged. Do it here instead of relying on the + // observer from the far side so that observers can see a correct value for mCount + // when responding to onChanged. + super.requery(); + return true; + } else { + deactivate(); + return false; + } + } finally { + // Don't take ownership of the window until the next call to onMove. + newWindow.close(); } } catch (Exception ex) { Log.e(TAG, "Unable to requery because the remote process exception " + ex.getMessage()); @@ -174,6 +174,8 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { @Override public String[] getColumnNames() { + throwIfCursorIsClosed(); + if (mColumns == null) { try { mColumns = mBulkCursor.getColumnNames(); @@ -187,6 +189,8 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { @Override public Bundle getExtras() { + throwIfCursorIsClosed(); + try { return mBulkCursor.getExtras(); } catch (RemoteException e) { @@ -198,6 +202,8 @@ public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor { @Override public Bundle respond(Bundle extras) { + throwIfCursorIsClosed(); + try { return mBulkCursor.respond(extras); } catch (RemoteException e) { diff --git a/core/java/android/database/CrossProcessCursor.java b/core/java/android/database/CrossProcessCursor.java index 77ba3a54463a..8e6a5aa01598 100644 --- a/core/java/android/database/CrossProcessCursor.java +++ b/core/java/android/database/CrossProcessCursor.java @@ -16,7 +16,7 @@ package android.database; -public interface CrossProcessCursor extends Cursor{ +public interface CrossProcessCursor extends Cursor { /** * returns a pre-filled window, return NULL if no such window */ diff --git a/core/java/android/database/CursorToBulkCursorAdaptor.java b/core/java/android/database/CursorToBulkCursorAdaptor.java index 8fa4d3b5414d..a65b3b304558 100644 --- a/core/java/android/database/CursorToBulkCursorAdaptor.java +++ b/core/java/android/database/CursorToBulkCursorAdaptor.java @@ -24,19 +24,37 @@ import android.util.Log; /** * Wraps a BulkCursor around an existing Cursor making it remotable. + * <p> + * If the wrapped cursor is a {@link AbstractWindowedCursor} then it owns + * the cursor window. Otherwise, the adaptor takes ownership of the + * cursor itself and ensures it gets closed as needed during deactivation + * and requeries. + * </p> * * {@hide} */ public final class CursorToBulkCursorAdaptor extends BulkCursorNative implements IBinder.DeathRecipient { private static final String TAG = "Cursor"; - private final CrossProcessCursor mCursor; - private CursorWindow mWindow; + + private final Object mLock = new Object(); private final String mProviderName; private ContentObserverProxy mObserver; - private static final class ContentObserverProxy extends ContentObserver - { + /** + * The cursor that is being adapted. + * This field is set to null when the cursor is closed. + */ + private CrossProcessCursor mCursor; + + /** + * The cursor window used by the cross process cursor. + * This field is always null for abstract windowed cursors since they are responsible + * for managing the lifetime of their window. + */ + private CursorWindow mWindowForNonWindowedCursor; + + private static final class ContentObserverProxy extends ContentObserver { protected IContentObserver mRemote; public ContentObserverProxy(IContentObserver remoteObserver, DeathRecipient recipient) { @@ -70,7 +88,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer, String providerName, - boolean allowWrite, CursorWindow window) { + CursorWindow window) { try { mCursor = (CrossProcessCursor) cursor; if (mCursor instanceof AbstractWindowedCursor) { @@ -81,90 +99,167 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative + providerName, new RuntimeException()); } } - windowedCursor.setWindow(window); + windowedCursor.setWindow(window); // cursor takes ownership of window } else { - mWindow = window; + mWindowForNonWindowedCursor = window; // we own the window mCursor.fillWindow(0, window); } } catch (ClassCastException e) { // TODO Implement this case. + window.close(); throw new UnsupportedOperationException( "Only CrossProcessCursor cursors are supported across process for now", e); } mProviderName = providerName; - createAndRegisterObserverProxy(observer); + synchronized (mLock) { + createAndRegisterObserverProxyLocked(observer); + } } - + + private void closeCursorAndWindowLocked() { + if (mCursor != null) { + unregisterObserverProxyLocked(); + mCursor.close(); + mCursor = null; + } + + if (mWindowForNonWindowedCursor != null) { + mWindowForNonWindowedCursor.close(); + mWindowForNonWindowedCursor = null; + } + } + + private void throwIfCursorIsClosed() { + if (mCursor == null) { + throw new StaleDataException("Attempted to access a cursor after it has been closed."); + } + } + + @Override public void binderDied() { - mCursor.close(); - if (mWindow != null) { - mWindow.close(); + synchronized (mLock) { + closeCursorAndWindowLocked(); } } - + + @Override public CursorWindow getWindow(int startPos) { - mCursor.moveToPosition(startPos); - - if (mWindow != null) { - if (startPos < mWindow.getStartPosition() || - startPos >= (mWindow.getStartPosition() + mWindow.getNumRows())) { - mCursor.fillWindow(startPos, mWindow); - } - return mWindow; - } else { - return ((AbstractWindowedCursor)mCursor).getWindow(); + synchronized (mLock) { + throwIfCursorIsClosed(); + + mCursor.moveToPosition(startPos); + + final CursorWindow window; + if (mCursor instanceof AbstractWindowedCursor) { + window = ((AbstractWindowedCursor)mCursor).getWindow(); + } else { + window = mWindowForNonWindowedCursor; + if (window != null + && (startPos < window.getStartPosition() || + startPos >= (window.getStartPosition() + window.getNumRows()))) { + mCursor.fillWindow(startPos, window); + } + } + + // Acquire a reference before returning from this RPC. + // The Binder proxy will decrement the reference count again as part of writing + // the CursorWindow to the reply parcel as a return value. + if (window != null) { + window.acquireReference(); + } + return window; } } + @Override public void onMove(int position) { - mCursor.onMove(mCursor.getPosition(), position); + synchronized (mLock) { + throwIfCursorIsClosed(); + + mCursor.onMove(mCursor.getPosition(), position); + } } + @Override public int count() { - return mCursor.getCount(); + synchronized (mLock) { + throwIfCursorIsClosed(); + + return mCursor.getCount(); + } } + @Override public String[] getColumnNames() { - return mCursor.getColumnNames(); + synchronized (mLock) { + throwIfCursorIsClosed(); + + return mCursor.getColumnNames(); + } } + @Override public void deactivate() { - maybeUnregisterObserverProxy(); - mCursor.deactivate(); + synchronized (mLock) { + if (mCursor != null) { + unregisterObserverProxyLocked(); + mCursor.deactivate(); + } + } } + @Override public void close() { - maybeUnregisterObserverProxy(); - mCursor.close(); + synchronized (mLock) { + closeCursorAndWindowLocked(); + } } + @Override public int requery(IContentObserver observer, CursorWindow window) { - if (mWindow == null) { - ((AbstractWindowedCursor)mCursor).setWindow(window); - } - try { - if (!mCursor.requery()) { - return -1; + synchronized (mLock) { + throwIfCursorIsClosed(); + + if (mCursor instanceof AbstractWindowedCursor) { + ((AbstractWindowedCursor) mCursor).setWindow(window); + } else { + if (mWindowForNonWindowedCursor != null) { + mWindowForNonWindowedCursor.close(); + } + mWindowForNonWindowedCursor = window; } - } catch (IllegalStateException e) { - IllegalStateException leakProgram = new IllegalStateException( - mProviderName + " Requery misuse db, mCursor isClosed:" + - mCursor.isClosed(), e); - throw leakProgram; - } - - if (mWindow != null) { - mCursor.fillWindow(0, window); - mWindow = window; + + try { + if (!mCursor.requery()) { + return -1; + } + } catch (IllegalStateException e) { + IllegalStateException leakProgram = new IllegalStateException( + mProviderName + " Requery misuse db, mCursor isClosed:" + + mCursor.isClosed(), e); + throw leakProgram; + } + + if (!(mCursor instanceof AbstractWindowedCursor)) { + if (window != null) { + mCursor.fillWindow(0, window); + } + } + + unregisterObserverProxyLocked(); + createAndRegisterObserverProxyLocked(observer); + return mCursor.getCount(); } - maybeUnregisterObserverProxy(); - createAndRegisterObserverProxy(observer); - return mCursor.getCount(); } + @Override public boolean getWantsAllOnMoveCalls() { - return mCursor.getWantsAllOnMoveCalls(); + synchronized (mLock) { + throwIfCursorIsClosed(); + + return mCursor.getWantsAllOnMoveCalls(); + } } /** @@ -173,7 +268,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative * @param observer the IContentObserver that wants to monitor the cursor * @throws IllegalStateException if an observer is already registered */ - private void createAndRegisterObserverProxy(IContentObserver observer) { + private void createAndRegisterObserverProxyLocked(IContentObserver observer) { if (mObserver != null) { throw new IllegalStateException("an observer is already registered"); } @@ -182,7 +277,7 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } /** Unregister the observer if it is already registered. */ - private void maybeUnregisterObserverProxy() { + private void unregisterObserverProxyLocked() { if (mObserver != null) { mCursor.unregisterContentObserver(mObserver); mObserver.unlinkToDeath(this); @@ -190,11 +285,21 @@ public final class CursorToBulkCursorAdaptor extends BulkCursorNative } } + @Override public Bundle getExtras() { - return mCursor.getExtras(); + synchronized (mLock) { + throwIfCursorIsClosed(); + + return mCursor.getExtras(); + } } + @Override public Bundle respond(Bundle extras) { - return mCursor.respond(extras); + synchronized (mLock) { + throwIfCursorIsClosed(); + + return mCursor.respond(extras); + } } } diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java index 2e3ef286fe80..5a91b80034e4 100644 --- a/core/java/android/database/CursorWindow.java +++ b/core/java/android/database/CursorWindow.java @@ -16,6 +16,8 @@ package android.database; +import dalvik.system.CloseGuard; + import android.content.res.Resources; import android.database.sqlite.SQLiteClosable; import android.database.sqlite.SQLiteException; @@ -48,6 +50,8 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { private int mStartPos; + private final CloseGuard mCloseGuard = CloseGuard.get(); + private static native int nativeInitializeEmpty(int cursorWindowSize, boolean localOnly); private static native int nativeInitializeFromBinder(IBinder nativeBinder); private static native void nativeDispose(int windowPtr); @@ -91,6 +95,7 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { throw new CursorWindowAllocationException("Cursor window allocation of " + (sCursorWindowSize / 1024) + " kb failed. " + printStats()); } + mCloseGuard.open("close"); recordNewWindow(Binder.getCallingPid(), mWindowPtr); } @@ -102,11 +107,15 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { throw new CursorWindowAllocationException("Cursor window could not be " + "created from binder."); } + mCloseGuard.open("close"); } @Override protected void finalize() throws Throwable { try { + if (mCloseGuard != null) { + mCloseGuard.warnIfOpen(); + } dispose(); } finally { super.finalize(); @@ -114,6 +123,9 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { } private void dispose() { + if (mCloseGuard != null) { + mCloseGuard.close(); + } if (mWindowPtr != 0) { recordClosingOfWindow(mWindowPtr); nativeDispose(mWindowPtr); @@ -677,6 +689,10 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeStrongBinder(nativeGetBinder(mWindowPtr)); dest.writeInt(mStartPos); + + if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { + releaseReference(); + } } @Override diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java index 81fe8241106a..9d7e15201be5 100644 --- a/core/java/android/database/sqlite/SQLiteCursor.java +++ b/core/java/android/database/sqlite/SQLiteCursor.java @@ -89,8 +89,6 @@ public class SQLiteCursor extends AbstractWindowedCursor { * @param query the {@link SQLiteQuery} object associated with this cursor object. */ public SQLiteCursor(SQLiteCursorDriver driver, String editTable, SQLiteQuery query) { - // The AbstractCursor constructor needs to do some setup. - super(); if (query == null) { throw new IllegalArgumentException("query object cannot be null"); } @@ -157,12 +155,7 @@ public class SQLiteCursor extends AbstractWindowedCursor { } private void fillWindow(int startPos) { - if (mWindow == null) { - // If there isn't a window set already it will only be accessed locally - mWindow = new CursorWindow(true /* the window is local only */); - } else { - mWindow.clear(); - } + clearOrCreateLocalWindow(); mWindow.setStartPosition(startPos); int count = getQuery().fillWindow(mWindow); if (startPos == 0) { // fillWindow returns count(*) only for startPos = 0 @@ -214,16 +207,9 @@ public class SQLiteCursor extends AbstractWindowedCursor { return mColumns; } - private void deactivateCommon() { - if (false) Log.v(TAG, "<<< Releasing cursor " + this); - closeWindow(); - if (false) Log.v("DatabaseWindow", "closing window in release()"); - } - @Override public void deactivate() { super.deactivate(); - deactivateCommon(); mDriver.cursorDeactivated(); } @@ -231,7 +217,6 @@ public class SQLiteCursor extends AbstractWindowedCursor { public void close() { super.close(); synchronized (this) { - deactivateCommon(); mQuery.close(); mDriver.cursorClosed(); } diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java index aaad8a1c7a98..1b24f0c7b35f 100644 --- a/core/java/android/net/NetworkPolicy.java +++ b/core/java/android/net/NetworkPolicy.java @@ -40,6 +40,8 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> { public long limitBytes; public long lastSnooze; + private static final long DEFAULT_MTU = 1500; + public NetworkPolicy(NetworkTemplate template, int cycleDay, long warningBytes, long limitBytes, long lastSnooze) { this.template = checkNotNull(template, "missing NetworkTemplate"); @@ -71,6 +73,17 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> { return 0; } + /** + * Test if given measurement is near enough to {@link #limitBytes} to be + * considered over-limit. + */ + public boolean isOverLimit(long totalBytes) { + // over-estimate, since kernel will trigger limit once first packet + // trips over limit. + totalBytes += 2 * DEFAULT_MTU; + return limitBytes != LIMIT_DISABLED && totalBytes >= limitBytes; + } + /** {@inheritDoc} */ public int compareTo(NetworkPolicy another) { if (another == null || another.limitBytes == LIMIT_DISABLED) { diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index d57132aef84d..169738257b3b 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -502,9 +502,23 @@ public class TextureView extends View { * @see #isAvailable() * @see #getBitmap(int, int) * @see #getBitmap() + * + * @throws IllegalStateException if the hardware rendering context cannot be + * acquired to capture the bitmap */ public Bitmap getBitmap(Bitmap bitmap) { if (bitmap != null && isAvailable()) { + AttachInfo info = mAttachInfo; + if (info != null && info.mHardwareRenderer != null && + info.mHardwareRenderer.isEnabled()) { + if (!info.mHardwareRenderer.validate()) { + throw new IllegalStateException("Could not acquire hardware rendering context"); + } + } + + applyUpdate(); + applyTransformMatrix(); + mLayer.copyInto(bitmap); } return bitmap; diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 15544ccc4887..86be28a534da 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -1486,7 +1486,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal | AccessibilityEvent.TYPE_VIEW_FOCUSED | AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED | AccessibilityEvent.TYPE_VIEW_HOVER_ENTER - | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT; + | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT + | AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED; /** * Temporary Rect currently for use in setBackground(). This will probably @@ -10125,6 +10126,14 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal return mHardwareLayer; } + /** + * Destroys this View's hardware layer if possible. + * + * @return True if the layer was destroyed, false otherwise. + * + * @see #setLayerType(int, android.graphics.Paint) + * @see #LAYER_TYPE_HARDWARE + */ boolean destroyLayer() { if (mHardwareLayer != null) { mHardwareLayer.destroy(); diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java index 25bc559e94e3..86dd9df0cb0a 100644 --- a/core/java/android/view/accessibility/AccessibilityEvent.java +++ b/core/java/android/view/accessibility/AccessibilityEvent.java @@ -200,15 +200,6 @@ import java.util.List; * <li>{@link #getBeforeText()} - The text of the source before the change.</li> * <li>{@link #getContentDescription()} - The content description of the source.</li> * </ul> - * <em>Note:</em> This event type is not dispatched to descendants though - * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) - * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event - * source {@link android.view.View} and the sub-tree rooted at it will not receive - * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent) - * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add - * text content to such events is by setting the - * {@link android.R.styleable#View_contentDescription contentDescription} of the source - * view.</br> * </p> * <p> * <b>View text selection changed</b> - represents the event of changing the text diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index f46af5137661..6d19c23fd2cb 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -2074,7 +2074,8 @@ public class WebView extends AbsoluteLayout * If the value of the encoding parameter is 'base64', then the data must * be encoded as base64. Otherwise, the data must use ASCII encoding for * octets inside the range of safe URL characters and use the standard %xx - * hex encoding of URLs for octets outside that range. + * hex encoding of URLs for octets outside that range. For example, + * '#', '%', '\', '?' should be replaced by %23, %25, %27, %3f respectively. * <p> * The 'data' scheme URL formed by this method uses the default US-ASCII * charset. If you need need to set a different charset, you should form a @@ -7415,6 +7416,10 @@ public class WebView extends AbsoluteLayout } } + void sendPluginDrawMsg() { + mWebViewCore.sendMessage(EventHub.PLUGIN_SURFACE_READY); + } + /** * Returns plugin bounds if x/y in content coordinates corresponds to a * plugin. Otherwise a NULL rectangle is returned. diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 44688b8bd2be..1294a28df190 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -1032,6 +1032,8 @@ public final class WebViewCore { static final int EXECUTE_JS = 194; + static final int PLUGIN_SURFACE_READY = 195; + // private message ids private static final int DESTROY = 200; @@ -1587,6 +1589,10 @@ public final class WebViewCore { nativeFullScreenPluginHidden(msg.arg1); break; + case PLUGIN_SURFACE_READY: + nativePluginSurfaceReady(); + break; + case ADD_PACKAGE_NAMES: if (BrowserFrame.sJavaBridge == null) { throw new IllegalStateException("No WebView " + @@ -2826,6 +2832,7 @@ public final class WebViewCore { private native void nativeResume(); private native void nativeFreeMemory(); private native void nativeFullScreenPluginHidden(int npp); + private native void nativePluginSurfaceReady(); private native boolean nativeValidNodeAndBounds(int frame, int node, Rect bounds); diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java index 62b078fb5df5..510e2d4cb488 100644 --- a/core/java/android/widget/SpellChecker.java +++ b/core/java/android/widget/SpellChecker.java @@ -44,7 +44,6 @@ public class SpellChecker implements SpellCheckerSessionListener { private final static int MAX_SPELL_BATCH_SIZE = 50; private final TextView mTextView; - private final Editable mText; final SpellCheckerSession mSpellCheckerSession; final int mCookie; @@ -64,7 +63,6 @@ public class SpellChecker implements SpellCheckerSessionListener { public SpellChecker(TextView textView) { mTextView = textView; - mText = (Editable) textView.getText(); final TextServicesManager textServicesManager = (TextServicesManager) textView.getContext(). getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE); @@ -121,9 +119,9 @@ public class SpellChecker implements SpellCheckerSessionListener { return mLength - 1; } - private void addSpellCheckSpan(int start, int end) { + private void addSpellCheckSpan(Editable editable, int start, int end) { final int index = nextSpellCheckSpanIndex(); - mText.setSpan(mSpellCheckSpans[index], start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + editable.setSpan(mSpellCheckSpans[index], start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); mIds[index] = mSpanSequenceCounter++; } @@ -168,8 +166,9 @@ public class SpellChecker implements SpellCheckerSessionListener { private void spellCheck() { if (mSpellCheckerSession == null) return; - final int selectionStart = Selection.getSelectionStart(mText); - final int selectionEnd = Selection.getSelectionEnd(mText); + Editable editable = (Editable) mTextView.getText(); + final int selectionStart = Selection.getSelectionStart(editable); + final int selectionEnd = Selection.getSelectionEnd(editable); TextInfo[] textInfos = new TextInfo[mLength]; int textInfosCount = 0; @@ -178,12 +177,12 @@ public class SpellChecker implements SpellCheckerSessionListener { final SpellCheckSpan spellCheckSpan = mSpellCheckSpans[i]; if (spellCheckSpan.isSpellCheckInProgress()) continue; - final int start = mText.getSpanStart(spellCheckSpan); - final int end = mText.getSpanEnd(spellCheckSpan); + final int start = editable.getSpanStart(spellCheckSpan); + final int end = editable.getSpanEnd(spellCheckSpan); // Do not check this word if the user is currently editing it if (start >= 0 && end > start && (selectionEnd < start || selectionStart > end)) { - final String word = mText.subSequence(start, end).toString(); + final String word = editable.subSequence(start, end).toString(); spellCheckSpan.setSpellCheckInProgress(true); textInfos[textInfosCount++] = new TextInfo(word, mCookie, mIds[i]); } @@ -202,6 +201,8 @@ public class SpellChecker implements SpellCheckerSessionListener { @Override public void onGetSuggestions(SuggestionsInfo[] results) { + Editable editable = (Editable) mTextView.getText(); + for (int i = 0; i < results.length; i++) { SuggestionsInfo suggestionsInfo = results[i]; if (suggestionsInfo.getCookie() != mCookie) continue; @@ -217,9 +218,9 @@ public class SpellChecker implements SpellCheckerSessionListener { SpellCheckSpan spellCheckSpan = mSpellCheckSpans[j]; if (!isInDictionary && looksLikeTypo) { - createMisspelledSuggestionSpan(suggestionsInfo, spellCheckSpan); + createMisspelledSuggestionSpan(editable, suggestionsInfo, spellCheckSpan); } - mText.removeSpan(spellCheckSpan); + editable.removeSpan(spellCheckSpan); break; } } @@ -234,18 +235,18 @@ public class SpellChecker implements SpellCheckerSessionListener { } } - private void createMisspelledSuggestionSpan(SuggestionsInfo suggestionsInfo, - SpellCheckSpan spellCheckSpan) { - final int start = mText.getSpanStart(spellCheckSpan); - final int end = mText.getSpanEnd(spellCheckSpan); + private void createMisspelledSuggestionSpan(Editable editable, + SuggestionsInfo suggestionsInfo, SpellCheckSpan spellCheckSpan) { + final int start = editable.getSpanStart(spellCheckSpan); + final int end = editable.getSpanEnd(spellCheckSpan); // Other suggestion spans may exist on that region, with identical suggestions, filter // them out to avoid duplicates. First, filter suggestion spans on that exact region. - SuggestionSpan[] suggestionSpans = mText.getSpans(start, end, SuggestionSpan.class); + SuggestionSpan[] suggestionSpans = editable.getSpans(start, end, SuggestionSpan.class); final int length = suggestionSpans.length; for (int i = 0; i < length; i++) { - final int spanStart = mText.getSpanStart(suggestionSpans[i]); - final int spanEnd = mText.getSpanEnd(suggestionSpans[i]); + final int spanStart = editable.getSpanStart(suggestionSpans[i]); + final int spanEnd = editable.getSpanEnd(suggestionSpans[i]); if (spanStart != start || spanEnd != end) { suggestionSpans[i] = null; break; @@ -293,7 +294,7 @@ public class SpellChecker implements SpellCheckerSessionListener { SuggestionSpan suggestionSpan = new SuggestionSpan(mTextView.getContext(), suggestions, SuggestionSpan.FLAG_EASY_CORRECT | SuggestionSpan.FLAG_MISSPELLED); - mText.setSpan(suggestionSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + editable.setSpan(suggestionSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // TODO limit to the word rectangle region mTextView.invalidate(); @@ -304,22 +305,24 @@ public class SpellChecker implements SpellCheckerSessionListener { private Object mRange = new Object(); public void init(int start, int end) { - mText.setSpan(mRange, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + ((Editable) mTextView.getText()).setSpan(mRange, start, end, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } public void close() { - mText.removeSpan(mRange); + ((Editable) mTextView.getText()).removeSpan(mRange); } public boolean isDone() { - return mText.getSpanStart(mRange) < 0; + return ((Editable) mTextView.getText()).getSpanStart(mRange) < 0; } public void parse() { + Editable editable = (Editable) mTextView.getText(); // Iterate over the newly added text and schedule new SpellCheckSpans - final int start = mText.getSpanStart(mRange); - final int end = mText.getSpanEnd(mRange); - mWordIterator.setCharSequence(mText, start, end); + final int start = editable.getSpanStart(mRange); + final int end = editable.getSpanEnd(mRange); + mWordIterator.setCharSequence(editable, start, end); // Move back to the beginning of the current word, if any int wordStart = mWordIterator.preceding(start); @@ -333,14 +336,16 @@ public class SpellChecker implements SpellCheckerSessionListener { wordEnd = mWordIterator.getEnd(wordStart); } if (wordEnd == BreakIterator.DONE) { - mText.removeSpan(mRange); + editable.removeSpan(mRange); return; } // We need to expand by one character because we want to include the spans that // end/start at position start/end respectively. - SpellCheckSpan[] spellCheckSpans = mText.getSpans(start-1, end+1, SpellCheckSpan.class); - SuggestionSpan[] suggestionSpans = mText.getSpans(start-1, end+1, SuggestionSpan.class); + SpellCheckSpan[] spellCheckSpans = editable.getSpans(start - 1, end + 1, + SpellCheckSpan.class); + SuggestionSpan[] suggestionSpans = editable.getSpans(start - 1, end + 1, + SuggestionSpan.class); int nbWordsChecked = 0; boolean scheduleOtherSpellCheck = false; @@ -350,20 +355,20 @@ public class SpellChecker implements SpellCheckerSessionListener { // A new word has been created across the interval boundaries with this edit. // Previous spans (ended on start / started on end) removed, not valid anymore if (wordStart < start && wordEnd > start) { - removeSpansAt(start, spellCheckSpans); - removeSpansAt(start, suggestionSpans); + removeSpansAt(editable, start, spellCheckSpans); + removeSpansAt(editable, start, suggestionSpans); } if (wordStart < end && wordEnd > end) { - removeSpansAt(end, spellCheckSpans); - removeSpansAt(end, suggestionSpans); + removeSpansAt(editable, end, spellCheckSpans); + removeSpansAt(editable, end, suggestionSpans); } // Do not create new boundary spans if they already exist boolean createSpellCheckSpan = true; if (wordEnd == start) { for (int i = 0; i < spellCheckSpans.length; i++) { - final int spanEnd = mText.getSpanEnd(spellCheckSpans[i]); + final int spanEnd = editable.getSpanEnd(spellCheckSpans[i]); if (spanEnd == start) { createSpellCheckSpan = false; break; @@ -373,7 +378,7 @@ public class SpellChecker implements SpellCheckerSessionListener { if (wordStart == end) { for (int i = 0; i < spellCheckSpans.length; i++) { - final int spanStart = mText.getSpanStart(spellCheckSpans[i]); + final int spanStart = editable.getSpanStart(spellCheckSpans[i]); if (spanStart == end) { createSpellCheckSpan = false; break; @@ -386,7 +391,7 @@ public class SpellChecker implements SpellCheckerSessionListener { scheduleOtherSpellCheck = true; break; } - addSpellCheckSpan(wordStart, wordEnd); + addSpellCheckSpan(editable, wordStart, wordEnd); nbWordsChecked++; } } @@ -401,23 +406,23 @@ public class SpellChecker implements SpellCheckerSessionListener { } if (scheduleOtherSpellCheck) { - mText.setSpan(mRange, wordStart, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + editable.setSpan(mRange, wordStart, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } else { - mText.removeSpan(mRange); + editable.removeSpan(mRange); } spellCheck(); } - private <T> void removeSpansAt(int offset, T[] spans) { + private <T> void removeSpansAt(Editable editable, int offset, T[] spans) { final int length = spans.length; for (int i = 0; i < length; i++) { final T span = spans[i]; - final int start = mText.getSpanStart(span); + final int start = editable.getSpanStart(span); if (start > offset) continue; - final int end = mText.getSpanEnd(span); + final int end = editable.getSpanEnd(span); if (end < offset) continue; - mText.removeSpan(span); + editable.removeSpan(span); } } } diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java index daabf425a461..77d0c97bbf62 100644 --- a/core/java/com/android/internal/app/ShutdownThread.java +++ b/core/java/com/android/internal/app/ShutdownThread.java @@ -109,7 +109,6 @@ public final class ShutdownThread extends Thread { if (confirm) { final CloseDialogReceiver closer = new CloseDialogReceiver(context); final AlertDialog dialog = new AlertDialog.Builder(context) - .setIconAttribute(android.R.attr.alertDialogIcon) .setTitle(com.android.internal.R.string.power_off) .setMessage(resourceId) .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() { diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java index 97bbe5218b70..5b49bffd8f02 100644 --- a/core/java/com/android/internal/widget/LockPatternView.java +++ b/core/java/com/android/internal/widget/LockPatternView.java @@ -17,8 +17,6 @@ package com.android.internal.widget; -import com.android.internal.R; - import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -39,6 +37,10 @@ import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager; + +import com.android.internal.R; import java.util.ArrayList; import java.util.List; @@ -401,6 +403,34 @@ public class LockPatternView extends View { invalidate(); } + private void notifyCellAdded() { + if (mOnPatternListener != null) { + mOnPatternListener.onPatternCellAdded(mPattern); + } + sendAccessEvent(R.string.lockscreen_access_pattern_cell_added); + } + + private void notifyPatternStarted() { + if (mOnPatternListener != null) { + mOnPatternListener.onPatternStart(); + } + sendAccessEvent(R.string.lockscreen_access_pattern_start); + } + + private void notifyPatternDetected() { + if (mOnPatternListener != null) { + mOnPatternListener.onPatternDetected(mPattern); + } + sendAccessEvent(R.string.lockscreen_access_pattern_detected); + } + + private void notifyPatternCleared() { + if (mOnPatternListener != null) { + mOnPatternListener.onPatternCleared(); + } + sendAccessEvent(R.string.lockscreen_access_pattern_cleared); + } + /** * Clear the pattern. */ @@ -554,9 +584,7 @@ public class LockPatternView extends View { private void addCellToPattern(Cell newCell) { mPatternDrawLookup[newCell.getRow()][newCell.getColumn()] = true; mPattern.add(newCell); - if (mOnPatternListener != null) { - mOnPatternListener.onPatternCellAdded(mPattern); - } + notifyCellAdded(); } // helper method to find which cell a point maps to @@ -619,6 +647,27 @@ public class LockPatternView extends View { } @Override + public boolean onHoverEvent(MotionEvent event) { + if (AccessibilityManager.getInstance(mContext).isTouchExplorationEnabled()) { + final int action = event.getAction(); + switch (action) { + case MotionEvent.ACTION_HOVER_ENTER: + event.setAction(MotionEvent.ACTION_DOWN); + break; + case MotionEvent.ACTION_HOVER_MOVE: + event.setAction(MotionEvent.ACTION_MOVE); + break; + case MotionEvent.ACTION_HOVER_EXIT: + event.setAction(MotionEvent.ACTION_UP); + break; + } + onTouchEvent(event); + event.setAction(action); + } + return super.onHoverEvent(event); + } + + @Override public boolean onTouchEvent(MotionEvent event) { if (!mInputEnabled || !isEnabled()) { return false; @@ -636,10 +685,8 @@ public class LockPatternView extends View { return true; case MotionEvent.ACTION_CANCEL: resetPattern(); - if (mOnPatternListener != null) { - mPatternInProgress = false; - mOnPatternListener.onPatternCleared(); - } + mPatternInProgress = false; + notifyPatternCleared(); if (PROFILE_DRAWING) { if (mDrawingProfilingStarted) { Debug.stopMethodTracing(); @@ -661,9 +708,9 @@ public class LockPatternView extends View { final int patternSizePreHitDetect = mPattern.size(); Cell hitCell = detectAndAddHit(x, y); final int patternSize = mPattern.size(); - if (hitCell != null && (mOnPatternListener != null) && (patternSize == 1)) { + if (hitCell != null && patternSize == 1) { mPatternInProgress = true; - mOnPatternListener.onPatternStart(); + notifyPatternStarted(); } // note current x and y for rubber banding of in progress patterns final float dx = Math.abs(x - mInProgressX); @@ -778,11 +825,17 @@ public class LockPatternView extends View { } } + private void sendAccessEvent(int resId) { + setContentDescription(mContext.getString(resId)); + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); + setContentDescription(null); + } + private void handleActionUp(MotionEvent event) { // report pattern detected - if (!mPattern.isEmpty() && mOnPatternListener != null) { + if (!mPattern.isEmpty()) { mPatternInProgress = false; - mOnPatternListener.onPatternDetected(mPattern); + notifyPatternDetected(); invalidate(); } if (PROFILE_DRAWING) { @@ -798,13 +851,13 @@ public class LockPatternView extends View { final float x = event.getX(); final float y = event.getY(); final Cell hitCell = detectAndAddHit(x, y); - if (hitCell != null && mOnPatternListener != null) { + if (hitCell != null) { mPatternInProgress = true; mPatternDisplayMode = DisplayMode.Correct; - mOnPatternListener.onPatternStart(); - } else if (mOnPatternListener != null) { + notifyPatternStarted(); + } else { mPatternInProgress = false; - mOnPatternListener.onPatternCleared(); + notifyPatternCleared(); } if (hitCell != null) { final float startX = getCenterXForColumn(hitCell.column); diff --git a/core/res/res/drawable-hdpi/stat_notify_disabled.png b/core/res/res/drawable-hdpi/stat_notify_disabled.png Binary files differnew file mode 100644 index 000000000000..5b5a7dcc6969 --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_notify_disabled.png diff --git a/core/res/res/drawable-mdpi/stat_notify_disabled.png b/core/res/res/drawable-mdpi/stat_notify_disabled.png Binary files differnew file mode 100644 index 000000000000..9661d3149dc3 --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_notify_disabled.png diff --git a/core/res/res/drawable-xhdpi/stat_notify_disabled.png b/core/res/res/drawable-xhdpi/stat_notify_disabled.png Binary files differnew file mode 100644 index 000000000000..0a003af6fc9d --- /dev/null +++ b/core/res/res/drawable-xhdpi/stat_notify_disabled.png diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index b1dc252d16dc..3f0f2f34ba4d 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1958,6 +1958,15 @@ <!-- Displayed on lock screen's right tab - turn sound off --> <string name="lockscreen_sound_off_label">Sound off</string> + <!-- Accessibility description sent when user starts drawing a lock pattern. [CHAR LIMIT=NONE] --> + <string name="lockscreen_access_pattern_start">Pattern started</string> + <!-- Accessibility description sent when the pattern times out and is cleared. [CHAR LIMIT=NONE] --> + <string name="lockscreen_access_pattern_cleared">Pattern cleared</string> + <!-- Accessibility description sent when user adds a cell to the pattern. [CHAR LIMIT=NONE] --> + <string name="lockscreen_access_pattern_cell_added">Cell added</string> + <!-- Accessibility description sent when user completes drawing a pattern. [CHAR LIMIT=NONE] --> + <string name="lockscreen_access_pattern_detected">Pattern completed</string> + <!-- Password keyboard strings. Used by LockScreen and Settings --><skip /> <!-- Label for "switch to symbols" key. Must be short to fit on key! --> <string name="password_keyboard_label_symbol_key">\?123</string> diff --git a/data/sounds/AudioPackage7.mk b/data/sounds/AudioPackage7.mk index 629ceb356d7c..66edb7a745d5 100755 --- a/data/sounds/AudioPackage7.mk +++ b/data/sounds/AudioPackage7.mk @@ -27,35 +27,33 @@ PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \ $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \ $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \ - $(LOCAL_PATH)/notifications/ogg/Altair.ogg:system/media/audio/notifications/Altair.ogg \ $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \ - $(LOCAL_PATH)/notifications/ogg/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \ + $(LOCAL_PATH)/notifications/ogg/Bellatrix.ogg:system/media/audio/notifications/Bellatrix.ogg \ $(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \ $(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \ - $(LOCAL_PATH)/notifications/ogg/Deneb.ogg:system/media/audio/notifications/Deneb.ogg \ $(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \ $(LOCAL_PATH)/notifications/ogg/Lalande.ogg:system/media/audio/notifications/Lalande.ogg \ $(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \ $(LOCAL_PATH)/notifications/ogg/Polaris.ogg:system/media/audio/notifications/Polaris.ogg \ + $(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \ $(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \ $(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \ - $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \ $(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \ $(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \ + $(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \ + $(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \ $(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Acheron.ogg:system/media/audio/ringtones/Acheron.ogg \ $(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \ $(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \ $(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \ $(LOCAL_PATH)/ringtones/ogg/CanisMajor.ogg:system/media/audio/ringtones/CanisMajor.ogg \ $(LOCAL_PATH)/ringtones/ogg/Carina.ogg:system/media/audio/ringtones/Carina.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Cassiopeia.ogg:system/media/audio/ringtones/Cassiopeia.ogg \ $(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \ $(LOCAL_PATH)/ringtones/ogg/Cygnus.ogg:system/media/audio/ringtones/Cygnus.ogg \ $(LOCAL_PATH)/ringtones/ogg/Draco.ogg:system/media/audio/ringtones/Draco.ogg \ + $(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \ $(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \ $(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Nasqueron.ogg:system/media/audio/ringtones/Nasqueron.ogg \ $(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \ $(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \ $(LOCAL_PATH)/ringtones/ogg/Perseus.ogg:system/media/audio/ringtones/Perseus.ogg \ @@ -66,4 +64,4 @@ PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \ $(LOCAL_PATH)/ringtones/ogg/Testudo.ogg:system/media/audio/ringtones/Testudo.ogg \ $(LOCAL_PATH)/ringtones/ogg/UrsaMinor.ogg:system/media/audio/ringtones/UrsaMinor.ogg \ - $(LOCAL_PATH)/ringtones/ogg/Vespa.ogg:system/media/audio/ringtones/Vespa.ogg + $(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg diff --git a/data/sounds/effects/ogg/Lock.ogg b/data/sounds/effects/ogg/Lock.ogg Binary files differindex ed845bee50e3..e7928e493f40 100644 --- a/data/sounds/effects/ogg/Lock.ogg +++ b/data/sounds/effects/ogg/Lock.ogg diff --git a/data/sounds/effects/ogg/Unlock.ogg b/data/sounds/effects/ogg/Unlock.ogg Binary files differindex 0a47b5c23095..cca95940d950 100644 --- a/data/sounds/effects/ogg/Unlock.ogg +++ b/data/sounds/effects/ogg/Unlock.ogg diff --git a/data/sounds/effects/wav/Lock.wav b/data/sounds/effects/wav/Lock.wav Binary files differindex 1655a8902f5f..b8076369a3e9 100644 --- a/data/sounds/effects/wav/Lock.wav +++ b/data/sounds/effects/wav/Lock.wav diff --git a/data/sounds/effects/wav/Unlock.wav b/data/sounds/effects/wav/Unlock.wav Binary files differindex 2229d03b5fed..e1d475ed84dd 100644 --- a/data/sounds/effects/wav/Unlock.wav +++ b/data/sounds/effects/wav/Unlock.wav diff --git a/data/sounds/notifications/ogg/Acrux.ogg b/data/sounds/notifications/ogg/Acrux.ogg Binary files differnew file mode 100644 index 000000000000..74ad149a7191 --- /dev/null +++ b/data/sounds/notifications/ogg/Acrux.ogg diff --git a/data/sounds/notifications/ogg/Bellatrix.ogg b/data/sounds/notifications/ogg/Bellatrix.ogg Binary files differnew file mode 100644 index 000000000000..37a1bdcaabdf --- /dev/null +++ b/data/sounds/notifications/ogg/Bellatrix.ogg diff --git a/data/sounds/notifications/ogg/Pollux.ogg b/data/sounds/notifications/ogg/Pollux.ogg Binary files differnew file mode 100644 index 000000000000..2f907fdb1909 --- /dev/null +++ b/data/sounds/notifications/ogg/Pollux.ogg diff --git a/data/sounds/notifications/ogg/Tejat.ogg b/data/sounds/notifications/ogg/Tejat.ogg Binary files differnew file mode 100644 index 000000000000..04ba06cef9b0 --- /dev/null +++ b/data/sounds/notifications/ogg/Tejat.ogg diff --git a/data/sounds/ringtones/ogg/Girtab.ogg b/data/sounds/ringtones/ogg/Girtab.ogg Binary files differnew file mode 100644 index 000000000000..f6b3a35a3859 --- /dev/null +++ b/data/sounds/ringtones/ogg/Girtab.ogg diff --git a/data/sounds/ringtones/ogg/Zeta.ogg b/data/sounds/ringtones/ogg/Zeta.ogg Binary files differnew file mode 100644 index 000000000000..ef64d2feda7e --- /dev/null +++ b/data/sounds/ringtones/ogg/Zeta.ogg diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index de0fabc7bd8f..50964d5e5546 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -285,7 +285,7 @@ public class GradientDrawable extends Drawable { of the fill (if any) without worrying about blending artifacts. */ final boolean useLayer = haveStroke && haveFill && st.mShape != LINE && - currStrokeAlpha < 255; + currStrokeAlpha < 255 && (mAlpha < 255 || mColorFilter != null); /* Drawing with a layer is slower than direct drawing, but it allows us to apply paint effects like alpha and colorfilter to diff --git a/media/java/android/media/videoeditor/AudioTrack.java b/media/java/android/media/videoeditor/AudioTrack.java index 2de82f25ecb6..c5cc2cad05de 100755 --- a/media/java/android/media/videoeditor/AudioTrack.java +++ b/media/java/android/media/videoeditor/AudioTrack.java @@ -147,14 +147,16 @@ public class AudioTrack { } catch (Exception e) { throw new IllegalArgumentException(e.getMessage() + " : " + filename); } - switch (mMANativeHelper.getFileType(properties.fileType)) { + int fileType = mMANativeHelper.getFileType(properties.fileType); + switch (fileType) { case MediaProperties.FILE_3GP: case MediaProperties.FILE_MP4: case MediaProperties.FILE_MP3: + case MediaProperties.FILE_AMR: break; default: { - throw new IllegalArgumentException("Unsupported input file type"); + throw new IllegalArgumentException("Unsupported input file type: " + fileType); } } switch (mMANativeHelper.getAudioCodecType(properties.audioFormat)) { diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java index d7b8eaa844ec..03ae62ac1e53 100644 --- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java +++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java @@ -3239,6 +3239,9 @@ class MediaArtistNativeHelper { case FileType.M4V: retValue = MediaProperties.FILE_M4V; break; + case FileType.AMR: + retValue = MediaProperties.FILE_AMR; + break; default: retValue = -1; diff --git a/media/java/android/media/videoeditor/MediaProperties.java b/media/java/android/media/videoeditor/MediaProperties.java index fd034abb03ae..cf518a5f3d7a 100755 --- a/media/java/android/media/videoeditor/MediaProperties.java +++ b/media/java/android/media/videoeditor/MediaProperties.java @@ -286,7 +286,7 @@ public class MediaProperties { */ public static final int FILE_3GP = 0; public static final int FILE_MP4 = 1; - // 2 is for AMRNB + public static final int FILE_AMR = 2; public static final int FILE_MP3 = 3; // 4 is for PCM public static final int FILE_JPEG = 5; diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index fa9417a50ebe..1165af5183a6 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -2005,6 +2005,11 @@ status_t AwesomePlayer::finishSetDataSource_l() { mConnectingDataSource->setUID(mUID); } + String8 cacheConfig; + bool disconnectAtHighwatermark; + NuCachedSource2::RemoveCacheSpecificHeaders( + &mUriHeaders, &cacheConfig, &disconnectAtHighwatermark); + mLock.unlock(); status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders); mLock.lock(); @@ -2024,7 +2029,10 @@ status_t AwesomePlayer::finishSetDataSource_l() { new ThrottledSource( mConnectingDataSource, 50 * 1024 /* bytes/sec */)); #else - mCachedSource = new NuCachedSource2(mConnectingDataSource); + mCachedSource = new NuCachedSource2( + mConnectingDataSource, + cacheConfig.isEmpty() ? NULL : cacheConfig.string(), + disconnectAtHighwatermark); #endif dataSource = mCachedSource; diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp index 9adb841d5989..4f183f57bb64 100644 --- a/media/libstagefright/NuCachedSource2.cpp +++ b/media/libstagefright/NuCachedSource2.cpp @@ -177,7 +177,10 @@ void PageCache::copy(size_t from, void *data, size_t size) { //////////////////////////////////////////////////////////////////////////////// -NuCachedSource2::NuCachedSource2(const sp<DataSource> &source) +NuCachedSource2::NuCachedSource2( + const sp<DataSource> &source, + const char *cacheConfig, + bool disconnectAtHighwatermark) : mSource(source), mReflector(new AHandlerReflector<NuCachedSource2>(this)), mLooper(new ALooper), @@ -190,9 +193,24 @@ NuCachedSource2::NuCachedSource2(const sp<DataSource> &source) mNumRetriesLeft(kMaxNumRetries), mHighwaterThresholdBytes(kDefaultHighWaterThreshold), mLowwaterThresholdBytes(kDefaultLowWaterThreshold), - mKeepAliveIntervalUs(kDefaultKeepAliveIntervalUs) { + mKeepAliveIntervalUs(kDefaultKeepAliveIntervalUs), + mDisconnectAtHighwatermark(disconnectAtHighwatermark) { + // We are NOT going to support disconnect-at-highwatermark indefinitely + // and we are not guaranteeing support for client-specified cache + // parameters. Both of these are temporary measures to solve a specific + // problem that will be solved in a better way going forward. + updateCacheParamsFromSystemProperty(); + if (cacheConfig != NULL) { + updateCacheParamsFromString(cacheConfig); + } + + if (mDisconnectAtHighwatermark) { + // Makes no sense to disconnect and do keep-alives... + mKeepAliveIntervalUs = 0; + } + mLooper->setName("NuCachedSource2"); mLooper->registerHandler(mReflector); mLooper->start(); @@ -339,6 +357,12 @@ void NuCachedSource2::onFetch() { if (mFetching && mCache->totalSize() >= mHighwaterThresholdBytes) { LOGI("Cache full, done prefetching for now"); mFetching = false; + + if (mDisconnectAtHighwatermark + && (mSource->flags() & DataSource::kIsHTTPBasedSource)) { + LOGV("Disconnecting at high watermark"); + static_cast<HTTPBase *>(mSource.get())->disconnect(); + } } } else { Mutex::Autolock autoLock(mLock); @@ -637,4 +661,34 @@ void NuCachedSource2::updateCacheParamsFromString(const char *s) { mKeepAliveIntervalUs); } +// static +void NuCachedSource2::RemoveCacheSpecificHeaders( + KeyedVector<String8, String8> *headers, + String8 *cacheConfig, + bool *disconnectAtHighwatermark) { + *cacheConfig = String8(); + *disconnectAtHighwatermark = false; + + if (headers == NULL) { + return; + } + + ssize_t index; + if ((index = headers->indexOfKey(String8("x-cache-config"))) >= 0) { + *cacheConfig = headers->valueAt(index); + + headers->removeItemsAt(index); + + LOGV("Using special cache config '%s'", cacheConfig->string()); + } + + if ((index = headers->indexOfKey( + String8("x-disconnect-at-highwatermark"))) >= 0) { + *disconnectAtHighwatermark = true; + headers->removeItemsAt(index); + + LOGV("Client requested disconnection at highwater mark"); + } +} + } // namespace android diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h index f04c56664713..7a03e7e4f976 100644 --- a/media/libstagefright/include/NuCachedSource2.h +++ b/media/libstagefright/include/NuCachedSource2.h @@ -28,7 +28,10 @@ struct ALooper; struct PageCache; struct NuCachedSource2 : public DataSource { - NuCachedSource2(const sp<DataSource> &source); + NuCachedSource2( + const sp<DataSource> &source, + const char *cacheConfig = NULL, + bool disconnectAtHighwatermark = false); virtual status_t initCheck() const; @@ -56,6 +59,11 @@ struct NuCachedSource2 : public DataSource { status_t getEstimatedBandwidthKbps(int32_t *kbps); status_t setCacheStatCollectFreq(int32_t freqMs); + static void RemoveCacheSpecificHeaders( + KeyedVector<String8, String8> *headers, + String8 *cacheConfig, + bool *disconnectAtHighwatermark); + protected: virtual ~NuCachedSource2(); @@ -105,6 +113,8 @@ private: // If the keep-alive interval is 0, keep-alives are disabled. int64_t mKeepAliveIntervalUs; + bool mDisconnectAtHighwatermark; + void onMessageReceived(const sp<AMessage> &msg); void onFetch(); void onRead(const sp<AMessage> &msg); diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java index 24dce1a0dd79..8343bbdf738e 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java @@ -186,6 +186,9 @@ class KeyguardStatusViewManager implements OnClickListener { mTransientTextManager = new TransientTextManager(mCarrierView); + mUpdateMonitor.registerInfoCallback(mInfoCallback); + mUpdateMonitor.registerSimStateCallback(mSimStateCallback); + resetStatusInfo(); refreshDate(); updateOwnerInfo(); diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java index 071044ed2b9c..265024be98b5 100644 --- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java +++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java @@ -98,7 +98,8 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler private View mLockScreen; private View mUnlockScreen; - private boolean mScreenOn = false; + private volatile boolean mScreenOn = false; + private volatile boolean mWindowFocused = false; private boolean mEnableFallback = false; // assume no fallback UI until we know better private boolean mShowLockBeforeUnlock = false; @@ -110,6 +111,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler private boolean mFaceLockServiceRunning = false; private final Object mFaceLockServiceRunningLock = new Object(); + private final Object mFaceLockStartupLock = new Object(); private Handler mHandler; private final int MSG_SHOW_FACELOCK_AREA_VIEW = 0; @@ -514,13 +516,10 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler stopAndUnbindFromFaceLock(); } - @Override - public void onScreenTurnedOn() { - mScreenOn = true; - show(); - - // When screen is turned on, need to bind to FaceLock service if we are using FaceLock - // But only if not dealing with a call + /** When screen is turned on and focused, need to bind to FaceLock service if we are using + * FaceLock, but only if we're not dealing with a call + */ + private void activateFaceLockIfAble() { final boolean transportInvisible = mTransportControlView == null ? true : mTransportControlView.getVisibility() != View.VISIBLE; if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE @@ -534,12 +533,34 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler } } - /** Unbind from facelock if something covers this window (such as an alarm) */ + @Override + public void onScreenTurnedOn() { + boolean runFaceLock = false; + //Make sure to start facelock iff the screen is both on and focused + synchronized(mFaceLockStartupLock) { + mScreenOn = true; + runFaceLock = mWindowFocused; + } + show(); + if(runFaceLock) activateFaceLockIfAble(); + } + + /** Unbind from facelock if something covers this window (such as an alarm) + * bind to facelock if the lockscreen window just came into focus, and the screen is on + */ @Override public void onWindowFocusChanged (boolean hasWindowFocus) { + boolean runFaceLock = false; + //Make sure to start facelock iff the screen is both on and focused + synchronized(mFaceLockStartupLock) { + if(mScreenOn && !mWindowFocused) runFaceLock = hasWindowFocus; + mWindowFocused = hasWindowFocus; + } if(!hasWindowFocus) { stopAndUnbindFromFaceLock(); mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW); + } else if (runFaceLock) { + activateFaceLockIfAble(); } } diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index 5758954794ff..f9f5458122ff 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -1966,6 +1966,9 @@ class BackupManagerService extends IBackupManager.Stub { synchronized (mQueueLock) { mBackupRunning = false; if (mStatus == BackupConstants.TRANSPORT_NOT_INITIALIZED) { + // Make sure we back up everything and perform the one-time init + clearMetadata(); + if (DEBUG) Slog.d(TAG, "Server requires init; rerunning"); backupNow(); } } @@ -1975,6 +1978,12 @@ class BackupManagerService extends IBackupManager.Stub { mWakelock.release(); } + // Remove the PM metadata state. This will generate an init on the next pass. + void clearMetadata() { + final File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL); + if (pmState.exists()) pmState.delete(); + } + // Invoke an agent's doBackup() and start a timeout message spinning on the main // handler in case it doesn't get back to us. int invokeAgentForBackup(String packageName, IBackupAgent agent, diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 5006de757cd3..3ae62add369f 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -163,6 +163,11 @@ class ServerThread extends Thread { pm = PackageManagerService.main(context, factoryTest != SystemServer.FACTORY_TEST_OFF, onlyCore); + boolean firstBoot = false; + try { + firstBoot = pm.isFirstBoot(); + } catch (RemoteException e) { + } ActivityManagerService.setSystemProcess(); @@ -208,7 +213,8 @@ class ServerThread extends Thread { Slog.i(TAG, "Window Manager"); wm = WindowManagerService.main(context, power, - factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL); + factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL, + !firstBoot); ServiceManager.addService(Context.WINDOW_SERVICE, wm); ActivityManagerService.self().setWindowManager(wm); diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 7bc19ab43882..b9d3d76bbd11 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -589,8 +589,8 @@ final class ActivityStack { } } app.thread.scheduleLaunchActivity(new Intent(r.intent), r, - System.identityHashCode(r), - r.info, r.compat, r.icicle, results, newIntents, !andResume, + System.identityHashCode(r), r.info, mService.mConfiguration, + r.compat, r.icicle, results, newIntents, !andResume, mService.isNextTransitionForward(), profileFile, profileFd, profileAutoStop); @@ -4035,7 +4035,18 @@ final class ActivityStack { // But then we need to figure out how it needs to deal with that. Configuration oldConfig = r.configuration; r.configuration = newConfig; - + + // Determine what has changed. May be nothing, if this is a config + // that has come back from the app after going idle. In that case + // we just want to leave the official config object now in the + // activity and do nothing else. + final int changes = oldConfig.diff(newConfig); + if (changes == 0 && !r.forceNewConfig) { + if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG, + "Configuration no differences in " + r); + return true; + } + // If the activity isn't currently running, just leave the new // configuration and it will pick that up next time it starts. if (r.app == null || r.app.thread == null) { @@ -4046,8 +4057,7 @@ final class ActivityStack { return true; } - // Figure out what has changed between the two configurations. - int changes = oldConfig.diff(newConfig); + // Figure out how to handle the changes between the configurations. if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { Slog.v(TAG, "Checking to restart " + r.info.name + ": changed=0x" + Integer.toHexString(changes) + ", handles=0x" diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index 0da5cc631e41..e6107826aa8c 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -85,7 +85,6 @@ import android.net.NetworkIdentity; import android.net.NetworkPolicy; import android.net.NetworkQuotaInfo; import android.net.NetworkState; -import android.net.NetworkStats; import android.net.NetworkTemplate; import android.os.Binder; import android.os.Environment; @@ -489,7 +488,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long end = currentTime; final long totalBytes = getTotalBytes(policy.template, start, end); - if (policy.limitBytes != LIMIT_DISABLED && totalBytes >= policy.limitBytes) { + if (policy.isOverLimit(totalBytes)) { if (policy.lastSnooze >= start) { enqueueNotification(policy, TYPE_LIMIT_SNOOZED, totalBytes); } else { @@ -574,7 +573,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final CharSequence title = res.getText(R.string.data_usage_warning_title); final CharSequence body = res.getString(R.string.data_usage_warning_body); - builder.setSmallIcon(R.drawable.ic_menu_info_details); + builder.setSmallIcon(R.drawable.stat_notify_error); builder.setTicker(title); builder.setContentTitle(title); builder.setContentText(body); @@ -606,7 +605,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { break; } - builder.setSmallIcon(com.android.internal.R.drawable.ic_menu_block); + builder.setSmallIcon(R.drawable.stat_notify_disabled); builder.setTicker(title); builder.setContentTitle(title); builder.setContentText(body); @@ -640,7 +639,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { break; } - builder.setSmallIcon(R.drawable.ic_menu_info_details); + builder.setSmallIcon(R.drawable.stat_notify_error); builder.setTicker(title); builder.setContentTitle(title); builder.setContentText(body); @@ -677,7 +676,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { builder.setOnlyAlertOnce(true); builder.setOngoing(true); - builder.setSmallIcon(R.drawable.ic_menu_info_details); + builder.setSmallIcon(R.drawable.stat_notify_error); builder.setTicker(title); builder.setContentTitle(title); builder.setContentText(body); @@ -750,8 +749,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long totalBytes = getTotalBytes(policy.template, start, end); // disable data connection when over limit and not snoozed - final boolean overLimit = policy.limitBytes != LIMIT_DISABLED - && totalBytes > policy.limitBytes && policy.lastSnooze < start; + final boolean overLimit = policy.isOverLimit(totalBytes) && policy.lastSnooze < start; final boolean enabled = !overLimit; setNetworkTemplateEnabled(policy.template, enabled); @@ -1535,10 +1533,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private long getTotalBytes(NetworkTemplate template, long start, long end) { try { - final NetworkStats stats = mNetworkStats.getSummaryForNetwork( - template, start, end); - final NetworkStats.Entry entry = stats.getValues(0, null); - return entry.rxBytes + entry.txBytes; + return mNetworkStats.getSummaryForNetwork(template, start, end).getTotalBytes(); } catch (RemoteException e) { // ignored; service lives in system_server return 0; diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 19dd606fe188..0e9f64c34480 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -1157,6 +1157,10 @@ public class PackageManagerService extends IPackageManager.Stub { } // synchronized (mInstallLock) } + public boolean isFirstBoot() { + return !mRestoredSettings; + } + private String getRequiredVerifierLPr() { final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION); final List<ResolveInfo> receivers = queryIntentReceivers(verification, PACKAGE_MIME_TYPE, @@ -2983,12 +2987,14 @@ public class PackageManagerService extends IPackageManager.Stub { } if (pkgs != null) { for (int i=0; i<pkgs.size(); i++) { - try { - ActivityManagerNative.getDefault().showBootMessage( - mContext.getResources().getString( - com.android.internal.R.string.android_upgrading_apk, - i+1, pkgs.size()), true); - } catch (RemoteException e) { + if (!isFirstBoot()) { + try { + ActivityManagerNative.getDefault().showBootMessage( + mContext.getResources().getString( + com.android.internal.R.string.android_upgrading_apk, + i+1, pkgs.size()), true); + } catch (RemoteException e) { + } } PackageParser.Package p = pkgs.get(i); synchronized (mInstallLock) { diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java index 7cdb5b15ba31..bfe6613cf630 100644 --- a/services/java/com/android/server/pm/Settings.java +++ b/services/java/com/android/server/pm/Settings.java @@ -1238,9 +1238,8 @@ final class Settings { mReadMessages.append("No start tag found in settings file\n"); PackageManagerService.reportSettingsProblem(Log.WARN, "No start tag found in package manager settings"); - Log - .wtf(PackageManagerService.TAG, - "No start tag found in package manager settings"); + Log.wtf(PackageManagerService.TAG, + "No start tag found in package manager settings"); return false; } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 73a96013358a..06a6e9892dfc 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -297,6 +297,8 @@ public class WindowManagerService extends IWindowManager.Stub final boolean mHaveInputMethods; + final boolean mAllowBootMessages; + final boolean mLimitedAlphaCompositing; final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager(); @@ -633,8 +635,8 @@ public class WindowManagerService extends IWindowManager.Stub float mCompatibleScreenScale; public static WindowManagerService main(Context context, - PowerManagerService pm, boolean haveInputMethods) { - WMThread thr = new WMThread(context, pm, haveInputMethods); + PowerManagerService pm, boolean haveInputMethods, boolean allowBootMsgs) { + WMThread thr = new WMThread(context, pm, haveInputMethods, allowBootMsgs); thr.start(); synchronized (thr) { @@ -654,19 +656,21 @@ public class WindowManagerService extends IWindowManager.Stub private final Context mContext; private final PowerManagerService mPM; private final boolean mHaveInputMethods; + private final boolean mAllowBootMessages; public WMThread(Context context, PowerManagerService pm, - boolean haveInputMethods) { + boolean haveInputMethods, boolean allowBootMsgs) { super("WindowManager"); mContext = context; mPM = pm; mHaveInputMethods = haveInputMethods; + mAllowBootMessages = allowBootMsgs; } public void run() { Looper.prepare(); WindowManagerService s = new WindowManagerService(mContext, mPM, - mHaveInputMethods); + mHaveInputMethods, mAllowBootMessages); android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_DISPLAY); android.os.Process.setCanSelfBackground(false); @@ -728,9 +732,10 @@ public class WindowManagerService extends IWindowManager.Stub } private WindowManagerService(Context context, PowerManagerService pm, - boolean haveInputMethods) { + boolean haveInputMethods, boolean showBootMsgs) { mContext = context; mHaveInputMethods = haveInputMethods; + mAllowBootMessages = showBootMsgs; mLimitedAlphaCompositing = context.getResources().getBoolean( com.android.internal.R.bool.config_sf_limitedAlpha); @@ -4846,6 +4851,9 @@ public class WindowManagerService extends IWindowManager.Stub public void showBootMessage(final CharSequence msg, final boolean always) { boolean first = false; synchronized(mWindowMap) { + if (!mAllowBootMessages) { + return; + } if (!mShowingBootMessages) { if (!always) { return; diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 51eb0a376d06..dab070567a29 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -22,6 +22,9 @@ LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES ifeq ($(TARGET_BOARD_PLATFORM), omap3) LOCAL_CFLAGS += -DNO_RGBX_8888 endif +ifeq ($(TARGET_BOARD_PLATFORM), omap4) + LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY +endif ifeq ($(TARGET_BOARD_PLATFORM), s5pc110) LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE endif diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java index dded39e1a6a3..fe41e7e61b0c 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java @@ -88,6 +88,7 @@ final class CdmaSMSDispatcher extends SMSDispatcher { PendingIntent intent = tracker.mDeliveryIntent; Intent fillIn = new Intent(); fillIn.putExtra("pdu", sms.getPdu()); + fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP2); try { intent.send(mContext, Activity.RESULT_OK, fillIn); } catch (CanceledException ex) {} diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java index 4e1cc9afd13f..c1553d831c9b 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java @@ -122,6 +122,7 @@ public final class GsmSMSDispatcher extends SMSDispatcher { PendingIntent intent = tracker.mDeliveryIntent; Intent fillIn = new Intent(); fillIn.putExtra("pdu", IccUtils.hexStringToBytes(pduString)); + fillIn.putExtra("format", android.telephony.SmsMessage.FORMAT_3GPP); try { intent.send(mContext, Activity.RESULT_OK, fillIn); } catch (CanceledException ex) {} diff --git a/test-runner/src/android/test/mock/MockContentProvider.java b/test-runner/src/android/test/mock/MockContentProvider.java index b63ff3dca8df..e0ce3228c75b 100644 --- a/test-runner/src/android/test/mock/MockContentProvider.java +++ b/test-runner/src/android/test/mock/MockContentProvider.java @@ -21,16 +21,12 @@ import android.content.ContentProviderOperation; import android.content.ContentProviderResult; import android.content.ContentValues; import android.content.Context; -import android.content.EntityIterator; import android.content.IContentProvider; import android.content.OperationApplicationException; import android.content.pm.PathPermission; import android.content.pm.ProviderInfo; import android.content.res.AssetFileDescriptor; import android.database.Cursor; -import android.database.CursorWindow; -import android.database.IBulkCursor; -import android.database.IContentObserver; import android.net.Uri; import android.os.Bundle; import android.os.IBinder; @@ -55,84 +51,75 @@ public class MockContentProvider extends ContentProvider { * IContentProvider that directs all calls to this MockContentProvider. */ private class InversionIContentProvider implements IContentProvider { - @SuppressWarnings("unused") + @Override public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) throws RemoteException, OperationApplicationException { return MockContentProvider.this.applyBatch(operations); } - @SuppressWarnings("unused") + @Override public int bulkInsert(Uri url, ContentValues[] initialValues) throws RemoteException { return MockContentProvider.this.bulkInsert(url, initialValues); } - @SuppressWarnings("unused") - public IBulkCursor bulkQuery(Uri url, String[] projection, String selection, - String[] selectionArgs, String sortOrder, IContentObserver observer, - CursorWindow window) throws RemoteException { - throw new UnsupportedOperationException("Must not come here"); - } - - @SuppressWarnings("unused") + @Override public int delete(Uri url, String selection, String[] selectionArgs) throws RemoteException { return MockContentProvider.this.delete(url, selection, selectionArgs); } - @SuppressWarnings("unused") + @Override public String getType(Uri url) throws RemoteException { return MockContentProvider.this.getType(url); } - @SuppressWarnings("unused") + @Override public Uri insert(Uri url, ContentValues initialValues) throws RemoteException { return MockContentProvider.this.insert(url, initialValues); } - @SuppressWarnings("unused") + @Override public AssetFileDescriptor openAssetFile(Uri url, String mode) throws RemoteException, FileNotFoundException { return MockContentProvider.this.openAssetFile(url, mode); } - @SuppressWarnings("unused") + @Override public ParcelFileDescriptor openFile(Uri url, String mode) throws RemoteException, FileNotFoundException { return MockContentProvider.this.openFile(url, mode); } - @SuppressWarnings("unused") + @Override public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs, String sortOrder) throws RemoteException { return MockContentProvider.this.query(url, projection, selection, selectionArgs, sortOrder); } - @SuppressWarnings("unused") + @Override public int update(Uri url, ContentValues values, String selection, String[] selectionArgs) throws RemoteException { return MockContentProvider.this.update(url, values, selection, selectionArgs); } - /** - * @hide - */ - @SuppressWarnings("unused") + @Override public Bundle call(String method, String request, Bundle args) throws RemoteException { return MockContentProvider.this.call(method, request, args); } + @Override public IBinder asBinder() { throw new UnsupportedOperationException(); } - @SuppressWarnings("unused") + @Override public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException { return MockContentProvider.this.getStreamTypes(url, mimeTypeFilter); } - @SuppressWarnings("unused") + @Override public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts) throws RemoteException, FileNotFoundException { return MockContentProvider.this.openTypedAssetFile(url, mimeType, opts); diff --git a/test-runner/src/android/test/mock/MockIContentProvider.java b/test-runner/src/android/test/mock/MockIContentProvider.java index 183be415880c..b7733a4d55eb 100644 --- a/test-runner/src/android/test/mock/MockIContentProvider.java +++ b/test-runner/src/android/test/mock/MockIContentProvider.java @@ -23,9 +23,6 @@ import android.content.EntityIterator; import android.content.IContentProvider; import android.content.res.AssetFileDescriptor; import android.database.Cursor; -import android.database.CursorWindow; -import android.database.IBulkCursor; -import android.database.IContentObserver; import android.net.Uri; import android.os.Bundle; import android.os.IBinder; @@ -47,12 +44,6 @@ public class MockIContentProvider implements IContentProvider { throw new UnsupportedOperationException("unimplemented mock method"); } - public IBulkCursor bulkQuery(Uri url, String[] projection, String selection, - String[] selectionArgs, String sortOrder, IContentObserver observer, - CursorWindow window) { - throw new UnsupportedOperationException("unimplemented mock method"); - } - @SuppressWarnings("unused") public int delete(Uri url, String selection, String[] selectionArgs) throws RemoteException { diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java index 3835378b5da0..c91a3bf91c51 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java @@ -23,9 +23,6 @@ import android.content.IContentProvider; import android.content.OperationApplicationException; import android.content.res.AssetFileDescriptor; import android.database.Cursor; -import android.database.CursorWindow; -import android.database.IBulkCursor; -import android.database.IContentObserver; import android.net.Uri; import android.os.Bundle; import android.os.IBinder; @@ -41,78 +38,84 @@ import java.util.ArrayList; * TODO: never return null when the method is not supposed to. Return fake data instead. */ public final class BridgeContentProvider implements IContentProvider { - + @Override public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> arg0) throws RemoteException, OperationApplicationException { // TODO Auto-generated method stub return null; } + @Override public int bulkInsert(Uri arg0, ContentValues[] arg1) throws RemoteException { // TODO Auto-generated method stub return 0; } - public IBulkCursor bulkQuery(Uri arg0, String[] arg1, String arg2, String[] arg3, - String arg4, IContentObserver arg5, CursorWindow arg6) throws RemoteException { - // TODO Auto-generated method stub - return null; - } - + @Override public Bundle call(String arg0, String arg1, Bundle arg2) throws RemoteException { // TODO Auto-generated method stub return null; } + @Override public int delete(Uri arg0, String arg1, String[] arg2) throws RemoteException { // TODO Auto-generated method stub return 0; } + @Override public String getType(Uri arg0) throws RemoteException { // TODO Auto-generated method stub return null; } + @Override public Uri insert(Uri arg0, ContentValues arg1) throws RemoteException { // TODO Auto-generated method stub return null; } + @Override public AssetFileDescriptor openAssetFile(Uri arg0, String arg1) throws RemoteException, FileNotFoundException { // TODO Auto-generated method stub return null; } + @Override public ParcelFileDescriptor openFile(Uri arg0, String arg1) throws RemoteException, FileNotFoundException { // TODO Auto-generated method stub return null; } + @Override public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4) throws RemoteException { // TODO Auto-generated method stub return null; } + @Override public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) throws RemoteException { // TODO Auto-generated method stub return 0; } + @Override public IBinder asBinder() { // TODO Auto-generated method stub return null; } + @Override public String[] getStreamTypes(Uri arg0, String arg1) throws RemoteException { // TODO Auto-generated method stub return null; } + @Override public AssetFileDescriptor openTypedAssetFile(Uri arg0, String arg1, Bundle arg2) throws RemoteException, FileNotFoundException { // TODO Auto-generated method stub |