mirror of
https://github.com/moparisthebest/android_external_SafeParcel
synced 2024-12-04 14:32:17 -05:00
Initial commit
This commit is contained in:
commit
53bf6bc84b
7
Android.mk
Normal file
7
Android.mk
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := SafeParcel
|
||||||
|
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_JAVA_LIBRARY)
|
4
AndroidManifest.xml
Normal file
4
AndroidManifest.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest package="org.microg.safeparcel">
|
||||||
|
<!-- This is not needed, it's just here to stop build systems from complaining -->
|
||||||
|
</manifest>
|
25
build.gradle
Normal file
25
build.gradle
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:1.0.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
apply plugin: 'com.android.library'
|
||||||
|
android {
|
||||||
|
compileSdkVersion 21
|
||||||
|
buildToolsVersion "21.0.2"
|
||||||
|
lintOptions.abortOnError false
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
manifest.srcFile 'AndroidManifest.xml'
|
||||||
|
java.srcDirs = ['src']
|
||||||
|
aidl.srcDirs = ['src']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
}
|
131
src/org/microg/safeparcel/SafeParcelReader.java
Normal file
131
src/org/microg/safeparcel/SafeParcelReader.java
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 μg Project Team
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.safeparcel;
|
||||||
|
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
public class SafeParcelReader {
|
||||||
|
public static int halfOf(int i) {
|
||||||
|
return i & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int readSingleInt(Parcel parcel) {
|
||||||
|
return parcel.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int readStart(Parcel parcel, int first) {
|
||||||
|
if ((first & 0xFFFF0000) != -65536)
|
||||||
|
return first >> 16 & 0xFFFF;
|
||||||
|
return parcel.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readStart(Parcel parcel, int position, int length) {
|
||||||
|
int i = readStart(parcel, position);
|
||||||
|
if (i != length)
|
||||||
|
throw new ReadException("Expected size " + length + " got " + i + " (0x" + Integer.toHexString(i) + ")", parcel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int readStart(Parcel parcel) {
|
||||||
|
int first = readSingleInt(parcel);
|
||||||
|
int length = readStart(parcel, first);
|
||||||
|
int start = parcel.dataPosition();
|
||||||
|
if (halfOf(first) != SafeParcelable.SAFE_PARCEL_MAGIC)
|
||||||
|
throw new ReadException("Expected object header. Got 0x" + Integer.toHexString(first), parcel);
|
||||||
|
int end = start + length;
|
||||||
|
if ((end < start) || (end > parcel.dataSize()))
|
||||||
|
throw new ReadException("Size read is invalid start=" + start + " end=" + end, parcel);
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int readInt(Parcel parcel, int position) {
|
||||||
|
readStart(parcel, position, 4);
|
||||||
|
return parcel.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte readByte(Parcel parcel, int position) {
|
||||||
|
readStart(parcel, position, 4);
|
||||||
|
return (byte) parcel.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static short readShort(Parcel parcel, int position) {
|
||||||
|
readStart(parcel, position, 4);
|
||||||
|
return (short) parcel.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean readBool(Parcel parcel, int position) {
|
||||||
|
readStart(parcel, position, 4);
|
||||||
|
return parcel.readInt() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long readLong(Parcel parcel, int position) {
|
||||||
|
readStart(parcel, position, 8);
|
||||||
|
return parcel.readLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float readFloat(Parcel parcel, int position) {
|
||||||
|
readStart(parcel, position, 4);
|
||||||
|
return parcel.readFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double readDouble(Parcel parcel, int position) {
|
||||||
|
readStart(parcel, position, 8);
|
||||||
|
return parcel.readDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String readString(Parcel parcel, int position) {
|
||||||
|
int length = readStart(parcel, position);
|
||||||
|
int start = parcel.dataPosition();
|
||||||
|
if (length == 0)
|
||||||
|
return null;
|
||||||
|
String string = parcel.readString();
|
||||||
|
parcel.setDataPosition(start + length);
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IBinder readBinder(Parcel parcel, int position) {
|
||||||
|
int length = readStart(parcel, position);
|
||||||
|
int start = parcel.dataPosition();
|
||||||
|
if (length == 0)
|
||||||
|
return null;
|
||||||
|
IBinder binder = parcel.readStrongBinder();
|
||||||
|
parcel.setDataPosition(start + length);
|
||||||
|
return binder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Parcelable> T readParcelable(Parcel parcel, int position, Parcelable.Creator<T> creator) {
|
||||||
|
int length = readStart(parcel, position);
|
||||||
|
int start = parcel.dataPosition();
|
||||||
|
if (length == 0)
|
||||||
|
return null;
|
||||||
|
T t = creator.createFromParcel(parcel);
|
||||||
|
parcel.setDataPosition(start + length);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void skip(Parcel parcel, int position) {
|
||||||
|
int i = readStart(parcel, position);
|
||||||
|
parcel.setDataPosition(parcel.dataPosition() + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ReadException extends RuntimeException {
|
||||||
|
public ReadException(String message, Parcel parcel) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
179
src/org/microg/safeparcel/SafeParcelUtil.java
Normal file
179
src/org/microg/safeparcel/SafeParcelUtil.java
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
package org.microg.safeparcel;
|
||||||
|
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SafeParcelUtil {
|
||||||
|
private static final String TAG = "SafeParcel";
|
||||||
|
|
||||||
|
public static void writeObject(SafeParcelable object, Parcel parcel, int flags) {
|
||||||
|
if (object == null)
|
||||||
|
throw new NullPointerException();
|
||||||
|
Class clazz = object.getClass();
|
||||||
|
int start = SafeParcelWriter.writeStart(parcel);
|
||||||
|
while (clazz != null) {
|
||||||
|
for (Field field : clazz.getDeclaredFields()) {
|
||||||
|
if (field.isAnnotationPresent(SafeParceled.class)) {
|
||||||
|
try {
|
||||||
|
writeField(object, parcel, field, flags);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.w(TAG, "Error writing field: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
SafeParcelWriter.writeEnd(parcel, start);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void readObject(SafeParcelable object, Parcel parcel) {
|
||||||
|
if (object == null)
|
||||||
|
throw new NullPointerException();
|
||||||
|
Class clazz = object.getClass();
|
||||||
|
Map<Integer, Field> fieldMap = new HashMap<>();
|
||||||
|
while (clazz != null) {
|
||||||
|
for (Field field : clazz.getDeclaredFields()) {
|
||||||
|
if (field.isAnnotationPresent(SafeParceled.class)) {
|
||||||
|
int fieldNum = field.getAnnotation(SafeParceled.class).value();
|
||||||
|
if (fieldMap.containsKey(fieldNum)) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"Field number " + fieldNum + " is used twice in " +
|
||||||
|
clazz.getName() + " for fields " + field.getName() +
|
||||||
|
" and " + fieldMap.get(fieldNum).getName());
|
||||||
|
}
|
||||||
|
fieldMap.put(fieldNum, field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
int end = SafeParcelReader.readStart(parcel);
|
||||||
|
while (parcel.dataPosition() < end) {
|
||||||
|
int position = SafeParcelReader.readSingleInt(parcel);
|
||||||
|
int fieldNum = SafeParcelReader.halfOf(position);
|
||||||
|
if (!fieldMap.containsKey(fieldNum)) {
|
||||||
|
Log.w(TAG,
|
||||||
|
"Unknown field num " + fieldNum + " in " + clazz.getName() + ", skipping.");
|
||||||
|
SafeParcelReader.skip(parcel, position);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
readField(object, parcel, fieldMap.get(fieldNum), position);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.w(TAG, "Error reading field: " + fieldNum + " in " + clazz.getName() +
|
||||||
|
", skipping.", e);
|
||||||
|
SafeParcelReader.skip(parcel, position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parcel.dataPosition() > end) {
|
||||||
|
throw new RuntimeException("Overread allowed size end=" + end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Parcelable.Creator getCreator(Field field)
|
||||||
|
throws IllegalAccessException {
|
||||||
|
try {
|
||||||
|
return (Parcelable.Creator) field.getType().getDeclaredField("CREATOR").get(null);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
field.getType() + " is an Parcelable without CREATOR");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeField(SafeParcelable object, Parcel parcel, Field field, int flags)
|
||||||
|
throws IllegalAccessException {
|
||||||
|
int num = field.getAnnotation(SafeParceled.class).value();
|
||||||
|
boolean mayNull = field.getAnnotation(SafeParceled.class).mayNull();
|
||||||
|
boolean acc = field.isAccessible();
|
||||||
|
field.setAccessible(true);
|
||||||
|
switch (SafeParcelType.fromClass(field.getType())) {
|
||||||
|
case Parcelable:
|
||||||
|
SafeParcelWriter.write(parcel, num, (Parcelable) field.get(object), flags, mayNull);
|
||||||
|
break;
|
||||||
|
case Binder:
|
||||||
|
SafeParcelWriter.write(parcel, num, (IBinder) field.get(object), mayNull);
|
||||||
|
break;
|
||||||
|
case Integer:
|
||||||
|
SafeParcelWriter.write(parcel, num, (Integer) field.get(object));
|
||||||
|
break;
|
||||||
|
case Long:
|
||||||
|
SafeParcelWriter.write(parcel, num, (Long) field.get(object));
|
||||||
|
break;
|
||||||
|
case Boolean:
|
||||||
|
SafeParcelWriter.write(parcel, num, (Boolean) field.get(object));
|
||||||
|
break;
|
||||||
|
case Float:
|
||||||
|
SafeParcelWriter.write(parcel, num, (Float) field.get(object));
|
||||||
|
break;
|
||||||
|
case Double:
|
||||||
|
SafeParcelWriter.write(parcel, num, (Double) field.get(object));
|
||||||
|
break;
|
||||||
|
case String:
|
||||||
|
SafeParcelWriter.write(parcel, num, (String) field.get(object), mayNull);
|
||||||
|
}
|
||||||
|
field.setAccessible(acc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void readField(SafeParcelable object, Parcel parcel, Field field, int position)
|
||||||
|
throws IllegalAccessException {
|
||||||
|
boolean acc = field.isAccessible();
|
||||||
|
field.setAccessible(true);
|
||||||
|
switch (SafeParcelType.fromClass(field.getType())) {
|
||||||
|
case Parcelable:
|
||||||
|
field.set(object, SafeParcelReader
|
||||||
|
.readParcelable(parcel, position, getCreator(field)));
|
||||||
|
break;
|
||||||
|
case Binder:
|
||||||
|
field.set(object, SafeParcelReader.readBinder(parcel,
|
||||||
|
position));
|
||||||
|
break;
|
||||||
|
case Integer:
|
||||||
|
field.set(object, SafeParcelReader.readInt(parcel, position));
|
||||||
|
break;
|
||||||
|
case Long:
|
||||||
|
field.set(object, SafeParcelReader.readLong(parcel, position));
|
||||||
|
break;
|
||||||
|
case Boolean:
|
||||||
|
field.set(object, SafeParcelReader.readBool(parcel, position));
|
||||||
|
break;
|
||||||
|
case Float:
|
||||||
|
field.set(object, SafeParcelReader.readFloat(parcel, position));
|
||||||
|
break;
|
||||||
|
case Double:
|
||||||
|
field.set(object, SafeParcelReader.readDouble(parcel, position));
|
||||||
|
break;
|
||||||
|
case String:
|
||||||
|
field.set(object, SafeParcelReader.readString(parcel, position));
|
||||||
|
}
|
||||||
|
field.setAccessible(acc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SafeParcelType {
|
||||||
|
Parcelable, Binder, Integer, Long, Boolean, Float, Double, String;
|
||||||
|
|
||||||
|
public static SafeParcelType fromClass(Class clazz) {
|
||||||
|
if (Parcelable.class.isAssignableFrom(clazz))
|
||||||
|
return Parcelable;
|
||||||
|
if (IBinder.class.isAssignableFrom(clazz))
|
||||||
|
return Binder;
|
||||||
|
if (clazz == int.class || clazz == Integer.class)
|
||||||
|
return Integer;
|
||||||
|
if (clazz == boolean.class || clazz == Boolean.class)
|
||||||
|
return Boolean;
|
||||||
|
if (clazz == long.class || clazz == Long.class)
|
||||||
|
return Long;
|
||||||
|
if (clazz == float.class || clazz == Float.class)
|
||||||
|
return Float;
|
||||||
|
if (clazz == double.class || clazz == Double.class)
|
||||||
|
return Float;
|
||||||
|
if (clazz == java.lang.String.class)
|
||||||
|
return String;
|
||||||
|
throw new RuntimeException("Type is not yet usable with SafeParcelUtil: " + clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
235
src/org/microg/safeparcel/SafeParcelWriter.java
Normal file
235
src/org/microg/safeparcel/SafeParcelWriter.java
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 μg Project Team
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.safeparcel;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SafeParcelWriter {
|
||||||
|
|
||||||
|
private static void writeStart(Parcel parcel, int position, int length) {
|
||||||
|
if (length >= 65535) {
|
||||||
|
parcel.writeInt(0xFFFF0000 | position);
|
||||||
|
parcel.writeInt(length);
|
||||||
|
} else {
|
||||||
|
parcel.writeInt(length << 16 | position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int writeStart(Parcel parcel) {
|
||||||
|
return writeStart(parcel, SafeParcelable.SAFE_PARCEL_MAGIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int writeStart(Parcel parcel, int position) {
|
||||||
|
parcel.writeInt(0xFFFF0000 | position);
|
||||||
|
parcel.writeInt(0);
|
||||||
|
return parcel.dataPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeEnd(Parcel parcel, int start) {
|
||||||
|
int end = parcel.dataPosition();
|
||||||
|
int length = end - start;
|
||||||
|
parcel.setDataPosition(start - 4);
|
||||||
|
parcel.writeInt(length);
|
||||||
|
parcel.setDataPosition(end);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, Boolean val) {
|
||||||
|
if (val == null) return;
|
||||||
|
writeStart(parcel, position, 4);
|
||||||
|
parcel.writeInt(val ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, Byte val) {
|
||||||
|
if (val == null) return;
|
||||||
|
writeStart(parcel, position, 4);
|
||||||
|
parcel.writeInt(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, Short val) {
|
||||||
|
if (val == null) return;
|
||||||
|
writeStart(parcel, position, 4);
|
||||||
|
parcel.writeInt(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, Integer val) {
|
||||||
|
if (val == null) return;
|
||||||
|
writeStart(parcel, position, 4);
|
||||||
|
parcel.writeInt(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, Long val) {
|
||||||
|
if (val == null) return;
|
||||||
|
writeStart(parcel, position, 8);
|
||||||
|
parcel.writeLong(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, Float val) {
|
||||||
|
if (val == null) return;
|
||||||
|
writeStart(parcel, position, 4);
|
||||||
|
parcel.writeFloat(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, Double val) {
|
||||||
|
if (val == null) return;
|
||||||
|
writeStart(parcel, position, 8);
|
||||||
|
parcel.writeDouble(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, String val, boolean mayNull) {
|
||||||
|
if (val == null) {
|
||||||
|
if (mayNull) {
|
||||||
|
writeStart(parcel, position, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int start = writeStart(parcel, position);
|
||||||
|
parcel.writeString(val);
|
||||||
|
writeEnd(parcel, start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, Parcelable val, int flags, boolean mayNull) {
|
||||||
|
if (val == null) {
|
||||||
|
if (mayNull) {
|
||||||
|
writeStart(parcel, position, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int start = writeStart(parcel, position);
|
||||||
|
val.writeToParcel(parcel, flags);
|
||||||
|
writeEnd(parcel, start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, Bundle val, boolean mayNull) {
|
||||||
|
if (val == null) {
|
||||||
|
if (mayNull) {
|
||||||
|
writeStart(parcel, position, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int start = writeStart(parcel, position);
|
||||||
|
parcel.writeBundle(val);
|
||||||
|
writeEnd(parcel, start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, byte[] val, boolean mayNull) {
|
||||||
|
if (val == null) {
|
||||||
|
if (mayNull) {
|
||||||
|
writeStart(parcel, position, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int start = writeStart(parcel, position);
|
||||||
|
parcel.writeByteArray(val);
|
||||||
|
writeEnd(parcel, start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, String[] val, boolean mayNull) {
|
||||||
|
if (val == null) {
|
||||||
|
if (mayNull) {
|
||||||
|
writeStart(parcel, position, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int start = writeStart(parcel, position);
|
||||||
|
parcel.writeStringArray(val);
|
||||||
|
writeEnd(parcel, start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeStringList(Parcel parcel, int position, List<String> val, boolean mayNull) {
|
||||||
|
if (val == null) {
|
||||||
|
if (mayNull) {
|
||||||
|
writeStart(parcel, position, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int start = writeStart(parcel, position);
|
||||||
|
parcel.writeStringList(val);
|
||||||
|
writeEnd(parcel, start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T extends Parcelable> void writeArrayPart(Parcel parcel, T val, int flags) {
|
||||||
|
int before = parcel.dataPosition();
|
||||||
|
parcel.writeInt(1);
|
||||||
|
int start = parcel.dataPosition();
|
||||||
|
val.writeToParcel(parcel, flags);
|
||||||
|
int end = parcel.dataPosition();
|
||||||
|
parcel.setDataPosition(before);
|
||||||
|
parcel.writeInt(end - start);
|
||||||
|
parcel.setDataPosition(end);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Parcelable> void write(Parcel parcel, int position, T[] val, int flags, boolean mayNull) {
|
||||||
|
if (val == null) {
|
||||||
|
if (mayNull) {
|
||||||
|
writeStart(parcel, position, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int start = writeStart(parcel, position);
|
||||||
|
parcel.writeInt(val.length);
|
||||||
|
for (T t : val) {
|
||||||
|
if (t == null) {
|
||||||
|
parcel.writeInt(0);
|
||||||
|
} else {
|
||||||
|
writeArrayPart(parcel, t, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeEnd(parcel, start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, Parcel val, boolean mayNull) {
|
||||||
|
if (val == null) {
|
||||||
|
if (mayNull) {
|
||||||
|
writeStart(parcel, position, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int start = writeStart(parcel, position);
|
||||||
|
parcel.appendFrom(val, 0, val.dataSize());
|
||||||
|
writeEnd(parcel, start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, List val, boolean mayNull) {
|
||||||
|
if (val == null) {
|
||||||
|
if (mayNull) {
|
||||||
|
writeStart(parcel, position, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int start = writeStart(parcel, position);
|
||||||
|
parcel.writeList(val);
|
||||||
|
writeEnd(parcel, start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(Parcel parcel, int position, IBinder val, boolean mayNull) {
|
||||||
|
if (val == null) {
|
||||||
|
if (mayNull) {
|
||||||
|
writeStart(parcel, position, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int start = writeStart(parcel, position);
|
||||||
|
parcel.writeStrongBinder(val);
|
||||||
|
writeEnd(parcel, start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
24
src/org/microg/safeparcel/SafeParcelable.java
Normal file
24
src/org/microg/safeparcel/SafeParcelable.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 μg Project Team
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.safeparcel;
|
||||||
|
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
public interface SafeParcelable extends Parcelable {
|
||||||
|
public static final String NULL = "SAFE_PARCELABLE_NULL_STRING";
|
||||||
|
int SAFE_PARCEL_MAGIC = 20293;
|
||||||
|
}
|
14
src/org/microg/safeparcel/SafeParceled.java
Normal file
14
src/org/microg/safeparcel/SafeParceled.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package org.microg.safeparcel;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface SafeParceled {
|
||||||
|
int value();
|
||||||
|
|
||||||
|
boolean mayNull() default false;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user