Ziirish's Home :: Blog

Ziirish's Pub

 
 

Ça fait un moment que je dois rédiger un petit article sur mon "architecture" de messagerie... Mais ça ne sera pas encore pour tout de suite !

Par contre, ce présent article est plus ou moins lié.

En effet, depuis plusieurs mois (quasiment 1 an, en fait), j'ai quitté les services de google pour ce qui est de la gestion de mes mails, de mes calendriers et de mes contacts. Mais il faut reconnaître que l'intégration de leurs applis avec Android est propre, et le fait de pouvoir accéder depuis son téléphone à ses contacts, calendriers et mails et que tout soit synchro dans tous les sens, c'est vachement classe. Et en plus, tout est unifié. Du coup, j'ai cherché un moyen de conserver le plus possible ce niveau de service, le tout en ayant la possibilité de s'auto-héberger.

Je vous détaillerai la partie backend dans un prochain article, tout comme la partie intégration android, mais rapidement, pour accéder à mais mails, calendriers et carnets d'adresses de manière unifiée depuis mon téléphone, j'utilise le protocole ActiveSync de Microsoft... Ce n'est pas Libre, mais ce protocole a l'avantage d'être très largement implémenté et il existe un grand nombre d'implémentations Open Source de la partie Serveur. Pour ma part, j'utilise l'excellent Z-Push-Contrib (auquel j'ai contribué pour le faire fonctionner avec Sabredav/Owncloud (voir ce commit ))

Et donc, j'accède désormais à l'ensemble de mes ressources (mails, calendriers et contacts) en ajoutant simplement un seul compte de type Exchange dans Android. La synchro fonctionne dans tous les sens et c'est donc une solution utilisable par "n'importe qui", même ma grand mère !

Le problème, c'est que les couleurs associées aux calendriers Exchange sur Android sont générées de manière totalement aléatoire (sauf si vous utilisez un vrai serveur Exchange à priori sur lequel vous pouvez choisir la couleur de votre calendrier).

Semaine dernière je suis passé sur Cyanogenmod 11, et d'un coup mon calendrier perso s'est vu attribuer la couleur fuchsia ! Ça piquait un peu beaucoup les yeux je dois vous l'avouer...

Du coup, voici la manip pour modifier les couleurs.

ATTENTION : IL FAUT ÊTRE ROOT, DE PLUS, NOUS ALLONS MODIFIER DES FICHIERS SYSTÈMES DONC PENSEZ À VOS SAUVEGARDES...

Vous voilà prévenus.

  • Vous devez avant tout disposer d'un shell via adb sur votre téléphone.
  • Ensuite vous activez les permissions root du démon adb :
adb root
  • Les calendriers sont stockés dans une base sqlite qui se trouve ici :
/data/data/com.android.providers.calendar/databases/calendar.db

On commence par récupérer les droits et permissions associées à ce fichier :

$ adb shell
root@mako:/ # cd data/data/com.android.providers.calendar/databases/
root@mako:/data/data/com.android.providers.calendar/databases # ls -l
-rw-rw---- u0_a11   u0_a11     217088 2014-03-10 20:25 calendar.db
-rw------- u0_a11   u0_a11     337040 2014-03-10 20:22 calendar.db-journal
root@mako:/data/data/com.android.providers.calendar/databases # exit

Puis on récupère le fichier en question via adb : adb get /data/data/com.android.providers.calendar/databases/calendar.db /tmp/calendar.db

  • On sauvegarde ce fichier car on va le modifier...
cp -a /tmp/calendar.db /tmp/calendar.db.ori
  • On passe aux choses sérieuses, à savoir modification de ce fichier pour changer nos couleurs :
$ sqlite3 calendar.db
SQLite version 3.7.13 2012-06-11 02:05:22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
Attendees             Colors                Reminders           
CalendarAlerts        Events                _sync_state         
CalendarCache         EventsRawTimes        _sync_state_metadata
CalendarMetaData      ExtendedProperties    android_metadata    
Calendars             Instances             view_events         
sqlite> .schema Calendars
CREATE TABLE Calendars (_id INTEGER PRIMARY KEY,account_name TEXT,account_type TEXT,_sync_id TEXT,dirty INTEGER,name TEXT,calendar_displayName TEXT,calendar_color INTEGER,calendar_color_index TEXT,calendar_access_level INTEGER,visible INTEGER NOT NULL DEFAULT 1,sync_events INTEGER NOT NULL DEFAULT 0,calendar_location TEXT,calendar_timezone TEXT,ownerAccount TEXT, isPrimary INTEGER, canOrganizerRespond INTEGER NOT NULL DEFAULT 1,canModifyTimeZone INTEGER DEFAULT 1,canPartiallyUpdate INTEGER DEFAULT 0,maxReminders INTEGER DEFAULT 5,allowedReminders TEXT DEFAULT '0,1',allowedAvailability TEXT DEFAULT '0,1',allowedAttendeeTypes TEXT DEFAULT '0,1,2',deleted INTEGER NOT NULL DEFAULT 0,cal_sync1 TEXT,cal_sync2 TEXT,cal_sync3 TEXT,cal_sync4 TEXT,cal_sync5 TEXT,cal_sync6 TEXT,cal_sync7 TEXT,cal_sync8 TEXT,cal_sync9 TEXT,cal_sync10 TEXT, mutators TEXT);
CREATE TRIGGER calendar_cleanup DELETE ON Calendars BEGIN DELETE FROM Events WHERE calendar_id=old._id;END;
CREATE TRIGGER calendar_color_update UPDATE OF calendar_color_index ON Calendars WHEN new.calendar_color_index NOT NULL BEGIN UPDATE Calendars SET calendar_color=(SELECT color FROM Colors WHERE account_name=new.account_name AND account_type=new.account_type AND color_index=new.calendar_color_index AND color_type=0)  WHERE _id=old._id; END;
sqlite> select * from Calendars;
[...]
12|toto@example.com|com.android.exchange|c/Cdefaultcalendar||Ziirish's Calendar|Ziirish's Calendar|-65313||700|1|1||Europe/Paris|toto@example.com||0|0|0|1|0,1|0,1,2|0,1,2|0|||||||||||
[...]
sqlite> .quit

J'ai coupé la sortie de la commande pour n'afficher que le calendrier qui nous intéressent. On voit ici qu'on dispose d'un champ calendar_color. Pour le calendrier n°12 la valeur de ce champ est -65313.

Alors attention accrochez vous, cette valeur correspond à la valeur négative de la conversion en décimal du code héxadécimal de la couleur invérsée. (Enfin, c'est à peu près la traduction française de ce qu'on va faire pour trouver la valeur de notre couleur finale).

Pour vérifier qu'il s'agit bien d'une couleur flashy qui justifie ces manips, on prend le positif de -65313, donc 65313. On converti en hexadécimal pour obtenir ff0021 (qui correspond à cette couleur ). Et enfin, on prend le négatif, le code hexa du négatif est donc 00ffbe, ce qui correspond à cette couleur (Attention, ça pique vachement aux yeux !).

J'ai choisi une couleur plus soft : celle là . Son code hexadécimal est donc 30a5cc. On l'inverse : CF5A33 (avec ce site par exemple). On converti en décimal : 13589043 et on prend le négatif : -13589043.

Ne reste plus qu'à mettre à jour la base :

$ sqlite3 calendar.db
SQLite version 3.7.13 2012-06-11 02:05:22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> update Calendars set calendar_color = -13589043 where _id = 12;
sqlite> .quit
  • On remet le fichier en place :
adb push calendar.db /data/data/com.android.providers.calendar/databases/calendar.db
  • On remet les bonnes permissions sur le fichier :
$ adb shell
root@mako:/ # cd data/data/com.android.providers.calendar/databases/
root@mako:/data/data/com.android.providers.calendar/databases # chown u0_a11:u0_a11 calendar.db
root@mako:/data/data/com.android.providers.calendar/databases # chmod 660 calendar.db
root@mako:/data/data/com.android.providers.calendar/databases # exit
  • Et enfin on reboot le téléphone

Il existe peut-être des applis permettant de faire ça plus simplement, mais je n'ai pas trouvé (et je n'ai pas cherché bien longtemps aussi...)