1 /*
2  * Copyright (C) 2023 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  *      https://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.common;
18 
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 
23 import androidx.annotation.NonNull;
24 
25 /**
26  * Receives uninstall events and persists them using a {@link EventResultPersister}.
27  */
28 public class UninstallEventReceiver extends BroadcastReceiver {
29     private static final Object sLock = new Object();
30     private static EventResultPersister sReceiver;
31 
32     /**
33      * Get the event receiver persisting the results
34      *
35      * @return The event receiver.
36      */
getReceiver(@onNull Context context)37     @NonNull private static EventResultPersister getReceiver(@NonNull Context context) {
38         synchronized (sLock) {
39             if (sReceiver == null) {
40                 sReceiver = new EventResultPersister(
41                         TemporaryFileManager.getUninstallStateFile(context));
42             }
43         }
44 
45         return sReceiver;
46     }
47 
48     @Override
onReceive(Context context, Intent intent)49     public void onReceive(Context context, Intent intent) {
50         getReceiver(context).onEventReceived(context, intent);
51     }
52 
53     /**
54      * Add an observer. If there is already an event for this id, call back inside of this call.
55      *
56      * @param context  A context of the current app
57      * @param id       The id the observer is for or {@code GENERATE_NEW_ID} to generate a new one.
58      * @param observer The observer to call back.
59      *
60      * @return The id for this event
61      */
addObserver(@onNull Context context, int id, @NonNull EventResultPersister.EventResultObserver observer)62     public static int addObserver(@NonNull Context context, int id,
63             @NonNull EventResultPersister.EventResultObserver observer)
64             throws EventResultPersister.OutOfIdsException {
65         return getReceiver(context).addObserver(id, observer);
66     }
67 
68     /**
69      * Remove a observer.
70      *
71      * @param context  A context of the current app
72      * @param id The id the observer was added for
73      */
removeObserver(@onNull Context context, int id)74     public static void removeObserver(@NonNull Context context, int id) {
75         getReceiver(context).removeObserver(id);
76     }
77 
78     /**
79      * @param context A context of the current app
80      *
81      * @return A new uninstall id
82      */
getNewId(@onNull Context context)83     public static int getNewId(@NonNull Context context)
84         throws EventResultPersister.OutOfIdsException {
85         return getReceiver(context).getNewId();
86     }
87 }
88