1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-12-25 18:15:49 +01:00

Amazfit Cor: support custom emoji font

This commit refactors code and implements a custom device specific string
filter, which does nothing by default.
The implementation in HuamiSupport does the custom emoji conversion.

The setting has been moved from devicesettings_amazfitbip.xml to an extra file
As soon as there is a custom font for Mi Band 2/3/4 it is sufficient to add
"devicesettings_custom_emoji_font.xml" to the list of supported settings
in the appropriate coordinator and everything will work.
This commit is contained in:
Andreas Shimokawa 2019-09-14 00:05:39 +02:00
parent aa8c41f722
commit 876515f1fd
12 changed files with 67 additions and 69 deletions

View File

@ -167,9 +167,6 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
@Override @Override
public boolean supportsUnicodeEmojis() { return false; } public boolean supportsUnicodeEmojis() { return false; }
@Override
public boolean supportsCustomFont() { return false; }
@Override @Override
public int[] getSupportedDeviceSpecificSettings(GBDevice device) { public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
return null; return null;

View File

@ -280,11 +280,6 @@ public interface DeviceCoordinator {
*/ */
boolean supportsUnicodeEmojis(); boolean supportsUnicodeEmojis();
/**
* Indicates whether the device supports using a custom font.
*/
boolean supportsCustomFont();
/** /**
* Indicates which device specific settings the device supports (not per device type or family, but unique per device). * Indicates which device specific settings the device supports (not per device type or family, but unique per device).
*/ */

View File

@ -77,15 +77,11 @@ public class AmazfitBipCoordinator extends HuamiCoordinator {
return true; return true;
} }
@Override
public boolean supportsCustomFont() {
return true;
}
@Override @Override
public int[] getSupportedDeviceSpecificSettings(GBDevice device) { public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
return new int[]{ return new int[]{
R.xml.devicesettings_amazfitbip, R.xml.devicesettings_amazfitbip,
R.xml.devicesettings_custom_emoji_font,
R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_liftwrist_display,
R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_disconnectnotification,
R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_expose_hr_thirdparty,

View File

@ -84,6 +84,7 @@ public class AmazfitCorCoordinator extends HuamiCoordinator {
public int[] getSupportedDeviceSpecificSettings(GBDevice device) { public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
return new int[]{ return new int[]{
R.xml.devicesettings_amazfitcor, R.xml.devicesettings_amazfitcor,
R.xml.devicesettings_custom_emoji_font,
R.xml.devicesettings_liftwrist_display, R.xml.devicesettings_liftwrist_display,
R.xml.devicesettings_disconnectnotification, R.xml.devicesettings_disconnectnotification,
R.xml.devicesettings_expose_hr_thirdparty, R.xml.devicesettings_expose_hr_thirdparty,

View File

@ -409,4 +409,8 @@ public abstract class AbstractDeviceSupport implements DeviceSupport {
LocalBroadcastManager.getInstance(context).sendBroadcast(messageIntent); LocalBroadcastManager.getInstance(context).sendBroadcast(messageIntent);
} }
public String customStringFilter(String inputString) {
return inputString;
}
} }

View File

@ -199,7 +199,6 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
private CMWeatherReceiver mCMWeatherReceiver = null; private CMWeatherReceiver mCMWeatherReceiver = null;
private LineageOsWeatherReceiver mLineageOsWeatherReceiver = null; private LineageOsWeatherReceiver mLineageOsWeatherReceiver = null;
private OmniJawsObserver mOmniJawsObserver = null; private OmniJawsObserver mOmniJawsObserver = null;
private Random mRandom = new Random();
private final String[] mMusicActions = { private final String[] mMusicActions = {
"com.android.music.metachanged", "com.android.music.metachanged",
@ -370,21 +369,9 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
if (text == null || text.length() == 0) if (text == null || text.length() == 0)
return text; return text;
text = mDeviceSupport.customStringFilter(text);
if (!mCoordinator.supportsUnicodeEmojis()) { if (!mCoordinator.supportsUnicodeEmojis()) {
// use custom font for emoji, if it is supported and enabled
if (mCoordinator.supportsCustomFont()) {
switch (mCoordinator.getDeviceType()) {
case AMAZFITBIP:
if (((HuamiCoordinator)mCoordinator).getUseCustomFont(mGBDevice.getAddress()))
return StringUtils.toCustomFont(text);
break;
// TODO: implement for Amazfit Cor
default:
break;
}
}
return EmojiConverter.convertUnicodeEmojiToAscii(text, getApplicationContext()); return EmojiConverter.convertUnicodeEmojiToAscii(text, getApplicationContext());
} }
@ -763,7 +750,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
if (mOmniJawsObserver == null && coordinator != null && coordinator.supportsWeather()) { if (mOmniJawsObserver == null && coordinator != null && coordinator.supportsWeather()) {
try { try {
mOmniJawsObserver = new OmniJawsObserver(new Handler()); mOmniJawsObserver = new OmniJawsObserver(new Handler());
getContentResolver().registerContentObserver(mOmniJawsObserver.WEATHER_URI, true, mOmniJawsObserver); getContentResolver().registerContentObserver(OmniJawsObserver.WEATHER_URI, true, mOmniJawsObserver);
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException e) {
//Nothing wrong, it just means we're not running on omnirom. //Nothing wrong, it just means we're not running on omnirom.
} }

View File

@ -130,4 +130,9 @@ public interface DeviceSupport extends EventHandler {
* Returns the Android context to use, e.g. to look up resources. * Returns the Android context to use, e.g. to look up resources.
*/ */
Context getContext(); Context getContext();
/**
* converts String in a device specific way, e.g. re-map characters for a custom font
*/
String customStringFilter(String inputString);
} }

View File

@ -113,6 +113,11 @@ public class ServiceDeviceSupport implements DeviceSupport {
return delegate.getContext(); return delegate.getContext();
} }
@Override
public String customStringFilter(String inputString) {
return delegate.customStringFilter(inputString);
}
@Override @Override
public boolean useAutoConnect() { public boolean useAutoConnect() {
return delegate.useAutoConnect(); return delegate.useAutoConnect();

View File

@ -127,6 +127,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils; import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
import nodomain.freeyourgadget.gadgetbridge.util.Version; import nodomain.freeyourgadget.gadgetbridge.util.Version;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_COUNT; import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.DEFAULT_VALUE_VIBRATION_COUNT;
@ -414,7 +415,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
int userid = alias.hashCode(); // hash from alias like mi1 int userid = alias.hashCode(); // hash from alias like mi1
// FIXME: Do encoding like in PebbleProtocol, this is ugly // FIXME: Do encoding like in PebbleProtocol, this is ugly
byte bytes[] = new byte[]{ byte[] bytes = new byte[]{
HuamiService.COMMAND_SET_USERINFO, HuamiService.COMMAND_SET_USERINFO,
0, 0,
0, 0,
@ -913,7 +914,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
} }
private byte[] getLatency(int minConnectionInterval, int maxConnectionInterval, int latency, int timeout, int advertisementInterval) { private byte[] getLatency(int minConnectionInterval, int maxConnectionInterval, int latency, int timeout, int advertisementInterval) {
byte result[] = new byte[12]; byte[] result = new byte[12];
result[0] = (byte) (minConnectionInterval & 0xff); result[0] = (byte) (minConnectionInterval & 0xff);
result[1] = (byte) (0xff & minConnectionInterval >> 8); result[1] = (byte) (0xff & minConnectionInterval >> 8);
result[2] = (byte) (maxConnectionInterval & 0xff); result[2] = (byte) (maxConnectionInterval & 0xff);
@ -2079,6 +2080,42 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
} }
} }
@Override
public String customStringFilter(String inputString) {
if (HuamiCoordinator.getUseCustomFont(gbDevice.getAddress())) {
return convertEmojiToCustomFont(inputString);
}
return inputString;
}
private String convertEmojiToCustomFont(String str) {
StringBuilder sb = new StringBuilder();
int i = 0;
while (i < str.length()) {
char charAt = str.charAt(i);
if (Character.isHighSurrogate(charAt)) {
int i2 = i + 1;
try {
int codePoint = Character.toCodePoint(charAt, str.charAt(i2));
if (codePoint < 127744 || codePoint > 129510) {
sb.append(charAt);
} else {
sb.append((char) (codePoint - 83712));
i = i2;
}
} catch (StringIndexOutOfBoundsException e) {
LOG.warn("error while converting emoji to custom font", e);
sb.append(charAt);
}
} else {
sb.append(charAt);
}
i++;
}
return sb.toString();
}
public void phase2Initialize(TransactionBuilder builder) { public void phase2Initialize(TransactionBuilder builder) {
LOG.info("phase2Initialize..."); LOG.info("phase2Initialize...");
requestBatteryInfo(builder); requestBatteryInfo(builder);

View File

@ -96,36 +96,4 @@ public class StringUtils {
} }
return ""; return "";
} }
/**
* @param str original text
* @return str with the emoticons in a format that can be displayed on an
* Amazfit Bip by using a custom font firmware with emoji support
*/
public static String toCustomFont(String str) {
StringBuilder sb = new StringBuilder();
int i = 0;
while (i < str.length()) {
char charAt = str.charAt(i);
if (Character.isHighSurrogate(charAt)) {
int i2 = i + 1;
try {
int codePoint = Character.toCodePoint(charAt, str.charAt(i2));
if (codePoint < 127744 || codePoint > 129510) {
sb.append(charAt);
} else {
sb.append(Character.toString((char) (codePoint - 83712)));
i = i2;
}
} catch (StringIndexOutOfBoundsException e) {
e.printStackTrace();
sb.append(charAt);
}
} else {
sb.append(charAt);
}
i++;
}
return sb.toString();
}
} }

View File

@ -17,10 +17,4 @@
android:key="language" android:key="language"
android:summary="%s" android:summary="%s"
android:title="@string/pref_title_language" /> android:title="@string/pref_title_language" />
<CheckBoxPreference
android:icon="@drawable/ic_font_download"
android:defaultValue="false"
android:key="use_custom_font"
android:summary="@string/pref_summary_use_custom_font"
android:title="@string/pref_title_use_custom_font" />
</androidx.preference.PreferenceScreen> </androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:defaultValue="false"
android:icon="@drawable/ic_font_download"
android:key="use_custom_font"
android:summary="@string/pref_summary_use_custom_font"
android:title="@string/pref_title_use_custom_font" />
</androidx.preference.PreferenceScreen>