diff options
| -rw-r--r-- | api/current.txt | 13 | ||||
| -rw-r--r-- | api/system-current.txt | 13 | ||||
| -rw-r--r-- | api/test-current.txt | 13 | ||||
| -rw-r--r-- | core/java/android/app/ApplicationPackageManager.java | 10 | ||||
| -rw-r--r-- | core/java/android/content/pm/ChangedPackages.aidl | 19 | ||||
| -rw-r--r-- | core/java/android/content/pm/ChangedPackages.java | 82 | ||||
| -rw-r--r-- | core/java/android/content/pm/IPackageManager.aidl | 3 | ||||
| -rw-r--r-- | core/java/android/content/pm/PackageManager.java | 12 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerService.java | 71 | ||||
| -rw-r--r-- | test-runner/src/android/test/mock/MockPackageManager.java | 7 | ||||
| -rw-r--r-- | tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java | 6 |
11 files changed, 246 insertions, 3 deletions
diff --git a/api/current.txt b/api/current.txt index bcc3fb35fc66..decd819f1211 100644 --- a/api/current.txt +++ b/api/current.txt @@ -9925,6 +9925,15 @@ package android.content.pm { method public final int compare(android.content.pm.ApplicationInfo, android.content.pm.ApplicationInfo); } + public final class ChangedPackages implements android.os.Parcelable { + ctor public ChangedPackages(int, java.util.List<java.lang.String>); + method public int describeContents(); + method public java.util.List<java.lang.String> getPackageNames(); + method public int getSequenceNumber(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.content.pm.ChangedPackages> CREATOR; + } + public class ComponentInfo extends android.content.pm.PackageItemInfo { ctor public ComponentInfo(); ctor public ComponentInfo(android.content.pm.ComponentInfo); @@ -10271,6 +10280,7 @@ package android.content.pm { method public abstract java.lang.CharSequence getApplicationLabel(android.content.pm.ApplicationInfo); method public abstract android.graphics.drawable.Drawable getApplicationLogo(android.content.pm.ApplicationInfo); method public abstract android.graphics.drawable.Drawable getApplicationLogo(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; + method public abstract android.content.pm.ChangedPackages getChangedPackages(int); method public abstract int getComponentEnabledSetting(android.content.ComponentName); method public abstract android.graphics.drawable.Drawable getDefaultActivityIcon(); method public abstract android.graphics.drawable.Drawable getDrawable(java.lang.String, int, android.content.pm.ApplicationInfo); @@ -40065,6 +40075,7 @@ package android.test.mock { method public java.lang.CharSequence getApplicationLabel(android.content.pm.ApplicationInfo); method public android.graphics.drawable.Drawable getApplicationLogo(android.content.pm.ApplicationInfo); method public android.graphics.drawable.Drawable getApplicationLogo(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; + method public android.content.pm.ChangedPackages getChangedPackages(int); method public int getComponentEnabledSetting(android.content.ComponentName); method public android.graphics.drawable.Drawable getDefaultActivityIcon(); method public android.graphics.drawable.Drawable getDrawable(java.lang.String, int, android.content.pm.ApplicationInfo); @@ -47318,7 +47329,7 @@ package android.view.textclassifier { public final class TextClassificationManager { method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence); - method public android.view.textclassifier.TextClassifier getDefaultTextClassifier(); + method public synchronized android.view.textclassifier.TextClassifier getDefaultTextClassifier(); } public final class TextClassificationResult { diff --git a/api/system-current.txt b/api/system-current.txt index 5ac97c1b062c..bfb67335b926 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -10373,6 +10373,15 @@ package android.content.pm { method public final int compare(android.content.pm.ApplicationInfo, android.content.pm.ApplicationInfo); } + public final class ChangedPackages implements android.os.Parcelable { + ctor public ChangedPackages(int, java.util.List<java.lang.String>); + method public int describeContents(); + method public java.util.List<java.lang.String> getPackageNames(); + method public int getSequenceNumber(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.content.pm.ChangedPackages> CREATOR; + } + public class ComponentInfo extends android.content.pm.PackageItemInfo { ctor public ComponentInfo(); ctor public ComponentInfo(android.content.pm.ComponentInfo); @@ -10770,6 +10779,7 @@ package android.content.pm { method public abstract java.lang.CharSequence getApplicationLabel(android.content.pm.ApplicationInfo); method public abstract android.graphics.drawable.Drawable getApplicationLogo(android.content.pm.ApplicationInfo); method public abstract android.graphics.drawable.Drawable getApplicationLogo(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; + method public abstract android.content.pm.ChangedPackages getChangedPackages(int); method public abstract int getComponentEnabledSetting(android.content.ComponentName); method public abstract android.graphics.drawable.Drawable getDefaultActivityIcon(); method public abstract java.lang.String getDefaultBrowserPackageNameAsUser(int); @@ -43490,6 +43500,7 @@ package android.test.mock { method public java.lang.CharSequence getApplicationLabel(android.content.pm.ApplicationInfo); method public android.graphics.drawable.Drawable getApplicationLogo(android.content.pm.ApplicationInfo); method public android.graphics.drawable.Drawable getApplicationLogo(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; + method public android.content.pm.ChangedPackages getChangedPackages(int); method public int getComponentEnabledSetting(android.content.ComponentName); method public android.graphics.drawable.Drawable getDefaultActivityIcon(); method public java.lang.String getDefaultBrowserPackageNameAsUser(int); @@ -50759,7 +50770,7 @@ package android.view.textclassifier { public final class TextClassificationManager { method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence); - method public android.view.textclassifier.TextClassifier getDefaultTextClassifier(); + method public synchronized android.view.textclassifier.TextClassifier getDefaultTextClassifier(); } public final class TextClassificationResult { diff --git a/api/test-current.txt b/api/test-current.txt index a5265b03e08b..fbd6b5efb19d 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -9953,6 +9953,15 @@ package android.content.pm { method public final int compare(android.content.pm.ApplicationInfo, android.content.pm.ApplicationInfo); } + public final class ChangedPackages implements android.os.Parcelable { + ctor public ChangedPackages(int, java.util.List<java.lang.String>); + method public int describeContents(); + method public java.util.List<java.lang.String> getPackageNames(); + method public int getSequenceNumber(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.content.pm.ChangedPackages> CREATOR; + } + public class ComponentInfo extends android.content.pm.PackageItemInfo { ctor public ComponentInfo(); ctor public ComponentInfo(android.content.pm.ComponentInfo); @@ -10300,6 +10309,7 @@ package android.content.pm { method public abstract java.lang.CharSequence getApplicationLabel(android.content.pm.ApplicationInfo); method public abstract android.graphics.drawable.Drawable getApplicationLogo(android.content.pm.ApplicationInfo); method public abstract android.graphics.drawable.Drawable getApplicationLogo(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; + method public abstract android.content.pm.ChangedPackages getChangedPackages(int); method public abstract int getComponentEnabledSetting(android.content.ComponentName); method public abstract android.graphics.drawable.Drawable getDefaultActivityIcon(); method public abstract java.lang.String getDefaultBrowserPackageNameAsUser(int); @@ -40202,6 +40212,7 @@ package android.test.mock { method public java.lang.CharSequence getApplicationLabel(android.content.pm.ApplicationInfo); method public android.graphics.drawable.Drawable getApplicationLogo(android.content.pm.ApplicationInfo); method public android.graphics.drawable.Drawable getApplicationLogo(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; + method public android.content.pm.ChangedPackages getChangedPackages(int); method public int getComponentEnabledSetting(android.content.ComponentName); method public android.graphics.drawable.Drawable getDefaultActivityIcon(); method public java.lang.String getDefaultBrowserPackageNameAsUser(int); @@ -47632,7 +47643,7 @@ package android.view.textclassifier { public final class TextClassificationManager { method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence); - method public android.view.textclassifier.TextClassifier getDefaultTextClassifier(); + method public synchronized android.view.textclassifier.TextClassifier getDefaultTextClassifier(); } public final class TextClassificationResult { diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 0c6c4ba33ee3..333e412e1c33 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -29,6 +29,7 @@ import android.content.IntentFilter; import android.content.IntentSender; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.ChangedPackages; import android.content.pm.ComponentInfo; import android.content.pm.InstantAppInfo; import android.content.pm.FeatureInfo; @@ -506,6 +507,15 @@ public class ApplicationPackageManager extends PackageManager { } @Override + public ChangedPackages getChangedPackages(int sequenceNumber) { + try { + return mPM.getChangedPackages(sequenceNumber, mContext.getUserId()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + @Override @SuppressWarnings("unchecked") public FeatureInfo[] getSystemAvailableFeatures() { try { diff --git a/core/java/android/content/pm/ChangedPackages.aidl b/core/java/android/content/pm/ChangedPackages.aidl new file mode 100644 index 000000000000..1a9f5a1505eb --- /dev/null +++ b/core/java/android/content/pm/ChangedPackages.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2017, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm; + +parcelable ChangedPackages;
\ No newline at end of file diff --git a/core/java/android/content/pm/ChangedPackages.java b/core/java/android/content/pm/ChangedPackages.java new file mode 100644 index 000000000000..94b8a5dfd5e0 --- /dev/null +++ b/core/java/android/content/pm/ChangedPackages.java @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2017, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.content.pm; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.Intent; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.List; + +/** + * Packages that have been changed since the last time they + * were requested. + */ +public final class ChangedPackages implements Parcelable { + /** The last known sequence number for these changes */ + private final int mSequenceNumber; + /** The names of the packages that have changed */ + private final List<String> mPackageNames; + + public ChangedPackages(int sequenceNumber, @NonNull List<String> packageNames) { + this.mSequenceNumber = sequenceNumber; + this.mPackageNames = packageNames; + } + + /** @hide */ + protected ChangedPackages(Parcel in) { + mSequenceNumber = in.readInt(); + mPackageNames = in.createStringArrayList(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mSequenceNumber); + dest.writeStringList(mPackageNames); + } + + /** + * Returns the last known sequence number for these changes. + */ + public int getSequenceNumber() { + return mSequenceNumber; + } + + /** + * Returns the names of the packages that have changed. + */ + public @NonNull List<String> getPackageNames() { + return mPackageNames; + } + + public static final Parcelable.Creator<ChangedPackages> CREATOR = + new Parcelable.Creator<ChangedPackages>() { + public ChangedPackages createFromParcel(Parcel in) { + return new ChangedPackages(in); + } + + public ChangedPackages[] newArray(int size) { + return new ChangedPackages[size]; + } + }; +} diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 3fb46cfab791..9d36a730ac09 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -23,6 +23,7 @@ import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.ContainerEncryptionParams; +import android.content.pm.ChangedPackages; import android.content.pm.InstantAppInfo; import android.content.pm.FeatureInfo; import android.content.pm.IPackageInstallObserver2; @@ -611,6 +612,8 @@ interface IPackageManager { String getServicesSystemSharedLibraryPackageName(); String getSharedSystemSharedLibraryPackageName(); + ChangedPackages getChangedPackages(int sequenceNumber, int userId); + boolean isPackageDeviceAdminOnAnyUser(String packageName); List<String> getPreviousCodePaths(in String packageName); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index b20b5e2e9d96..308153dd3538 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -20,6 +20,7 @@ import android.Manifest; import android.annotation.CheckResult; import android.annotation.DrawableRes; import android.annotation.IntDef; +import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -3853,6 +3854,17 @@ public abstract class PackageManager { public abstract @NonNull String getSharedSystemSharedLibraryPackageName(); /** + * Returns the names of the packages that have been changed + * [eg. added, removed or updated] since the given sequence + * number. + * <p>If no packages have been changed, returns <code>null</code>. + * <p>The sequence number starts at <code>0</code> and is + * reset every boot. + */ + public abstract @Nullable ChangedPackages getChangedPackages( + @IntRange(from=0) int sequenceNumber); + + /** * Get a list of features that are available on the * system. * diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index ebd0b343f9cf..6da916ba4466 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -126,6 +126,7 @@ import android.content.ServiceConnection; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.AppsQueryHelper; +import android.content.pm.ChangedPackages; import android.content.pm.ComponentInfo; import android.content.pm.InstantAppInfo; import android.content.pm.EphemeralRequest; @@ -720,6 +721,21 @@ public class PackageManagerService extends IPackageManager.Stub { private final InstantAppRegistry mInstantAppRegistry; + @GuardedBy("mPackages") + int mChangedPackagesSequenceNumber; + /** + * List of changed [installed, removed or updated] packages. + * mapping from user id -> sequence number -> package name + */ + @GuardedBy("mPackages") + final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>(); + /** + * The sequence number of the last change to a package. + * mapping from user id -> package name -> sequence number + */ + @GuardedBy("mPackages") + final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>(); + public static final class SharedLibraryEntry { public final String path; public final String apk; @@ -4220,6 +4236,52 @@ public class PackageManagerService extends IPackageManager.Stub { } } + private void updateSequenceNumberLP(String packageName, int[] userList) { + for (int i = userList.length - 1; i >= 0; --i) { + final int userId = userList[i]; + SparseArray<String> changedPackages = mChangedPackages.get(userId); + if (changedPackages == null) { + changedPackages = new SparseArray<>(); + mChangedPackages.put(userId, changedPackages); + } + Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId); + if (sequenceNumbers == null) { + sequenceNumbers = new HashMap<>(); + mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers); + } + final Integer sequenceNumber = sequenceNumbers.get(packageName); + if (sequenceNumber != null) { + changedPackages.remove(sequenceNumber); + } + changedPackages.put(mChangedPackagesSequenceNumber, packageName); + sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber); + } + mChangedPackagesSequenceNumber++; + } + + @Override + public ChangedPackages getChangedPackages(int sequenceNumber, int userId) { + synchronized (mPackages) { + if (sequenceNumber >= mChangedPackagesSequenceNumber) { + return null; + } + final SparseArray<String> changedPackages = mChangedPackages.get(userId); + if (changedPackages == null) { + return null; + } + final List<String> packageNames = + new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber); + for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) { + final String packageName = changedPackages.get(i); + if (packageName != null) { + packageNames.add(packageName); + } + } + return packageNames.isEmpty() + ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames); + } + } + @Override public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() { ArrayList<FeatureInfo> res; @@ -13263,6 +13325,9 @@ public class PackageManagerService extends IPackageManager.Stub { } } sendPackageAddedForUser(packageName, pkgSetting, userId); + synchronized (mPackages) { + updateSequenceNumberLP(packageName, new int[]{ userId }); + } } } finally { Binder.restoreCallingIdentity(callingId); @@ -16847,6 +16912,10 @@ public class PackageManagerService extends IPackageManager.Stub { sUserManager.getUserIds(), true); } } + + if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) { + updateSequenceNumberLP(pkgName, res.newUsers); + } } } @@ -17429,6 +17498,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (res) { mInstantAppRegistry.onPackageUninstalledLPw(uninstalledPs.pkg, info.removedUsers); + updateSequenceNumberLP(packageName, info.removedUsers); } } } @@ -19725,6 +19795,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } } scheduleWritePackageRestrictionsLocked(userId); + updateSequenceNumberLP(packageName, new int[] { userId }); components = mPendingBroadcasts.get(userId, packageName); final boolean newPackage = components == null; if (newPackage) { diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java index 0dcd0f14dd38..d51d75ee9f95 100644 --- a/test-runner/src/android/test/mock/MockPackageManager.java +++ b/test-runner/src/android/test/mock/MockPackageManager.java @@ -24,6 +24,7 @@ import android.content.IntentFilter; import android.content.IntentSender; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.ChangedPackages; import android.content.pm.InstantAppInfo; import android.content.pm.FeatureInfo; import android.content.pm.IPackageDataObserver; @@ -374,6 +375,12 @@ public class MockPackageManager extends PackageManager { throw new UnsupportedOperationException(); } + /** @hide */ + @Override + public ChangedPackages getChangedPackages(int sequenceNumber) { + throw new UnsupportedOperationException(); + } + @Override public ResolveInfo resolveActivity(Intent intent, int flags) { throw new UnsupportedOperationException(); diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java index 00799a1c6bb6..00394763f1b3 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java @@ -24,6 +24,7 @@ import android.content.IntentFilter; import android.content.IntentSender; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.ChangedPackages; import android.content.pm.InstantAppInfo; import android.content.pm.FeatureInfo; import android.content.pm.IPackageDataObserver; @@ -859,6 +860,11 @@ public class BridgePackageManager extends PackageManager { } @Override + public ChangedPackages getChangedPackages(int sequenceNumber) { + return null; + } + + @Override public boolean isUpgrade() { return false; } |