sdk: Nuke Berry Styles
This is being ditched in favour of ThemePicker. Change-Id: I00c5faca452164d59b804cb64166edb83611f77d
This commit is contained in:
@@ -348,7 +348,6 @@ 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";
|
||||
@@ -989,35 +988,6 @@ package lineageos.providers {
|
||||
|
||||
}
|
||||
|
||||
package lineageos.style {
|
||||
|
||||
public class StyleInterface {
|
||||
method public java.lang.String getAccent();
|
||||
method public int getGlobalStyle();
|
||||
method public static lineageos.style.StyleInterface getInstance(android.content.Context);
|
||||
method public lineageos.style.Suggestion getSuggestion(android.graphics.Bitmap, int[]);
|
||||
method public java.util.List<java.lang.String> getTrustedAccents();
|
||||
method public boolean isDarkNow();
|
||||
method public boolean setAccent(java.lang.String);
|
||||
method public boolean setGlobalStyle(int, java.lang.String);
|
||||
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.trust {
|
||||
|
||||
public class TrustInterface {
|
||||
|
||||
@@ -1,393 +0,0 @@
|
||||
/*
|
||||
* 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.Context;
|
||||
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 com.android.server.SystemService;
|
||||
|
||||
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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** @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() {
|
||||
/* No-op */
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBootPhase(int phase) {
|
||||
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
|
||||
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");
|
||||
}
|
||||
|
||||
/* Public methods implementation */
|
||||
|
||||
private boolean setGlobalStyleInternal(int mode, String packageName) {
|
||||
// Check whether the packageName is valid
|
||||
if (isAValidPackage(packageName)) {
|
||||
throw new IllegalArgumentException(packageName + " is not a valid package name!");
|
||||
}
|
||||
|
||||
boolean statusValue = LineageSettings.System.putInt(mContext.getContentResolver(),
|
||||
LineageSettings.System.BERRY_GLOBAL_STYLE, mode);
|
||||
boolean packageNameValue = LineageSettings.System.putString(mContext.getContentResolver(),
|
||||
LineageSettings.System.BERRY_MANAGED_BY_APP, packageName);
|
||||
return statusValue && packageNameValue;
|
||||
}
|
||||
|
||||
private int getGlobalStyleInternal() {
|
||||
return LineageSettings.System.getInt(mContext.getContentResolver(),
|
||||
LineageSettings.System.BERRY_GLOBAL_STYLE,
|
||||
StyleInterface.STYLE_GLOBAL_AUTO_WALLPAPER);
|
||||
}
|
||||
|
||||
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 = getAccentInternal();
|
||||
|
||||
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 String getAccentInternal() {
|
||||
return LineageSettings.System.getString(mContext.getContentResolver(),
|
||||
LineageSettings.System.BERRY_CURRENT_ACCENT);
|
||||
}
|
||||
|
||||
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 List<String> getTrustedAccentsInternal() {
|
||||
List<String> results = new ArrayList<>();
|
||||
String[] packages = mContext.getResources()
|
||||
.getStringArray(R.array.trusted_accent_packages);
|
||||
|
||||
results.add(StyleInterface.ACCENT_DEFAULT);
|
||||
for (String item : packages) {
|
||||
if (isChangeableOverlay(item)) {
|
||||
results.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private boolean isDarkNowInternal() {
|
||||
String target = getDarkOverlayInternal();
|
||||
return isEnabled(target);
|
||||
}
|
||||
|
||||
private boolean setDarkOverlayInternal(String overlayName) {
|
||||
boolean isDefault = StyleInterface.OVERLAY_DARK_DEFAULT.equals(overlayName);
|
||||
boolean isBlack = StyleInterface.OVERLAY_DARK_BLACK.equals(overlayName);
|
||||
int userId = UserHandle.myUserId();
|
||||
|
||||
if (!isDefault && !isBlack) {
|
||||
Log.e(TAG, overlayName + " is not a valid dark overlay!");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
String currentDarkOverlay = LineageSettings.System.getString(
|
||||
mContext.getContentResolver(), LineageSettings.System.BERRY_DARK_OVERLAY,
|
||||
StyleInterface.OVERLAY_DARK_DEFAULT);
|
||||
if (isEnabled(currentDarkOverlay)) {
|
||||
// Swich dark overlays
|
||||
mOverlayService.setEnabled(currentDarkOverlay, false, userId);
|
||||
mOverlayService.setEnabled(overlayName, true, userId);
|
||||
}
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to change dark overlay");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getDarkOverlayInternal() {
|
||||
return LineageSettings.System.getString(mContext.getContentResolver(),
|
||||
LineageSettings.System.BERRY_DARK_OVERLAY, StyleInterface.OVERLAY_DARK_DEFAULT);
|
||||
}
|
||||
|
||||
/* Utils */
|
||||
|
||||
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.isStaticOverlayPackage() &&
|
||||
isValidAccent(pkgName);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEnabled(String pkgName) {
|
||||
int userId = UserHandle.myUserId();
|
||||
try {
|
||||
OverlayInfo info = mOverlayService.getOverlayInfo(pkgName, userId);
|
||||
return info.isEnabled();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage());
|
||||
}
|
||||
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 boolean isAValidPackage(String packageName) {
|
||||
try {
|
||||
return packageName != null && mPackageManager.getPackageInfo(packageName, 0) == null;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Binder */
|
||||
|
||||
private final IBinder mService = new IStyleInterface.Stub() {
|
||||
@Override
|
||||
public boolean setGlobalStyle(int style, String packageName) {
|
||||
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, packageName);
|
||||
restoreCallingIdentity(token);
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGlobalStyle() {
|
||||
/*
|
||||
* 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();
|
||||
int result = getGlobalStyleInternal();
|
||||
restoreCallingIdentity(token);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setAccent(String pkgName) {
|
||||
enforceChangeStylePermission();
|
||||
return setAccentInternal(pkgName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccent() {
|
||||
/*
|
||||
* 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();
|
||||
String result = getAccentInternal();
|
||||
restoreCallingIdentity(token);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Suggestion getSuggestion(Bitmap source, int[] colors) {
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTrustedAccents() {
|
||||
/*
|
||||
* 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();
|
||||
List<String> result = getTrustedAccentsInternal();
|
||||
restoreCallingIdentity(token);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDarkNow() {
|
||||
/*
|
||||
* 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 result = isDarkNowInternal();
|
||||
restoreCallingIdentity(token);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setDarkOverlay(String overlayName) {
|
||||
enforceChangeStylePermission();
|
||||
return setDarkOverlayInternal(overlayName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDarkOverlay() {
|
||||
/*
|
||||
* 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();
|
||||
String result = getDarkOverlayInternal();
|
||||
restoreCallingIdentity(token);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -39,13 +39,6 @@
|
||||
<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>
|
||||
<!-- this is wrong, but google's package manager uses the android:description
|
||||
attribute as description for the runtime permission request dialog
|
||||
with non-default dangerous permissions -->
|
||||
<string name="permdesc_changeStyle">customize the system colors</string>
|
||||
|
||||
<!-- Profiles -->
|
||||
<!-- Names of default profiles. -->
|
||||
<string name="profileNameDefault">Default</string>
|
||||
@@ -164,18 +157,6 @@
|
||||
<string name="kilobytespersecond_short">kB/s</string>
|
||||
<string name="megabytespersecond_short">MB/s</string>
|
||||
|
||||
<!-- Accent colors -->
|
||||
<string name="accent_black">Carbon</string>
|
||||
<string name="accent_blue">Blueberry</string>
|
||||
<string name="accent_brown">Cocoa</string>
|
||||
<string name="accent_cyan">Cyan</string>
|
||||
<string name="accent_green">Forest</string>
|
||||
<string name="accent_orange">Pumpkin</string>
|
||||
<string name="accent_pink">Cherry</string>
|
||||
<string name="accent_purple">Lavender</string>
|
||||
<string name="accent_red">Tomato</string>
|
||||
<string name="accent_yellow">Banana</string>
|
||||
|
||||
<!-- Trust interface -->
|
||||
<!-- This string will be referenced from other apps when they're referring to the Trust interface.
|
||||
Trust is a feature name, it's not suggested to translate this unless there are conflicts due
|
||||
|
||||
@@ -145,19 +145,6 @@
|
||||
<java-symbol type="string" name="kilobytespersecond_short" />
|
||||
<java-symbol type="string" name="megabytespersecond_short" />
|
||||
|
||||
<!-- Accent colors -->
|
||||
<java-symbol type="array" name="trusted_accent_packages" />
|
||||
<java-symbol type="string" name="accent_black" />
|
||||
<java-symbol type="string" name="accent_blue" />
|
||||
<java-symbol type="string" name="accent_brown" />
|
||||
<java-symbol type="string" name="accent_cyan" />
|
||||
<java-symbol type="string" name="accent_green" />
|
||||
<java-symbol type="string" name="accent_orange" />
|
||||
<java-symbol type="string" name="accent_pink" />
|
||||
<java-symbol type="string" name="accent_purple" />
|
||||
<java-symbol type="string" name="accent_red" />
|
||||
<java-symbol type="string" name="accent_yellow" />
|
||||
|
||||
<java-symbol type="array" name="config_vendorPlatformSignatures" />
|
||||
|
||||
<!-- Colors -->
|
||||
|
||||
@@ -1356,37 +1356,47 @@ public final class LineageSettings {
|
||||
* 1: time - based on LiveDisplay status
|
||||
* 2: force light
|
||||
* 3: force dark
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String BERRY_GLOBAL_STYLE = "berry_global_style";
|
||||
|
||||
/** @hide */
|
||||
@Deprecated
|
||||
public static final Validator BERRY_GLOBAL_STYLE_VALIDATOR =
|
||||
new InclusiveIntegerRangeValidator(0, 3);
|
||||
|
||||
/**
|
||||
* Current accent package name
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String BERRY_CURRENT_ACCENT = "berry_current_accent";
|
||||
|
||||
/** @hide */
|
||||
@Deprecated
|
||||
public static final Validator BERRY_CURRENT_ACCENT_VALIDATOR =
|
||||
sNonNullStringValidator;
|
||||
|
||||
/**
|
||||
* Current dark overlay package name
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String BERRY_DARK_OVERLAY = "berry_dark_overlay";
|
||||
|
||||
/** @hide */
|
||||
@Deprecated
|
||||
public static final Validator BERRY_DARK_OVERLAY_VALIDATOR =
|
||||
sNonNullStringValidator;
|
||||
|
||||
/**
|
||||
* Current application managing the style
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String BERRY_MANAGED_BY_APP = "berry_managed_by_app";
|
||||
|
||||
/** @hide */
|
||||
@Deprecated
|
||||
public static final Validator BERRY_MANAGED_BY_APP_VALIDATOR =
|
||||
sNonNullStringValidator;
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
**
|
||||
** 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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** {@hide} */
|
||||
interface IStyleInterface {
|
||||
boolean setGlobalStyle(int style, String pkgName);
|
||||
int getGlobalStyle();
|
||||
boolean setAccent(String pkgName);
|
||||
String getAccent();
|
||||
Suggestion getSuggestion(in Bitmap source, in int[] colors);
|
||||
List<String> getTrustedAccents();
|
||||
boolean isDarkNow();
|
||||
boolean setDarkOverlay(String overlayName);
|
||||
String getDarkOverlay();
|
||||
}
|
||||
@@ -1,352 +0,0 @@
|
||||
/**
|
||||
* 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.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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface used to customize the System colors. It's capable of setting a global
|
||||
* light and dark mode and custom color accents.
|
||||
*/
|
||||
|
||||
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 name.
|
||||
* It can also be used to remove any active accent
|
||||
*
|
||||
* @see #setAccent
|
||||
*/
|
||||
public static final String ACCENT_DEFAULT = "lineageos";
|
||||
|
||||
/**
|
||||
* Dark style: default
|
||||
*
|
||||
* @see #setDarkOverlay
|
||||
* @hide
|
||||
*/
|
||||
public static final String OVERLAY_DARK_DEFAULT = "org.lineageos.overlay.dark";
|
||||
|
||||
/**
|
||||
* Dark style: black
|
||||
*
|
||||
* @see #setDarkOverlay
|
||||
* @hide
|
||||
*/
|
||||
public static final String OVERLAY_DARK_BLACK = "org.lineageos.overlay.black";
|
||||
|
||||
/**
|
||||
* 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 =
|
||||
"android.permission.CHANGE_OVERLAY_PACKAGES";
|
||||
|
||||
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.style.StyleInterface}
|
||||
*
|
||||
* @param context Used to get the service
|
||||
* @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}
|
||||
* @param pkgName The package name of the calling application
|
||||
*
|
||||
* @return Whether the process failed
|
||||
*/
|
||||
public boolean setGlobalStyle(int style, String pkgName) {
|
||||
if (sService == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return sService.setGlobalStyle(style, pkgName);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage(), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current global style.
|
||||
*
|
||||
* @return One of {@link #STYLE_GLOBAL_AUTO_WALLPAPER},
|
||||
* {@link #STYLE_GLOBAL_AUTO_DAYTIME},
|
||||
* {@link #STYLE_GLOBAL_LIGHT} or
|
||||
* {@link #STYLE_GLOBAL_DARK}
|
||||
*/
|
||||
public int getGlobalStyle() {
|
||||
if (sService == null) {
|
||||
return STYLE_GLOBAL_AUTO_WALLPAPER;
|
||||
}
|
||||
try {
|
||||
return sService.getGlobalStyle();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage(), e);
|
||||
}
|
||||
return STYLE_GLOBAL_AUTO_WALLPAPER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set color accent package.
|
||||
*
|
||||
* You will need {@link #CHANGE_STYLE_SETTINGS_PERMISSION}
|
||||
* to utilize this functionality.
|
||||
*
|
||||
* @param pkgName The package name of the accent
|
||||
*
|
||||
* @return Whether the process failed
|
||||
*/
|
||||
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 current accent package.
|
||||
*
|
||||
* @return The current accent package name. Defaults to {#ACCENT_DEFAULT}
|
||||
*/
|
||||
public String getAccent() {
|
||||
if (sService == null) {
|
||||
return ACCENT_DEFAULT;
|
||||
}
|
||||
try {
|
||||
return sService.getAccent();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage(), e);
|
||||
}
|
||||
return ACCENT_DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of trusted accents that are included in the build.
|
||||
*
|
||||
* The first element (if any) is the default accent.
|
||||
*
|
||||
* @see #setAccent
|
||||
*
|
||||
* @return A list of accents package names that can be used with {#setAccent}.
|
||||
*/
|
||||
public List<String> getTrustedAccents() {
|
||||
if (sService == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
try {
|
||||
return sService.getTrustedAccents();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage(), e);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 A {@link lineageos.style.Suggestion} which holds the best 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the dark style is being used right now,
|
||||
* regardless of the current global style mode.
|
||||
*
|
||||
* @return Returns true if dark style is enabled
|
||||
*/
|
||||
public boolean isDarkNow() {
|
||||
if (sService == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return sService.isDarkNow();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage(), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set dark overlay package.
|
||||
*
|
||||
* You will need {@link #CHANGE_STYLE_SETTINGS_PERMISSION}
|
||||
* to utilize this functionality.
|
||||
*
|
||||
* @see #OVERLAY_DARK_DEFAULT
|
||||
* @see #OVERLAY_DARK_BLACK
|
||||
* @param overlayName The package name of the overlay.
|
||||
* One of {@link #OVERLAY_DARK_DEFAULT} or
|
||||
* {@link #OVERLAY_DARK_BLACK},
|
||||
*
|
||||
* @return Whether the process failed
|
||||
* @hide
|
||||
*/
|
||||
public boolean setDarkOverlay(String overlayName) {
|
||||
if (sService == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return sService.setDarkOverlay(overlayName);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage(), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current dark overlay package name.
|
||||
*
|
||||
* @see #OVERLAY_DARK_DEFAULT
|
||||
* @see #OVERLAY_DARK_BLACK
|
||||
* @@return {@link #OVERLAY_DARK_DEFAULT} or {@link #OVERLAY_DARK_BLACK}
|
||||
* @hide
|
||||
*/
|
||||
public String getDarkOverlay() {
|
||||
if (sService == null) {
|
||||
return OVERLAY_DARK_DEFAULT;
|
||||
}
|
||||
try {
|
||||
return sService.getDarkOverlay();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, e.getLocalizedMessage(), e);
|
||||
}
|
||||
return OVERLAY_DARK_DEFAULT;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
**
|
||||
** 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;
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
**
|
||||
** 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;
|
||||
|
||||
/**
|
||||
* Style suggestion holder class.
|
||||
* This is returned when calling {@link #lineageos.style.StyleInterface#getSuggestion}
|
||||
*/
|
||||
public class Suggestion implements Parcelable {
|
||||
public final int globalStyle;
|
||||
public final int selectedAccent;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @see {@link lineageos.style.StyleInterface#getSuggestion}
|
||||
*
|
||||
* @param globalStyle One of {@link #lineageos.style.StyleInterface#STYLE_GLOBAL_LIGHT} or
|
||||
* {@link #lineageos.style.StyleInterface#STYLE_GLOBAL_DARK}
|
||||
* @param selectedAccent The position of the 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