Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 149e0fe8 authored by kholoud mohamed's avatar kholoud mohamed
Browse files

Fix crash in IntentForwarderActivity

The crash was caused by trying to resolve an instant
app which is not allowed on the main thread, fixed it by
resolving on a background thread.

Fixes: 146141583
Test: atest IntentForwarderActivityTest
Test: atest ResolverActivityTest
Test: atest ChooserActivityTest
Change-Id: I250d682cf90870c7360eb66529be8c91fac266b1
parent a16b8b31
Loading
Loading
Loading
Loading
+52 −27
Original line number Diff line number Diff line
@@ -50,6 +50,9 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * This is used in conjunction with
@@ -74,11 +77,13 @@ public class IntentForwarderActivity extends Activity {
    private Injector mInjector;

    private MetricsLogger mMetricsLogger;
    protected ExecutorService mExecutorService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mInjector = createInjector();
        mExecutorService = Executors.newSingleThreadExecutor();

        Intent intentReceived = getIntent();
        String className = intentReceived.getComponent().getClassName();
@@ -118,35 +123,52 @@ public class IntentForwarderActivity extends Activity {
                mInjector.getIPackageManager(), getContentResolver());
        if (newIntent != null) {
            newIntent.prepareToLeaveUser(callingUserId);
            maybeShowDisclosureAsync(intentReceived, newIntent, targetUserId, userMessageId);
            CompletableFuture.runAsync(() -> startActivityAsCaller(
                    newIntent, targetUserId), mExecutorService);
        } else {
            Slog.wtf(TAG, "the intent: " + intentReceived + " cannot be forwarded from user "
                    + callingUserId + " to user " + targetUserId);
        }
        finish();
    }

    private void maybeShowDisclosureAsync(
            Intent intentReceived, Intent newIntent, int userId, int messageId) {
        final CompletableFuture<ResolveInfo> resolveInfoFuture =
                mInjector.resolveActivityAsUser(newIntent, MATCH_DEFAULT_ONLY, userId);
        resolveInfoFuture.thenAcceptAsync(ri -> {
            if (shouldShowDisclosure(ri, intentReceived)) {
                mInjector.showToast(messageId, Toast.LENGTH_LONG);
            }
        }, getApplicationContext().getMainExecutor());
    }

            final ResolveInfo ri = mInjector.resolveActivityAsUser(newIntent, MATCH_DEFAULT_ONLY,
                    targetUserId);
    private void startActivityAsCaller(Intent newIntent, int userId) {
        try {
                startActivityAsCaller(newIntent, null, null, false, targetUserId);
            startActivityAsCaller(
                    newIntent,
                    /* options= */ null,
                    /* permissionToken= */ null,
                    /* ignoreTargetSecurity= */ false,
                    userId);
        } catch (RuntimeException e) {
            int launchedFromUid = -1;
            String launchedFromPackage = "?";
            try {
                launchedFromUid = ActivityTaskManager.getService().getLaunchedFromUid(
                        getActivityToken());
                    launchedFromPackage = ActivityTaskManager.getService().getLaunchedFromPackage(
                            getActivityToken());
                launchedFromPackage = ActivityTaskManager.getService()
                        .getLaunchedFromPackage(getActivityToken());
            } catch (RemoteException ignored) {
            }

            Slog.wtf(TAG, "Unable to launch as UID " + launchedFromUid + " package "
                    + launchedFromPackage + ", while running in "
                    + ActivityThread.currentProcessName(), e);
        } finally {
            mExecutorService.shutdown();
        }

            if (shouldShowDisclosure(ri, intentReceived)) {
                mInjector.showToast(userMessageId, Toast.LENGTH_LONG);
            }
        } else {
            Slog.wtf(TAG, "the intent: " + intentReceived + " cannot be forwarded from user "
                    + callingUserId + " to user " + targetUserId);
        }
        finish();
    }

    private void launchChooserActivityWithCorrectTab(Intent intentReceived, String className) {
@@ -322,8 +344,11 @@ public class IntentForwarderActivity extends Activity {
        }

        @Override
        public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
            return getPackageManager().resolveActivityAsUser(intent, flags, userId);
        @Nullable
        public CompletableFuture<ResolveInfo> resolveActivityAsUser(
                Intent intent, int flags, int userId) {
            return CompletableFuture.supplyAsync(
                    () -> getPackageManager().resolveActivityAsUser(intent, flags, userId));
        }

        @Override
@@ -339,7 +364,7 @@ public class IntentForwarderActivity extends Activity {

        PackageManager getPackageManager();

        ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId);
        CompletableFuture<ResolveInfo> resolveActivityAsUser(Intent intent, int flags, int userId);

        void showToast(@StringRes int messageId, int duration);
    }
+10 −2
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@ import org.mockito.MockitoAnnotations;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@RunWith(AndroidJUnit4.class)
public class IntentForwarderActivityTest {
@@ -633,6 +635,11 @@ public class IntentForwarderActivityTest {
        public void onCreate(@Nullable Bundle savedInstanceState) {
            getIntent().setComponent(sComponentName);
            super.onCreate(savedInstanceState);
            try {
                mExecutorService.awaitTermination(/* timeout= */ 30, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        @Override
@@ -671,7 +678,8 @@ public class IntentForwarderActivityTest {
        }

        @Override
        public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
        public CompletableFuture<ResolveInfo> resolveActivityAsUser(
                Intent intent, int flags, int userId) {
            ActivityInfo activityInfo = new ActivityInfo();
            activityInfo.packageName = sPackageName;
            activityInfo.name = sActivityName;
@@ -680,7 +688,7 @@ public class IntentForwarderActivityTest {
            ResolveInfo resolveInfo = new ResolveInfo();
            resolveInfo.activityInfo = activityInfo;

            return resolveInfo;
            return CompletableFuture.completedFuture(resolveInfo);
        }

        @Override