Skip to content

Commit

Permalink
Bump to v1.0.4
Browse files Browse the repository at this point in the history
Release version 1.0.4 with some performance fixes and new configurations.
Now BossKey can be made toggleable.
Mouse dissappearance time is fixed to 10 seconds, hopefully should not vary now
Also added a notice in the APP

And updating Redistributing and Modding section
  • Loading branch information
virresh committed Jun 26, 2021
1 parent 807be4b commit ae5ca99
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 44 deletions.
55 changes: 34 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

#### Please read the After Install instructions carefully otherwise you might end up soft-bricking yourself (it's possible to recover, but why do you want to risk it, eh?)

# MATVT: Mouse for Android TV Toggle
# MATVT: Mouse for Android TV Toggle (Now for flipphones as well)

Hard to reach portions of some legacy app that you're running on your Android TV?
Feeling the need to have a touch input in your Android TV?
Or just looking for an alternative to the famous Mouse Toggle App for your TV?
Hard to reach portions of some legacy app that you're running on your Android TV (/flipphone)?
Feeling the need to have a touch input in your Android TV (/flipphone)?
Or just looking for an alternative to the famous Mouse Toggle App for your TV (/flipphone)?

MATVT solves all the above. Unfortunately, it's not on the playstore, and there are no plans to
launch it there either. If you'd like to see it on playstore, please let me know in the issues
Expand All @@ -17,37 +17,36 @@ Official Releases (and pre-releases) can be seen at https://github.com/virresh/m
The latest stable release fit for usage on TV can be downloaded at https://github.com/virresh/matvt/releases/latest.

## So what does this app do?
MATVT is intended for users running Android TV (Android version 9+) and have a big remote with
MATVT is intended for users running Android TV / Flipphone (Android version 7+, limited functionality on Android 6 flipphone) and have a big remote with
atleast the following:
- DPAD (for up, down, left, right and center buttons)
- Color buttons (Red, Green, Yellow, Blue)
- Info button
- A spare key to toggle mouse mode (we call it the BossKey)
- <Optional> Color buttons (Red, Green, Yellow, Blue)
- <Optional> Info button

After installing this app, you'll get a (*BIG*) mouse cursor that can move around, perform clicks and
After installing this app, you'll get a mouse cursor that can move around, perform clicks and
left / right / up / down swipes from your remote itself without any extra hardware (no need to pair
with an android phone / laptop etc)

### UPDATE: Thanks to community contributions, now the app can be run on Android Boxes with small sized remotes as well. Checkout the how to use section for more information

## How to install?
Download the APK from the releases section and side-load it on your TV.
The source-code is open and available should you wish to inspect it / build it yourself / don't
trust the release apk ;)

Remember there are two apks, one for Android TVs, one for Android FlipPhones. The one's without a `-phone` suffix are for flipphones, the others are for TVs.

## How to use?
- DPAD is for movement and single clicks (I think I added long click support too, but isn't very reliable)
- DPAD is for movement and single clicks (has long click support too, but isn't very reliable)
- The color buttons are for swiping. RED and GREEN for up/down swipe, YELLOW and BLUE for left/right swipe
- Info button will instantly toggle mouse visibility (so you can switch between mouse and no mouse instantly)
- ~~Pressing back button for more than 3 seconds will disable the accessibility service completely~~ This is now removed.
- The mouse will auto-disappear after a short while and re-appear when you press another relevant button.
- Toggling mouse visibility via the Info button resets cursor position
- Toggling mouse modes resets cursor position
- The mouse warps around your TV sides, so you can roll over from the top of your TV to the bottom instantly
- Mouse movement is momentum based, so keeping key pressed for longer will increase the movement / send multiple swipes
- Mouse movement is momentum based, so keeping key pressed for longer will increase the movement / send multiple swipes in scroll mode
- For remotes who don't have the above buttons, a `Boss Key` is available which can be used to toggle between mouse mode / scroll mode / dpad mode. By default this is the mute key, but can be overridden in the configuration settings. See the Youtube video linked below by TechDoctorUK for a demo of how that works.
- You can change the cursor icon used from the companion GUI app. It also supports changing mouse size / scroll speed.

- You can change the cursor icon used from the companion GUI app. It also supports several useful mouse configurations, detailed in a separate section below

Shoutout to @sweenwolf for enhancing the app to work on tv boxes with less remote buttons.
See a demo of a modified version in action by TechDoctorUK at:
[https://youtu.be/UC7bPw2tG4c](https://youtu.be/UC7bPw2tG4c)

Expand All @@ -56,9 +55,21 @@ See a demo of a modified version in action by TechDoctorUK at:
other system apps. If you don't do this step and enable the accessibility service beforehand, the app won't have
necessary permissions to do anything and it'll keep consuming your input, so your remote will no longer work.
If you have gotten yourself in this situation, see FAQ.
- *AFTER* doing the above, you can go to accesibility settings and enable MATVT service.
- *AFTER* doing the above, you can go to accessibility settings and enable MATVT service.
- Now you can press the info button and there you have your mouse

# Configurations available in the APP:
- Mouse Size
- Mouse Scroll Speed `**`
- Mouse Icon (two icons, light and transparent available)
- Bordered Window (Enabling this will prevent the cursor from warping over the screen edges)
- Disable Boss Key (If you have a full size remote, you don't need to keep a boss key. Info key and color buttons are sufficient, read how to use section for more info)
- Will Boss Key Toggle (When remotes don't allow long pressing, this will allow people to cycle through various modes on key press in the order: Dpad -> Mouse -> Scroll -> Dpad) `*`
- Override Activation Key (Select this to set a custom keyCode for bossKey)

` *` Not available on FlipPhone version
`**` Not available on FlipPhones with Android 6.

# FAQs

- **Is this tested?**
Expand Down Expand Up @@ -92,13 +103,15 @@ If you have gotten yourself in this situation, see FAQ.
# Redistributing and Creating MODs

I welcome everyone who'd like to hack on the application, but I request everyone to stick by the following
- Please consider sending the enhancement to this project itself. I'm open to all enhancements and fixes. The whole point of making this app open source is so that folks have full access to the source code and don't have to pay anything for it.
- Please consider sending the enhancement to this project itself. I'm open to all enhancements and fixes. The whole point of making this app open source is so that folks have full access to the source code and don't have to pay anything for it.
- Please considering pointing to the latest releases from this repository itself, unless you explicitly want folks to download an old version. This prevents more people from downloading old versions and reporting bugs that might have been fixed.
- If you absolutely do not want to contribute back anything here, then please add a disclaimer to your distribution that it's bugs should not be reported here.
- If you absolutely do not want to contribute back anything here, then please add a disclaimer to your distribution that it's bugs should not be reported here.
- By no means should you think that the source code being free means you can sell it. The source code is officially licensed under GPLv3, kindly abide by it's terms of use (it requires disclosing source code).
- If you want to make commercial application out of the project and for some reason need another license / cannot abide by terms of GPL, please file an issue to discuss.

**What would happen I don't do the above?**
Nothing. Frankly, I don't really care how people use this code. But eventually without community support or corporate backing, open source projects like this die, and this one will die too. A time will come when no developer would want to open source their projects because it's a total loss of time and spend their time making stuff behind paywalls.

Also keep in mind this project source has contributions from several people.

# Reporting Bugs
Please ensure to report bugs against an official release. It's hard for me to track down mods. Please try the latest official release before reporting a bug, just in case the latest version has fixed issues that you might be facing.
Expand All @@ -110,7 +123,7 @@ All kinds of contributions are welcome. Two ways of contributing:

# Credits
Thanks to EVA Facial Mouse for open sourcing their code. I've taken lots of ideas from their codebase. You can check them out at https://github.com/cmauri/eva_facial_mouse
Thanks to @sweenwolf for making this app work on remotes with less buttons, and for the app icons and fully transparent curson images
Thanks to @sweenwolf for making this app work on remotes with less buttons, and for the app icons and fully transparent cursor images
Thanks to TechDoctorUK for making a demo video

# Disclaimer
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ android {
applicationId "io.github.virresh.matvt"
minSdkVersion 24
targetSdkVersion 29
versionCode 103
versionName '1.0.3'
versionCode 104
versionName '1.0.4'

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public class MouseEmulationEngine {

CountDownTimer waitToChange;

CountDownTimer disappearTimer;

private boolean isInScrollMode = false;

// service which started this engine
Expand All @@ -51,6 +53,8 @@ public class MouseEmulationEngine {

public static boolean isBossKeyDisabled;

public static boolean isBossKeySetToToggle;

private Handler timerHandler;

private Runnable previousRunnable;
Expand Down Expand Up @@ -165,11 +169,22 @@ public void run() {
* Auto Disappear mouse after some duration and reset momentum
*/
private void detachPreviousTimer () {
if (disappearTimer != null) {
disappearTimer.cancel();
}
if (previousRunnable != null) {
timerHandler.removeCallbacks(previousRunnable);
previousRunnable = mPointerControl::disappear;
timerHandler.postDelayed(previousRunnable, 30000);
momentumStack = 0;
disappearTimer = new CountDownTimer(10000, 10000) {
@Override
public void onTick(long l) { }

@Override
public void onFinish() {
mPointerControl.disappear();
}
};
disappearTimer.start();
}
}

Expand Down Expand Up @@ -201,7 +216,7 @@ private static GestureDescription createSwipe (PointF originPoint, int direction
public boolean perform (KeyEvent keyEvent) {

// toggle mouse mode if going via bossKey
if (keyEvent.getKeyCode() == bossKey && !isBossKeyDisabled) {
if (keyEvent.getKeyCode() == bossKey && !isBossKeyDisabled && !isBossKeySetToToggle) {
if (keyEvent.getAction() == KeyEvent.ACTION_UP) {
if (waitToChange != null) {
// cancel change countdown
Expand All @@ -219,7 +234,27 @@ public boolean perform (KeyEvent keyEvent) {
}
}
}
else if (keyEvent.getKeyCode() == bossKey) {
else if (keyEvent.getKeyCode() == bossKey && !isBossKeyDisabled && isBossKeySetToToggle) {
// keep a three way toggle. Dpad Mode -> Mouse Mode -> Scroll Mode -> Dpad Mode
if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
if (isEnabled && isInScrollMode) {
// Scroll Mode -> Dpad mode
setMouseModeEnabled(false);
isInScrollMode = false;
} else if (isEnabled && !isInScrollMode) {
// Mouse Mode -> Scroll Mode
Toast.makeText(mService, "Scroll Mode", Toast.LENGTH_SHORT).show();
isInScrollMode = true;
} else if (!isEnabled) {
// Dpad mode -> Mouse mode
setMouseModeEnabled(true);
isInScrollMode = false;
}
}
// bossKey is enabled. Handle this here itself and don't let it reach system
return true;
}
else if (keyEvent.getKeyCode() == bossKey && isBossKeyDisabled) {
// bossKey is set to disabled, let system do it's thing
return false;
}
Expand Down
28 changes: 20 additions & 8 deletions app/src/main/java/io/github/virresh/matvt/gui/GuiActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.provider.Settings;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.SeekBar;
Expand All @@ -23,9 +20,7 @@

import androidx.appcompat.app.AppCompatActivity;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import io.github.virresh.matvt.BuildConfig;

import io.github.virresh.matvt.R;
import io.github.virresh.matvt.engine.impl.MouseEmulationEngine;
Expand All @@ -37,8 +32,8 @@

public class GuiActivity extends AppCompatActivity {
CountDownTimer repopulate;
CheckBox cb_override, cb_mouse_bordered, cb_disable_bossKey;
TextView gui_acc_perm, gui_acc_serv, gui_overlay_perm, gui_overlay_serv;
CheckBox cb_override, cb_mouse_bordered, cb_disable_bossKey, cb_behaviour_bossKey;
TextView gui_acc_perm, gui_acc_serv, gui_overlay_perm, gui_overlay_serv, gui_about;

EditText et_override;
Button bt_override;
Expand All @@ -59,16 +54,25 @@ protected void onCreate(Bundle savedInstanceState) {
gui_acc_serv = findViewById(R.id.gui_acc_serv);
gui_overlay_perm = findViewById(R.id.gui_overlay_perm);
gui_overlay_serv = findViewById(R.id.gui_overlay_serv);
gui_about = findViewById(R.id.gui_about);
boss_override = findViewById(R.id.boss_override);

bt_override = findViewById(R.id.bt_override);
et_override = findViewById(R.id.et_override);
cb_override = findViewById(R.id.cb_override);

cb_mouse_bordered = findViewById(R.id.cb_border_window);
cb_disable_bossKey = findViewById(R.id.cb_disable_bossKey);
cb_behaviour_bossKey = findViewById(R.id.cb_behaviour_bossKey);

sp_mouse_icon = findViewById(R.id.sp_mouse_icon);
dsbar_mouse_size = findViewById(R.id.dsbar_mouse_size);
dsbar_scroll_speed = findViewById(R.id.dsbar_mouse_scspeed);

// don't like to advertise in the product, but need to mention here
// need to increase visibility of the open source version
gui_about.setText("MATVT v" + BuildConfig.VERSION_NAME + "\nThis is an open source project. It's available for free and will always be. If you find issues / would like to help in improving this project, please contribute at \nhttps://github.com/virresh/matvt");

// render icon style dropdown
IconStyleSpinnerAdapter iconStyleSpinnerAdapter = new IconStyleSpinnerAdapter(this, R.layout.spinner_icon_text_gui, R.id.textView, IconStyleSpinnerAdapter.getResourceList());
sp_mouse_icon.setAdapter(iconStyleSpinnerAdapter);
Expand Down Expand Up @@ -151,6 +155,11 @@ public void onStopTrackingTouch(SeekBar seekBar) {}
MouseEmulationEngine.isBossKeyDisabled = value;
}));

cb_behaviour_bossKey.setOnCheckedChangeListener((((compoundButton, value) -> {
Helper.setBossKeyBehaviour(getApplicationContext(), value);
MouseEmulationEngine.isBossKeySetToToggle = value;
})));

populateText();
findViewById(R.id.gui_setup_perm).setOnClickListener(view -> askPermissions());
}
Expand All @@ -176,6 +185,9 @@ private void checkValues(IconStyleSpinnerAdapter adapter) {

boolean bossKeyStatus = Helper.isBossKeyDisabled(ctx);
cb_disable_bossKey.setChecked(bossKeyStatus);

boolean bossKeyBehaviour = Helper.isBossKeySetToToggle(ctx);
cb_behaviour_bossKey.setChecked(bossKeyBehaviour);
}

private void showBossLayout(boolean status) {
Expand Down
14 changes: 14 additions & 0 deletions app/src/main/java/io/github/virresh/matvt/helper/Helper.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class Helper {
static final String PREF_KEY_SCROLL_SPEED = "SCROLL_SPEED";
static final String PREF_KEY_MOUSE_BORDERED = "MOUSE_BORDERED";
static final String PREF_KEY_CB_DISABLE_BOSSKEY = "DISABLE_BOSSKEY";
static final String PREF_KEY_CB_BEHAVIOUR_BOSSKEY = "CB_BEHAVIOUR_BOSSKEY";

public static boolean isAccessibilityDisabled(Context ctx) {
return !isAccServiceInstalled(ctx.getPackageName() + "/.services.MouseEventService", ctx);
Expand Down Expand Up @@ -139,4 +140,17 @@ public static boolean isBossKeyDisabled(Context ctx) {
return sp.getBoolean(PREF_KEY_CB_DISABLE_BOSSKEY, false);
}

@SuppressLint("ApplySharedPref")
public static void setBossKeyBehaviour(Context ctx, Boolean val) {
SharedPreferences sp = ctx.getSharedPreferences(PREFS_ID, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean(PREF_KEY_CB_BEHAVIOUR_BOSSKEY, val);
editor.commit();
}

public static boolean isBossKeySetToToggle(Context ctx) {
SharedPreferences sp = ctx.getSharedPreferences(PREFS_ID, Context.MODE_PRIVATE);
return sp.getBoolean(PREF_KEY_CB_BEHAVIOUR_BOSSKEY, false);
}

}

0 comments on commit ae5ca99

Please sign in to comment.