Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Systemアプリ開発入門

kobashin
March 10, 2017

 Systemアプリ開発入門

DroidKaigi 2017 Day2 14:20 - 14 : 50 のセッションです

kobashin

March 10, 2017
Tweet

More Decks by kobashin

Other Decks in Technology

Transcript

  1. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 10 AndroidʹΠϯετʔϧ͞Ε͍ͯΔΞϓϦ • System.imgʹؚ·Εͳ͍௨ৗͷΞϓϦ • System.imgʹؚ·ΕΔΞϓϦ •

    PrivilegedΞϓϦ • sharedUserId=“android.uid.xxxx” • ಛఆͷॺ໊෇͖ΞϓϦ • etc… SystemΞϓϦ
  2. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 11 ௨ৗͷΞϓϦͱSystemΞϓϦͱͷҧ͍ • ύʔϛογϣϯϞσϧʹΑΓ੍ݶ͞Εͨ
 APIͷར༻ • @hide

    API, @systemApiͷར༻ • ಉuid͔ΒͷΈͷΞΫηεՄAPIͷར༻ $ Πϯετʔϧख๏ʹΑΓݖݶ͕ҟͳΔ ∠
  3. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 14 protectionLevel = BasicProtection | AdditionalFlag ex.

    signatureOrSystem = signature | privileged ϓϩςΫγϣϯϨϕϧ + permission: a.p.WRITE_MEDIA_STORAGE package: android label: null description: null protectionLevel: signature|privileged
  4. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 15 Basic Protection Type ֓ཁɺڐՄ৚݅ normal ௿ϦεΫ

    dangerous Ϣʔβͷݸਓ৘ใ΍อଘσʔλ΁ ͷΞΫηε͕ൃੜ͢Δ signature ύʔϛογϣϯͷఆٛऀͱಉ͡ॺ ໊Λ࣋ͭΞϓϦ signatureOrSystem signatureݖݶɺSystemΞϓϦ
  5. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 16 Additional Flag ֓ཁɺڐՄ৚݅ privileged(system) /system/priv-app ҎԼʹΠϯετʔϧ

    ͞ΕͨΞϓϦ development ༧ΊڐՄ͍ͯ͠ͳ͍ͱڐՄͰ͖ͳ͍ installer Intent.ACTION_INSTALL_PACKAGEʹ ൓Ԡ͢ΔActivityΛ࣋ͭΞϓϦ appop AppOpsͰ؅ཧ͞Ε͍ͯΔύʔϛογ ϣϯ
  6. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 17 Additional Flag ֓ཁɺڐՄ৚݅ pre23 targetSdkVersion <

    23 verifier Intent.ACTION_PACKAGE_NEEDS_VER IFICATIONʹ൓ԠͰ͖ΔActivityΛ࣋ͭ setup Intent.CATEGORY_SETUP_WIZARDʹ ൓ԠͰ͖ΔActivityΛ࣋ͭ preinstalled γεςϜΠϝʔδʹؚ·ΕΔશͯͷΞ ϓϦ
  7. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 19 APIΛ୳͢ • ྨࣅΞϓϦ͔ΒAPIΛ୳͢ • SettingsΞϓϦ͕࣋ͬͯΔ •

    ֘౰Օॴͷιʔε͔ΒAPIΛݟ͚ͭΔ private void doMasterClear() {
 Intent intent = new Intent(Intent.ACTION_MASTER_CLEAR);
 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
 intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm");
 intent.putExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, mEraseSdCard);
 getActivity().sendBroadcast(intent);
 // Intent handling is asynchronous -- assume it will happen soon.
 }
 MasterClearConfirm.java
  8. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 20 APIຖͷύʔϛογϣϯΛ֬ೝ <receiver android:name="com.android.server.MasterClearReceiver"
 android:permission="android.permission.MASTER_CLEAR">
 <intent-filter
 android:priority="100"

    >
 <!-- For Checkin, Settings, etc.: action=MASTER_CLEAR -->
 <action android:name="android.intent.action.MASTER_CLEAR" />
 AndroidManifest.xml ୺຤ΛFactoryReset͢ΔAPI͸ ʮMASTER_CLEARʯ͕ඞཁ
  9. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 21 permissionͷprotectionLevelΛ֬ೝ $ adb shell pm list

    permissions -f + permission:android.permission.MASTER_CLEAR package:android label:null description:null protectionLevel:signature|privileged ʮMASTER_CLEARʯ-> signature | privileged ॺ໊ or /system/priv-app ΁Πϯετʔϧඞཁ
  10. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 23 APIΛ୳͢ • XXManager͔ΒAPIΛ୳͢ • ֘౰Օॴͷιʔε͔ΒAPIΛݟ͚ͭΔ /**


    * Forces the device to go to sleep.
 * 
 * Requires the {@link android.Manifest.permission#DEVICE_POWER} * permission.
 * 
 * @hide Requires signature permission.
 */
 public void goToSleep(long time, int reason, int flags) {
 PowerManager.java
  11. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 24 APIຖͷύʔϛογϣϯΛ֬ೝ /**
 * Forces the device

    to go to sleep.
 * 
 * Requires the {@link android.Manifest.permission#DEVICE_POWER} * permission.
 * 
 * @hide Requires signature permission.
 */
 public void goToSleep(long time, int reason, int flags) {
 PowerManager.java ୺຤ΛSleepঢ়ଶ΁Ҡߦ͢ΔAPI͸ ʮDEVICE_POWERʯ͕ඞཁ
  12. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 25 permissionͷprotectionLevelΛ֬ೝ $ adb shell pm list

    permissions -f + permission:android.permission.DEVICE_POWER package:android label:null description:null protectionLevel:signature ʮDEVICE_POWERʯ-> signature͕ඞཁ
 platformॺ໊͕ඞཁ
  13. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 28 sharedUserId=“android.uid.system” • uidΛݻఆԽʢuid = 1000ʣ •

    uid.system͕࣋ͭϦιʔε΁ͷΞΫηε • Ұ෦੍ݶAPIΛར༻Մೳʹ • platformॺ໊ඞཁ • ҰํɺWebView͕ར༻ෆՄೳʹ
  14. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 29 uidʹΑ੍ͬͯݶ͞ΕΔAPI /**
 * Validate a user-supplied

    password string with cryptfs
 */
 @Override
 public int verifyEncryptionPassword(String password) throws RemoteException {
 // Only the system process is permitted to validate passwords
 if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
 throw new SecurityException("no permission to access the crypt keeper");
 } MountService.java ҉߸ԽFSͷύεϫʔυνΣοΫAPI
  15. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 30 uidʹΑ੍ͬͯݶ͞ΕΔAPI final int uid = android.os.Process.myUid();


    if (uid == android.os.Process.ROOT_UID || uid == android.os.Process.SYSTEM_UID) {
 throw new UnsupportedOperationException(
 "For security reasons, WebView is not allowed in privileged processes");
 } WebViewFactory.java ٯʹandroid.uid.systemͱ͢Δ͜ͱͰWebview ͸ར༻Ͱ͖ͳ͘ͳΔ
  16. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 32 privileged? APIݕ౼ ҰൠAPP signature? uid? priv-app

    signature sharedUid SystemΞϓϦͱύʔϛογϣϯ YES NO NO YES YES NO
  17. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 33 SystemΞϓϦͱύʔϛογϣϯ • API͸ྨࣅΞϓϦ or XXManager͔Β୳͢ •

    Platformॺ໊͕ඞཁ͔Ͳ͏͔ • ԿͰ΋͚ͭΕ͹ྑ͍ͬͯ΋ͷͰ΋ແ͍ • uid.system͸੍ݶ΋͋Δ͜ͱʹ஫ҙ Point
  18. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 35 SystemΞϓϦͱΞοϓσʔτ • ΞοϓσʔτࡁΈͷSystemΞϓϦ͔Ͳ͏͔
 ͸্هAPIͰ֬ೝՄೳ /**
 *

    @hide
 */
 public boolean isUpdatedSystemApp() {
 return (flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
 } ApplicationInfo.java
  19. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 37 ϚϧνϢʔβʔ͓͞Β͍ Tablet • from 4.2 •

    Restricted Profile Hand Set ※ݫີʹ͸Voice capableʹର Ԡ͍ͯ͠Δ͔Ͳ͏͔ • from 5.0
  20. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 38 ΞϓϦͷΠϯετʔϧͷ͞Εํ /data/user/ 0 10 11 •

    Owner User • /data/data/ ΁ͷSymbolic Link • New User • New Profile $ ΞϓϦέʔγϣϯσʔλ͸Ϣʔβʔຖʹಠཱ
  21. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 39 ϢʔβʔؒͰσʔλڞ༗͍ͨ͠ • ΞϓϦσʔλ/EXTERNAL STORAGE σʔλڞʹϢʔβʔຖʹഉଞ •

    ઃఆҾ͖ܧ͗ • ϢʔβʔຖʹৼΔ෣͍Λมߋ͍ͨ͠ service, receiverΛʮSingleton Componentʯʹ ∠
  22. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 41 MyApp uid=0 MyApp uid=10 Activity Service

    singleUser Activity Singleton Component service, receiver΁singleUse=“true”Λઃఆ uid=0 ͷcomponentΛSingletonͱͯ͠ར༻
  23. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 42 ϚϧνϢʔβʔૢ࡞ʹඞཁͳॺ໊ • INTERACT_ACROSS_USER • signature |

    privilege • Ϣʔβʔૢ࡞Ұൠʹඞཁ • INTERACT_ACROSS_USER_FULL • signature • ଞϢʔβʔͷActivityىಈ
 ଞϢʔβʔͷContentObserverొ࿥ͳͲ
  24. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 43 Singleton Component <service
 android:name=".MultiUserSingletonService"
 android:enabled="true"
 android:exported="true"


    android:singleUser="true" /> <receiver
 android:name=".MyReceiver"
 android:enabled="true"
 android:exported="true"
 android:singleUser="true">
 
 AndroidManifest.xml
  25. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 44 Singleton Component @Override
 public int sampleAidlApi()

    throws RemoteException {
 File file = getFilesDir(); // ͲͷϢʔβ͔ΒͰ΋ /data/user/0/xxx.xxx.xxx/files
 Log.i(TAG, "filesDir: " + file.getAbsolutePath());
 
 SampleService.java
  26. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 46 Singleton Component @Override
 public int sampleAidlApi()

    throws RemoteException {
 if( UserHandle.USER_SYSTEM == getCallingUserId()){
 // USER_SYSTEM (uid == 0)
 } else {
 // other user (uid != 0)
 UserManager userManager = (UserManager) getSystemService(USER_SERVICE);
 UserInfo userInfo = ɹuserManager.getUserInfo(getCallingUserId());
 // ֤ϢʔβຖͷInfo UserInfo{10:New user:10} Log.i(TAG, "UserInfo " + userInfo.toString());
 }
 SampleService.java
  27. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 47 ϢʔβʔຖͷComponentΛىಈ͢Δ • startActivityAsUser(Intent, UserHandle) • UserΛࢦఆ͠ActivityΛىಈ

    • ֤ίϯϙʔωϯτ༻ʹAsUser API͕ଘࡏ • ޡͬͨActivityΛىಈ͠Α͏ͱͨ͠৔߹
 SecurityException͕ൃੜ͢Δ
  28. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 48 Singleton Component @Override
 public int sampleAidlApi()

    throws RemoteException {
 // loginதϢʔβʔͷActivityىಈ Intent intent = new Intent();
 intent.setClass(MultiUserSingletonService.this, MainActivity.class);
 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 startActivityAsUser(intent, UserHandle.CURRENT); // uid=0ϢʔβʔͷServiceىಈ(SYSTEM=OWNER) startServiceAsUser(intent, UserHandle.SYSTEM);
 
 
 SampleService.java
  29. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 50 Restricted Profile • ੍ݶϢʔβʔʹ͸ɺΞϓ ϦέʔγϣϯͷڐՄঢ় ଶΛઃఆͰ͖Δ

    • Intent.ACTION_GET_RES TRICTION_ENTRIESʹΑ Γ੍ݶ಺༰Λݸผʹઃ ఆͰ͖Δ
  30. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 51 SystemΞϓϦͱRestricted Profile • SystemΞϓϦͷදࣔ৚݅ • ॺ໊༗Γ͸ඇදࣔ

    • platformॺ໊ແ͠͸දࣔ • platformॺ໊༗Γʴɹ Intent.ACTION_GET_REST RICTION_ENTRIESΛड৴ ͢ΔReceiver࣮૷
  31. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 52 ະॺ໊ platformॺ໊ platformॺ໊ has receiver දࣔঢ়ଶ

    දࣔ ඇදࣔ දࣔ + ' SystemΞϓϦͱRestricted Profile • platformॺ໊࣋ͪͷ৔߹͸ON/OFFઃఆͰ͖ͳ͍
 ৄࡉઃఆΛߦ͏ͨΊʹ Intent.ACTION_GET_RESTRICTION_ENTRIESΛϋϯυϧ͢Δ
  32. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 54 SystemΞϓϦͱϚϧνϢʔβʔ • جຊҰൠΞϓϦͱมΘΒͳ͍ • ϢʔβʔؒͰσʔλڞ༗ɺϢʔβʔຖͷڍಈมߋ
 ɹ㱺singleUserͷservice,

    receiverΛར༻͢Δ • Restricted Profile͸ॺ໊༗ແͰڍಈมߋ͋Γ
 ඞཁʹԠ͡ACTION_GET_RESTRICTION_ENTRIESͷ
 ࣮૷ݕ౼Λʢ࣮૷಺༰͸ҰൠΞϓϦͱಉ౳ʣ
  33. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 60 2. framework.jarΛϥΠϒϥϦͱͯ͠ొ࿥ 2. apkʹؚΊͳ͍Α͏ʹprovidedͰಡΈࠐΉ dependencies {


    // build pathʹframework.jarΛؚΊΔɻAPKʹ͸ؚΊͳ͍
 provided fileTree(dir: 'framework', include: ['*.jar']) }
  34. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 62 import groovy.xml.*
 task changeOrderEntry {
 def

    iml = file("app.iml")
 def doc = (new XmlParser()).parse(iml);
 def deleteNode = doc.component[1].orderEntry.find { it.@type == "jdk" }
 
 def _type = deleteNode.@type
 def _jdkName = deleteNode.@jdkName
 def _jdkType = deleteNode.@jdkType
 
 doc.component[1].remove(deleteNode)
 new Node(doc.component[1], 'orderEntry', ['type': _type, 'jdkName': _jdkName, 'jdkType': _jdkType])
 
 iml.text = XmlUtil.serialize(doc)
 }
 preBuild.dependsOn(changeOrderEntry) 3. ϏϧυΤϥʔճආͷͨΊbuild.gradleมߋ
  35. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 63 tasks.withType(JavaCompile) {
 options.compilerArgs.add('-Xbootclasspath/p:app/framework/ framework.jar')
 }
 3.

    ϏϧυΤϥʔճආͷͨΊbuild.gradleมߋ • packageੜ੒࣌ʹBuildPathʹׂΓࠐΉʹ͸
 -Xbootclasspath/p: Λར༻͢Δ
  36. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 64 4. ॺ໊͕ඞཁͳΒ෇༩͢Δ • debugॺ໊͸ build/target/product/security •

    keytool-importkeypair • https://github.com/getfatday/keytool-importkeypair signingConfigs {
 debug {
 storeFile file(“/path/to/debug.keystore")
 storePassword "android"
 keyAlias "platform"
 keyPassword "android"
 }
 }

  37. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 65 AndroidSDKͷ࣋ͨͳ͍APIΛར༻͢Δ • priv-app΁ͷΠϯετʔϧ͸ผ్ඞཁ • ࠷ۙͷfirm͸dm-verity͕̤̣ͳͷͰ
 `adb

    disable-verity; adb reboot;` Λ๨Εͣʹ • SDKͷjarΛฤू͢Δํ๏ͩͱɺ
 :app:mockableAndroidJar TaskͰΤϥʔൃੜ
  38. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 67 Debugging AOSP Source 1. user-debugͷ࣮ػΛ༻ҙ 2.

    AOSPͷϏϧυ 3. ./development/tools/idegen/intellij-gen.sh
 ͰϓϩδΣΫτͷiprΛ࡞੒ 4. DDMSىಈ 5. studioͰಡΈࠐΈ & debug࣮ߦ
  39. SystemΞϓϦ։ൃೖ໳ ! @kobashinG 68 
 $ ./development/tools/idegen/intellij-gen.sh \ packages/apps/Settings $

    monitor
 iprͷ࡞੒ͱDDMSͷىಈ • intellij-gen.shΛར༻͠iprΛ࡞੒ • idegen.shͰ΋ߏΘͳ͍͕AOSPશମ͸ϝϞϦෛՙ • DDMS͕port:8700ͰσόΠεͱ௨৴
 ಉportͰAndroid StudioͰremote઀ଓ͢Δ