FileDocCategorySizeDatePackage
PackageMonitor.javaAPI DocAndroid 5.1 API15563Thu Mar 12 22:22:10 GMT 2015com.android.internal.content

PackageMonitor

public abstract class PackageMonitor extends android.content.BroadcastReceiver
Helper class for monitoring the state of packages: adding, removing, updating, and disappearing and reappearing on the SD card.

Fields Summary
static final android.content.IntentFilter
sPackageFilt
static final android.content.IntentFilter
sNonDataFilt
static final android.content.IntentFilter
sExternalFilt
final HashSet
mUpdatingPackages
android.content.Context
mRegisteredContext
android.os.Handler
mRegisteredHandler
String[]
mDisappearingPackages
String[]
mAppearingPackages
String[]
mModifiedPackages
int
mChangeType
int
mChangeUserId
boolean
mSomePackagesChanged
String[]
mTempArray
public static final int
PACKAGE_UNCHANGED
public static final int
PACKAGE_UPDATING
public static final int
PACKAGE_TEMPORARY_CHANGE
public static final int
PACKAGE_PERMANENT_CHANGE
Constructors Summary
Methods Summary
public booleananyPackagesAppearing()

        return mAppearingPackages != null;
    
public booleananyPackagesDisappearing()

        return mDisappearingPackages != null;
    
public booleandidSomePackagesChange()

        return mSomePackagesChanged;
    
public intgetChangingUserId()

        return mChangeUserId;
    
java.lang.StringgetPackageName(android.content.Intent intent)

        Uri uri = intent.getData();
        String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
        return pkg;
    
public android.os.HandlergetRegisteredHandler()

        return mRegisteredHandler;
    
public intisPackageAppearing(java.lang.String packageName)

        if (mAppearingPackages != null) {
            for (int i=mAppearingPackages.length-1; i>=0; i--) {
                if (packageName.equals(mAppearingPackages[i])) {
                    return mChangeType;
                }
            }
        }
        return PACKAGE_UNCHANGED;
    
public intisPackageDisappearing(java.lang.String packageName)

        if (mDisappearingPackages != null) {
            for (int i=mDisappearingPackages.length-1; i>=0; i--) {
                if (packageName.equals(mDisappearingPackages[i])) {
                    return mChangeType;
                }
            }
        }
        return PACKAGE_UNCHANGED;
    
public booleanisPackageModified(java.lang.String packageName)

        if (mModifiedPackages != null) {
            for (int i=mModifiedPackages.length-1; i>=0; i--) {
                if (packageName.equals(mModifiedPackages[i])) {
                    return true;
                }
            }
        }
        return false;
    
booleanisPackageUpdating(java.lang.String packageName)

        synchronized (mUpdatingPackages) {
            return mUpdatingPackages.contains(packageName);
        }
    
public booleanisReplacing()

        return mChangeType == PACKAGE_UPDATING;
    
public voidonBeginPackageChanges()

    
public voidonFinishPackageChanges()

    
public booleanonHandleForceStop(android.content.Intent intent, java.lang.String[] packages, int uid, boolean doit)

        return false;
    
public voidonHandleUserStop(android.content.Intent intent, int userHandle)

    
public voidonPackageAdded(java.lang.String packageName, int uid)
Called when a package is really added (and not replaced).

    
public voidonPackageAppeared(java.lang.String packageName, int reason)
Called when a package appears for any reason.

    
public booleanonPackageChanged(java.lang.String packageName, int uid, java.lang.String[] components)
Direct reflection of {@link Intent#ACTION_PACKAGE_CHANGED Intent.ACTION_PACKAGE_CHANGED} being received, informing you of changes to the enabled/disabled state of components in a package and/or of the overall package.

param
packageName The name of the package that is changing.
param
uid The user ID the package runs under.
param
components Any components in the package that are changing. If the overall package is changing, this will contain an entry of the package name itself.
return
Return true to indicate you care about this change, which will result in {@link #onSomePackagesChanged()} being called later. If you return false, no further callbacks will happen about this change. The default implementation returns true if this is a change to the entire package.

        if (components != null) {
            for (String name : components) {
                if (packageName.equals(name)) {
                    return true;
                }
            }
        }
        return false;
    
public voidonPackageDisappeared(java.lang.String packageName, int reason)
Called when a package disappears for any reason.


                 
          
    
public voidonPackageModified(java.lang.String packageName)
Called when an existing package is updated or its disabled state changes.

    
public voidonPackageRemoved(java.lang.String packageName, int uid)
Called when a package is really removed (and not replaced).

    
public voidonPackageRemovedAllUsers(java.lang.String packageName, int uid)
Called when a package is really removed (and not replaced) for all users on the device.

    
public voidonPackageUpdateFinished(java.lang.String packageName, int uid)

    
public voidonPackageUpdateStarted(java.lang.String packageName, int uid)

    
public voidonPackagesAvailable(java.lang.String[] packages)

    
public voidonPackagesUnavailable(java.lang.String[] packages)

    
public voidonReceive(android.content.Context context, android.content.Intent intent)

        mChangeUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
                UserHandle.USER_NULL);
        if (mChangeUserId == UserHandle.USER_NULL) {
            Slog.w("PackageMonitor", "Intent broadcast does not contain user handle: " + intent);
            return;
        }
        onBeginPackageChanges();
        
        mDisappearingPackages = mAppearingPackages = null;
        mSomePackagesChanged = false;
        
        String action = intent.getAction();
        if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
            String pkg = getPackageName(intent);
            int uid = intent.getIntExtra(Intent.EXTRA_UID, 0);
            // We consider something to have changed regardless of whether
            // this is just an update, because the update is now finished
            // and the contents of the package may have changed.
            mSomePackagesChanged = true;
            if (pkg != null) {
                mAppearingPackages = mTempArray;
                mTempArray[0] = pkg;
                if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
                    mModifiedPackages = mTempArray;
                    mChangeType = PACKAGE_UPDATING;
                    onPackageUpdateFinished(pkg, uid);
                    onPackageModified(pkg);
                } else {
                    mChangeType = PACKAGE_PERMANENT_CHANGE;
                    onPackageAdded(pkg, uid);
                }
                onPackageAppeared(pkg, mChangeType);
                if (mChangeType == PACKAGE_UPDATING) {
                    synchronized (mUpdatingPackages) {
                        mUpdatingPackages.remove(pkg);
                    }
                }
            }
        } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
            String pkg = getPackageName(intent);
            int uid = intent.getIntExtra(Intent.EXTRA_UID, 0);
            if (pkg != null) {
                mDisappearingPackages = mTempArray;
                mTempArray[0] = pkg;
                if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
                    mChangeType = PACKAGE_UPDATING;
                    synchronized (mUpdatingPackages) {
                        //not used for now
                        //mUpdatingPackages.add(pkg);
                    }
                    onPackageUpdateStarted(pkg, uid);
                } else {
                    mChangeType = PACKAGE_PERMANENT_CHANGE;
                    // We only consider something to have changed if this is
                    // not a replace; for a replace, we just need to consider
                    // it when it is re-added.
                    mSomePackagesChanged = true;
                    onPackageRemoved(pkg, uid);
                    if (intent.getBooleanExtra(Intent.EXTRA_REMOVED_FOR_ALL_USERS, false)) {
                        onPackageRemovedAllUsers(pkg, uid);
                    }
                }
                onPackageDisappeared(pkg, mChangeType);
            }
        } else if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
            String pkg = getPackageName(intent);
            int uid = intent.getIntExtra(Intent.EXTRA_UID, 0);
            String[] components = intent.getStringArrayExtra(
                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
            if (pkg != null) {
                mModifiedPackages = mTempArray;
                mTempArray[0] = pkg;
                mChangeType = PACKAGE_PERMANENT_CHANGE;
                if (onPackageChanged(pkg, uid, components)) {
                    mSomePackagesChanged = true;
                }
                onPackageModified(pkg);
            }
        } else if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) {
            mDisappearingPackages = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
            mChangeType = PACKAGE_TEMPORARY_CHANGE;
            boolean canRestart = onHandleForceStop(intent,
                    mDisappearingPackages,
                    intent.getIntExtra(Intent.EXTRA_UID, 0), false);
            if (canRestart) setResultCode(Activity.RESULT_OK);
        } else if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
            mDisappearingPackages = new String[] {getPackageName(intent)};
            mChangeType = PACKAGE_TEMPORARY_CHANGE;
            onHandleForceStop(intent, mDisappearingPackages,
                    intent.getIntExtra(Intent.EXTRA_UID, 0), true);
        } else if (Intent.ACTION_UID_REMOVED.equals(action)) {
            onUidRemoved(intent.getIntExtra(Intent.EXTRA_UID, 0));
        } else if (Intent.ACTION_USER_STOPPED.equals(action)) {
            if (intent.hasExtra(Intent.EXTRA_USER_HANDLE)) {
                onHandleUserStop(intent, intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
            }
        } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
            String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
            mAppearingPackages = pkgList;
            mChangeType = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)
                    ? PACKAGE_UPDATING : PACKAGE_TEMPORARY_CHANGE;
            mSomePackagesChanged = true;
            if (pkgList != null) {
                onPackagesAvailable(pkgList);
                for (int i=0; i<pkgList.length; i++) {
                    onPackageAppeared(pkgList[i], mChangeType);
                }
            }
        } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
            String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
            mDisappearingPackages = pkgList;
            mChangeType = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)
                    ? PACKAGE_UPDATING : PACKAGE_TEMPORARY_CHANGE;
            mSomePackagesChanged = true;
            if (pkgList != null) {
                onPackagesUnavailable(pkgList);
                for (int i=0; i<pkgList.length; i++) {
                    onPackageDisappeared(pkgList[i], mChangeType);
                }
            }
        }
        
        if (mSomePackagesChanged) {
            onSomePackagesChanged();
        }
        
        onFinishPackageChanges();
        mChangeUserId = UserHandle.USER_NULL;
    
public voidonSomePackagesChanged()

    
public voidonUidRemoved(int uid)

    
public voidregister(android.content.Context context, android.os.Looper thread, boolean externalStorage)


            
        register(context, thread, null, externalStorage);
    
public voidregister(android.content.Context context, android.os.Looper thread, android.os.UserHandle user, boolean externalStorage)

        if (mRegisteredContext != null) {
            throw new IllegalStateException("Already registered");
        }
        mRegisteredContext = context;
        if (thread == null) {
            mRegisteredHandler = BackgroundThread.getHandler();
        } else {
            mRegisteredHandler = new Handler(thread);
        }
        if (user != null) {
            context.registerReceiverAsUser(this, user, sPackageFilt, null, mRegisteredHandler);
            context.registerReceiverAsUser(this, user, sNonDataFilt, null, mRegisteredHandler);
            if (externalStorage) {
                context.registerReceiverAsUser(this, user, sExternalFilt, null,
                        mRegisteredHandler);
            }
        } else {
            context.registerReceiver(this, sPackageFilt, null, mRegisteredHandler);
            context.registerReceiver(this, sNonDataFilt, null, mRegisteredHandler);
            if (externalStorage) {
                context.registerReceiver(this, sExternalFilt, null, mRegisteredHandler);
            }
        }
    
public voidunregister()

        if (mRegisteredContext == null) {
            throw new IllegalStateException("Not registered");
        }
        mRegisteredContext.unregisterReceiver(this);
        mRegisteredContext = null;