diff options
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/app/Activity.java | 76 | ||||
-rw-r--r-- | core/java/android/app/ActivityManagerNative.java | 46 | ||||
-rw-r--r-- | core/java/android/app/ActivityThread.java | 17 | ||||
-rw-r--r-- | core/java/android/app/ApplicationThreadNative.java | 23 | ||||
-rw-r--r-- | core/java/android/app/IActivityManager.java | 14 | ||||
-rw-r--r-- | core/java/android/app/IApplicationThread.java | 3 |
6 files changed, 164 insertions, 15 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index d1efd0d1..fa746ba 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -745,6 +745,7 @@ public class Activity extends ContextThemeWrapper // protected by synchronized (this) int mResultCode = RESULT_CANCELED; Intent mResultData = null; + private TranslucentConversionListener mTranslucentCallback; private boolean mTitleReady = false; @@ -1382,6 +1383,7 @@ public class Activity extends ContextThemeWrapper if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStop " + this); if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false); getApplication().dispatchActivityStopped(this); + mTranslucentCallback = null; mCalled = true; } @@ -4886,22 +4888,61 @@ public class Activity extends ContextThemeWrapper /** * Convert a translucent themed Activity {@link android.R.attr#windowIsTranslucent} to a * fullscreen opaque Activity. - * + * <p> * Call this whenever the background of a translucent Activity has changed to become opaque. - * Doing so will allow the previously visible Activity behind this one to be stopped. Stopped - * apps consume no CPU cycles and are eligible for removal when reclaiming memory. + * Doing so will allow the {@link android.view.Surface} of the Activity behind to be released. + * <p> + * This call has no effect on non-translucent activities or on activities with the + * {@link android.R.attr#windowIsFloating} attribute. * + * @see #convertToTranslucent(TranslucentConversionListener) + * @see TranslucentConversionListener + */ + public void convertFromTranslucent() { + try { + mTranslucentCallback = null; + ActivityManagerNative.getDefault().convertFromTranslucent(mToken); + } catch (RemoteException e) { + // pass + } + } + + /** + * Convert a translucent themed Activity {@link android.R.attr#windowIsTranslucent} back from + * opaque to translucent following a call to {@link #convertFromTranslucent()}. + * <p> + * Calling this allows the Activity behind this one to be seen again. Once all such Activities + * have been redrawn {@link TranslucentConversionListener#onTranslucentConversionComplete} will + * be called indicating that it is safe to make this activity translucent again. Until + * {@link TranslucentConversionListener#onTranslucentConversionComplete} is called the image + * behind the frontmost Activity will be indeterminate. + * <p> * This call has no effect on non-translucent activities or on activities with the * {@link android.R.attr#windowIsFloating} attribute. + * + * @param callback the method to call when all visible Activities behind this one have been + * drawn and it is safe to make this Activity translucent again. + * + * @see #convertFromTranslucent() + * @see TranslucentConversionListener */ - public void convertToOpaque() { + public void convertToTranslucent(TranslucentConversionListener callback) { try { - ActivityManagerNative.getDefault().convertToOpaque(mToken); + mTranslucentCallback = callback; + ActivityManagerNative.getDefault().convertToTranslucent(mToken); } catch (RemoteException e) { // pass } } + /** @hide */ + void onTranslucentConversionComplete(boolean drawComplete) { + if (mTranslucentCallback != null) { + mTranslucentCallback.onTranslucentConversionComplete(drawComplete); + mTranslucentCallback = null; + } + } + /** * Adjust the current immersive mode setting. * @@ -4947,6 +4988,7 @@ public class Activity extends ContextThemeWrapper * @return The new action mode, or <code>null</code> if the activity does not want to * provide special handling for this action mode. (It will be handled by the system.) */ + @Override public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) { initActionBar(); if (mActionBar != null) { @@ -4961,6 +5003,7 @@ public class Activity extends ContextThemeWrapper * * @param mode The new action mode. */ + @Override public void onActionModeStarted(ActionMode mode) { } @@ -4970,6 +5013,7 @@ public class Activity extends ContextThemeWrapper * * @param mode The action mode that just finished. */ + @Override public void onActionModeFinished(ActionMode mode) { } @@ -5373,4 +5417,26 @@ public class Activity extends ContextThemeWrapper } } } + + /** + * Interface for informing a translucent {@link Activity} once all visible activities below it + * have completed drawing. This is necessary only after an {@link Activity} has been made + * opaque using {@link Activity#convertFromTranslucent()} and before it has been drawn + * translucent again following a call to {@link + * Activity#convertToTranslucent(TranslucentConversionListener)}. + */ + public interface TranslucentConversionListener { + /** + * Callback made following {@link Activity#convertToTranslucent} once all visible Activities + * below the top one have been redrawn. Following this callback it is safe to make the top + * Activity translucent because the underlying Activity has been drawn. + * + * @param drawComplete True if the background Activity has drawn itself. False if a timeout + * occurred waiting for the Activity to complete drawing. + * + * @see Activity#convertFromTranslucent() + * @see Activity#convertToTranslucent(TranslucentConversionListener) + */ + public void onTranslucentConversionComplete(boolean drawComplete); + } } diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index a23611e..acfcb40 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -1499,10 +1499,18 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } - case CONVERT_TO_OPAQUE_TRANSACTION: { + case CONVERT_FROM_TRANSLUCENT_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); - convertToOpaque(token); + convertFromTranslucent(token); + reply.writeNoException(); + return true; + } + + case CONVERT_TO_TRANSLUCENT_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IBinder token = data.readStrongBinder(); + convertToTranslucent(token); reply.writeNoException(); return true; } @@ -1957,6 +1965,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } + case NOTIFY_ACTIVITY_DRAWN_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IBinder token = data.readStrongBinder(); + notifyActivityDrawn(token); + reply.writeNoException(); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -3840,13 +3855,25 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } - public void convertToOpaque(IBinder token) + public void convertFromTranslucent(IBinder token) + throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(token); + mRemote.transact(CONVERT_FROM_TRANSLUCENT_TRANSACTION, data, reply, 0); + reply.readException(); + data.recycle(); + reply.recycle(); + } + + public void convertToTranslucent(IBinder token) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(token); - mRemote.transact(CONVERT_TO_OPAQUE_TRANSACTION, data, reply, 0); + mRemote.transact(CONVERT_TO_TRANSLUCENT_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); @@ -4482,5 +4509,16 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } + public void notifyActivityDrawn(IBinder token) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(token); + mRemote.transact(NOTIFY_ACTIVITY_DRAWN_TRANSACTION, data, reply, 0); + reply.readException(); + data.recycle(); + reply.recycle(); + } + private IBinder mRemote; } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 4568525..a23f304 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1222,6 +1222,9 @@ public final class ActivityThread { queueOrSendMessage(H.TRIM_MEMORY, null, level); } + public void scheduleTranslucentConversionComplete(IBinder token, boolean drawComplete) { + queueOrSendMessage(H.TRANSLUCENT_CONVERSION_COMPLETE, token, drawComplete ? 1 : 0); + } } private class H extends Handler { @@ -1269,6 +1272,7 @@ public final class ActivityThread { public static final int DUMP_PROVIDER = 141; public static final int UNSTABLE_PROVIDER_DIED = 142; public static final int REQUEST_ACTIVITY_EXTRAS = 143; + public static final int TRANSLUCENT_CONVERSION_COMPLETE = 144; String codeToString(int code) { if (DEBUG_MESSAGES) { switch (code) { @@ -1316,6 +1320,7 @@ public final class ActivityThread { case DUMP_PROVIDER: return "DUMP_PROVIDER"; case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED"; case REQUEST_ACTIVITY_EXTRAS: return "REQUEST_ACTIVITY_EXTRAS"; + case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE"; } } return Integer.toString(code); @@ -1530,6 +1535,9 @@ public final class ActivityThread { case REQUEST_ACTIVITY_EXTRAS: handleRequestActivityExtras((RequestActivityExtras)msg.obj); break; + case TRANSLUCENT_CONVERSION_COMPLETE: + handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1); + break; } if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what)); } @@ -2452,7 +2460,14 @@ public final class ActivityThread { } catch (RemoteException e) { } } - + + public void handleTranslucentConversionComplete(IBinder token, boolean drawComplete) { + ActivityClientRecord r = mActivities.get(token); + if (r != null) { + r.activity.onTranslucentConversionComplete(drawComplete); + } + } + private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>(); /** diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index e903447..cc495aa 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -603,6 +603,16 @@ public abstract class ApplicationThreadNative extends Binder reply.writeNoException(); return true; } + + case SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION: + { + data.enforceInterface(IApplicationThread.descriptor); + IBinder token = data.readStrongBinder(); + boolean timeout = data.readInt() == 1; + scheduleTranslucentConversionComplete(token, timeout); + reply.writeNoException(); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -1197,6 +1207,7 @@ class ApplicationThreadProxy implements IApplicationThread { data.recycle(); } + @Override public void unstableProviderDied(IBinder provider) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); @@ -1205,6 +1216,7 @@ class ApplicationThreadProxy implements IApplicationThread { data.recycle(); } + @Override public void requestActivityExtras(IBinder activityToken, IBinder requestToken, int requestType) throws RemoteException { Parcel data = Parcel.obtain(); @@ -1215,4 +1227,15 @@ class ApplicationThreadProxy implements IApplicationThread { mRemote.transact(REQUEST_ACTIVITY_EXTRAS_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } + + @Override + public void scheduleTranslucentConversionComplete(IBinder token, boolean timeout) + throws RemoteException { + Parcel data = Parcel.obtain(); + data.writeInterfaceToken(IApplicationThread.descriptor); + data.writeStrongBinder(token); + data.writeInt(timeout ? 1 : 0); + mRemote.transact(SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); + data.recycle(); + } } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 3793c73..19858dc 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -258,7 +258,7 @@ public interface IActivityManager extends IInterface { StrictMode.ViolationInfo crashInfo) throws RemoteException; /* - * This will deliver the specified signal to all the persistent processes. Currently only + * This will deliver the specified signal to all the persistent processes. Currently only * SIGUSR1 is delivered. All others are ignored. */ public void signalPersistentProcesses(int signal) throws RemoteException; @@ -301,7 +301,9 @@ public interface IActivityManager extends IInterface { public void finishHeavyWeightApp() throws RemoteException; - public void convertToOpaque(IBinder token) throws RemoteException; + public void convertFromTranslucent(IBinder token) throws RemoteException; + public void convertToTranslucent(IBinder token) throws RemoteException; + public void notifyActivityDrawn(IBinder token) throws RemoteException; public void setImmersive(IBinder token, boolean immersive) throws RemoteException; public boolean isImmersive(IBinder token) throws RemoteException; @@ -494,7 +496,7 @@ public interface IActivityManager extends IInterface { thisTime = source.readLong(); totalTime = source.readLong(); } - }; + } String descriptor = "android.app.IActivityManager"; @@ -670,6 +672,8 @@ public interface IActivityManager extends IInterface { int GET_STACK_BOXES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170; int SET_FOCUSED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+171; int GET_STACK_BOX_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+172; - int CONVERT_TO_OPAQUE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+173; - int REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+174; + int CONVERT_FROM_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+173; + int CONVERT_TO_TRANSLUCENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+174; + int NOTIFY_ACTIVITY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+175; + int REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+176; } diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java index a009bd3..286566d 100644 --- a/core/java/android/app/IApplicationThread.java +++ b/core/java/android/app/IApplicationThread.java @@ -133,6 +133,8 @@ public interface IApplicationThread extends IInterface { void unstableProviderDied(IBinder provider) throws RemoteException; void requestActivityExtras(IBinder activityToken, IBinder requestToken, int requestType) throws RemoteException; + void scheduleTranslucentConversionComplete(IBinder token, boolean timeout) + throws RemoteException; String descriptor = "android.app.IApplicationThread"; @@ -183,4 +185,5 @@ public interface IApplicationThread extends IInterface { int DUMP_DB_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+45; int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+46; int REQUEST_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+47; + int SCHEDULE_TRANSLUCENT_CONVERSION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+48; } |