1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.permissioncontroller.role.model; 18 19 import android.content.Context; 20 import android.content.pm.ApplicationInfo; 21 22 import androidx.annotation.NonNull; 23 import androidx.annotation.Nullable; 24 25 import com.android.permissioncontroller.role.utils.PackageUtils; 26 27 import java.util.Objects; 28 29 /** 30 * An app op to be granted or revoke by a {@link Role}. 31 */ 32 public class AppOp { 33 34 /** 35 * The name of this app op. 36 */ 37 @NonNull 38 private final String mName; 39 40 /** 41 * The maximum target SDK version for this app op to be granted, or {@code null} if none. 42 */ 43 @Nullable 44 private final Integer mMaxTargetSdkVersion; 45 46 /** 47 * The mode of this app op when granted. 48 */ 49 private final int mMode; 50 AppOp(@onNull String name, @Nullable Integer maxTargetSdkVersion, int mode)51 public AppOp(@NonNull String name, @Nullable Integer maxTargetSdkVersion, int mode) { 52 mName = name; 53 mMaxTargetSdkVersion = maxTargetSdkVersion; 54 mMode = mode; 55 } 56 57 @NonNull getName()58 public String getName() { 59 return mName; 60 } 61 62 @Nullable getMaxTargetSdkVersion()63 public Integer getMaxTargetSdkVersion() { 64 return mMaxTargetSdkVersion; 65 } 66 getMode()67 public int getMode() { 68 return mMode; 69 } 70 71 /** 72 * Grant this app op to an application. 73 * 74 * @param packageName the package name of the application 75 * @param context the {@code Context} to retrieve system services 76 * 77 * @return whether any app mode has changed 78 */ grant(@onNull String packageName, @NonNull Context context)79 public boolean grant(@NonNull String packageName, @NonNull Context context) { 80 if (!checkTargetSdkVersion(packageName, context)) { 81 return false; 82 } 83 return Permissions.setAppOpUidMode(packageName, mName, mMode, context); 84 } 85 86 /** 87 * Revoke this app op from an application. 88 * 89 * @param packageName the package name of the application 90 * @param context the {@code Context} to retrieve system services 91 * 92 * @return whether any app mode has changed 93 */ revoke(@onNull String packageName, @NonNull Context context)94 public boolean revoke(@NonNull String packageName, @NonNull Context context) { 95 if (!checkTargetSdkVersion(packageName, context)) { 96 return false; 97 } 98 int defaultMode = Permissions.getDefaultAppOpMode(mName); 99 return Permissions.setAppOpUidMode(packageName, mName, defaultMode, context); 100 } 101 checkTargetSdkVersion(@onNull String packageName, @NonNull Context context)102 private boolean checkTargetSdkVersion(@NonNull String packageName, @NonNull Context context) { 103 if (mMaxTargetSdkVersion == null) { 104 return true; 105 } 106 ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(packageName, context); 107 if (applicationInfo == null) { 108 return false; 109 } 110 return applicationInfo.targetSdkVersion <= mMaxTargetSdkVersion; 111 } 112 113 @Override toString()114 public String toString() { 115 return "AppOp{" 116 + "mName='" + mName + '\'' 117 + ", mMaxTargetSdkVersion=" + mMaxTargetSdkVersion 118 + ", mMode=" + mMode 119 + '}'; 120 } 121 122 @Override equals(Object object)123 public boolean equals(Object object) { 124 if (this == object) { 125 return true; 126 } 127 if (object == null || getClass() != object.getClass()) { 128 return false; 129 } 130 AppOp appOp = (AppOp) object; 131 return mMode == appOp.mMode 132 && Objects.equals(mName, appOp.mName) 133 && Objects.equals(mMaxTargetSdkVersion, appOp.mMaxTargetSdkVersion); 134 } 135 136 @Override hashCode()137 public int hashCode() { 138 return Objects.hash(mName, mMaxTargetSdkVersion, mMode); 139 } 140 } 141