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:
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
28
sdk/src/java/lineageos/style/IStyleInterface.aidl
Normal file
28
sdk/src/java/lineageos/style/IStyleInterface.aidl
Normal 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);
|
||||
}
|
||||
199
sdk/src/java/lineageos/style/StyleInterface.java
Normal file
199
sdk/src/java/lineageos/style/StyleInterface.java
Normal 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;
|
||||
}
|
||||
}
|
||||
20
sdk/src/java/lineageos/style/Suggestion.aidl
Normal file
20
sdk/src/java/lineageos/style/Suggestion.aidl
Normal 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;
|
||||
94
sdk/src/java/lineageos/style/Suggestion.java
Normal file
94
sdk/src/java/lineageos/style/Suggestion.java
Normal 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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user