Skip to content

Commit

Permalink
build upgrade; do not cycle scroll; do not include current app; add icon
Browse files Browse the repository at this point in the history
  • Loading branch information
yauhen-l committed Jul 28, 2020
1 parent 993e27e commit 3cfd150
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 60 deletions.
15 changes: 5 additions & 10 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apply plugin: 'com.android.application'

android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
buildToolsVersion "28.0.3"
defaultConfig {
applicationId "by.yauhenl.gardine"
minSdkVersion 23
Expand All @@ -20,13 +20,8 @@ android {
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.2.0'
//compile 'com.android.support.constraint:constraint-layout:1.1.3'
//testCompile 'org.testng:testng:7.1.0'
testCompile 'junit:junit:4.12'
testCompile 'org.assertj:assertj-core:3.16.1'
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:25.2.0'
testImplementation 'junit:junit:4.12'
testImplementation 'org.assertj:assertj-core:3.16.1'
}
Binary file added app/src/main/ic_launcher-web.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 24 additions & 11 deletions app/src/main/java/by/yauhenl/gardine/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,46 @@
*/
public class App {

public final String title;
public final String packageName;
public final Intent startIntent;
final String title;
final String packageName;
final Intent startIntent;

public App(String title, String packageName, Intent startIntent) {
App(String title, String packageName, Intent startIntent) {
this.title = title;
this.packageName = packageName;
this.startIntent = startIntent;
}

public String toString() {
return this.title;
}

@Override
public boolean equals(Object obj) {
if(obj == null) {
return false;
}
if(!(obj instanceof App)) {
return false;
String pn = "";
if(obj instanceof String) {
pn = (String) obj;
} else if (obj instanceof App) {
pn = ((App) obj).packageName;
}
return this.packageName.equals(((App) obj).packageName);
return this.packageName.equals(pn);
}

@Override
public int hashCode() {
return this.packageName.hashCode();
}

// WARN: it is used in list item view
@Override
public String toString() {
return this.title;
}

public String toLogString() {
return "App{" +
"title='" + title + '\'' +
", packageName='" + packageName + '\'' +
", startIntent=" + startIntent +
'}';
}
}
3 changes: 1 addition & 2 deletions app/src/main/java/by/yauhenl/gardine/DiscardingStack.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package by.yauhenl.gardine;

import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;

Expand Down Expand Up @@ -30,7 +29,7 @@ public void add(T app) {
apps.add(app);
}

public Collection<T> getAll() {
public ArrayDeque<T> getAll() {
ArrayDeque<T> reversed = new ArrayDeque<>();
for (T a : this.apps) {
reversed.push(a);
Expand Down
94 changes: 61 additions & 33 deletions app/src/main/java/by/yauhenl/gardine/GardineWidgetService.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,34 @@
import android.widget.ImageView;
import android.widget.ListView;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;

import static android.widget.AdapterView.INVALID_POSITION;

public class GardineWidgetService extends AccessibilityService {

public static final String LOG_TAG_COORD = "coord";
public static final String LOG_TAG_RECENT_APPS = "recent_apps";
public static final String LOG_TAG_EVENT = "event";

// TODO: move to preferences
private static final int MAX_ITEMS = 6;
private static final int SHOW_X_THRESHOLD = 30;
private static final int SCROLL_Y_THRESHOLD = 45;
private static final int VIBRATE_DURATION = 20;
private static final int MAX_Y_DIFF = MAX_ITEMS * SCROLL_Y_THRESHOLD - SCROLL_Y_THRESHOLD/2;
private static final int MIN_Y_DIFF = 0;

private WindowManager windowManager;
private View gardine;
private ArrayList<App> recentApps;
private DiscardingStack<App> recentActivities;
private String currentAppPackage;
private ArrayAdapter<App> recentAppsAdapter;
private Vibrator vibrator;

public GardineWidgetService() {
this.recentApps = new ArrayList<>();
this.recentActivities = new DiscardingStack<>(MAX_ITEMS);
}

Expand All @@ -66,34 +71,39 @@ protected void onServiceConnected() {

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.d(LOG_TAG_EVENT, "Got event: " + event);
if (event.getEventType() != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
return;
}
if (event.getPackageName() != null && event.getClassName() != null) {
ComponentName componentName = new ComponentName(
event.getPackageName().toString(),
event.getClassName().toString()
);

ActivityInfo activityInfo;
PackageManager pm = this.getPackageManager();
try {
activityInfo = pm.getActivityInfo(componentName, 0);
} catch (PackageManager.NameNotFoundException e) {
Log.i(LOG_TAG_RECENT_APPS, "Ignore window of component: " + componentName);
return;
}
Intent startIntent = pm.getLaunchIntentForPackage(activityInfo.packageName);
if (startIntent == null) {
Log.d(LOG_TAG_RECENT_APPS, "Skipping package " + activityInfo.packageName + " due to absence of launch intent");
return;
}
if (event.getPackageName() == null || event.getClassName() == null) {
return;
}
this.currentAppPackage = event.getPackageName().toString();

ComponentName componentName = new ComponentName(
event.getPackageName().toString(),
event.getClassName().toString()
);

ActivityInfo activityInfo;
PackageManager pm = this.getPackageManager();
try {
activityInfo = pm.getActivityInfo(componentName, 0);
} catch (PackageManager.NameNotFoundException e) {
Log.i(LOG_TAG_RECENT_APPS, "Ignore window of component: " + componentName);
return;
}
Intent startIntent = pm.getLaunchIntentForPackage(activityInfo.packageName);
if (startIntent == null) {
Log.d(LOG_TAG_RECENT_APPS, "Skipping package " + activityInfo.packageName + " due to absence of launch intent");
return;
}

String label = pm.getApplicationLabel(activityInfo.applicationInfo).toString();
this.recentActivities.add(new App(label, activityInfo.packageName, startIntent));
String label = pm.getApplicationLabel(activityInfo.applicationInfo).toString();
App a = new App(label, activityInfo.packageName, startIntent);
this.recentActivities.add(a);

Log.i(LOG_TAG_RECENT_APPS, componentName.flattenToShortString());
}
Log.i(LOG_TAG_RECENT_APPS, "Added app to the stack: " + a.toLogString());
}


Expand Down Expand Up @@ -130,7 +140,7 @@ public void onCreate() {

this.recentAppsAdapter = new ArrayAdapter<>(
this, R.layout.item, R.id.item,
this.recentApps);
new ArrayList<App>(MAX_ITEMS));

final ListView tasksList = (ListView) gardine.findViewById(R.id.tasks_list);
tasksList.setAdapter(this.recentAppsAdapter);
Expand Down Expand Up @@ -173,7 +183,7 @@ public boolean onTouch(View v, MotionEvent event) {
Log.d(LOG_TAG_COORD, "UP at " + event.getRawX() + ", " + event.getRawY());


if(!isHidden()) {
if (!isHidden()) {
int checkedPos = tasksList.getCheckedItemPosition();
if (checkedPos != INVALID_POSITION) {
App selectedApp = (App) tasksList.getItemAtPosition(checkedPos);
Expand All @@ -197,19 +207,31 @@ public boolean onTouch(View v, MotionEvent event) {
show();
}
} else {
if(event.getRawX() - this.initialShowX > SHOW_X_THRESHOLD/2) {
if (event.getRawX() - this.initialShowX > SHOW_X_THRESHOLD / 2) {
hide();
return true;
}

int Ydiff = (int) (event.getRawY() - this.initialShowY);
int yd = (int) (event.getRawY() - this.initialShowY);
int oyd = yd;
yd = Math.min(yd, MAX_Y_DIFF);
yd = Math.max(yd, MIN_Y_DIFF);
int correction = oyd - yd;
this.initialShowY += correction;

int itemsNumber = recentAppsAdapter.getCount();

if (itemsNumber > 0) {
int selectedItem = Math.abs((Ydiff / SCROLL_Y_THRESHOLD) % itemsNumber);
int selectedItem = (yd / SCROLL_Y_THRESHOLD);
if(selectedItem < 0) {
selectedItem = 0;
} else if (selectedItem >= itemsNumber) {
selectedItem = itemsNumber - 1;
}

int prevItem = tasksList.getCheckedItemPosition();
if (prevItem != selectedItem) {
Log.d(LOG_TAG_COORD, "Vibrate at Ydiff=" + Ydiff + ", prevItem=" + prevItem + ", curItem=" + selectedItem);
Log.d(LOG_TAG_COORD, "Vibrate at Ydiff=" + yd + ", prevItem=" + prevItem + ", curItem=" + selectedItem);
vibrator.vibrate(VIBRATE_DURATION);
tasksList.setItemChecked(selectedItem, true);
}
Expand All @@ -231,8 +253,14 @@ public void onDestroy() {
}

private void actualizeRecentApps() {
this.recentApps.clear();
this.recentApps.addAll(this.recentActivities.getAll());
this.recentAppsAdapter.clear();

ArrayDeque<App> recentApps = this.recentActivities.getAll();
if(this.currentAppPackage != null) {
boolean removed = recentApps.removeFirstOccurrence(new App(null, this.currentAppPackage, null));
Log.d(LOG_TAG_RECENT_APPS, "Current app " + this.currentAppPackage + " has been removed: " + removed);
}
this.recentAppsAdapter.addAll(recentApps);
this.recentAppsAdapter.notifyDataSetChanged();
}
}
Binary file modified app/src/main/res/mipmap-hdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/mipmap-mdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/mipmap-xhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import org.junit.Test;
import static org.assertj.core.api.Java6Assertions.*;

public class RecentActivitiesTest {
public class DiscardingStackTest {

private static final String a = "a", b = "b", c = "c", d = "d";

Expand Down
4 changes: 3 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0'
classpath 'com.android.tools.build:gradle:3.4.2'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand All @@ -15,6 +16,7 @@ buildscript {
allprojects {
repositories {
jcenter()
google()
}
}

Expand Down
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Fri Mar 10 14:43:36 IST 2017
#Fri Jul 24 21:17:47 CEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip

0 comments on commit 3cfd150

Please sign in to comment.