1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-12-05 00:12:56 +01:00
Gadgetbridge/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java

442 lines
16 KiB
Java
Raw Normal View History

2019-02-13 20:43:30 +01:00
/* Copyright (C) 2015-2019 Alberto, Andreas Shimokawa, Carsten Pfeiffer,
criogenic, dakhnod, Daniele Gobbetti, Frank Slezak, ivanovlev, José Rebelo,
Julien Pivotto, Kasha, Roi Greenberg, Steffen Liebergeld
2017-03-10 14:53:19 +01:00
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.impl;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import java.util.ArrayList;
import java.util.UUID;
import androidx.annotation.Nullable;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
import nodomain.freeyourgadget.gadgetbridge.util.LanguageUtils;
2018-09-04 01:00:14 +02:00
import nodomain.freeyourgadget.gadgetbridge.util.RtlUtils;
import static nodomain.freeyourgadget.gadgetbridge.util.JavaExtensions.coalesce;
2018-09-04 01:00:14 +02:00
public class GBDeviceService implements DeviceService {
protected final Context mContext;
private final Class<? extends Service> mServiceClass;
private final String[] transliterationExtras = new String[]{
EXTRA_NOTIFICATION_PHONENUMBER,
EXTRA_NOTIFICATION_SENDER,
EXTRA_NOTIFICATION_SUBJECT,
EXTRA_NOTIFICATION_TITLE,
EXTRA_NOTIFICATION_BODY,
EXTRA_NOTIFICATION_SOURCENAME,
EXTRA_CALL_PHONENUMBER,
EXTRA_CALL_DISPLAYNAME,
EXTRA_MUSIC_ARTIST,
EXTRA_MUSIC_ALBUM,
EXTRA_MUSIC_TRACK,
EXTRA_CALENDAREVENT_TITLE,
EXTRA_CALENDAREVENT_DESCRIPTION
};
public GBDeviceService(Context context) {
mContext = context;
mServiceClass = DeviceCommunicationService.class;
}
protected Intent createIntent() {
return new Intent(mContext, mServiceClass);
}
protected void invokeService(Intent intent) {
if (LanguageUtils.transliterate()) {
for (String extra : transliterationExtras) {
if (intent.hasExtra(extra)) {
intent.putExtra(extra, LanguageUtils.transliterate(intent.getStringExtra(extra)));
}
}
}
2018-09-04 01:00:14 +02:00
if (RtlUtils.rtlSupport()) {
2018-08-21 20:27:00 +02:00
for (String extra : transliterationExtras) {
if (intent.hasExtra(extra)) {
2018-09-04 01:00:14 +02:00
intent.putExtra(extra, RtlUtils.fixRtl(intent.getStringExtra(extra)));
2018-08-21 20:27:00 +02:00
}
}
}
mContext.startService(intent);
}
protected void stopService(Intent intent) {
mContext.stopService(intent);
}
@Override
public void start() {
Intent intent = createIntent().setAction(ACTION_START);
invokeService(intent);
}
@Override
public void connect() {
connect(null, false);
}
@Override
public void connect(@Nullable GBDevice device) {
connect(device, false);
}
@Override
public void connect(@Nullable GBDevice device, boolean firstTime) {
Intent intent = createIntent().setAction(ACTION_CONNECT)
.putExtra(GBDevice.EXTRA_DEVICE, device)
.putExtra(EXTRA_CONNECT_FIRST_TIME, firstTime);
invokeService(intent);
}
@Override
public void disconnect() {
Intent intent = createIntent().setAction(ACTION_DISCONNECT);
invokeService(intent);
}
@Override
public void quit() {
Intent intent = createIntent();
stopService(intent);
}
@Override
public void requestDeviceInfo() {
Intent intent = createIntent().setAction(ACTION_REQUEST_DEVICEINFO);
invokeService(intent);
}
@Override
public void onNotification(NotificationSpec notificationSpec) {
Intent intent = createIntent().setAction(ACTION_NOTIFICATION)
.putExtra(EXTRA_NOTIFICATION_FLAGS, notificationSpec.flags)
.putExtra(EXTRA_NOTIFICATION_PHONENUMBER, notificationSpec.phoneNumber)
.putExtra(EXTRA_NOTIFICATION_SENDER, coalesce(notificationSpec.sender, getContactDisplayNameByNumber(notificationSpec.phoneNumber)))
.putExtra(EXTRA_NOTIFICATION_SUBJECT, notificationSpec.subject)
.putExtra(EXTRA_NOTIFICATION_TITLE, notificationSpec.title)
.putExtra(EXTRA_NOTIFICATION_BODY, notificationSpec.body)
.putExtra(EXTRA_NOTIFICATION_ID, notificationSpec.getId())
.putExtra(EXTRA_NOTIFICATION_TYPE, notificationSpec.type)
.putExtra(EXTRA_NOTIFICATION_ACTIONS, notificationSpec.attachedActions)
.putExtra(EXTRA_NOTIFICATION_SOURCENAME, notificationSpec.sourceName)
2018-07-23 02:24:38 +02:00
.putExtra(EXTRA_NOTIFICATION_PEBBLE_COLOR, notificationSpec.pebbleColor)
.putExtra(EXTRA_NOTIFICATION_SOURCEAPPID, notificationSpec.sourceAppId);
invokeService(intent);
}
@Override
public void onDeleteNotification(int id) {
Intent intent = createIntent().setAction(ACTION_DELETE_NOTIFICATION)
.putExtra(EXTRA_NOTIFICATION_ID, id);
invokeService(intent);
}
@Override
public void onSetTime() {
Intent intent = createIntent().setAction(ACTION_SETTIME);
invokeService(intent);
}
@Override
public void onSetAlarms(ArrayList<? extends Alarm> alarms) {
Intent intent = createIntent().setAction(ACTION_SET_ALARMS)
.putExtra(EXTRA_ALARMS, alarms);
invokeService(intent);
}
@Override
public void onSetCallState(CallSpec callSpec) {
Context context = GBApplication.getContext();
String currentPrivacyMode = GBApplication.getPrefs().getString("pref_call_privacy_mode", GBApplication.getContext().getString(R.string.p_call_privacy_mode_off));
2018-01-30 22:44:27 +01:00
if (currentPrivacyMode.equals(context.getString(R.string.p_call_privacy_mode_name))) {
callSpec.name = callSpec.number;
2018-01-30 22:44:27 +01:00
} else if (currentPrivacyMode.equals(context.getString(R.string.p_call_privacy_mode_complete))) {
callSpec.number = null;
callSpec.name = null;
2018-01-30 22:44:27 +01:00
} else if (currentPrivacyMode.equals(context.getString(R.string.p_call_privacy_mode_number))){
callSpec.name = coalesce(callSpec.name, getContactDisplayNameByNumber(callSpec.number));
if (callSpec.name != null && !callSpec.name.equals(callSpec.number)) {
callSpec.number = null;
}
} else {
callSpec.name = coalesce(callSpec.name, getContactDisplayNameByNumber(callSpec.number));
}
Intent intent = createIntent().setAction(ACTION_CALLSTATE)
.putExtra(EXTRA_CALL_PHONENUMBER, callSpec.number)
.putExtra(EXTRA_CALL_DISPLAYNAME, callSpec.name)
.putExtra(EXTRA_CALL_COMMAND, callSpec.command);
invokeService(intent);
}
@Override
public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) {
Intent intent = createIntent().setAction(ACTION_SETCANNEDMESSAGES)
.putExtra(EXTRA_CANNEDMESSAGES_TYPE, cannedMessagesSpec.type)
.putExtra(EXTRA_CANNEDMESSAGES, cannedMessagesSpec.cannedMessages);
invokeService(intent);
}
@Override
public void onSetMusicState(MusicStateSpec stateSpec) {
Intent intent = createIntent().setAction(ACTION_SETMUSICSTATE)
.putExtra(EXTRA_MUSIC_REPEAT, stateSpec.repeat)
.putExtra(EXTRA_MUSIC_RATE, stateSpec.playRate)
.putExtra(EXTRA_MUSIC_STATE, stateSpec.state)
.putExtra(EXTRA_MUSIC_SHUFFLE, stateSpec.shuffle)
.putExtra(EXTRA_MUSIC_POSITION, stateSpec.position);
invokeService(intent);
}
@Override
public void onSetMusicInfo(MusicSpec musicSpec) {
Intent intent = createIntent().setAction(ACTION_SETMUSICINFO)
.putExtra(EXTRA_MUSIC_ARTIST, musicSpec.artist)
.putExtra(EXTRA_MUSIC_ALBUM, musicSpec.album)
.putExtra(EXTRA_MUSIC_TRACK, musicSpec.track)
.putExtra(EXTRA_MUSIC_DURATION, musicSpec.duration)
.putExtra(EXTRA_MUSIC_TRACKCOUNT, musicSpec.trackCount)
.putExtra(EXTRA_MUSIC_TRACKNR, musicSpec.trackNr);
invokeService(intent);
}
@Override
public void onInstallApp(Uri uri) {
Intent intent = createIntent().setAction(ACTION_INSTALL)
.putExtra(EXTRA_URI, uri);
invokeService(intent);
}
@Override
public void onAppInfoReq() {
Intent intent = createIntent().setAction(ACTION_REQUEST_APPINFO);
invokeService(intent);
}
@Override
public void onAppStart(UUID uuid, boolean start) {
Intent intent = createIntent().setAction(ACTION_STARTAPP)
.putExtra(EXTRA_APP_UUID, uuid)
.putExtra(EXTRA_APP_START, start);
invokeService(intent);
}
@Override
public void onAppDelete(UUID uuid) {
Intent intent = createIntent().setAction(ACTION_DELETEAPP)
.putExtra(EXTRA_APP_UUID, uuid);
invokeService(intent);
}
@Override
public void onAppConfiguration(UUID uuid, String config, Integer id) {
Intent intent = createIntent().setAction(ACTION_APP_CONFIGURE)
.putExtra(EXTRA_APP_UUID, uuid)
.putExtra(EXTRA_APP_CONFIG, config);
if (id != null) {
intent.putExtra(EXTRA_APP_CONFIG_ID, id);
}
invokeService(intent);
}
@Override
public void onAppReorder(UUID[] uuids) {
Intent intent = createIntent().setAction(ACTION_APP_REORDER)
.putExtra(EXTRA_APP_UUID, uuids);
invokeService(intent);
}
@Override
public void onFetchRecordedData(int dataTypes) {
Intent intent = createIntent().setAction(ACTION_FETCH_RECORDED_DATA)
.putExtra(EXTRA_RECORDED_DATA_TYPES, dataTypes);
invokeService(intent);
}
@Override
public void onReset(int flags) {
Intent intent = createIntent().setAction(ACTION_RESET)
.putExtra(EXTRA_RESET_FLAGS, flags);
invokeService(intent);
}
@Override
2016-02-29 22:05:29 +01:00
public void onHeartRateTest() {
Intent intent = createIntent().setAction(ACTION_HEARTRATE_TEST);
invokeService(intent);
}
@Override
public void onFindDevice(boolean start) {
Intent intent = createIntent().setAction(ACTION_FIND_DEVICE)
.putExtra(EXTRA_FIND_START, start);
invokeService(intent);
}
@Override
public void onSetConstantVibration(int intensity) {
Intent intent = createIntent().setAction(ACTION_SET_CONSTANT_VIBRATION)
.putExtra(EXTRA_VIBRATION_INTENSITY, intensity);
invokeService(intent);
}
@Override
public void onScreenshotReq() {
Intent intent = createIntent().setAction(ACTION_REQUEST_SCREENSHOT);
invokeService(intent);
}
@Override
public void onEnableRealtimeSteps(boolean enable) {
Intent intent = createIntent().setAction(ACTION_ENABLE_REALTIME_STEPS)
.putExtra(EXTRA_BOOLEAN_ENABLE, enable);
invokeService(intent);
}
@Override
public void onEnableHeartRateSleepSupport(boolean enable) {
Intent intent = createIntent().setAction(ACTION_ENABLE_HEARTRATE_SLEEP_SUPPORT)
.putExtra(EXTRA_BOOLEAN_ENABLE, enable);
invokeService(intent);
}
@Override
public void onSetHeartRateMeasurementInterval(int seconds) {
Intent intent = createIntent().setAction(ACTION_SET_HEARTRATE_MEASUREMENT_INTERVAL)
.putExtra(EXTRA_INTERVAL_SECONDS, seconds);
invokeService(intent);
}
@Override
public void onEnableRealtimeHeartRateMeasurement(boolean enable) {
Intent intent = createIntent().setAction(ACTION_ENABLE_REALTIME_HEARTRATE_MEASUREMENT)
.putExtra(EXTRA_BOOLEAN_ENABLE, enable);
invokeService(intent);
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
Intent intent = createIntent().setAction(ACTION_ADD_CALENDAREVENT)
.putExtra(EXTRA_CALENDAREVENT_ID, calendarEventSpec.id)
.putExtra(EXTRA_CALENDAREVENT_TYPE, calendarEventSpec.type)
.putExtra(EXTRA_CALENDAREVENT_TIMESTAMP, calendarEventSpec.timestamp)
.putExtra(EXTRA_CALENDAREVENT_DURATION, calendarEventSpec.durationInSeconds)
.putExtra(EXTRA_CALENDAREVENT_TITLE, calendarEventSpec.title)
.putExtra(EXTRA_CALENDAREVENT_DESCRIPTION, calendarEventSpec.description)
.putExtra(EXTRA_CALENDAREVENT_LOCATION, calendarEventSpec.location);
invokeService(intent);
}
@Override
public void onDeleteCalendarEvent(byte type, long id) {
Intent intent = createIntent().setAction(ACTION_DELETE_CALENDAREVENT)
.putExtra(EXTRA_CALENDAREVENT_TYPE, type)
.putExtra(EXTRA_CALENDAREVENT_ID, id);
invokeService(intent);
}
@Override
public void onSendConfiguration(String config) {
Intent intent = createIntent().setAction(ACTION_SEND_CONFIGURATION)
.putExtra(EXTRA_CONFIG, config);
invokeService(intent);
}
@Override
public void onReadConfiguration(String config) {
Intent intent = createIntent().setAction(ACTION_READ_CONFIGURATION)
.putExtra(EXTRA_CONFIG, config);
invokeService(intent);
}
@Override
public void onTestNewFunction() {
Intent intent = createIntent().setAction(ACTION_TEST_NEW_FUNCTION);
invokeService(intent);
}
@Override
public void onSendWeather(WeatherSpec weatherSpec) {
Intent intent = createIntent().setAction(ACTION_SEND_WEATHER)
.putExtra(EXTRA_WEATHER, weatherSpec);
invokeService(intent);
}
/**
* Returns contact DisplayName by call number
*
* @param number contact number
* @return contact DisplayName, if found it
*/
private String getContactDisplayNameByNumber(String number) {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
String name = number;
if (number == null || number.equals("")) {
return name;
}
try (Cursor contactLookup = mContext.getContentResolver().query(uri, null, null, null, null)) {
if (contactLookup != null && contactLookup.getCount() > 0) {
contactLookup.moveToNext();
name = contactLookup.getString(contactLookup.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
}
} catch (SecurityException e) {
// ignore, just return name below
}
return name;
}
@Override
public void onSetFmFrequency(float frequency) {
Intent intent = createIntent().setAction(ACTION_SET_FM_FREQUENCY)
.putExtra(EXTRA_FM_FREQUENCY, frequency);
invokeService(intent);
}
@Override
public void onSetLedColor(int color) {
Intent intent = createIntent().setAction(ACTION_SET_LED_COLOR)
.putExtra(EXTRA_LED_COLOR, color);
invokeService(intent);
}
}