Skip to content

Commit

Permalink
[Refactor] Migrate to Parcel#obtain(IBinder) with compatibility
Browse files Browse the repository at this point in the history
Signed-off-by: Muntashir Al-Islam <[email protected]>
  • Loading branch information
MuntashirAkon committed Apr 24, 2024
1 parent 71c6898 commit 1a8928c
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import io.github.muntashirakon.AppManager.ipc.ps.ProcessEntry;
import io.github.muntashirakon.AppManager.ipc.ps.Ps;
import io.github.muntashirakon.AppManager.server.common.IRootServiceManager;
import io.github.muntashirakon.compat.os.ParcelCompat2;

public class AMService extends RootService {
static class IAMServiceImpl extends IAMService.Stub {
Expand Down Expand Up @@ -87,7 +88,7 @@ private void transactRemote(@NonNull Parcel data, @Nullable Parcel reply) throws
int targetCode = data.readInt();
int targetFlags = data.readInt();

Parcel newData = Parcel.obtain();
Parcel newData = ParcelCompat2.obtain(targetBinder);
try {
newData.appendFrom(data, data.dataPosition(), data.dataAvail());
long id = Binder.clearCallingIdentity();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.Objects;

import io.github.muntashirakon.AppManager.server.common.IRootServiceManager;
import io.github.muntashirakon.compat.os.ParcelCompat2;

// Copyright 2020 Rikka
public class ProxyBinder implements IBinder {
Expand Down Expand Up @@ -53,15 +54,16 @@ public ProxyBinder(@NonNull IBinder original) {
@Override
public boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags) throws RemoteException {
if (LocalServices.alive()) {
Parcel newData = Parcel.obtain();
IBinder targetBinder = LocalServices.getAmService().asBinder();
Parcel newData = ParcelCompat2.obtain(targetBinder);
try {
newData.writeInterfaceToken(IRootServiceManager.class.getName());
newData.writeStrongBinder(mOriginal);
newData.writeInt(code);
newData.writeInt(flags);
newData.appendFrom(data, 0, data.dataSize());
// Transact via AMService
LocalServices.getAmService().asBinder().transact(PROXY_BINDER_TRANSACT_CODE, newData, reply, 0);
targetBinder.transact(PROXY_BINDER_TRANSACT_CODE, newData, reply, 0);
} finally {
newData.recycle();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-License-Identifier: GPL-3.0-or-later

package io.github.muntashirakon.compat.os;

import android.os.Build;
import android.os.IBinder;
import android.os.Parcel;

import androidx.annotation.NonNull;

public final class ParcelCompat2 {
@NonNull
public static Parcel obtain(@NonNull IBinder binder) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return Parcel.obtain(binder);
}
return Parcel.obtain();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@
package aosp.android.content.pm;

import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;

import io.github.muntashirakon.compat.os.ParcelCompat2;
import io.github.muntashirakon.io.IoUtils;

/**
* Transfer a large list of Parcelable objects across an IPC. Splits into
* multiple transactions if needed.
Expand All @@ -29,7 +34,13 @@ abstract class BaseParceledListSlice<T> implements Parcelable {
private static final String TAG = "ParceledListSlice";
private static final boolean DEBUG = false;

private static final int MAX_IPC_SIZE = 1024 * 50; /*IoUtils.DEFAULT_BUFFER_SIZE*/
private static final int MAX_IPC_SIZE;

static {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
MAX_IPC_SIZE = IBinder.getSuggestedMaxIpcSizeBytes();
} else MAX_IPC_SIZE = IoUtils.DEFAULT_BUFFER_SIZE;
}

private final List<T> mList;

Expand All @@ -39,7 +50,7 @@ public BaseParceledListSlice(List<T> list) {
mList = list;
}

BaseParceledListSlice(Parcel p) {
BaseParceledListSlice(@NonNull Parcel p) {
// Unlike the Android frameworks, we have no access to certain remote class
ClassLoader loader = BaseParceledListSlice.class.getClassLoader();
final int N = p.readInt();
Expand Down Expand Up @@ -76,8 +87,8 @@ public BaseParceledListSlice(List<T> list) {
final IBinder retriever = p.readStrongBinder();
while (i < N) {
if (DEBUG) Log.d(TAG, "Reading more @" + i + " of " + N + ": retriever=" + retriever);
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
Parcel data = ParcelCompat2.obtain(retriever);
Parcel reply = ParcelCompat2.obtain(retriever);
data.writeInt(i);
try {
retriever.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
Expand All @@ -100,7 +111,7 @@ public BaseParceledListSlice(List<T> list) {
}

@SuppressWarnings("unchecked")
private T readCreator(Parcelable.Creator<?> creator, Parcel p, ClassLoader loader) {
private T readCreator(Parcelable.Creator<?> creator, Parcel p, @Nullable ClassLoader loader) {
if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
Parcelable.ClassLoaderCreator<?> classLoaderCreator =
(Parcelable.ClassLoaderCreator<?>) creator;
Expand All @@ -109,7 +120,7 @@ private T readCreator(Parcelable.Creator<?> creator, Parcel p, ClassLoader loade
return (T) creator.createFromParcel(p);
}

private static void verifySameType(final Class<?> expected, final Class<?> actual) {
private static void verifySameType(@Nullable final Class<?> expected, @NonNull final Class<?> actual) {
if (!actual.equals(expected)) {
throw new IllegalArgumentException("Can't unparcel type "
+ actual.getName() + " in list of type "
Expand Down Expand Up @@ -192,5 +203,5 @@ protected boolean onTransact(int code, @NonNull Parcel data, Parcel reply, int f

protected abstract void writeParcelableCreator(T parcelable, Parcel dest);

protected abstract Parcelable.Creator<?> readParcelableCreator(Parcel from, ClassLoader loader);
protected abstract Parcelable.Creator<?> readParcelableCreator(Parcel from, @Nullable ClassLoader loader);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import android.os.Parcel;
import android.os.Parcelable;

import androidx.annotation.Nullable;

import java.util.Collections;
import java.util.List;

Expand Down Expand Up @@ -43,7 +45,7 @@ protected void writeParcelableCreator(String parcelable, Parcel dest) {
}

@Override
protected Parcelable.Creator<?> readParcelableCreator(Parcel from, ClassLoader loader) {
protected Parcelable.Creator<?> readParcelableCreator(Parcel from, @Nullable ClassLoader loader) {
return Parcel.STRING_CREATOR;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,28 @@
import android.os.Parcelable;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

// Copyright 2017 Zheng Li
public class CallerResult implements Parcelable {
@Nullable
private byte[] mReply;
@Nullable
private Throwable mThrowable;
@Nullable
private Object mReplyObj;

@Nullable
public byte[] getReply() {
return mReply;
}

@Nullable
public Throwable getThrowable() {
return mThrowable;
}

@Nullable
public Object getReplyObj() {
if (mReplyObj == null && mReply != null) {
mReplyObj = ParcelableUtil.readValue(mReply);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,36 @@
import android.os.Parcelable;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.jetbrains.annotations.Contract;

// Copyright 2017 Zheng Li
public class ParcelableUtil {
@NonNull
public static byte[] marshall(@NonNull Parcelable parcelable) {
Parcel parcel = Parcel.obtain();
parcelable.writeToParcel(parcel, 0);
byte[] bytes = parcel.marshall();
parcel.recycle();
return bytes;
try {
parcelable.writeToParcel(parcel, 0);
return parcel.marshall();
} finally {
parcel.recycle();
}
}

public static <T extends Parcelable> T unmarshall(byte[] bytes, Parcelable.Creator<T> creator) {
@Contract("!null,_ -> !null")
@Nullable
public static <T extends Parcelable> T unmarshall(@Nullable byte[] bytes, @NonNull Parcelable.Creator<T> creator) {
if (bytes == null) {
return null;
}
Parcel parcel = unmarshall(bytes);
return creator.createFromParcel(parcel);
}

public static Parcel unmarshall(byte[] bytes) {
@Contract("!null -> !null")
@Nullable
public static Parcel unmarshall(@Nullable byte[] bytes) {
if (bytes == null) {
return null;
}
Expand All @@ -36,13 +45,16 @@ public static Parcel unmarshall(byte[] bytes) {
return parcel;
}

@Nullable
public static Object readValue(byte[] bytes) {
if (bytes == null) {
return null;
}
Parcel unmarshall = unmarshall(bytes);
Object o = unmarshall.readValue(ParcelableUtil.class.getClassLoader());
unmarshall.recycle();
return o;
try {
return unmarshall.readValue(ParcelableUtil.class.getClassLoader());
} finally {
unmarshall.recycle();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,12 @@ public void onMessage(@NonNull byte[] bytes) {
Shell.Result shellResult = shell.exec(shellCaller.getCommand());
result = new CallerResult();
Parcel parcel = Parcel.obtain();
parcel.writeValue(shellResult);
result.setReply(parcel.marshall());
parcel.recycle();
try {
parcel.writeValue(shellResult);
result.setReply(parcel.marshall());
} finally {
parcel.recycle();
}
}
LifecycleAgent.sServerInfo.successCount++;
} catch (Throwable e) {
Expand Down

0 comments on commit 1a8928c

Please sign in to comment.