adb: Added configuration setting oldandroid=true
authorJoey Hess <joeyh@joeyh.name>
Wed, 13 Jul 2022 22:00:47 +0000 (18:00 -0400)
committerJoey Hess <joeyh@joeyh.name>
Wed, 13 Jul 2022 22:00:47 +0000 (18:00 -0400)
To avoid using find -printf, which was first supported in Android around
2019-2020.

Probing seems too fragile, and execing stat once per file is too slow to do
when there's a faster way available, which brought me to an option...

Sponsored-by: Brett Eisenberg on Patreon
CHANGELOG
Remote/Adb.hs
doc/bugs/adb_remote_fails_to_import_treeish.mdwn
doc/bugs/adb_remote_fails_to_import_treeish/comment_3_5e819d0b5f3101e86f0f95a7ab725ad4._comment [new file with mode: 0644]
doc/special_remotes/adb.mdwn

index eb210d72ea40376a3afeeb2742b46f3c5f9abeb6..e7ce34e4b080633eb6d4ade037259ddb0038a9c6 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,11 @@ git-annex (10.20220625) UNRELEASED; urgency=medium
     another directory. (Introduced in version 10.20220624)
   * filter-process: Fix a bug involving handling of empty files,
     that caused git to kill git-annex filter-process.
+  * adb: Added configuration setting oldandroid=true to avoid using
+    find -printf, which was first supported in Android around 2019-2020.
+    This may need to be enabled for old android devices that used to work
+    without it being set, since version 10.20220222 started using 
+    find -printf.
 
  -- Joey Hess <id@joeyh.name>  Tue, 28 Jun 2022 14:49:17 -0400
 
index 081b69cfe86529d2f3852de665d7cf9c88b87766..715b8ab3a6ffe6d1996e05eabb13cd70712c9915 100644 (file)
@@ -46,6 +46,8 @@ remote = specialRemoteType $ RemoteType
                        (FieldDesc "sometimes needed to specify which Android device to use")
                , yesNoParser ignorefinderrorField (Just False)
                        (FieldDesc "ignore adb find errors")
+               , yesNoParser oldandroidField (Just False)
+                       (FieldDesc "support old versions of android (slower)")
                ]
        , setup = adbSetup
        , exportSupported = exportIsSupported
@@ -62,6 +64,8 @@ androidserialField = Accepted "androidserial"
 ignorefinderrorField :: RemoteConfigField
 ignorefinderrorField = Accepted "ignorefinderror"
 
+oldandroidField :: RemoteConfigField
+oldandroidField = Accepted "oldandroid"
 
 gen :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> RemoteStateHandle -> Annex (Maybe Remote)
 gen r u rc gc rs = do
@@ -305,26 +309,44 @@ listImportableContentsM serial adir c = adbfind >>= \case
                ImportableContents (mapMaybe mk ls) []
        Nothing -> giveup "adb find failed"
   where
-       adbfind = adbShell' serial
+       adbfind = adbShell' serial findparams
+               (\s -> if oldandroid
+                       then s ++ ignorefinderrorsh
+                       else concat
+                               [ "set -o pipefail; "
+                               , s
+                               , "| xargs -0 stat -c " ++ shellEscape statformat ++ " --"
+                               , ignorefinderrorsh
+                               ]
+               )
+       
+       findparams =
                [ Param "find"
                -- trailing slash is needed, or android's find command
                -- won't recurse into the directory
                , File $ fromAndroidPath adir ++ "/"
                , Param "-type", Param "f"
-               , Param "-printf", Param "%p\\0"
-               ] 
-               (\s -> concat
-                       [ "set -o pipefail; "
-                       , s
-                       , "| xargs -0 stat -c " ++ shellEscape statformat ++ " --"
-                       , if ignorefinderror then " || true" else ""
-                       ]
-               )
+               ] ++ if oldandroid
+                       then 
+                               [ Param "-exec"
+                               , Param "stat"
+                               , Param "-c"
+                               , Param statformat
+                               , Param "{}"
+                               , Param ";"
+                               ]
+                       else 
+                               [ Param "-printf"
+                               , Param "%p\\0"
+                               ]
 
        ignorefinderror = fromMaybe False (getRemoteConfigValue ignorefinderrorField c)
+       oldandroid = fromMaybe False (getRemoteConfigValue oldandroidField c)
 
        statformat = adbStatFormat ++ "\t%n"
 
+       ignorefinderrorsh = if ignorefinderror then " || true" else ""
+
        mk ('S':'T':'\t':l) =
                let (stat, fn) = separate (== '\t') l
                    sz = fromMaybe 0 (readish (takeWhile (/= ' ') stat))
index c9cd1d51b764f43e94bc859ceb640e9de46da531..d53bd900d9bf8a084c807b648011e8dd9397598f 100644 (file)
@@ -72,3 +72,4 @@ http://git-annex.branchable.com/tips/android_sync_with_adb/#comment-88511cef6861
 ### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)
 git annex has been great so far, aside from some pitfalls on some of the more advanced features, i have been using it to manage my files using all kinds of special and non special remotes very solidly for 2 years now.
 
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/adb_remote_fails_to_import_treeish/comment_3_5e819d0b5f3101e86f0f95a7ab725ad4._comment b/doc/bugs/adb_remote_fails_to_import_treeish/comment_3_5e819d0b5f3101e86f0f95a7ab725ad4._comment
new file mode 100644 (file)
index 0000000..242fa0a
--- /dev/null
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2022-07-13T19:18:13Z"
+ content="""
+Ok, I've added an oldandroid=yes configuration to fix this. To enable it:
+
+       git-annex enableremote android oldandroid=yes
+
+(Replace "android" with whatever name you used for the adb remote.)
+
+I don't much like this, but it's better than git-annex being slow with new
+phones, and being slow with old phones is better than failing when there are
+too many files to import. I did consider trying to auto-probe it from the
+error message, but that seemed likely to be too fragile.
+"""]]
index 44f0f79e90f183db60910b2570e179e6beadf97f..ebd1c1c3da109a508b8e494d84ad6c06df4b74a6 100644 (file)
@@ -32,6 +32,11 @@ the adb remote.
   by [[git-annex-import]]. When set in combination with exporttree,
   this lets files be imported from it, and changes exported back to it.
 
+* `oldandroid` - Set to "yes" if your Android device is too old
+  to support `find -printf`. Enabling this will make importing slower.
+  If you see an error like "bad arg '-printf'", you can enable this
+  option, by running eg: `git-annex enableremote android oldandroid=yes`
+
 * `ignorefinderror` - Set to "yes" to ignore errors when running "adb find"
   on the Android device. This can be useful eg, if some subdirectories are
   not readable, to let it import the other things that are readable.