Skip to content

Commit

Permalink
Add lock screen quick action
Browse files Browse the repository at this point in the history
  • Loading branch information
0xRe1nk0 committed Sep 25, 2024
1 parent 0fca921 commit 50883fb
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 1 deletion.
2 changes: 2 additions & 0 deletions OsmAnd/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
- For wording and consistency, please note https://docs.osmand.net/docs/technical/contributions/translating-osmand
Thx - Hardy
-->
<string name="lock_screen_description">Enables or disables touch screen functionality to prevent accidental taps</string>
<string name="lock_screen">Lock screen</string>
<string name="unit_volt">V</string>
<string name="wikimedia">Wikimedia</string>
<string name="open_in_browser">Open in browser</string>
Expand Down
4 changes: 4 additions & 0 deletions OsmAnd/src/net/osmand/plus/activities/MapActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -1365,6 +1365,10 @@ public boolean isDrawerAvailable() {

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (app.getLockHelper().isScreenLocked()) {
return app.getLockHelper().getLockGestureDetector(this).onTouchEvent(event);
}

if (settings.DO_NOT_USE_ANIMATIONS.get()) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
Expand Down
11 changes: 11 additions & 0 deletions OsmAnd/src/net/osmand/plus/helpers/AndroidUiHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.util.DisplayMetrics;
Expand Down Expand Up @@ -111,6 +112,16 @@ public static int getScreenOrientation(@NonNull Activity activity) {
return orientation;
}

public static boolean isViewInBounds(@NonNull View view, float x, float y){
Rect outRect = new Rect();
int[] location = new int[2];

view.getDrawingRect(outRect);
view.getLocationOnScreen(location);
outRect.offset(location[0], location[1]);
return outRect.contains((int) x, (int) y);
}

public static boolean updateVisibility(@Nullable View view, boolean visible) {
if (view != null && visible != (view.getVisibility() == View.VISIBLE)) {
if (visible) {
Expand Down
107 changes: 107 additions & 0 deletions OsmAnd/src/net/osmand/plus/helpers/LockHelper.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package net.osmand.plus.helpers;

import static net.osmand.plus.helpers.AndroidUiHelper.isViewInBounds;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
Expand All @@ -11,16 +13,24 @@
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.provider.Settings;
import android.view.GestureDetector;
import android.view.MotionEvent;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import net.osmand.PlatformUtil;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.quickaction.actions.LockScreenAction;
import net.osmand.plus.settings.backend.OsmAndAppCustomization.OsmAndAppCustomizationListener;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.backend.preferences.CommonPreference;
import net.osmand.plus.routing.VoiceRouter.VoiceMessageListener;
import net.osmand.plus.views.controls.maphudbuttons.QuickActionButton;
import net.osmand.plus.views.layers.MapQuickActionLayer;
import net.osmand.plus.views.mapwidgets.configure.buttons.QuickActionButtonState;

import org.apache.commons.logging.Log;

Expand All @@ -32,6 +42,8 @@ public class LockHelper implements SensorEventListener {

private static final int SENSOR_SENSITIVITY = 4;

private static boolean LOCK_SCREEN = false;

@Nullable
private WakeLock wakeLock;

Expand All @@ -47,6 +59,7 @@ public class LockHelper implements SensorEventListener {
private LockUIAdapter lockUIAdapter;
private final Runnable lockRunnable;
private final VoiceMessageListener voiceMessageListener;
private LockGestureDetector gestureDetector;

public interface LockUIAdapter {

Expand Down Expand Up @@ -123,6 +136,14 @@ public void lock() {
}
}

public void toggleLockScreen(){
LOCK_SCREEN = !LOCK_SCREEN;
}

public boolean isScreenLocked(){
return LOCK_SCREEN;
}

private void timedUnlock(long millis) {
uiHandler.removeCallbacks(lockRunnable);
if (wakeLock == null) {
Expand Down Expand Up @@ -201,4 +222,90 @@ public void onStop(@NonNull Activity activity) {
public void setLockUIAdapter(@Nullable LockUIAdapter adapter) {
lockUIAdapter = adapter;
}

public GestureDetector getLockGestureDetector(@NonNull MapActivity mapActivity) {
if (gestureDetector == null) {
gestureDetector = new LockGestureDetector(mapActivity, new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(@NonNull MotionEvent e) {
return false;
}

@Override
public void onShowPress(@NonNull MotionEvent e) {

}

@Override
public boolean onSingleTapUp(@NonNull MotionEvent e) {
QuickActionButton actionButton = getPressedQuickActionButton(mapActivity, e);
if (actionButton != null) {
actionButton.performClick();
return true;
}
return false;
}

@Override
public boolean onScroll(@Nullable MotionEvent e1, @NonNull MotionEvent e2, float distanceX, float distanceY) {
return false;
}

@Override
public void onLongPress(@NonNull MotionEvent e) {

}

@Override
public boolean onFling(@Nullable MotionEvent e1, @NonNull MotionEvent e2, float velocityX, float velocityY) {
return false;
}
});
}

return gestureDetector;
}

public class LockGestureDetector extends GestureDetector {
private final MapActivity mapActivity;
private QuickActionButton pressedActionButton;

public LockGestureDetector(@NonNull MapActivity mapActivity, @NonNull OnGestureListener listener) {
super(mapActivity, listener);
this.mapActivity = mapActivity;
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
pressedActionButton = getPressedQuickActionButton(mapActivity, ev);
if (pressedActionButton != null) {
pressedActionButton.setPressed(true);
}
} else if (ev.getAction() == MotionEvent.ACTION_UP) {
if (pressedActionButton != null) {
pressedActionButton.setPressed(false);
}
}
return super.onTouchEvent(ev);
}
}

private QuickActionButton getPressedQuickActionButton(@NonNull MapActivity mapActivity, @NonNull MotionEvent ev) {
float x = ev.getX();
float y = ev.getY();

MapQuickActionLayer quickActionLayer = mapActivity.getMapLayers().getMapQuickActionLayer();
for (QuickActionButton actionButton : quickActionLayer.getActionButtons()) {
QuickActionButtonState buttonState = actionButton.getButtonState();
if (buttonState != null) {
for (QuickAction action : buttonState.getQuickActions()) {
if (action instanceof LockScreenAction && isViewInBounds(actionButton, x, y)) {
return actionButton;
}
}
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ public void updateActionTypes() {
allTypes.add(OpenSearchViewAction.TYPE);
allTypes.add(ShowHideDrawerAction.TYPE);
allTypes.add(NavigatePreviousScreenAction.TYPE);
allTypes.add(LockScreenAction.TYPE);

List<QuickActionType> enabledTypes = new ArrayList<>(allTypes);
PluginsHelper.registerQuickActionTypesPlugins(allTypes, enabledTypes);
Expand Down
1 change: 1 addition & 0 deletions OsmAnd/src/net/osmand/plus/quickaction/QuickActionIds.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,5 @@ public class QuickActionIds {
public static final int OPEN_SEARCH_VIEW_ACTION = 70;
public static final int SHOW_HIDE_DRAWER_ACTION = 71;
public static final int NAVIGATE_PREVIOUS_SCREEN_ACTION = 72;
public static final int LOCK_SCREEN_ACTION = 73;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package net.osmand.plus.quickaction.actions;

import static net.osmand.plus.quickaction.QuickActionIds.LOCK_SCREEN_ACTION;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;

import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.quickaction.QuickActionType;

public class LockScreenAction extends QuickAction {

public static final QuickActionType TYPE = new QuickActionType(LOCK_SCREEN_ACTION,
"lock_screen_action", LockScreenAction.class)
.nameRes(R.string.lock_screen)
.iconRes(R.drawable.ic_action_touch_screen_lock)
.category(QuickActionType.INTERFACE)
.nameActionRes(R.string.quick_action_verb_turn_on_off);

public LockScreenAction() {
super(TYPE);
}

public LockScreenAction(QuickAction quickAction) {
super(quickAction);
}

@Override
public void execute(@NonNull MapActivity mapActivity) {
mapActivity.getMyApplication().getLockHelper().toggleLockScreen();
mapActivity.getMapLayers().getMapQuickActionLayer().refreshLayer();
}

@Override
public void drawUI(@NonNull ViewGroup parent, @NonNull MapActivity mapActivity) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.quick_action_with_text, parent, false);
((TextView) view.findViewById(R.id.text)).setText(mapActivity.getString(R.string.lock_screen_description));
parent.addView(view);
}

@Override
public int getIconRes(Context context) {
OsmandApplication app = (OsmandApplication) context.getApplicationContext();
return app.getLockHelper().isScreenLocked() ? R.drawable.ic_action_touch_screen_unlock : R.drawable.ic_action_touch_screen_lock;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import net.osmand.plus.R;
import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.quickaction.actions.LockScreenAction;
import net.osmand.plus.views.layers.MapQuickActionLayer;
import net.osmand.plus.views.mapwidgets.configure.buttons.QuickActionButtonState;

Expand Down Expand Up @@ -41,7 +42,13 @@ public QuickActionButton(@NonNull Context context, @Nullable AttributeSet attrs,

setOnClickListener(v -> {
mapActivity.getFragmentsHelper().dismissCardDialog();
if (!buttonState.isDefaultButton() && buttonState.isSingleAction()) {
if (app.getLockHelper().isScreenLocked()) {
for (QuickAction action : buttonState.getQuickActions()) {
if (action instanceof LockScreenAction) {
layer.onActionSelected(buttonState, action);
}
}
} else if (!buttonState.isDefaultButton() && buttonState.isSingleAction()) {
List<QuickAction> actions = buttonState.getQuickActions();
layer.onActionSelected(buttonState, actions.get(0));
} else if (!showTutorialIfNeeded()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ private void updateButtons() {
}
}

public List<QuickActionButton> getActionButtons() {
return actionButtons;
}

public void refreshLayer() {
setSelectedButton(null);
isLayerOn = mapButtonsHelper.hasEnabledButtons();
Expand Down

0 comments on commit 50883fb

Please sign in to comment.