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.packageinstaller.role.ui; 18 19 import android.app.role.RoleManager; 20 import android.content.Context; 21 import android.os.UserHandle; 22 import android.util.Log; 23 24 import androidx.annotation.NonNull; 25 import androidx.annotation.Nullable; 26 import androidx.lifecycle.LiveData; 27 28 import java.util.concurrent.Executor; 29 import java.util.function.Consumer; 30 31 /** 32 * {@link LiveData} for the state of managing a role holder. 33 */ 34 public class ManageRoleHolderStateLiveData extends LiveData<Integer> { 35 36 private static final String LOG_TAG = ManageRoleHolderStateLiveData.class.getSimpleName(); 37 38 private static final boolean DEBUG = false; 39 40 public static final int STATE_IDLE = 0; 41 public static final int STATE_WORKING = 1; 42 public static final int STATE_SUCCESS = 2; 43 public static final int STATE_FAILURE = 3; 44 45 @Nullable 46 private String mLastPackageName; 47 private boolean mLastAdd; 48 private int mLastFlags; 49 private UserHandle mLastUser; 50 ManageRoleHolderStateLiveData()51 public ManageRoleHolderStateLiveData() { 52 setValue(STATE_IDLE); 53 } 54 55 /** 56 * Set whether an application is a holder of a role, and update the state accordingly. Will 57 * be no-op if the current state is not {@link #STATE_IDLE}. 58 * 59 * @param roleName the name of the role 60 * @param packageName the package name of the application 61 * @param add whether to add or remove the application as a role holder 62 * @param flags optional behavior flags 63 * @param user the user to manage the role holder for 64 * @param context the {@code Context} to retrieve system services 65 */ setRoleHolderAsUser(@onNull String roleName, @NonNull String packageName, boolean add, int flags, @NonNull UserHandle user, @NonNull Context context)66 public void setRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, 67 boolean add, int flags, @NonNull UserHandle user, @NonNull Context context) { 68 if (getValue() != STATE_IDLE) { 69 Log.e(LOG_TAG, "Already (tried) managing role holders, requested role: " + roleName 70 + ", requested package: " + packageName); 71 return; 72 } 73 if (DEBUG) { 74 Log.i(LOG_TAG, (add ? "Adding" : "Removing") + " package as role holder, role: " 75 + roleName + ", package: " + packageName); 76 } 77 mLastPackageName = packageName; 78 mLastAdd = add; 79 mLastFlags = flags; 80 mLastUser = user; 81 setValue(STATE_WORKING); 82 83 RoleManager roleManager = context.getSystemService(RoleManager.class); 84 Executor executor = context.getMainExecutor(); 85 Consumer<Boolean> callback = successful -> { 86 if (successful) { 87 if (DEBUG) { 88 Log.i(LOG_TAG, "Package " + (add ? "added" : "removed") 89 + " as role holder, role: " + roleName + ", package: " + packageName); 90 } 91 setValue(STATE_SUCCESS); 92 } else { 93 if (DEBUG) { 94 Log.i(LOG_TAG, "Failed to " + (add ? "add" : "remove") 95 + " package as role holder, role: " + roleName + ", package: " 96 + packageName); 97 } 98 setValue(STATE_FAILURE); 99 } 100 }; 101 if (add) { 102 roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback); 103 } else { 104 roleManager.removeRoleHolderAsUser(roleName, packageName, flags, user, executor, 105 callback); 106 } 107 } 108 109 /** 110 * Clear the holders of a role, and update the state accordingly. Will be no-op if the current 111 * state is not {@link #STATE_IDLE}. 112 * 113 * @param roleName the name of the role 114 * @param flags optional behavior flags 115 * @param user the user to manage the role holder for 116 * @param context the {@code Context} to retrieve system services 117 */ clearRoleHoldersAsUser(@onNull String roleName, int flags, @NonNull UserHandle user, @NonNull Context context)118 public void clearRoleHoldersAsUser(@NonNull String roleName, int flags, 119 @NonNull UserHandle user, @NonNull Context context) { 120 if (getValue() != STATE_IDLE) { 121 Log.e(LOG_TAG, "Already (tried) managing role holders, requested role: " + roleName); 122 return; 123 } 124 if (DEBUG) { 125 Log.i(LOG_TAG, "Clearing role holders, role: " + roleName); 126 } 127 mLastPackageName = null; 128 mLastAdd = false; 129 mLastFlags = flags; 130 mLastUser = user; 131 setValue(STATE_WORKING); 132 133 RoleManager roleManager = context.getSystemService(RoleManager.class); 134 Executor executor = context.getMainExecutor(); 135 Consumer<Boolean> callback = successful -> { 136 if (successful) { 137 if (DEBUG) { 138 Log.i(LOG_TAG, "Cleared role holders, role: " + roleName); 139 } 140 setValue(STATE_SUCCESS); 141 } else { 142 if (DEBUG) { 143 Log.i(LOG_TAG, "Failed to clear role holders, role: " + roleName); 144 } 145 setValue(STATE_FAILURE); 146 } 147 }; 148 roleManager.clearRoleHoldersAsUser(roleName, flags, user, executor, callback); 149 } 150 151 @Nullable getLastPackageName()152 public String getLastPackageName() { 153 return mLastPackageName; 154 } 155 isLastAdd()156 public boolean isLastAdd() { 157 return mLastAdd; 158 } 159 getLastFlags()160 public int getLastFlags() { 161 return mLastFlags; 162 } 163 getLastUser()164 public UserHandle getLastUser() { 165 return mLastUser; 166 } 167 168 /** 169 * Reset the state of this live data to {@link #STATE_IDLE}. Will be no-op if the current state 170 * is not {@link #STATE_SUCCESS} or {@link #STATE_FAILURE}. 171 */ resetState()172 public void resetState() { 173 int state = getValue(); 174 if (!(state == STATE_SUCCESS || state == STATE_FAILURE)) { 175 Log.e(LOG_TAG, "Trying to reset state when the current state is not STATE_SUCCESS or" 176 + " STATE_FAILURE"); 177 return; 178 } 179 mLastPackageName = null; 180 mLastAdd = false; 181 mLastFlags = 0; 182 mLastUser = null; 183 setValue(STATE_IDLE); 184 } 185 } 186