SlideShare une entreprise Scribd logo
1  sur  39
Télécharger pour lire hors ligne
Utilisation du NDK : Lecture & Gestion
des PDF sous Android
Juin 2014Julien Sanchez
Julien Sanchez
Développeur Android
@JuSchz
+JulienSanchez9
Objectif :
Pdf et Android SDK
Pdf et Android SDK
1/ Laisser la main à l’OS
File file = new File("/sdcard/files/mypdf.pdf");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/pdf");
Pdf et QuickOffice
2/ Quickoffice + webview
String myUrl = "https://drive.google.com/viewer?url=" + myPdfFile;
mWebview = (WebView) findViewById(R.id.webview);
mWebview.getSettings().setJavaScriptEnabled(true);
mWebview.loadUrl(myUrl);
Rendu Quickoffice
Si > 20 Mo
Pdf et Android SDK
3/ Faire son propre rendu
> Bibliothèque Java : qoppa, IText, PdfJet, PSPDFkit
> Bibliothèque JNI : muPdf, Android Pdf Viewer (APV)
Know your audience
http://www.funnysigns.net/files/illiterate-write-for-help.jpg
NDK : Native Developement Kit
Qu’est ce que le NDK ?
https://developer.android.com/tools/sdk/ndk/
NDK : Usage
JNIEXPORT jint JNICALL com_myndklib_myNdkFunction
(JNIEnv * env, jobject pThis, jstring jParam) {
return 2+2;
}
public class myClass {
static { System.loadLibrary("myndklib"); }
private native int myNdkFunction(String param); // => 4
}
NDK : Avantages / Contraintes
Avantages
- Performances++
- Plus de mémoire (heap) disponible
- Cross-plaform
- Sécurité
- Utilisation de bibliothèque C
Contraintes
- Langage : C/C++
- Peu d’API : Interfaces--
- Dépendant de l’architecture CPU
- Pas d’outil d’obfuscation
SDK : Taille mémoire
Heap Sizes :
- Galaxy S3 : 256Mo
- Galaxy Tab : 64 Mb
- HTC Wildfire : 16 Mo
/system/build.prop
NDK dans le SDK
ex: Allocation de Bitmap
=> bibliothèques systèmes dans /system/lib
// File : android.graphics.Bitmap.java:1566
private static native Bitmap nativeCreate(int[] colors, int offset, int stride, int
width, int height, int nativeConfig, boolean mutable);
private static native void nativeDestructor(int nativeBitmap);
private static native boolean nativeRecycle(int nativeBitmap);
Apps utilisant le NDK
(AndEngine)(libvorbis)
(libopencv)
Plus sur le NDK ?
-> Session du Paris AUG, Mars 2013
par Sylvain Ratabouil
http://youtu.be/K4TgkzpEEvM
Rendu PDF
Utilisation de la bibliothèque MuPDF
Rendu PDF : MuPDF
- Developpé par Artifex Software depuis 2006
- Gratuit et open source
- Licence GNU GPL v3
https/code.google.com/p/mupdf/
MuPDF : Etape 1
Récupération des sources & third-party :
$ git clone git://git.ghostscript.com/mupdf.git
$ cd mupdf/
$ git submodule update --init
$ make generate
MuPDF : Etape 2
Compilation de la bibliothèque :
-> mupdf/platform/android/libs/armeabi-v7a/libmupdf.so
$ cd platform/android/
$ NDK_PATH/ndk-build
[armeabi-v7a] Install : libmupdf.so => libs/armeabi-v7a/libmupdf.so
Question
ou
MuPDF : Etape 3
Eclipse : intégration bibliothèque/projet externe
Android Studio (gradle > 0.7.2) :
/src/main/jniLibs /armeabi/myndklib.so
/armeabi-v7a/myndklib.so
/x86/myndklib.so
Changer le répertoire par défaut (build.gradle) :
sourceSets.main { jniLibs.srcDir 'src/main/myNDKlibs'}
MuPDF : Etape 4
Appel bibliothèque coté SDK :
Intent intent = new Intent(activity, MuPDFActivity.class);
Uri data_decoded = Uri.parse(myUrl); // ex: sdcard; internal storage;
ressources
intent.setAction(Intent.ACTION_VIEW);
intent.setData(data_decoded);
activity.startActivity(intent);
MuPdf : Etape 5 (finale)
Génération de l’executable :
$ ./gradlew assemble
MuPdf
Taille .apk : 14 Mo
http://www.quickmeme.com/Surprised-Koala/page/2/
Architecture CPU
Architectures : armv7, armeabi-v7a, mips, intel x86
> 1 exécutable par architecture
File : mupdf/platform/android/jni/Application.mk
APP_ABI := all
#APP_ABI := armeabi armeabi-v7a x86 mips
MuPdf : Options de compilation
Fonts CJK (China/Japan/Korea) :
// File : mupdf/platform/source/pdf/pdf-fontfile.c:17
#ifdef NOCJK
#define NOCJKFONT
#endif
…
#ifndef NOCJKFONT
#ifndef NOCJKFULL
#include "gen_font_cjk_full.h"
MuPdf : Options de compilation(2)
// File : mupdf/platform/android/jni/Core.mk:7
LOCAL_CFLAGS := -DNOCJK
ifeq ($(TARGET_ARCH),arm)
LOCAL_CFLAGS += -DARCH_ARM -DARCH_THUMB -
DARCH_ARM_CAN_LOAD_UNALIGNED
ifdef NDK_PROFILER
Ajout d’un flag ‘NOCJK’ :
MuPdf
Apk final : 2,2 Mo
http://www.quickmeme.com/meme/3rzk86
MuPdf : immersive mode
// File : MuPDFActivity:485
if (android.os.Build.VERSION.SDK_INT >= 11){
mDocView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
| View.SYSTEM_UI_FLAG_IMMERSIVE); // kitkat
}
layout.addView(mDocView);
Résultat
Sécurité des PDF
Comment sécuriser l’accès aux
documents ?
Sécurité : Approche #0
Accès fichiers sous Android
Fichiers distants (via web) = stockage :
Inclus dans executable (ex: res/raw) :
$ adb pull /data/com.package/files/myfile.pdf ./ // ou sdcard
$ adb pull /data/app/com.package.apk ./
$ tar -xvf com.package.apk
Sécurité : Chiffrage coté Java
Génération de la clé :
String seed = “myseed”;
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed.getBytes();
kgen.init(128, sr);
SecretKeySpec sKey = new SecretKeySpec(kgen.generateKey().getEncoded(),
"AES");
Sécurité : Chiffrage coté Java
Génération du vecteur d’initialisation (iv) :
byte[] iv = new byte[16];
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.nextBytes(iv);
Sécurité : Chiffrage coté Java
Chiffrage / Dechiffrage :
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, sKey, ivspec); // ou DECRYPT_MODE
encryptedCount = cipher.update(data, 0, bytesRead, encryptedData);
Plus de sécurité
- Fichier PDF avec mot de passe :
- Chiffrage coté JNI
- SSL (+ vérification certificats)
MuPDFCore.authenticatePassword(“mypassword”);
Utilisation du NDK : Lecture & gestion des PDF (@TAUG, Juin 2014)

Contenu connexe

En vedette

Rescate Proyecto Divino
Rescate Proyecto DivinoRescate Proyecto Divino
Rescate Proyecto DivinoEuler
 
Hijoscomonavios
HijoscomonaviosHijoscomonavios
Hijoscomonavioskatrojcr
 
Arquitectura de la Información
Arquitectura de la InformaciónArquitectura de la Información
Arquitectura de la Informaciónhectorium
 
Store Remodels for Chico's
Store Remodels for Chico'sStore Remodels for Chico's
Store Remodels for Chico'sThompsonFixture
 
VersióN Para Exponer En 1ras Jornadas En Chubut Inicadoresd
VersióN Para Exponer En 1ras Jornadas En  Chubut  InicadoresdVersióN Para Exponer En 1ras Jornadas En  Chubut  Inicadoresd
VersióN Para Exponer En 1ras Jornadas En Chubut Inicadoresdhildaberon
 
Compras para tí
Compras para tíCompras para tí
Compras para tídjcani
 
Introduction au Social Media Optimization
Introduction au Social Media OptimizationIntroduction au Social Media Optimization
Introduction au Social Media OptimizationBastien Perreuil
 
104 08 Agregees 1
104 08 Agregees 1104 08 Agregees 1
104 08 Agregees 1patlecat
 
Webseminaire Ubimédia "be context friendly", Sqli Agency
Webseminaire Ubimédia "be context friendly",  Sqli AgencyWebseminaire Ubimédia "be context friendly",  Sqli Agency
Webseminaire Ubimédia "be context friendly", Sqli AgencyFrançois VERRON
 
Metodologia y proyecto investigacion
Metodologia y proyecto  investigacionMetodologia y proyecto  investigacion
Metodologia y proyecto investigacionEuler
 
D E R E C H O S
D E R E C H O SD E R E C H O S
D E R E C H O SHJTandil66
 
La violencia de género a través del humor gráfico
La violencia de género a través del humor gráficoLa violencia de género a través del humor gráfico
La violencia de género a través del humor gráficoMatilde Martínez Sallés
 

En vedette (19)

Rescate Proyecto Divino
Rescate Proyecto DivinoRescate Proyecto Divino
Rescate Proyecto Divino
 
Simposio Internacional
Simposio InternacionalSimposio Internacional
Simposio Internacional
 
Hijoscomonavios
HijoscomonaviosHijoscomonavios
Hijoscomonavios
 
Charla Phh 2009
Charla Phh 2009Charla Phh 2009
Charla Phh 2009
 
Arquitectura de la Información
Arquitectura de la InformaciónArquitectura de la Información
Arquitectura de la Información
 
CapíTulo 8
CapíTulo 8CapíTulo 8
CapíTulo 8
 
FELIZ NAVIDAD
FELIZ NAVIDADFELIZ NAVIDAD
FELIZ NAVIDAD
 
Store Remodels for Chico's
Store Remodels for Chico'sStore Remodels for Chico's
Store Remodels for Chico's
 
VersióN Para Exponer En 1ras Jornadas En Chubut Inicadoresd
VersióN Para Exponer En 1ras Jornadas En  Chubut  InicadoresdVersióN Para Exponer En 1ras Jornadas En  Chubut  Inicadoresd
VersióN Para Exponer En 1ras Jornadas En Chubut Inicadoresd
 
Compras para tí
Compras para tíCompras para tí
Compras para tí
 
Introduction au Social Media Optimization
Introduction au Social Media OptimizationIntroduction au Social Media Optimization
Introduction au Social Media Optimization
 
Ingeniería de Requerimientos
Ingeniería de RequerimientosIngeniería de Requerimientos
Ingeniería de Requerimientos
 
104 08 Agregees 1
104 08 Agregees 1104 08 Agregees 1
104 08 Agregees 1
 
Le Monde
Le MondeLe Monde
Le Monde
 
Webseminaire Ubimédia "be context friendly", Sqli Agency
Webseminaire Ubimédia "be context friendly",  Sqli AgencyWebseminaire Ubimédia "be context friendly",  Sqli Agency
Webseminaire Ubimédia "be context friendly", Sqli Agency
 
Foiegras
FoiegrasFoiegras
Foiegras
 
Metodologia y proyecto investigacion
Metodologia y proyecto  investigacionMetodologia y proyecto  investigacion
Metodologia y proyecto investigacion
 
D E R E C H O S
D E R E C H O SD E R E C H O S
D E R E C H O S
 
La violencia de género a través del humor gráfico
La violencia de género a través del humor gráficoLa violencia de género a través del humor gráfico
La violencia de género a través del humor gráfico
 

Utilisation du NDK : Lecture & gestion des PDF (@TAUG, Juin 2014)

  • 1. Utilisation du NDK : Lecture & Gestion des PDF sous Android Juin 2014Julien Sanchez
  • 5. Pdf et Android SDK 1/ Laisser la main à l’OS File file = new File("/sdcard/files/mypdf.pdf"); Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); Uri uri = Uri.fromFile(file); intent.setDataAndType(uri, "application/pdf");
  • 6. Pdf et QuickOffice 2/ Quickoffice + webview String myUrl = "https://drive.google.com/viewer?url=" + myPdfFile; mWebview = (WebView) findViewById(R.id.webview); mWebview.getSettings().setJavaScriptEnabled(true); mWebview.loadUrl(myUrl);
  • 8. Pdf et Android SDK 3/ Faire son propre rendu > Bibliothèque Java : qoppa, IText, PdfJet, PSPDFkit > Bibliothèque JNI : muPdf, Android Pdf Viewer (APV)
  • 10. NDK : Native Developement Kit Qu’est ce que le NDK ? https://developer.android.com/tools/sdk/ndk/
  • 11. NDK : Usage JNIEXPORT jint JNICALL com_myndklib_myNdkFunction (JNIEnv * env, jobject pThis, jstring jParam) { return 2+2; } public class myClass { static { System.loadLibrary("myndklib"); } private native int myNdkFunction(String param); // => 4 }
  • 12. NDK : Avantages / Contraintes Avantages - Performances++ - Plus de mémoire (heap) disponible - Cross-plaform - Sécurité - Utilisation de bibliothèque C Contraintes - Langage : C/C++ - Peu d’API : Interfaces-- - Dépendant de l’architecture CPU - Pas d’outil d’obfuscation
  • 13. SDK : Taille mémoire Heap Sizes : - Galaxy S3 : 256Mo - Galaxy Tab : 64 Mb - HTC Wildfire : 16 Mo /system/build.prop
  • 14. NDK dans le SDK ex: Allocation de Bitmap => bibliothèques systèmes dans /system/lib // File : android.graphics.Bitmap.java:1566 private static native Bitmap nativeCreate(int[] colors, int offset, int stride, int width, int height, int nativeConfig, boolean mutable); private static native void nativeDestructor(int nativeBitmap); private static native boolean nativeRecycle(int nativeBitmap);
  • 15. Apps utilisant le NDK (AndEngine)(libvorbis) (libopencv)
  • 16. Plus sur le NDK ? -> Session du Paris AUG, Mars 2013 par Sylvain Ratabouil http://youtu.be/K4TgkzpEEvM
  • 17. Rendu PDF Utilisation de la bibliothèque MuPDF
  • 18. Rendu PDF : MuPDF - Developpé par Artifex Software depuis 2006 - Gratuit et open source - Licence GNU GPL v3 https/code.google.com/p/mupdf/
  • 19. MuPDF : Etape 1 Récupération des sources & third-party : $ git clone git://git.ghostscript.com/mupdf.git $ cd mupdf/ $ git submodule update --init $ make generate
  • 20. MuPDF : Etape 2 Compilation de la bibliothèque : -> mupdf/platform/android/libs/armeabi-v7a/libmupdf.so $ cd platform/android/ $ NDK_PATH/ndk-build [armeabi-v7a] Install : libmupdf.so => libs/armeabi-v7a/libmupdf.so
  • 22. MuPDF : Etape 3 Eclipse : intégration bibliothèque/projet externe Android Studio (gradle > 0.7.2) : /src/main/jniLibs /armeabi/myndklib.so /armeabi-v7a/myndklib.so /x86/myndklib.so Changer le répertoire par défaut (build.gradle) : sourceSets.main { jniLibs.srcDir 'src/main/myNDKlibs'}
  • 23. MuPDF : Etape 4 Appel bibliothèque coté SDK : Intent intent = new Intent(activity, MuPDFActivity.class); Uri data_decoded = Uri.parse(myUrl); // ex: sdcard; internal storage; ressources intent.setAction(Intent.ACTION_VIEW); intent.setData(data_decoded); activity.startActivity(intent);
  • 24. MuPdf : Etape 5 (finale) Génération de l’executable : $ ./gradlew assemble
  • 25. MuPdf Taille .apk : 14 Mo http://www.quickmeme.com/Surprised-Koala/page/2/
  • 26. Architecture CPU Architectures : armv7, armeabi-v7a, mips, intel x86 > 1 exécutable par architecture File : mupdf/platform/android/jni/Application.mk APP_ABI := all #APP_ABI := armeabi armeabi-v7a x86 mips
  • 27. MuPdf : Options de compilation Fonts CJK (China/Japan/Korea) : // File : mupdf/platform/source/pdf/pdf-fontfile.c:17 #ifdef NOCJK #define NOCJKFONT #endif … #ifndef NOCJKFONT #ifndef NOCJKFULL #include "gen_font_cjk_full.h"
  • 28. MuPdf : Options de compilation(2) // File : mupdf/platform/android/jni/Core.mk:7 LOCAL_CFLAGS := -DNOCJK ifeq ($(TARGET_ARCH),arm) LOCAL_CFLAGS += -DARCH_ARM -DARCH_THUMB - DARCH_ARM_CAN_LOAD_UNALIGNED ifdef NDK_PROFILER Ajout d’un flag ‘NOCJK’ :
  • 29. MuPdf Apk final : 2,2 Mo http://www.quickmeme.com/meme/3rzk86
  • 30. MuPdf : immersive mode // File : MuPDFActivity:485 if (android.os.Build.VERSION.SDK_INT >= 11){ mDocView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar | View.SYSTEM_UI_FLAG_IMMERSIVE); // kitkat } layout.addView(mDocView);
  • 32. Sécurité des PDF Comment sécuriser l’accès aux documents ?
  • 34. Accès fichiers sous Android Fichiers distants (via web) = stockage : Inclus dans executable (ex: res/raw) : $ adb pull /data/com.package/files/myfile.pdf ./ // ou sdcard $ adb pull /data/app/com.package.apk ./ $ tar -xvf com.package.apk
  • 35. Sécurité : Chiffrage coté Java Génération de la clé : String seed = “myseed”; KeyGenerator kgen = KeyGenerator.getInstance("AES"); SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); sr.setSeed(seed.getBytes(); kgen.init(128, sr); SecretKeySpec sKey = new SecretKeySpec(kgen.generateKey().getEncoded(), "AES");
  • 36. Sécurité : Chiffrage coté Java Génération du vecteur d’initialisation (iv) : byte[] iv = new byte[16]; SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); random.nextBytes(iv);
  • 37. Sécurité : Chiffrage coté Java Chiffrage / Dechiffrage : Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec ivspec = new IvParameterSpec(iv); cipher.init(Cipher.ENCRYPT_MODE, sKey, ivspec); // ou DECRYPT_MODE encryptedCount = cipher.update(data, 0, bytesRead, encryptedData);
  • 38. Plus de sécurité - Fichier PDF avec mot de passe : - Chiffrage coté JNI - SSL (+ vérification certificats) MuPDFCore.authenticatePassword(“mypassword”);