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

Commit 8dfe7994 authored by Cole Faust's avatar Cole Faust Committed by Android (Google) Code Review
Browse files

Merge "Allow automotive OEMs to customize the permission dialog" into rvc-dev

parents 47af6145 fb063a77
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -54,6 +54,9 @@
    <!-- Title for the dialog button to deny a permission grant despite a warning of implications. [CHAR LIMIT=15] -->
    <string name="grant_dialog_button_deny_anyway">Deny anyway</string>

    <!-- Alternative dialog button to deny a permission, but phrased as dismissing the dialog. Currently only used in automotive. [CHAR LIMIT=20] -->
    <string name="grant_dialog_button_dismiss">Dismiss</string>

    <!-- Template for the current permission from the total number of permissions. [CHAR LIMIT=100] -->
    <string name="current_permission_template">
        <xliff:g id="current_permission_index" example="1">%1$s</xliff:g> of
+75 −41
Original line number Diff line number Diff line
@@ -16,26 +16,40 @@

package com.android.permissioncontroller.permission.ui.auto;

import static com.android.permissioncontroller.permission.ui.GrantPermissionsActivity.ALLOW_ALWAYS_BUTTON;
import static com.android.permissioncontroller.permission.ui.GrantPermissionsActivity.ALLOW_BUTTON;
import static com.android.permissioncontroller.permission.ui.GrantPermissionsActivity.ALLOW_FOREGROUND_BUTTON;
import static com.android.permissioncontroller.permission.ui.GrantPermissionsActivity.ALLOW_ONE_TIME_BUTTON;
import static com.android.permissioncontroller.permission.ui.GrantPermissionsActivity.DENY_AND_DONT_ASK_AGAIN_BUTTON;
import static com.android.permissioncontroller.permission.ui.GrantPermissionsActivity.DENY_BUTTON;
import static com.android.permissioncontroller.permission.ui.GrantPermissionsActivity.NO_UPGRADE_AND_DONT_ASK_AGAIN_BUTTON;
import static com.android.permissioncontroller.permission.ui.GrantPermissionsActivity.NO_UPGRADE_BUTTON;
import static com.android.permissioncontroller.permission.ui.GrantPermissionsActivity.NO_UPGRADE_OT_AND_DONT_ASK_AGAIN_BUTTON;
import static com.android.permissioncontroller.permission.ui.GrantPermissionsActivity.NO_UPGRADE_OT_BUTTON;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;

import com.android.car.ui.AlertDialogBuilder;
import com.android.car.ui.recyclerview.CarUiContentListItem;
import com.android.car.ui.recyclerview.CarUiListItem;
import com.android.car.ui.recyclerview.CarUiListItemAdapter;
import com.android.permissioncontroller.R;
import com.android.permissioncontroller.permission.ui.GrantPermissionsViewHandler;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

/**
 * A {@link GrantPermissionsViewHandler} that is specific for the auto use-case. In this case, the
 * permissions dialog is displayed using car-ui-lib {@link AlertDialogBuilder}
 */
public class GrantPermissionsAutoViewHandler implements GrantPermissionsViewHandler,
        DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
public class GrantPermissionsAutoViewHandler implements GrantPermissionsViewHandler {
    private static final String ARG_GROUP_NAME = "ARG_GROUP_NAME";
    private static final String ARG_GROUP_COUNT = "ARG_GROUP_COUNT";
    private static final String ARG_GROUP_INDEX = "ARG_GROUP_INDEX";
@@ -94,27 +108,69 @@ public class GrantPermissionsAutoViewHandler implements GrantPermissionsViewHand
        if (mDialog != null) {
            mDialog.setOnDismissListener(null);
            mDialog.dismiss();
            mDialog = null;
        }

        AlertDialogBuilder builder = new AlertDialogBuilder(mContext)
                .setTitle(mContext.getString(R.string.permission_request_title))
                .setMessage(mGroupMessage)
                .setIcon(mGroupIcon.loadDrawable(mContext))
                .setIconTinted(true)
                .setOnDismissListener(this)
                .setNeutralButton(mContext.getString(R.string.grant_dialog_button_deny), this)
                .setPositiveButton(mContext.getString(R.string.grant_dialog_button_allow), this);
        if (mButtonVisibilities[DENY_AND_DONT_ASK_AGAIN_BUTTON]) {
            builder.setNegativeButton(mContext.getString(R.string.never_ask_again), this);
        }
        if (mGroupCount > 1) {
            builder.setSubtitle(mContext.getString(R.string.current_permission_template,
                    mGroupIndex + 1, mGroupCount));
        }
                .setTitle(mGroupMessage)
                .setSubtitle(mDetailMessage)
                .setNegativeButton(R.string.grant_dialog_button_dismiss, (dialog, which) ->
                        dialog.dismiss())
                .setOnDismissListener((dialog) -> {
                    mDialog = null;
                    mResultListener.onPermissionGrantResult(mGroupName, DENIED);
                });
        if (mGroupIcon != null) {
            builder.setIcon(mGroupIcon.loadDrawable(mContext));
        }

        List<CarUiListItem> itemList = new ArrayList<>();

        // Don't show the allow one time button as per automotive design decisions
        createListItem(itemList, R.string.grant_dialog_button_allow,
                GRANTED_ALWAYS, ALLOW_BUTTON, ALLOW_ONE_TIME_BUTTON);
        createListItem(itemList, R.string.grant_dialog_button_allow_always,
                GRANTED_ALWAYS, ALLOW_ALWAYS_BUTTON);
        createListItem(itemList, R.string.grant_dialog_button_allow_foreground,
                GRANTED_FOREGROUND_ONLY, ALLOW_FOREGROUND_BUTTON);
        createListItem(itemList, R.string.grant_dialog_button_deny,
                DENIED, DENY_BUTTON);
        createListItem(itemList, R.string.grant_dialog_button_deny_and_dont_ask_again,
                DENIED_DO_NOT_ASK_AGAIN, DENY_AND_DONT_ASK_AGAIN_BUTTON);

        // It seems even on phone the same strings are used for "no upgrade" and
        // "no upgrade don't ask again"
        createListItem(itemList, R.string.grant_dialog_button_no_upgrade, DENIED,
                NO_UPGRADE_BUTTON, NO_UPGRADE_OT_BUTTON);
        createListItem(itemList, R.string.grant_dialog_button_no_upgrade, DENIED_DO_NOT_ASK_AGAIN,
                NO_UPGRADE_AND_DONT_ASK_AGAIN_BUTTON, NO_UPGRADE_OT_AND_DONT_ASK_AGAIN_BUTTON);

        builder.setAdapter(new CarUiListItemAdapter(itemList));

        mDialog = builder.create();
        mDialog.show();
    }

    private void createListItem(List<CarUiListItem> list,
            int stringId, @Result int result, int... indices) {
        // Check that at least one of the indices is shown.
        if (IntStream.of(indices)
                .mapToObj(i -> i >= 0 && i < mButtonVisibilities.length && mButtonVisibilities[i])
                .noneMatch(b -> b)) {
            return;
        }

        CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE);
        item.setTitle(mContext.getString(stringId));
        item.setOnItemClickedListener(i -> {
            mDialog.setOnDismissListener(null);
            mDialog.dismiss();
            mDialog = null;
            mResultListener.onPermissionGrantResult(mGroupName, result);
        });
        list.add(item);
    }

    @Override
    public void saveInstanceState(Bundle arguments) {
        arguments.putString(ARG_GROUP_NAME, mGroupName);
@@ -124,7 +180,6 @@ public class GrantPermissionsAutoViewHandler implements GrantPermissionsViewHand
        arguments.putCharSequence(ARG_GROUP_MESSAGE, mGroupMessage);
        arguments.putCharSequence(ARG_GROUP_DETAIL_MESSAGE, mDetailMessage);
        arguments.putBooleanArray(ARG_BUTTON_VISIBILITIES, mButtonVisibilities);

    }

    @Override
@@ -140,32 +195,11 @@ public class GrantPermissionsAutoViewHandler implements GrantPermissionsViewHand
        update();
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        mDialog.setOnDismissListener(null);
        switch (which) {
            case DialogInterface.BUTTON_POSITIVE:
                mResultListener.onPermissionGrantResult(mGroupName, GRANTED_ALWAYS);
                break;
            case DialogInterface.BUTTON_NEUTRAL:
                mResultListener.onPermissionGrantResult(mGroupName, DENIED);
                break;
            case DialogInterface.BUTTON_NEGATIVE:
                mResultListener.onPermissionGrantResult(mGroupName, DENIED_DO_NOT_ASK_AGAIN);
                break;
        }
    }

    @Override
    public void onBackPressed() {
        if (mResultListener != null) {
            mResultListener.onPermissionGrantResult(mGroupName, DENIED);
        }
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        if (mResultListener != null) {
        if (mDialog != null) {
            mDialog.dismiss();
        } else if (mResultListener != null) {
            mResultListener.onPermissionGrantResult(mGroupName, DENIED);
        }
    }