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.server.nearby.common.servicemonitor; 18 19 import android.content.BroadcastReceiver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.IntentFilter; 23 import android.net.Uri; 24 import android.os.Handler; 25 import android.os.Looper; 26 27 import com.android.modules.utils.BackgroundThread; 28 29 import java.util.Objects; 30 31 /** 32 * This is mostly from frameworks PackageMonitor. 33 * Helper class for watching somePackagesChanged. 34 */ 35 public abstract class PackageWatcher extends BroadcastReceiver { 36 static final String TAG = "PackageWatcher"; 37 static final IntentFilter sPackageFilt = new IntentFilter(); 38 static final IntentFilter sNonDataFilt = new IntentFilter(); 39 static final IntentFilter sExternalFilt = new IntentFilter(); 40 41 static { 42 sPackageFilt.addAction(Intent.ACTION_PACKAGE_ADDED); 43 sPackageFilt.addAction(Intent.ACTION_PACKAGE_REMOVED); 44 sPackageFilt.addAction(Intent.ACTION_PACKAGE_CHANGED); 45 sPackageFilt.addDataScheme("package"); 46 sNonDataFilt.addAction(Intent.ACTION_PACKAGES_SUSPENDED); 47 sNonDataFilt.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED); 48 sExternalFilt.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); 49 sExternalFilt.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 50 } 51 52 Context mRegisteredContext; 53 Handler mRegisteredHandler; 54 boolean mSomePackagesChanged; 55 PackageWatcher()56 public PackageWatcher() { 57 } 58 register(Context context, Looper thread, boolean externalStorage)59 void register(Context context, Looper thread, boolean externalStorage) { 60 register(context, externalStorage, 61 (thread == null) ? BackgroundThread.getHandler() : new Handler(thread)); 62 } 63 register(Context context, boolean externalStorage, Handler handler)64 void register(Context context, boolean externalStorage, Handler handler) { 65 if (mRegisteredContext != null) { 66 throw new IllegalStateException("Already registered"); 67 } 68 mRegisteredContext = context; 69 mRegisteredHandler = Objects.requireNonNull(handler); 70 context.registerReceiverForAllUsers(this, sPackageFilt, null, mRegisteredHandler); 71 context.registerReceiverForAllUsers(this, sNonDataFilt, null, mRegisteredHandler); 72 if (externalStorage) { 73 context.registerReceiverForAllUsers(this, sExternalFilt, null, mRegisteredHandler); 74 } 75 } 76 unregister()77 void unregister() { 78 if (mRegisteredContext == null) { 79 throw new IllegalStateException("Not registered"); 80 } 81 mRegisteredContext.unregisterReceiver(this); 82 mRegisteredContext = null; 83 } 84 85 // Called when some package has been changed. onSomePackagesChanged()86 abstract void onSomePackagesChanged(); 87 getPackageName(Intent intent)88 String getPackageName(Intent intent) { 89 Uri uri = intent.getData(); 90 String pkg = uri != null ? uri.getSchemeSpecificPart() : null; 91 return pkg; 92 } 93 94 @Override onReceive(Context context, Intent intent)95 public void onReceive(Context context, Intent intent) { 96 mSomePackagesChanged = false; 97 98 String action = intent.getAction(); 99 if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { 100 // We consider something to have changed regardless of whether 101 // this is just an update, because the update is now finished 102 // and the contents of the package may have changed. 103 mSomePackagesChanged = true; 104 } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { 105 String pkg = getPackageName(intent); 106 if (pkg != null) { 107 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 108 mSomePackagesChanged = true; 109 } 110 } 111 } else if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) { 112 String pkg = getPackageName(intent); 113 if (pkg != null) { 114 mSomePackagesChanged = true; 115 } 116 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { 117 mSomePackagesChanged = true; 118 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 119 mSomePackagesChanged = true; 120 } else if (Intent.ACTION_PACKAGES_SUSPENDED.equals(action)) { 121 mSomePackagesChanged = true; 122 } else if (Intent.ACTION_PACKAGES_UNSUSPENDED.equals(action)) { 123 mSomePackagesChanged = true; 124 } 125 126 if (mSomePackagesChanged) { 127 onSomePackagesChanged(); 128 } 129 } 130 } 131