Merge commit 'a137cf2a1899b863913b4ab32a87835c2d47d8fe' into kraken * commit 'a137cf2a1899b863913b4ab32a87835c2d47d8fe': Fix 2578016.
This commit is contained in:
11
core/tests/coretests/apks/install_loc_auto/Android.mk
Normal file
11
core/tests/coretests/apks/install_loc_auto/Android.mk
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
LOCAL_PATH:= $(call my-dir)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE_TAGS := tests
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||||
|
|
||||||
|
LOCAL_PACKAGE_NAME := FrameworkCoreTests_install_loc_auto
|
||||||
|
|
||||||
|
include $(BUILD_PACKAGE)
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2010 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.
|
||||||
|
-->
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:installLocation="auto"
|
||||||
|
package="com.android.frameworks.coretests.install_loc">
|
||||||
|
|
||||||
|
<application android:hasCode="false">
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!-- Just need this dummy file to have something to build. -->
|
||||||
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
|
<string name="dummy">dummy</string>
|
||||||
|
</resources>
|
||||||
11
core/tests/coretests/apks/install_loc_internal/Android.mk
Normal file
11
core/tests/coretests/apks/install_loc_internal/Android.mk
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
LOCAL_PATH:= $(call my-dir)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE_TAGS := tests
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||||
|
|
||||||
|
LOCAL_PACKAGE_NAME := FrameworkCoreTests_install_loc_internal
|
||||||
|
|
||||||
|
include $(BUILD_PACKAGE)
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2010 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.
|
||||||
|
-->
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:installLocation="internalOnly"
|
||||||
|
package="com.android.frameworks.coretests.install_loc">
|
||||||
|
|
||||||
|
<application android:hasCode="false">
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!-- Just need this dummy file to have something to build. -->
|
||||||
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
|
<string name="dummy">dummy</string>
|
||||||
|
</resources>
|
||||||
11
core/tests/coretests/apks/install_loc_sdcard/Android.mk
Normal file
11
core/tests/coretests/apks/install_loc_sdcard/Android.mk
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
LOCAL_PATH:= $(call my-dir)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE_TAGS := tests
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||||
|
|
||||||
|
LOCAL_PACKAGE_NAME := FrameworkCoreTests_install_loc_sdcard
|
||||||
|
|
||||||
|
include $(BUILD_PACKAGE)
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2010 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.
|
||||||
|
-->
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:installLocation="preferExternal"
|
||||||
|
package="com.android.frameworks.coretests.install_loc">
|
||||||
|
|
||||||
|
<application android:hasCode="false">
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!-- Just need this dummy file to have something to build. -->
|
||||||
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
|
<string name="dummy">dummy</string>
|
||||||
|
</resources>
|
||||||
11
core/tests/coretests/apks/install_loc_unspecified/Android.mk
Normal file
11
core/tests/coretests/apks/install_loc_unspecified/Android.mk
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
LOCAL_PATH:= $(call my-dir)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE_TAGS := tests
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||||
|
|
||||||
|
LOCAL_PACKAGE_NAME := FrameworkCoreTests_install_loc_unspecified
|
||||||
|
|
||||||
|
include $(BUILD_PACKAGE)
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2010 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.
|
||||||
|
-->
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.android.frameworks.coretests.install_loc">
|
||||||
|
|
||||||
|
<application android:hasCode="false">
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<!-- Just need this dummy file to have something to build. -->
|
||||||
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
|
<string name="dummy">dummy</string>
|
||||||
|
</resources>
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -24,6 +24,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.IPackageMoveObserver;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageParser;
|
import android.content.pm.PackageParser;
|
||||||
@@ -1218,8 +1219,15 @@ public class PackageManagerTests extends AndroidTestCase {
|
|||||||
private class PackageMoveObserver extends IPackageMoveObserver.Stub {
|
private class PackageMoveObserver extends IPackageMoveObserver.Stub {
|
||||||
public int returnCode;
|
public int returnCode;
|
||||||
private boolean doneFlag = false;
|
private boolean doneFlag = false;
|
||||||
|
public String packageName;
|
||||||
|
public PackageMoveObserver(String pkgName) {
|
||||||
|
packageName = pkgName;
|
||||||
|
}
|
||||||
public void packageMoved(String packageName, int returnCode) {
|
public void packageMoved(String packageName, int returnCode) {
|
||||||
|
Log.i("DEBUG_MOVE::", "pkg = " + packageName + ", " + "ret = " + returnCode);
|
||||||
|
if (!packageName.equals(this.packageName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
this.returnCode = returnCode;
|
this.returnCode = returnCode;
|
||||||
doneFlag = true;
|
doneFlag = true;
|
||||||
@@ -1234,7 +1242,7 @@ public class PackageManagerTests extends AndroidTestCase {
|
|||||||
|
|
||||||
public boolean invokeMovePackage(String pkgName, int flags,
|
public boolean invokeMovePackage(String pkgName, int flags,
|
||||||
GenericReceiver receiver) throws Exception {
|
GenericReceiver receiver) throws Exception {
|
||||||
PackageMoveObserver observer = new PackageMoveObserver();
|
PackageMoveObserver observer = new PackageMoveObserver(pkgName);
|
||||||
final boolean received = false;
|
final boolean received = false;
|
||||||
mContext.registerReceiver(receiver, receiver.filter);
|
mContext.registerReceiver(receiver, receiver.filter);
|
||||||
try {
|
try {
|
||||||
@@ -1269,6 +1277,26 @@ public class PackageManagerTests extends AndroidTestCase {
|
|||||||
mContext.unregisterReceiver(receiver);
|
mContext.unregisterReceiver(receiver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private boolean invokeMovePackageFail(String pkgName, int flags, int errCode) throws Exception {
|
||||||
|
PackageMoveObserver observer = new PackageMoveObserver(pkgName);
|
||||||
|
try {
|
||||||
|
// Wait on observer
|
||||||
|
synchronized(observer) {
|
||||||
|
getPm().movePackage(pkgName, observer, flags);
|
||||||
|
long waitTime = 0;
|
||||||
|
while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
|
||||||
|
observer.wait(WAIT_TIME_INCR);
|
||||||
|
waitTime += WAIT_TIME_INCR;
|
||||||
|
}
|
||||||
|
if(!observer.isDone()) {
|
||||||
|
throw new Exception("Timed out waiting for pkgmove callback");
|
||||||
|
}
|
||||||
|
assertEquals(errCode, observer.returnCode);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private int getInstallLoc() {
|
private int getInstallLoc() {
|
||||||
boolean userSetting = false;
|
boolean userSetting = false;
|
||||||
@@ -1285,31 +1313,37 @@ public class PackageManagerTests extends AndroidTestCase {
|
|||||||
Settings.System.putInt(mContext.getContentResolver(),
|
Settings.System.putInt(mContext.getContentResolver(),
|
||||||
Settings.System.DEFAULT_INSTALL_LOCATION, loc);
|
Settings.System.DEFAULT_INSTALL_LOCATION, loc);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Tests for moving apps between internal and external storage
|
||||||
|
*/
|
||||||
/*
|
/*
|
||||||
* Utility function that reads a apk bundled as a raw resource
|
* Utility function that reads a apk bundled as a raw resource
|
||||||
* copies it into own data directory and invokes
|
* copies it into own data directory and invokes
|
||||||
* PackageManager api to install first and then replace it
|
* PackageManager api to install first and then replace it
|
||||||
* again.
|
* again.
|
||||||
*/
|
*/
|
||||||
public void moveFromRawResource(int installFlags, int moveFlags,
|
|
||||||
int expRetCode) {
|
private void moveFromRawResource(String outFileName,
|
||||||
|
int rawResId, int installFlags, int moveFlags, boolean cleanUp,
|
||||||
|
boolean fail, int result) {
|
||||||
int origDefaultLoc = getInstallLoc();
|
int origDefaultLoc = getInstallLoc();
|
||||||
setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
|
InstallParams ip = null;
|
||||||
// Install first
|
|
||||||
InstallParams ip = sampleInstallFromRawResource(installFlags, false);
|
|
||||||
ApplicationInfo oldAppInfo = null;
|
|
||||||
try {
|
try {
|
||||||
oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0);
|
setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
|
||||||
} catch (NameNotFoundException e) {
|
// Install first
|
||||||
failStr("Pkg hasnt been installed correctly");
|
ip = installFromRawResource("install.apk", rawResId, installFlags, false,
|
||||||
}
|
false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
ApplicationInfo oldAppInfo = getPm().getApplicationInfo(ip.pkg.packageName, 0);
|
||||||
// Create receiver based on expRetCode
|
if (fail) {
|
||||||
MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName);
|
assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
|
||||||
try {
|
ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
|
||||||
boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags,
|
assertNotNull(info);
|
||||||
receiver);
|
assertEquals(oldAppInfo.flags, info.flags);
|
||||||
if (expRetCode == PackageManager.MOVE_SUCCEEDED) {
|
} else {
|
||||||
|
// Create receiver based on expRetCode
|
||||||
|
MoveReceiver receiver = new MoveReceiver(ip.pkg.packageName);
|
||||||
|
boolean retCode = invokeMovePackage(ip.pkg.packageName, moveFlags,
|
||||||
|
receiver);
|
||||||
assertTrue(retCode);
|
assertTrue(retCode);
|
||||||
ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
|
ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
|
||||||
assertNotNull(info);
|
assertNotNull(info);
|
||||||
@@ -1318,40 +1352,91 @@ public class PackageManagerTests extends AndroidTestCase {
|
|||||||
} else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0){
|
} else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0){
|
||||||
assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
|
assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
assertFalse(retCode);
|
|
||||||
ApplicationInfo info = getPm().getApplicationInfo(ip.pkg.packageName, 0);
|
|
||||||
assertNotNull(info);
|
|
||||||
assertEquals(oldAppInfo.flags, info.flags);
|
|
||||||
}
|
}
|
||||||
|
} catch (NameNotFoundException e) {
|
||||||
|
failStr("Pkg hasnt been installed correctly");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
failStr("Failed with exception : " + e);
|
failStr("Failed with exception : " + e);
|
||||||
} finally {
|
} finally {
|
||||||
cleanUpInstall(ip);
|
if (ip != null) {
|
||||||
|
cleanUpInstall(ip);
|
||||||
|
}
|
||||||
// Restore default install location
|
// Restore default install location
|
||||||
setInstallLoc(origDefaultLoc);
|
setInstallLoc(origDefaultLoc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void sampleMoveFromRawResource(int installFlags, int moveFlags, boolean fail,
|
||||||
|
int result) {
|
||||||
|
moveFromRawResource("install.apk",
|
||||||
|
R.raw.install, installFlags, moveFlags, true,
|
||||||
|
fail, result);
|
||||||
|
}
|
||||||
|
|
||||||
public void testMoveAppInternalToExternal() {
|
public void testMoveAppInternalToExternal() {
|
||||||
moveFromRawResource(0, PackageManager.MOVE_EXTERNAL_MEDIA,
|
int installFlags = PackageManager.INSTALL_INTERNAL;
|
||||||
PackageManager.MOVE_SUCCEEDED);
|
int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
|
||||||
|
boolean fail = false;
|
||||||
|
int result = PackageManager.MOVE_SUCCEEDED;
|
||||||
|
sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMoveAppInternalToInternal() {
|
public void testMoveAppInternalToInternal() {
|
||||||
moveFromRawResource(0, PackageManager.MOVE_INTERNAL,
|
int installFlags = PackageManager.INSTALL_INTERNAL;
|
||||||
PackageManager.MOVE_FAILED_INVALID_LOCATION);
|
int moveFlags = PackageManager.MOVE_INTERNAL;
|
||||||
|
boolean fail = true;
|
||||||
|
int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
|
||||||
|
sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMoveAppExternalToExternal() {
|
public void testMoveAppExternalToExternal() {
|
||||||
moveFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.MOVE_EXTERNAL_MEDIA,
|
int installFlags = PackageManager.INSTALL_EXTERNAL;
|
||||||
PackageManager.MOVE_FAILED_INVALID_LOCATION);
|
int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
|
||||||
|
boolean fail = true;
|
||||||
|
int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
|
||||||
|
sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
|
||||||
}
|
}
|
||||||
public void testMoveAppExternalToInternal() {
|
public void testMoveAppExternalToInternal() {
|
||||||
moveFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.MOVE_INTERNAL,
|
int installFlags = PackageManager.INSTALL_EXTERNAL;
|
||||||
PackageManager.MOVE_SUCCEEDED);
|
int moveFlags = PackageManager.MOVE_INTERNAL;
|
||||||
|
boolean fail = false;
|
||||||
|
int result = PackageManager.MOVE_SUCCEEDED;
|
||||||
|
sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
|
||||||
|
}
|
||||||
|
public void testMoveAppForwardLocked() {
|
||||||
|
int installFlags = PackageManager.INSTALL_FORWARD_LOCK;
|
||||||
|
int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
|
||||||
|
boolean fail = true;
|
||||||
|
int result = PackageManager.MOVE_FAILED_FORWARD_LOCKED;
|
||||||
|
sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
|
||||||
|
}
|
||||||
|
public void testMoveAppFailInternalToExternalDelete() {
|
||||||
|
int installFlags = 0;
|
||||||
|
int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
|
||||||
|
boolean fail = true;
|
||||||
|
final int result = PackageManager.MOVE_FAILED_DOESNT_EXIST;
|
||||||
|
|
||||||
|
int rawResId = R.raw.install;
|
||||||
|
int origDefaultLoc = getInstallLoc();
|
||||||
|
InstallParams ip = null;
|
||||||
|
try {
|
||||||
|
PackageManager pm = getPm();
|
||||||
|
setInstallLoc(PackageHelper.APP_INSTALL_AUTO);
|
||||||
|
// Install first
|
||||||
|
ip = installFromRawResource("install.apk", R.raw.install, installFlags, false,
|
||||||
|
false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
|
||||||
|
// Delete the package now retaining data.
|
||||||
|
pm.deletePackage(ip.pkg.packageName, null, PackageManager.DONT_DELETE_DATA);
|
||||||
|
assertTrue(invokeMovePackageFail(ip.pkg.packageName, moveFlags, result));
|
||||||
|
} catch (Exception e) {
|
||||||
|
failStr(e);
|
||||||
|
} finally {
|
||||||
|
if (ip != null) {
|
||||||
|
cleanUpInstall(ip);
|
||||||
|
}
|
||||||
|
// Restore default install location
|
||||||
|
setInstallLoc(origDefaultLoc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test that an install error code is returned when media is unmounted
|
* Test that an install error code is returned when media is unmounted
|
||||||
* and package installed on sdcard via package manager flag.
|
* and package installed on sdcard via package manager flag.
|
||||||
@@ -1799,7 +1884,7 @@ public class PackageManagerTests extends AndroidTestCase {
|
|||||||
rFlags,
|
rFlags,
|
||||||
true,
|
true,
|
||||||
false, -1,
|
false, -1,
|
||||||
PackageInfo.INSTALL_LOCATION_AUTO);
|
PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* The following set of tests check install location for existing
|
* The following set of tests check install location for existing
|
||||||
|
|||||||
@@ -9699,9 +9699,6 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
|
|
||||||
public void movePackage(final String packageName,
|
public void movePackage(final String packageName,
|
||||||
final IPackageMoveObserver observer, final int flags) {
|
final IPackageMoveObserver observer, final int flags) {
|
||||||
if (packageName == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mContext.enforceCallingOrSelfPermission(
|
mContext.enforceCallingOrSelfPermission(
|
||||||
android.Manifest.permission.MOVE_PACKAGE, null);
|
android.Manifest.permission.MOVE_PACKAGE, null);
|
||||||
int returnCode = PackageManager.MOVE_SUCCEEDED;
|
int returnCode = PackageManager.MOVE_SUCCEEDED;
|
||||||
@@ -9711,30 +9708,31 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
PackageParser.Package pkg = mPackages.get(packageName);
|
PackageParser.Package pkg = mPackages.get(packageName);
|
||||||
if (pkg == null) {
|
if (pkg == null) {
|
||||||
returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
|
returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
|
||||||
}
|
|
||||||
// Disable moving fwd locked apps and system packages
|
|
||||||
if (pkg.applicationInfo != null &&
|
|
||||||
(pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
|
||||||
Slog.w(TAG, "Cannot move system application");
|
|
||||||
returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
|
|
||||||
} else if (pkg.applicationInfo != null &&
|
|
||||||
(pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0) {
|
|
||||||
Slog.w(TAG, "Cannot move forward locked app.");
|
|
||||||
returnCode = PackageManager.MOVE_FAILED_FORWARD_LOCKED;
|
|
||||||
} else {
|
} else {
|
||||||
// Find install location first
|
// Disable moving fwd locked apps and system packages
|
||||||
if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 &&
|
if (pkg.applicationInfo != null &&
|
||||||
(flags & PackageManager.MOVE_INTERNAL) != 0) {
|
(pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
||||||
Slog.w(TAG, "Ambigous flags specified for move location.");
|
Slog.w(TAG, "Cannot move system application");
|
||||||
returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
|
returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
|
||||||
|
} else if (pkg.applicationInfo != null &&
|
||||||
|
(pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0) {
|
||||||
|
Slog.w(TAG, "Cannot move forward locked app.");
|
||||||
|
returnCode = PackageManager.MOVE_FAILED_FORWARD_LOCKED;
|
||||||
} else {
|
} else {
|
||||||
newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ?
|
// Find install location first
|
||||||
PackageManager.INSTALL_EXTERNAL : 0;
|
if ((flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 &&
|
||||||
currFlags = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0 ?
|
(flags & PackageManager.MOVE_INTERNAL) != 0) {
|
||||||
PackageManager.INSTALL_EXTERNAL : 0;
|
Slog.w(TAG, "Ambigous flags specified for move location.");
|
||||||
if (newFlags == currFlags) {
|
|
||||||
Slog.w(TAG, "No move required. Trying to move to same location");
|
|
||||||
returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
|
returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
|
||||||
|
} else {
|
||||||
|
newFlags = (flags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0 ?
|
||||||
|
PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
|
||||||
|
currFlags = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0 ?
|
||||||
|
PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL;
|
||||||
|
if (newFlags == currFlags) {
|
||||||
|
Slog.w(TAG, "No move required. Trying to move to same location");
|
||||||
|
returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9758,67 +9756,87 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
public void run() {
|
public void run() {
|
||||||
mHandler.removeCallbacks(this);
|
mHandler.removeCallbacks(this);
|
||||||
int returnCode = currentStatus;
|
int returnCode = currentStatus;
|
||||||
boolean moveSucceeded = (returnCode == PackageManager.MOVE_SUCCEEDED);
|
if (currentStatus == PackageManager.MOVE_SUCCEEDED) {
|
||||||
if (moveSucceeded) {
|
int uidArr[] = null;
|
||||||
int uid = -1;
|
ArrayList<String> pkgList = null;
|
||||||
synchronized (mPackages) {
|
synchronized (mPackages) {
|
||||||
uid = mPackages.get(mp.packageName).applicationInfo.uid;
|
PackageParser.Package pkg = mPackages.get(mp.packageName);
|
||||||
}
|
if (pkg == null ) {
|
||||||
ArrayList<String> pkgList = new ArrayList<String>();
|
Slog.w(TAG, " Package " + mp.packageName +
|
||||||
pkgList.add(mp.packageName);
|
" doesn't exist. Aborting move");
|
||||||
int uidArr[] = new int[] { uid };
|
returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
|
||||||
// Send resources unavailable broadcast
|
} else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) {
|
||||||
sendResourcesChangedBroadcast(false, pkgList, uidArr);
|
Slog.w(TAG, "Package " + mp.packageName + " code path changed from " +
|
||||||
|
mp.srcArgs.getCodePath() + " to " + pkg.applicationInfo.sourceDir +
|
||||||
// Update package code and resource paths
|
" Aborting move and returning error");
|
||||||
synchronized (mInstallLock) {
|
returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
|
||||||
synchronized (mPackages) {
|
} else {
|
||||||
PackageParser.Package pkg = mPackages.get(mp.packageName);
|
uidArr = new int[] { pkg.applicationInfo.uid };
|
||||||
if (pkg != null) {
|
pkgList = new ArrayList<String>();
|
||||||
String oldCodePath = pkg.mPath;
|
pkgList.add(mp.packageName);
|
||||||
String newCodePath = mp.targetArgs.getCodePath();
|
}
|
||||||
String newResPath = mp.targetArgs.getResourcePath();
|
}
|
||||||
pkg.mPath = newCodePath;
|
if (returnCode == PackageManager.MOVE_SUCCEEDED) {
|
||||||
// Move dex files around
|
// Send resources unavailable broadcast
|
||||||
if (moveDexFilesLI(pkg)
|
sendResourcesChangedBroadcast(false, pkgList, uidArr);
|
||||||
!= PackageManager.INSTALL_SUCCEEDED) {
|
// Update package code and resource paths
|
||||||
// Moving of dex files failed. Set
|
synchronized (mInstallLock) {
|
||||||
// error code and abort move.
|
synchronized (mPackages) {
|
||||||
pkg.mPath = pkg.mScanPath;
|
PackageParser.Package pkg = mPackages.get(mp.packageName);
|
||||||
returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
|
// Recheck for package again.
|
||||||
moveSucceeded = false;
|
if (pkg == null ) {
|
||||||
} else {
|
Slog.w(TAG, " Package " + mp.packageName +
|
||||||
pkg.mScanPath = newCodePath;
|
" doesn't exist. Aborting move");
|
||||||
pkg.applicationInfo.sourceDir = newCodePath;
|
returnCode = PackageManager.MOVE_FAILED_DOESNT_EXIST;
|
||||||
pkg.applicationInfo.publicSourceDir = newResPath;
|
} else if (!mp.srcArgs.getCodePath().equals(pkg.applicationInfo.sourceDir)) {
|
||||||
PackageSetting ps = (PackageSetting) pkg.mExtras;
|
Slog.w(TAG, "Package " + mp.packageName + " code path changed from " +
|
||||||
ps.codePath = new File(pkg.applicationInfo.sourceDir);
|
mp.srcArgs.getCodePath() + " to " + pkg.applicationInfo.sourceDir +
|
||||||
ps.codePathString = ps.codePath.getPath();
|
" Aborting move and returning error");
|
||||||
ps.resourcePath = new File(pkg.applicationInfo.publicSourceDir);
|
returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
|
||||||
ps.resourcePathString = ps.resourcePath.getPath();
|
} else {
|
||||||
// Set the application info flag correctly.
|
String oldCodePath = pkg.mPath;
|
||||||
if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
|
String newCodePath = mp.targetArgs.getCodePath();
|
||||||
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
|
String newResPath = mp.targetArgs.getResourcePath();
|
||||||
} else {
|
pkg.mPath = newCodePath;
|
||||||
pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
|
// Move dex files around
|
||||||
}
|
if (moveDexFilesLI(pkg)
|
||||||
ps.setFlags(pkg.applicationInfo.flags);
|
!= PackageManager.INSTALL_SUCCEEDED) {
|
||||||
mAppDirs.remove(oldCodePath);
|
// Moving of dex files failed. Set
|
||||||
mAppDirs.put(newCodePath, pkg);
|
// error code and abort move.
|
||||||
// Persist settings
|
pkg.mPath = pkg.mScanPath;
|
||||||
mSettings.writeLP();
|
returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
|
||||||
}
|
} else {
|
||||||
}
|
pkg.mScanPath = newCodePath;
|
||||||
|
pkg.applicationInfo.sourceDir = newCodePath;
|
||||||
|
pkg.applicationInfo.publicSourceDir = newResPath;
|
||||||
|
PackageSetting ps = (PackageSetting) pkg.mExtras;
|
||||||
|
ps.codePath = new File(pkg.applicationInfo.sourceDir);
|
||||||
|
ps.codePathString = ps.codePath.getPath();
|
||||||
|
ps.resourcePath = new File(pkg.applicationInfo.publicSourceDir);
|
||||||
|
ps.resourcePathString = ps.resourcePath.getPath();
|
||||||
|
// Set the application info flag correctly.
|
||||||
|
if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
|
||||||
|
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
|
||||||
|
} else {
|
||||||
|
pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
|
||||||
|
}
|
||||||
|
ps.setFlags(pkg.applicationInfo.flags);
|
||||||
|
mAppDirs.remove(oldCodePath);
|
||||||
|
mAppDirs.put(newCodePath, pkg);
|
||||||
|
// Persist settings
|
||||||
|
mSettings.writeLP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Send resources available broadcast
|
||||||
|
sendResourcesChangedBroadcast(true, pkgList, uidArr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Send resources available broadcast
|
|
||||||
sendResourcesChangedBroadcast(true, pkgList, uidArr);
|
|
||||||
}
|
}
|
||||||
if (!moveSucceeded){
|
if (returnCode != PackageManager.MOVE_SUCCEEDED){
|
||||||
// Clean up failed installation
|
// Clean up failed installation
|
||||||
if (mp.targetArgs != null) {
|
if (mp.targetArgs != null) {
|
||||||
mp.targetArgs.doPostInstall(
|
mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR);
|
||||||
returnCode);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Force a gc to clear things up.
|
// Force a gc to clear things up.
|
||||||
@@ -9840,3 +9858,4 @@ class PackageManagerService extends IPackageManager.Stub {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user