diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2019-05-14 15:23:48 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2019-05-15 16:33:06 -0700 |
commit | dedda05568a3f144c548d60e2bb1d7f5e7c58c6c (patch) | |
tree | e075cf6cd4d7fa5981428d14a00c132ba21837c2 /quickstep/src | |
parent | 7daf892f66d58715863c1ec4fb3f6f7cd373654d (diff) | |
download | android_packages_apps_Trebuchet-dedda05568a3f144c548d60e2bb1d7f5e7c58c6c.tar.gz android_packages_apps_Trebuchet-dedda05568a3f144c548d60e2bb1d7f5e7c58c6c.tar.bz2 android_packages_apps_Trebuchet-dedda05568a3f144c548d60e2bb1d7f5e7c58c6c.zip |
Using a proxy activity for startActivityForResult
This ensures that the home task is never blocked by a different task
Bug: 74500048
Change-Id: I01fd26f1d6242e39b2d8fabac5e064b748aebe62
Diffstat (limited to 'quickstep/src')
3 files changed, 226 insertions, 0 deletions
diff --git a/quickstep/src/com/android/launcher3/proxy/ProxyActivityStarter.java b/quickstep/src/com/android/launcher3/proxy/ProxyActivityStarter.java new file mode 100644 index 000000000..e302b4f15 --- /dev/null +++ b/quickstep/src/com/android/launcher3/proxy/ProxyActivityStarter.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.proxy; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.IntentSender.SendIntentException; +import android.os.Bundle; +import android.util.Log; + +public class ProxyActivityStarter extends Activity { + + private static final String TAG = "ProxyActivityStarter"; + + public static final String EXTRA_PARAMS = "start-activity-params"; + + private StartActivityParams mParams; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setVisible(false); + + mParams = getIntent().getParcelableExtra(EXTRA_PARAMS); + if (mParams == null) { + Log.d(TAG, "Proxy activity started without params"); + finishAndRemoveTask(); + return; + } + + if (savedInstanceState != null) { + // Already started the activity. Just wait for the result. + return; + } + + if (mParams.intent != null) { + startActivityForResult(mParams.intent, mParams.requestCode, mParams.options); + return; + } else if (mParams.intentSender != null) { + try { + startIntentSenderForResult(mParams.intentSender, mParams.requestCode, + mParams.fillInIntent, mParams.flagsMask, mParams.flagsValues, + mParams.extraFlags, + mParams.options); + return; + } catch (SendIntentException e) { + mParams.deliverResult(this, RESULT_CANCELED, null); + } + } + finishAndRemoveTask(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == mParams.requestCode) { + mParams.deliverResult(this, resultCode, data); + } + finishAndRemoveTask(); + } + + public static Intent getLaunchIntent(Context context, StartActivityParams params) { + return new Intent(context, ProxyActivityStarter.class) + .putExtra(EXTRA_PARAMS, params) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED + | Intent.FLAG_ACTIVITY_CLEAR_TASK); + } +} diff --git a/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java b/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java new file mode 100644 index 000000000..1e8bd933f --- /dev/null +++ b/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.proxy; + +import android.app.Activity; +import android.app.PendingIntent; +import android.app.PendingIntent.CanceledException; +import android.content.Context; +import android.content.Intent; +import android.content.IntentSender; +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +public class StartActivityParams implements Parcelable { + + private static final String TAG = "StartActivityParams"; + + private final PendingIntent mCallback; + public final int requestCode; + + public Intent intent; + + public IntentSender intentSender; + public Intent fillInIntent; + public int flagsMask; + public int flagsValues; + public int extraFlags; + public Bundle options; + + public StartActivityParams(Activity activity, int requestCode) { + mCallback = activity.createPendingResult(requestCode, new Intent(), + PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT); + this.requestCode = requestCode; + } + + private StartActivityParams(Parcel parcel) { + mCallback = parcel.readTypedObject(PendingIntent.CREATOR); + requestCode = parcel.readInt(); + intent = parcel.readTypedObject(Intent.CREATOR); + + intentSender = parcel.readTypedObject(IntentSender.CREATOR); + fillInIntent = parcel.readTypedObject(Intent.CREATOR); + flagsMask = parcel.readInt(); + flagsValues = parcel.readInt(); + extraFlags = parcel.readInt(); + options = parcel.readBundle(); + } + + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int flags) { + parcel.writeTypedObject(mCallback, flags); + parcel.writeInt(requestCode); + parcel.writeTypedObject(intent, flags); + + parcel.writeTypedObject(intentSender, flags); + parcel.writeTypedObject(fillInIntent, flags); + parcel.writeInt(flagsMask); + parcel.writeInt(flagsValues); + parcel.writeInt(extraFlags); + parcel.writeBundle(options); + } + + public void deliverResult(Context context, int resultCode, Intent data) { + try { + mCallback.send(context, resultCode, data); + } catch (CanceledException e) { + Log.e(TAG, "Unable to send back result", e); + } + } + + public static final Parcelable.Creator<StartActivityParams> CREATOR = + new Parcelable.Creator<StartActivityParams>() { + public StartActivityParams createFromParcel(Parcel source) { + return new StartActivityParams(source); + } + + public StartActivityParams[] newArray(int size) { + return new StartActivityParams[size]; + } + }; +} diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java index 77ac35c50..489174614 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java +++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java @@ -16,6 +16,8 @@ package com.android.launcher3.uioverrides; +import static android.app.Activity.RESULT_CANCELED; + import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON; import static com.android.launcher3.LauncherState.ALL_APPS; @@ -31,6 +33,9 @@ import android.animation.AnimatorSet; import android.animation.ValueAnimator; import android.app.Activity; import android.content.Context; +import android.content.Intent; +import android.content.IntentSender; +import android.os.Bundle; import android.os.CancellationSignal; import android.util.Base64; @@ -43,6 +48,8 @@ import com.android.launcher3.LauncherStateManager.StateHandler; import com.android.launcher3.QuickstepAppTransitionManagerImpl; import com.android.launcher3.Utilities; import com.android.launcher3.dragndrop.DragLayer; +import com.android.launcher3.proxy.ProxyActivityStarter; +import com.android.launcher3.proxy.StartActivityParams; import com.android.quickstep.OverviewInteractionState; import com.android.quickstep.RecentsModel; import com.android.quickstep.SysUINavigationMode; @@ -192,6 +199,40 @@ public class UiFactory extends RecentsUiFactory { return true; } + public static boolean startIntentSenderForResult(Activity activity, IntentSender intent, + int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, + Bundle options) { + StartActivityParams params = new StartActivityParams(activity, requestCode); + params.intentSender = intent; + params.fillInIntent = fillInIntent; + params.flagsMask = flagsMask; + params.flagsValues = flagsValues; + params.extraFlags = extraFlags; + params.options = options; + ((Context) activity).startActivity(ProxyActivityStarter.getLaunchIntent(activity, params)); + return true; + } + + public static boolean startActivityForResult(Activity activity, Intent intent, int requestCode, + Bundle options) { + StartActivityParams params = new StartActivityParams(activity, requestCode); + params.intent = intent; + params.options = options; + activity.startActivity(ProxyActivityStarter.getLaunchIntent(activity, params)); + return true; + } + + /** + * Removes any active ProxyActivityStarter task and sends RESULT_CANCELED to Launcher. + * + * ProxyActivityStarter is started with clear task to reset the task after which it removes the + * task itself. + */ + public static void resetPendingActivityResults(Launcher launcher, int requestCode) { + launcher.onActivityResult(requestCode, RESULT_CANCELED, null); + launcher.startActivity(ProxyActivityStarter.getLaunchIntent(launcher, null)); + } + public static ScaleAndTranslation getOverviewScaleAndTranslationForNormalState(Launcher l) { if (SysUINavigationMode.getMode(l) == Mode.NO_BUTTON) { float offscreenTranslationX = l.getDeviceProfile().widthPx |