Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1bdff913 authored by Adrian Roos's avatar Adrian Roos
Browse files

Decouple package manager lock and bitmap decoding

Also moves the actual reading and decoding of the
icon into the client process to avoid unnecessary
copies.

Bug: 18474438
Change-Id: I71623ef48c770d752593aa97d69517f6139cc947
parent 211f8b4d
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.os.Bundle;
import android.content.pm.UserInfo;
import android.content.RestrictionEntry;
import android.graphics.Bitmap;
import android.os.ParcelFileDescriptor;

/**
 *  {@hide}
@@ -32,7 +33,7 @@ interface IUserManager {
    boolean removeUser(int userHandle);
    void setUserName(int userHandle, String name);
    void setUserIcon(int userHandle, in Bitmap icon);
    Bitmap getUserIcon(int userHandle);
    ParcelFileDescriptor getUserIcon(int userHandle);
    List<UserInfo> getUsers(boolean excludeDying);
    List<UserInfo> getProfiles(int userHandle, boolean enabledOnly);
    UserInfo getProfileParent(int userHandle);
+14 −2
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.provider.Settings;
@@ -30,6 +31,7 @@ import android.view.WindowManager.LayoutParams;

import com.android.internal.R;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@@ -1083,11 +1085,21 @@ public class UserManager {
     */
    public Bitmap getUserIcon(int userHandle) {
        try {
            return mService.getUserIcon(userHandle);
            ParcelFileDescriptor fd = mService.getUserIcon(userHandle);
            if (fd != null) {
                try {
                    return BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor());
                } finally {
                    try {
                        fd.close();
                    } catch (IOException e) {
                    }
                }
            }
        } catch (RemoteException re) {
            Log.w(TAG, "Could not get the user icon ", re);
            return null;
        }
        return null;
    }

    /**
+17 −4
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
@@ -36,6 +35,7 @@ import android.os.FileUtils;
import android.os.Handler;
import android.os.IUserManager;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -111,6 +111,7 @@ public class UserManagerService extends IUserManager.Stub {
    private static final String USER_INFO_DIR = "system" + File.separator + "users";
    private static final String USER_LIST_FILENAME = "userlist.xml";
    private static final String USER_PHOTO_FILENAME = "photo.png";
    private static final String USER_PHOTO_FILENAME_TMP = USER_PHOTO_FILENAME + ".tmp";

    private static final String RESTRICTIONS_FILE_PREFIX = "res_";
    private static final String XML_SUFFIX = ".xml";
@@ -433,7 +434,8 @@ public class UserManagerService extends IUserManager.Stub {
    }

    @Override
    public Bitmap getUserIcon(int userId) {
    public ParcelFileDescriptor getUserIcon(int userId) {
        String iconPath;
        synchronized (mPackagesLock) {
            UserInfo info = mUsers.get(userId);
            if (info == null || info.partial) {
@@ -448,8 +450,16 @@ public class UserManagerService extends IUserManager.Stub {
            if (info.iconPath == null) {
                return null;
            }
            return BitmapFactory.decodeFile(info.iconPath);
            iconPath = info.iconPath;
        }

        try {
            return ParcelFileDescriptor.open(
                    new File(iconPath), ParcelFileDescriptor.MODE_READ_ONLY);
        } catch (FileNotFoundException e) {
            Log.e(LOG_TAG, "Couldn't find icon file", e);
        }
        return null;
    }

    public void makeInitialized(int userId) {
@@ -572,6 +582,7 @@ public class UserManagerService extends IUserManager.Stub {
        try {
            File dir = new File(mUsersDir, Integer.toString(info.id));
            File file = new File(dir, USER_PHOTO_FILENAME);
            File tmp = new File(dir, USER_PHOTO_FILENAME_TMP);
            if (!dir.exists()) {
                dir.mkdir();
                FileUtils.setPermissions(
@@ -580,7 +591,8 @@ public class UserManagerService extends IUserManager.Stub {
                        -1, -1);
            }
            FileOutputStream os;
            if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, os = new FileOutputStream(file))) {
            if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, os = new FileOutputStream(tmp))
                    && tmp.renameTo(file)) {
                info.iconPath = file.getAbsolutePath();
            }
            try {
@@ -588,6 +600,7 @@ public class UserManagerService extends IUserManager.Stub {
            } catch (IOException ioe) {
                // What the ... !
            }
            tmp.delete();
        } catch (FileNotFoundException e) {
            Slog.w(LOG_TAG, "Error setting photo for user ", e);
        }