diff --git a/api/current.xml b/api/current.xml index fa9ab9362db19..d6b272f638f51 100644 --- a/api/current.xml +++ b/api/current.xml @@ -17060,6 +17060,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + must have been created with + * {@link PendingIntent#getActivity PendingIntent.getActivity}; all other + * types will result in an IllegalArgumentException being thrown. + * + * @param intent The PendingIntent to launch. + * @param requestCode If >= 0, this code will be returned in + * onActivityResult() when the activity exits. + * @param fillInIntent If non-null, this will be provided as the + * intent parameter to {@link PendingIntent#send(Context, int, Intent) + * PendingIntent.send(Context, int, Intent)}. + * @param flagsMask Intent flags in the original PendingIntent that you + * would like to change. + * @param flagsValues Desired values for any bits set in + * flagsMask + */ + public void startActivityForResult(PendingIntent intent, int requestCode, + Intent fillInIntent, int flagsMask, int flagsValues) + throws PendingIntent.CanceledException { + if (mParent == null) { + startActivityForResultInner(intent, requestCode, fillInIntent, + flagsMask, flagsValues, this); + } else { + mParent.startActivityFromChild(this, intent, requestCode, + fillInIntent, flagsMask, flagsValues); + } + } + + private void startActivityForResultInner(PendingIntent intent, int requestCode, + Intent fillInIntent, int flagsMask, int flagsValues, Activity activity) + throws PendingIntent.CanceledException { + try { + String resolvedType = null; + if (fillInIntent != null) { + resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver()); + } + int result = ActivityManagerNative.getDefault() + .startActivityPendingIntent(mMainThread.getApplicationThread(), intent, + fillInIntent, resolvedType, mToken, activity.mEmbeddedID, + requestCode, flagsMask, flagsValues); + if (result == IActivityManager.START_CANCELED) { + throw new PendingIntent.CanceledException(); + } + Instrumentation.checkStartActivityResult(result, null); + } catch (RemoteException e) { + } + if (requestCode >= 0) { + // If this start is requesting a result, we can avoid making + // the activity visible until the result is received. Setting + // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the + // activity hidden during this time, to avoid flickering. + // This can only be done when a result is requested because + // that guarantees we will get information back when the + // activity is finished, no matter what happens to it. + mStartedActivity = true; + } + } + /** * Launch a new activity. You will not receive any information about when * the activity exits. This implementation overrides the base version, @@ -2745,6 +2803,27 @@ public class Activity extends ContextThemeWrapper startActivityForResult(intent, -1); } + /** + * Like {@link #startActivity(Intent)}, but taking a PendingIntent + * to start; see + * {@link #startActivityForResult(PendingIntent, int, Intent, int, int)} + * for more information. + * + * @param intent The PendingIntent to launch. + * @param fillInIntent If non-null, this will be provided as the + * intent parameter to {@link PendingIntent#send(Context, int, Intent) + * PendingIntent.send(Context, int, Intent)}. + * @param flagsMask Intent flags in the original PendingIntent that you + * would like to change. + * @param flagsValues Desired values for any bits set in + * flagsMask + */ + public void startActivity(PendingIntent intent, + Intent fillInIntent, int flagsMask, int flagsValues) + throws PendingIntent.CanceledException { + startActivityForResult(intent, -1, fillInIntent, flagsMask, flagsValues); + } + /** * A special variation to launch an activity only if a new activity * instance is needed to handle the given Intent. In other words, this is @@ -2865,6 +2944,19 @@ public class Activity extends ContextThemeWrapper } } + /** + * Like {@link #startActivityFromChild(Activity, Intent, int)}, but + * taking a PendingIntent; see + * {@link #startActivityForResult(PendingIntent, int, Intent, int, int)} + * for more information. + */ + public void startActivityFromChild(Activity child, PendingIntent intent, + int requestCode, Intent fillInIntent, int flagsMask, int flagsValues) + throws PendingIntent.CanceledException { + startActivityForResultInner(intent, requestCode, fillInIntent, + flagsMask, flagsValues, child); + } + /** * Call this to set the result that your activity will return to its * caller. diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 4ed152e34631e..4796e49375e8b 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -144,6 +144,30 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeInt(result); return true; } + + case START_ACTIVITY_PENDING_INTENT_TRANSACTION: + { + data.enforceInterface(IActivityManager.descriptor); + IBinder b = data.readStrongBinder(); + IApplicationThread app = ApplicationThreadNative.asInterface(b); + PendingIntent intent = PendingIntent.CREATOR.createFromParcel(data); + Intent fillInIntent = null; + if (data.readInt() != 0) { + fillInIntent = Intent.CREATOR.createFromParcel(data); + } + String resolvedType = data.readString(); + IBinder resultTo = data.readStrongBinder(); + String resultWho = data.readString(); + int requestCode = data.readInt(); + int flagsMask = data.readInt(); + int flagsValues = data.readInt(); + int result = startActivityPendingIntent(app, intent, + fillInIntent, resolvedType, resultTo, resultWho, + requestCode, flagsMask, flagsValues); + reply.writeNoException(); + reply.writeInt(result); + return true; + } case START_NEXT_MATCHING_ACTIVITY_TRANSACTION: { @@ -1179,6 +1203,34 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); return result; } + public int startActivityPendingIntent(IApplicationThread caller, + PendingIntent intent, Intent fillInIntent, String resolvedType, + IBinder resultTo, String resultWho, int requestCode, + int flagsMask, int flagsValues) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(caller != null ? caller.asBinder() : null); + intent.writeToParcel(data, 0); + if (fillInIntent != null) { + data.writeInt(1); + fillInIntent.writeToParcel(data, 0); + } else { + data.writeInt(0); + } + data.writeString(resolvedType); + data.writeStrongBinder(resultTo); + data.writeString(resultWho); + data.writeInt(requestCode); + data.writeInt(flagsMask); + data.writeInt(flagsValues); + mRemote.transact(START_ACTIVITY_PENDING_INTENT_TRANSACTION, data, reply, 0); + reply.readException(); + int result = reply.readInt(); + reply.recycle(); + data.recycle(); + return result; + } public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent) throws RemoteException { Parcel data = Parcel.obtain(); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index a937c11f789cd..82446455cddc1 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -77,10 +77,16 @@ public interface IActivityManager extends IInterface { public static final int START_CLASS_NOT_FOUND = -2; public static final int START_FORWARD_AND_REQUEST_CONFLICT = -3; public static final int START_PERMISSION_DENIED = -4; + public static final int START_NOT_ACTIVITY = -5; + public static final int START_CANCELED = -6; public int startActivity(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) throws RemoteException; + public int startActivityPendingIntent(IApplicationThread caller, + PendingIntent intent, Intent fillInIntent, String resolvedType, + IBinder resultTo, String resultWho, int requestCode, + int flagsMask, int flagsValues) throws RemoteException; public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent) throws RemoteException; public boolean finishActivity(IBinder token, int code, Intent data) @@ -436,4 +442,5 @@ public interface IActivityManager extends IInterface { int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96; int GET_PROCESS_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+97; int KILL_APPLICATION_PROCESS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+98; + int START_ACTIVITY_PENDING_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+99; } diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java index e31f4f834404d..6d79aee973f96 100644 --- a/core/java/android/app/Instrumentation.java +++ b/core/java/android/app/Instrumentation.java @@ -1468,7 +1468,7 @@ public class Instrumentation { mWatcher = watcher; } - /*package*/ static void checkStartActivityResult(int res, Intent intent) { + /*package*/ static void checkStartActivityResult(int res, Object intent) { if (res >= IActivityManager.START_SUCCESS) { return; } @@ -1476,10 +1476,10 @@ public class Instrumentation { switch (res) { case IActivityManager.START_INTENT_NOT_RESOLVED: case IActivityManager.START_CLASS_NOT_FOUND: - if (intent.getComponent() != null) + if (intent instanceof Intent && ((Intent)intent).getComponent() != null) throw new ActivityNotFoundException( "Unable to find explicit activity class " - + intent.getComponent().toShortString() + + ((Intent)intent).getComponent().toShortString() + "; have you declared this activity in your AndroidManifest.xml?"); throw new ActivityNotFoundException( "No Activity found to handle " + intent); @@ -1489,6 +1489,9 @@ public class Instrumentation { case IActivityManager.START_FORWARD_AND_REQUEST_CONFLICT: throw new AndroidRuntimeException( "FORWARD_RESULT_FLAG used while also requesting a result"); + case IActivityManager.START_NOT_ACTIVITY: + throw new IllegalArgumentException( + "PendingIntent is not an activity"); default: throw new AndroidRuntimeException("Unknown error code " + res + " when starting " + intent); diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index f7479bcdb8bf0..18d9b92fbc5cd 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -519,7 +519,8 @@ public final class PendingIntent implements Parcelable { mTarget = IIntentSender.Stub.asInterface(target); } - /*package*/ IIntentSender getTarget() { + /** @hide */ + public IIntentSender getTarget() { return mTarget; } } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 95b5730c0fecd..e5659d57a0cb1 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -22,7 +22,10 @@ import com.android.internal.view.BaseSurfaceHolder; import android.app.Service; import android.app.WallpaperManager; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.graphics.Rect; import android.os.IBinder; import android.os.Message; @@ -88,6 +91,8 @@ public abstract class WallpaperService extends Service { boolean mInitializing = true; boolean mVisible; + boolean mScreenOn = true; + boolean mReportedVisible; boolean mDestroyed; // Current window state. @@ -117,6 +122,19 @@ public abstract class WallpaperService extends Service { float mPendingYOffset; MotionEvent mPendingMove; + final BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) { + mScreenOn = true; + reportVisibility(); + } else if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) { + mScreenOn = false; + reportVisibility(); + } + } + }; + final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() { @Override @@ -239,7 +257,7 @@ public abstract class WallpaperService extends Service { * {@link #onVisibilityChanged(boolean)}. */ public boolean isVisible() { - return mVisible; + return mReportedVisible; } /** @@ -489,6 +507,11 @@ public abstract class WallpaperService extends Service { mSession = ViewRoot.getWindowSession(getMainLooper()); mWindow.setSession(mSession); + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_SCREEN_ON); + filter.addAction(Intent.ACTION_SCREEN_OFF); + registerReceiver(mReceiver, filter); + if (DEBUG) Log.v(TAG, "onCreate(): " + this); onCreate(mSurfaceHolder); @@ -505,11 +528,19 @@ public abstract class WallpaperService extends Service { } void doVisibilityChanged(boolean visible) { + mVisible = visible; + reportVisibility(); + } + + void reportVisibility() { if (!mDestroyed) { - mVisible = visible; - if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + visible - + "): " + this); - onVisibilityChanged(visible); + boolean visible = mVisible && mScreenOn; + if (mReportedVisible != visible) { + mReportedVisible = visible; + if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + visible + + "): " + this); + onVisibilityChanged(visible); + } } } @@ -562,6 +593,8 @@ public abstract class WallpaperService extends Service { if (DEBUG) Log.v(TAG, "onDestroy(): " + this); onDestroy(); + unregisterReceiver(mReceiver); + if (mCreated) { try { mSession.remove(mWindow); diff --git a/core/res/res/anim/activity_close_enter.xml b/core/res/res/anim/activity_close_enter.xml new file mode 100644 index 0000000000000..9d1ef53743a24 --- /dev/null +++ b/core/res/res/anim/activity_close_enter.xml @@ -0,0 +1,25 @@ + + + + + + diff --git a/core/res/res/anim/activity_close_exit.xml b/core/res/res/anim/activity_close_exit.xml new file mode 100644 index 0000000000000..47cb6d69423b8 --- /dev/null +++ b/core/res/res/anim/activity_close_exit.xml @@ -0,0 +1,24 @@ + + + + + + diff --git a/core/res/res/anim/activity_open_enter.xml b/core/res/res/anim/activity_open_enter.xml new file mode 100644 index 0000000000000..e4c7e9bcc9d5b --- /dev/null +++ b/core/res/res/anim/activity_open_enter.xml @@ -0,0 +1,24 @@ + + + + + + diff --git a/core/res/res/anim/activity_open_exit.xml b/core/res/res/anim/activity_open_exit.xml new file mode 100644 index 0000000000000..9d47b7f59c332 --- /dev/null +++ b/core/res/res/anim/activity_open_exit.xml @@ -0,0 +1,25 @@ + + + + + + diff --git a/core/res/res/anim/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml index c289869cafcb7..303cfd6827381 100644 --- a/core/res/res/anim/task_close_enter.xml +++ b/core/res/res/anim/task_close_enter.xml @@ -1,8 +1,7 @@ - + android:interpolator="@anim/decelerate_interpolator"> + diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml index 96fff94a27b10..a28ac3ba902a6 100644 --- a/core/res/res/anim/task_close_exit.xml +++ b/core/res/res/anim/task_close_exit.xml @@ -1,8 +1,7 @@ - + android:interpolator="@anim/decelerate_interpolator" + android:zAdjustment="top"> + + diff --git a/core/res/res/anim/task_open_enter.xml b/core/res/res/anim/task_open_enter.xml index 8e7d049ce8537..234abb23cbcda 100644 --- a/core/res/res/anim/task_open_enter.xml +++ b/core/res/res/anim/task_open_enter.xml @@ -1,8 +1,7 @@ - + android:interpolator="@anim/decelerate_interpolator" + android:zAdjustment="top"> + + diff --git a/core/res/res/anim/task_open_exit.xml b/core/res/res/anim/task_open_exit.xml index 5e5c66d0edf50..98975fb92fcc6 100644 --- a/core/res/res/anim/task_open_exit.xml +++ b/core/res/res/anim/task_open_exit.xml @@ -1,8 +1,7 @@ + + + + + diff --git a/core/res/res/anim/translucent_exit.xml b/core/res/res/anim/translucent_exit.xml new file mode 100644 index 0000000000000..1d424e18d3be8 --- /dev/null +++ b/core/res/res/anim/translucent_exit.xml @@ -0,0 +1,26 @@ + + + + + + + diff --git a/core/res/res/anim/wallpaper_close_enter.xml b/core/res/res/anim/wallpaper_close_enter.xml index 8e7d049ce8537..e4c7e9bcc9d5b 100644 --- a/core/res/res/anim/wallpaper_close_enter.xml +++ b/core/res/res/anim/wallpaper_close_enter.xml @@ -1,8 +1,7 @@ + - + diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index bfdce1e25328a..3b9590d246526 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -306,19 +306,22 @@