Tag: adb

  • Spoofing Battery and Forcing Sleep (Android Development)

    I wanted to do something with my Android phone using ADB commands, while keeping it plugged in to run the said commands. However, the thing I wanted to test was related to the idle (dozing or asleep) mode of Android devices. The workaround was to spoof the battery state to bypass Android’s charging restrictions.

    Spoofing Battery Charging Status and Forcing Android Device to Sleep (Idle Mode)

    • Turn off the device screen using the physical power button.
    • Trick Android into thinking the device is running on battery power: adb shell dumpsys battery unplug
    • Force the device to step into deep Doze mode: adb shell dumpsys deviceidle force-idle
    • Verify the device is successfully spoofed and asleep: adb shell dumpsys deviceidle get deep (This should return IDLE).

    Can also do:
    adb shell dumpsys battery unplug && adb shell dumpsys deviceidle force-idle && adb shell dumpsys deviceidle get deep

    Device Cleanup for Spoofed Battery and Forced Sleep (Crucial!)

    1. Once testing is done, you must tell the OS to start reading the actual battery state again, otherwise it won’t charge properly: adb shell dumpsys battery reset
    2. Bring the device out of idle: adb shell dumpsys deviceidle unforce

    Can also do:
    adb shell dumpsys battery reset && adb shell dumpsys deviceidle unforce && adb shell dumpsys deviceidle get deep

  • Android emulator shell list fails: Permission Denied in app directory

    Today I learned I should include the app package name after shell in my ADB command, if for example I want to list files under the “subdirectory/media” directory of an app, like so:

    adb -s emulator-5556 shell run-as com.domain.my.app ls -al /data/user/0/com.domain.my.app/subdirectory/media

    First try’s command below failed with a Permission Denied error message:

    adb -s emulator-5556 shell ls -al /data/user/0/com.domain.my.app/subdirectory/media

    Makes sense, right? Because part of Android OS’ security is limiting access to app directories. But if you “run-as” the package owner app itself, it should grant you access.

  • Run command automatically after updating a file on Mac

    I get a kick out of automating things! Especially those seemingly easy extra steps that we do numerous times a day, everyday.

    There’s this configuration file that I frequently have to adb push into my test Android devices. And the cycle of editing the file, saving it, and then going to the terminal to run the push command (sometimes having to press the up ↑ key a few times) , is repeated as many times as needed.

    Last week, while rapidly becoming exhausted from the extreme summer heat, I was becoming frustrated at the bug I was trying to fix. Having to repeat the edit-save-push cycle on the file a countless number of times, along with the discomfort from sweaty armpits, wasn’t helpful in fixing the bug.

    I wondered, how do I automatically push this configuration file when unix detects a change in the file after editing and saving?

    What I did was rely on “entr”.

    I first installed it on my mac like so: brew install entr

    And then ran below command in my terminal:

    ls /Users/catz/Documents/MyConfigFile.json | | entr adb -e push /Users/catz/Documents/MyConfigFile.json /sdcard/Android/data/com.example.app/files/config/MyConfigFile.json

    /Users/catz/Documents/MyConfigFile.json is the configuration file I frequently edit and push.

    /sdcard/Android/data/com.example.app/files/config/MyConfigFile.json is the expected location of the file in my test Android device. The app reads the configuration from this location.

    Now, with this setup, I simply have to hit Save after editing the configuration file, and I just watch it automatically get pushed to my test Android device. 😎 My younger self probably would have tried to code her own script for automation, but my old, cranky present self knows better than waste time like that. Heh.

    Automating little things, such as having to push a changed file each and every time it’s edited, can have a big impact in one’s workflow. Streamlining mine this way allows me to use my little energy on what really matters.

    So, how did the bug squashing go?

    A quick background on the bug: StateFlow.update was not updating a value inside a list of data class model. I thought that a deep copy was what I needed, but it turned out that the data class contained an override function of equals and it was lacking a necessary logic to return the correct Boolean value. StateFlow.compareAndSet, which is called by StateFlow.update behind the scenes, does not proceed with updating the value, because the old and new value are seen as “equal” due to the overridden equals function not returning the correct result.

    I didn’t notice the faulty equals logic until I regained my calm focus on that hot workday — all thanks to a quick cool shower, and of course, the kick I got from setting up my command to automatically run after updating the configuration file~

    And yes, remember to try to feel comfortable as you do problem solving tasks! I think that feeling comfortable helps us keep a clear head, which consequently helps us solve problems more effectively.