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

Commit 296c42e4 authored by Ryan Lin's avatar Ryan Lin Committed by Android (Google) Code Review
Browse files

Merge "Add uninstall option in the capabilities confirm dialog" into sc-dev

parents 588c4e15 4806a385
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -134,6 +134,11 @@
                android:text="@string/accessibility_dialog_button_deny"
                style="@style/AccessibilityDialogButton" />

            <Button
                android:id="@+id/permission_enable_uninstall_button"
                android:text="@string/uninstall_text"
                android:visibility="gone"
                style="@style/AccessibilityDialogButton" />
        </LinearLayout>
    </LinearLayout>

+22 −4
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;

@@ -60,11 +61,19 @@ public class AccessibilityServiceWarning {
        return false;
    };

    /**
     * The interface to execute the uninstallation action.
     */
    interface UninstallActionPerformer {
        void uninstallPackage();
    }

    /** Returns a {@link Dialog} to be shown to confirm that they want to enable a service. */
    public static Dialog createCapabilitiesDialog(Context context,
            AccessibilityServiceInfo info, View.OnClickListener listener) {
    public static Dialog createCapabilitiesDialog(@NonNull Context context,
            @NonNull AccessibilityServiceInfo info, @NonNull View.OnClickListener listener,
            @NonNull UninstallActionPerformer performer) {
        final AlertDialog ad = new AlertDialog.Builder(context)
                .setView(createEnableDialogContentView(context, info, listener))
                .setView(createEnableDialogContentView(context, info, listener, performer))
                .create();

        Window window = ad.getWindow();
@@ -88,7 +97,8 @@ public class AccessibilityServiceWarning {
    }

    private static View createEnableDialogContentView(Context context,
            AccessibilityServiceInfo info, View.OnClickListener listener) {
            @NonNull AccessibilityServiceInfo info, View.OnClickListener listener,
            UninstallActionPerformer performer) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);

@@ -129,6 +139,14 @@ public class AccessibilityServiceWarning {
        permissionAllowButton.setOnTouchListener(filterTouchListener);
        permissionDenyButton.setOnClickListener(listener);

        final Button uninstallButton = content.findViewById(
                R.id.permission_enable_uninstall_button);
        // Shows an uninstall button to help users quickly remove the non-system App due to the
        // required permissions.
        if (!AccessibilityUtil.isSystemApp(info)) {
            uninstallButton.setVisibility(View.VISIBLE);
            uninstallButton.setOnClickListener(v -> performer.uninstallPackage());
        }
        return content;
    }

+9 −0
Original line number Diff line number Diff line
@@ -381,4 +381,13 @@ final class AccessibilityUtil {
        return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, screenHeightDp,
                resources.getDisplayMetrics()));
    }

    /**
     * Indicates if the accessibility service belongs to a system App.
     * @param info AccessibilityServiceInfo
     * @return {@code true} if the App is a system App.
     */
    public static boolean isSystemApp(@NonNull AccessibilityServiceInfo info) {
        return info.getResolveInfo().serviceInfo.applicationInfo.isSystemApp();
    }
}
+82 −4
Original line number Diff line number Diff line
@@ -24,10 +24,14 @@ import android.app.Activity;
import android.app.Dialog;
import android.app.admin.DevicePolicyManager;
import android.app.settings.SettingsEnums;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.net.Uri;
@@ -37,12 +41,14 @@ import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.Switch;

import androidx.annotation.Nullable;
import androidx.preference.Preference;

import com.android.internal.widget.LockPatternUtils;
@@ -59,7 +65,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class ToggleAccessibilityServicePreferenceFragment extends
        ToggleFeaturePreferenceFragment {

    public static final int ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION = 1;
    private static final String TAG = "ToggleAccessibilityServicePreferenceFragment";
    private static final int ACTIVITY_REQUEST_CONFIRM_CREDENTIAL_FOR_WEAKER_ENCRYPTION = 1;
    private LockPatternUtils mLockPatternUtils;
    private AtomicBoolean mIsDialogShown = new AtomicBoolean(/* initialValue= */ false);

@@ -74,6 +81,7 @@ public class ToggleAccessibilityServicePreferenceFragment extends
            };

    private Dialog mDialog;
    private BroadcastReceiver mPackageRemovedReceiver;

    @Override
    public int getMetricsCategory() {
@@ -93,6 +101,17 @@ public class ToggleAccessibilityServicePreferenceFragment extends
        mLockPatternUtils = new LockPatternUtils(getPrefContext());
    }

    @Override
    public void onStart() {
        super.onStart();
        final AccessibilityServiceInfo serviceInfo = getAccessibilityServiceInfo();
        if (serviceInfo == null) {
            getActivity().finishAndRemoveTask();
        } else if (!AccessibilityUtil.isSystemApp(serviceInfo)) {
            registerPackageRemoveReceiver();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
@@ -111,6 +130,7 @@ public class ToggleAccessibilityServicePreferenceFragment extends
    // capabilities. For
    // example, before JellyBean MR2 the user was granting the explore by touch
    // one.
    @Nullable
    AccessibilityServiceInfo getAccessibilityServiceInfo() {
        final List<AccessibilityServiceInfo> infos = AccessibilityManager.getInstance(
                getPrefContext()).getInstalledAccessibilityServiceList();
@@ -136,7 +156,8 @@ public class ToggleAccessibilityServicePreferenceFragment extends
                }
                mDialog = AccessibilityServiceWarning
                        .createCapabilitiesDialog(getPrefContext(), info,
                                this::onDialogButtonFromEnableToggleClicked);
                                this::onDialogButtonFromEnableToggleClicked,
                                this::onDialogButtonFromUninstallClicked);
                break;
            }
            case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT_TOGGLE: {
@@ -146,7 +167,8 @@ public class ToggleAccessibilityServicePreferenceFragment extends
                }
                mDialog = AccessibilityServiceWarning
                        .createCapabilitiesDialog(getPrefContext(), info,
                                this::onDialogButtonFromShortcutToggleClicked);
                                this::onDialogButtonFromShortcutToggleClicked,
                                this::onDialogButtonFromUninstallClicked);
                break;
            }
            case DialogEnums.ENABLE_WARNING_FROM_SHORTCUT: {
@@ -156,7 +178,8 @@ public class ToggleAccessibilityServicePreferenceFragment extends
                }
                mDialog = AccessibilityServiceWarning
                        .createCapabilitiesDialog(getPrefContext(), info,
                                this::onDialogButtonFromShortcutClicked);
                                this::onDialogButtonFromShortcutClicked,
                                this::onDialogButtonFromUninstallClicked);
                break;
            }
            case DialogEnums.DISABLE_WARNING_FROM_TOGGLE: {
@@ -246,6 +269,32 @@ public class ToggleAccessibilityServicePreferenceFragment extends
        }
    }

    private void registerPackageRemoveReceiver() {
        if (mPackageRemovedReceiver != null || getContext() == null) {
            return;
        }
        mPackageRemovedReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                final String packageName = intent.getData().getSchemeSpecificPart();
                if (TextUtils.equals(mComponentName.getPackageName(), packageName)) {
                    getActivity().finishAndRemoveTask();
                }
            }
        };
        final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
        filter.addDataScheme("package");
        getContext().registerReceiver(mPackageRemovedReceiver, filter);
    }

    private void unregisterPackageRemoveReceiver() {
        if (mPackageRemovedReceiver == null || getContext() == null) {
            return;
        }
        getContext().unregisterReceiver(mPackageRemovedReceiver);
        mPackageRemovedReceiver = null;
    }

    private boolean isServiceSupportAccessibilityButton() {
        final AccessibilityManager ams = getPrefContext().getSystemService(
                AccessibilityManager.class);
@@ -378,6 +427,35 @@ public class ToggleAccessibilityServicePreferenceFragment extends
        }
    }

    private void onDialogButtonFromUninstallClicked() {
        mDialog.dismiss();
        final Intent uninstallIntent = createUninstallPackageActivityIntent();
        if (uninstallIntent == null) {
            return;
        }
        startActivity(uninstallIntent);
    }

    @Nullable
    private Intent createUninstallPackageActivityIntent() {
        final AccessibilityServiceInfo a11yServiceInfo = getAccessibilityServiceInfo();
        if (a11yServiceInfo == null) {
            Log.w(TAG, "createUnInstallIntent -- invalid a11yServiceInfo");
            return null;
        }
        final ApplicationInfo appInfo =
                a11yServiceInfo.getResolveInfo().serviceInfo.applicationInfo;
        final Uri packageUri = Uri.parse("package:" + appInfo.packageName);
        final Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageUri);
        return uninstallIntent;
    }

    @Override
    public void onStop() {
        super.onStop();
        unregisterPackageRemoveReceiver();
    }

    private void onAllowButtonFromEnableToggleClicked() {
        if (isFullDiskEncrypted()) {
            final String title = createConfirmCredentialReasonMessage();