XPost: comp.mobile.android, alt.comp.os.windows-10   
   From: mariasophia@comprehension.com   
      
   Frank Slootweg wrote:   
   >> The privacy decency point is I know exactly where my contacts are stored.   
   >> Now let's ask you to answer the same question of fact that I just did.   
   >>   
   >> Q: Where are all *your* Android mobile-device contacts actually stored?   
   >> A: ?   
   >   
   > Carlos already answered it and very well and succinctly, so I'll just   
   > repeat it:   
   >   
   >    
   > In our phones, with a copy in our private area of google servers. Under   
   > our control.   
   >    
      
   Hi Frank,   
      
   Thanks for hazarding a guess as to what the answer to the question is.   
   I am well aware it's scary to answer factual questions on Usenet.   
      
   Unfortunately, the explanation you gave leaves out an important part since   
   even if contacts are stored locally and synced to Google, that's only one   
   tiny part of the picture. Any app with contact access can upload that data   
   to its own servers, and many do. WhatsApp, Facebook Messenger, Telegram,   
   Signal (for contact discovery), LinkedIn and many others all do this.   
      
   And it's not just messaging apps. Contact managers, SMS apps, RCS clients,   
   dialer replacements, email apps, sharing apps and even spam-blocking or   
   caller-ID apps routinely upload contact information. They use it for   
   matching, spam detection, 'smart' suggestions, syncing or building their   
   own databases. Once you grant access to any app on Android, there's no   
   technical way to verify where that data goes or how long it's kept."   
      
   That's why saying 'my contacts are only on my phone and Google' isn't   
   accurate in practice. But since you were brave enough to answer the   
   question (which I knew ahead of time how you would answer it), allow me to   
   be brave enough to point out on my own system how many apps that may be.   
      
   C:\> adb shell pm list permissions -g -d | grep CONTACTS   
    group:android.permission-group.CONTACTS   
    permission:android.permission.WRITE_CONTACTS   
    permission:android.permission.READ_CONTACTS   
   This prints every package entry where READ_CONTACTS appears in the granted   
   permissions list where the second command below gives cleaner output.   
      
   This dumps too much information:   
    C:\> adb shell dumpsys package | findstr /R /C:"Package \[" /C:   
   grantedPermissions" /C:"READ_CONTACTS"   
      
   Where on Windows we're looking for apps with permission granted.   
    android.permission.READ_CONTACTS: granted=true   
      
   We care about lines containing Package [ & granted=true & READ_CONTACTS   
    C:\> adb shell dumpsys package | findstr /R "Package \[" > pkgs.txt & adb   
   shell dumpsys package | findstr "READ_CONTACTS" | findstr "granted=true" >   
   granted.txt & for /f "tokens=2 delims=[]" %A in ('findstr /G:granted.txt   
   pkgs.txt') do @echo %A   
   But that is so horrible that I had to drop down into PowerShell syntax.   
      
   C:\> type extract_contacts.bat   
    @echo off   
    :: extract_contacts.bat   
    powershell -ExecutionPolicy Bypass -File extract_contacts.ps1   
    pause   
      
   This should work but I just can't get the syntax right.   
   C:\ type extract_contacts.ps1   
    # extract_contacts.ps1   
    # version 1p0 20260210   
    # a. Runs adb shell dumpsys package   
    # b. finds each package block   
    # c. checks whether that block contains READ_CONTACTS and granted=true   
    # d. prints only the package names that actually have contact access   
    # Run using a batch script that calls this powershell script   
    # @echo off   
    # :: extract_contacts.bat   
    # powershell -ExecutionPolicy Bypass -File extract_contacts.ps1   
    # pause   
    # version 1p1 20260210   
    # Had to completely rewrite it as powershell hates white space   
    # version 1p2 20260210   
    # Fixed regex patterns so they're each only a single line   
    # version 1p3 20260210   
    # Fixed regex so it matches... Package [   
    # version 1p4 20260210   
    # Added... $blocks = $blocks[1..($blocks.Count - 1)]   
    # To remove headerless garbage block that contains permission lines   
    # This takes into account the split pattern, the indentation issue,   
    # the junk first block, the name extraction and the grant filter out of   
    # C:\> adb shell dumpsys package   
    # version 1p5 20260210   
    # Needed to trim in the for loop   
      
    $packages = adb shell dumpsys package   
      
    # Regex patterns stored safely in variables   
    $splitPattern = ' Package \['   
    $grantPattern = 'android\.permission\.READ_CONTACTS: granted=true'   
    # $namePattern = '^(.*?)\]'   
    # $namePattern = '^(?!android\.permission)(.*?)\]'   
    $namePattern = '^([^\]]+)\]'   
      
    # Split into blocks per package   
    $blocks = $packages -split $splitPattern   
    $blocks = $blocks[1..($blocks.Count - 1)]   
      
    foreach ($block in $blocks) {   
    $block = $block.TrimStart()   
    if ($block -match $grantPattern) {   
    if ($block -match $namePattern) {   
    $pkg = $matches[1].Trim()   
    Write-Output $pkg   
    }   
    }   
    }   
    # end of extract_contacts.ps1   
      
      
   This is what is working, so far, from Windows to Android:   
    1. adb shell dumpsys package runs correctly.   
    $packages contains the full dump.   
    2. The split produces multiple blocks.   
    $blocks is an array with many entries.   
    3. The junk first block is removed correctly.   
    $blocks = $blocks[1..(...)] works.   
    4. The READ_CONTACTS filter works correctly.   
    $grantPattern matches exactly the lines you see.   
    5. The loop runs and prints matches.   
    The script is executing the intend   
   But this isn't working so I'm gonna try something else.   
      
    6. The package-name regex never matches the package header.   
    Not even once. $matches[1] is never the package name.   
      
    7. The split pattern does not match the real indentation.   
    The dump uses non-ASCII whitespace (tabs, NBSP, Unicode spaces).   
    PowerShell treats these differently than ASCII spaces.   
      
    8. Because the split is wrong, each block is missing the package header line.   
    The block starts after the package name.   
    Therefore the name regex never sees the package name.   
      
    9. The name regex falls back to the next line containing a closing bracket.   
    The first such line is always:   
    android.permission.READ_CONTACTS: granted=true, flags=...   
      
   10. Trimming does not fix the issue.   
    TrimStart does not remove leading newlines inside multi-line strings.   
    The package name still never appears at the start of the block.   
      
   So I'm gonna drop back to a purely manual method since my goal   
   was to provide everyone with a script that told them what they   
   don't know until they look what has the read permissions.   
      
      
   [continued in next message]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|