title: Install APK using root, handling new limitations of "/data/local/tmp/" folder
body: <h2>Background</h2>
  
  <p>So far, I was able to install APK files using root (within the app), via this code:</p>
  
  <pre><code>pm install -t -f fullPathToApkFile
  </code></pre>
  
  <p>and if I want to (try to) install to sd-card :</p>
  
  <pre><code>pm install -t -s fullPathToApkFile
  </code></pre>
  
  <h2>The problem</h2>
  
  <p>Recently, not sure from which Android version (issue exists on Android P beta, at least), the above method fails, showing me this message:</p>
  
  <pre><code>avc:  denied  { read } for  scontext=u:r:system_server:s0 tcontext=u:object_r:sdcardfs:s0 tclass=file permissive=0
  System server has no access to read file context u:object_r:sdcardfs:s0 (from path /storage/emulated/0/Download/FDroid.apk, context u:r:system_server:s0)
  Error: Unable to open file: /storage/emulated/0/Download/FDroid.apk
  Consider using a file under /data/local/tmp/
  Error: Can't open file: /storage/emulated/0/Download/FDroid.apk
  Exception occurred while executing:
  java.lang.IllegalArgumentException: Error: Can't open file: /storage/emulated/0/Download/FDroid.apk
      at com.android.server.pm.PackageManagerShellCommand.setParamsSize(PackageManagerShellCommand.java:306)
      at com.android.server.pm.PackageManagerShellCommand.runInstall(PackageManagerShellCommand.java:884)
      at com.android.server.pm.PackageManagerShellCommand.onCommand(PackageManagerShellCommand.java:138)
      at android.os.ShellCommand.exec(ShellCommand.java:103)
      at com.android.server.pm.PackageManagerService.onShellCommand(PackageManagerService.java:21125)
      at android.os.Binder.shellCommand(Binder.java:634)
      at android.os.Binder.onTransact(Binder.java:532)
      at android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:2806)
      at com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:3841)
      at android.os.Binder.execTransact(Binder.java:731)
  </code></pre>
  
  <p>This seems to also affect popular apps such as "<a href="https://play.google.com/store/apps/details?id=com.keramidas.TitaniumBackup&amp;hl=en" rel="noreferrer"><strong>Titanium backup</strong></a> (pro)", which fails to restore apps.</p>
  
  <h2>What I've tried</h2>
  
  <p>Looking at what's written, it appears it lacks permission to install APK files that are not in <code>/data/local/tmp/</code>.</p>
  
  <p>So I tried the next things, to see if I can overcome it:</p>
  
  <ol>
  <li>set the access to the file (<code>chmod 777</code>) - didn't help.</li>
  <li>grant permissions to my app, of both storage and <a href="https://developer.android.com/reference/android/Manifest.permission.html#REQUEST_INSTALL_PACKAGES" rel="noreferrer"><strong>REQUEST_INSTALL_PACKAGES</strong></a> (using <a href="https://developer.android.com/reference/android/provider/Settings#ACTION_MANAGE_UNKNOWN_APP_SOURCES" rel="noreferrer"><strong>ACTION_MANAGE_UNKNOWN_APP_SOURCES</strong></a> Intent) - didn't help.</li>
  <li><p>create a symlink to the file, so that it will be inside the <code>/data/local/tmp/</code>, using official API:</p>
  
  <pre><code> Os.symlink(fullPathToApkFile, symLinkFilePath)
  </code></pre>
  
  <p>This didn't do anything.</p></li>
  <li><p>create a symlink using this :</p>
  
  <pre><code> ln -sf $fullPathToApkFile $symLinkFilePath
  </code></pre>
  
  <p>This partially worked. The file is there, as I can see it in Total Commander app, but when I try to check if it exists there, and when I try to install the APK from there, it fails.  </p></li>
  <li><p>Copy/move (using <code>cp</code> or <code>mv</code>) the file to the <code>/data/local/tmp/</code> path, and then install from there. This worked, but it has disadvantages: moving is risky because it temporarily hides the original file, and it changes the timestamp of the original file. Copying is bad because of using extra space just for installing (even temporarily) and because it wastes time in doing so.</p></li>
  <li><p>Copy the APK file, telling it to avoid actual copy (meaning hard link), using this command (taken from <a href="https://superuser.com/a/220216/152400"><strong>here</strong></a>) :</p>
  
  <pre><code> cp -p -r -l $fullPathToApkFile $tempFileParentPath"
  </code></pre>
  
  <p>This didn't work. It got me this error:</p>
  
  <pre><code> cp: /data/local/tmp/test.apk: Cross-device link
  </code></pre></li>
  <li><p>Checking what happens in other cases of installing apps. When you install via  via the IDE, it actually does create the APK file in this special path, but if you install via the Play Store, simple APK install (via Intent) or adb (via PC), it doesn't.</p></li>
  <li><p>Wrote about this here too: <a href="https://issuetracker.google.com/issues/80270303" rel="noreferrer">https://issuetracker.google.com/issues/80270303</a></p></li>
  </ol>
  
  <h2>The questions</h2>
  
  <ol>
  <li><p>Is there any way to overcome the disadvantages of installing the APK using root on this special path? Maybe even avoid handling this path at all?</p></li>
  <li><p>Why does the OS suddenly require to use this path? Why not use the original path instead, just like in the other methods of installing apps? What do the other methods of installing apps do, that somehow avoids using the spacial path?</p></li>
  </ol>