Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collaboration between screen filter app devs #222

Closed
smichel17 opened this issue Jul 9, 2018 · 22 comments
Closed

Collaboration between screen filter app devs #222

smichel17 opened this issue Jul 9, 2018 · 22 comments

Comments

@smichel17
Copy link
Member

smichel17 commented Jul 9, 2018

On f-droid, there are 3 screen filter apps that all do more or less the same thing:

And some apps that have partial overlap:

It seems like a waste of effort to have so many of us working independently on the same kinds of issues. Are any of you interested in merging our apps, or collaborating in some other way (eg, refactoring some functionality into libraries we could share)?

edit: We're all GPLv3 (or GPLv3+), so we can freely combine our code.

@notjuliee
Copy link
Member

I think a library for screen filtering would be very useful. Sounds like fun to work on :D

My app lacks a lot of functionality, I would love to somehow merge it in to a more fleshed-out app.

@fython
Copy link

fython commented Jul 10, 2018

Thank you for organizing a collaboration. I'm glad to share idea about my open source apps with people. Although I might not migrate my app to some new library, I would support your work!

@smichel17
Copy link
Member Author

smichel17 commented Jul 12, 2018

So far it seems like there's more interest in libraries. I would slightly prefer merging, because:

  • Maintaining a UI is still a bunch of work, that we could share if we combined apps.
  • It's less likely that one app with multiple maintainers will be abandoned, compared to a bunch of apps with single maintainers.
  • We'd be able to get to bug reports faster, etc.

However, merging is be a big step to take, especially since most of us have not worked together at all yet, and I'd rather collaborate on a library than not collaborate at all. That would also be a good way for us to get comfortable working together, and we could always decide to merge later.

@smichel17
Copy link
Member Author

Some ideas I had for libraries are:

  • A library that handles scheduling alarms and fading in/out in a battery-friendly way.
  • A library with each of the filtering methods, behind the same interface, so any of our apps can use any method.
    • KCAL (Night Light) — standard stable interface, but requires root and ROM support
    • SurfaceFlinger (changing compositor values) (OpenShift) — works on most devices, but requires root and uses an undocumented API (might break)
    • Overlay (Night Screen + Red Moon) — works on all devices, but prevents installing apks and isn't as effective at filtering blue light
    • System Overlay (Night Screen) — like overlay and doesn't prevent installing apks, but can only dim (no blue light filtering)
  • A library for interfacing with other applications (eg, so people can use apps like Tasker/Easer/LibreTasks to program our apps).

If we really wanted to go all the way, we could make a single library that handles the entire backend (everything above, keeping track of state, etc). Then we'd just maintain our separate UIs (simpler vs more customizable, etc).

How do any of those ideas sound to you?

@notjuliee
Copy link
Member

I definitely agree that merging the UIs would ease development, but people have different ideas of what makes a good UX.

  • Handling scheduling and fading seems like something that would fit in a more general library.
  • That sounds good, but I'm not sure how System Overlay would fit as it doesn't support the same feature set.
  • I'm not sure what you mean by that? Like an IPC thing?

@smichel17
Copy link
Member Author

smichel17 commented Jul 12, 2018

Handling scheduling and fading seems like something that would fit in a more general library.

I think our situation is a bit unique, since

  1. We don't need anything to trigger or run while the screen is off (unlike an alarm)
    and
  2. We need to update the fade state immediately when the screen turns on (most non-alarm apps can wait until they get re-opened)

Plus, none of us actually have this feature, so it would be useful to all of us :)

I'm not sure how System Overlay would fit as it doesn't support the same feature set.

I'd guess, by ignoring values it doesn't use. Let's decide which library to start with, first.

Like an IPC thing?

Like, we could all respond to the same type of intent broadcast, instead of the current way where it's specific to Red Moon. Honestly it might make more sense for this to just be a spec we agree on, than a library, since it's pretty simple to implement.

@corphish
Copy link

Library seems a nice idea.

A library that handles scheduling alarms and fading in/out in a battery-friendly way.

Nice. This is something that is common in all of the apps here. I guess we could start off by this?

A library with each of the filtering methods, behind the same interface, so any of our apps can use any method.

Ok, I don't know about others but implementing KCAL is easy (surfaceflinger seems easy too, what about overlays?), and since this is where the apps differ, for now I would keep it specific to app (and later think about generalizing it).

A library for interfacing with other applications (eg, so people can use apps like Tasker/Easer/LibreTasks to program our apps).

We would need a common way for those apps to interact with ours. Would be pretty interesting to implement, but yeah this would be nice.

Also, how about having a library for color related stuff? Like RGB calculation for a color temperature and all those stuff? A small but useful helper sort of...

About commonizing UI, how about having common UI elements rather than UI itself? Like a SeekBar specifically made for dealing with color temperature inputs and maybe having a link with a TextView or EditText to show the values?

@fython
Copy link

fython commented Jul 13, 2018

Will this library include a implementation of Service? My opinion is to write a backend class which has its own lifecycle (Like onStart, onPause, onConfigurationChange, onStop, etc). Allow developers to use it in their Service defiend by themselves. How to handle broadcasts and display notifications will not be included in library.

And, although Kotlin is one of the most popular Android development languages, it's not suitable for a library project. We know that developers will be forced to implement Kotlin standard libraries if library dependecies use Kotlin. It may increase install package size by at least 100KB. To guarantee developers' choice, just use Java. (Java 8 is also okay. Lambda helps us improve coding performance.)

@smichel17
Copy link
Member Author

smichel17 commented Jul 13, 2018

Kotlin is one of the most popular Android development languages, it's not suitable for a library project

That's a good point. I like Kotlin, but it shouldn't be that painful to use Java for shared libraries. Of course, if it's something @corphish and I want but you don't care about, we could write it in Kotlin, or share code instead of making a library.

Scheduling / fading

I guess we could start off by this?

I agree that this seems like the easiest one to start with, since it's pretty small scope. I described the part that makes it hard on stackexchange when I was originally grappling with how to handle fading. I was thinking the library interface would be a fairly thin wrapper around AlarmManager and ValueAnimator. Something like:

// Empty methods so you can choose which to override
public class AbstractAnimatorListener implements Animator.AnimatorListener, ValueAnimator.AnimatorUpdateListener {
    // AnimatorListener
    public void onAnimationStart(Animator animation) {}
    public void onAnimationEnd(Animator animation) {}
    // etc

    // AnimatorUpdateListener
    public void onAnimationUpdate(ValueAnimator animation)
}

public class ValueAnimatorScheduler {
    // Runs the animation between the given times, but *not* when the screen is off
    // Returns an id for the job
    public int schedule(AbstractAnimatorListener listener, long startAtMillis, long endAtMillis)
    
    public void cancel(int id)
    public void cancelAll()
}

We could also definitely simplify the AbstractAnimatorListener interface, if you'd prefer that to staying closer to the Android animation api.

Filtering library

easy to implement […] since this is where the apps differ, for now I would keep it specific to app

I don't think any of them are difficult, particularly since we already have working implementations. The complexity comes from things like:

  • Overlays preventing interaction with secure apps is confusing to many users, so Red Moon can monitor the open app and automatically pause/resume filtering in known secure apps (ie, installing apks). It does this with usage stats, which is an incredibly poorly documented API (and I am actually relying on some undocumented behavior).

since this is where the apps differ, for now I would keep it specific to app

For what it's worth, about a year ago @joonatoona and I were looking into implementing surfaceflinger into Red Moon, so a lot of the ground work for this is already done.

A lot of the complexity here comes from trying to maintain a consistent UX across filtering methods. For example, surfaceFlinger requires opening a root shell, which is slow. Red Moon fades in over half a second, instead of starting at full strength immediately, and opening a new shell each time might not be feasible. @joonatoona was looking into things like opening a shell and then passing new values to it using a named pipe; I don't honestly remember what the outcome of that was (@joonatoona, do you?).

Due to that complexity, I agree that this is not the best place to start. However, I think it would be really valuable to have eventually. Different methods have trade-offs that make them ideal for different people — for example, surfaceFlinger is strictly better than overlay… but only if you have root, which many people don't.

Will this library include a implementation of Service? My opinion is to write a backend class which has its own lifecycle […] How to handle broadcasts and display notifications will not be included in library.

Agreed. @joonatoona and I ended up with something like this:

interface Filter {
    fun start()
    fun setColor(profile: Profile)
    fun stop()
}

We'd probably need to modify it a little since our apps use different representations of the filter settings (Red Moon has 3 settings, Night Screen has 2, not sure what Night Light uses since I don't have root to check).

Color Library

That sounds useful. Red Moon's current calculations are here. I don't think we ever got around to converting between the values in Red Moon's profile and what's needed for the surfaceFlinger call. I think @raatmarien might have planned on looking into that?

Seekbar / UI elements

The whole Red Moon UI is built using preference screens, I suspect it'll be a bit difficult to share, unless Night Light is, too. That said, it does have a SeekBarPreference that's close to what you're describing.

@smichel17
Copy link
Member Author

smichel17 commented Jul 15, 2018

I'm starting on the timer library. Does the interface I proposed sound good to you? (edit: we'll need a context in there, too)

To start, I just made a new branch in this repo; when I have anything worth sharing, I'll move it out to its own repo and make you all maintainers (is everyone okay with having it under the LibreShift organization? Any good ideas for a name?).

@smichel17
Copy link
Member Author

smichel17 commented Jul 30, 2018

I haven't had that much time, but I'm close to a proof-of-concept implementation. The interface now looks like:

public int schedule(Context context, Animator animator, long startAtMillis)

I did it this way since we all have separate representations of a profile, so we might as well let the Android animation framework do the work of calculating intermediate values instead of doing it ourselves.

@smichel17
Copy link
Member Author

@corphish @fython How would you like me to share the code when I'm ready? I think it would make sense to put in its own repo and publish to jcenter, but I'm not sure what namespace to use (right now it's just com.example.timer as a placeholder).

The other option is to keep it where it is right now, as a new library module in Red Moon. However, we'll have to figure out a namespace eventually, so I think I'd rather just do that now.

@corphish
Copy link

Yeah having it in its own repo seems fine.

@smichel17
Copy link
Member Author

smichel17 commented Jul 30, 2018

Any suggestions for a name? (edit: repo name and package name)

@smichel17
Copy link
Member Author

TransitionManager?

@smichel17
Copy link
Member Author

I could buy a domain to use as a namespace; libreshift.com, .org, and .net are all available.

@notjuliee
Copy link
Member

Its not really a transition manager, is it? TransitionScheduler?

@smichel17
Copy link
Member Author

I was thinking of Android's AlarmManager, but yeah, either could work.

@smichel17
Copy link
Member Author

I made https://github.com/LibreShift/TransitionScheduler and pushed what I have so far. Obviously still a work in progress, with many // TODOs left, but it's enough to show the general idea of what I was thinking. I'd appreciate feedback on the design (and/or code, if you'd like to make changes yourself; I made all 3 of you admins).

I used org.libreshift.transitionscheduler as the package name (for now; of course we can change it if there's a problem later). I'm willing to buy libreshift.org, but I really would like it to be an organization and not a project with bus factor: me. So, if I do that, I'd like to figure out a way to share account credentials, so I'm not the only one with access.

@smichel17
Copy link
Member Author

It might be easier to create new issues in that repo than in this thread, which is already quite long.

@fython
Copy link

fython commented Jul 31, 2018

Thanks for sharing push access. If I catch my own idea or want to make some changes, I will send a pull request or an issue before pushing to master branch.

@smichel17
Copy link
Member Author

Closing this since we have a new repo to make issues on, now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants