diff --git a/Android.mk b/Android.mk index d8a54782..d5a04a7f 100644 --- a/Android.mk +++ b/Android.mk @@ -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 # ============================================================ diff --git a/api/lineage_current.txt b/api/lineage_current.txt index 35620dbe..094a2e7b 100644 --- a/api/lineage_current.txt +++ b/api/lineage_current.txt @@ -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 { diff --git a/lineage/lib/main/java/org/lineageos/platform/internal/StyleInterfaceService.java b/lineage/lib/main/java/org/lineageos/platform/internal/StyleInterfaceService.java new file mode 100644 index 00000000..aae442da --- /dev/null +++ b/lineage/lib/main/java/org/lineageos/platform/internal/StyleInterfaceService.java @@ -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; + } + }; +} \ No newline at end of file diff --git a/lineage/res/AndroidManifest.xml b/lineage/res/AndroidManifest.xml index 81b44a1e..f3a5346a 100644 --- a/lineage/res/AndroidManifest.xml +++ b/lineage/res/AndroidManifest.xml @@ -117,6 +117,13 @@ android:icon="@drawable/ic_launcher_lineageos" android:protectionLevel="normal" /> + + + org.lineageos.platform.internal.LineageWeatherManagerService org.lineageos.platform.internal.display.LiveDisplayService org.lineageos.platform.internal.LineageAudioService + org.lineageos.platform.internal.StyleInterfaceService diff --git a/lineage/res/res/values/strings.xml b/lineage/res/res/values/strings.xml index 5bb3549d..7c8c0b53 100644 --- a/lineage/res/res/values/strings.xml +++ b/lineage/res/res/values/strings.xml @@ -39,6 +39,10 @@ add and remove apps to protected apps Allows an app to mark other apps as protected and lock them. + + change system style + Allows an app customize the system colors. + Default diff --git a/sdk/src/java/lineageos/app/LineageContextConstants.java b/sdk/src/java/lineageos/app/LineageContextConstants.java index f113d6d6..640e308b 100644 --- a/sdk/src/java/lineageos/app/LineageContextConstants.java +++ b/sdk/src/java/lineageos/app/LineageContextConstants.java @@ -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"; } } diff --git a/sdk/src/java/lineageos/os/Build.java b/sdk/src/java/lineageos/os/Build.java index 42dc3128..67e1b56b 100644 --- a/sdk/src/java/lineageos/os/Build.java +++ b/sdk/src/java/lineageos/os/Build.java @@ -178,6 +178,11 @@ public class Build { /** * Unreleased preliminary version starting from LineageOS 15.1 + *

Applications targeting this or a later version will get access to these + * new features!

+ * */ public static final int HACKBERRY = 8; } diff --git a/sdk/src/java/lineageos/style/IStyleInterface.aidl b/sdk/src/java/lineageos/style/IStyleInterface.aidl new file mode 100644 index 00000000..a69c07c2 --- /dev/null +++ b/sdk/src/java/lineageos/style/IStyleInterface.aidl @@ -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); +} \ No newline at end of file diff --git a/sdk/src/java/lineageos/style/StyleInterface.java b/sdk/src/java/lineageos/style/StyleInterface.java new file mode 100644 index 00000000..cf6f7a91 --- /dev/null +++ b/sdk/src/java/lineageos/style/StyleInterface.java @@ -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; + } +} \ No newline at end of file diff --git a/sdk/src/java/lineageos/style/Suggestion.aidl b/sdk/src/java/lineageos/style/Suggestion.aidl new file mode 100644 index 00000000..242e6d12 --- /dev/null +++ b/sdk/src/java/lineageos/style/Suggestion.aidl @@ -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; diff --git a/sdk/src/java/lineageos/style/Suggestion.java b/sdk/src/java/lineageos/style/Suggestion.java new file mode 100644 index 00000000..cbb379cc --- /dev/null +++ b/sdk/src/java/lineageos/style/Suggestion.java @@ -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 CREATOR = + new Parcelable.Creator() { + + @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(); + } +}