2012-11-18

La Messagerie Visuelle Vocale FreeMobile pour tous.

MISE À JOUR : Vous pouvez récuperer vos identifiants avec l'application net.cekage.vvmfreemobile  depuis le PlayStore  
 
Fin Octobre 2012, FreeMobile a proposé pour ses clients Android la Messagerie Visuelle Vocale (MVV) en téléchargement gratuit sur le PlayStore mais l'a réservée aux dernières générations de téléphones Android et Apple. Cette limite est d'autant plus étonnante que FreeMobile propose encore des terminaux en 2.3 :
Le Galaxy Y en 2.3 (GingerBread)
L'objectif de cet article est de documenter pour les développeurs d'applications mobiles pour Android <4, Symbian, Windows Mobile, Bada,... le fonctionnement de la MVV pour pouvoir l'utiliser sur leur système favori. Pour ma part, j'utilise souvent mon vieux Smartophonus Ginderbreadus et la MVV est un confort.

Comme à mon habitude, je privilégie l'approche candide pour deviner le protocole.  Une fois que je sais reproduire les fonctions ciblées je vérifie avec la documentation si elle est disponible.

2012-10-24

Android et le sentiment d'insécurité SSL

Hier,  Generation-NT a publié un article sur la sécurité d'Android au niveau du protocole SSL.

Si le titre "Android : des experts démontrent une sécurisation défaillante SSL" est racoleur, l'introduction est plus précise "Des experts en sécurité suggèrent que de nombreuses applications Android sécurisent mal les données sensibles malgré les protocoles de protection.".

L'étude

L'article fait écho à un article de Ars Technica basé sur l'étude de Sascha Fahl, Marian Harbach, Thomas Muders, Matthew Smith, Lars Baumgärtner et Bernd Freisleben (ou ici).  L'art d'Ars est de monter en épingle des détails de l'étude : pwn un antivirus en injectant sa propre signature dans sa base de signature de virus, vol de cookies, rejeu de requête...

Aujourd'hui il existe suffisamment d'attaques SSL simples pour ne plus se reposer uniquement sur le chiffrement de la conversation pour se sentir en sécurité.

Gestion par défaut du SSL par Android

Il est important de comprendre que par défaut les API du SDK Android lancent une "exception" si il y a un quelconque problème dans la communication SSL. Le problème peut venir d'une autorité de certification inconnue, un problème d'implémentation du protocole SSL (version, handshake) ...

Le problème le plus fréquent est l'autorité de certification inconnue. Plutôt que de payer 80€/an un certificat SSL, quelques développeurs créent leur propre autorité de certification (self-signed cert).
Comme Android refuse par défaut le certificat self-signed, le développeur adapte l'application pour qu'elle l'accepte malgré le primo-refus d'Android.

Ce mécanisme n'est pas vraiment un problème si le developpeur prend des mesures supplémentaires qu'on verra plus tard.

Détection des apps qui acceptent les self-signed


Prenons un exemple simple pour faire un HTTP GET sur Twitter en https.
Trois lignes de JAVA suffisent :
HttpGet request = new HttpGet("http://search.twitter.com/search.json?q=blue%20angels&rpp=5&include_entities=true&result_type=mixed");
HttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(request);

Maintenant ce qu'on trouve le plus communément pour un certificat self-signed, ce code est DÉCONSEILLÉ tel quel :
public static HttpClient wrapClient(HttpClient base) {
 try {
  SSLContext ctx = SSLContext.getInstance("TLS");
  X509TrustManager tm = new X509TrustManager() {

   @Override
   public void checkClientTrusted(
     java.security.cert.X509Certificate[] chain,
     String authType)
     throws java.security.cert.CertificateException {
    // TODO Auto-generated method stub

   }
   @Override
   public void checkServerTrusted(
     java.security.cert.X509Certificate[] chain,
     String authType)
     throws java.security.cert.CertificateException {
    // TODO Auto-generated method stub
   }

   @Override
   public java.security.cert.X509Certificate[] getAcceptedIssuers() {
    // TODO Auto-generated method stub
    return null;
   }
  };
  X509HostnameVerifier verifier = new X509HostnameVerifier() {

   @Override
   public boolean verify(String arg0, SSLSession arg1) {
    // TODO Auto-generated method stub
    return true;
   }

   @Override
   public void verify(String arg0, SSLSocket arg1)
     throws IOException {
    // TODO Auto-generated method stub
   }

   @Override
   public void verify(String arg0,
     java.security.cert.X509Certificate arg1)
     throws SSLException {
    // TODO Auto-generated method stub
   }

   @Override
   public void verify(String arg0, String[] arg1, String[] arg2)
     throws SSLException {
    // TODO Auto-generated method stub
    }
  };
  ctx.init(null, new TrustManager[] { tm }, null);
  SSLSocketFactory ssf = new SSLSocketFactory(ctx);
  ssf.setHostnameVerifier(verifier);
  ClientConnectionManager ccm = base.getConnectionManager();
  SchemeRegistry sr = ccm.getSchemeRegistry();
  sr.register(new Scheme("https", ssf, 443));
  return new DefaultHttpClient(ccm, base.getParams());
 } catch (Exception ex) {
  ex.printStackTrace();
  return null;
 }
}
(...)
HttpGet request = new HttpGet("http://search.twitter.com/search.json?q=blue%20angels&rpp=5&include_entities=true&result_type=mixed"
HttpClient httpClient = new DefaultHttpClient();
httpClient = wrapClient(httpClient);
HttpResponse response = httpClient.execute(request);
(...)
Soyons clairs, ce code là ne fait QUE accepter TOUS les certificats, signés ou non. Le développeur doit vérifier ensuite l'IP et/ou l'autorité ce certification et/ou le hash du certificat.

Les auteurs de l'étude ont téléchargé 13500 applications depuis le PlayStore puis les ont dé-compilé (AndroGuard+MalloDroid).
Ils ont recherché dans le code les mots clefs de la gymnastique Java nécessaire à l'acceptation des certificats self-signed (AcceptAllTrustM AllTrustM DummyTrustM EasyX509TrustM  .. page 54).

Les attaques qui marchent

Les auteurs de l'étude font un tour d'horizon des attaques SSL qui aboutissent à coup sûr lorsqu'une application désactive les erreurs SSL et qui peuvent également aboutir dans certains cas. 
  • Attaque mitm, pour man in the middle. Une machine fait proxy SSL entre Android et le serveur par exemple Twitter.com. Cette attaque fonctionne avec toutes les application "normales" et un Android configuré pour l'attaque (= l'autorité de certification utilisée par l'outil de mitm à été ajoutée dans Android).
  • Les attaques réseaux (attaque arp poison ou dns menteur ou iptables ou ...), qui renvoie vers une machine piège plutôt que la légitime. Cette attaque fonctionne dans les mêmes condition qu'une attaque mitm.
  • L'attaque sslstrip. C'est un proxy (attaque arp poison ou dns menteur ou iptables ou ...) qui piège l'utilisateur distrait qui saisi "paypal.com" dans son navigateur. Le proxy propose un faux paypal en http qui communique en httpS avec le vrai serveur "paypal.com" mais en http avec le terminal Android. Cette attaque ne fonctionne qu'avec un navigateur et par défaut avec Android.

Comment "bien" faire ?

Le point commun de toutes ces attaques est qu'une machine intermédiaire lit ce qu'il se passe.

Dans l'idéal :
  • Toute communication doit être faite en SSL
  • L'application doit vérifier l'IP résolue par le nom
  • L'application doit comparer l'autorité de certification du certificat avec une liste interne
  • L'application doit comparer le hash du certificat avec une liste interne.
  • L'application doit utiliser des tokens contre le rejeu
Les auteurs de l'étude préconisent aussi :
  • Que Google inclue un "vérificateur" d'APK basé sur MalloDroid avant de l'installer (analyse statique heuristique ou par signature)
  • HTTPS EveryWhere
  • Une distinction entre INTERNET_PLAIN et INTERNET_SSL pour informer les utilisateurs d'une probable communication "en-clair".

Conclusion

Comme écrit sur Twitter l'application analysée par mes soins la plus sérieuse est le client officiel Twitter qui, comme les autres, prête au moins un flanc aux attaques et fini par livrer en clair ses communications … et ses tokens.

2012-10-23

SMATAB 700 : installer le PlayStore

J'ai presque testé pour vous la tablette SMAT@B 700 proposée par Fiducial Office Solution, notre gentil fournituriste.

N'attendez rien d'extraordinaire pour la centaine d'euro (TTC), mais si vous souhaitez l'utiliser dans votre SI, soyez méfiants. Cette tablette est insécurisée et ne se sécurise pas.

Présentation

Ce qui ne va pas, matériellement : l'écran est salissant, la webcam est poussive, les touches physiques sont cheap, la prise USB mini-B.

Ce qui ne va pas logiciellement : pas de PlayStore, pas les Contacts Android, le launcher est peu réactif, ADB activé par défaut. Le fichier /etc/default.prop est a priori ignoré, la tablette ne peut être mise en mode "production builds".

Ce qui est susceptible de vous intéresser matériellement : un cable pour faire de l'USB-Host, une sortie hdmi, 2 modes de recharges.

Et vous intéresser  logiciellement : Android en mode débogage (= adb root), la partition /system/ montée

Activer le play store

Le PlayStore est actif mais masqué par défaut. Il existe 3 moyens d'y accéder
  1. En cherchant le mot "Play" dans la barre de recherche du launcher
  2. Par adb shell
    am start com.android.vending 
  3. Avec une application minimale

Activer les contacts

Le carnet d'adress est actif mais masqué par défaut. Il existe 3 moyens d'y accéder
  1. En cherchant le mot "Cont" dans la barre de recherche du launcher
  2. Par adb shell
    am start com.android.contacts
  3. Avec une application minimale

L'application minimale

package net.cekage.shortcut;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;

public class Shortcut extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  Intent intent = new Intent(Intent.ACTION_MAIN);
  intent.setComponent(new ComponentName("com.android.vending",
    "com.android.vending.AssetBrowserActivity"));
  startActivity(intent);
  finish();
 }
}

A acheter ou pas ?

C'est une tablette de niche, rien ne semble correctement fini :
  • hackable mais non évolutive.
  • Ouverte aux GApps mais celles-ci sont cachées. 
  • Interface tablette mais trop faible résolution, le texte est trop aliasé.
  • Autonome mais pas trop : la batterie s'épuise vite.
A mon humble avis, sa meilleure utilisation est un device d'appoint pour tester ses développements ailleurs que sur l'émulateur.

2012-10-08

stat_sys_adb en SVG


Pour le nouveau logo de adb_lock j'ai eu besoin d'utiliser les images utilisée par Android lorsque le téléphone est en mode débogage.

Si vous travaillez avec Inkscape voici un pense-bête pour les effets chez carnivora-publishing. Si vous utilisez Inkscape pour MountainLion et que libxml2 vous fait des misères, voyez chez lrem.net.

Le SVG est fait main, il n'est donc pas exactement identique à l'icône Android :

SVG file :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   sodipodi:docname="logo-debug.svg"
   inkscape:version="0.48.2 r9819"
   version="1.1"
   id="svg2"
   height="744.09448"
   width="1052.3622"
   inkscape:export-xdpi="71.966667"
   inkscape:export-ydpi="71.966667">
  <title
     id="title36756">stat_sys_adb SVG</title>
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="0.16136213"
     inkscape:cx="-1335.2764"
     inkscape:cy="-427.65272"
     inkscape:document-units="px"
     showgrid="false"
     showguides="true"
     inkscape:guide-bbox="true"
     inkscape:window-width="1440"
     inkscape:window-height="821"
     inkscape:window-x="194"
     inkscape:window-y="15"
     inkscape:window-maximized="0"
     inkscape:current-layer="layer4" />
  <defs
     id="defs4" />
  <metadata
     id="metadata7">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title>stat_sys_adb SVG</dc:title>
        <dc:date>2012-10-07</dc:date>
        <dc:creator>
          <cc:Agent>
            <dc:title>CeKaGe</dc:title>
          </cc:Agent>
        </dc:creator>
        <dc:rights>
          <cc:Agent>
            <dc:title>http://sam.zoy.org/wtfpl/COPYINGs</dc:title>
          </cc:Agent>
        </dc:rights>
        <dc:publisher>
          <cc:Agent>
            <dc:title>CeKaGe</dc:title>
          </cc:Agent>
        </dc:publisher>
        <dc:language>fr_FR</dc:language>
        <dc:description>Entirely based on Android SDK icon stat_sys_adb.png</dc:description>
        <cc:license
           rdf:resource="http://sam.zoy.org/wtfpl/COPYING" />
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:label="ronds"
     id="layer4"
     inkscape:groupmode="layer"
     transform="translate(0,-308.2677)">
    <path
       inkscape:connector-curvature="0"
       id="stat_sys_adb_ICS"
       d="m 129.8507,642.21771 c -1.56864,0.0448 -3.2899,0.50893 -5.2016,1.42102 -9.03946,8.14097 5.74203,15.8443 8.88078,28.31903 -4.65862,7.40003 -39.088256,21.29558 -41.003826,68.41228 l 187.714306,-0.12688 c -3.76065,-34.15455 -14.14904,-49.52154 -40.52173,-68.00627 2.70742,-13.78943 14.50986,-14.54933 8.17032,-28.87729 -14.79482,-5.29954 -15.44999,10.49324 -23.01391,20.12275 l -76.60307,0.81202 c -5.88875,-10.99361 -9.9506,-22.3189 -18.42127,-22.07666 z m 16.97498,46.53862 c 6.60523,0 11.95099,5.11722 11.95099,11.44434 0,6.32711 -5.34576,11.46971 -11.95099,11.46971 -6.60525,0 -11.97637,-5.1426 -11.97637,-11.46971 0,-6.32712 5.37112,-11.44434 11.97637,-11.44434 z m 47.42336,0.76126 c 6.30715,0 11.41815,4.93475 11.41815,11.03833 0,6.10359 -5.111,11.06371 -11.41815,11.06371 -6.30716,0 -11.41815,-4.96012 -11.41815,-11.06371 0,-6.10358 5.11099,-11.03833 11.41815,-11.03833 z M 50.278914,749.80972 c -9.76592,0 -17.63469,7.86933 -17.63469,17.63595 l 0,96.70596 c 0,9.76659 7.86877,17.6105 17.63469,17.6105 l 9.08377,0 c 9.76592,8e-5 17.60932,-7.84391 17.60932,-17.6105 l 0,-96.70596 c 0,-9.76662 -7.8434,-17.63595 -17.60932,-17.63595 l -9.08377,0 z m 262.820336,0 c -9.76592,0 -17.63469,7.86933 -17.63469,17.63595 l 0,96.70596 c 0,9.76659 7.86877,17.6105 17.63469,17.6105 l 9.05839,0 c 9.76592,8e-5 17.63469,-7.84391 17.63469,-17.6105 l 0,-96.70596 c 0,-9.76662 -7.86877,-17.63595 -17.63469,-17.63595 l -9.05839,0 z m -187.51133,4.28845 c -18.64403,0 -33.645456,14.05482 -33.645456,31.51634 l 0,173.08606 c 0,17.46181 15.001426,31.51625 33.645456,31.51645 l 92.41086,0 c 0.0114,-9.51019 2.16996,-16.34988 2.23288,-25.85768 0.72073,-8.80054 7.65517,-17.57534 16.46751,-17.40758 5.16247,0.0138 11.91344,-1.59877 17.07647,-1.59861 0.0115,-8.97699 -1.55644,-15.81684 -1.49705,-24.79188 0.72073,-8.80054 7.65517,-17.601 16.46751,-17.43291 2.63471,0.008 5.71079,-0.17597 9.08376,-0.45684 l 0,-117.05701 c 0,-17.46152 -15.00144,-31.51634 -33.64546,-31.51634 l -118.59648,0 z m 2.10602,14.41327 69.52382,0 c 10.92892,0 19.89022,12.28426 19.71533,27.53239 l -1.0657,93.15335 c -32.68796,-0.87381 -31.83327,22.79221 -29.05283,42.07254 -23.12641,0.0674 -34.62109,8.71097 -34.33056,42.90997 l -27.4543,0.53284 c -10.92687,0.21259 -17.05109,-12.25794 -17.05109,-27.50701 l 0,-151.16169 c 0,-15.24914 8.7864,-27.53239 19.71533,-27.53239 z m 58.10567,33.82551 0,15.68204 15.96003,0 0,-15.68204 -15.96003,0 z m -62.36845,0.0253 0,15.68205 15.7063,0 0,-15.68205 -15.7063,0 z m 31.28572,31.33872 0,15.93582 15.85854,0 0,-15.93582 -15.85854,0 z m 31.2096,31.23719 0,15.68204 15.83316,0 0,-15.68204 -15.83316,0 z m -62.67293,0.0503 0,15.68205 15.70629,0 0,-15.68205 -15.70629,0 z m 31.36184,31.36409 0,15.52979 15.73167,0 0,-15.52979 -15.73167,0 z m -31.26035,31.33875 0,15.75813 15.78242,0 0,-15.75813 -15.78242,0 z"
       style="color:#000000;fill:#33b5e5;fill-opacity:1;stroke:#33b5e5;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
       inkscape:label="#path5309"
       inkscape:export-xdpi="72"
       inkscape:export-ydpi="72" />
    <path
       style="fill:#33b5e5;fill-opacity:1;fill-rule:nonzero;stroke:none"
       d="m 926.06018,714.17829 c -27.22353,-12.00453 -30.55244,42.51128 -35.0691,41.25189 -34.67205,-9.66763 -80.71112,-7.81977 -122.07702,0.004 -22.48447,4.25265 -58.38589,14.8761 -78.22496,24.33748 -12.49865,-4.28099 -28.95334,-49.73487 -48.87993,-33.00071 -11.57241,15.98748 24.68234,50.79657 18.2805,60.47016 -25.23911,38.13797 -41.05442,21.97111 -42.4231,98.3444 -0.91334,50.967 32.22027,108.49709 134.71262,86.42742 19.67802,-4.23735 35.50576,-9.52521 56.73124,-9.60298 39.57385,-0.14536 96.83676,7.89129 121.02155,-5.93925 44.38563,-25.38236 59.22363,-62.1197 59.55063,-97.34376 0.5,-53.86529 -37.73872,-93.1189 -71.35197,-110.15389 17.36884,-34.1089 21.90616,-48.65518 7.72954,-54.79446 z m -61.41404,109.33792 c 8.51986,0 15.42657,6.38378 15.42657,14.23102 0,7.84725 -6.90671,14.19246 -15.42657,14.19246 -8.51987,0 -15.42659,-6.34521 -15.42659,-14.19246 0,-7.84724 6.90672,-14.23102 15.42659,-14.23102 z m -134.78976,8.94742 c 8.96828,0 16.23648,5.98373 16.23648,13.38256 0,7.39884 -7.2682,13.38256 -16.23648,13.38256 -8.96828,0 -16.23647,-5.98372 -16.23647,-13.38256 0,-7.39883 7.26819,-13.38256 16.23647,-13.38256 z"
       id="stat_sys_adb_JB"
       inkscape:connector-curvature="0"
       sodipodi:nodetypes="cssccssscssccssssssssss"
       inkscape:label="#path4733"
       inkscape:export-xdpi="72"
       inkscape:export-ydpi="72" />
    <path
       sodipodi:nodetypes="cccccccccccccscccsssssssssssssssssscccccccccccccccccccccccccccccsssscccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
       inkscape:connector-curvature="0"
       id="stat_sys_adb_GB"
       d="m 451.07406,339.14504 c -0.86677,-0.019 -1.73909,0.2364 -2.48694,0.75793 l -2.65279,1.84748 c -1.99436,1.39066 -2.38174,4.23619 -0.8764,6.3951 l 21.19861,30.43591 c -28.23061,17.45288 -48.75443,48.92262 -48.55539,93.32118 l 208.45656,-0.30795 c 0.25588,-45.60482 -19.65614,-76.72416 -47.20527,-93.70008 l 20.74855,-29.74906 c 1.50534,-2.15891 1.11796,-5.00444 -0.8764,-6.3951 l -2.65279,-1.84748 c -1.99436,-1.39066 -4.81866,-0.78514 -6.324,1.37377 l -21.53021,30.90961 c -14.49958,-6.66462 -30.50231,-9.86084 -46.47107,-9.63998 -15.42556,0.21336 -30.85702,3.68714 -44.93147,10.27953 l -22.00393,-31.54916 c -0.94082,-1.34928 -2.39243,-2.10033 -3.83706,-2.1317 z m 26.52783,55.40048 12.60072,0 c 2.43131,0 4.40551,2.1289 4.40551,4.76084 l 0,25.53303 c 0,2.63194 -1.9742,4.73712 -4.40551,4.73712 l -12.60072,0 c -2.43131,0 -4.38179,-2.10518 -4.38179,-4.73712 l 0,-25.53303 c 0,-2.63194 1.95048,-4.76084 4.38179,-4.76084 z m 75.79379,0 12.60072,0 c 2.43131,0 4.40552,2.1289 4.40552,4.76084 l 0,25.53303 c 0,2.63194 -1.97421,4.73712 -4.40552,4.73712 l -12.60072,0 c -2.43131,0 -4.38179,-2.10518 -4.38179,-4.73712 l 0,-25.53303 c 0,-2.63194 1.95048,-4.76084 4.38179,-4.76084 z m -167.81215,86.92609 c -2.52629,-0.008 -5.01801,0.61809 -7.55573,0.5921 -4.81321,0.23374 -9.63241,0.22571 -14.4482,0.37897 -6.19591,0.10959 -11.13138,5.0778 -13.33493,10.54011 -1.92455,4.95092 -2.68818,10.66388 -0.92377,15.77458 1.15994,3.3294 4.16775,6.32984 7.91097,6.15825 4.53672,0 8.14094,-3.09709 11.96125,-5.06871 7.5555,-3.03979 16.32197,-0.42498 22.40654,4.57135 3.49424,1.85331 7.59204,-0.15273 10.01895,-2.84227 2.41131,-2.45276 3.82251,-5.82763 3.64758,-9.28474 -0.10179,-10.12188 -8.36468,-19.85441 -18.59313,-20.77227 -0.36244,-0.0303 -0.72868,-0.0462 -1.08953,-0.047 z m 286.23994,0 c -2.52621,-0.008 -5.01793,0.61809 -7.55566,0.5921 -4.81321,0.23374 -9.63248,0.22571 -14.44819,0.37897 -6.19591,0.10959 -11.1551,5.07788 -13.35865,10.54011 -1.92456,4.95092 -2.66454,10.66388 -0.90006,15.77458 1.15988,3.32947 4.16775,6.32977 7.91098,6.15825 4.53671,0 8.14094,-3.09701 11.96117,-5.06871 7.55558,-3.03971 16.29832,-0.42498 22.38289,4.57135 3.49425,1.85331 7.61569,-0.1528 10.04268,-2.84227 2.41131,-2.45284 3.82243,-5.82771 3.64758,-9.28474 -0.10179,-10.12196 -8.36468,-19.85441 -18.5932,-20.77227 -0.36245,-0.0303 -0.72861,-0.0462 -1.08954,-0.047 z m -254.14605,1.94221 0,21.17489 0,29.22798 -0.41989,100.61763 c -0.0493,11.72007 22.47195,34.13191 34.19209,34.16845 l 134.89135,0.41989 c 11.72022,0.0364 37.75447,-21.61002 37.94766,-33.32865 l 1.67959,-101.87732 0,-29.22798 0,-21.17489 -21.15116,0 -165.96475,0 z m -32.09389,48.53175 c -2.52629,-0.008 -5.01801,0.6181 -7.55573,0.5921 -4.81321,0.23375 -9.63241,0.22572 -14.4482,0.37897 -6.19591,0.1096 -11.13138,5.07781 -13.33493,10.54011 -1.92455,4.95093 -2.68818,10.66389 -0.92377,15.77459 1.15994,3.32939 4.16775,6.32977 7.91097,6.15817 4.53672,0 8.14094,-3.09701 11.96125,-5.06864 7.5555,-3.03978 16.32197,-0.42505 22.40654,4.5712 3.49424,1.85331 7.59204,-0.15272 10.01895,-2.84219 2.41131,-2.45269 3.82251,-5.82763 3.64758,-9.28474 -0.10179,-10.12188 -8.36468,-19.85433 -18.59313,-20.7722 -0.36244,-0.0303 -0.72868,-0.047 -1.08953,-0.047 z m 286.23994,0 c -2.52621,-0.008 -5.01793,0.6181 -7.55566,0.5921 -4.81321,0.23375 -9.63248,0.22572 -14.44819,0.37897 -6.19591,0.10952 -11.1551,5.07781 -13.35865,10.54011 -1.92456,4.95093 -2.66454,10.66389 -0.90006,15.77459 1.15988,3.32939 4.16775,6.32977 7.91098,6.15817 4.53671,0 8.14094,-3.09701 11.96117,-5.06864 7.55558,-3.03978 16.29832,-0.42505 22.38289,4.5712 3.49425,1.85331 7.61569,-0.15272 10.04268,-2.84219 2.41131,-2.45269 3.82243,-5.82763 3.64758,-9.28474 -0.10179,-10.12196 -8.36468,-19.85441 -18.5932,-20.7722 -0.36245,-0.0303 -0.72861,-0.047 -1.08954,-0.047 z m -286.23994,50.47382 c -2.52629,-0.008 -5.01801,0.61817 -7.55573,0.59217 -4.81321,0.23375 -9.63241,0.22572 -14.4482,0.37897 -6.19591,0.1096 -11.13138,5.07781 -13.33493,10.54012 -1.92455,4.95085 -2.68818,10.6638 -0.92377,15.7745 1.15994,3.32947 4.16775,6.35357 7.91097,6.18197 4.53672,0 8.14094,-3.12081 11.96125,-5.09236 7.5555,-3.03986 16.32197,-0.42505 22.40654,4.57128 3.49424,1.85331 7.59204,-0.15272 10.01895,-2.84227 2.41131,-2.45276 3.82251,-5.82763 3.64758,-9.28474 -0.10179,-10.12188 -8.36468,-19.85441 -18.59313,-20.7722 -0.36244,-0.0303 -0.72868,-0.047 -1.08953,-0.0478 z m 286.23994,0 c -2.52621,-0.008 -5.01793,0.61817 -7.55566,0.59217 -4.81321,0.23375 -9.63248,0.22572 -14.44819,0.37897 -6.19591,0.1096 -11.1551,5.07781 -13.35865,10.54012 -1.92456,4.95085 -2.66454,10.6638 -0.90006,15.7745 1.15988,3.32947 4.16775,6.35357 7.91098,6.18197 4.53671,0 8.14094,-3.12081 11.96117,-5.09236 7.55558,-3.03986 16.29832,-0.42505 22.38289,4.57128 3.49425,1.85331 7.61569,-0.15272 10.04268,-2.84227 2.41131,-2.45276 3.82243,-5.82763 3.64758,-9.28474 -0.10179,-10.12188 -8.36468,-19.85441 -18.5932,-20.7722 -0.36245,-0.0303 -0.72861,-0.047 -1.08954,-0.0478 z"
       style="opacity:0.91588780999999997;fill:#99cc00;fill-opacity:1;fill-rule:nonzero;stroke:#99cc00;stroke-width:0;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:50"
       inkscape:label="#rect4314"
       inkscape:export-xdpi="72"
       inkscape:export-ydpi="72" />
  </g>
</svg>

2012-09-13

Achat in-app : attention aux signatures

APK avec signature de test vs signature développeur. 

 Le plug-in ADT pour Eclipse simplifie considérablement le travail de signature d'une application. En effet ADT signe avec une clef de test votre APK pour une future installation sur un terminal (ou émulateur).

Si pratique qu'elle soit, la clef de test sera refusée par le PlayStore : chaque développeur doit créer sa propre clef pour une signature unique.

Dans ce monde manichéen nous avons donc des APK signés avec la clef développeur sur le PlayStore et des APK signées par ADT. Et lorsqu'on essaye de faire un achat in-app :


Erreur liée à l'application
Cette version de l'application n'est pas configurée pour la facturation via Google Play. Pour plus d'informations, veuillez consulter le centre d'aide.


Ne cherchez pas trop longtemps le centre d'aide. Cette erreur est causée par la signature de l'APK.

Comment automatiser la signature avec sa clef de développement ?

Utilisons encore la documentation Android sur la signature avec jarsigner :
$ jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore my.keystore \
-storepass PA55W0RDST0RE -keypass PA55W0RDKEY my.apk myDevNickName

Il y a de très fortes chances que vous obteniez ce message :

jarsigner: unable to sign jar: java.util.zip.ZipException: invalid entry compressed size (expected 765 but got 771 bytes)

Ce message, comme son code erreur ne l'indique pas, est causé par la présence d'une signature dans l'APK : vous avez utilisé l'APK créée par ADT et stockée dans workspace/MyAndroidApp/bin/ qui est en fait signée avec la clef temporaire.

Pour supprimer la précédente signature, une simple commande zip (manpage):
zip my.apk -d "META-INF/*"

En un script : signandup.sh

#!/bin/sh
zip my.apk -d "META-INF/*"
jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore my.keystore \
-storepass PA55W0RDST0RE -keypass PA55W0RDKEY my.apk myDevNickName
adb install -r my.apk

2012-06-28

Les détails sympas de JellyBean Android 4.1

Vous avez-vu les vidéos avec du JellyBean ? C'était rapide ? Oui ... 60 fps ça pardonne pas !

Prenons quelques minutes, statiques, et regardons vers où JellyBean nous mène.


Le nouveau logo de debug Android : une droidgibus !!

Le feedback du déplacement du doigt sur le lock-screen

Pour réduire le clavier on utilise une flèche vers le bas. Logique non ?

Les "receivers" sont affichés sur 2 colonnes ET le texte desactivé est "limite" visible.

Feedback de la position du doigt. On ne retrouve pas le même que le lockscreen mais les deux bleus holo combinés

En revanche sur la home, le feedback du lock-screen. La boule "Google" est pour "Google Now".

Application "Photo". A gauche l'application et a droite la "Galerie" avec un slide du doigt (en rouge).

Redimensionnement des widgets.

La date est complète mais compacte, L'icone pour les parametres et l'escalier pour chasser toutes les notifications.

LongClick sur une notification : on va pouvoir trouver l'application qui notifie ! Yeah !

Future option ?

Vous remarquez ? Les "switchers" sont à angles droits !

Le popup à les coins légèrement arrondis et il y a 3 gris.
Freenaute, il n'y a pas d'EAP-SIM :(


L'icône plus, très moche, n'a pas été mise à la poubelle. Pire, on lui adjoint un "refresh" "réussi".

Amélioration du menu Application : réinitialiser les associations par défaut.

Précision pertinente.

Nouveautés pertinente pour les tablettes !

Voila voila, on va pouvoir limiter les gros vilains qui fouinent sur la SD :)

Il va falloir patcher :)

C'est qui qui publie avec les options de débogage ? Hein ?

Pour faire apparaitre l'easter egg : comme pour toutes les autres versions.

Tadaaaaaaaaaaaaaaa !

Tiens ... un nouveau feedback ?

Voila, votre prochain achat sera un Nexus.

2012-06-25

Maîtrisez vos versions beta avec Zubhium

[Billet non sponsorisé]

Google Play Store

Distribuer des versions instables de ses applications via le Play Store est périlleux pour la distribution et surtout pour son image de marque.

Le principal avantage est que l'utilisateur n'a pas besoin de changer les paramètres de son terminal pour installer l'application, on bénéficie des serveurs de google et on est tiré vers le haut par les exigences (capture d'écran, bannière, description, ...).

Comme inconvénients, il y a justement la lourdeur des informations obligatoires, l'absence de kill-switch et la suppression des versions anciennes (juste désactivées). Le principal inconvénient est (de très loin) la horde de crétins insidieusement infiltrée dans le reste des utilisateurs :

Jusqu'à présent j'utilisais l'auto hébergement avec un réducteur d'URL efficace et prévenais mes volontaires par sms/mail. C'est au détour d'une lecture de StackOverFlow que j'ai découvert Zubhium ...

La solution zubhium.com


Zubhium est un service en beta et gratuit qui se propose pour l'hébergement de vos apk, la notification des nouvelles versions, le recueil des crashlogs (optionnel) et des feedback (anonymes) des utilisateurs. Il faut préalablement s'inscrire et le système est prêt à fonctionner.

Déclarer un apk

Tout commence par la déclaration de votre beta. Plus simple que Google : un nom, une icône et une description.

L'étape suivante est l'envoi de l'apk, phase très simple qui fonctionne même si on utilise l'apk signée par Eclipse (disponible dans bin/ !).

La dernière étape est la déclaration des adresses e-mail des vos cobayes. Vos cobayes n'ont pas besoin de s'inscrire, l'adresse ne sert qu'à les prévenir.

Les règles de confidentialité sont précisées ici, à vous de juger de l'opportunité de déclarer telle ou telle adresse e-mail.

Vous pouvez également distribuer un lien direct vers votre beta en le copiant/collant dans un tweet par exemple.

Déclarer une nouvelle version


Les nouvelles versions sont nommées "push". Il n'y a que deux contraintes pour faire un nouveau push ce qui rend l'opération largement plus simple que sur le Play Store. Votre apk doit avoir une version supérieure aux "push" existants et vous devez déclarer les modifications apportées.

Ces modifications seront transmises à vos volontaires dans le corps de l'email de notification. Notez que jusqu'à présent il n'est pas nécessaire d’intégrer le SDK de Zubhium à l'application.

Bloquer une ancienne version

Plusieurs raisons peuvent vous emmener à clôturer une version : cesser de recevoir des crash-logs dus à un bug résolu, orienter vers une nouvelle beta ou tout simplement passer à la version officielle sur le site marchand de Google ou Amazon.

Pour pouvoir interagir avec une ancienne beta, il faut nécessairement intégrer le SDK. La documentation est suffisamment bien rédigée pour ne pas l'aborder dans ce billet. Si vous avez des soucis on peut en causer sur twitter.

Le blocage se fait dans l'onglet "Manage" et en cliquant sur "LIVE" :

L'interface vous propose de
  • Envoyer un message qui sera affiché à chaque démarrage de l'application dont la version beta a expiré.
  • Proposer aux utilisateurs un lien vers une beta plus récente OU un store (Google ou Amazon)
  • Forcer l'utilisateur à passer à la version officielle (Google ou Amazon) en bloquant complètement l'application (Kill-switch)

Les crashlogs


Comme précisé dans la documentation, Zubhium peut servir de back-end à ACRA et ainsi agréger les informations obtenues :

En savoir plus sur le terminal:

L'état du réseau :

La pile :

Les logs (que je n'active JAMAIS) :

Et le dump :

Limite plus pratique que DDMS non ?

Bilan

Ça marche et ça marche excellemment bien ! C'est un outil bien pensé et gratuit.

Le SDK permet, sans effort de développement de garder la main sur sa beta et de récupérer les crash de manière textuelle ET graphique. J'adooooore la possibilité d'uploader un apk non signé !

Il est dommage que la fenêtre de feedback ne soit pas (encore) internationalisée, ça peut freiner les cobayes anglophobes. Il y aurait également la possibilité de faire pointer la fin d'une beta vers la toute dernière version.

Bref, je souhaite à Zubhium un bon développement et de perdurer dans la philosophie KISS et surtout de perdurer dans le temps.

Nice works guys.

2012-06-16

Appliquer un gradient XML pour le contour d'un shape


Pour l'instant (SDK API LEVEL 15) il n'est pas possible de mettre un gradient comme contour d'une forme géométrique dans un drawable.

Le contour se définit par l'élément <stroke> dans le drawable et n'accepte comme paramètre de couleur android:color qui est soit une ressource "color" soit une couleur littérale.

Je vais détailler comment faire ce contour en dégradé uniquement avec les drawables XML, donc sans utiliser de bitmap (png).

Stroke par l'exemple

Prenons le drawable XML (res/drawable/radiogroup2.xml) suivant :

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#000" />
    <stroke
        android:width="3dip"
        android:color="#0af" />
    <corners android:radius="5dip" />
</shape>
que j'applique à un widget de l'interface :
<RadioGroup
            android:id="@+id/rgModeGPS"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:background="@drawable/radiogroup2" >
(...)
</RadioGroup>
Qui donne ceci :

Gradient par l'exemple

On peut s'approcher de notre objectif en utilisant un gradient (res/drawable/radiogroup3.xml) :
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#000" />
    <gradient
        android:angle="270"
        android:endColor="#0048ff"
        android:startColor="#00fffc"  />
    <corners android:radius="5dip" />
</shape>
que j'applique à un widget de l'interface :
<RadioGroup
            android:id="@+id/rgModeGPS"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:background="@drawable/radiogroup3" >
(...)
</RadioGroup>
Qui donne ceci :

Solution

La solution passe par l'utilisation simultanée du dégradé et d'un rectangle noir. Pour cela il faut utiliser plusieurs couches (layer)

Le drawable XML (res/drawable/radiogroup3.xml) doit comprendre un item avec le gradient et un item avec solid noir  :
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- Définition du gradient -->
    <item
        android:bottom="0dip"
        android:left="0dip"
        android:right="0dip"
        android:top="0dip">
        <shape>
            <solid android:color="#112233" />

            <gradient
                android:angle="270"
                android:endColor="#0048ff"
                android:startColor="#00fffc" />

            <corners android:radius="5dip" />
        </shape>
    </item>
    
    <!-- Définition du fond noir -->
    <item
        android:bottom="5dip"
        android:left="5dip"
        android:right="5dip"
        android:top="5dip">
        <shape>
            <!-- Le padding aère le contenu -->
            <padding
                android:bottom="10dip"
                android:left="10dip"
                android:right="10dip"
                android:top="10dip" />

            <solid android:color="#000" />

            <corners android:radius="5dip" />
        </shape>
    </item>

</layer-list>
      Tadaaaaaaaaaaaaaa!

2012-05-27

Suivre ses comptes bancaires avec linxo

Ce billet n'est pas sponsorisé.

3615 mavie.

Mes différents déménagements et projets m'ont emmené à avoir plusieurs comptes bancaires dans plusieurs banques. Par fidélité et un petit peu par laisser-aller j'ai donc des revenus qui "tombent" sur plusieurs comptes et surtout des prélèvements automatiques sur des comptes que je surveille peu.

En attendant le courage de fermer les comptes et donner les nouveaux RIB, je me sers des sites web des banques ou des applications mobiles. Dans le premier cas il faut systématiquement s'authentifier et c'est pénible (surtout chez Tarneaud) et dans l'autre cas c'est trop souvent un portage bridé de la version iOS (inadaptée à Android).

2012-05-06

Quelques conseils sur SeekBar.setThumb()

Toujours dans mon projet de tracking GPS, j'utilise une SeekBar comme feedback de l'état de progression. Le véhicule se déplace sur toute la longueur de l'écran symbolisant la distance parcourue depuis l'événement n-1 et celle à parcourir avant l'évènement n.

Techniquement, la SeekBar, barre de progression, utilise un curseur (nommé thumb) qui est un Drawable.

Problème 1 : afficher complètement le thumb.

Lorsque la progression de la SeekBar est à 0, le curseur était affiché à moitié. Réciproquement une seule moitié était affichée lorsque le curseur est au maximum.
La solution se trouve dans la documentation de l'API :
sb.setThumbOffset(0);
Explication par le source Android AbsSeekBar.java:
108    // Assuming the thumb drawable is symmetric, set the thumb offset
109    // such that the thumb will hang halfway off either edge of the
110    // progress bar.
111    mThumbOffset = thumb.getIntrinsicWidth() / 2;

Problème 2 : setThumb fait disparaître le curseur.

Quelques secondes après l'affichage du Drawable comme curseur, ce dernier disparaissait.
La solution a été donnée par Romain GUY, il faut refaire une étape de setThumb() (cf paragraphe précédent)
Drawable retourDrawable;
retourDrawable = getResources().getDrawable(
  R.drawable.voituremgps1234);
retourDrawable.setBounds(new Rect(0, 0, 
  retourDrawable.getIntrinsicWidth(),
  retourDrawable.getIntrinsicHeight()));
sb.setThumb(retourDrawable);

Problème 3 : setThumb remet le curseur à 0

Ce problème m'a donné pas mal de fil à retordre. La responsabilité de setThumb dans le repositionnement du curseur n'est pas immédiate. C'est en procédant au pas à pas que le lien m'est apparu. Concrètement, le curseur est positionné à zéro mais ne réponds pas aux ordres de repositionnement.

C'est probablement dans l'API mais je n'ai pas trouvé.

Mon conseil est de mettre le curseur à une valeur nulle ou négative avant de le remettre à la bonne position :
sb.setThumb(retourDrawable); // Le drawable
sb.setProgress(-1); // progress négatif
sb.setProgress(positionThumb); // progress à la bonne place.

2012-04-26


Il y a deux jours, j'ai reçu un sms non sollicité, un spam.

Non mobilobox, c'est un numéro porté, je ne suis plus trait (meuh) par le cartel des 3 escrocs que sont Béton, Vivendi et Mandarine. Je suis chez FreeMobile ce qui te vaut la chance incroyable de ne pas être signalé au 33700.

Ça marche pas de chez çamarchepas.com

Ma version personnelle de SignalSpam envoie directement les SMS. Elle ne passe pas obligatoirement par “Intent.ACTION_VIEW“ comme la version grand public disponible sur le PlayStore.

Donc ... erreur sur erreur : l'application refuse obstinément d'envoyer le message au 33700. Mon code est correct, mais ça ne fonctionne pas. Par dépit je passe en mode “Intent.ACTION_VIEW“ pour laisser l'application native de ICS.

Diantre ... même l'application native se casse les dents.

Explications

Le 33700 est géré par l'Association SMS+ (association loi 1901) alias L'Association Française du Multimédia Mobile. L'AFMM précise sur une page de son site les opérateurs membres :
  •  Auchan Telecom
  • Bouygues Telecom
  • Debitel
  • NRJ Mobile
  • Omer Telecom
  • Orange France
  • Orange Réunion
  • SFR
  • SRR
  • Tele2 Mobile
  • Telegate
Il n'y a pas FreeMobile.

Steuplait Monsieur Free ...

Bon M. Free, nous savons toi et moi que ta marge de progression dans le mobile est géante. Tu es encore jeune et plein d'ambition.

Donc, si tu veux vraiment progresser dans le détail de confort inutile à 99% de la population des mobinautes, gère le 33700.

Toi et moi aimons ces détails inutiles qui ont fait ta singularité dans l'ADSL ;)

Message Perso : Hey mobilobox, fais-moi plaisir, internet c'est avec un I majuscule. Autre chose, qu'utilises-tu comme logiciel pourri en ASCII en 2012 ? Cet anachronisme technologique fait commercialement désordre.

2012-04-25

fill_parent ou match_parent

Selon votre plus ou moins grande ancienneté avec le SDK Android, il doit vous arriver de mélanger au sein d'une même description d'interface XML des “fill_parent“ ou des “match_parent“ pour vos “android:layout_width“ ou vos “android:layout_height“.

Les deux valeurs sont équivalentes, le widget doit prendre toute la place laissée vacante dans le widget parent. La différence réside dans la version de l'API. Si votre projet vise les SDK < 7, vous devez utiliser “fill_parent“. Au delà, pour le SDK 8 et supérieurs, la valeur conseillée est “match_parent“.

Si votre projet vise un numéro d'API strictement plus grand que 7 :
find . -iname "*.xml" -exec sed -i "" "s/fill_parent/match_parent/g" {} \;
Si votre projet vise un numéro d'API strictement inférieur ou égale à 7 :
find . -iname "*.xml" -exec sed -i "" "s/match_parent/fill_parent/g" {} \;


Plus de lecture : ici (Anglais).

2012-04-23

Mettre à jour un Galaxy Nexus chiffré sans perdre de données.

Dans un précédent billet, je donnais une méthode propre pour passer son Galaxy Nexus en rom aokp. Propre, ok mais au prix de vos données.
Il est possible de mettre à jour la partie ROM du terminal sans toucher à la partie RWM. Simple sans être trivial, voici comment faire.
Attention, cette méthode de mise à jour est conforme à l'esprit de la norme ISO 1664.

Sauvegardez vos données. Sauvegardez vos données. Sauvegardez vos données.

Cette méthode n'a été vérifiée QUE et UNIQUEMENT sur un terminal chiffré équipé d'une ROM AOKP.

Préparer la rom AOKP qui va bien.

Durant cette phase, les commandes seront exécutées sur mon ordinateur personnel. La préparation doit se faire sur une machine séparée pour plusieurs raisons :
  • On ne peut pas échanger de données entre une session chiffrée et une session en clair (cwm).
  • Zip et Bzip2 sont des opérations gourmandes en temps CPU et I/O.
Le billet est réalisé avec la build 32 de la rom aokp récupérable ici
Une fois téléchargé, je prépare 2 archives supplémentaires : system.zip et system.tar.bz2
$ cd /tmp/
$ unzip aokp_maguro_build-32.zip
$ cd aokp_maguro_build-32/system/
$ # Création de l'archive ZIP
$ zip -r ../../system.zip *
$ # Création de l'archive tar.bz2
$ tar cjf ../../system.tar.bz2 *
Un ordre d'idée des tailles obtenues :
$ ls -alh  /tmp/system.*
 -rw-r--r--  1 ckg  ckg   107M 17 avr 14:23 /tmp/system.tar.bz2
 -rw-r--r--  1 ckg  ckg   108M 17 avr 14:20 /tmp/system.zip

Sauvegardez apk+data (méthode intelligente)

Pour une sauvegarde en toute tranquillité, utilisez Titanium Backup ou Rerware Backup sur le play store.

Sauvegardez apk+data (méthode barbare)

~ # # Création des dossiers
~ # mkdir /mnt/sdcard/backup/apk
~ # mkdir /mnt/sdcard/backup/apk-data
~ # # Sauvegarde des apk
~ # cp /data/app/*.apk /mnt/backup/apk
~ # cd /data/data/
~ # # Purge des caches
~ # rm -r */cache/*
~ # # Dans l'absolu, lib/ est optionnel
~ # for i in *;do tar cjf /mnt/sdcard/backup/apk-data/$i.tar.bz2 $i;done;
Si vous souhaitez récupérer les sous-dossiers de /mnt/sdcard/backup via MTP il faut forcer le daemon mtp à recharger sa liste de fichier :
~ # pkill -HUP f_mtp 
il ne reste plus qu'a sauvegarder la carte SD.

Shell minimal : Clockwork Mode Recovery

La suite des opérations se fait dans le mode recovery.
$ adb reboot recovery
Une fois le recovery actif, je lance une session shell.
Le mount m'indique que seule la partition /cache est chargée :
~ # mount
rootfs on / type rootfs (rw)
tmpfs on /dev type tmpfs (rw,nosuid,relatime,mode=755)
devpts on /dev/pts type devpts (rw,relatime,mode=600)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
/dev/block/platform/omap/omap_hsmmc.0/by-name/cache on /cache type ext4 (rw,nodev,noatime,nodiratime,barrier=1,data=ordered)
Visiblement, pas de /system monté. Le chemin pour trouver /system est indiqué par /cache.
Pour monter /system :
~ # mkdir /x
~ # mount /dev/block/platform/omap/omap_hsmmc.0/by-name/system /x/
On peut vérifier :
~ # ls /x/
addon.d     build.prop  framework   media       tts         xbin
app         etc         lib         su-backup   usr
bin         fonts       lost+found  system      vendor
La partition /system/ n'est pas chiffrée.
Si votre téléphone est saisi par un tiers vous pouvez le considérer comme corrompu. Je reviendrai un autre jour sur le "comment détecter la compromission d'un terminal". C'est la fin de la phase de préparation depuis le shell minimal.

Pousser la rom aokp complete

Normalement, vous devriez avoir la place de pousser la rom complete dans le /data/media de votre terminal. Depuis l'ordinateur :
$ adb push system.zip /data/media
Depuis la session shell (adb shell)
~ # unzip -o /data/media/system.zip -d /x/
Si vous obtenez "unzip: zip flags 1 and 8 are not supported", utilisez l'archive system.tar.bz2 définie plus haut alors, depuis l'ordinateur :
$ adb push system.tar.bz2 /data/media
Depuis la session shell (adb shell)
~ # cd /data/media/
~ # bunzip2 system.tar.bz2
~ # tar xf system.tar -C /x/

Fin

Avant de débrancher, il faut umount puis reboot :
~ # umount /x/
~ # reboot

2012-04-16

import org.iso.9001.*;

Semaine sans Android ... l'audit de renouvellement par BVC s'est très bien passé. Ouf. Cependant d'après l'auditeur, le système documentaire gagnerait en pertinence en étant plus informatisé.

Note pour le futur, la maîtrise de la diffusion d'un document peut reposer en partie sur l'utilisateur final. Lorsque ce dernier effectue une consultation non maitrisée (document imprimé ou PDF) il s'engage à toujours se référer au document original. Cette pirouette est permise par l'esprit général du 6.2.1 que je limitais, à tort, à l'incidence sur la conformité du produit.

J'ai commencé ma formation avec le référentiel 1994 pour lequel le report d'une telle responsabilité était inenvisageable. 12 après la publication du référentiel 2000 il me reste des réflexes à dépoussiérer.

Comment prouver la vérification / validation / approbation du document ? Dans un premier temps, plaider la faible complexité de l'organisme qui m'emploie et me contenter de la mise à disposition du PDF sur un serveur partagé en lecture seule.
Dans un second temps, il faudra mettre en place une PKI et signer ces foutus PDF.

Il va falloir jouer avec iText et BouncyCastle ... avec une application tablet Android ? :-)

2012-04-09

Free gère bien ses codes GSM en itinérance.

Dans mon article sur coucou-networks j’accusai Free d'ignorer les ordres GSM concernant la gestion des transferts d'appels.

Je déteste viscéralement les répondeurs. A chaque changement d'opérateur, j’envoie le code GSM (magique) ##002# (à ne pas faire sans précautions).

Le statut obtenu, avec l'opérateur Free donne ceci :

Dans la théorie ça devrait marcher.
Dans la réalité, chez moi ça marche pas™, et ça m'agace. Mes correspondants tombent sur le répondeur et laissent des messages ([Message de Service] : je n'écoute pas vos messages, tous les 2-3 mois je supprime sans les écouter).

Or, hier, j'ai été surpris de sentir 5 vibrations dans ma poche avant de pouvoir décrocher ... A Angers, où je n'étais pas en itinérance Orange, le répondeur ne s'est pas déclenché.

Ce matin, à la maison, en itinérance Orange : pas de répondeur.

Ce matin, pas loin de mon travail, en itinérance Orange : pas de répondeur.


Bien bien bien Free. Je suis exigeant et râleur, mais je vous ♡ !

Plus de lecture : http://geckobeach.com/cellular/secrets/gsmcodes.php