A little story about an insignificant Android app: birth, growth and death sentence

🇺🇸 – Monday, September, 21st 2020

Mots clés : #Android, #GooglePlay, #root, #clicker, #app

How a simple app I forged was used and hacked by users before being kicked by Google without warning.

Few years ago when I was an impetuous-padawan-developer I discovered useless but must-have apps to waste time like Cookie Clicker and Woy !. The aim of Cookie Clicker was simple: tap on the screen to get more cookies. Woy ! was an app created by colleagues which helped to define notifications (useful or dumb) to send to contacts (but was removed from Google Play). Thus I started to work on an app which may help me to trigger a lot of clicks to these kinds of apps, during day and nights. Yes, I need to fill my week-ends and I wanted to spam my friend 😁.

The first issue I met was the open source license to use. 🐧

In fact I wanted to create a free project, and finally chose the MIT license. Much simpler and smaller than Apache 2.0, and didn’t want to use contaminative licences like GPL.I wasn’t yet an enough bearded linuxian. My mood was something like “use it, ant that’s it”

Text of MIT license

Next, the tools. 🛠️

Nothing original, created a repo on GitHub, listed the features I wanted to implement in a poor plain text file (too lazy to create at that time a Trello or Wekan account). I decided to upload the app on Google Play, my first baby project! I thought about alternative stores like F-Droid but decided to not use it ; youngster laziness (remember my baby-linuxian beard? I had only a moustache). First project, wanted to keep it simple.

Then, the tests. ✅

How could I ensure my software was enough stable for release? How could I ensure to find any regressions? So I decided to play with unit tests using JUnit and functional tests with Espresso and UI Automator. Nice choice! I was quite confident about the coverage of my tests (too much?), even if the core of the app was tricky to test with automated tools. I should had used TDD and clean code principles to make things cleaner and better. With hindsight I should have been more careful about the coverage of my sources (to ensure all cases have been properly tested).

Java-written functional test source code

After that, I tried to build an HTML doc using JavaDoc because I chose Java. ☕

Yes, I love comments, and Java was one of the two first programming languages I discovered, it has a special flavor for me. Maybe I wrote too much of comments in that project. But having a nice bunch of HTML pages is fun for me. The boring thing was more about the use of Java instead of Kotlin, but at that time Kotlin was not ready at all. JavaDoc was cool and quite efficient to have a quick look on the API.

Java source code sample of a click async task

First project, so first occasion to use fun third-party components. 🧱

For example I integrated a material arc menu, custom switch buttons, introduction screens, swipe selectors, and material seek bars. I tried to have a simple but nice UI. Time to get pleasure!

Then, the features. ⚙️

At that era, it was not possible for an app to make clicks outside itself ; thus no app was able to click on other components. However if the smartphone in use is rooted, let's party! A whole API is reachable, a lot of funny things can be done using a shell with sudo rights. With this low-level API all actions can be triggered, like clicks or swipes. It worked during a long time but it seems it will be the pretext for Google to use the shotgun. The use case was simple: define a list of points to tap on the screen, apply a configuration (duration of clicks, breaks between them, …), ask for sudo access and go. Simple, isn't it? The app allowed also to export configurations, use predefined scenarii and could be triggered from outside. A more curated list of features is in the README.

One of the cool part of this story was the unexpected third-party contributions, about translations. 🌍

Indeed like a naive developer I used dumbly Google Translate to translate my wording (in english and french) to other languages. In fact I saw thanks to the Play Store developer console a lot of users lived in plenty of countries, from Russia to Spain, Iran to Middle-East, Korea to South America. But the translations I integrated were awful. Users were complaining a lot about how bad it was ; the UI was not usable at all! I should had used only languages I was able to read, write and understand. DeepL was not launched. However a Russian and a German users some day send to me the translations in its mother language, and an Italian user made a pull request for new translations. Motivating! It was free, efficient and clear, thanks to these guys!

Very bad comment on Google Play Store about bad translations

The interesting thing was about the use of the app, and firstly the metrics I got. 📋

I saw there was a two-sided relationship between users and the app: love and hate. Reading the store stars, I had a big split with high stars numbers with the worst mark (1 star) and… the best (5 stars). But why? Why did I received such rude and offensive comments on a side, and enjoying and motivating comment on the other side?

App page review with 322 marks, an average rank to 3.0 and highest scores in 5 stars and 1 star.

It was because… I did not mentioned the app was for rooted device. Woops. Yes the promise was cool (click on everything!) but it was also fucking disappointing for users if the device was not capable. Thus I mentioned in CAPSLOCK in the title of the store page the app was for unleashed smartphones, and things were a bit better. saying in the description of the app was not enough.

Header of the app's page on Google Play Store with the icon, the name and screen shots.

Few months later, I asked search engines like Google and Duck Duck Go... 🦆

...to check if there were some contents about the app, like reviews, counterfeiting and videos about it. I was both kindly surprised and upset about the things I

In the hand I saw the app was available on third-party platforms, kinds of APK aggregators. I was upset: no consent was given to them to steal the app and provide it on foreign platforms. I checked also the content: I found some of the provided APK were compromised! Thank you guys, my project, my app, open sourced it, and you altered it to make I-don't-know-what operations. Sincerely, go fuck yourself. You deserve nothing, and because of you and the stupidity of some users (using blindly such tools) you give to Google too much points to say third-party stores are hazardous (even if Yalp and F-Droid are reliable!).

The other things I got, a more pleasant one, was some users hacked my app so as to use it for other things: get more followers on Instagram! From my point of view we should have the right to hack apps and use them for use cases we want, and that was pleasant to see people talking about Smooth Clicker on YouTube! It was not expected at all but it made my smile 😊. A review here and another here 😄.

However shit had finally come for my app: the Google head shot with a railgun. Painful and rough. 💥

Some day I received an email from Google whistling the end: “Hey guy, we found your app was violating our terms of uses, in fact you altered the state of the device and we disliked that. So, say goodbye to your project! Best regards ❤”. Holly crap. That was unexpected. I tried to have a look and the console but… nothing! Because the app has been blocked, every fucking thing has been hidden or disabled. Comments ? Nope. App reviews? Nope? Crash reports? Ahah, nope. Metrics about the devices of users? Stop dreaming, blocked.

Email of Google saying the app has been ssuspended because of rules 4.8 and 4.9 violations of Play Store terms of uses

Maybe I should have appealed. In fact my app did not changed the state of phones: it only triggered the sudo mode of rooted devices (but did not root them) and call ADB primitives to make clicks. Ok, the app had links in the settings page to help people to make their devices rooted using dedicated tools. But it's ok, be fair-play, it was a bit borderline 😛.

Java code which builds an ADB command and processes it in a SUDO processus

Even if I appealed it won't be very useful for me to get access to the app to make patches: in fact like a moron I formatted my laptop. Guess what was the file I forgot to save? The keystore file with keys to sign the APK 😒. In fact I had a backup, but a too old one. A full jackass. Credentials lost. Woops.

Later I saw my Git history was fucked up (in fact a certain amount of repositories I used were in a big mess). Heavy files commited (woops!), non-linear history, saved secrets, I was a newbie and also my personal email was used in commits. Bots found that and I received between 50 and 100 emails per day with scams. So, I decided to change my emails accounts and burn all my repositories. Fresh start, cleaner history, good base. Not smooth but I didn't care.

And so what?

Smooth Clicker was my first junior side project, and it was pleasant. Doc, tests, design patterns, open source, in production and hacked by people, between 50k and 100K downloads… it was incredible. The main feature with the Shell ADB commands was cool to implement, and I learned a lot. Good skills have been got and will be used in the future. I have a lot of regrets about the Google sentence: I would have liked to have a warning instead of such one-shot. But it's the game: I tried, and it not accepted. But it was a cool journey! I would liked to go further with the app but it's a sad fact: the 2.1.3 version (code name Juicy Jellyfish) will be the last.

Extract of app page saying there was between 50,000 and 100,000 downloads

Error message in Google Play saying the app is not available anymore

Dernière mise à jour : mercredi 9 février 2022 Précédemment sur Medium et paper.wf

Did you enjoy reading this blog? Give me a beer 🍺 or use something else ❤️‍🔥 Licensed under CC-BY-SA 4.0 Opinions are my own, even if I have some interests. For any comment or to contact me, feel free to choose the most suitable medium for you.