• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.server.adservices;
18 
19 import android.annotation.NonNull;
20 import android.util.ArrayMap;
21 
22 import com.android.internal.annotations.GuardedBy;
23 import com.android.internal.annotations.VisibleForTesting;
24 import com.android.server.adservices.consent.AppConsentManager;
25 import com.android.server.adservices.consent.ConsentManager;
26 import com.android.server.adservices.data.topics.TopicsDao;
27 import com.android.server.adservices.rollback.RollbackHandlingManager;
28 
29 import java.io.File;
30 import java.io.IOException;
31 import java.io.PrintWriter;
32 import java.nio.file.Files;
33 import java.nio.file.Path;
34 import java.nio.file.Paths;
35 import java.util.Map;
36 
37 /**
38  * Manager to handle User Instance. This is to ensure that each user profile is isolated.
39  *
40  * @hide
41  */
42 public class UserInstanceManager {
43 
44     private final Object mLock = new Object();
45 
46     // We have 1 ConsentManager per user/user profile. This is to isolate user's data.
47     @GuardedBy("mLock")
48     private final Map<Integer, ConsentManager> mConsentManagerMapLocked = new ArrayMap<>();
49 
50     @GuardedBy("mLock")
51     private final Map<Integer, AppConsentManager> mAppConsentManagerMapLocked = new ArrayMap<>();
52 
53 
54     @GuardedBy("UserInstanceManager.class")
55     private final Map<Integer, BlockedTopicsManager> mBlockedTopicsManagerMapLocked =
56             new ArrayMap<>();
57 
58     // We have 1 RollbackManager per user/user profile, to isolate each user's data.
59     @GuardedBy("mLock")
60     private final Map<Integer, RollbackHandlingManager> mRollbackHandlingManagerMapLocked =
61             new ArrayMap<>();
62 
63     private final String mAdServicesBaseDir;
64 
65     private final TopicsDao mTopicsDao;
66 
UserInstanceManager(@onNull TopicsDao topicsDao, @NonNull String adServicesBaseDir)67     UserInstanceManager(@NonNull TopicsDao topicsDao, @NonNull String adServicesBaseDir) {
68         mTopicsDao = topicsDao;
69         mAdServicesBaseDir = adServicesBaseDir;
70     }
71 
72     @NonNull
getOrCreateUserConsentManagerInstance(int userIdentifier)73     ConsentManager getOrCreateUserConsentManagerInstance(int userIdentifier) throws IOException {
74         synchronized (mLock) {
75             ConsentManager instance = getUserConsentManagerInstance(userIdentifier);
76             if (instance == null) {
77                 instance = ConsentManager.createConsentManager(mAdServicesBaseDir, userIdentifier);
78                 mConsentManagerMapLocked.put(userIdentifier, instance);
79             }
80             return instance;
81         }
82     }
83 
84     @NonNull
getOrCreateUserAppConsentManagerInstance(int userIdentifier)85     AppConsentManager getOrCreateUserAppConsentManagerInstance(int userIdentifier)
86             throws IOException {
87         synchronized (mLock) {
88             AppConsentManager instance = mAppConsentManagerMapLocked.get(userIdentifier);
89             if (instance == null) {
90                 instance =
91                         AppConsentManager.createAppConsentManager(
92                                 mAdServicesBaseDir, userIdentifier);
93                 mAppConsentManagerMapLocked.put(userIdentifier, instance);
94             }
95             return instance;
96         }
97     }
98 
99     @NonNull
getOrCreateUserBlockedTopicsManagerInstance(int userIdentifier)100     BlockedTopicsManager getOrCreateUserBlockedTopicsManagerInstance(int userIdentifier) {
101         synchronized (UserInstanceManager.class) {
102             BlockedTopicsManager instance = mBlockedTopicsManagerMapLocked.get(userIdentifier);
103             if (instance == null) {
104                 instance = new BlockedTopicsManager(mTopicsDao, userIdentifier);
105                 mBlockedTopicsManagerMapLocked.put(userIdentifier, instance);
106             }
107             return instance;
108         }
109     }
110 
111     @NonNull
getOrCreateUserRollbackHandlingManagerInstance( int userIdentifier, int packageVersion)112     RollbackHandlingManager getOrCreateUserRollbackHandlingManagerInstance(
113             int userIdentifier, int packageVersion) throws IOException {
114         synchronized (mLock) {
115             RollbackHandlingManager instance =
116                     mRollbackHandlingManagerMapLocked.get(userIdentifier);
117             if (instance == null) {
118                 instance =
119                         RollbackHandlingManager.createRollbackHandlingManager(
120                                 mAdServicesBaseDir, userIdentifier, packageVersion);
121                 mRollbackHandlingManagerMapLocked.put(userIdentifier, instance);
122             }
123             return instance;
124         }
125     }
126 
127     @VisibleForTesting
getUserConsentManagerInstance(int userIdentifier)128     ConsentManager getUserConsentManagerInstance(int userIdentifier) {
129         synchronized (mLock) {
130             return mConsentManagerMapLocked.get(userIdentifier);
131         }
132     }
133 
134     /**
135      * Deletes the user instance and remove the user consent related data. This will delete the
136      * directory: /data/system/adservices/user_id
137      */
deleteUserInstance(int userIdentifier)138     void deleteUserInstance(int userIdentifier) throws Exception {
139         synchronized (mLock) {
140             ConsentManager instance = mConsentManagerMapLocked.get(userIdentifier);
141             if (instance != null) {
142                 String userDirectoryPath = mAdServicesBaseDir + "/" + userIdentifier;
143                 final Path packageDir = Paths.get(userDirectoryPath);
144                 if (Files.exists(packageDir)) {
145                     if (!instance.deleteUserDirectory(new File(userDirectoryPath))) {
146                         LogUtil.e("Failed to delete " + userDirectoryPath);
147                     }
148                 }
149                 mConsentManagerMapLocked.remove(userIdentifier);
150             }
151 
152             // Delete all data in the database that belongs to this user
153             mTopicsDao.clearAllBlockedTopicsOfUser(userIdentifier);
154         }
155     }
156 
dump(PrintWriter writer, String[] args)157     void dump(PrintWriter writer, String[] args) {
158         writer.println("UserInstanceManager");
159         String prefix = "  ";
160         writer.printf("%smAdServicesBaseDir: %s\n", prefix, mAdServicesBaseDir);
161         synchronized (mLock) {
162             writer.printf("%smConsentManagerMapLocked: %s\n", prefix, mConsentManagerMapLocked);
163             writer.printf(
164                     "%smAppConsentManagerMapLocked: %s\n", prefix, mAppConsentManagerMapLocked);
165             writer.printf(
166                     "%smRollbackHandlingManagerMapLocked: %s\n",
167                     prefix, mRollbackHandlingManagerMapLocked);
168         }
169         synchronized (UserInstanceManager.class) {
170             writer.printf(
171                     "%smBlockedTopicsManagerMapLocked=%s\n",
172                     prefix, mBlockedTopicsManagerMapLocked);
173         }
174 
175         mTopicsDao.dump(writer, prefix, args);
176     }
177 
178     @VisibleForTesting
tearDownForTesting()179     void tearDownForTesting() {
180         synchronized (mLock) {
181             for (ConsentManager consentManager : mConsentManagerMapLocked.values()) {
182                 consentManager.tearDownForTesting();
183             }
184             for (AppConsentManager appConsentManager : mAppConsentManagerMapLocked.values()) {
185                 appConsentManager.tearDownForTesting();
186             }
187             for (RollbackHandlingManager rollbackHandlingManager :
188                     mRollbackHandlingManagerMapLocked.values()) {
189                 rollbackHandlingManager.tearDownForTesting();
190             }
191         }
192     }
193 }
194