1 /* 2 * Copyright (C) 2022 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.settingslib.spaprivileged.model.app 18 19 import android.app.AppOpsManager; 20 import android.app.AppOpsManager.MODE_ALLOWED 21 import android.app.AppOpsManager.MODE_ERRORED 22 import android.app.AppOpsManager.Mode 23 import android.content.Context 24 import android.content.pm.ApplicationInfo 25 import android.content.pm.PackageManager 26 import android.os.UserHandle 27 import androidx.lifecycle.LiveData 28 import androidx.lifecycle.MutableLiveData 29 import androidx.lifecycle.map 30 import com.android.settingslib.spaprivileged.framework.common.appOpsManager 31 32 interface IAppOpsController { 33 val mode: LiveData<Int> 34 val isAllowed: LiveData<Boolean> 35 get() = mode.map { it == MODE_ALLOWED } 36 37 fun setAllowed(allowed: Boolean) 38 39 @Mode fun getMode(): Int 40 } 41 42 class AppOpsController( 43 context: Context, 44 private val app: ApplicationInfo, 45 private val op: Int, 46 private val modeForNotAllowed: Int = MODE_ERRORED, 47 private val setModeByUid: Boolean = false, 48 ) : IAppOpsController { 49 private val appOpsManager = context.appOpsManager 50 private val packageManager = context.packageManager 51 52 override val mode: LiveData<Int> 53 get() = _mode 54 55 override fun setAllowed(allowed: Boolean) { 56 val mode = if (allowed) MODE_ALLOWED else modeForNotAllowed 57 58 if (setModeByUid) { 59 appOpsManager.setUidMode(op, app.uid, mode) 60 } else { 61 appOpsManager.setMode(op, app.uid, app.packageName, mode) 62 } 63 64 val permission = AppOpsManager.opToPermission(op) 65 if (permission != null) { 66 packageManager.updatePermissionFlags(permission, app.packageName, 67 PackageManager.FLAG_PERMISSION_USER_SET, 68 PackageManager.FLAG_PERMISSION_USER_SET, 69 UserHandle.getUserHandleForUid(app.uid)) 70 } 71 _mode.postValue(mode) 72 } 73 74 @Mode override fun getMode(): Int = appOpsManager.checkOpNoThrow(op, app.uid, app.packageName) 75 76 private val _mode = 77 object : MutableLiveData<Int>() { 78 override fun onActive() { 79 postValue(getMode()) 80 } 81 } 82 } 83