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!
+ *
+ * - Change system colors via {@link lineageos.app.StyleInterface}
+ *
*/
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();
+ }
+}