Skip to content

Commit

Permalink
cmsdk: Declare a parcelable header.
Browse files Browse the repository at this point in the history
  - This change forces that a parcelable header is written as the
  first data positions in a parcel and defines a means to distinguish
  between old sdk class versions vs new ones to do proper unraveling
  of parcels.

Ticket: BAMBOO-152
Change-Id: I9cc762fe8a51cc527e85be7fe5de57e4613be019
  • Loading branch information
Adnan Begovic committed Jul 21, 2015
1 parent 5ff5e10 commit 33a24ad
Show file tree
Hide file tree
Showing 10 changed files with 535 additions and 124 deletions.
157 changes: 126 additions & 31 deletions src/java/cyanogenmod/app/CustomTile.java
Expand Up @@ -23,6 +23,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import cyanogenmod.os.Build;

import java.util.ArrayList;

Expand Down Expand Up @@ -85,26 +86,42 @@ public class CustomTile implements Parcelable {
* Unflatten the CustomTile from a parcel.
*/
public CustomTile(Parcel parcel) {
resourcesPackageName = parcel.readString();
if (parcel.readInt() != 0) {
this.onClick = PendingIntent.CREATOR.createFromParcel(parcel);
}
if (parcel.readInt() != 0) {
this.onSettingsClick = Intent.CREATOR.createFromParcel(parcel);
}
if (parcel.readInt() != 0) {
this.onClickUri = Uri.CREATOR.createFromParcel(parcel);
}
if (parcel.readInt() != 0) {
this.label = parcel.readString();
}
if (parcel.readInt() != 0) {
this.contentDescription = parcel.readString();
// Read parcelable version, make sure to define explicit changes
// within {@link Build.PARCELABLE_VERSION);
int parcelableVersion = parcel.readInt();
int parcelableSize = parcel.readInt();
int startPosition = parcel.dataPosition();

// Pattern here is that all new members should be added to the end of
// the writeToParcel method. Then we step through each version, until the latest
// API release to help unravel this parcel
if (parcelableVersion >= Build.CM_VERSION_CODES.APRICOT) {
if (parcel.readInt() != 0) {
this.onClick = PendingIntent.CREATOR.createFromParcel(parcel);
}
if (parcel.readInt() != 0) {
this.onSettingsClick = Intent.CREATOR.createFromParcel(parcel);
}
if (parcel.readInt() != 0) {
this.onClickUri = Uri.CREATOR.createFromParcel(parcel);
}
if (parcel.readInt() != 0) {
this.label = parcel.readString();
}
if (parcel.readInt() != 0) {
this.contentDescription = parcel.readString();
}
if (parcel.readInt() != 0) {
this.expandedStyle = ExpandedStyle.CREATOR.createFromParcel(parcel);
}
this.icon = parcel.readInt();
}
if (parcel.readInt() != 0) {
this.expandedStyle = ExpandedStyle.CREATOR.createFromParcel(parcel);

if (parcelableVersion >= Build.CM_VERSION_CODES.BOYSENBERRY) {
this.resourcesPackageName = parcel.readString();
}
this.icon = parcel.readInt();

parcel.setDataPosition(startPosition + parcelableSize);
}

/**
Expand Down Expand Up @@ -177,7 +194,17 @@ public int describeContents() {

@Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(resourcesPackageName);
// Write parcelable version, make sure to define explicit changes
// within {@link Build.PARCELABLE_VERSION);
out.writeInt(Build.PARCELABLE_VERSION);

// Inject a placeholder that will store the parcel size from this point on
// (not including the size itself).
int sizePosition = out.dataPosition();
out.writeInt(0);
int startPosition = out.dataPosition();

// ==== APRICOT =====
if (onClick != null) {
out.writeInt(1);
onClick.writeToParcel(out, 0);
Expand Down Expand Up @@ -215,6 +242,15 @@ public void writeToParcel(Parcel out, int flags) {
out.writeInt(0);
}
out.writeInt(icon);

// ==== BOYSENBERRY =====
out.writeString(resourcesPackageName);

// Go back and write size
int parcelableSize = out.dataPosition() - startPosition;
out.setDataPosition(sizePosition);
out.writeInt(parcelableSize);
out.setDataPosition(startPosition + parcelableSize);
}

/**
Expand Down Expand Up @@ -245,10 +281,23 @@ private ExpandedStyle() {
private int styleId;

private ExpandedStyle(Parcel parcel) {
if (parcel.readInt() != 0) {
expandedItems = parcel.createTypedArray(ExpandedItem.CREATOR);
// Read parcelable version, make sure to define explicit changes
// within {@link Build.PARCELABLE_VERSION);
int parcelableVersion = parcel.readInt();
int parcelableSize = parcel.readInt();
int startPosition = parcel.dataPosition();

// Pattern here is that all new members should be added to the end of
// the writeToParcel method. Then we step through each version, until the latest
// API release to help unravel this parcel
if (parcelableVersion >= Build.CM_VERSION_CODES.APRICOT) {
if (parcel.readInt() != 0) {
expandedItems = parcel.createTypedArray(ExpandedItem.CREATOR);
}
styleId = parcel.readInt();
}
styleId = parcel.readInt();

parcel.setDataPosition(startPosition + parcelableSize);
}

/**
Expand Down Expand Up @@ -298,13 +347,30 @@ public int describeContents() {

@Override
public void writeToParcel(Parcel parcel, int i) {
// Write parcelable version, make sure to define explicit changes
// within {@link Build.PARCELABLE_VERSION);
parcel.writeInt(Build.PARCELABLE_VERSION);

// Inject a placeholder that will store the parcel size from this point on
// (not including the size itself).
int sizePosition = parcel.dataPosition();
parcel.writeInt(0);
int startPosition = parcel.dataPosition();

// ==== APRICOT ====
if (expandedItems != null) {
parcel.writeInt(1);
parcel.writeTypedArray(expandedItems, 0);
} else {
parcel.writeInt(0);
}
parcel.writeInt(styleId);

// Go back and write size
int parcelableSize = parcel.dataPosition() - startPosition;
parcel.setDataPosition(sizePosition);
parcel.writeInt(parcelableSize);
parcel.setDataPosition(startPosition + parcelableSize);
}

@Override
Expand Down Expand Up @@ -444,16 +510,29 @@ protected void internalSetOnClickPendingIntent(PendingIntent pendingIntent) {
* Unflatten the ExpandedItem from a parcel.
*/
protected ExpandedItem(Parcel parcel) {
if (parcel.readInt() != 0) {
onClickPendingIntent = PendingIntent.CREATOR.createFromParcel(parcel);
}
if (parcel.readInt() != 0) {
itemTitle = parcel.readString();
}
if (parcel.readInt() != 0) {
itemSummary = parcel.readString();
// Read parcelable version, make sure to define explicit changes
// within {@link Build.PARCELABLE_VERSION);
int parcelableVersion = parcel.readInt();
int parcelableSize = parcel.readInt();
int startPosition = parcel.dataPosition();

// Pattern here is that all new members should be added to the end of
// the writeToParcel method. Then we step through each version, until the latest
// API release to help unravel this parcel
if (parcelableVersion >= Build.CM_VERSION_CODES.APRICOT) {
if (parcel.readInt() != 0) {
onClickPendingIntent = PendingIntent.CREATOR.createFromParcel(parcel);
}
if (parcel.readInt() != 0) {
itemTitle = parcel.readString();
}
if (parcel.readInt() != 0) {
itemSummary = parcel.readString();
}
itemDrawableResourceId = parcel.readInt();
}
itemDrawableResourceId = parcel.readInt();

parcel.setDataPosition(startPosition + parcelableSize);
}

@Override
Expand All @@ -463,6 +542,16 @@ public int describeContents() {

@Override
public void writeToParcel(Parcel out, int flags) {
// Write parcelable version, make sure to define explicit changes
// within {@link Build.PARCELABLE_VERSION);
out.writeInt(Build.PARCELABLE_VERSION);

// Inject a placeholder that will store the parcel size from this point on
// (not including the size itself).
int sizePosition = out.dataPosition();
out.writeInt(0);
int startPosition = out.dataPosition();

if (onClickPendingIntent != null) {
out.writeInt(1);
onClickPendingIntent.writeToParcel(out, 0);
Expand All @@ -482,6 +571,12 @@ public void writeToParcel(Parcel out, int flags) {
out.writeInt(0);
}
out.writeInt(itemDrawableResourceId);

// Go back and write size
int parcelableSize = out.dataPosition() - startPosition;
out.setDataPosition(sizePosition);
out.writeInt(parcelableSize);
out.setDataPosition(startPosition + parcelableSize);
}

@Override
Expand Down

0 comments on commit 33a24ad

Please sign in to comment.