Skip to content

Commit

Permalink
SubstratumService: Rewrite installation method for Pie InstallSession…
Browse files Browse the repository at this point in the history
… API

Change-Id: I378da3e891e02933cff24ec289b73b06de840942
Signed-off-by: Harsh Shandilya <harsh@prjkt.io>
Signed-off-by: VenkatVishalV <venkatvishal124@gmail.com>
  • Loading branch information
ivaniskandar authored and VenkatVishalV committed Nov 10, 2018
1 parent 0985d21 commit 1e5a056
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ oneway interface ISubstratumHelperService {
void applyBootAnimation();
void applyShutdownAnimation();
void applyProfile(in String name);
void installOverlay(in List<String> paths);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@

import android.app.Service;
import android.content.Intent;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
import android.content.IntentSender;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.Session;
import android.content.pm.PackageInstaller.SessionParams;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
import android.os.FileUtils;
import android.os.IBinder;
Expand All @@ -28,6 +35,14 @@
import com.android.internal.substratum.ISubstratumHelperService;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

public class SubstratumHelperService extends Service {
private static final String TAG = "SubstratumHelperService";
Expand Down Expand Up @@ -108,6 +123,51 @@ public void applyProfile(String name) {
}
}

@Override
public void installOverlay(List<String> paths) {
if (!isAuthorized(Binder.getCallingUid())) return;
LocalIntentReceiver receiver = new LocalIntentReceiver();
for (String path : paths) {
//Settings.Global.putInt(mContext.getContentResolver(),
// Settings.Global.PACKAGE_VERIFIER_ENABLE, 0);
File apkFile = new File(path);
try {
//PackageParser.PackageLite pkg = PackageParser.parsePackageLite(apkFile, 0);
PackageInstaller installer = getPackageManager().getPackageInstaller();
SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
int sessionId = installer.createSession(params);
try (PackageInstaller.Session session = installer.openSession(sessionId)) {
try (InputStream in = new FileInputStream(apkFile);
OutputStream apkStream = session.openWrite(
"base.apk", 0, apkFile.length())) {
byte[] buffer = new byte[32 * 1024];
long size = apkFile.length();
while (size > 0) {
long toRead = (buffer.length < size) ? buffer.length : size;
int didRead = in.read(buffer, 0, (int) toRead);
apkStream.write(buffer, 0, didRead);
size -= didRead;
}
}
session.commit(receiver.getIntentSender());
}
} catch (IOException e) {
Log.e(TAG, "Install failed", e);
continue;
}

Intent result = receiver.getResult();
int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
PackageInstaller.STATUS_FAILURE);
if (status == PackageInstaller.STATUS_SUCCESS) {
String installedPackageName = result.getStringExtra(
PackageInstaller.EXTRA_PACKAGE_NAME);
} else {
// ¯\_(ツ)_/¯
}
}
}

private boolean isAuthorized(int uid) {
return Process.SYSTEM_UID == uid;
}
Expand Down Expand Up @@ -137,4 +197,32 @@ private boolean copyDir(File src, File dst) {
public IBinder onBind(Intent intent) {
return mISubstratumHelperService.asBinder();
}

private static class LocalIntentReceiver {
private final SynchronousQueue<Intent> mResult = new SynchronousQueue<>();

private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
@Override
public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
try {
mResult.offer(intent, 5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};

public IntentSender getIntentSender() {
return new IntentSender((IIntentSender) mLocalSender);
}

public Intent getResult() {
try {
return mResult.take();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public final class SubstratumService extends SystemService {

private static final String TAG = "SubstratumService";
private static final String SUBSTRATUM_PACKAGE = "projekt.substratum";
private static final boolean DEBUG = false;
private static final boolean DEBUG = true;

private static final Signature SUBSTRATUM_SIGNATURE = new Signature(""
+ "308202eb308201d3a003020102020411c02f2f300d06092a864886f70d01010b050030263124302206"
Expand Down Expand Up @@ -214,7 +214,15 @@ private void waitForHelperConnection() {
Intent intent = new Intent("projekt.substratum.helper.SubstratumHelperService");
intent.setPackage("projekt.substratum.helper");
mContext.bindServiceAsUser(intent, mHelperConnection,
Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT_BACKGROUND, UserHandle.SYSTEM);
int retryCount = 1;
while (mHelperService == null && retryCount <= 30) {
try {
Thread.sleep(100);
} catch (InterruptedException ignored) {
}
retryCount++;
}
}
}

Expand Down Expand Up @@ -266,72 +274,14 @@ private void checkCallerAuthorization(int uid) {
public void installOverlay(List<String> paths) {
checkCallerAuthorization(Binder.getCallingUid());
final long ident = Binder.clearCallingIdentity();
final int packageVerifierEnable = Settings.Global.getInt(
mContext.getContentResolver(),
Settings.Global.PACKAGE_VERIFIER_ENABLE, 1);
try {
synchronized (mLock) {
PackageInstallObserver installObserver = new PackageInstallObserver();
PackageDeleteObserver deleteObserver = new PackageDeleteObserver();
for (String path : paths) {
mInstalledPackageName = null;
log("Installer - installing package from path \'" + path + "\'");
mIsWaiting = true;
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.PACKAGE_VERIFIER_ENABLE, 0);
try {
mPm.installExistingPackageAsUser(
mInstalledPackageName,
UserHandle.USER_SYSTEM,
PackageManager.INSTALL_REPLACE_EXISTING,
PackageManager.INSTALL_REASON_UNKNOWN);

while (mIsWaiting) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// Someone interrupted my sleep, ugh!
}
}
} catch (RemoteException e) {
logE("There is an exception when trying to install " + path, e);
continue;
}

if (mInstalledPackageName != null) {
try {
PackageInfo pi = mPm.getPackageInfo(mInstalledPackageName,
0, UserHandle.USER_SYSTEM);
if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0 ||
pi.overlayTarget == null) {
mIsWaiting = true;
int versionCode = mPm.getPackageInfo(
mInstalledPackageName, 0, UserHandle.USER_SYSTEM)
.versionCode;
mPm.deletePackageAsUser(
mInstalledPackageName,
versionCode,
deleteObserver,
0,
UserHandle.USER_SYSTEM);

while (mIsWaiting) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// Someone interrupted my sleep, ugh!
}
}
}
} catch (RemoteException e) {
// Probably won't happen but we need to keep quiet here
}
}
}
waitForHelperConnection();
mHelperService.installOverlay(paths);
}
} catch (RemoteException ignored) {
// ¯\_(ツ)_/¯
} finally {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.PACKAGE_VERIFIER_ENABLE, packageVerifierEnable);
Binder.restoreCallingIdentity(ident);
}
}
Expand Down Expand Up @@ -1085,7 +1035,7 @@ private void logE(String msg) {
private void updateSettings() {
synchronized (mLock) {
mSigOverride = Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.FORCE_AUTHORIZE_SUBSTRATUM_PACKAGES, 0,
Settings.Secure.FORCE_AUTHORIZE_SUBSTRATUM_PACKAGES, 1,
UserHandle.USER_CURRENT) == 1;
}
}
Expand Down

0 comments on commit 1e5a056

Please sign in to comment.