Install APK on SD card and TF card

Source: Internet
Author: User
1. Introduction

To install the application on the SD card and TF card, the android system does not support it by default. It has only one ASEC mount point:/mnt/secure/ASEC. In my system, this mount point is occupied by/mnt/sdcard, so the TF card is not supported. To solve this problem, there is no other way except to read and understand the code. To facilitate understanding of the following description, Let's first look at the vold (managing peripherals hot swapping) system framework:

For the related class diagram, refer to the diagram of other friends:


2. Procedures for installing applications from a USB flash drive

Packageinstalleractivity. Java: initiateinstall->
: Startinstallconfirm->

Installappprogress: oncreate->
Installappprogress: initview->

Packagemanager: installpackage->

Packagemanagerservice: installpackage->
Installpackagewithverification->
Mhandler. sendmessage (MSG)->

Packagehandler: handlemessage->
Packagehandler: dohandlemessage->
Handlerparams: startcopy->
Installparams: handlestartcopy-> (confirm the installation location based on installlocation. Only the lowthreshold is available for/Data partitions)
Sdinstallargs: copyapk-> (the key points are described below)
Installparams: handlereturncode->
Packagemanagerservice: processpendinginstall->
Packagemanagerservice: installpackageli-> // ARGs, Res Analysis
Packagemanagerservice: installnewpackageli-> // or replacepackageli
Packagemanagerservice: scanpackageli-> (key)-> parsepackage (parsing androidmanifest. XML)
Installer: Install (minstaller. Install)-> (socket) --->
Installd)

2.1 sdinstallargs: copyapk

Sdinstallargs: copyapk->
Defaultcontainerservice: copyresourceinner->
Packagehelper: createsddir->
Mountservice: createsecurecontainer->

(Cmd = string. Format (New locale ("en", "us "),

"ASEC create % S % d", ID, sizemb, fstype, key, owneruid );)
Nativedaemonconnector: docommandlocked-> (send a command to vold socket and wait for the result)
Nativedaemonconnector: sendcommandlocked-> (socket)

Frameworklistener: ondataavailable-> (receive message) "buffer = ASEC list"
Or "buffer = ASEC create smdl2tmp1 19 fat caf791d0108d682e5b2aafc5439d55a9 10023"
Frameworklistener: dispatchcommand->
Commandlistener: aseccmd: runcommand-> (all Code related to volume: sec_asecdir must be modified)
Volumemanager: createasec (determines the Installation File Path volume: sec_asecdir)

2.2 complex Mount relationships

For detailed code, see volume. cpp ::

The Code does not mount sdcard & udisk to ASEC by default. Therefore, you need to mount the SD card or TF card to the ASEC mount point. Of course, the system only has one/mnt/secure/ASEC by default, you can. create/mnt/secure/asecsd or/mnt/secure/asectf in RC and run mount.

•/Mnt/Secure: the mount point under is the mount point of the physical peripherals

•/Mnt/ASEC: A shared public mount point. It is a mount point of the tmpfs file system. Applications installed on SD or tF can be mounted to the mount point in this directory.

The complex Mount relationship is as follows:

1)/dev/block/vold/31: 9 mount to/mnt/secure/staging
2)/mnt/secure/staging/. android_secure mount to/mnt/secure/ASEC (ms_bind)
3) tmpfs mount to/mnt/secure/staging/. android_secure (read-only 0-byte tmpfs, hide it, obscuring the ASEC image directory from non root users)
4) Move the subdirectory (. android_secure) under/mnt/secure/staging to/mnt/sdcard

Note:Ms_bind: Run BIND mounting to make the file or subdirectory tree visible on another point in the file system.

Only the root user can view files under/mnt/secure/ASEC. Of course, the TF card can be viewed on widows. under the android_secure directory. ASEC file.

2.3 install the APK on the SD card or TF card

When you install the APK on the SD card or TF card, you will leave it in the following places:

1)/mnt/secure/ASEC: (The. ASEC file generated after installation, which is the real content)
-Rwxrwxr-x system sdcard_rw 20257280 2013-04-07 06:14 com. myarrow. test-1.asec

2)/mnt/ASEC/COM. myarrow. Test-1: (it is mounted. It is a tmpfs and does not really occupy flash space)
Dr-XR-x system root 2013-04-07 06:14 lib
-R-XR-x system root 4973096 pkg.apk

3)/data/COM. myarrow. Test: (it is just a link and does not really occupy flash space)
Lrwxrwxrwx system 2013-04-09 06:51 Lib->/mnt/ASEC/COM. myarrow. Test-1/lib

4)/data/Dalvik-Cache: (contains the DEX file in the APK package, which occupies the flash space of the Data Partition, so the data partition must be reserved)
-RW-r -- System app_58 36608 mnt@asec@com.myarrow.test-1@pkg.apk @ classes. Dex

3. Main files to be modified

1) volume. cpp

Modify mountvol/unmountvol and run bindmount on the SD or TF card.

2) defaultcontainerservice. Java

Modify isunderexternalthreshold. When there is insufficient space, check whether there is sufficient space on the SD or TF card.

3) volumemanager. cpp

Extended the location related to volume: sec_asecdir, because we added a volume: sec_sd_asecdir

4. Mount and unmoun ASEC t Processes

1) Mount:

Mountservice. Java (policyvolumestatechange/onevent)->
Mountservice. jvav (updatepublicvolumestate)->
Packagemanagerservice. Java (updateexternalmediastatus)->
(Updateexternalmediastatusinner)->
(Loadmediapackages)->
Sdinstallargs. dopreinstall->
Packagehelper. Java (mountsddir)->
Mountservice. Java (mountsecurecontainer)->
Commandlistener. cpp (commandlistener: aseccmd: runcommand)

 

2) unmount:
Mountservice. Java (policyvolumestatechange/onevent)->
Mountservice. jvav (updatepublicvolumestate)->
Packagemanagerservice. Java (updateexternalmediastatus)->
(Updateexternalmediastatusinner)->
(Unloadmediapackages)-> (send updated_media_status)
Packagehandler. dohandlemessage (get updated_media_status)->
Unloadallcontainers->
(Sdinstallargs. dopostdeleteli)->

Packagehelper. Java (unmountsddir)->
Mountservice. Java (unmountsecurecontainer)->
Commandlistener. cpp (commandlistener: aseccmd: runcommand)

5. copyresourceinner

The detailed code is as follows:

    private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName) {        // Make sure the sdcard is mounted.        String status = Environment.getExternalStorageState();        if (!status.equals(Environment.MEDIA_MOUNTED)) {            Slog.w(TAG, "Make sure sdcard is mounted.");            return null;        }        // The .apk file        String codePath = packageURI.getPath();        File codeFile = new File(codePath);        // Calculate size of container needed to hold base APK.        int sizeMb;        try {            sizeMb = calculateContainerSize(codeFile);        } catch (FileNotFoundException e) {            Slog.w(TAG, "File does not exist when trying to copy " + codeFile.getPath());            return null;        }        // Create new container        final String newCachePath;        if ((newCachePath = PackageHelper.createSdDir(sizeMb, newCid, key, Process.myUid())) == null) {            Slog.e(TAG, "Failed to create container " + newCid);            return null;        }        /*if (localLOGV)*/ {            Slog.i(TAG, "Created container for " + newCid + " at path : " + newCachePath);        }        final File resFile = new File(newCachePath, resFileName);        if (FileUtils.copyFile(new File(codePath), resFile)) {            /*if (localLOGV)*/ {                Slog.i(TAG, "Copied " + codePath + " to " + resFile);            }        } else {            Slog.e(TAG, "Failed to copy " + codePath + " to " + resFile);            // Clean up container            PackageHelper.destroySdDir(newCid);            return null;        }        final File sharedLibraryDir = new File(newCachePath, LIB_DIR_NAME);        if (sharedLibraryDir.mkdir()) {            int ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(codeFile, sharedLibraryDir);            if (ret != PackageManager.INSTALL_SUCCEEDED) {                Slog.e(TAG, "Could not copy native libraries to " + sharedLibraryDir.getPath());                PackageHelper.destroySdDir(newCid);                return null;            }        } else {            Slog.e(TAG, "Could not create native lib directory: " + sharedLibraryDir.getPath());            PackageHelper.destroySdDir(newCid);            return null;        }        if (!PackageHelper.finalizeSdDir(newCid)) {            Slog.e(TAG, "Failed to finalize " + newCid + " at path " + newCachePath);            // Clean up container            PackageHelper.destroySdDir(newCid);            return null;        }        if (localLOGV) {            Slog.i(TAG, "Finalized container " + newCid);        }        if (PackageHelper.isContainerMounted(newCid)) {            if (localLOGV) {                Slog.i(TAG, "Unmounting " + newCid + " at path " + newCachePath);            }            // Force a gc to avoid being killed.            Runtime.getRuntime().gc();            PackageHelper.unMountSdDir(newCid);        } else {            if (localLOGV) {                Slog.i(TAG, "Container " + newCid + " not mounted");            }        }        return newCachePath;    }

Its main functions are as follows:

1) create a. ASEC File

2) Copy APK

3) Copy lib

4) Final. ASEC File

The detailed log information is as follows:

D/VoldVolumeManager(   85):  createAsec(367) call createImageFile   E/Vold    (   85): createImageFile(236) call creat                  E/Vold    (   85): createImageFile(241) call ftruncate              E/Vold    (   85): createImageFile(247) END                         D/VoldVolumeManager(   85): createAsec(374) call asecHash           D/VoldVolumeManager(   85): createAsec(383) call Loop::create       D/VoldVolumeManager(   85): createAsec(397) call Devmapper::create  D/VoldVolumeManager(   85): createAsec(414) call open               D/VoldVolumeManager(   85): createAsec(436) write sb                D/VoldVolumeManager(   85): createAsec(453) Fat::format             D/VoldVolumeManager(   85): createAsec(477) Fat::doMount            D/VoldVolumeManager(   85): createAsec(491) End                                                                                         ****copy apk and lib*****                                                                                                               D/VoldVolumeManager(   85): finalizeAsec(502) start                 D/VoldVolumeManager(   85): finalizeAsec(520) End                   D/VoldVolumeManager(   85): renameAsec:538 Volume::SEC_ASECDIR startD/VoldVolumeManager(   85): renameAsec:538 Volume::SEC_ASECDIR start

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.