mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 11:18:21 +00:00
Using a proxy activity for startActivityForResult
This ensures that the home task is never blocked by a different task Bug: 74500048 Change-Id: I01fd26f1d6242e39b2d8fabac5e064b748aebe62
This commit is contained in:
@@ -85,6 +85,13 @@
|
||||
android:name="com.android.launcher3.uioverrides.dynamicui.WallpaperManagerCompatVL$ColorExtractionService"
|
||||
tools:node="remove" />
|
||||
|
||||
<activity
|
||||
android:name="com.android.launcher3.proxy.ProxyActivityStarter"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"
|
||||
android:launchMode="singleTask"
|
||||
android:clearTaskOnLaunch="true"
|
||||
android:exported="false" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -72,7 +72,6 @@ import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
import android.widget.Toast;
|
||||
@@ -191,6 +190,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
private static final String RUNTIME_STATE = "launcher.state";
|
||||
// Type: PendingRequestArgs
|
||||
private static final String RUNTIME_STATE_PENDING_REQUEST_ARGS = "launcher.request_args";
|
||||
// Type: int
|
||||
private static final String RUNTIME_STATE_PENDING_REQUEST_CODE = "launcher.request_code";
|
||||
// Type: ActivityResultInfo
|
||||
private static final String RUNTIME_STATE_PENDING_ACTIVITY_RESULT = "launcher.activity_result";
|
||||
// Type: SparseArray<Parcelable>
|
||||
@@ -264,6 +265,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
* {@link #startActivityForResult(Intent, int)} or {@link #requestPermissions(String[], int)}
|
||||
*/
|
||||
private PendingRequestArgs mPendingRequestArgs;
|
||||
// Request id for any pending activity result
|
||||
private int mPendingActivityRequestCode = -1;
|
||||
|
||||
public ViewGroupFocusHelper mFocusHandler;
|
||||
|
||||
@@ -762,6 +765,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
@Override
|
||||
public void onActivityResult(
|
||||
final int requestCode, final int resultCode, final Intent data) {
|
||||
mPendingActivityRequestCode = -1;
|
||||
handleActivityResult(requestCode, resultCode, data);
|
||||
if (mLauncherCallbacks != null) {
|
||||
mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);
|
||||
@@ -890,9 +894,21 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
|
||||
UiFactory.onLauncherStateOrResumeChanged(this);
|
||||
AppLaunchTracker.INSTANCE.get(this).onReturnedToHome();
|
||||
resetPendingActivityResultIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
private void resetPendingActivityResultIfNeeded() {
|
||||
if (hasBeenResumed() && mPendingActivityRequestCode != -1 && isInState(NORMAL)) {
|
||||
UiFactory.resetPendingActivityResults(this, mPendingActivityRequestCode);
|
||||
}
|
||||
}
|
||||
|
||||
protected void onStateSet(LauncherState state) {
|
||||
getAppWidgetHost().setResumed(state == LauncherState.NORMAL);
|
||||
resetPendingActivityResultIfNeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
RaceConditionTracker.onEvent(ON_RESUME_EVT, ENTER);
|
||||
@@ -1009,6 +1025,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
if (requestArgs != null) {
|
||||
setWaitingForResult(requestArgs);
|
||||
}
|
||||
mPendingActivityRequestCode = savedState.getInt(RUNTIME_STATE_PENDING_REQUEST_CODE);
|
||||
|
||||
mPendingActivityResult = savedState.getParcelable(RUNTIME_STATE_PENDING_ACTIVITY_RESULT);
|
||||
|
||||
@@ -1392,6 +1409,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
if (mPendingRequestArgs != null) {
|
||||
outState.putParcelable(RUNTIME_STATE_PENDING_REQUEST_ARGS, mPendingRequestArgs);
|
||||
}
|
||||
outState.putInt(RUNTIME_STATE_PENDING_REQUEST_CODE, mPendingActivityRequestCode);
|
||||
|
||||
if (mPendingActivityResult != null) {
|
||||
outState.putParcelable(RUNTIME_STATE_PENDING_ACTIVITY_RESULT, mPendingActivityResult);
|
||||
}
|
||||
@@ -1448,17 +1467,29 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
|
||||
|
||||
@Override
|
||||
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
|
||||
super.startActivityForResult(intent, requestCode, options);
|
||||
if (requestCode != -1) {
|
||||
mPendingActivityRequestCode = requestCode;
|
||||
}
|
||||
if (requestCode == -1
|
||||
|| !UiFactory.startActivityForResult(this, intent, requestCode, options)) {
|
||||
super.startActivityForResult(intent, requestCode, options);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startIntentSenderForResult (IntentSender intent, int requestCode,
|
||||
public void startIntentSenderForResult(IntentSender intent, int requestCode,
|
||||
Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {
|
||||
try {
|
||||
super.startIntentSenderForResult(intent, requestCode,
|
||||
fillInIntent, flagsMask, flagsValues, extraFlags, options);
|
||||
} catch (IntentSender.SendIntentException e) {
|
||||
throw new ActivityNotFoundException();
|
||||
if (requestCode != -1) {
|
||||
mPendingActivityRequestCode = requestCode;
|
||||
}
|
||||
if (requestCode == -1 || !UiFactory.startIntentSenderForResult(this, intent, requestCode,
|
||||
fillInIntent, flagsMask, flagsValues, extraFlags, options)) {
|
||||
try {
|
||||
super.startIntentSenderForResult(intent, requestCode,
|
||||
fillInIntent, flagsMask, flagsValues, extraFlags, options);
|
||||
} catch (IntentSender.SendIntentException e) {
|
||||
throw new ActivityNotFoundException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -452,7 +452,7 @@ public class LauncherStateManager {
|
||||
}
|
||||
mState = state;
|
||||
mState.onStateEnabled(mLauncher);
|
||||
mLauncher.getAppWidgetHost().setResumed(state == LauncherState.NORMAL);
|
||||
mLauncher.onStateSet(mState);
|
||||
|
||||
if (state.disablePageClipping) {
|
||||
// Only disable clipping if needed, otherwise leave it as previous value.
|
||||
|
||||
@@ -46,6 +46,8 @@ import com.android.launcher3.ItemInfo;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherModel;
|
||||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.LauncherStateManager;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.FirstFrameAnimatorHelper;
|
||||
@@ -60,7 +62,7 @@ import androidx.dynamicanimation.animation.FloatPropertyCompat;
|
||||
import androidx.dynamicanimation.animation.SpringAnimation;
|
||||
import androidx.dynamicanimation.animation.SpringForce;
|
||||
|
||||
public class DragView extends View {
|
||||
public class DragView extends View implements LauncherStateManager.StateListener {
|
||||
private static final ColorMatrix sTempMatrix1 = new ColorMatrix();
|
||||
private static final ColorMatrix sTempMatrix2 = new ColorMatrix();
|
||||
|
||||
@@ -172,6 +174,27 @@ public class DragView extends View {
|
||||
setElevation(getResources().getDimension(R.dimen.drag_elevation));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
mLauncher.getStateManager().addStateListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
mLauncher.getStateManager().removeStateListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateTransitionStart(LauncherState toState) { }
|
||||
|
||||
@Override
|
||||
public void onStateTransitionComplete(LauncherState finalState) {
|
||||
setVisibility((finalState == LauncherState.NORMAL
|
||||
|| finalState == LauncherState.SPRING_LOADED) ? VISIBLE : INVISIBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize {@code #mIconDrawable} if the item can be represented using
|
||||
* an {@link AdaptiveIconDrawable} or {@link FolderAdaptiveIcon}.
|
||||
|
||||
@@ -18,6 +18,9 @@ package com.android.launcher3.uioverrides;
|
||||
|
||||
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 com.android.launcher3.DeviceProfile;
|
||||
@@ -79,4 +82,18 @@ public class UiFactory {
|
||||
public static RotationMode getRotationMode(DeviceProfile dp) {
|
||||
return RotationMode.NORMAL;
|
||||
}
|
||||
|
||||
public static boolean startIntentSenderForResult(Activity activity, IntentSender intent,
|
||||
int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
|
||||
Bundle options) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean startActivityForResult(Activity activity, Intent intent, int requestCode,
|
||||
Bundle options) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void resetPendingActivityResults(Launcher launcher, int requestCode) { }
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user