Loading AndroidManifest.xml +8 −0 Original line number Diff line number Diff line Loading @@ -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"> Loading res/layout/request_role_item.xml +5 −1 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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" Loading @@ -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> Loading res/layout/request_role_view.xml 0 → 100644 +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> src/com/android/packageinstaller/Constants.java +17 −0 Original line number Diff line number Diff line Loading @@ -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:"; } src/com/android/packageinstaller/role/model/UserDeniedManager.java 0 → 100644 +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
AndroidManifest.xml +8 −0 Original line number Diff line number Diff line Loading @@ -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"> Loading
res/layout/request_role_item.xml +5 −1 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -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" Loading @@ -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> Loading
res/layout/request_role_view.xml 0 → 100644 +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>
src/com/android/packageinstaller/Constants.java +17 −0 Original line number Diff line number Diff line Loading @@ -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:"; }
src/com/android/packageinstaller/role/model/UserDeniedManager.java 0 → 100644 +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(); } } }