Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6788212d authored by Svet Ganov's avatar Svet Ganov
Browse files

Platform support for static shared libraries

This change adds support for static shared libraries that
emulate static linking allowing apps that statically link
against the same library version to share a common
implementation. A library is hosed by a package in a standard
APK.

Static shared libraries have a name and a version declared
by a dedicated manifest tag. A client uses also a new tag
to refer to the static library it uses by specifying the
lib name, version, and the hash of the signing certificate.
This allows two apps to rely on two different library versions
and prevents impersonation of the shared library by a side-loaded
app with the same package name.

Internally apps providing static libs use synthetic package
name generated from the manifest package name and the library
version. This allows having different "versions" of the same
package installed at the same time.

An application cannot be installed if a static shared lib it
depends on is missing. A used shared library cannot be uninstalled.
Shared libraries can rotate certificates like normal apps. The
versions of these libs should be ordered similarly to the version
codes of the hosting package. Such libs cannot use shared user
id, cannot be ephemeral, cannot declare other libraries, cannot
rename their package, cannot declare child-packages. They must
target O SDK. Also they cannot be suspended or hidden or their
uninstall blocked. Generally, speaking policy regarding code in
static shared libs should be applied to the packages using the
library as it could have just statically linked the code.

We now have APIs to query information about the shared libraries
on the device in general. To clients static shared libraries are
presented as multiple versions of the same package which is how
they are declared and published. Therefore, one can have two
versions of the same package which means we need way to query
for and uninstall a specific version of a package. Also static
shared libs can depend on other static shared libs which are
versioned packages. To ease representation we add the concept
of a versioned package which should be used in the case of
static shared libs.

A client can see only the static shared libs it depends on and
more specifically only the versions it depends would be retrieved
by using the standard package manager APIs. There is a new
dedicated API to get info about all shared libraries which
would provide data about all static shared lib versions. Also
these libraries must use v2 signing scheme.

Test: CTS tests pass

bug:30974070

Change-Id: I4f3d537ee7a81f880950377b996e1d9d4813da5c
parent 9a33bda0
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ package android {
    field public static final java.lang.String RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH";
    field public static final java.lang.String RECORD_AUDIO = "android.permission.RECORD_AUDIO";
    field public static final java.lang.String REORDER_TASKS = "android.permission.REORDER_TASKS";
    field public static final java.lang.String REQUEST_DELETE_PACKAGES = "android.permission.REQUEST_DELETE_PACKAGES";
    field public static final java.lang.String REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
    field public static final java.lang.String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
    field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
@@ -362,6 +363,7 @@ package android {
    field public static final int centerMedium = 16842959; // 0x10100cf
    field public static final int centerX = 16843170; // 0x10101a2
    field public static final int centerY = 16843171; // 0x10101a3
    field public static final int certDigest = 16844106; // 0x101054a
    field public static final int checkBoxPreferenceStyle = 16842895; // 0x101008f
    field public static final int checkMark = 16843016; // 0x1010108
    field public static final int checkMarkTint = 16843943; // 0x10104a7
@@ -9935,6 +9937,7 @@ package android.content.pm {
    method public void registerSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
    method public void registerSessionCallback(android.content.pm.PackageInstaller.SessionCallback, android.os.Handler);
    method public void uninstall(java.lang.String, android.content.IntentSender);
    method public void uninstall(android.content.pm.VersionedPackage, android.content.IntentSender);
    method public void unregisterSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
    method public void updateSessionAppIcon(int, android.graphics.Bitmap);
    method public void updateSessionAppLabel(int, java.lang.CharSequence);
@@ -10081,6 +10084,7 @@ package android.content.pm {
    method public abstract int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract int[] getPackageGids(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.pm.PackageInfo getPackageInfo(android.content.pm.VersionedPackage, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.pm.PackageInstaller getPackageInstaller();
    method public abstract int getPackageUid(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract java.lang.String[] getPackagesForUid(int);
@@ -10095,6 +10099,7 @@ package android.content.pm {
    method public abstract android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.res.Resources getResourcesForApplication(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract java.util.List<android.content.pm.SharedLibraryInfo> getSharedLibraries(int);
    method public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
    method public abstract java.lang.String[] getSystemSharedLibraryNames();
    method public abstract java.lang.CharSequence getText(java.lang.String, int, android.content.pm.ApplicationInfo);
@@ -10253,6 +10258,7 @@ package android.content.pm {
    field public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; // 0xfffffffc
    field public static final int VERIFICATION_ALLOW = 1; // 0x1
    field public static final int VERIFICATION_REJECT = -1; // 0xffffffff
    field public static final int VERSION_CODE_HIGHEST = -1; // 0xffffffff
  }
  public static class PackageManager.NameNotFoundException extends android.util.AndroidException {
@@ -10392,6 +10398,20 @@ package android.content.pm {
    field public java.lang.String permission;
  }
  public final class SharedLibraryInfo implements android.os.Parcelable {
    method public int describeContents();
    method public android.content.pm.VersionedPackage getDeclaringPackage();
    method public java.util.List<android.content.pm.VersionedPackage> getDependentPackages();
    method public java.lang.String getName();
    method public int getVersion();
    method public boolean isBuiltin();
    method public boolean isDynamic();
    method public boolean isStatic();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.pm.SharedLibraryInfo> CREATOR;
    field public static final int VERSION_UNDEFINED = -1; // 0xffffffff
  }
  public final class ShortcutInfo implements android.os.Parcelable {
    method public int describeContents();
    method public android.content.ComponentName getActivity();
@@ -10467,6 +10487,15 @@ package android.content.pm {
    field public static final android.os.Parcelable.Creator<android.content.pm.Signature> CREATOR;
  }
  public final class VersionedPackage implements android.os.Parcelable {
    ctor public VersionedPackage(java.lang.String, int);
    method public int describeContents();
    method public java.lang.String getPackageName();
    method public long getVersionCode();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.pm.VersionedPackage> CREATOR;
  }
}
package android.content.res {
@@ -39175,6 +39204,7 @@ package android.test.mock {
    method public int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
    method public int[] getPackageGids(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public android.content.pm.PackageInfo getPackageInfo(android.content.pm.VersionedPackage, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public android.content.pm.PackageInstaller getPackageInstaller();
    method public int getPackageUid(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public java.lang.String[] getPackagesForUid(int);
@@ -39189,6 +39219,7 @@ package android.test.mock {
    method public android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo);
    method public android.content.res.Resources getResourcesForApplication(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
    method public android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public java.util.List<android.content.pm.SharedLibraryInfo> getSharedLibraries(int);
    method public android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
    method public java.lang.String[] getSystemSharedLibraryNames();
    method public java.lang.CharSequence getText(java.lang.String, int, android.content.pm.ApplicationInfo);
+31 −0
Original line number Diff line number Diff line
@@ -200,6 +200,7 @@ package android {
    field public static final java.lang.String REGISTER_SIM_SUBSCRIPTION = "android.permission.REGISTER_SIM_SUBSCRIPTION";
    field public static final java.lang.String REMOVE_DRM_CERTIFICATES = "android.permission.REMOVE_DRM_CERTIFICATES";
    field public static final java.lang.String REORDER_TASKS = "android.permission.REORDER_TASKS";
    field public static final java.lang.String REQUEST_DELETE_PACKAGES = "android.permission.REQUEST_DELETE_PACKAGES";
    field public static final java.lang.String REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
    field public static final java.lang.String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
    field public static final java.lang.String REQUEST_NETWORK_SCORES = "android.permission.REQUEST_NETWORK_SCORES";
@@ -471,6 +472,7 @@ package android {
    field public static final int centerMedium = 16842959; // 0x10100cf
    field public static final int centerX = 16843170; // 0x10101a2
    field public static final int centerY = 16843171; // 0x10101a3
    field public static final int certDigest = 16844106; // 0x101054a
    field public static final int checkBoxPreferenceStyle = 16842895; // 0x101008f
    field public static final int checkMark = 16843016; // 0x1010108
    field public static final int checkMarkTint = 16843943; // 0x10104a7
@@ -10369,6 +10371,7 @@ package android.content.pm {
    method public void registerSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
    method public void registerSessionCallback(android.content.pm.PackageInstaller.SessionCallback, android.os.Handler);
    method public void uninstall(java.lang.String, android.content.IntentSender);
    method public void uninstall(android.content.pm.VersionedPackage, android.content.IntentSender);
    method public void unregisterSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
    method public void updateSessionAppIcon(int, android.graphics.Bitmap);
    method public void updateSessionAppLabel(int, java.lang.CharSequence);
@@ -10522,6 +10525,7 @@ package android.content.pm {
    method public abstract int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract int[] getPackageGids(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.pm.PackageInfo getPackageInfo(android.content.pm.VersionedPackage, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.pm.PackageInstaller getPackageInstaller();
    method public abstract int getPackageUid(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract java.lang.String[] getPackagesForUid(int);
@@ -10537,6 +10541,7 @@ package android.content.pm {
    method public abstract android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.res.Resources getResourcesForApplication(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract java.util.List<android.content.pm.SharedLibraryInfo> getSharedLibraries(int);
    method public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
    method public abstract java.lang.String[] getSystemSharedLibraryNames();
    method public abstract java.lang.CharSequence getText(java.lang.String, int, android.content.pm.ApplicationInfo);
@@ -10752,6 +10757,7 @@ package android.content.pm {
    field public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; // 0xfffffffc
    field public static final int VERIFICATION_ALLOW = 1; // 0x1
    field public static final int VERIFICATION_REJECT = -1; // 0xffffffff
    field public static final int VERSION_CODE_HIGHEST = -1; // 0xffffffff
  }
  public static class PackageManager.NameNotFoundException extends android.util.AndroidException {
@@ -10900,6 +10906,20 @@ package android.content.pm {
    field public java.lang.String permission;
  }
  public final class SharedLibraryInfo implements android.os.Parcelable {
    method public int describeContents();
    method public android.content.pm.VersionedPackage getDeclaringPackage();
    method public java.util.List<android.content.pm.VersionedPackage> getDependentPackages();
    method public java.lang.String getName();
    method public int getVersion();
    method public boolean isBuiltin();
    method public boolean isDynamic();
    method public boolean isStatic();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.pm.SharedLibraryInfo> CREATOR;
    field public static final int VERSION_UNDEFINED = -1; // 0xffffffff
  }
  public final class ShortcutInfo implements android.os.Parcelable {
    method public int describeContents();
    method public android.content.ComponentName getActivity();
@@ -10975,6 +10995,15 @@ package android.content.pm {
    field public static final android.os.Parcelable.Creator<android.content.pm.Signature> CREATOR;
  }
  public final class VersionedPackage implements android.os.Parcelable {
    ctor public VersionedPackage(java.lang.String, int);
    method public int describeContents();
    method public java.lang.String getPackageName();
    method public long getVersionCode();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.pm.VersionedPackage> CREATOR;
  }
}
package android.content.pm.permission {
@@ -42444,6 +42473,7 @@ package android.test.mock {
    method public int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
    method public int[] getPackageGids(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public android.content.pm.PackageInfo getPackageInfo(android.content.pm.VersionedPackage, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public android.content.pm.PackageInstaller getPackageInstaller();
    method public int getPackageUid(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public java.lang.String[] getPackagesForUid(int);
@@ -42459,6 +42489,7 @@ package android.test.mock {
    method public android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo);
    method public android.content.res.Resources getResourcesForApplication(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
    method public android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public java.util.List<android.content.pm.SharedLibraryInfo> getSharedLibraries(int);
    method public android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
    method public java.lang.String[] getSystemSharedLibraryNames();
    method public java.lang.CharSequence getText(java.lang.String, int, android.content.pm.ApplicationInfo);
+31 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ package android {
    field public static final java.lang.String RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH";
    field public static final java.lang.String RECORD_AUDIO = "android.permission.RECORD_AUDIO";
    field public static final java.lang.String REORDER_TASKS = "android.permission.REORDER_TASKS";
    field public static final java.lang.String REQUEST_DELETE_PACKAGES = "android.permission.REQUEST_DELETE_PACKAGES";
    field public static final java.lang.String REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
    field public static final java.lang.String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
    field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
@@ -362,6 +363,7 @@ package android {
    field public static final int centerMedium = 16842959; // 0x10100cf
    field public static final int centerX = 16843170; // 0x10101a2
    field public static final int centerY = 16843171; // 0x10101a3
    field public static final int certDigest = 16844106; // 0x101054a
    field public static final int checkBoxPreferenceStyle = 16842895; // 0x101008f
    field public static final int checkMark = 16843016; // 0x1010108
    field public static final int checkMarkTint = 16843943; // 0x10104a7
@@ -9963,6 +9965,7 @@ package android.content.pm {
    method public void registerSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
    method public void registerSessionCallback(android.content.pm.PackageInstaller.SessionCallback, android.os.Handler);
    method public void uninstall(java.lang.String, android.content.IntentSender);
    method public void uninstall(android.content.pm.VersionedPackage, android.content.IntentSender);
    method public void unregisterSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
    method public void updateSessionAppIcon(int, android.graphics.Bitmap);
    method public void updateSessionAppLabel(int, java.lang.CharSequence);
@@ -10111,6 +10114,7 @@ package android.content.pm {
    method public abstract int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract int[] getPackageGids(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.pm.PackageInfo getPackageInfo(android.content.pm.VersionedPackage, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.pm.PackageInstaller getPackageInstaller();
    method public abstract int getPackageUid(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract java.lang.String[] getPackagesForUid(int);
@@ -10125,6 +10129,7 @@ package android.content.pm {
    method public abstract android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.res.Resources getResourcesForApplication(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public abstract java.util.List<android.content.pm.SharedLibraryInfo> getSharedLibraries(int);
    method public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
    method public abstract java.lang.String[] getSystemSharedLibraryNames();
    method public abstract java.lang.CharSequence getText(java.lang.String, int, android.content.pm.ApplicationInfo);
@@ -10283,6 +10288,7 @@ package android.content.pm {
    field public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; // 0xfffffffc
    field public static final int VERIFICATION_ALLOW = 1; // 0x1
    field public static final int VERIFICATION_REJECT = -1; // 0xffffffff
    field public static final int VERSION_CODE_HIGHEST = -1; // 0xffffffff
  }
  public static class PackageManager.NameNotFoundException extends android.util.AndroidException {
@@ -10423,6 +10429,20 @@ package android.content.pm {
    field public java.lang.String permission;
  }
  public final class SharedLibraryInfo implements android.os.Parcelable {
    method public int describeContents();
    method public android.content.pm.VersionedPackage getDeclaringPackage();
    method public java.util.List<android.content.pm.VersionedPackage> getDependentPackages();
    method public java.lang.String getName();
    method public int getVersion();
    method public boolean isBuiltin();
    method public boolean isDynamic();
    method public boolean isStatic();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.pm.SharedLibraryInfo> CREATOR;
    field public static final int VERSION_UNDEFINED = -1; // 0xffffffff
  }
  public final class ShortcutInfo implements android.os.Parcelable {
    method public int describeContents();
    method public android.content.ComponentName getActivity();
@@ -10499,6 +10519,15 @@ package android.content.pm {
    field public static final android.os.Parcelable.Creator<android.content.pm.Signature> CREATOR;
  }
  public final class VersionedPackage implements android.os.Parcelable {
    ctor public VersionedPackage(java.lang.String, int);
    method public int describeContents();
    method public java.lang.String getPackageName();
    method public long getVersionCode();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.pm.VersionedPackage> CREATOR;
  }
}
package android.content.res {
@@ -39299,6 +39328,7 @@ package android.test.mock {
    method public int[] getPackageGids(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
    method public int[] getPackageGids(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public android.content.pm.PackageInfo getPackageInfo(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public android.content.pm.PackageInfo getPackageInfo(android.content.pm.VersionedPackage, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public android.content.pm.PackageInstaller getPackageInstaller();
    method public int getPackageUid(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public java.lang.String[] getPackagesForUid(int);
@@ -39313,6 +39343,7 @@ package android.test.mock {
    method public android.content.res.Resources getResourcesForApplication(android.content.pm.ApplicationInfo);
    method public android.content.res.Resources getResourcesForApplication(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
    method public android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
    method public java.util.List<android.content.pm.SharedLibraryInfo> getSharedLibraries(int);
    method public android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
    method public java.lang.String[] getSystemSharedLibraryNames();
    method public java.lang.CharSequence getText(java.lang.String, int, android.content.pm.ApplicationInfo);
+1 −1
Original line number Diff line number Diff line
@@ -1556,7 +1556,7 @@ public final class Pm {
        System.err.println("       pm install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH]");
        System.err.println("       pm install-commit SESSION_ID");
        System.err.println("       pm install-abandon SESSION_ID");
        System.err.println("       pm uninstall [-k] [--user USER_ID] PACKAGE");
        System.err.println("       pm uninstall [-k] [--user USER_ID] [--versionCode VERSION_CODE] PACKAGE");
        System.err.println("       pm set-installer PACKAGE INSTALLER");
        System.err.println("       pm move-package PACKAGE [internal|UUID]");
        System.err.println("       pm move-primary-storage [internal|UUID]");
+45 −8

File changed.

Preview size limit exceeded, changes collapsed.

Loading