sdk: introduce Style API

This API will allow apps to change global style mode and accent.

Global style mode can be
* Automatic (wallpaper)
* Automatic (day of time)
* Light
* Dark

Accent colors are defined in the caller application that will have
to pass the package name.

It's possible for apps to pass a Bitmap and get a suggestion
of a global style + accent color that can be applied.

Restrictions:
* Only one accent can be enabled at time.
* We're not limiting this to system apps, but we're marking
  this as dangerous permissions so apps will have to require
  it at runtime to the user.

Change-Id: I921e8758c3ae093a88e897899612830258c97f8d
Signed-off-by: Joey <joey@lineageos.org>
This commit is contained in:
Joey
2018-02-22 14:30:42 +01:00
parent 17b61ed328
commit 76fc3d3942
12 changed files with 640 additions and 6 deletions

View File

@@ -25,7 +25,7 @@ LOCAL_PATH := $(call my-dir)
lineage_platform_res := APPS/org.lineageos.platform-res_intermediates/src
# List of packages used in lineage-api-stubs
lineage_stub_packages := lineageos.app:lineageos.content:lineageos.hardware:lineageos.media:lineageos.os:lineageos.preference:lineageos.profiles:lineageos.providers:lineageos.platform:lineageos.power:lineageos.util:lineageos.weather:lineageos.weatherservice
lineage_stub_packages := lineageos.app:lineageos.content:lineageos.hardware:lineageos.media:lineageos.os:lineageos.preference:lineageos.profiles:lineageos.providers:lineageos.platform:lineageos.power:lineageos.util:lineageos.weather:lineageos.weatherservice:lineageos.style
# The LineageOS Platform Framework Library
# ============================================================

View File

@@ -270,6 +270,7 @@ package lineageos.hardware {
method public boolean isAutomaticOutdoorModeEnabled();
method public boolean isCABCEnabled();
method public boolean isColorEnhancementEnabled();
method public boolean isNightModeEnabled();
method public boolean setAutoContrastEnabled(boolean);
method public boolean setAutomaticOutdoorModeEnabled(boolean);
method public boolean setCABCEnabled(boolean);
@@ -279,7 +280,6 @@ package lineageos.hardware {
method public boolean setMode(int);
method public boolean setNightColorTemperature(int);
method public boolean setPictureAdjustment(lineageos.hardware.HSIC);
method public boolean isNightModeEnabled();
field public static final int ADJUSTMENT_CONTRAST = 3; // 0x3
field public static final int ADJUSTMENT_HUE = 0; // 0x0
field public static final int ADJUSTMENT_INTENSITY = 2; // 0x2
@@ -359,17 +359,14 @@ package lineageos.platform {
ctor public Manifest.permission();
field public static final java.lang.String ACCESS_WEATHER_MANAGER = "lineageos.permission.ACCESS_WEATHER_MANAGER";
field public static final java.lang.String BIND_WEATHER_PROVIDER_SERVICE = "lineageos.permission.BIND_WEATHER_PROVIDER_SERVICE";
field public static final java.lang.String CHANGE_STYLE = "lineageos.permission.CHANGE_STYLE";
field public static final java.lang.String HARDWARE_ABSTRACTION_ACCESS = "lineageos.permission.HARDWARE_ABSTRACTION_ACCESS";
field public static final java.lang.String MANAGE_LIVEDISPLAY = "lineageos.permission.MANAGE_LIVEDISPLAY";
field public static final java.lang.String MANAGE_REMOTE_PREFERENCES = "lineageos.permission.MANAGE_REMOTE_PREFERENCES";
field public static final java.lang.String MODIFY_MSIM_PHONE_STATE = "lineageos.permission.MODIFY_MSIM_PHONE_STATE";
field public static final java.lang.String MODIFY_NETWORK_SETTINGS = "lineageos.permission.MODIFY_NETWORK_SETTINGS";
field public static final java.lang.String MODIFY_PROFILES = "lineageos.permission.MODIFY_PROFILES";
field public static final java.lang.String MODIFY_SOUND_SETTINGS = "lineageos.permission.MODIFY_SOUND_SETTINGS";
field public static final java.lang.String PERFORMANCE_ACCESS = "lineageos.permission.PERFORMANCE_ACCESS";
field public static final java.lang.String PROTECTED_APP = "lineageos.permission.PROTECTED_APP";
field public static final java.lang.String READ_DATAUSAGE = "lineageos.permission.READ_DATAUSAGE";
field public static final java.lang.String READ_MSIM_PHONE_STATE = "lineageos.permission.READ_MSIM_PHONE_STATE";
field public static final java.lang.String READ_WEATHER = "lineageos.permission.READ_WEATHER";
field public static final java.lang.String WRITE_DATAUSAGE = "lineageos.permission.WRITE_DATAUSAGE";
field public static final java.lang.String WRITE_SECURE_SETTINGS = "lineageos.permission.WRITE_SECURE_SETTINGS";
@@ -381,6 +378,10 @@ package lineageos.platform {
ctor public R();
}
public static final class R.anim {
ctor public R.anim();
}
public static final class R.array {
ctor public R.array();
}
@@ -403,6 +404,10 @@ package lineageos.platform {
ctor public R.bool();
}
public static final class R.dimen {
ctor public R.dimen();
}
public static final class R.drawable {
ctor public R.drawable();
}
@@ -796,6 +801,8 @@ package lineageos.providers {
field public static final java.lang.String BATTERY_LIGHT_LOW_COLOR = "battery_light_low_color";
field public static final java.lang.String BATTERY_LIGHT_MEDIUM_COLOR = "battery_light_medium_color";
field public static final java.lang.String BATTERY_LIGHT_PULSE = "battery_light_pulse";
field public static final java.lang.String BERRY_CURRENT_ACCENT = "berry_current_accent";
field public static final java.lang.String BERRY_GLOBAL_STYLE = "berry_global_style";
field public static final java.lang.String BLUETOOTH_ACCEPT_ALL_FILES = "bluetooth_accept_all_files";
field public static final java.lang.String CALL_RECORDING_FORMAT = "call_recording_format";
field public static final java.lang.String CAMERA_LAUNCH = "camera_launch";
@@ -979,6 +986,31 @@ package lineageos.providers {
}
package lineageos.style {
public class StyleInterface {
method public static lineageos.style.StyleInterface getInstance(android.content.Context);
method public lineageos.style.Suggestion getSuggestion(android.graphics.Bitmap, int[]);
method public boolean setAccent(java.lang.String);
method public boolean setGlobalStyle(int);
field public static final java.lang.String ACCENT_DEFAULT = "lineageos";
field public static final java.lang.String CHANGE_STYLE_SETTINGS_PERMISSION = "lineageos.permission.CHANGE_STYLE";
field public static final int STYLE_GLOBAL_AUTO_DAYTIME = 1; // 0x1
field public static final int STYLE_GLOBAL_AUTO_WALLPAPER = 0; // 0x0
field public static final int STYLE_GLOBAL_DARK = 3; // 0x3
field public static final int STYLE_GLOBAL_LIGHT = 2; // 0x2
}
public class Suggestion implements android.os.Parcelable {
ctor public Suggestion(int, int);
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
field public final int globalStyle;
field public final int selectedAccent;
}
}
package lineageos.util {
public class ColorUtils {

View File

@@ -0,0 +1,225 @@
/*
* Copyright (c) 2018 The LineageOS Project
*
* 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.lineageos.platform.internal;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.om.IOverlayManager;
import android.content.om.OverlayInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.util.Log;
import lineageos.app.LineageContextConstants;
import lineageos.providers.LineageSettings;
import lineageos.style.IStyleInterface;
import lineageos.style.StyleInterface;
import lineageos.style.Suggestion;
import lineageos.util.palette.Palette;
/** @hide */
public class StyleInterfaceService extends LineageSystemService {
private static final String TAG = "LineageStyleInterfaceService";
private static final String ACCENT_METADATA_COLOR = "lineage_berry_accent_preview";
private static final int COLOR_DEFAULT = Color.BLACK;
private Context mContext;
private IOverlayManager mOverlayService;
private PackageManager mPackageManager;
public StyleInterfaceService(Context context) {
super(context);
mContext = context;
if (context.getPackageManager().hasSystemFeature(LineageContextConstants.Features.STYLES)) {
publishBinderService(LineageContextConstants.LINEAGE_STYLE_INTERFACE, mService);
} else {
Log.wtf(TAG, "Lineage profile service started by system server but feature xml not" +
" declared. Not publishing binder service!");
}
}
@Override
public String getFeatureDeclaration() {
return LineageContextConstants.Features.STYLES;
}
@Override
public void onStart() {
mPackageManager = mContext.getPackageManager();
mOverlayService = IOverlayManager.Stub.asInterface(ServiceManager.getService("overlay"));
}
private void enforceChangeStylePermission() {
mContext.enforceCallingOrSelfPermission(StyleInterface.CHANGE_STYLE_SETTINGS_PERMISSION,
"You do not have permissions to change system style");
}
private boolean setGlobalStyleInternal(int mode) {
return LineageSettings.System.putInt(mContext.getContentResolver(),
LineageSettings.System.BERRY_GLOBAL_STYLE, mode);
}
private boolean setAccentInternal(String pkgName) {
if (!isChangeableOverlay(pkgName)) {
Log.e(TAG, pkgName + ": is not a valid overlay package");
return false;
}
int userId = UserHandle.myUserId();
// Disable current accent
String currentAccent = LineageSettings.System.getString(mContext.getContentResolver(),
LineageSettings.System.BERRY_CURRENT_ACCENT);
try {
mOverlayService.setEnabled(currentAccent, false, userId);
} catch (RemoteException e) {
Log.e(TAG, "Failed to disable current accent", e);
}
if (StyleInterface.ACCENT_DEFAULT.equals(pkgName)) {
return LineageSettings.System.putString(mContext.getContentResolver(),
LineageSettings.System.BERRY_CURRENT_ACCENT, "");
}
// Enable new one
try {
mOverlayService.setEnabled(pkgName, true, userId);
return LineageSettings.System.putString(mContext.getContentResolver(),
LineageSettings.System.BERRY_CURRENT_ACCENT, pkgName);
} catch (RemoteException e) {
Log.e(TAG, "Failed to enable new accent", e);
}
return false;
}
private Suggestion getSuggestionInternal(Bitmap source, int[] colors) {
Palette palette = Palette.from(source).generate();
// Extract dominant color
int sourceColor = palette.getVibrantColor(COLOR_DEFAULT);
// If vibrant color extraction failed, let's try muted color
if (sourceColor == COLOR_DEFAULT) {
sourceColor = palette.getMutedColor(COLOR_DEFAULT);
}
boolean isLight = Color.luminance(sourceColor) > 0.3;
int bestColorPosition = getBestColor(sourceColor, colors);
int suggestedGlobalStyle = isLight ?
StyleInterface.STYLE_GLOBAL_LIGHT : StyleInterface.STYLE_GLOBAL_DARK;
return new Suggestion(suggestedGlobalStyle, bestColorPosition);
}
private int getBestColor(int sourceColor, int[] colors) {
int best = 0;
double minDiff = Double.MAX_VALUE;
for (int i = 0; i < colors.length; i++) {
double diff = Math.sqrt(
Math.pow(Color.red(colors[i]) - Color.red(sourceColor), 2) +
Math.pow(Color.green(colors[i]) - Color.green(sourceColor), 2) +
Math.pow(Color.blue(colors[i]) - Color.blue(sourceColor), 2));
if (diff < minDiff) {
best = i;
minDiff = diff;
}
}
return best;
}
private boolean isChangeableOverlay(String pkgName) {
if (pkgName == null) {
return false;
}
if (StyleInterface.ACCENT_DEFAULT.equals(pkgName)) {
return true;
}
try {
PackageInfo pi = mPackageManager.getPackageInfo(pkgName, 0);
return pi != null && !pi.isStaticOverlay && isValidAccent(pkgName);
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
private boolean isValidAccent(String pkgName) {
try {
ApplicationInfo ai = mPackageManager.getApplicationInfo(pkgName,
PackageManager.GET_META_DATA);
int color = ai.metaData == null ? -1 :
ai.metaData.getInt(ACCENT_METADATA_COLOR, -1);
return color != -1;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
private final IBinder mService = new IStyleInterface.Stub() {
@Override
public boolean setGlobalStyle(int style) {
enforceChangeStylePermission();
/*
* We need to clear the caller's identity in order to
* allow this method call to modify settings
* not allowed by the caller's permissions.
*/
long token = clearCallingIdentity();
boolean success = setGlobalStyleInternal(style);
restoreCallingIdentity(token);
return success;
}
@Override
public boolean setAccent(String pkgName) {
enforceChangeStylePermission();
/*
* We need to clear the caller's identity in order to
* allow this method call to modify settings
* not allowed by the caller's permissions.
*/
long token = clearCallingIdentity();
boolean success = setAccentInternal(pkgName);
restoreCallingIdentity(token);
return success;
}
@Override
public Suggestion getSuggestion(Bitmap source, int[] colors) {
enforceChangeStylePermission();
/*
* We need to clear the caller's identity in order to
* allow this method call to modify settings
* not allowed by the caller's permissions.
*/
long token = clearCallingIdentity();
Suggestion result = getSuggestionInternal(source, colors);
restoreCallingIdentity(token);
return result;
}
};
}

View File

@@ -117,6 +117,13 @@
android:icon="@drawable/ic_launcher_lineageos"
android:protectionLevel="normal" />
<!-- Allows an application to change system style -->
<permission android:name="lineageos.permission.CHANGE_STYLE"
android:label="@string/permlab_changeStyle"
android:description="@string/permdesc_changeStyle"
android:icon="@drawable/ic_launcher_lineageos"
android:protectionLevel="dangerous" />
<application android:process="system"
android:persistent="true"
android:hasCode="false"

View File

@@ -81,6 +81,7 @@
<item>org.lineageos.platform.internal.LineageWeatherManagerService</item>
<item>org.lineageos.platform.internal.display.LiveDisplayService</item>
<item>org.lineageos.platform.internal.LineageAudioService</item>
<item>org.lineageos.platform.internal.StyleInterfaceService</item>
</string-array>
<!-- The LineageSystemServer class that is invoked from Android's SystemServer -->

View File

@@ -39,6 +39,10 @@
<string name="permlab_protectedApp">add and remove apps to protected apps</string>
<string name="permdesc_protectedApp">Allows an app to mark other apps as protected and lock them.</string>
<!-- Labels for CHANGE_STYLE permission -->
<string name="permlab_changeStyle">change system style</string>
<string name="permdesc_changeStyle">Allows an app customize the system colors.</string>
<!-- Profiles -->
<!-- Names of default profiles. -->
<string name="profileNameDefault">Default</string>

View File

@@ -96,6 +96,17 @@ public final class LineageContextConstants {
*/
public static final String LINEAGE_AUDIO_SERVICE = "lineageaudio";
/**
* Use with {@link android.content.Context#getSystemService} to retrieve a
* {@link lineageos.app.StyleInterface} interact with system style.
*
* @see android.content.Context#getSystemService
* @see lineageos.app.StyleInterface
*
* @hide
*/
public static final String LINEAGE_STYLE_INTERFACE = "lineagestyle";
/**
* Features supported by the Lineage SDK.
*/
@@ -147,5 +158,13 @@ public final class LineageContextConstants {
*/
@SdkConstant(SdkConstant.SdkConstantType.FEATURE)
public static final String AUDIO = "org.lineageos.audio";
/**
* Feature for {@link PackageManager#getSystemAvailableFeatures} and
* {@link PackageManager#hasSystemFeature}: The device includes the lineage style service
* utilized by the lineage sdk.
*/
@SdkConstant(SdkConstant.SdkConstantType.FEATURE)
public static final String STYLES = "org.lineageos.style";
}
}

View File

@@ -178,6 +178,11 @@ public class Build {
/**
* Unreleased preliminary version starting from LineageOS 15.1
* <p>Applications targeting this or a later version will get access to these
* new features!</p>
* <ul>
* <li>Change system colors via {@link lineageos.app.StyleInterface}
* </ul>
*/
public static final int HACKBERRY = 8;
}

View File

@@ -0,0 +1,28 @@
/*
**
** Copyright (C) 2018 The LineageOS Project
**
** 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 lineageos.style;
import android.graphics.Bitmap;
import lineageos.style.Suggestion;
/** {@hide} */
interface IStyleInterface {
boolean setGlobalStyle(int style);
boolean setAccent(String pkgName);
Suggestion getSuggestion(in Bitmap source, in int[] colors);
}

View File

@@ -0,0 +1,199 @@
/**
* Copyright (c) 2015, The CyanogenMod Project
*
* 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 lineageos.style;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import lineageos.app.LineageContextConstants;
public class StyleInterface {
/**
* Global style: automatic (based on wallpaper) mode
*
* @see #setGlobalStyle
*/
public static final int STYLE_GLOBAL_AUTO_WALLPAPER = 0;
/**
* Global style: automatic (based on day time) mode
*
* @see #setGlobalStyle
*/
public static final int STYLE_GLOBAL_AUTO_DAYTIME = 1;
/**
* Global style: light
*
* @see #setGlobalStyle
*/
public static final int STYLE_GLOBAL_LIGHT = 2;
/**
* Global style: dark
*
* @see #setGlobalStyle
*/
public static final int STYLE_GLOBAL_DARK = 3;
/**
* Default accent
* Used to remove any active accent and use default one
*
* @see #setAccent
*/
public static final String ACCENT_DEFAULT = "lineageos";
/**
* Allows an application to change system style.
* This is a dangerous permission, your app must request
* it at runtime as any other dangerous permission
*/
public static final String CHANGE_STYLE_SETTINGS_PERMISSION =
"lineageos.permission.CHANGE_STYLE";
private static final String TAG = "StyleInterface";
private static IStyleInterface sService;
private static StyleInterface sInstance;
private Context mContext;
private StyleInterface(Context context) {
Context appContext = context.getApplicationContext();
if (appContext != null) {
mContext = appContext;
} else {
mContext = context;
}
sService = getService();
if (context.getPackageManager().hasSystemFeature(
LineageContextConstants.Features.STYLES) && sService == null) {
throw new RuntimeException("Unable to get StyleInterfaceService. The service" +
" either crashed, was not started, or the interface has been called to early" +
" in SystemServer init");
}
}
/**
* Get or create an instance of the {@link lineageos.app.StyleInterface}
* @param context
* @return {@link StyleInterface}
*/
public static StyleInterface getInstance(Context context) {
if (sInstance == null) {
sInstance = new StyleInterface(context);
}
return sInstance;
}
/** @hide **/
public static IStyleInterface getService() {
if (sService != null) {
return sService;
}
IBinder b = ServiceManager.getService(LineageContextConstants.LINEAGE_STYLE_INTERFACE);
sService = IStyleInterface.Stub.asInterface(b);
if (b != null) {
sService = IStyleInterface.Stub.asInterface(b);
return sService;
} else {
Log.e(TAG, "null service. SAD!");
return null;
}
}
/**
* Set global style.
*
* You will need {@link #CHANGE_STYLE_SETTINGS_PERMISSION}
* to utilize this functionality.
*
* @see #STYLE_GLOBAL_AUTO_WALLPAPER
* @see #STYLE_GLOBAL_AUTO_DAYTIME
* @see #STYLE_GLOBAL_LIGHT
* @see #STYLE_GLOBAL_DARK
* @param style The style mode to set the device to.
* One of {@link #STYLE_GLOBAL_AUTO_WALLPAPER},
* {@link #STYLE_GLOBAL_AUTO_DAYTIME},
* {@link #STYLE_GLOBAL_LIGHT} or
* {@link #STYLE_GLOBAL_DARK}
*/
public boolean setGlobalStyle(int style) {
if (sService == null) {
return false;
}
try {
return sService.setGlobalStyle(style);
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
return false;
}
/**
* Set color accent package.
*
* You will need {@link #CHANGE_STYLE_SETTINGS_PERMISSION}
* to utilize this functionality.
*
* @param pkgName The package name of the accent
*/
public boolean setAccent(String pkgName) {
if (sService == null) {
return false;
}
try {
return sService.setAccent(pkgName);
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
return false;
}
/**
* Get the best color that suites a bitmap object and the appropriate global style
*
* @param source The object you want the suggested color to be matched with
* @param colors A list of colors that the selection will be made from
*
* @return suggestion for global style + accent combination
*/
public Suggestion getSuggestion(Bitmap source, int[] colors) {
if (colors.length == 0) {
throw new IllegalArgumentException(
"The colors array argument must contain at least one element");
}
Suggestion fallback = new Suggestion(STYLE_GLOBAL_LIGHT, colors[0]);
if (sService == null) {
return fallback;
}
try {
return sService.getSuggestion(source, colors);
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
return fallback;
}
}

View File

@@ -0,0 +1,20 @@
/*
**
** Copyright (C) 2018 The LineageOS Project
**
** 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 lineageos.style;
parcelable Suggestion;

View File

@@ -0,0 +1,94 @@
/*
**
** Copyright (C) 2018 The LineageOS Project
**
** 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 lineageos.style;
import android.os.Parcel;
import android.os.Parcelable;
import lineageos.os.Build;
import lineageos.os.Concierge;
import lineageos.os.Concierge.ParcelInfo;
public class Suggestion implements Parcelable {
public final int globalStyle;
public final int selectedAccent;
/**
* Default constructor
*
* @see lineageos.style.StyleInterface#getSuggestion
*
* @param globalStyle one of {@link #STYLE_GLOBAL_LIGHT} or {@link #STYLE_GLOBAL_DARK}
* @param colorPosition position of selected color in the input array
*/
public Suggestion(int globalStyle, int selectedAccent) {
this.globalStyle = globalStyle;
this.selectedAccent = selectedAccent;
}
private Suggestion(Parcel parcel) {
ParcelInfo parcelInfo = Concierge.receiveParcel(parcel);
int parcelableVersion = parcelInfo.getParcelVersion();
if (parcelableVersion >= Build.LINEAGE_VERSION_CODES.HACKBERRY) {
globalStyle = parcel.readInt();
selectedAccent = parcel.readInt();
} else {
globalStyle = 0;
selectedAccent = 0;
}
// Complete parcel info for the concierge
parcelInfo.complete();
}
/** @hide */
public static final Parcelable.Creator<Suggestion> CREATOR =
new Parcelable.Creator<Suggestion>() {
@Override
public Suggestion createFromParcel(Parcel source) {
return new Suggestion(source);
}
@Override
public Suggestion[] newArray(int size) {
return new Suggestion[size];
}
};
/** @hide */
@Override
public int describeContents() {
return 0;
}
/** @hide */
@Override
public void writeToParcel(Parcel dest, int flags) {
// Tell the concierge to prepare the parcel
ParcelInfo parcelInfo = Concierge.prepareParcel(dest);
// ==== HACKBERRY ====
dest.writeInt(globalStyle);
dest.writeInt(selectedAccent);
// Complete parcel info for the concierge
parcelInfo.complete();
}
}