diff --git a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlCallback.aidl b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlCallback.aidl index 1d7f954815..0598f31854 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlCallback.aidl +++ b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlCallback.aidl @@ -51,4 +51,9 @@ interface IOsmAndAidlCallback { * Callback for {@link IOsmAndAidlInterface} registerForVoiceRouterMessages() method. */ void onVoiceRouterNotify(in OnVoiceNavigationParams params); + + /** + * Callback for {@link IOsmAndAidlInterface} registerForKeyEvents() method. + */ + void onKeyEvent(in KeyEvent params); } \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl index 1b1433178a..c9974dd2c9 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl +++ b/OsmAnd-api/src/net/osmand/aidlapi/IOsmAndAidlInterface.aidl @@ -95,8 +95,11 @@ import net.osmand.aidlapi.mapmarker.RemoveMapMarkersParams; import net.osmand.aidlapi.quickaction.QuickActionParams; import net.osmand.aidlapi.quickaction.QuickActionInfoParams; + import net.osmand.aidlapi.lock.SetLockStateParams; +import net.osmand.aidlapi.events.AKeyEventsParams; + // NOTE: Add new methods at the end of file!!! interface IOsmAndAidlInterface { @@ -842,9 +845,19 @@ interface IOsmAndAidlInterface { boolean executeQuickAction(in QuickActionParams params); boolean getQuickActionsInfo(out List quickActions); + /** * Toggle Lock/Unlock screen. */ - boolean setLockState(in SetLockStateParams params); + + /** + * Method to register for key events. + * + * @params subscribeToUpdates (boolean) - boolean flag to subscribe or unsubscribe from key events + * @params callbackId (long) - id of callback, needed to unsubscribe key events + * @params callback (IOsmAndAidlCallback) - callback to notify user on key event + * @params keyEventList (List) - list of requested key events + */ + long registerForKeyEvents(in AKeyEventsParams params, IOsmAndAidlCallback callback); } \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.aidl b/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.aidl new file mode 100644 index 0000000000..972b2cb218 --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.aidl @@ -0,0 +1,2 @@ +package net.osmand.aidlapi.events; +parcelable AKeyEventsParams; \ No newline at end of file diff --git a/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.java b/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.java new file mode 100644 index 0000000000..83c4d4368e --- /dev/null +++ b/OsmAnd-api/src/net/osmand/aidlapi/events/AKeyEventsParams.java @@ -0,0 +1,73 @@ +package net.osmand.aidlapi.events; + +import android.os.Bundle; +import android.os.Parcel; +import android.os.Parcelable; + +import net.osmand.aidlapi.AidlParams; + +import java.util.ArrayList; + +public class AKeyEventsParams extends AidlParams { + + private long callbackId = -1L; + private boolean subscribeToUpdates = true; + private ArrayList keyEventList; + + public AKeyEventsParams() { + } + + protected AKeyEventsParams(Parcel in) { + readFromParcel(in); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public AKeyEventsParams createFromParcel(Parcel in) { + return new AKeyEventsParams(in); + } + + @Override + public AKeyEventsParams[] newArray(int size) { + return new AKeyEventsParams[size]; + } + }; + + public long getCallbackId() { + return callbackId; + } + + public void setCallbackId(long callbackId) { + this.callbackId = callbackId; + } + + public void setSubscribeToUpdates(boolean subscribeToUpdates) { + this.subscribeToUpdates = subscribeToUpdates; + } + + public boolean isSubscribeToUpdates() { + return subscribeToUpdates; + } + + public void setKeyEventList(ArrayList keyEventList) { + this.keyEventList = keyEventList; + } + + public ArrayList getKeyEventList() { + return keyEventList; + } + + @Override + protected void readFromBundle(Bundle bundle) { + callbackId = bundle.getLong("callbackId"); + subscribeToUpdates = bundle.getBoolean("subscribeToUpdates"); + keyEventList = bundle.getIntegerArrayList("keyEventList"); + } + + @Override + public void writeToBundle(Bundle bundle) { + bundle.putLong("callbackId", callbackId); + bundle.putBoolean("subscribeToUpdates", subscribeToUpdates); + bundle.putIntegerArrayList("keyEventList", keyEventList); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java index 10ff8ffd79..cc526f75ae 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlApi.java @@ -15,6 +15,7 @@ import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.ParcelFileDescriptor; +import android.view.KeyEvent; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -102,8 +103,10 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; @@ -131,6 +134,7 @@ public class OsmandAidlApi { public static final int KEY_ON_NAV_DATA_UPDATE = 2; public static final int KEY_ON_CONTEXT_MENU_BUTTONS_CLICK = 4; public static final int KEY_ON_VOICE_MESSAGE = 5; + public static final int KEY_ON_KEY_EVENT = 6; private static final Log LOG = PlatformUtil.getLog(OsmandAidlApi.class); @@ -2354,6 +2358,37 @@ public class OsmandAidlApi { a.points, a.wptPoints, a.wptCategoryNames); } + private Map> keyEventCallbacks = new ConcurrentHashMap<>(); + + public boolean onKeyEvent(KeyEvent event) { + if (aidlCallbackListenerV2 != null) { + for (Map.Entry entry : aidlCallbackListenerV2.getAidlCallbacks().entrySet()) { + OsmandAidlServiceV2.AidlCallbackParams cb = entry.getValue(); + if ((cb.getKey() & KEY_ON_KEY_EVENT) > 0) { + Set keyEventsList = keyEventCallbacks.get(entry.getKey()); + //An empty list means all key are requested + if (keyEventsList != null && (keyEventsList.isEmpty() || keyEventsList.contains(event.getKeyCode()))) { + try { + cb.getCallback().onKeyEvent(event); + return true; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + } + } + } + } + } + return false; + } + + void registerForKeyEvents(long id, ArrayList keyEventLst) { + keyEventCallbacks.put(id, new HashSet<>(keyEventLst)); + } + + public void unregisterFromKeyEvents(long id) { + keyEventCallbacks.remove(id); + } + public interface SearchCompleteCallback { void onSearchComplete(List resultSet); } diff --git a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java index 79ab219d9b..e8ca7291c2 100644 --- a/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java +++ b/OsmAnd/src/net/osmand/aidl/OsmandAidlServiceV2.java @@ -15,7 +15,6 @@ import net.osmand.PlatformUtil; import net.osmand.aidl.OsmandAidlApi.GpxBitmapCreatedCallback; import net.osmand.aidl.OsmandAidlApi.OsmandAppInitCallback; import net.osmand.aidl.OsmandAidlApi.SearchCompleteCallback; -import net.osmand.aidlapi.lock.SetLockStateParams; import net.osmand.aidlapi.IOsmAndAidlCallback; import net.osmand.aidlapi.IOsmAndAidlInterface; import net.osmand.aidlapi.calculateroute.CalculateRouteParams; @@ -28,6 +27,7 @@ import net.osmand.aidlapi.customization.OsmandSettingsInfoParams; import net.osmand.aidlapi.customization.OsmandSettingsParams; import net.osmand.aidlapi.customization.ProfileSettingsParams; import net.osmand.aidlapi.customization.SetWidgetsParams; +import net.osmand.aidlapi.events.AKeyEventsParams; import net.osmand.aidlapi.favorite.AFavorite; import net.osmand.aidlapi.favorite.AddFavoriteParams; import net.osmand.aidlapi.favorite.RemoveFavoriteParams; @@ -46,6 +46,7 @@ import net.osmand.aidlapi.gpx.RemoveGpxParams; import net.osmand.aidlapi.gpx.ShowGpxParams; import net.osmand.aidlapi.gpx.StartGpxRecordingParams; import net.osmand.aidlapi.gpx.StopGpxRecordingParams; +import net.osmand.aidlapi.lock.SetLockStateParams; import net.osmand.aidlapi.map.ALatLon; import net.osmand.aidlapi.map.SetMapLocationParams; import net.osmand.aidlapi.maplayer.AddMapLayerParams; @@ -88,8 +89,8 @@ import net.osmand.aidlapi.search.SearchParams; import net.osmand.aidlapi.search.SearchResult; import net.osmand.aidlapi.tiles.ASqliteDbFile; import net.osmand.data.LatLon; -import net.osmand.plus.settings.backend.OsmAndAppCustomization; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.settings.backend.OsmAndAppCustomization; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; @@ -101,6 +102,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import static net.osmand.aidl.OsmandAidlApi.KEY_ON_CONTEXT_MENU_BUTTONS_CLICK; +import static net.osmand.aidl.OsmandAidlApi.KEY_ON_KEY_EVENT; import static net.osmand.aidl.OsmandAidlApi.KEY_ON_NAV_DATA_UPDATE; import static net.osmand.aidl.OsmandAidlApi.KEY_ON_UPDATE; import static net.osmand.aidl.OsmandAidlApi.KEY_ON_VOICE_MESSAGE; @@ -1116,6 +1118,28 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener return UNKNOWN_API_ERROR; } } + @Override + public long registerForKeyEvents(AKeyEventsParams params, final IOsmAndAidlCallback callback) { + try { + OsmandAidlApi api = getApi("registerForKeyEvents"); + if (api != null) { + if (!params.isSubscribeToUpdates() && params.getCallbackId() != -1) { + api.unregisterFromKeyEvents(params.getCallbackId()); + removeAidlCallback(params.getCallbackId()); + return -1; + } else { + long id = addAidlCallback(callback, KEY_ON_KEY_EVENT); + api.registerForKeyEvents(id, params.getKeyEventList()); + return id; + } + } else { + return -1; + } + } catch (Exception e) { + handleException(e); + return UNKNOWN_API_ERROR; + } + } @Override public long addContextMenuButtons(ContextMenuButtonsParams params, final IOsmAndAidlCallback callback) { diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityKeyListener.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityKeyListener.java index be642ff80d..66bfc93a7b 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityKeyListener.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityKeyListener.java @@ -63,7 +63,7 @@ public class MapActivityKeyListener implements KeyEvent.Callback { } else if (mapScrollHelper.isScrollingDirectionKeyCode(keyCode)) { return mapScrollHelper.onKeyDown(keyCode, event); } - return false; + return app.getAidlApi().onKeyEvent(event); } @Override @@ -123,10 +123,10 @@ public class MapActivityKeyListener implements KeyEvent.Callback { mapActivity.changeZoom(1); return true; } - } else { - return OsmandPlugin.onMapActivityKeyUp(mapActivity, keyCode); + } else if (OsmandPlugin.onMapActivityKeyUp(mapActivity, keyCode)) { + return true; } - return false; + return app.getAidlApi().onKeyEvent(event); } @Override