I'm not an Android developer, but I do work with Android applications which means I have to work with Android Studio and Android emulator quite often. Recently, I encountered a quite interesting problem which prompt me to write this post and hopefully can help someone in the future.


Because I need to identify where the user of the mobile app is located and provide different content to the user based on their location.


There are definitely several ways to do so, one obvious way is to use the IP address. However, with the growing use of VPN, this is definitely not the most reliable option.

The other option that comes up is to identify through the mobile carrier. If you are not familiar with telco or mobile networks, I will provide a brief background next.

MCCs and MNCs
Each mobile network operator (or carrier) can be uniquely identified by using a combination of MCC (mobile country code) and MNC(mobile network code). More information on this on Wikipedia. What this means is that, you can usually reliably identify where the user is from by looking at their mobile carrier's MCC code.

Usually, you would have to translate the MCC code to a country code on your own but it turns out in Android you don't have to do the translation yourself. Instead, you can directly use this API which will give you an ISO country code in 2 letters. You can then do whatever you want with this country code, pass this through a header to a server or the likes.

Once you have implemented this using getNetworkCountryIso, you will realize it is almost impossible to test or verify if this functionality will actually work as expected. One of the easiest way is to provide a debug menu within the app (in debug mode) and then mock different countries, this is the obviously the most efficient and cost effective way.

If in reality, a debug menu to mock countries is not something you can achieve, then you will have to use the emulator. This is what the rest of this post will be about, and hopefully this post can help you with your solution.

Read more »

It's been almost two years since I wrote the post on how to automate Zoom with Alfred and Apple Scripts. Sadly enough, the situation has not improved at all, you still have to click on the link for the Zoom meeting and then wait for it to launch your Zoom app.

The need for a simple way to join Zoom meetings (on Linux)

The goal is to open Zoom directly and join the meeting without going through the browser.

I have started using my Linux laptop to join a Zoom meeting regularly recently, and I simply can't tolerate having to click on the same link over and over again each time I want to join the meeting -- I just wish there is a simpler way to open Zoom with one click without going through the browser.

Read more »

As a long time Linux user, I have to admit sometimes it is not easy to achieve some of the things that can be easily done in other OS (like macOS or Windows), but that one of the things I enjoy about Linux as well -- you need to force yourself to learn something, and once you've achieved it, you will learn from it and then realize how powerful Linux is. Anyway, for me, this had been one of the problems that had me troubled for a while -- using dual monitors, and have Linux automatically detect and extend desktops automatically.


I use bspwm as my tiling window manager, and polybar as the 'bar'. The problem I'm trying to solve here is to have the laptop automatically detect monitor hot-plug and then extend the bars with different layout to the new monitor. And when I unplugged the external monitor, the system revert back to single monitor layout.

Read more »

As a developer, one of the most important things is to find the right tool to write code with. To me, that means this tool needs to be lightweight, portable, and most importantly reliable.

Why VSCode is not for me

VSCode, aka Visual Studio Code, is a code editor developed by Microsoft. It is based on top of the Atom editor that was previously developed by GitHub. As a full stack developer whose main language is JavaScript/TypeScript, I was told to use VSCode when I joined the company. However, as a long-time vim user, I still use the vim mappings when I am using VSCode. This is all done through plugin/extensions. This seems to be okay at first, but over time, I really find VSCode annoying to use and I simply can't tolerate it.

The first thing is that contrary to most popular belief, VSCode is NOT an open source product. Yes, part of the source of VSCode is open-sourced, but the VSCode you downloaded from Microsoft website is not. They have put some proprietary stuff into the end product and I'm not a big fan of that. There are ways to get around this, namely, there are several truly open source edition of VSCode, the one I used to use is called VSCodium, but then you will lose access to the extensions market provided by Microsoft.

Another thing that annoys me is that VSCode or any product that based on VSCode is just too slow and resource intensive -- they are just an electron app running on another Chromium based browser. Having one Chrome is enough for me, so thank you Microsoft (I tried to avoid electron based apps as much as possible, for example, I use web version of Teams, rather than the app one)

Read more »


⚠ Hiding phone numbers may not be legal in some places, and even if you hide your number, you mobile operator WILL (of course) see your number. Use the method described in this article at your own risk!

Read more »

Yesterday morning, when I woke up, I faced a serious issue on my laptop which has Manjaro Linux installed -- the X server can not be started.

Locating the problem

It took me some time to get my head around and locate the root cause. The first thing I tried is obviously force reboot several times, it turned out this did not help at all! Reboot will not solve everything.™
The next thing I tried was the fallback initramfs mode. I don't really understand what it does, but tried it anyway. And unfortunately, that does not work either.
At this point,the only option left for me to try is recovery mode. And it turned out to be working correctly. As root user in the recovery mode, I issued the following command systemctl set-default, this makes the tty the default target rather than the graphical interface. Another reboot, and I got into the terminal.
Once in terminal, I immediately tried startx, this failed due to some wired permission issue, and with sudo startx, the command failed as well. Looking at the Xorg log, I noticed that the start process stops at: (II) Initializing extension VNC.

Read more »


Font family name (Name Id 1 in name table of the font) in a OpenType font file should not be used as the font-family property in CSS if the font is not one of regular, italic, bold, and bold italic style. Instead, the Typographic Family Name or Preferred Font Family (Name ID 16 in name table of the font) should be used if including them in CSS.

Background and Problem

Recently, I was tasked to investigate an interesting problem found in our custom font implementation. Font is something I have no prior knowledge about and this investigation really helped me learn a lot more about font and by writing it down, I hope I can help developers who may face similar problems.

Our system allows user to upload any font as long as they have the permission to use the font commercially. Recently, we realized that some of the fonts uploaded by user were not displayed correctly. More specifically the font-family attribute of these said fonts were incorrectly extracted.

As an example, an user uploaded a font called fontA-SemiBold, the extracted font-family name from the font was fontA-SemiBold whereas the correct name of for the font-family should be fontA. And in this case. The incorrect font name resulted in incorrect rendering in the front-end as the CSS rendering is suppose to have the correct font-family name.

Read more »

I've always considered myself to be an advanced computer user, but I'm not a Windows person, at least not when I'm coding. So when I got a Windows 10 laptop as a daily work machine, I'm beyond disappointed. Luckily, there's always a way around -- VirtualBox it is. The laptop I got was powerful enough that I was able to allocate 16GB of memory as well as 3 cores of the host machine to the virtual machine.

Once I had my vm setup, I always use Windows Terminal and SSH into the machine for development. One day, it occurs to me I can (and should) automate all of this.


Automatically start the selected VirtualBox virtual machine in headless mode (this can save a bit of resources), wait for the machine to boot, and then SSH into the VM using Windows Terminal with selected port forwarding on the host and virtual machine.

Read more »

Though this is technically a tech blog where I usually put my thoughts and learnings regarding technologies, I still would like to share some of my experience with taking the IELTS exam which is about a month ago.

Please note that the author is in no way affiliate with the websites and/or services mentioned below, use of these software and/or services is at the sole discretion of the reader

Why I choose to take IELTS

To be honest, my current status does not require me to take the IELTS exam. Though after some consideration, I have decided to take the exam and see if I can benefit from extra immigration points by taking the IELTS exam. My goal is reaching 8 in listening and 7 in all other sections. I made the decision to take the exam on the night of May 22nd, 2021. I took the exam on June 13th, 2021. The preparation time is around 21 days.

Read more »

This week, while setting up local project for work, I encountered some weired issue during the unit test and this has something to do with postgres and its default settings under Windows and other OS.


As an example, consider the following array: [ 'D', 'd', 'a', 'A', 'c', 'b', 'CD', 'Capacitor' ]

Sorting this in JavaScript results in case sensitive result, where upper case always come first:

>>> [ 'D', 'd', 'a', 'A', 'c', 'b', 'CD', 'Capacitor' ].sort()
[ "A", "CD", "Capacitor", "D", "a", "b", "c", "d" ]

Sorting this in Postgres SQL with default installation will yield a case insensitive sorting where upper and lower case are mixed:

SELECT regexp_split_to_table('D d a A c b CD Capacitor', ' ') ORDER BY 1;


The goal here is to make sorting consistent, so we can either fix the Postgres side or fix the JavaScript side.

Read more »