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

Commit 9e87cfb3 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add don't ask again when requesting role."

parents a562718b 64a3e702
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -276,6 +276,14 @@
            </intent-filter>
        </service>

        <receiver android:name="com.android.packageinstaller.role.service.ClearUserDeniedReceiver">
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_DATA_CLEARED" />
                <action android:name="android.intent.action.PACKAGE_FULLY_REMOVED"/>
                <data android:scheme="package" />
            </intent-filter>
        </receiver>

        <!-- Debug report authorization (bugreport and incident report) -->
        <receiver android:name="com.android.packageinstaller.incident.ConfirmationReceiver"
            android:exported="true">
+5 −1
Original line number Diff line number Diff line
@@ -30,7 +30,8 @@
    <ImageView
        android:id="@+id/icon"
        android:layout_width="32dp"
        android:layout_height="32dp" />
        android:layout_height="32dp"
        android:duplicateParentState="true" />

    <LinearLayout
        android:id="@+id/title_and_subtitle"
@@ -39,12 +40,14 @@
        android:layout_weight="1"
        android:layout_marginStart="16dp"
        android:animateLayoutChanges="true"
        android:duplicateParentState="true"
        android:orientation="vertical">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:duplicateParentState="true"
            android:textAppearance="?android:textAppearanceListItem"
            android:textColor="?android:textColorAlertDialogListItem"
            android:singleLine="true"
@@ -54,6 +57,7 @@
            android:id="@+id/subtitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:duplicateParentState="true"
            android:textAppearance="?android:textAppearanceListItemSecondary"
            android:textColor="?android:textColorSecondary" />
    </LinearLayout>
+36 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>

<!--
  ~ 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.
  -->

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingStart="?android:dialogPreferredPadding"
    android:paddingEnd="?android:dialogPreferredPadding"
    android:clipChildren="false"
    android:clipToPadding="false">

    <CheckBox
        android:id="@+id/dont_ask_again"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="40dp"
        android:paddingStart="16dp"
        android:text="@string/request_role_dont_ask_again"
        android:textAppearance="@style/android:TextAppearance.Material.Subhead" />
</FrameLayout>
+17 −0
Original line number Diff line number Diff line
@@ -118,4 +118,21 @@ public class Constants {
     * yet.
     */
    public static final String DELAYED_RESTORE_PERMISSIONS_FILE = "delayed_restore_permissions.xml";

    /**
     * Name of file containing the user denied status for requesting roles.
     */
    public static final String REQUEST_ROLE_USER_DENIED_FILE = "request_role_user_denied";

    /**
     * Key in the user denied status for requesting roles shared preferences that stores a string
     * set for the names of the roles that an application has been denied for once.
     */
    public static final String REQUEST_ROLE_USER_DENIED_ONCE_KEY_PREFIX = "denied_once:";

    /**
     * Key in the user denied status for requesting roles shared preferences that stores a string
     * set for the names of the roles that an application is always denied for.
     */
    public static final String REQUEST_ROLE_USER_DENIED_ALWAYS_KEY_PREFIX = "denied_always:";
}
+160 −0
Original line number Diff line number Diff line
/*
 * 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.packageinstaller.role.model;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.ArraySet;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.packageinstaller.Constants;

import java.util.Collections;
import java.util.Set;

/**
 * Manages user denied status for requesting roles.
 */
public class UserDeniedManager {

    @Nullable
    private static UserDeniedManager sInstance;

    private final SharedPreferences mPreferences;

    /**
     * Get a singleton instance of this class
     *
     * @param context the context for retrieving shared preferences.
     *
     * @return the singleton instance of this class
     */
    @NonNull
    public static UserDeniedManager getInstance(@NonNull Context context) {
        if (sInstance == null) {
            sInstance = new UserDeniedManager(context);
        }
        return sInstance;
    }

    private UserDeniedManager(@NonNull Context context) {
        context = context.getApplicationContext();
        mPreferences = context.getSharedPreferences(Constants.REQUEST_ROLE_USER_DENIED_FILE,
                Context.MODE_PRIVATE);
    }

    /**
     * Check whether an application has been denied for a role once.
     *
     * @param roleName the name of the role
     * @param packageName the package name of the application
     *
     * @return whether the application has been denied for the role once
     */
    public boolean isDeniedOnce(@NonNull String roleName, @NonNull String packageName) {
        return isDenied(roleName, packageName, false);
    }

    /**
     * Remember that an application has been denied for a role once.
     *
     * @param roleName the name of the role
     * @param packageName the package name of the application
     */
    public void setDeniedOnce(@NonNull String roleName, @NonNull String packageName) {
        setDenied(roleName, packageName, false, true);
    }

    /**
     * Check whether an application is always denied for a role.
     *
     * @param roleName the name of the role
     * @param packageName the package name of the application
     *
     * @return whether the application is always denied for the role
     */
    public boolean isDeniedAlways(@NonNull String roleName, @NonNull String packageName) {
        return isDenied(roleName, packageName, true);
    }

    /**
     * Remember that an application is always denied for a role.
     *
     * @param roleName the name of the role
     * @param packageName the package name of the application
     */
    public void setDeniedAlways(@NonNull String roleName, @NonNull String packageName) {
        setDenied(roleName, packageName, true, true);
    }

    /**
     * Forget about whether an application is denied for a role, once or always.
     *
     * @param roleName the name of the role
     * @param packageName the package name of the application
     */
    public void clearDenied(@NonNull String roleName, @NonNull String packageName) {
        setDenied(roleName, packageName, false, false);
        setDenied(roleName, packageName, true, false);
    }

    /**
     * Forget about whether an application is denied for any of the roles, once or always.
     *
     * @param packageName the package name of the application
     */
    public void clearPackageDenied(@NonNull String packageName) {
        mPreferences.edit()
                .remove(getKey(packageName, false))
                .remove(getKey(packageName, true))
                .apply();
    }

    @NonNull
    private static String getKey(@NonNull String packageName, boolean always) {
        return (always ? Constants.REQUEST_ROLE_USER_DENIED_ALWAYS_KEY_PREFIX
                : Constants.REQUEST_ROLE_USER_DENIED_ONCE_KEY_PREFIX) + packageName;
    }

    private boolean isDenied(@NonNull String roleName, @NonNull String packageName,
            boolean always) {
        String key = getKey(packageName, always);
        return mPreferences.getStringSet(key, Collections.emptySet()).contains(roleName);
    }

    private void setDenied(@NonNull String roleName, @NonNull String packageName, boolean always,
            boolean denied) {
        String key = getKey(packageName, always);
        Set<String> roleNames = mPreferences.getStringSet(key, Collections.emptySet());
        if (roleNames.contains(roleName) == denied) {
            return;
        }
        roleNames = new ArraySet<>(roleNames);
        if (denied) {
            roleNames.add(roleName);
        } else {
            roleNames.remove(roleName);
        }
        if (roleName.isEmpty()) {
            mPreferences.edit().remove(key).apply();
        } else {
            mPreferences.edit().putStringSet(key, roleNames).apply();
        }
    }
}
Loading