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

Commit 1ab90a2e authored by Suprabh Shukla's avatar Suprabh Shukla
Browse files

Fixing user tap on suspended widget

Widgets get masked with separate remove views when suspended. Need to
update them with the correct pending intent. Moved around the logic
creating the suspended alert activity to make it reusable.

Test: Manually, "pm suspend <app-with-widget>", followed by tap on
widget
Existing tests pass:
atest GtsSuspendAppsTestCases
atest com.android.server.am.ActivityStartInterceptorTest

Bug: 79474038
Change-Id: Ic75ee762434bf92c54bda307e9cb6018f94a914c
parent 1b69d7b4
Loading
Loading
Loading
Loading
+39 −12
Original line number Diff line number Diff line
@@ -16,10 +16,12 @@

package com.android.internal.app;

import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.UserHandle;
import android.util.Slog;
@@ -30,35 +32,47 @@ import com.android.internal.R;
public class SuspendedAppActivity extends AlertActivity
        implements DialogInterface.OnClickListener {
    private static final String TAG = "SuspendedAppActivity";

    public static final String EXTRA_SUSPENDED_PACKAGE =
            "SuspendedAppActivity.extra.SUSPENDED_PACKAGE";
    public static final String EXTRA_SUSPENDING_PACKAGE =
            "SuspendedAppActivity.extra.SUSPENDING_PACKAGE";
    public static final String EXTRA_DIALOG_MESSAGE = "SuspendedAppActivity.extra.DIALOG_MESSAGE";
    public static final String EXTRA_MORE_DETAILS_INTENT =
            "SuspendedAppActivity.extra.MORE_DETAILS_INTENT";

    private Intent mMoreDetailsIntent;
    private int mUserId;
    private PackageManager mPm;

    private CharSequence getAppLabel(String packageName) {
        final PackageManager pm = getPackageManager();
        try {
            return pm.getApplicationInfoAsUser(packageName, 0, mUserId).loadLabel(pm);
            return mPm.getApplicationInfoAsUser(packageName, 0, mUserId).loadLabel(mPm);
        } catch (PackageManager.NameNotFoundException ne) {
            Slog.e(TAG, "Package " + packageName + " not found", ne);
        }
        return packageName;
    }

    private Intent getMoreDetailsActivity(String suspendingPackage, String suspendedPackage,
            int userId) {
        final Intent moreDetailsIntent = new Intent(Intent.ACTION_SHOW_SUSPENDED_APP_DETAILS)
                .setPackage(suspendingPackage);
        final String requiredPermission = Manifest.permission.SEND_SHOW_SUSPENDED_APP_DETAILS;
        final ResolveInfo resolvedInfo = mPm.resolveActivityAsUser(moreDetailsIntent, 0, userId);
        if (resolvedInfo != null && resolvedInfo.activityInfo != null
                && requiredPermission.equals(resolvedInfo.activityInfo.permission)) {
            moreDetailsIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, suspendedPackage)
                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            return moreDetailsIntent;
        }
        return null;
    }

    @Override
    public void onCreate(Bundle icicle) {
        getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
        super.onCreate(icicle);
        mPm = getPackageManager();
        getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);

        final Intent intent = getIntent();
        mMoreDetailsIntent = intent.getParcelableExtra(EXTRA_MORE_DETAILS_INTENT);
        mUserId = intent.getIntExtra(Intent.EXTRA_USER_ID, -1);
        if (mUserId < 0) {
            Slog.wtf(TAG, "Invalid user: " + mUserId);
@@ -66,13 +80,13 @@ public class SuspendedAppActivity extends AlertActivity
            return;
        }
        final String suppliedMessage = intent.getStringExtra(EXTRA_DIALOG_MESSAGE);
        final CharSequence suspendedAppLabel = getAppLabel(
                intent.getStringExtra(EXTRA_SUSPENDED_PACKAGE));
        final String suspendedPackage = intent.getStringExtra(EXTRA_SUSPENDED_PACKAGE);
        final String suspendingPackage = intent.getStringExtra(EXTRA_SUSPENDING_PACKAGE);
        final CharSequence suspendedAppLabel = getAppLabel(suspendedPackage);
        final CharSequence dialogMessage;
        if (suppliedMessage == null) {
            dialogMessage = getString(R.string.app_suspended_default_message,
                    suspendedAppLabel,
                    getAppLabel(intent.getStringExtra(EXTRA_SUSPENDING_PACKAGE)));
            dialogMessage = getString(R.string.app_suspended_default_message, suspendedAppLabel,
                    getAppLabel(suspendingPackage));
        } else {
            dialogMessage = String.format(getResources().getConfiguration().getLocales().get(0),
                    suppliedMessage, suspendedAppLabel);
@@ -82,6 +96,7 @@ public class SuspendedAppActivity extends AlertActivity
        ap.mTitle = getString(R.string.app_suspended_title);
        ap.mMessage = dialogMessage;
        ap.mPositiveButtonText = getString(android.R.string.ok);
        mMoreDetailsIntent = getMoreDetailsActivity(suspendingPackage, suspendedPackage, mUserId);
        if (mMoreDetailsIntent != null) {
            ap.mNeutralButtonText = getString(R.string.app_suspended_more_details);
        }
@@ -99,4 +114,16 @@ public class SuspendedAppActivity extends AlertActivity
        }
        finish();
    }

    public static Intent createSuspendedAppInterceptIntent(String suspendedPackage,
            String suspendingPackage, String dialogMessage, int userId) {
        return new Intent()
                .setClassName("android", SuspendedAppActivity.class.getName())
                .putExtra(EXTRA_SUSPENDED_PACKAGE, suspendedPackage)
                .putExtra(EXTRA_DIALOG_MESSAGE, dialogMessage)
                .putExtra(EXTRA_SUSPENDING_PACKAGE, suspendingPackage)
                .putExtra(Intent.EXTRA_USER_ID, userId)
                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    }
}
+17 −2
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import static android.content.Context.KEYGUARD_SERVICE;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;

import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;

import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AlarmManager;
@@ -50,6 +52,7 @@ import android.content.pm.LauncherApps;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
@@ -96,6 +99,7 @@ import android.view.WindowManager;
import android.widget.RemoteViews;

import com.android.internal.R;
import com.android.internal.app.SuspendedAppActivity;
import com.android.internal.app.UnlaunchableAppActivity;
import com.android.internal.appwidget.IAppWidgetHost;
import com.android.internal.appwidget.IAppWidgetService;
@@ -228,6 +232,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
    private AppOpsManager mAppOpsManager;
    private KeyguardManager mKeyguardManager;
    private DevicePolicyManagerInternal mDevicePolicyManagerInternal;
    private PackageManagerInternal mPackageManagerInternal;

    private SecurityPolicy mSecurityPolicy;

@@ -254,6 +259,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
        mKeyguardManager = (KeyguardManager) mContext.getSystemService(KEYGUARD_SERVICE);
        mDevicePolicyManagerInternal = LocalServices.getService(DevicePolicyManagerInternal.class);
        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
        mSaveStateHandler = BackgroundThread.getHandler();
        mCallbackHandler = new CallbackHandler(mContext.getMainLooper());
        mBackupRestoreController = new BackupRestoreController();
@@ -620,8 +626,17 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
            if (provider.maskedBySuspendedPackage) {
                UserInfo userInfo = mUserManager.getUserInfo(providerUserId);
                showBadge = userInfo.isManagedProfile();
                final String suspendingPackage = mPackageManagerInternal.getSuspendingPackage(
                        providerPackage, providerUserId);
                if (PLATFORM_PACKAGE_NAME.equals(suspendingPackage)) {
                    onClickIntent = mDevicePolicyManagerInternal.createShowAdminSupportIntent(
                            providerUserId, true);
                } else {
                    final String dialogMessage = mPackageManagerInternal.getSuspendedDialogMessage(
                            providerPackage, providerUserId);
                    onClickIntent = SuspendedAppActivity.createSuspendedAppInterceptIntent(
                            providerPackage, suspendingPackage, dialogMessage, providerUserId);
                }
            } else if (provider.maskedByQuietProfile) {
                showBadge = true;
                onClickIntent = UnlaunchableAppActivity.createInQuietModeDialogIntent(
+2 −28
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;

import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;

import android.Manifest;
import android.app.ActivityOptions;
import android.app.KeyguardManager;
import android.app.admin.DevicePolicyManagerInternal;
@@ -233,31 +232,6 @@ class ActivityStartInterceptor {
        return true;
    }

    private Intent createSuspendedAppInterceptIntent(String suspendedPackage,
            String suspendingPackage, String dialogMessage, int userId) {
        final Intent interceptIntent = new Intent(mServiceContext, SuspendedAppActivity.class)
                .putExtra(SuspendedAppActivity.EXTRA_SUSPENDED_PACKAGE, suspendedPackage)
                .putExtra(SuspendedAppActivity.EXTRA_DIALOG_MESSAGE, dialogMessage)
                .putExtra(SuspendedAppActivity.EXTRA_SUSPENDING_PACKAGE, suspendingPackage)
                .putExtra(Intent.EXTRA_USER_ID, userId)
                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);

        final Intent moreDetailsIntent = new Intent(Intent.ACTION_SHOW_SUSPENDED_APP_DETAILS)
                .setPackage(suspendingPackage);
        final String requiredPermission = Manifest.permission.SEND_SHOW_SUSPENDED_APP_DETAILS;
        final ResolveInfo resolvedInfo = mSupervisor.resolveIntent(moreDetailsIntent, null, userId,
                0, mRealCallingUid);
        if (resolvedInfo != null && resolvedInfo.activityInfo != null
                && requiredPermission.equals(resolvedInfo.activityInfo.permission)) {
            moreDetailsIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, suspendedPackage)
                    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            interceptIntent.putExtra(SuspendedAppActivity.EXTRA_MORE_DETAILS_INTENT,
                    moreDetailsIntent);
        }
        return interceptIntent;
    }

    private boolean interceptSuspendedPackageIfNeeded() {
        // Do not intercept if the package is not suspended
        if (mAInfo == null || mAInfo.applicationInfo == null ||
@@ -274,8 +248,8 @@ class ActivityStartInterceptor {
            return interceptSuspendedByAdminPackage();
        }
        final String dialogMessage = pmi.getSuspendedDialogMessage(suspendedPackage, mUserId);
        mIntent = createSuspendedAppInterceptIntent(suspendedPackage, suspendingPackage,
                dialogMessage, mUserId);
        mIntent = SuspendedAppActivity.createSuspendedAppInterceptIntent(suspendedPackage,
                suspendingPackage, dialogMessage, mUserId);
        mCallingPid = mRealCallingPid;
        mCallingUid = mRealCallingUid;
        mResolvedType = null;