Skocz do zawartości
JustArchi

ArchiDroid | Skarbnica Wiedzy

    Rekomendowane odpowiedzi

    JustArchi

    Z racji tego, że utrzymuję maksymalny porządek, czystość/jakość kodu i implementację najnowszych technologii (takich jak np. aroma) postanowiłem się podzielić użytecznymi linkami dla "samonauki" na bazie ArchiDroida.

    Jeśli ktoś nie jest w temacie to ArchiDroid to jeden z najbardziej skomplikowanych ROMów pod kwestią "wnętrzności", czyli tego co nie jest widoczne dla przeciętnego użytkownika.

    Wszystko co znajdziecie w tym temacie bazuje na rozwiązaniach SGS3 I9300, aczkolwiek duża część z nich jest ogromnie uniwersalna dzięki mojemu "podejściu" do kwestii budowy custom romów, dzięki temu przeportowanie AD na inne urządzenie oparte o armv7a to kwestia 20-30 minut. Uważam to za spory sukces (Przykład: MrturDroid na Nexusa 4)

    Ale do rzeczy...

    Temat został stworzony dla osób, które chciałyby zacząć przygodę w tworzeniu swoich własnych romów.

    Będę go uzupełniał w miarę wolnego czasu. Pierw pojawią się bardziej zaawansowane porady, a te najbardziej podstawowe zostawię sobie na koniec, jako że większa część osób je zna i może się nimi podzielić. Idea tematu jest dość prosta - naszym developerom też się coś należy, a moja skrzynka PM staje się pełna w ciągu tygodnia ;).

    Skarbnica wiedzy do własnoręcznej nauki:

    Mój GitHub

    Mój profil na XDA

    ArchiDroid

    ArchiDroid na XDA

    98ArchiDroid_RunOnce

    99ArchiDroid_Init

    Rzeczy, które trzeba już mieć w małym palcu - http://forum.android.com.pl/f551/kompendium-wiedzy-odin-bootloader-recovery-backup-rom-root-sudden-death-300314/ . W szczególności słowniczek pojęć i rozeznanie w temacie (na bazie SGS3).

    Słowniczek nowych pojęć, które musisz znać:

    Bash - Język skryptowy, a konkretniej powłoka systemowa. Android domyślnie korzysta z powłoki sh - shell, ale bash sam w sobie jest tylko rozszerzeniem shella, więc skrypty zachowują dużą kompatybilność. Skrypty w bashu to najprostsza i najskuteczniejsza metoda zaawansowanego przygotowywania systemu operacyjnego (romu).

    init.d - Folder ze skryptami wykonywanymi podczas bootowania. Skrypty są wykonywane przez kernel jako user root i napisane w Bash'u.

    #1 Permissions

    Jak dobrze wiemy odpowiednie accessy to coś co chcemy mieć. Temat accessów przewija się co chwila w zasadzie bo nie ma jednej i uniwersalnej metody na ustawienie całego Androida.

    Również spotkałem się z tym problemem i już jakiś czas temu w moim ArchiDroidzie zastosowałem podwójny system permissions. Na czym polega? Instalator Aroma ustawia odpowiednie dla większości accessy, które bez problemu sobie działają, a skrypt post-instalacyjny permfix załatwia resztę.

    Tutaj nieco więcej o tym, prosto z changeloga ArchiDroida 1.4.1:

    1.4.1

    - [EXPERIMENTAL] Fixed very important permission issues.

    # It now works a bit different. I've cleaned up permissions and made them as universal as I could.

    # There are 2 stages now - aroma stage and android stage.

    # Aroma stage is same as before - permissions are set during the installation.

    # Android stage is something new, implemented by me to ensure that everything is allright.

    # After an initital sleep of 2 minutes (to make sure system is fully loaded) on the first boot my new script 98archidroid_permfix will be called from /system/etc/init.d.

    # It basicly checks if everything is allright with proper permissions and if not - it fixes permissions so they're always up to date and fixed.

    # After clean finish it automatically delete itself to prevent being called on the next boot.

    # This is a very professional way to deal with a permissions, we're calling it directly from loaded system so we're sure that system is fully loaded and permission are finally set in the initial stage.

    # Probably I've just fixed a million of problems which may or may not arrive in the future. We're now sure that permissions are ok after installation.

    # I highly recommend to NOT reboot or shut down system before first 4-5 minutes of running on the first boot.

    # Even if something like that happen my script should be automatically executed on the second boot and fix broken permissions made by first instance anyway.

    # But I didn't test it for such thing and I can't assure you that everything will work as it should.

    # That shouldn't be a problem anyway because my script only modifies already broken permissions (not everyone) so it could only be better, not worse.

    # As for now I left debug log in /sdcard/fix_permissions.log. If you're interested in that feel free to browse around after these 5 minutes of work.

    # I'm going to remove this log in the next release after being sure that it works like a charm.

    No i oczywiście sam kod.

    /system/etc/init.d/zzzArchiDroid_PermFix

    #!/system/bin/sh
    
    # ArchiDroid Universal Fix Permissions Script
    # JustArchi@JustArchi.net
    
    # Coming from https://github.com/CyanogenMod/android_bootable_recovery/blob/jellybean/utilities/fix_permissions
    
    # Not Disabled
    #exit 0
    
    # ArchiDroid Semaphore
    # Wait until we see some android processes to consider boot is more or less complete (credits to AndiP71)
    
    # NOTICE: We've already finished runonce and init scripts so it shouldn't be needed anyway but let's make sure
    while ! pgrep com.android ; do
     sleep 1
    done
    
    # Now that is checked, let's just wait another tiny little bit
    sleep 10
    
    VERSION="2.04"
    
    # Defaults
    DEBUG=0 # Debug off by default
    LOGGING=1 # Logging on by default
    VERBOSE=1 # Verbose on by default
    
    # Messages
    UID_MSG="Changing user ownership for:"
    GID_MSG="Changing group ownership for:"
    PERM_MSG="Changing permissions for:"
    
    # Programs needed
    ECHO="busybox echo"
    GREP="busybox grep"
    EGREP="busybox egrep"
    CAT="busybox cat"
    CHOWN="busybox chown"
    CHMOD="busybox chmod"
    MOUNT="busybox mount"
    UMOUNT="busybox umount"
    CUT="busybox cut"
    FIND="busybox find"
    LS="busybox ls"
    TR="busybox tr"
    TEE="busybox tee"
    TEST="busybox test"
    SED="busybox sed"
    RM="busybox rm"
    WC="busybox wc"
    EXPR="busybox expr"
    DATE="busybox date"
    
    # Initialise vars
    CODEPATH=""
    UID=""
    GID=""
    PACKAGE=""
    REMOVE=0
    NOSYSTEM=0
    ONLY_ONE=""
    SIMULATE=0
    SYSREMOUNT=0
    SYSMOUNT=0
    DATAMOUNT=0
    SYSSDMOUNT=0
    FP_STARTTIME=$( $DATE +"%m-%d-%Y %H:%M:%S" )
    FP_STARTEPOCH=$( $DATE +%s )
    if $TEST "$SD_EXT_DIRECTORY" = ""; then
       #check for mount point, /system/sd included in tests for backward compatibility
       for MP in /sd-ext /system/sd;do
           if $TEST -d $MP; then
               SD_EXT_DIRECTORY=$MP
               break
           fi
       done
    fi
    fp_usage()
    {
      $ECHO "Usage $0 [OPTIONS] [APK_PATH]"
      $ECHO "      -d         turn on debug"
      $ECHO "      -f         fix only package APK_PATH"
      $ECHO "      -l         disable logging for this run (faster)"
      $ECHO "      -r         remove stale data directories"
      $ECHO "                 of uninstalled packages while fixing permissions"
      $ECHO "      -s         simulate only"
      $ECHO "      -u         check only non-system directories"
      $ECHO "      -v         disable verbosity for this run (less output)"
      $ECHO "      -V         print version"
      $ECHO "      -h         this help"
    }
    
    fp_parseargs()
    {
      # Parse options
      while $TEST $# -ne 0; do
         case "$1" in
            -d)
               DEBUG=1
            ;;
            -f)
               if $TEST $# -lt 2; then
                  $ECHO "$0: missing argument for option $1"
                  exit 1
               else
                  if $TEST $( $ECHO $2 | $CUT -c1 ) != "-"; then
                     ONLY_ONE=$2
                     shift;
                  else
                     $ECHO "$0: missing argument for option $1"
                     exit 1
                  fi
               fi
            ;;
            -r)
               REMOVE=1
            ;;
            -s)
               SIMULATE=1
            ;;
            -l)
               if $TEST $LOGGING -eq 0; then
                  LOGGING=1
               else
                  LOGGING=0
               fi
            ;;
            -v)
               if $TEST $VERBOSE -eq 0; then
                  VERBOSE=1
               else
                  VERBOSE=0
               fi
            ;;
            -u)
               NOSYSTEM=1
            ;;
            -V)
               $ECHO "$0 $VERSION"
               exit 0
            ;;
            -h)
               fp_usage
               exit 0
            ;;
            -*)
               $ECHO "$0: unknown option $1"
               $ECHO
               fp_usage
               exit 1
            ;;
         esac
         shift;
      done
    }
    
    fp_print()
    {
      MSG=$@
      if $TEST $LOGGING -eq 1; then
         $ECHO $MSG | $TEE -a $LOG_FILE
      else
         $ECHO $MSG
      fi
    }
    
    fp_start()
    {
      if $TEST $SIMULATE -eq 0 ; then
         if $TEST $( $GREP -c " /system " "/proc/mounts" ) -ne 0; then
            DEVICE=$( $GREP " /system " "/proc/mounts" | $CUT -d ' ' -f1 )
            if $TEST $DEBUG -eq 1; then
               fp_print "/system mounted on $DEVICE"
            fi
            if $TEST $( $GREP " /system " "/proc/mounts" | $GREP -c " ro " ) -ne 0; then
               $MOUNT -o remount,rw $DEVICE /system
               SYSREMOUNT=1
            fi
         else
            $MOUNT /system > /dev/null 2>&1
            SYSMOUNT=1
         fi
    
         if $TEST $( $GREP -c " /data " "/proc/mounts" ) -eq 0; then
            $MOUNT /data > /dev/null 2>&1
            DATAMOUNT=1
         fi
    
         if $TEST -e /dev/block/mmcblk0p2 && $TEST $( $GREP -c " $SD_EXT_DIRECTORY " "/proc/mounts" ) -eq 0; then
            $MOUNT $SD_EXT_DIRECTORY > /dev/null 2>&1
            SYSSDMOUNT=1
         fi
      fi
      if $TEST $( $MOUNT | $GREP -c /sdcard ) -eq 0; then
         LOG_FILE="/data/archidroid_fix_permissions.log"
      else
         LOG_FILE="/sdcard/archidroid_fix_permissions.log"
      fi
      if $TEST ! -e "$LOG_FILE"; then
         > $LOG_FILE
      fi
    
      fp_print "$0 $VERSION started at $FP_STARTTIME"
    }
    
    fp_chown_uid()
    {
      FP_OLDUID=$1
      FP_UID=$2
      FP_FILE=$3
    
      #if user ownership doesn't equal then change them
      if $TEST "$FP_OLDUID" != "$FP_UID"; then
         if $TEST $VERBOSE -ne 0; then
            fp_print "$UID_MSG $FP_FILE from '$FP_OLDUID' to '$FP_UID'"
         fi
         if $TEST $SIMULATE -eq 0; then
            $CHOWN $FP_UID "$FP_FILE"
         fi
      fi
    }
    
    fp_chown_gid()
    {
      FP_OLDGID=$1
      FP_GID=$2
      FP_FILE=$3
    
      #if group ownership doesn't equal then change them
      if $TEST "$FP_OLDGID" != "$FP_GID"; then
         if $TEST $VERBOSE -ne 0; then
            fp_print "$GID_MSG $FP_FILE from '$FP_OLDGID' to '$FP_GID'"
         fi
         if $TEST $SIMULATE -eq 0; then
            $CHOWN :$FP_GID "$FP_FILE"
         fi
      fi
    }
    
    fp_chmod()
    {
      FP_OLDPER=$1
      FP_OLDPER=$( $ECHO $FP_OLDPER | cut -c2-10 )
      FP_PERSTR=$2
      FP_PERNUM=$3
      FP_FILE=$4
    
      #if the permissions are not equal
      if $TEST "$FP_OLDPER" != "$FP_PERSTR"; then
         if $TEST $VERBOSE -ne 0; then
            fp_print "$PERM_MSG $FP_FILE from '$FP_OLDPER' to '$FP_PERSTR' ($FP_PERNUM)"
         fi
         #change the permissions
         if $TEST $SIMULATE -eq 0; then
            $CHMOD $FP_PERNUM "$FP_FILE"
         fi
      fi
    }
    
    fp_all()
    {
      FP_NUMS=$( $CAT /data/system/packages.xml | $EGREP "^<package.*serId" | $GREP -v framework-res.apk | $GREP -v com.htc.resources.apk | $WC -l )
      I=0
      $CAT /data/system/packages.xml | $EGREP "^<package.*serId" | $GREP -v framework-res.apk | $GREP -v com.htc.resources.apk | while read all_line; do
         I=$( $EXPR $I + 1 )
         fp_package "$all_line" $I $FP_NUMS
      done
    }
    
    fp_single()
    {
      FP_SFOUND=$( $CAT /data/system/packages.xml | $EGREP "^<package.*serId" | $GREP -v framework-res.apk | $GREP -v com.htc.resources.apk | $GREP -i $ONLY_ONE | wc -l )
      if $TEST $FP_SFOUND -gt 1; then
         fp_print "Cannot perform single operation on $FP_SFOUND matched package(s)."
         elif $TEST $FP_SFOUND = "" -o $FP_SFOUND -eq 0; then
         fp_print "Could not find the package you specified in the packages.xml file."
      else
         FP_SPKG=$( $CAT /data/system/packages.xml | $EGREP "^<package.*serId" | $GREP -v framework-res.apk | $GREP -v com.htc.resources.apk | $GREP -i $ONLY_ONE )
         fp_package "${FP_SPKG}" 1 1
      fi
    }
    
    fp_package()
    {
      pkgline=$1
      curnum=$2
      endnum=$3
      CODEPATH=$( $ECHO $pkgline | $SED 's%.* codePath="\(.*\)".*%\1%' |  $CUT -d '"' -f1 )
      PACKAGE=$( $ECHO $pkgline | $SED 's%.* name="\(.*\)".*%\1%' | $CUT -d '"' -f1 )
      UID=$( $ECHO $pkgline | $SED 's%.*serId="\(.*\)".*%\1%' |  $CUT -d '"' -f1 )
      GID=$UID
      APPDIR=$( $ECHO $CODEPATH | $SED 's%^\(.*\)/.*%\1%' )
      APK=$( $ECHO $CODEPATH | $SED 's%^.*/\(.*\..*\)$%\1%' )
    
      #debug
      if $TEST $DEBUG -eq 1; then
         fp_print "CODEPATH: $CODEPATH APPDIR: $APPDIR APK:$APK UID/GID:$UID:$GID"
      fi
    
      #check for existence of apk
      if $TEST -e $CODEPATH;  then
         fp_print "Processing ($curnum of $endnum): $PACKAGE..."
    
         #lets get existing permissions of CODEPATH
         OLD_UGD=$( $LS -ln "$CODEPATH" )
         OLD_PER=$( $ECHO $OLD_UGD | $CUT -d ' ' -f1 )
         OLD_UID=$( $ECHO $OLD_UGD | $CUT -d ' ' -f3 )
         OLD_GID=$( $ECHO $OLD_UGD | $CUT -d ' ' -f4 )
    
         #apk source dirs
         if $TEST "$APPDIR" = "/system/app"; then
            #skip system apps if set
            if $TEST "$NOSYSTEM" = "1"; then
               fp_print "***SKIPPING SYSTEM APP ($PACKAGE)!"
               return
            fi
            fp_chown_uid $OLD_UID 0 "$CODEPATH"
            fp_chown_gid $OLD_GID 0 "$CODEPATH"
            fp_chmod $OLD_PER "rw-r--r--" 644 "$CODEPATH"
            elif $TEST "$APPDIR" = "/data/app" || $TEST "$APPDIR" = "/sd-ext/app"; then
            fp_chown_uid $OLD_UID 1000 "$CODEPATH"
            fp_chown_gid $OLD_GID 1000 "$CODEPATH"
            fp_chmod $OLD_PER "rw-r--r--" 644 "$CODEPATH"
            elif $TEST "$APPDIR" = "/data/app-private" || $TEST "$APPDIR" = "/sd-ext/app-private"; then
            fp_chown_uid $OLD_UID 1000 "$CODEPATH"
            fp_chown_gid $OLD_GID $GID "$CODEPATH"
            fp_chmod $OLD_PER "rw-r-----" 640 "$CODEPATH"
         fi
      else
         fp_print "$CODEPATH does not exist ($curnum of $endnum). Reinstall..."
         if $TEST $REMOVE -eq 1; then
            if $TEST -d /data/data/$PACKAGE ; then
               fp_print "Removing stale dir /data/data/$PACKAGE"
               if $TEST $SIMULATE -eq 0 ; then
                  $RM -R /data/data/$PACKAGE
               fi
            fi
         fi
      fi
    
      #the data/data for the package
      if $TEST -d "/data/data/$PACKAGE"; then
         #find all directories in /data/data/$PACKAGE
         $FIND /data/data/$PACKAGE -type d -exec $LS -ldn {} \; | while read dataline; do
            #get existing permissions of that directory
            OLD_PER=$( $ECHO $dataline | $CUT -d ' ' -f1 )
            OLD_UID=$( $ECHO $dataline | $CUT -d ' ' -f3 )
            OLD_GID=$( $ECHO $dataline | $CUT -d ' ' -f4 )
            FILEDIR=$( $ECHO $dataline | $CUT -d ' ' -f9 )
            FOURDIR=$( $ECHO $FILEDIR | $CUT -d '/' -f5 )
    
            #set defaults for iteration
            ISLIB=0
            REVPERM=755
            REVPSTR="rwxr-xr-x"
            REVUID=$UID
            REVGID=$GID
    
            if $TEST "$FOURDIR" = ""; then
               #package directory, perms:755 owner:$UID:$GID
               fp_chmod $OLD_PER "rwxr-xr-x" 755 "$FILEDIR"
               elif $TEST "$FOURDIR" = "lib"; then
               #lib directory, perms:755 owner:1000:1000
               #lib files, perms:755 owner:1000:1000
               ISLIB=1
               REVPERM=755
               REVPSTR="rwxr-xr-x"
               REVUID=1000
               REVGID=1000
               fp_chmod $OLD_PER "rwxr-xr-x" 755 "$FILEDIR"
               elif $TEST "$FOURDIR" = "shared_prefs"; then
               #shared_prefs directories, perms:771 owner:$UID:$GID
               #shared_prefs files, perms:660 owner:$UID:$GID
               REVPERM=660
               REVPSTR="rw-rw----"
               fp_chmod $OLD_PER "rwxrwx--x" 771 "$FILEDIR"
               elif $TEST "$FOURDIR" = "databases"; then
               #databases directories, perms:771 owner:$UID:$GID
               #databases files, perms:660 owner:$UID:$GID
               REVPERM=660
               REVPSTR="rw-rw----"
               fp_chmod $OLD_PER "rwxrwx--x" 771 "$FILEDIR"
               elif $TEST "$FOURDIR" = "cache"; then
               #cache directories, perms:771 owner:$UID:$GID
               #cache files, perms:600 owner:$UID:GID
               REVPERM=600
               REVPSTR="rw-------"
               fp_chmod $OLD_PER "rwxrwx--x" 771 "$FILEDIR"
            else
               #other directories, perms:771 owner:$UID:$GID
               REVPERM=771
               REVPSTR="rwxrwx--x"
               fp_chmod $OLD_PER "rwxrwx--x" 771 "$FILEDIR"
            fi
    
            #change ownership of directories matched
            if $TEST "$ISLIB" = "1"; then
               fp_chown_uid $OLD_UID 1000 "$FILEDIR"
               fp_chown_gid $OLD_GID 1000 "$FILEDIR"
            else
               fp_chown_uid $OLD_UID $UID "$FILEDIR"
               fp_chown_gid $OLD_GID $GID "$FILEDIR"
            fi
    
            #if any files exist in directory with improper permissions reset them
            $FIND $FILEDIR -type f -maxdepth 1 ! -perm $REVPERM -exec $LS -ln {} \; | while read subline; do
               OLD_PER=$( $ECHO $subline | $CUT -d ' ' -f1 )
               SUBFILE=$( $ECHO $subline | $CUT -d ' ' -f9 )
               fp_chmod $OLD_PER $REVPSTR $REVPERM "$SUBFILE"
            done
    
            #if any files exist in directory with improper user reset them
            $FIND $FILEDIR -type f -maxdepth 1 ! -user $REVUID -exec $LS -ln {} \; | while read subline; do
               OLD_UID=$( $ECHO $subline | $CUT -d ' ' -f3 )
               SUBFILE=$( $ECHO $subline | $CUT -d ' ' -f9 )
               fp_chown_uid $OLD_UID $REVUID "$SUBFILE"
            done
    
            #if any files exist in directory with improper group reset them
            $FIND $FILEDIR -type f -maxdepth 1 ! -group $REVGID -exec $LS -ln {} \; | while read subline; do
               OLD_GID=$( $ECHO $subline | $CUT -d ' ' -f4 )
               SUBFILE=$( $ECHO $subline | $CUT -d ' ' -f9 )
               fp_chown_gid $OLD_GID $REVGID "$SUBFILE"
            done
         done
      fi
    }
    
    date_diff()
    {
      if $TEST $# -ne 2; then
         FP_DDM="E"
         FP_DDS="E"
         return
      fi
      FP_DDD=$( $EXPR $2 - $1 )
      FP_DDM=$( $EXPR $FP_DDD / 60 )
      FP_DDS=$( $EXPR $FP_DDD % 60 )
    }
    
    fp_end()
    {
      if $TEST $SYSREMOUNT -eq 1; then
         $MOUNT -o remount,ro $DEVICE /system > /dev/null 2>&1
      fi
    
      if $TEST $SYSSDMOUNT -eq 1; then
         $UMOUNT $SD_EXT_DIRECTORY > /dev/null 2>&1
      fi
    
      if $TEST $SYSMOUNT -eq 1; then
         $UMOUNT /system > /dev/null 2>&1
      fi
    
      if $TEST $DATAMOUNT -eq 1; then
         $UMOUNT /data > /dev/null 2>&1
      fi
    
      FP_ENDTIME=$( $DATE +"%m-%d-%Y %H:%M:%S" )
      FP_ENDEPOCH=$( $DATE +%s )
    
      date_diff $FP_STARTEPOCH $FP_ENDEPOCH
    
      fp_print "$0 $VERSION ended at $FP_ENDTIME (Runtime:${FP_DDM}m${FP_DDS}s)"
    }
    
    #MAIN SCRIPT
    
    fp_parseargs $@
    fp_start
    if $TEST "$ONLY_ONE" != "" -a "$ONLY_ONE" != "0" ; then
      fp_single "$ONLY_ONE"
    else
      fp_all
    fi
    
    # We've finished so we're no longer needed
    sysrw
    rm -f $0
    sysro
    
    # End
    fp_end
    exit 0

    Dzięki temu jesteśmy pewni, że skrypt odpali się jako ostatni, wyczeka ew. załadowania systemu, ustawi odpowiednie accessy i się sam usunie.

    UWAGA! Metoda jest czysto archiwalna, ponieważ NIE POWINNO jej się stosować przede wszystkim na Androidach ze wsparciem SELinux oraz na ROMach, w który "wiemy" co się dzieje. Nie polecam stosowania jej na dłuższą metę.

    #2 Flashowanie /data/data

    Ostatnio natknąłem się na potrzebę sflashowania programu razem z jego "ustawieniami". Ustawienia danej aplikacji siedzą w /data/data/codenameaplikacji/shared_prefs. O ile na Stockach jest to dość proste (jeszcze) bo wystarczy wyłącznie dane wrzucić w odpowiednie miejsca podczas flashowania to z Cyanogenem i generalnie z Androidem 4.2.2 będą już problemy.

    1. Jeśli wrzucimy potrzebne pliki podczas flashowania to Android podczas pierwszego bootu nam je usunie

    2. Jeśli wrzucimy potrzebne pliki podczas flashowania i zablokujemy je poprzez chattr +i to aplikacje owszem będą działały, ale Android wywali nam błąd o niekompatybilności danych i niestabilności systemu, a tego nie chcemy.

    3. Jeśli wrzucimy dane w skrypcie post-instalacyjnym (po załadowaniu) to dane będą dopiero załadowane od następnego rebootu.

    Pytanie brzmi. Jak sobie z tym poradzić?

    Nie powiem, że miałem dość ładną zagadkę przez ostatni tydzień, ale w końcu sobie poradziłem z jej rozwiązaniem. Stworzyłem skrypt init.d, który w pełni spełnia moje oczekiwania.

    Skrypt jest mojego własnego autorstwa, pisany od zera. Doceń moją pracę jeśli będziesz chciał go użyć :).

    /system/etc/init.d/98ArchiDroid_RunOnce

    #!/system/bin/sh
    
    # ArchiDroid FirstBoot Script
    # JustArchi@JustArchi.net
    
    # Not Disabled
    #exit 0
    
    # ArchiDroid Semaphore
    # Wait until we see some android processes to consider boot is more or less complete (credits to AndiP71)
    while ! pgrep com.android ; do
    
    # Now let's MAKE SURE that our settings are in fact applied, only if we don't have shared_prefs already (prevent non-clean override)
    
    if [ -d /data/media/0/archidroid/firstboot ]; then
    	cd /data/media/0/archidroid/firstboot
    	for FOLDER in * ; do
    		if [ -d /data/data/$FOLDER ]; then
    			if [ ! -d /data/data/$FOLDER/shared_prefs ]; then
    				mv $FOLDER/* /data/data/$FOLDER
    
    				# Let's set basic permissions because ArchiDroid_Permfix will fix it anyway really soon
    				ADOWNER=`stat -c %U /data/data/$FOLDER`
    				chown -hR $ADOWNER.$ADOWNER /data/data/$FOLDER
    				chmod -R 755 /data/data/$FOLDER
    
    				# And we're done!
    				rm -Rf $FOLDER
    				ADOWNER=""
    			fi
    		fi
    	done
    fi
    
    # Sleeping time
    sleep 2
    done
    
    # Now that is checked, let's just wait another tiny little bit
    sleep 10
    
    # If we have any more runonce scripts then it's the right place for that
    
    
    
    # I'm runonce script so let's clean everything and delete myself
    
    # NOTICE
    # ArchiDroid has sysro/sysrw support, change that to remount system rw if needed
    rm -Rf /data/media/0/archidroid/firstboot
    sysrw
    rm -f $0
    sysro
    
    # Finish
    exit 0

    Zasada działania jest bardzo prosta. Podczas flashowania tworzymy przykładowa strukturę /data/media/0/archidroid/firstboot/, a następnie w tym folderze firstboot umieszczamy foldery zgodne z nazwami folderów aplikacji, do których chcemy wrzucić dane. Czyli przykładowo dla boeffli będzie to /data/media/0/archidroid/firstboot/com.near.boefflasound/shared_prefs. Mój skrypt RunOnce wyczeka aż Android wyczyści stare dane i utworzy foldery, a następnie od razu wrzuci do nich dane naszych aplikacji i ustawi odpowiednie accessy. Efekt jest taki, że Androidowi nie będzie to przeszkadzać, a mój permfix (który również dołączam w punkcie #1) ładnie przeczyści pozostałości.

    Skryptowi oczywiście nadajemy flagę (chmod) +x, żeby był wykonany podczas bootowania (i umieszczamy go w /system/etc/init.d).

    UWAGA! Mój system wykrywania załadowanego systemu wstrzymuje jakiekolwiek dalsze skrypty przed uruchomieniem tzn. uruchomią się, ale dopiero po całkowitym zakończeniu wykonywania się runonce'a, dlatego upewnijmy się, że jest to ostatni lub jeden z ostatnich skryptów do wykonania (poprzez odpowiednią alfabetyczną nazwę). Ew. możemy zastosować mój mały "hack" z backgroundem, który wprowadziłem w nowszych wersjach RunOnce. W tym punkcie przedstawiam ogólną "ideę" działania skryptu, a nie jego najnowszą i najlepszą wersję.

    UWAGA! Jeśli Twój rom nie ma wsparcia dla sysro/sysrw zamień te komendy na mount -o remount,ro /system i rw.

    #? GitHub / (CR)LF / Linux vs. Windows

    Nie od dziś wiadomo, że Windows i Linux się nie lubią, również nawet pod taką błahą kwestią jak znaki nowej linii.

    Co to jest znak nowej linii? To specjalny znak, który określa przejście do nowego wiersza w plikach tekstowych (i nie tylko). W linuxie jest to LF, w windowsie CRLF, po więcej informacji zapraszam na google.

    No i dobra, fajnie, ale o co tu chodzi? Na pewno nie raz spotkałeś się z sytuacją w której dany plik tekstowy X był otwierany przez notatnik jako jeden wielki tekst ciągły, w ogóle bez "enterów", podczas gdy Notepad++ otwierał go normalnie. Czemu tak? Ano właśnie ten plik pochodzi z Linuxa lub systemu, który nie jest zgodny z Windowsem i używa innego zakończenia plików. Notepad++ jest na tyle sprytny, że sam wykrywa które zakończenie jest używane i właśnie tego używa, niestety nie każdy tak się zachowuje.

    W gicie jest taki fajny zapisik konfiguracyjny o nazwie core.autocrlf. Może on przyjmować różne wartości, ale nas interesują dwie - true oraz false. Na wszystkich linuxach i gitach linuxowych ta funkcja przyjmuje wartość false, podczas gdy na gicie windowsowym true. Ponoć jest to zamierzone, ale ja nie widzę żadnego pozytywu w tym, że git windowsowy chce nam na sile poprawić życie i mieli wszystkie pliki, które zdoła na okoliczność CRLF.

    Prosta sztuczka, która temu zapobiegnie:

    git config --global core.autocrlf false

    Należy to zrobić przed sklonowaniem jakiegokolwiek repo. Wtedy od następnego clone'a linie będą już normalne.

    A czemu jest to takie ważne? Ano temu, że przykładowo ściągając ArchiDroida z mojego githuba via git for windows nie uda nam się odpalić nawet aromy, z racji że spakujemy wersję z CRLF'ami, a nie LF'ami, a ani aroma ani android CRLF'ów nie czyta. Dlatego też jest to bardzo istotne i praktycznie pierwszy krok, który należy zrobić (dotyczy tylko git for windows).

    Inna rzeczą, o której warto wspomnieć jest system plików. W linuxach standardowo jest ext4, w windowsach ntfs. No i dobra, można powiedzieć, że bez problemu da się kopiować jeden plik z ext4 na ntfs i vice versa, w końcu robimy to cały czas w naszym sgs3, ale czy na pewno?

    Wykonaj test, utwórz na pulpicie plik test.txt, a następnie plik TEST.TXT. Niby litery są różne, a więc nie ma tej samej nazwy, no i co? :D

    No, to teraz będzie najlepsza część.

    root@archi ~/git # touch a.txt
    root@archi ~/git # touch A.TXT
    root@archi ~/git # ls
    a.txt  A.TXT

    Co ty na to? :D

    Powiesz sobie teraz "dobra, ale jak rzadko mamy styczność z taką sytuacją". Wbrew pozorom podczas tworzenia romów na androida bardzo często. A jak często? Pechowa liczba 13 plików o takich samych nazwach (ale różnych wielkościach liter) zawiera się w linuxowym kernelu 3.0.X. No i tutaj zonk bo jeśli gitem sklonujemy sobie repo linuxowego kernela 3.0.X to od razu na dzień dobry pojawi nam się 13 zmodyfikowanych plików, a przecież jeszcze nie zaczęliśmy nic zmieniać. No i w tym momencie całe repo można już wywalić bo jest popsute ;). Poza tym, źródła Androida 4.4.X też NIE SĄ już zgodne z NTFS i linuxowy filesystem jest obowiązkowy.

    To tylko przykłady niekompatybilności linuxa i windowsa, których można znaleźć o wiele więcej. Dlatego też trzeba pamiętać przynajmniej o tych dwóch rzeczach wyżej jeśli tworzy się rzeczy oparte o Androida. Nawet nie wiecie ile czasu straciłem na próby poszukiwania problemu gdy winą był nie kto inny, ale właśnie wymuszony CRLF, o istnieniu którego całkowicie zapomniałem w tamtym czasie.

    NAJBEZPIECZNIEJSZĄ metodą na zabawę z romami jest działanie na jakimkolwiek linuxie z partycją ext4 (lub jakąkolwiek inną zgodną z case-insensitive), a do "shared" folderu windowsowego kopiowanie wyłącznie wyników końcowych, zipek, obrazów kernela itp.

    Jeśli temat okaże się pomocny to na pewno dorzucę więcej ciekawostek w związku z zaawansowaną praca nad Androidem. Póki co nie proszę o podwieszenie tematu, ale jeśli któryś z moderatorów uzna, że temat jest tego wart to będę wdzięczny.

    Z miłą chęcią również odpowiem na wszystkie pytania związane z "profesjonalnym" tworzeniem romów, te najbardziej podstawowe pytania proszę kierować do pozostałych tematów, jako że nie mam zbytnio sił na tłumaczeniu czym jest linux, jak zbudować CM etc. :).

    Edytowane przez JustArchi

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    maxprzemo

    Witam .

    Widzę że jesteś chyba w stanie pomóc mi w moim problemie .

    Chciałem zsynchronizować repozytorium na mój dysk zewnętrzny ale operacja niestety się nie powiodła i wyskoczył mi taki error :

    unq9.jpg

    Coś o tym że mój system plików musi obsługiwać symlinki .

    Obecnie na dysku mam system plików FAT32 , Primary , Active .

    Na jaki muszę zmienić żeby synchronizacja repozytorium ruszyła ?

    No i ewentualnie żeby windows też później widział ten system plików bo często skacze między linuxem a windowsem .

    Pozdrawiam .

    Edytowane przez wdarku
    Obrazy umieszczamy w spoilerach

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Dzięki ci :D

    Piwko leci. Pewnie WKD622 też się ucieszy :)

    Edytowane przez Zenderable

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    JustArchi
    Witam .

    Widzę że jesteś chyba w stanie pomóc mi w moim problemie .

    Chciałem zsynchronizować repozytorium na mój dysk zewnętrzny ale operacja niestety się nie powiodła i wyskoczył mi taki error :

    unq9.jpg

    Coś o tym że mój system plików musi obsługiwać symlinki .

    Obecnie na dysku mam system plików FAT32 , Primary , Active .

    Na jaki muszę zmienić żeby synchronizacja repozytorium ruszyła ?

    No i ewentualnie żeby windows też później widział ten system plików bo często skacze między linuxem a windowsem .

    Pozdrawiam .

    Cześć.

    FAT32 nie obsługuje symlinków. Przeczytaj mój punkt dotyczący LF vs. CRLF, porusza m.in ten problem (pod nieco innym kątem).

    Musisz przeformatować system na zgodny z linuxem, np. ext4.

    Edytowane przez wdarku
    Obrazy w spoilerach

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Siemka. Mam dylemat :D Linux Ubuntu 13.10 czy Debian Whezzy bedzie lepszy do takiego "Androidowania"?

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    JustArchi

    Nie ma różnicy. Ubuntu będzie nieco szybszy bo używa upstarta zamiasy sysvinita.

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    @up Ok thx :) Jeszcze jedno ile gb trzeba pobrać ze zródła CM, bo jedni piszą,że 100gb,drudzy 10gb.. To jak to wkońcu jest?

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    JustArchi

    Tyle, ile potrzeba.

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    @up czyli ile mam zarezerwować na to miejsca(bo robie w Virtual Boxie)?

    Edit: I nie wiem czy to ważne ale bede kombinował z SGS III

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach
    JustArchi

    80 GB starczy na wszystko włącznie z systemem.

    Udostępnij tę odpowiedź


    Odnośnik do odpowiedzi
    Udostępnij na innych stronach

    Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

    Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

    Zarejestruj nowe konto

    Załóż nowe konto. To bardzo proste!

    Zarejestruj się

    Zaloguj się

    Posiadasz już konto? Zaloguj się poniżej.

    Zaloguj się

    • Przeglądający   0 użytkowników

      Brak zarejestrowanych użytkowników przeglądających tę stronę.