1 /*
2  * Copyright (C) 2021 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.permission.data
18 
19 import android.apphibernation.AppHibernationManager
20 import android.content.Context.APP_HIBERNATION_SERVICE
21 import android.os.UserHandle
22 import android.util.Log
23 import com.android.permissioncontroller.DumpableLog
24 import com.android.permissioncontroller.PermissionControllerApplication
25 import com.android.permissioncontroller.permission.utils.Utils.getUserContext
26 import kotlinx.coroutines.Job
27 
28 /** Tracks which packages have been hibernated. */
29 object HibernatedPackagesLiveData : SmartAsyncMediatorLiveData<Set<Pair<String, UserHandle>>>() {
30     private val LOG_TAG = HibernatedPackagesLiveData::class.java.simpleName
31 
32     init {
<lambda>null33         addSource(AllPackageInfosLiveData) { update() }
34     }
35 
loadDataAndPostValuenull36     override suspend fun loadDataAndPostValue(job: Job) {
37         if (job.isCancelled) {
38             return
39         }
40         if (!AllPackageInfosLiveData.isInitialized) {
41             return
42         }
43         val allPackages = AllPackageInfosLiveData.value!!
44         val hibernatingPackages = mutableSetOf<Pair<String, UserHandle>>()
45         for ((user, pkgs) in allPackages) {
46             val userContext = getUserContext(PermissionControllerApplication.get(), user)
47             val hibernationManager =
48                 userContext.getSystemService(APP_HIBERNATION_SERVICE) as AppHibernationManager
49             for (pkg in pkgs) {
50                 try {
51                     if (hibernationManager.isHibernatingForUser(pkg.packageName)) {
52                         hibernatingPackages.add(pkg.packageName to user)
53                     }
54                 } catch (e: Exception) {
55                     DumpableLog.e(
56                         LOG_TAG,
57                         "Failed to get hibernation state of package: ${pkg.packageName}"
58                     )
59                 }
60             }
61         }
62 
63         Log.i(LOG_TAG, "postValue: $hibernatingPackages")
64 
65         postValue(hibernatingPackages)
66     }
67 }
68 
69 private val hibernatedOrRevokedPackagesLiveData =
70     object : SmartUpdateMediatorLiveData<Set<Pair<String, UserHandle>>>() {
71 
72         init {
<lambda>null73             addSource(AutoRevokedPackagesLiveData) { update() }
<lambda>null74             addSource(HibernatedPackagesLiveData) { update() }
75         }
76 
onUpdatenull77         override fun onUpdate() {
78             if (
79                 !AutoRevokedPackagesLiveData.isInitialized ||
80                     !HibernatedPackagesLiveData.isInitialized
81             ) {
82                 return
83             }
84             value = AutoRevokedPackagesLiveData.value!!.keys + HibernatedPackagesLiveData.value!!
85         }
86     }
87 val unusedHibernatedOrRevokedPackagesLiveData =
88     UnusedPackagesLiveData(hibernatedOrRevokedPackagesLiveData)
89