Merge "Add the {get,set}PackageObbPaths calls to API" into honeycomb

This commit is contained in:
Kenny Root
2011-01-14 12:42:12 -08:00
committed by Android (Google) Code Review
7 changed files with 346 additions and 23 deletions

View File

@@ -60256,6 +60256,19 @@
<exception name="PackageManager.NameNotFoundException" type="android.content.pm.PackageManager.NameNotFoundException">
</exception>
</method>
<method name="getPackageObbPaths"
return="java.lang.String[]"
abstract="true"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="packageName" type="java.lang.String">
</parameter>
</method>
<method name="getPackagesForUid"
return="java.lang.String[]"
abstract="true"
@@ -60742,6 +60755,21 @@
<parameter name="installerPackageName" type="java.lang.String">
</parameter>
</method>
<method name="setPackageObbPaths"
return="void"
abstract="true"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="packageName" type="java.lang.String">
</parameter>
<parameter name="paths" type="java.lang.String[]">
</parameter>
</method>
<field name="COMPONENT_ENABLED_STATE_DEFAULT"
type="int"
transient="false"
@@ -185251,6 +185279,19 @@
<exception name="PackageManager.NameNotFoundException" type="android.content.pm.PackageManager.NameNotFoundException">
</exception>
</method>
<method name="getPackageObbPaths"
return="java.lang.String[]"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="packageName" type="java.lang.String">
</parameter>
</method>
<method name="getPackagesForUid"
return="java.lang.String[]"
abstract="false"
@@ -185750,6 +185791,21 @@
<parameter name="path" type="java.lang.String">
</parameter>
</method>
<method name="setPackageObbPaths"
return="void"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="packageName" type="java.lang.String">
</parameter>
<parameter name="paths" type="java.lang.String[]">
</parameter>
</method>
</class>
<class name="MockResources"
extends="android.content.res.Resources"

View File

@@ -1104,14 +1104,24 @@ final class ApplicationPackageManager extends PackageManager {
}
@Override
public void setPackageObbPath(String packageName, String path) {
public void setPackageObbPaths(String packageName, String[] paths) {
try {
mPM.setPackageObbPath(packageName, path);
mPM.setPackageObbPaths(packageName, paths);
} catch (RemoteException e) {
// Should never happen!
}
}
@Override
public String[] getPackageObbPaths(String packageName) {
try {
return mPM.getPackageObbPaths(packageName);
} catch (RemoteException e) {
// Should never happen!
}
return null;
}
private final ContextImpl mContext;
private final IPackageManager mPM;

View File

@@ -324,5 +324,6 @@ interface IPackageManager {
boolean setInstallLocation(int loc);
int getInstallLocation();
void setPackageObbPath(String packageName, String path);
void setPackageObbPaths(in String packageName, in String[] paths);
String[] getPackageObbPaths(in String packageName);
}

View File

@@ -2291,15 +2291,30 @@ public abstract class PackageManager {
String packageName, IPackageMoveObserver observer, int flags);
/**
* Sets the Opaque Binary Blob (OBB) file location.
* Sets the Opaque Binary Blob (OBB) file path associated with a package
* name. The caller must have the
* {@link android.Manifest.permission#INSTALL_PACKAGES} permission.
* <p>
* NOTE: The existence or format of this file is not currently checked, but
* it may be in the future.
*
* @param packageName Name of the package with which to associate the .obb
* file
* @param path Path on the filesystem to the .obb file
* @hide
* file.
* @param paths Arrays of paths on the filesystem to the .obb files
* associated with the package.
* @see #getPackageObbPaths(String)
*/
public abstract void setPackageObbPath(String packageName, String path);
public abstract void setPackageObbPaths(String packageName, String[] paths);
/**
* Gets the Opaque Binary Blob (OBB) file path associated with the package.
* The caller must be the owner of the package queried or have the
* {@link android.Manifest.permission#INSTALL_PACKAGES} permission.
*
* @param packageName Name of the package with which to associate the .obb
* file.
* @return array of paths to .obb files associated with the package
* @see #setPackageObbPaths(String, String[])
*/
public abstract String[] getPackageObbPaths(String packageName);
}

View File

@@ -48,6 +48,7 @@ import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
public class PackageManagerTests extends AndroidTestCase {
private static final boolean localLOGV = true;
@@ -3105,6 +3106,164 @@ public class PackageManagerTests extends AndroidTestCase {
PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
}
@LargeTest
public void testPackageObbPaths_Nonexistent() {
try {
final PackageManager pm = getPm();
// Invalid Java package name.
pm.getPackageObbPaths("=non-existent");
fail("Should not be able to get package OBB paths for non-existent package");
} catch (IllegalArgumentException e) {
// pass
}
}
@LargeTest
public void testPackageObbPaths_Initial() {
InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, false);
try {
final PackageManager pm = getPm();
assertEquals("Initial obb paths should be null",
null, pm.getPackageObbPaths(ip.pkg.packageName));
} finally {
cleanUpInstall(ip);
}
}
@LargeTest
public void testPackageObbPaths_Null() {
InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, false);
try {
final PackageManager pm = getPm();
pm.setPackageObbPaths(ip.pkg.packageName, null);
assertEquals("Returned paths should be null",
null, pm.getPackageObbPaths(ip.pkg.packageName));
} finally {
cleanUpInstall(ip);
}
}
@LargeTest
public void testPackageObbPaths_Empty() {
InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, false);
try {
final PackageManager pm = getPm();
final String[] paths = new String[0];
pm.setPackageObbPaths(ip.pkg.packageName, paths);
assertEquals("Empty list should be interpreted as null",
null, pm.getPackageObbPaths(ip.pkg.packageName));
} finally {
cleanUpInstall(ip);
}
}
@LargeTest
public void testPackageObbPaths_Single() {
InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, false);
try {
final PackageManager pm = getPm();
final String[] paths = new String[] {
"/example/test",
};
pm.setPackageObbPaths(ip.pkg.packageName, paths.clone());
assertTrue("Previously set paths should be the same as the returned paths.",
Arrays.equals(paths, pm.getPackageObbPaths(ip.pkg.packageName)));
} finally {
cleanUpInstall(ip);
}
}
@LargeTest
public void testPackageObbPaths_Multiple() {
InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, false);
try {
final PackageManager pm = getPm();
final String[] paths = new String[] {
"/example/test1",
"/example/test2",
};
pm.setPackageObbPaths(ip.pkg.packageName, paths.clone());
assertTrue("Previously set paths should be the same as the returned paths.",
Arrays.equals(paths, pm.getPackageObbPaths(ip.pkg.packageName)));
} finally {
cleanUpInstall(ip);
}
}
@LargeTest
public void testPackageObbPaths_Twice() {
InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, false);
try {
final PackageManager pm = getPm();
final String[] paths = new String[] {
"/example/test1",
"/example/test2",
};
pm.setPackageObbPaths(ip.pkg.packageName, paths.clone());
assertTrue("Previously set paths should be the same as the returned paths.",
Arrays.equals(paths, pm.getPackageObbPaths(ip.pkg.packageName)));
paths[0] = "/example/test3";
pm.setPackageObbPaths(ip.pkg.packageName, paths.clone());
assertTrue("Previously set paths should be the same as the returned paths.",
Arrays.equals(paths, pm.getPackageObbPaths(ip.pkg.packageName)));
} finally {
cleanUpInstall(ip);
}
}
@LargeTest
public void testPackageObbPaths_ReplacePackage() {
InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, false);
try {
final PackageManager pm = getPm();
final String[] paths = new String[] {
"/example/test1",
"/example/test2",
};
pm.setPackageObbPaths(ip.pkg.packageName, paths.clone());
Log.i(TAG, "Creating replaceReceiver");
final GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
final int flags = PackageManager.INSTALL_REPLACE_EXISTING;
invokeInstallPackage(ip.packageURI, flags, receiver);
assertInstall(ip.pkg, flags, ip.pkg.installLocation);
assertTrue("Previously set paths should be the same as the returned paths.",
Arrays.equals(paths, pm.getPackageObbPaths(ip.pkg.packageName)));
} finally {
cleanUpInstall(ip);
}
}
/*---------- Recommended install location tests ----*/
/*
* TODO's

View File

@@ -4646,16 +4646,52 @@ class PackageManagerService extends IPackageManager.Stub {
}
}
public void setPackageObbPath(String packageName, String path) {
public void setPackageObbPaths(String packageName, String[] paths) {
if (DEBUG_OBB)
Log.v(TAG, "Setting .obb path for " + packageName + " to: " + path);
PackageSetting pkgSetting;
Log.v(TAG, "Setting .obb paths for " + packageName + " to: " + Arrays.toString(paths));
final int uid = Binder.getCallingUid();
final int permission = mContext.checkCallingPermission(
android.Manifest.permission.INSTALL_PACKAGES);
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
if (!allowedByPermission) {
throw new SecurityException("Permission denial: attempt to set .obb file from pid="
+ Binder.getCallingPid());
}
synchronized (mPackages) {
final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
if (paths != null) {
if (paths.length == 0) {
// Don't bother storing an empty array.
paths = null;
} else {
// Don't allow the caller to manipulate our copy of the
// list.
paths = paths.clone();
}
}
// Only write settings file if the new and old settings are not the
// same.
if (!Arrays.equals(paths, pkgSetting.obbPathStrings)) {
pkgSetting.obbPathStrings = paths;
mSettings.writeLP();
}
}
}
public String[] getPackageObbPaths(String packageName) {
if (DEBUG_OBB)
Log.v(TAG, "Getting .obb paths for " + packageName);
final int uid = Binder.getCallingUid();
final int permission = mContext.checkCallingPermission(
android.Manifest.permission.INSTALL_PACKAGES);
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
synchronized (mPackages) {
pkgSetting = mSettings.mPackages.get(packageName);
final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
if (pkgSetting == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
@@ -4664,8 +4700,7 @@ class PackageManagerService extends IPackageManager.Stub {
+ Binder.getCallingPid() + ", uid=" + uid + ", package uid="
+ pkgSetting.userId);
}
pkgSetting.obbPathString = path;
mSettings.writeLP();
return pkgSetting.obbPathStrings;
}
}
@@ -7238,7 +7273,7 @@ class PackageManagerService extends IPackageManager.Stub {
pw.print(" codePath="); pw.println(ps.codePathString);
pw.print(" resourcePath="); pw.println(ps.resourcePathString);
pw.print(" nativeLibraryPath="); pw.println(ps.nativeLibraryPathString);
pw.print(" obbPath="); pw.println(ps.obbPathString);
pw.print(" obbPaths="); pw.println(Arrays.toString(ps.obbPathStrings));
pw.print(" versionCode="); pw.println(ps.versionCode);
if (ps.pkg != null) {
pw.print(" versionName="); pw.println(ps.pkg.mVersionName);
@@ -7818,7 +7853,7 @@ class PackageManagerService extends IPackageManager.Stub {
File resourcePath;
String resourcePathString;
String nativeLibraryPathString;
String obbPathString;
String[] obbPathStrings;
long timeStamp;
long firstInstallTime;
long lastUpdateTime;
@@ -7864,7 +7899,11 @@ class PackageManagerService extends IPackageManager.Stub {
resourcePath = base.resourcePath;
resourcePathString = base.resourcePathString;
nativeLibraryPathString = base.nativeLibraryPathString;
obbPathString = base.obbPathString;
if (base.obbPathStrings != null) {
obbPathStrings = base.obbPathStrings.clone();
}
timeStamp = base.timeStamp;
firstInstallTime = base.firstInstallTime;
lastUpdateTime = base.lastUpdateTime;
@@ -8923,8 +8962,15 @@ class PackageManagerService extends IPackageManager.Stub {
if (pkg.installerPackageName != null) {
serializer.attribute(null, "installer", pkg.installerPackageName);
}
if (pkg.obbPathString != null) {
serializer.attribute(null, "obbPath", pkg.obbPathString);
if (pkg.obbPathStrings != null && pkg.obbPathStrings.length > 0) {
int N = pkg.obbPathStrings.length;
serializer.startTag(null, "obbs");
for (int i = 0; i < N; i++) {
serializer.startTag(null, "obb");
serializer.attribute(null, "path", pkg.obbPathStrings[i]);
serializer.endTag(null, "obb");
}
serializer.endTag(null, "obbs");
}
pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
if ((pkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
@@ -9328,7 +9374,6 @@ class PackageManagerService extends IPackageManager.Stub {
String codePathStr = null;
String resourcePathStr = null;
String nativeLibraryPathStr = null;
String obbPathStr = null;
String systemStr = null;
String installerPackageName = null;
String uidError = null;
@@ -9348,7 +9393,6 @@ class PackageManagerService extends IPackageManager.Stub {
codePathStr = parser.getAttributeValue(null, "codePath");
resourcePathStr = parser.getAttributeValue(null, "resourcePath");
nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
obbPathStr = parser.getAttributeValue(null, "obbPath");
version = parser.getAttributeValue(null, "version");
if (version != null) {
try {
@@ -9473,7 +9517,6 @@ class PackageManagerService extends IPackageManager.Stub {
packageSetting.uidError = "true".equals(uidError);
packageSetting.installerPackageName = installerPackageName;
packageSetting.nativeLibraryPathString = nativeLibraryPathStr;
packageSetting.obbPathString = obbPathStr;
final String enabledStr = parser.getAttributeValue(null, "enabled");
if (enabledStr != null) {
if (enabledStr.equalsIgnoreCase("true")) {
@@ -9521,6 +9564,8 @@ class PackageManagerService extends IPackageManager.Stub {
readGrantedPermissionsLP(parser,
packageSetting.grantedPermissions);
packageSetting.permissionsFixed = true;
} else if (tagName.equals("obbs")) {
readObbPathsLP(packageSetting, parser);
} else {
reportSettingsProblem(Log.WARN,
"Unknown element under <package>: "
@@ -9725,6 +9770,34 @@ class PackageManagerService extends IPackageManager.Stub {
}
}
private void readObbPathsLP(PackageSettingBase packageSetting, XmlPullParser parser)
throws XmlPullParserException, IOException {
final List<String> obbPaths = new ArrayList<String>();
final int outerDepth = parser.getDepth();
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
final String tagName = parser.getName();
if (tagName.equals("obb")) {
final String path = parser.getAttributeValue(null, "path");
obbPaths.add(path);
} else {
reportSettingsProblem(Log.WARN, "Unknown element under <obbs>: "
+ parser.getName());
}
XmlUtils.skipCurrentTag(parser);
}
if (obbPaths.size() == 0) {
return;
} else {
packageSetting.obbPathStrings = obbPaths.toArray(new String[obbPaths.size()]);
}
}
// Returns -1 if we could not find an available UserId to assign
private int newUserIdLP(Object obj) {
// Let's be stupidly inefficient for now...

View File

@@ -496,8 +496,17 @@ public class MockPackageManager extends PackageManager {
throw new UnsupportedOperationException();
}
@Override
public void setPackageObbPath(String packageName, String path) {
throw new UnsupportedOperationException();
}
@Override
public void setPackageObbPaths(String packageName, String[] paths) {
throw new UnsupportedOperationException();
}
@Override
public String[] getPackageObbPaths(String packageName) {
throw new UnsupportedOperationException();
}
}