• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.wallpaper.module;
17 
18 import android.content.Context;
19 import android.content.Intent;
20 import android.content.pm.LauncherApps;
21 import android.content.pm.PackageManager;
22 import android.os.UserHandle;
23 
24 import dagger.hilt.android.qualifiers.ApplicationContext;
25 
26 import java.util.HashMap;
27 import java.util.Map;
28 
29 import javax.inject.Inject;
30 import javax.inject.Singleton;
31 
32 
33 /**
34  * Default version of {@link PackageStatusNotifier} that uses {@link LauncherApps}
35  */
36 @Singleton
37 public class DefaultPackageStatusNotifier implements PackageStatusNotifier {
38 
39     private final Map<Listener, ListenerWrapper> mListeners = new HashMap<>();
40     private final Context mAppContext;
41     private final LauncherApps mLauncherApps;
42 
43     @Inject
DefaultPackageStatusNotifier(@pplicationContext Context context)44     public DefaultPackageStatusNotifier(@ApplicationContext Context context) {
45         mAppContext = context;
46         mLauncherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
47     }
48 
49     @Override
addListener(Listener listener, String action)50     public void addListener(Listener listener, String action) {
51         ListenerWrapper wrapper = new ListenerWrapper(mAppContext, action, listener);
52         removeListenerAndMaybeUnregisterCallback(listener);
53         mListeners.put(listener, wrapper);
54         mLauncherApps.registerCallback(wrapper);
55     }
56 
57     @Override
removeListener(Listener listener)58     public void removeListener(Listener listener) {
59         removeListenerAndMaybeUnregisterCallback(listener);
60     }
61 
removeListenerAndMaybeUnregisterCallback(Listener listener)62     private void removeListenerAndMaybeUnregisterCallback(Listener listener) {
63         ListenerWrapper oldWrapper = mListeners.remove(listener);
64         if (oldWrapper != null) {
65             mLauncherApps.unregisterCallback(oldWrapper);
66         }
67     }
68 
69     private static class ListenerWrapper extends LauncherApps.Callback {
70 
71         private final Context mAppContext;
72         private final Intent mIntentFilter;
73         private final Listener mListener;
74 
ListenerWrapper(Context context, String action, Listener listener)75         ListenerWrapper(Context context, String action, Listener listener) {
76             mAppContext = context.getApplicationContext();
77             mIntentFilter = new Intent(action);
78             mListener = listener;
79         }
80 
isValidPackage(String packageName)81         private boolean isValidPackage(String packageName) {
82             mIntentFilter.setPackage(packageName);
83             PackageManager pm = mAppContext.getPackageManager();
84             return !pm.queryIntentServices(mIntentFilter, 0).isEmpty()
85                     || !pm.queryIntentActivities(mIntentFilter, 0).isEmpty();
86         }
87 
88 
89         @Override
onPackageRemoved(String packageName, UserHandle userHandle)90         public void onPackageRemoved(String packageName, UserHandle userHandle) {
91             // We can't check if the removed package is "valid" for the given action, as it's not
92             // there any more, so trigger REMOVED for all cases.
93             mListener.onPackageChanged(packageName, PackageStatus.REMOVED);
94         }
95 
96         @Override
onPackageAdded(String packageName, UserHandle userHandle)97         public void onPackageAdded(String packageName, UserHandle userHandle) {
98             if (isValidPackage(packageName)) {
99                 mListener.onPackageChanged(packageName, PackageStatus.ADDED);
100             }
101         }
102 
103         @Override
onPackageChanged(String packageName, UserHandle userHandle)104         public void onPackageChanged(String packageName, UserHandle userHandle) {
105             if (isValidPackage(packageName)) {
106                 mListener.onPackageChanged(packageName, PackageStatus.CHANGED);
107             }
108         }
109 
110         @Override
onPackagesAvailable(String[] packageNames, UserHandle userHandle, boolean replacing)111         public void onPackagesAvailable(String[] packageNames, UserHandle userHandle,
112                                         boolean replacing) {
113             for (String packageName : packageNames) {
114                 if (isValidPackage(packageName)) {
115                     mListener.onPackageChanged(packageName,
116                             replacing ? PackageStatus.CHANGED : PackageStatus.ADDED);
117                 }
118             }
119         }
120 
121         @Override
onPackagesUnavailable(String[] packageNames, UserHandle userHandle, boolean replacing)122         public void onPackagesUnavailable(String[] packageNames, UserHandle userHandle,
123                                           boolean replacing) {
124             for (String packageName : packageNames) {
125                 if (!replacing && isValidPackage(packageName)) {
126                     mListener.onPackageChanged(packageName, PackageStatus.REMOVED);
127                 }
128             }
129         }
130 
131         @Override
onPackagesSuspended(String[] packageNames, UserHandle user)132         public void onPackagesSuspended(String[] packageNames, UserHandle user) {
133             for (String packageName : packageNames) {
134                 if (isValidPackage(packageName)) {
135                     mListener.onPackageChanged(packageName, PackageStatus.REMOVED);
136                 }
137             }
138         }
139 
140         @Override
onPackagesUnsuspended(String[] packageNames, UserHandle user)141         public void onPackagesUnsuspended(String[] packageNames, UserHandle user) {
142             for (String packageName : packageNames) {
143                 if (isValidPackage(packageName)) {
144                     mListener.onPackageChanged(packageName, PackageStatus.ADDED);
145                 }
146             }
147         }
148     }
149 }
150