@@ -5863,9 +5863,28 @@ public void handleStartCopy() throws RemoteException {
58635863 Log .w (TAG , "Insufficient storage to install" );
58645864 return ;
58655865 }
5866- // Create the file args now.
5866+
5867+ mRet = srcArgs .doPreCopy ();
5868+ if (mRet != PackageManager .INSTALL_SUCCEEDED ) {
5869+ return ;
5870+ }
5871+
58675872 mRet = targetArgs .copyApk (mContainerService , false );
5868- targetArgs .doPreInstall (mRet );
5873+ if (mRet != PackageManager .INSTALL_SUCCEEDED ) {
5874+ srcArgs .doPostCopy (uid );
5875+ return ;
5876+ }
5877+
5878+ mRet = srcArgs .doPostCopy (uid );
5879+ if (mRet != PackageManager .INSTALL_SUCCEEDED ) {
5880+ return ;
5881+ }
5882+
5883+ mRet = targetArgs .doPreInstall (mRet );
5884+ if (mRet != PackageManager .INSTALL_SUCCEEDED ) {
5885+ return ;
5886+ }
5887+
58695888 if (DEBUG_SD_INSTALL ) {
58705889 StringBuilder builder = new StringBuilder ();
58715890 if (srcArgs != null ) {
@@ -5936,7 +5955,7 @@ private InstallArgs createInstallArgs(int flags, String fullCodePath, String ful
59365955 String nativeLibraryPath ) {
59375956 if (installOnSd (flags ) || installForwardLocked (flags )) {
59385957 return new AsecInstallArgs (fullCodePath , fullResourcePath , nativeLibraryPath ,
5939- (flags & PackageManager . INSTALL_EXTERNAL ) != 0 );
5958+ installOnSd (flags ), installForwardLocked ( flags ) );
59405959 } else {
59415960 return new FileInstallArgs (fullCodePath , fullResourcePath , nativeLibraryPath );
59425961 }
@@ -5945,9 +5964,10 @@ private InstallArgs createInstallArgs(int flags, String fullCodePath, String ful
59455964 // Used by package mover
59465965 private InstallArgs createInstallArgs (Uri packageURI , int flags , String pkgName , String dataDir ) {
59475966 if (installOnSd (flags ) || installForwardLocked (flags )) {
5948- String cid = getNextCodePath (null , pkgName , "/" + AsecInstallArgs .RES_FILE_NAME );
5949- return new AsecInstallArgs (packageURI , cid ,
5950- (flags & PackageManager .INSTALL_EXTERNAL ) != 0 );
5967+ String cid = getNextCodePath (packageURI .getPath (), pkgName , "/"
5968+ + AsecInstallArgs .RES_FILE_NAME );
5969+ return new AsecInstallArgs (packageURI , cid , installOnSd (flags ),
5970+ installForwardLocked (flags ));
59515971 } else {
59525972 return new FileInstallArgs (packageURI , pkgName , dataDir );
59535973 }
@@ -5984,6 +6004,26 @@ static abstract class InstallArgs {
59846004 abstract boolean doPostDeleteLI (boolean delete );
59856005 abstract boolean checkFreeStorage (IMediaContainerService imcs ) throws RemoteException ;
59866006
6007+ /**
6008+ * Called before the source arguments are copied. This is used mostly
6009+ * for MoveParams when it needs to read the source file to put it in the
6010+ * destination.
6011+ */
6012+ int doPreCopy () {
6013+ return PackageManager .INSTALL_SUCCEEDED ;
6014+ }
6015+
6016+ /**
6017+ * Called after the source arguments are copied. This is used mostly for
6018+ * MoveParams when it needs to read the source file to put it in the
6019+ * destination.
6020+ *
6021+ * @return
6022+ */
6023+ int doPostCopy (int uid ) {
6024+ return PackageManager .INSTALL_SUCCEEDED ;
6025+ }
6026+
59876027 protected boolean isFwdLocked () {
59886028 return (flags & PackageManager .INSTALL_FORWARD_LOCK ) != 0 ;
59896029 }
@@ -6280,8 +6320,9 @@ class AsecInstallArgs extends InstallArgs {
62806320 }
62816321
62826322 AsecInstallArgs (String fullCodePath , String fullResourcePath , String nativeLibraryPath ,
6283- boolean isExternal ) {
6284- super (null , null , isExternal ? PackageManager .INSTALL_EXTERNAL : 0 , null , null );
6323+ boolean isExternal , boolean isForwardLocked ) {
6324+ super (null , null , (isExternal ? PackageManager .INSTALL_EXTERNAL : 0 )
6325+ | (isForwardLocked ? PackageManager .INSTALL_FORWARD_LOCK : 0 ), null , null );
62856326 // Extract cid from fullCodePath
62866327 int eidx = fullCodePath .lastIndexOf ("/" );
62876328 String subStr1 = fullCodePath .substring (0 , eidx );
@@ -6296,8 +6337,9 @@ class AsecInstallArgs extends InstallArgs {
62966337 setCachePath (PackageHelper .getSdDir (cid ));
62976338 }
62986339
6299- AsecInstallArgs (Uri packageURI , String cid , boolean isExternal ) {
6300- super (packageURI , null , isExternal ? PackageManager .INSTALL_EXTERNAL : 0 , null , null );
6340+ AsecInstallArgs (Uri packageURI , String cid , boolean isExternal , boolean isForwardLocked ) {
6341+ super (packageURI , null , (isExternal ? PackageManager .INSTALL_EXTERNAL : 0 )
6342+ | (isForwardLocked ? PackageManager .INSTALL_FORWARD_LOCK : 0 ), null , null );
63016343 this .cid = cid ;
63026344 }
63036345
@@ -6443,8 +6485,18 @@ int doPostInstall(int status, int uid) {
64436485 if (status != PackageManager .INSTALL_SUCCEEDED ) {
64446486 cleanUp ();
64456487 } else {
6488+ final int groupOwner ;
6489+ final String protectedFile ;
6490+ if (isFwdLocked ()) {
6491+ groupOwner = uid ;
6492+ protectedFile = RES_FILE_NAME ;
6493+ } else {
6494+ groupOwner = -1 ;
6495+ protectedFile = null ;
6496+ }
6497+
64466498 if (uid < Process .FIRST_APPLICATION_UID
6447- || !PackageHelper .fixSdPermissions (cid , uid , RES_FILE_NAME )) {
6499+ || !PackageHelper .fixSdPermissions (cid , groupOwner , protectedFile )) {
64486500 Slog .e (TAG , "Failed to finalize " + cid );
64496501 PackageHelper .destroySdDir (cid );
64506502 return PackageManager .INSTALL_FAILED_CONTAINER_ERROR ;
@@ -6505,6 +6557,33 @@ boolean doPostDeleteLI(boolean delete) {
65056557 }
65066558 return ret ;
65076559 }
6560+
6561+ @ Override
6562+ int doPreCopy () {
6563+ if (isFwdLocked ()) {
6564+ if (!PackageHelper .fixSdPermissions (cid ,
6565+ getPackageUid (DEFAULT_CONTAINER_PACKAGE , 0 ), RES_FILE_NAME )) {
6566+ return PackageManager .INSTALL_FAILED_CONTAINER_ERROR ;
6567+ }
6568+ }
6569+
6570+ return PackageManager .INSTALL_SUCCEEDED ;
6571+ }
6572+
6573+ @ Override
6574+ int doPostCopy (int uid ) {
6575+ if (isFwdLocked ()) {
6576+ PackageHelper .fixSdPermissions (cid , uid , RES_FILE_NAME );
6577+ if (uid < Process .FIRST_APPLICATION_UID
6578+ || !PackageHelper .fixSdPermissions (cid , uid , RES_FILE_NAME )) {
6579+ Slog .e (TAG , "Failed to finalize " + cid );
6580+ PackageHelper .destroySdDir (cid );
6581+ return PackageManager .INSTALL_FAILED_CONTAINER_ERROR ;
6582+ }
6583+ }
6584+
6585+ return PackageManager .INSTALL_SUCCEEDED ;
6586+ }
65086587 };
65096588
65106589 // Utility method used to create code paths based on package name and available index.
@@ -8696,9 +8775,15 @@ public void movePackage(final String packageName, final IPackageMoveObserver obs
86968775 : PackageManager .INSTALL_INTERNAL ;
86978776 currFlags = isExternal (pkg ) ? PackageManager .INSTALL_EXTERNAL
86988777 : PackageManager .INSTALL_INTERNAL ;
8778+
86998779 if (newFlags == currFlags ) {
87008780 Slog .w (TAG , "No move required. Trying to move to same location" );
87018781 returnCode = PackageManager .MOVE_FAILED_INVALID_LOCATION ;
8782+ } else {
8783+ if (isForwardLocked (pkg )) {
8784+ currFlags |= PackageManager .INSTALL_FORWARD_LOCK ;
8785+ newFlags |= PackageManager .INSTALL_FORWARD_LOCK ;
8786+ }
87028787 }
87038788 }
87048789 if (returnCode == PackageManager .MOVE_SUCCEEDED ) {
@@ -8784,21 +8869,31 @@ public void run() {
87848869 final String newNativePath = mp .targetArgs
87858870 .getNativeLibraryPath ();
87868871
8787- if ((mp .flags & PackageManager .INSTALL_EXTERNAL ) == 0 ) {
8788- if (mInstaller
8789- .unlinkNativeLibraryDirectory (pkg .applicationInfo .dataDir ) < 0 ) {
8790- returnCode = PackageManager .MOVE_FAILED_INSUFFICIENT_STORAGE ;
8872+ try {
8873+ final File newNativeDir = new File (newNativePath );
8874+
8875+ final String libParentDir = newNativeDir .getParentFile ()
8876+ .getCanonicalPath ();
8877+ if (newNativeDir .getParentFile ().getCanonicalPath ()
8878+ .equals (pkg .applicationInfo .dataDir )) {
8879+ if (mInstaller
8880+ .unlinkNativeLibraryDirectory (pkg .applicationInfo .dataDir ) < 0 ) {
8881+ returnCode = PackageManager .MOVE_FAILED_INSUFFICIENT_STORAGE ;
8882+ } else {
8883+ NativeLibraryHelper .copyNativeBinariesIfNeededLI (
8884+ new File (newCodePath ), newNativeDir );
8885+ }
87918886 } else {
8792- NativeLibraryHelper .copyNativeBinariesIfNeededLI (new File (
8793- newCodePath ), new File (newNativePath ));
8794- }
8795- } else {
8796- if (mInstaller .linkNativeLibraryDirectory (
8797- pkg .applicationInfo .dataDir , newNativePath ) < 0 ) {
8798- returnCode = PackageManager .MOVE_FAILED_INSUFFICIENT_STORAGE ;
8887+ if (mInstaller .linkNativeLibraryDirectory (
8888+ pkg .applicationInfo .dataDir , newNativePath ) < 0 ) {
8889+ returnCode = PackageManager .MOVE_FAILED_INSUFFICIENT_STORAGE ;
8890+ }
87998891 }
8892+ } catch (IOException e ) {
8893+ returnCode = PackageManager .MOVE_FAILED_INVALID_LOCATION ;
88008894 }
88018895
8896+
88028897 if (returnCode == PackageManager .MOVE_SUCCEEDED ) {
88038898 pkg .mPath = newCodePath ;
88048899 // Move dex files around
0 commit comments