Football Fans: Download the 2012 Schedule App from Google Play!


Go Back   Android Forums > Android Development > Application Development > Developer 101

Developer 101 101 Tutorials



Reply
 
LinkBack Thread Tools
Old January 5th, 2012, 03:36 AM   #1 (permalink)
New Member
 
Join Date: Jan 2012
Posts: 13
 
Device(s):
Thanks: 4
Thanked 0 Times in 0 Posts
Default UID - why can share file. Practical usage UID?

Hello android masters,

Android recruit reporting.

Could someone tell me about android UID? I searched but could not find any usefull information and/or working sample prog about UID.

I programmed 2 apps:
1 to create a file on the android SD card.
2nd app reads the text from the SD card file.

additional info:
- Both app use the same android vm on my eclipse Android SDK
- package names should not matter, but I gave them different names: com.xxx and
com.yyy

The text is written to my logcat in my linux terminal. I could read the SD file created by the other app. I did not use sharedUserId. I thought that every app gets it's own UID, and that they could not share files.

Could someone tell me why I can, without setting UID?
2nd question: How is UID used practically? didn't see any sample programs that use UID.

Many thanks in advance.

chihwahli is offline  
Reply With Quote
Sponsors
Old January 5th, 2012, 03:42 AM   #2 (permalink)
Premium Member
 
Join Date: Oct 2011
Location: Sydney, Australia
Posts: 193
 
Device(s): Galaxy Nexus GSM
Thanks: 2
Thanked 37 Times in 33 Posts
Default

There's no protection on the SD card. They're typically formatted with some kind of FAT filesystem. FAT filesystems doesn't support access permissions.

The restrictions of one app not accessing another app's data only applies to internal storage.
jiminaus is offline  
Reply With Quote
The Following User Says Thank You to jiminaus For This Useful Post:
chihwahli (January 5th, 2012)
Old January 5th, 2012, 03:53 AM   #3 (permalink)
New Member
 
Join Date: Jan 2012
Posts: 13
 
Device(s):
Thanks: 4
Thanked 0 Times in 0 Posts
Default

Thanks jiminaus that is usefull info.

Is there another way to share a variable and use UID?, so that I can share data between apps. I am researching the use of UID and sharing data. Normally apps operate in different vm's. Thus totally isolated from eachother.

(I know of SQLite, etc. But that is not the research I have to do for my study. Will add that in my report as a possible way to share data between apps)

Any more volunteers who might enlighten me about UID?
chihwahli is offline  
Reply With Quote
Old January 5th, 2012, 04:09 AM   #4 (permalink)
Premium Member
 
Join Date: Oct 2011
Location: Sydney, Australia
Posts: 193
 
Device(s): Galaxy Nexus GSM
Thanks: 2
Thanked 37 Times in 33 Posts
Default

You've studied both of these right?

Security and Permissions | Android Developers
Android Security Overview | Android Open Source

In particular the sharedUserId element of AndroidManifest.xml
jiminaus is offline  
Reply With Quote
Old January 5th, 2012, 09:35 AM   #5 (permalink)
New Member
 
Join Date: Jan 2012
Posts: 13
 
Device(s):
Thanks: 4
Thanked 0 Times in 0 Posts
Default

Yes, although I have read them, perhaps I missed something. Let me quote what I understand from it.

Quotes from Security and Permissions | Android Developers
Setting sharedUserId: "By doing this, for purposes of security the two packages are then treated as being the same application, with the same user ID and file permissions.... Any data stored by an application will be assigned that application's user ID, and not normally accessible to other packages"
Quote: android:sharedUserIdThe name of a Linux user ID that will be shared with other applications. By default, Android assigns each application its own unique user ID. However, if this attribute is set to the same value for two or more applications, they will all share the same ID — provided that they are also signed by the same certificate. Application with the same user ID can access each other's data and, if desired, run in the same process.How to implement: add this line to the androidManifest.xml: "android:sharedUserId="com.cwli"
My thoughts: Thus when 2 apps have the same UID, they could run in the same process


An Android app does not have permissions unless you set them in the Androidmanifest.xml file. An app can enforce their own permissions that are not found in manifest.permission.

Quotes from Android Security Overview | Android Open Source
Android application runtime: "Applications are sandboxed at kernel level..."

Filesystem permissions: "In a UNIX-style environment, filesystem permissions ensure that one user cannot alter or read another user's files. In the case of Android, each application runs as its own user. Unless the developer explicitly exposes files to other applications, files created by one application cannot be read or altered by another application." My thought: It's possible to create a file in Android filesystem and then give other apps permission to read it.
From the link Is it possible to access the SQLite-database of an Android-app on my phone? - Stack Overflow, the database is stored in "/data/data/your.applications.package/databases" This means I could let a 2nd app gain access if I set the same UID?

Did I miss some important fact and/or is my last assumption possible? (based on security perhaps
not the best way)
chihwahli is offline  
Reply With Quote
Old January 5th, 2012, 03:49 PM   #6 (permalink)
Premium Member
 
Join Date: Oct 2011
Location: Sydney, Australia
Posts: 193
 
Device(s): Galaxy Nexus GSM
Thanks: 2
Thanked 37 Times in 33 Posts
Default

Quote:
Originally Posted by chihwahli View Post
Application with the same user ID can access each other's data and, if desired, run in the same process.

How to implement: add this line to the androidManifest.xml: "android:sharedUserId="com.cwli"
Yes. But the name doesn't relate to Java packages. It'll effectively become a Linux user. So I would advised against dots in the name. Perhaps, cwliappsuite or cwli_app_suite.


Quote:
Originally Posted by chihwahli View Post
My thoughts: Thus when 2 apps have the same UID, they could run in the same process.
Yes.


Quote:
Originally Posted by chihwahli View Post
An Android app does not have permissions unless you set them in the Androidmanifest.xml file. An app can enforce their own permissions that are not found in manifest.permission.
The security in AndroidManifest.xml is really just about filesystem and process security by way of sharing of user IDs. Manifest.permission file is about access to the features of the Android platform. I can't see a way to extend this to something like "this app by developer X can access this other app's data by developer A".


Quote:
Originally Posted by chihwahli View Post
My thought: It's possible to create a file in Android filesystem and then give other apps permission to read it.
Possibly. I've not investigated this.

At the most basic, you can make a file or database world readable and/or world writable via the flags parameter of android.content.Context#openFileOutput(String, int) or android.content.Context#openOrCreateDatabase(Strin g, int, SQLiteDatabase.CursorFactory).

If you want finer-grain control, then this could be more difficult.

On Linux, if you wanted to 2 users to be able to shared files, you'd create a Unix group and added the 2 users to that group. You'd then set the group of those files to be this new Unix group and get the file group file permission to be group readable (and writeable, if appropriate).

Again on Linux, if the filesystem support ACLs you grant and revoke permissions to files by adding ACLs.

But you can't create groups on Android and you can't can users to groups on Android. And I don't know of a way to manipulate either traditional UNIX file permissions or ACLs via the Android Java API.


Quote:
Originally Posted by chihwahli View Post
From the link Is it possible to access the SQLite-database of an Android-app on my phone? - Stack Overflow, the database is stored in "/data/data/your.applications.package/databases" This means I could let a 2nd app gain access if I set the same UID?
Yes. But don't forget both apps need to signed with the same certificate.
jiminaus is offline  
Reply With Quote
Old January 5th, 2012, 06:07 PM   #7 (permalink)
New Member
 
Join Date: Jan 2012
Posts: 13
 
Device(s):
Thanks: 4
Thanked 0 Times in 0 Posts
Default

Thanks jiminaus for all the help so far! <thumbs up>

Going to try internal storage, the file will not be located in the SD, thus normally not reachable by other apps.

android - Read/write file to internal private storage - Stack Overflow

if(stuck || solved)
{
System.out.println("Will report back. <bow>");
}
chihwahli is offline  
Reply With Quote
Old January 8th, 2012, 02:53 PM   #8 (permalink)
New Member
 
Join Date: Jan 2012
Posts: 13
 
Device(s):
Thanks: 4
Thanked 0 Times in 0 Posts
Default

Tried internal storage. I have 2 sample apps:
1) Creates the internal storage, it's a variable. The same program opens this
variable and prints it's contains to logcat. (to verify it can be written /
read)
2) The 2nd app tries to read from this variable.

Remark: I did not use UID. (and every apk file gets signed with it's own UID)
Internal storage code is partly from: http://developer.android.com/guide/topics/data/datastorage.html#filesInternal

Question 1: How come I can access the variable?


I used openFileInput. Could it be that a file is created on the SD. That explains it why it could be accessed. I tried adb shell and went into a few directories, but could not find the file. Any help is appreciated!

Code:
package com.cwli;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.os.Bundle;

public class Internal_storage_create_readActivity extends Activity {
    private static final String IDS_LIST_FILE_NAME = null;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        try {
            createReadStorage();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    public void createReadStorage() throws IOException
    {
        String FILENAME = "hello_file";
        String string = "hello from internal..storage!";

        FileOutputStream fos = null;
        try {
            fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            fos.write(string.getBytes());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();            
        }
        
        try {
            fos.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
         InputStream instream = openFileInput(FILENAME);

            if (instream != null) {
                // prepare the file for reading
                InputStreamReader inputreader = new InputStreamReader(instream);
                BufferedReader buffreader = new BufferedReader(inputreader);

                String line;

                // read every line of the file into the line-variable, on line at the time
                while (( line = buffreader.readLine()) != null) {
                    System.out.println("--------------------------------");
                    System.out.println(line);
                    System.out.println("--------------------------------");
                }

              }

        
        
    }
}

Code:
package com.cwli;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import android.app.Activity;
import android.os.Bundle;

public class Internal_storage_readActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        try {
            lezen();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    public void lezen() throws IOException 
    {
    
    String FILENAME = "hello_file";
    InputStream instream = openFileInput(FILENAME);

    if (instream != null) 
    {
        // prepare the file for reading
        InputStreamReader inputreader = new InputStreamReader(instream);
        BufferedReader buffreader = new BufferedReader(inputreader);

        String line;

        // read every line of the file into the line-variable, on line at the time
        while (( line = buffreader.readLine()) != null) 
        {
            System.out.println("--------------------------------");
            System.out.println(line);
            System.out.println("--------------------------------");
        }

    
        
        }
    }
}
chihwahli is offline  
Last edited by chihwahli; January 8th, 2012 at 04:12 PM.
Reply With Quote
Old January 8th, 2012, 03:33 PM   #9 (permalink)
Premium Member
 
Join Date: Oct 2011
Location: Sydney, Australia
Posts: 193
 
Device(s): Galaxy Nexus GSM
Thanks: 2
Thanked 37 Times in 33 Posts
Default

Please edit the post above and surround your code with [CODE] ... [/CODE] tags so your code is readable.

The easiest way to do this is to highlight the code and then click the # button in the post editor's toolbar.
jiminaus is offline  
Reply With Quote
Old January 8th, 2012, 03:41 PM   #10 (permalink)
New Member
 
Join Date: Jan 2012
Posts: 13
 
Device(s):
Thanks: 4
Thanked 0 Times in 0 Posts
Default

The code tags are added.
chihwahli is offline  
Reply With Quote
Sponsors
Old January 9th, 2012, 01:37 AM   #11 (permalink)
Premium Member
 
Join Date: Oct 2011
Location: Sydney, Australia
Posts: 193
 
Device(s): Galaxy Nexus GSM
Thanks: 2
Thanked 37 Times in 33 Posts
Default

You did ask before somewhere where the file was stored. For me, on Android 4.0.1, the file was stored in /data/data/com.cwli/files/hello_file.

Quote:
Originally Posted by chihwahli View Post
How come I can access the variable? [...] Could it be that a file is created on the SD.
It can't be that came for me that the file is being created on an SD card, because my Galaxy Nexus doesn't have an SD card and all its file systems (including the "fake" /mnt/sdcard file system) support file permissions.

Yet when I run your code, it does work as you say.

However if I change the package in AndroidManifest.xml of the second app, the second app does fail with access denied.

That doesn't make sense to me. Even if two apps are in the same package, they shouldn't be able to access each others data.
jiminaus is offline  
Reply With Quote
Old January 9th, 2012, 03:30 AM   #12 (permalink)
New Member
 
Join Date: Jan 2012
Posts: 13
 
Device(s):
Thanks: 4
Thanked 0 Times in 0 Posts
Default

Thanks for verifying jiminaus. <thumbs up>.

I searched and found this link: Android package security - Stack Overflow

It seems I read wrongly or posts on internet about UID are not always right and contributed to my confusion. As you (jiminaus) have tested, if you change the Android packet name, you could not access the data of the other app, but if you changed both to the same packet name, you could.

Thus at this moment I guess that the same UID is given based on the same packet name. Packets with the same packet name in the AndroidManifest.xml , all get the same UID.....? Thus "all apps/apk files get a different UID, seems to be wrong perhaps...

Going to try something out....
chihwahli is offline  
Last edited by chihwahli; January 9th, 2012 at 04:32 AM.
Reply With Quote
Old January 9th, 2012, 04:48 AM   #13 (permalink)
New Member
 
Join Date: Jan 2012
Posts: 13
 
Device(s):
Thanks: 4
Thanked 0 Times in 0 Posts
Default

More info about the previous two apps.

Logcat from my create internal storage app:
I/ActivityManager( 91): Start proc com.cwli for activity com.cwli/.Internal_storage_create_readActivity: pid=643 uid=10044 gids={}
remark: The UID is 10044 and proces ID is 643

Logcat from my read app:
I/ActivityManager( 91): Start proc com.cwli for activity com.cwli/.Internal_storage_readActivity: pid=713 uid=10044 gids={}
W/NetworkManagementSocketTagger( 91): setKernelCountSet(10044, 1) failed with errno -2
I/System.out( 713): --------------------------------
I/System.out( 713): hello from internal..storage!
I/System.out( 713): --------------------------------
D/gralloc_goldfish( 713): Emulator without GPU emulation detected.
remark: As you can see the uid is 10044 with the proces ID 713

So this confirms that both apps are really running with the same UID, and thus can access eachothers data. Do notice that they have different process ID's..... As far as I know, program would not be able to access eachothers data, because they are a different process. Threads on the other hand can access eachothers data, because they share the same memory space.

Going to try:
- different package name and try to read data, check UID, if it's really different.
- What if UID is different and PID is the same. Any prog running as the same process, would be able to access eachothers data, or is Android different?
chihwahli is offline  
Last edited by chihwahli; January 9th, 2012 at 04:57 AM.
Reply With Quote
Old January 9th, 2012, 08:34 AM   #14 (permalink)
New Member
 
Join Date: Jan 2012
Posts: 13
 
Device(s):
Thanks: 4
Thanked 0 Times in 0 Posts
Default

3rd app just reads like the 2nd app, but changed the packet name from com.cwli to com.ccc. Now it looks in a different directory and the UID is different as you could see below:

I/ActivityManager( 77): Start proc com.ccc for activity com.ccc/.Internal_storage_read_different_packagenameActivi ty: pid=674 uid=10045 gids={}
W/NetworkManagementSocketTagger( 77): setKernelCountSet(10045, 1) failed with errno -2
D/dalvikvm( 233): GC_CONCURRENT freed 310K, 5% free 9494K/9927K, paused 3ms+5ms
W/System.err( 674): java.io.FileNotFoundException: /data/data/com.ccc/files/hello_file: open failed: ENOENT (No such file or directory)

Result: Indeed. cannot access the file. Because it's running in it's own memory space...

4th app:
- different package names
- used same sharedUserId: android:sharedUserId="com.bread"


Result: app did not install:

D/AndroidRuntime( 916): Shutting down VM
W/dalvikvm( 916): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
E/AndroidRuntime( 916): FATAL EXCEPTION: main
E/AndroidRuntime( 916): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.cwli/com.cwli.Internal_storage_create_UID1Activity}: java.lang.NullPointerException

Althought it's clear how to run apps under de same UID, the use of android:sharedUserId eludes me still. Why does it not install when I set sharedUserID?
chihwahli is offline  
Reply With Quote
Old January 9th, 2012, 03:10 PM   #15 (permalink)
Premium Member
 
Join Date: Oct 2011
Location: Sydney, Australia
Posts: 193
 
Device(s): Galaxy Nexus GSM
Thanks: 2
Thanked 37 Times in 33 Posts
Default

Process IDs (PIDs) are just a runtime number. Every process that runs get's its own ID. Every time you run an app, it will get a different PID.

But you're right that if your apps are running literally at the same time, and you see the same PID then yes they are running in the same Java virtual machine in the same memory space.

However, this is not a requirement to being able to access each other's files. The only requirement is that they have the same UID, so that the filesystem permission checks pass.


Do you also notice that you can't have multiple apps with the same package installed at the same time? I didn't notice it as first, but when I ran your second app, it replaced the first app. It looks from Android's perspective, that the second app was an some kind of upgrade or replacement to first app. This explains why the two apps got the same UID without sharedUserId.


Your third app couldn't access the file because the file didn't exist, not because access was denied. However, if you hardcoded the file path in your third app to the file created by your first app, I think your third app would be denied access.


For sharedUserId to work, both your first app and your fourth app need to have this same attribute with the same value. Don't use dots in the name. This name has nothing to do with Java packages, it's ultimately related to Linux usernames.

Remove your first app. Then install and run your first app after adding sharedUserId. Then install and run your fourth app after updating its sharedUserId to match the value of your first app's sharedUserId. Now your fourth app should run under the same UID as your first app be able to access each other's file.
jiminaus is offline  
Last edited by jiminaus; January 9th, 2012 at 03:14 PM. Reason: Fixed typos
Reply With Quote
Old January 9th, 2012, 05:38 PM   #16 (permalink)
New Member
 
Join Date: Jan 2012
Posts: 13
 
Device(s):
Thanks: 4
Thanked 0 Times in 0 Posts
Default

Hmm, Android SDK gives an error if I don't use the dots.

The logcat error:
): <manifest> specifies bad sharedUserId name "com_bread": must have at least one '.' separator
chihwahli is offline  
Reply With Quote
Old January 10th, 2012, 08:06 AM   #17 (permalink)
New Member
 
Join Date: Jan 2012
Posts: 13
 
Device(s):
Thanks: 4
Thanked 0 Times in 0 Posts
Default

Thank you jiminaus for pointing out a few things. I understand this better now. Thursday I will give a presentation with others about Android programming (SDK - NDK) Finishing the last few things and make presentation sheets. By the way: Wish you (and other readers a very good 2012 amen!
chihwahli is offline  
Reply With Quote
Reply

Bookmarks


Go Back   Android Forums > Android Development > Application Development > Developer 101 User CP
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




All times are GMT -5. The time now is 08:21 PM.
Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2012, vBulletin Solutions, Inc.
Custom vBulletin Skins by: Relivo