Thursday, July 6, 2023

Feedback

Do you use haptic feedback on your phone? I didn't until recently when I turned it on one day on a whim, it's pretty cool. Since I'm so interested now in the pleasing little buzz of haptics when you swipe and scroll and press on important buttons, I'm adding haptics to all pyamsoft apps, and the PYDroid library. Yay buzz buzz!

Work continues on TetherFi specifically around network proxy performance. I continue to look at the ability to proxy UDP traffic - but it does not really seem to be as easy as I was hoping for a non-rooted Android app to be able to do, so this may need to be put on ice for a while as I figure it out more.

I have been daily driving both my stock app "TickerTape" and my finance management app "Sleep for Breakfast" for a while now - but just haven't made the final polish touches to release them as products, which is unfortunate. Sleep for Breakfast is pretty neat - it watches your phone notifications for things like Google Wallet payment notifications and Venmo transactions, and automatically adds Spending or Earning transactions, so you don't need to open the app up every time youre doing stuff to annoyingly fiddle with a virtual keyboard. You don't even need to take a picture of a stupid receipt, because as long as you received a notification about it, its already recorded! Super useful - very not complete though.

Final bits on the coding side, PYDroid has almost completely removed everything related to the old View system, meaning we are almost ready to go 100% Compose and never interact again with Fragments, Views, or XML (except in string/color resources I guess). Some day soon! I also moved the build toolchain to the new KSP instead of kapt (except in the case of Dagger, which needs kapt still), and hope to eventually move all to KSP once Dagger is ready.

Other miscellaneous updates on the non-coding side, my Steam game launching script gametime gained support for Zink OpenGL rendering, inside of a flatpak, inside of a gamescope embedded session. It's proven very useful when playing Team Fortress 2 and other old OpenGL games that are - lets face it - never getting Vulkan support.

I haven't wrote much lately because all of my computer time has either been spent being employed, or coding instead of writing. Sorry about that. But for the foreseeable future, I see myself coding more than writing once again.

Stay tuned!

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Saturday, June 3, 2023

Been a little while

Hey there,

Been away for a bit but that doesn't mean that nothing has been happening. Nerd stuff first.

TetherFi

Multiple app updates went out, the latest and most stable being version 24. Version 23 has a critical performance bug which will slow down your phone after enough usage, and I recommend you upgrade immediately off of it. A bunch of performance and battery changes have been made so the app should be faster and more efficient!

PYDroid

The library has seen some changes, mainly on the usage of the EventBus class, which is now just an alias for a Flow. We still keep this class because the event bus underneath is a MutableSharedFlow, which for some reason is harder to bind into Dagger than using our own EventBus and EventConsumer. Plus, the interface names being different from "just a Flow" help mentally convey that this flow may travel outside of the class you directly find it in.

Lots of other small changes and fun projects continued and some new ones started. Mostly revolving around money and investments and spending - you know how it is in this economy. Hopefully later on I will have more concrete thoughts to write about, but for now, just know that I'm still here, and still working.

When I'm not playing Zelda, that is.

Stay tuned!



========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Thursday, February 9, 2023

Android 14 and the death of fun things

She's dead, Jim.

Android 14's first developer preview released and with it comes continued changes to make applications that solely run as background utilities useless.

Namely, these changes affect at least Home Button and Trickle. TetherFi fits slightly easier into the use-case mold that Google seems to want Android to evolve towards - as it's usecase is met under the CONNECTED_DEVICES type of foreground long-running service, as it managed connected devices under a WiFi Direct group. Home Button and Trickle both do not fall under any use case specifically, and thus they would be put under the "special use" type which is subject to both approval and deprecation in the future.

Let me be very clear, no third-party app will ever receive the "special use" case type approval from Google unless they are large, multi-million dollar companies. As such, since both Trickle and Home Button require a foreground service to operate even in a somewhat expected way, both of these applications cannot continue on the Play Store in the future.

Trickle was a newer application but was genuinely useful, as it allowed the device to automatically enter the system-level low-power mode - a feature which has not yet been duplicated in the system or other third-party applications and thus there is no replacement for it.

Home Button is pyamsoft's original Android app, built first as a learning opportunity and turned into an online product. It has seen widespread use, but now has official alternatives such as modern software buttons and device-swipe controls. After more than 10 long years of Android development and support - it finally sees its last day.

TetherFi should continue to be supported, assuming that we are allowed as a valid foreground service use-case, and the upcoming stock app should also not be affected by these new restrictions.

Stay tuned!

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Tuesday, January 24, 2023

New Kung Fu

PYDroid 26.2.0 has been released which brings support for fully Compose layouts. No more view binding, no more XML, no more fragments - all Compose. PYDroid is now a Kotlin first, Compose first library.

And since PYDroid is the backbone of all pyamsoft applications, updates to all pyamsoft applications have been released (Home Button still reviewing) that move them to fully Compose layouts too.

TetherFi has received a plethora of fixes and new features as the community has picked up around it a bit this weekend. The network can be shared with a QR code, the password will be hidden by default, and language changes attempt to clarify features in the application. Future updates will continue to bring more features, and one day UDP proxying will work too - one can hope.

These updates have been pushed to the store and will go live for you soon.

Stay tuned!

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Wednesday, January 18, 2023

The important of re-reading documentation

PYDroid is being updated to 26.2.0 which brings support for a fully Compose application. PYDroid internally is dropping all Fragments and moving to a Single-Activity, multi-Composable architecture.

With this change comes a lot of learning about Compose. One particular problem that had me super confused for almost a day involves some very innocent code and some very particular Compose behaviors.

@Composable
fun Test() {
  val (show, setShow) = remember { mutableStateOf(false) }

  Scaffold {
    Box(
      modifier = Modifier.fillMaxSize(),
      contentAlignment = Alignment.Center,
    ) {
      Button(
        onClick = { setShow(true) },
      ) {
        Text(
          text = "Click Me",
        )
      }
    }
  }

  if (show) {
    Dialog(
      onDismissRequest = { setShow(false) },
    ) {
      Text(
        text = "Hello!",
      )
    }
  }
}

Looks pretty simple right? A composable with a button in the center, that when clicked, shows a Dialog. This works fine.

This doesn't:

@Composable
fun Test() {
  val (show, setShow) = remember { mutableStateOf(false) }
  val breakItAll by rememberUpdatedState { setShow(true) }

  Scaffold {
    Box(
      modifier = Modifier.fillMaxSize(),
      contentAlignment = Alignment.Center,
    ) {
      Button(
        onClick = breakItAll,
      ) {
        Text(
          text = "Click Me",
        )
      }
    }
  }

  if (show) {
    Dialog(
      onDismissRequest = { setShow(false) },
    ) {
      Text(
        text = "Hello!",
      )
    }
  }
}

See what changed? I've added a breakItAll field which remembers a callback passed to it through future renders.

If you've ever coded in React before, this kind of pattern may look very familiar to you. Instead of passing a lambda function to a callback, you memoize the callback with React.useCallback so it won't continue to be allocated each render pass.

In Compose this breaks horribly. Once you click the button and the Dialog launches, your Button will begin infinitely recomposing, and it will never ever stop, even if you close the Dialog. Like a ticking time bomb, once you set it off there is no going back.  Even worse, your app will probably still continue to work. The button still works, the Dialog still shows. But performance dies in a hole. No crashes, just extreme amounts of lag. What the heck is going on here, why does one simple change, which should optimize the code even, make it blow up so spectacularly?

Compose does not like this, because Compose also cares about the idea of Stability. There are plenty of good articles on the web about Compose and Stable such as this one. Now what is the problem with the above by rememberUpdatedState?

Compose treats lambdas as Stable. The first code works because the onClick is a lambda, so when it fires, the re-render sees that the Button component has not changed at all and skips it. It renders the Dialog and is done, life moves on. This is how things should work.

When we change this to by rememberUpdatedState, our resulting variable (despite being the same Type as the lambda) is no longer stable, since the type of the variable is actually the delegated property. Thus, when the button is clicked and the state is switched, the Button is re-rendered and (even though the onClick is not re-allocated, it is re-assigned to a new lambda) a new onClick is attached. It then goes and re-renders the Dialog as it did before. The issue now though, is the Composition snapshot has treated Button as a dirty change, and tells the engine to once again re-render the Button. The Button is rendered, a re-assigned onClick handler is given to it, and Compose once again marks it dirty. This continues to happen infinitely, causing the problem above.

The reason you may want to memoize something like a callback is for all the reasons Compose provides you with that callback function. But you need to be aware that typewise, the function is not the same as a lambda at all. You should generally only be using this rememberUpdatedState when you are attempting a callback from an Effect hook, as it was designed. This second code block is an anti-pattern and should not be used.

That was a fun day. Thankfully the problem has been fixed, and various Stable issues in PYDroid have been addressed, so performance is significantly improved. With the new library changes will come new versions of pyamsoft applications with shiny new features, so get excited for that!

Stay tuned!

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Thursday, December 29, 2022

The importance of reading documentation

Linux has a few great tools that allow people to game easier with better performance.

One of these very important tools is a program called gamescope. Gamescope does some very complex things, but to keep it easy for a layman, it runs your game and lies to it about how big your computer screen is. You can run a game in a normal window, instead of in fullscreen, and gamescope will tell the game that your computer is actually only a resolution of 1280x720, but output to a window the size of 1920x1080. This allows for a couple of interesting gaming hacks for better performance.

The main performance boost granted by gamescope is that it allows you to apply AMD FSR upscaling to any game. This is possible because the game thinks it is running in exclusive fullscreen, so FSR is able to treat the window as the screen and apply upscaling to it, so your game can run at a lower resolution but render out at a higher one. It also allows any game no matter how old to apply a framerate limiter as gamescope is able to lie about the refresh rate of the screen as well.

It is important to read the documentation though, as I used to think I was using gamescope on my system to help with performance, but found one very important requirement - you must run your game in fullscreen mode or else nothing will take effect. I run all of my programs in windowed mode so I can multitask easier while I play, and many games nowadays default to fullscreen-windowed instead of exclusive fullscreen, which was preventing gamescope from helping with performance. Only after a quick debugging session last night and some reading this morning did I rediscover this very important requirement. You will know gamescope is working because when you set your game to exclusive-fullscreen, the max offered (or only offered) fullscreen resolution should be your configured virtual nested resolution.

The second useful tool is mangohud, which displays frametimes and system info on top of any game (as long as it uses Vulkan). One very important note I found after reading the documentation is that: if you are using gamescope and mangohud, you must run gamescope first, and then use gamescope to run mangohud, and then use mangohud to run your game, like so:

$ gamescope ${gamescope_options} -- mangohud -- "$@"

If you do not apply things in this order, mangohud will cause gamescope to crash on startup. Also, do not use the gamescope option --steam outside of Steam, or else weird things will happen. You have been warned.

Using both of these tools together helps a system that is performance limited by its hardware use software to side step these constraints and gives a longer lifespan to the system. How fun, thanks Linux (and Valve)!

More code and stuff later next week.

Stay tuned!

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Wednesday, December 28, 2022

2022 In Review

What a year it's been!

2022 In pyamsoft apps

2 New Android applications were created this year. Trickle, an automatic power-saving application that uses Android's Low-Power mode automatically, was released on the first week of January 2022. TetherFi, a no-root WiFi tethering hotspot application, was released in May of 2022. Both of these applications are currently supported, run on the latest Android 13, and are available today for your device!

Sadly, I also had to retire some Android applications this year, as there is only so much free time in a day. 2 old Android applications were retired this year. FridgeFriend, a light touch food inventory application, and SplatTrak, a map rotation tracker for Splatoon 2 (3) were both retired this year. They do not support the latest Android 13, and there is sadly no guarantee they will continue to work on new devices. I hope you got the chance to enjoy them while they were around.

On the desktop front, pyamsoft continues to maintain a handful of Linux applications. pstate-frequency is still live and working (though as frequency stepping in the kernel gets more robust it becomes more and more hands off). bubblewrap-wrap gained support for pipewire audio, and is generally less-needed as more applications continue to get official Flatpak versions. bubblewrap-wrap will continue to exist though as there will be many applications that benefit from it's lighter sandboxing and home isolation, while also not being self-isolated enough to be a full Flatpak. dockerize is a new script that was created from a grouping of dotfiles, and helps to set up simple docker containers without docker-compose, that uses extremely strict sandbox security by default, and also dynamically allocates a new container user to run the container as, instead of running the container as the host machine user. It exists as a lighter, script alternative to docker-compose, though it is generally intended for simple setups instead of full service containerized environments. I generally use it on my desktop machines to isolate instances of game servers, adblocking DNS, and media servers. git-ssh was updated to include support for ProxyCommands and still sees active use on all of my personal and work machines.

Two JavaScript Discord bots that I wrote initially in late 2021 got updated in 2022 to use Typescript and run completely self-serving inside of Docker. mousewatch is a simple Discord bot (not on the Bot Marketplace) that checks the Anaheim Disneyland Resort Magic Key Calendar periodically, and pings you when a spot opens up on a given day. stonk-bot is a simple Yahoo Finance bot which gets you company quotes quickly.

Overall, 2022 was a productive and interesting year for me on the side of code and creation. I am excited to see what new creations and advances 2023 brings for me in the world of product and application development.


2022 In Gaming

Personally, I think this year was a bit rough for gaming. At the start of the year I was generally glued on the Nintendo Switch, though as the year went on I moved off the Switch and more towards the PS4 and Steam gaming on Linux. I think the big winner of the year for me as far as new gaming advancements is Heroic which kept me connected to the Epic Games store and all of it's various freebies throughout the year. The easy integration with Wine is almost as seamless as Valve's Proton project is, and its always good to keep healthy competitors in the ecosystem. I may have a larger gaming focused posting later on, but suffice to say the games that kept my interest this year are largely the games that did last year too: Super Smash Bros Ultimate, Tetris Effect, Bloons TD6, Slay the Spire, Mario Tennis. Some newcomers to my generally rotating catalog were: OpenRCT2, Trombone Champ, and Orcs Must Die 3. Mario Kart 8 made a resurgence given the release of it's Booster Course pack, and I see myself continuing to pick it up in 2023. I've started playing Orcs Must Die 3 on Steam and its a fun co-op time. I look forward to Disney Speedstorm, whenever it ends up releasing in 2023.

You may notice that many of these games did not release in 2022. I think that summarizes my general thoughts on new releases in 2022. There were some releases I did pick up that I think are enjoyable however.

Elden Ring was a smash hit in February, and though I am awful at it and have fallen off of it since it released (because I am just not good enough), I do not deny that I had a ton of fun with it for the couple of months that I was able to keep up. Modern Warfare II released, and it is fun, but extremely buggy and I generally find myself lacking a reason to keep coming back to it. I have yet to play God of War, but its on my radar - and I've heard only good about it. I enjoyed Cult of the Lamb on Nintendo Switch when it released, and beat it within a week, but it was a buggy slow mess and I have not touched it at all since the first completion. 

So many Nintendo Switch games were disappointing this year. Nintendo Switch Sports was a huge disappointment, even if I only really purchased it to bowl - it was still a sorry excuse for a follow up to Wii Sports. Lego Skywalker Saga was a good game and a solid Star Wars entry, but as with many games this year, once you take a small break, you fall off forever and never come back. Same with Disney Dreamlight Valley. Same with Splatoon 3. Same with Pokemon (both Arceus and Violet). The best games that came to the system this year, aside from Kirby, were remakes. Persona 5, 13 Sentinels, Skyrim (again, again (again)), Stanley Parable, Nier Automata. The Switch this year was rough. The console is showing it's age. Or maybe I am.

2022 In Health

Not the best, not the worst. Mentally I feel still motivated to do new things and see new places. I'm generally comfortable where I am. Physically I don't find myself any unhealthier after the holidays than before - which I suppose is a win in my book. I've fallen into a bit of a rut and have found that forcing myself outside to break up the monotony of being at home in a single room apartment helps. The market continues to tank, but honestly I've learned to ignore it. There is other wealth in life besides money, and as the year ends I generally find myself rich in these other measures. I am still very active in trading though, as I continue to find it intellectually stimulating and very enjoyable.


Happy Holidays from pyamsoft, and here's to a Happy New Year!

Stay tuned!

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Tuesday, December 20, 2022

Tailscale and Your Traveling Setup

Let me set the stage for you.

I've got 2 computers. One which has a ton of media on it, the other which is my main (development) machine. Both of my computers are small form-factor, though the media machine is 10L (about the size of a backpack) and my main machine which is 4L in a K39v2 (it fits in the backpack).

As I joked, my entire main machine, along with keyboard, mouse, and portable monitor fits inside of one (heavy) backpack. I'm pretty proud of this completely portable setup, since I work from home and thus - I work from anywhere.

One thing that I can't always do though, is connect my main machine to my media machine when I'm away from home. Or, at least, I couldn't until recently. Let's chat briefly about networking solutions that bring two remote PCs together for LAN like communication.

Enter Tailscale, an open-source solution that lets you create a mesh VPN between multiple devices on the same tailscale account. I have it running on my Android phone, and both of my machines. This allows me to ping my media machine running on my home internet when I am outside (or on mobile data), without exposing any ports or my IP address to the outside world.

Because Tailscale lets me treat my machines as if they were on a local network together, I can open my SSH port on my media machine to LAN connections, and SSH into my media machine from anywhere in the world - as long as the SSH client is from my Tailscale account.

Since I can access my media machine from anywhere, I've also started running Gnome Remote Desktop on my media machine. I can connect via a fast RDP client, like Remmina to my media machine, to graphically manage it, from anywhere in the world.

I've been enjoying this setup so much, that I also enabled it on my Android phone! I have the Tailscale client on my phone, which allows it to connect remotely to my main machine and my media machine. I have the Remote Desktop Manager app which allows me to use RDP to connect to both of my desktop machines. All it takes is a USB hub for peripherals, and a TetherFi proxy for the devices around me, and I've got a completely mobile setup that uses my main or media machines compute power for builds and even things like video games.

One note about Android Tailscale: By default, something is wrong with the interaction between the Private-DNS setting and the VPN service. You can see more information about this issue here. This matters to me because my Android device uses a custom ad-blocking DNS setup via NextDNS - out of the box the Tailscale settings would not allow it to connect Private-DNS while the VPN was running. To resolve this, I followed a workaround in that issue above - Disable MagicDNS, and remove all other nameservers (you may also have to reboot your phone). Once done, even though Private-DNS in Android still displays the annoying "Couldn't Connect", it actually does connect just fine and my NextDNS dashboard confirms the connection. Odd.

In summary:
Use Tailscale to connect your devices together from anywhere.
Use SSH and RDP to remotely use and manage your devices.
Dongle a USB hub to your Android phone to plug peripherals in.
TetherFi proxy any other devices to your phone to share the Internet.
Remote work, remote play.

How neat. While I usually can just pack my main machine into a bag, in the rare instances where I don't have it with me but still want to get work done, I can use this remote setup. Does this make me any more productive though, or make updates come out faster? No!

Stay tuned...

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Monday, December 19, 2022

Old and New Again

PYDroid 26.1.0 will come with some new features when it releases sometime later next year.

First is that I am re-enabling the Version Update flow in app - so when a new pyamsoft Android application is uploaded to the store, you will receive a notification in the app to download and apply the new update.

Second is the changelog for updates will become optionally viewable upon upgrading. You will be able to click an easy button to view the changelog.

Finally you may notice non intrusive in-app rating prompts appearing after you have used each app for a while. Good reviews really help me out and motivate me to continue updating and creating new and interesting Android applications.

In speaking of new and interesting applications, I also bring some sad news. I have decided to drop support for SplatTrak, the unofficial Android frontend to Splatoon3.ink. The project is archived on GitHub, and unpublished from the Play Store. I no longer have time to maintain the application, it always lagged behind Splatoon3.ink because that was where it sourced data from, and I believe that Splatoon3.ink is just a better service to use. If you were using the application you can continue to do so, as it should still work, but it will not receive any more bugfixes or updates.

New applications should be coming soon though, so keep an eye out here for more exciting updates!

Stay tuned...

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================

Friday, December 9, 2022

PYDroid 26

PYDroid 26 is being published which brings some significant API changes.

First, the hard requirement of having to extend an Application class to install PYDroid, and use the PYDroidActivity base class is gone. Now instead, you can install PYDroid into your application using the Application.installPYDroid extension function, and you can extend your own BaseActivity and use AppCompatActivity.installPYDroid() to initialize it's UI bits.

This should help developers implement PYDroid into their own applications more easily, as we no longer have a hard dependency on PYDroid existing as a BaseActivity.

Future work in 26.1.0 will refactor pydroid-inject to use an explicit object graph instead of overriding getSystemService in a very hacky way. This will help reduce crashes from bad system graph initializations, and should further remove our dependency on very specifically structured Android code.

PYDroid 26 will be present in all pyamsoft application updates, which will be hitting a Play Store near you hopefully in the next week or so.

Happy Holidays!

Stay tuned...

========================
Follow pyamsoft around the Web for updates and announcements about the newest applications!
Like what I do?

Send me an email at: pyam.soft@gmail.com
Or find me online at: https://pyamsoft.blogspot.com

Follow my Facebook Page
Check out my code on GitHub
=========================