Modifying the KaiOS 1.0 System App to Remove Toasters

Those dang toasty boys are messin up my mojo!


In KaiOS, the "Toaster" is the information drop-down telling you what text input mode you are now in, such as abc, ABC, Abc, 123, etc., or other text-only information such as the Photo or Video mode in the camera. It’s different from the drop-down notifications that an event is happening from the calendar or the like. These toasters are pretty annoying, take a while for the animation to play, and in most cases, completely unnecessary. 


The numerical input toaster The switched to video toaster
These really don't add any useful information, do they? Let's get rid of 'em.


This is a method to remove the annoying toasters from the System application. It removes the Text Input Mode and/or general System Toasters. This method does leave in place the toaster which indicates when you switch between languages by holding the "#" key, e.g. English/Spanish. I'm actually not sure why the language toaster still works, because it supposedly uses the System Toaster, but I'm not going to complain, that one's actually useful. There must be multiple System Toasters listening.


You can pick and choose here - either disable just the text input method, or both. I don't know if you can only disable the System toaster and leave the text input method toaster working, but I would hazard a guess if you want one gone, you probably want the other.


The first thing you need to do is establish a backup in case things go wrong. We are going to be modifying the system application, so that is a very real possibility. I recommend backing up the system images via EDL, but whatever recovery you choose is up to you. If you screw up your phone and it doesn't boot any more, I likely can't help you. I wish I could, but I can't.


So the first thing you should do is back up the following partitions with EDL:


Getting the system app from the phone

We do need ADB root access, so install the adbroot app or your rooting method of choice. Then get the system app and webapps.json from the phone with ADB root like so:


adb pull /system/b2g/webapps/system.gaiamobile.org

adb pull /data/local/webapps/webapps.json


Create a working directory and extract the application source there:


mkdir source

unzip system.gaiamobile.org/application.zip -d source


Now we can do the modifications!


Text input method toaster

The text input toaster obscuring an event notification
BIG OOF

We need to modify these files:


Well, js/keyboard_manager.js doesn't have to be modified, but it's probably best to do it anyway. We want to find the following block of code:


  _publishModeChanged: function(mode) {

    var idMap = {

      'abc': 'ime-lowercase',

      'ABC': 'ime-uppercase',

      '123': 'ime-number',

      'Abc': 'ime-capitalize',

      'T9': 'ime-t9'

    };


    var ariaLabel = navigator.mozL10n.get(idMap[mode]);

    this._showToaster({text: mode, ariaLabel: ariaLabel});


    window.dispatchEvent(new CustomEvent('keyboard-mode-changed', {

      detail:{mode: mode}

    }));

  },


Now comment out the line:


 this._showToaster({text: mode, ariaLabel: ariaLabel});


Here's the tricky bit. It appears most (not all) javascript in the app gets "minified" and put into gaia_build_*.js files. If you know how to rebuild these files, you could do that and avoid directly modifying them. However, we really only need to remove one line, so it’s not too bad to go in and do what we need to.


So we need to go in and remove the same line of code in gaia_build_defer_index.js


Back up this file before you change it. It's a huge scary block of code, but just find that exact piece of code that we commented out before, and delete it, including the semicolon on the end. Done!


General System Toasters

The battery full toaster
Begone!

This one is actually easier, as the javascript file we need appears to not be minified for some unknown reason. But hey, that works out for us.


The file we need is:


Find this block of code:


  _createClass(SystemToaster, [{

    key: 'componentDidMount',

    value: function componentDidMount() {

      var _this2 = this;


      this.element = _reactDom2.default.findDOMNode(this.refs.element);

      this.on('closed', function () {

        _this2.clear();

      });

      Service.register('show', this);

      window.addEventListener('iac-systoaster', this);

    }

  },


And simply comment out the line:


window.addEventListener('iac-systoaster', this);


Cool!


Putting the app back on the phone

To put the app back on the phone, we will zip up the source files and put the app on the phone in a new location:


cd source

rm ../system.gaiamobile.org/application.zip

zip -r ../system.gaiamobile.org/application.zip ./*

cd ..

adb push system.gaiamobile.org /data/local/webapps


And now we will change the path to the app in the webapps.json file we pulled earlier. Find the system.gaiamobile.org section in the file:


  "system.gaiamobile.org": {

    "origin": "app://system.gaiamobile.org",

    "installOrigin": "app://system.gaiamobile.org",

    "receipt": null,

    "installTime": 1547465160507,

    "updateTime": 1547465160507,

    "manifestURL": "app://system.gaiamobile.org/manifest.webapp",

    "localId": 1027,

    "appStatus": 3,

    "manifestHash": "b48cdb88c287d7047eb3a99ebd3f6113",

    "basePath": “/system/b2g/webapps",

    "id": "system.gaiamobile.org",

    "removable": false,

    "kind": "packaged",

    "enabled": true,

    "name": "System",

    "csp": "",

    "role": "system",

    "widgetPages": [],

    "redirects": null,

    "additionalLanguages": {},

    "installerAppId": 0,

    "installerIsBrowser": false,

    "installState": "installed",

    "storeId": "",

    "storeVersion": 0,

    "downloading": false,

    "readyToApplyDownload": false

  },


Yours will probably be slightly different, but all we need to do is change the basePath line from “/system/b2g/webapps" to “/data/local/webapps”.


Finally, push the webapps.json file back to the phone and reboot:


adb push webapps.json /data/local/webapps/

adb reboot


Testing

System notifications still work No toaster shown
Notifications still work!

Testing is simple. 


For the text input method toaster, find any text input field and select it. You should not see any toaster. Change the text input method with “#” and one should not appear.


For the system toaster, the easiest one I have found is to go to the Camera app and switch between Photo and Video. You should not see a toaster.


To check that notifications are still working, try creating a new event for today in the Calendar app. When you save it, you should see a notification drop down saying it has already started.


Done!