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

Commit a7d4901d authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Grant DCS storage access; better OBB errors."

parents 12d5f7d2 0095a82b
Loading
Loading
Loading
Loading
+0 −75
Original line number Diff line number Diff line
/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.os.storage;

/**
 * Class that provides access to constants returned from StorageManager
 * and lower level StorageManagerService APIs.
 * 
 * @hide
 */
public class StorageResultCode
{
    /**
     * Operation succeeded.
     * @see android.os.storage.StorageManager
     */
    public static final int OperationSucceeded               =  0;

    /**
     * Operation failed: Internal error.
     * @see android.os.storage.StorageManager
     */
    public static final int OperationFailedInternalError     = -1;

    /**
     * Operation failed: Missing media.
     * @see android.os.storage.StorageManager
     */
    public static final int OperationFailedNoMedia           = -2;

    /**
     * Operation failed: Media is blank.
     * @see android.os.storage.StorageManager
     */
    public static final int OperationFailedMediaBlank        = -3;

    /**
     * Operation failed: Media is corrupt.
     * @see android.os.storage.StorageManager
     */
    public static final int OperationFailedMediaCorrupt      = -4;

    /**
     * Operation failed: Storage not mounted.
     * @see android.os.storage.StorageManager
     */
    public static final int OperationFailedStorageNotMounted  = -5;

    /**
     * Operation failed: Storage is mounted.
     * @see android.os.storage.StorageManager
     */
    public static final int OperationFailedStorageMounted     = -6;

    /**
     * Operation failed: Storage is busy.
     * @see android.os.storage.StorageManager
     */
    public static final int OperationFailedStorageBusy        = -7;

}
+0 −3
Original line number Diff line number Diff line
@@ -6,9 +6,6 @@
    <uses-permission android:name="android.permission.ASEC_DESTROY"/>
    <uses-permission android:name="android.permission.ASEC_MOUNT_UNMOUNT"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- Used to improve MeasureUtils performance on emulated storage, and to
         view storage for all users -->
    <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM" />
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />

+68 −85
Original line number Diff line number Diff line
@@ -16,6 +16,15 @@

package com.android.server;

import static android.os.storage.OnObbStateChangeListener.ERROR_ALREADY_MOUNTED;
import static android.os.storage.OnObbStateChangeListener.ERROR_COULD_NOT_MOUNT;
import static android.os.storage.OnObbStateChangeListener.ERROR_COULD_NOT_UNMOUNT;
import static android.os.storage.OnObbStateChangeListener.ERROR_INTERNAL;
import static android.os.storage.OnObbStateChangeListener.ERROR_NOT_MOUNTED;
import static android.os.storage.OnObbStateChangeListener.ERROR_PERMISSION_DENIED;
import static android.os.storage.OnObbStateChangeListener.MOUNTED;
import static android.os.storage.OnObbStateChangeListener.UNMOUNTED;

import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
import static com.android.internal.util.XmlUtils.readLongAttribute;
@@ -60,7 +69,6 @@ import android.os.FileUtils;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.IProgressListener;
import android.os.IStoraged;
import android.os.IVold;
import android.os.IVoldListener;
@@ -87,7 +95,6 @@ import android.os.storage.IStorageShutdownObserver;
import android.os.storage.OnObbStateChangeListener;
import android.os.storage.StorageManager;
import android.os.storage.StorageManagerInternal;
import android.os.storage.StorageResultCode;
import android.os.storage.StorageVolume;
import android.os.storage.VolumeInfo;
import android.os.storage.VolumeRecord;
@@ -137,8 +144,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.GeneralSecurityException;
import java.security.spec.KeySpec;
import java.util.ArrayList;
import java.util.Arrays;
@@ -3032,8 +3038,8 @@ class StorageManagerService extends IStorageManager.Stub
                        // If this is the only one pending we might
                        // have to bind to the service again.
                        if (!connectToService()) {
                            Slog.e(TAG, "Failed to bind to media container service");
                            action.handleError();
                            action.notifyObbStateChange(new ObbException(ERROR_INTERNAL,
                                    "Failed to bind to media container service"));
                            return;
                        }
                    }
@@ -3049,10 +3055,10 @@ class StorageManagerService extends IStorageManager.Stub
                    }
                    if (mContainerService == null) {
                        // Something seriously wrong. Bail out
                        Slog.e(TAG, "Cannot bind to media container service");
                        for (ObbAction action : mActions) {
                            // Indicate service bind error
                            action.handleError();
                            action.notifyObbStateChange(new ObbException(ERROR_INTERNAL,
                                    "Failed to bind to media container service"));
                        }
                        mActions.clear();
                    } else if (mActions.size() > 0) {
@@ -3074,10 +3080,10 @@ class StorageManagerService extends IStorageManager.Stub
                            disconnectService();
                        }
                        if (!connectToService()) {
                            Slog.e(TAG, "Failed to bind to media container service");
                            for (ObbAction action : mActions) {
                                // Indicate service bind error
                                action.handleError();
                                action.notifyObbStateChange(new ObbException(ERROR_INTERNAL,
                                        "Failed to bind to media container service"));
                            }
                            mActions.clear();
                        }
@@ -3167,6 +3173,20 @@ class StorageManagerService extends IStorageManager.Stub
        }
    }

    private static class ObbException extends Exception {
        public final int status;

        public ObbException(int status, String message) {
            super(message);
            this.status = status;
        }

        public ObbException(int status, Throwable cause) {
            super(cause.getMessage(), cause);
            this.status = status;
        }
    }

    abstract class ObbAction {
        private static final int MAX_RETRIES = 3;
        private int mRetries;
@@ -3183,46 +3203,44 @@ class StorageManagerService extends IStorageManager.Stub
                    Slog.i(TAG, "Starting to execute action: " + toString());
                mRetries++;
                if (mRetries > MAX_RETRIES) {
                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
                    mObbActionHandler.sendEmptyMessage(OBB_MCS_UNBIND);
                    handleError();
                    notifyObbStateChange(new ObbException(ERROR_INTERNAL,
                            "Failed to bind to media container service"));
                } else {
                    handleExecute();
                    if (DEBUG_OBB)
                        Slog.i(TAG, "Posting install MCS_UNBIND");
                    mObbActionHandler.sendEmptyMessage(OBB_MCS_UNBIND);
                }
            } catch (RemoteException e) {
                if (DEBUG_OBB)
                    Slog.i(TAG, "Posting install MCS_RECONNECT");
                mObbActionHandler.sendEmptyMessage(OBB_MCS_RECONNECT);
            } catch (Exception e) {
                if (DEBUG_OBB)
                    Slog.d(TAG, "Error handling OBB action", e);
                handleError();
            } catch (ObbException e) {
                notifyObbStateChange(e);
                mObbActionHandler.sendEmptyMessage(OBB_MCS_UNBIND);
            }
        }

        abstract void handleExecute() throws RemoteException, IOException;
        abstract void handleError();
        abstract void handleExecute() throws ObbException;

        protected ObbInfo getObbInfo() throws IOException {
            ObbInfo obbInfo;
        protected ObbInfo getObbInfo() throws ObbException {
            final ObbInfo obbInfo;
            try {
                obbInfo = mContainerService.getObbInfo(mObbState.canonicalPath);
            } catch (RemoteException e) {
                Slog.d(TAG, "Couldn't call DefaultContainerService to fetch OBB info for "
                        + mObbState.canonicalPath);
                obbInfo = null;
            }
            if (obbInfo == null) {
                throw new IOException("Couldn't read OBB file: " + mObbState.canonicalPath);
            } catch (Exception e) {
                throw new ObbException(ERROR_PERMISSION_DENIED, e);
            }
            if (obbInfo != null) {
                return obbInfo;
            } else {
                throw new ObbException(ERROR_INTERNAL,
                        "Missing OBB info for: " + mObbState.canonicalPath);
            }
        }

        protected void sendNewStatusOrIgnore(int status) {
        protected void notifyObbStateChange(ObbException e) {
            Slog.w(TAG, e);
            notifyObbStateChange(e.status);
        }

        protected void notifyObbStateChange(int status) {
            if (mObbState == null || mObbState.token == null) {
                return;
            }
@@ -3246,16 +3264,14 @@ class StorageManagerService extends IStorageManager.Stub
        }

        @Override
        public void handleExecute() throws IOException, RemoteException {
        public void handleExecute() throws ObbException {
            warnOnNotMounted();

            final ObbInfo obbInfo = getObbInfo();

            if (!isUidOwnerOfPackageOrSystem(obbInfo.packageName, mCallingUid)) {
                Slog.w(TAG, "Denied attempt to mount OBB " + obbInfo.filename
                        + " which is owned by " + obbInfo.packageName);
                sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
                return;
                throw new ObbException(ERROR_PERMISSION_DENIED, "Denied attempt to mount OBB "
                        + obbInfo.filename + " which is owned by " + obbInfo.packageName);
            }

            final boolean isMounted;
@@ -3263,9 +3279,8 @@ class StorageManagerService extends IStorageManager.Stub
                isMounted = mObbPathToStateMap.containsKey(mObbState.rawPath);
            }
            if (isMounted) {
                Slog.w(TAG, "Attempt to mount OBB which is already mounted: " + obbInfo.filename);
                sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
                return;
                throw new ObbException(ERROR_ALREADY_MOUNTED,
                        "Attempt to mount OBB which is already mounted: " + obbInfo.filename);
            }

            final String hashedKey;
@@ -3283,28 +3298,16 @@ class StorageManagerService extends IStorageManager.Stub
                    BigInteger bi = new BigInteger(key.getEncoded());
                    hashedKey = bi.toString(16);
                    binderKey = hashedKey;
                } catch (NoSuchAlgorithmException e) {
                    Slog.e(TAG, "Could not load PBKDF2 algorithm", e);
                    sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_INTERNAL);
                    return;
                } catch (InvalidKeySpecException e) {
                    Slog.e(TAG, "Invalid key spec when loading PBKDF2 algorithm", e);
                    sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_INTERNAL);
                    return;
                } catch (GeneralSecurityException e) {
                    throw new ObbException(ERROR_INTERNAL, e);
                }
            }

            int rc = StorageResultCode.OperationSucceeded;
            try {
                mObbState.volId = mVold.createObb(mObbState.canonicalPath, binderKey,
                        mObbState.ownerGid);
                mVold.mount(mObbState.volId, 0, -1);
            } catch (Exception e) {
                Slog.w(TAG, e);
                rc = StorageResultCode.OperationFailedInternalError;
            }

            if (rc == StorageResultCode.OperationSucceeded) {
                if (DEBUG_OBB)
                    Slog.d(TAG, "Successfully mounted OBB " + mObbState.canonicalPath);

@@ -3312,17 +3315,10 @@ class StorageManagerService extends IStorageManager.Stub
                    addObbStateLocked(mObbState);
                }

                sendNewStatusOrIgnore(OnObbStateChangeListener.MOUNTED);
            } else {
                Slog.e(TAG, "Couldn't mount OBB file: " + rc);

                sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_COULD_NOT_MOUNT);
            }
                notifyObbStateChange(MOUNTED);
            } catch (Exception e) {
                throw new ObbException(ERROR_COULD_NOT_MOUNT, e);
            }

        @Override
        public void handleError() {
            sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_INTERNAL);
        }

        @Override
@@ -3344,7 +3340,7 @@ class StorageManagerService extends IStorageManager.Stub
        }

        @Override
        public void handleExecute() throws IOException {
        public void handleExecute() throws ObbException {
            warnOnNotMounted();

            final ObbState existingState;
@@ -3353,42 +3349,29 @@ class StorageManagerService extends IStorageManager.Stub
            }

            if (existingState == null) {
                sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_NOT_MOUNTED);
                return;
                throw new ObbException(ERROR_NOT_MOUNTED, "Missing existingState");
            }

            if (existingState.ownerGid != mObbState.ownerGid) {
                Slog.w(TAG, "Permission denied attempting to unmount OBB " + existingState.rawPath
                        + " (owned by GID " + existingState.ownerGid + ")");
                sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
                notifyObbStateChange(new ObbException(ERROR_PERMISSION_DENIED,
                        "Permission denied to unmount OBB " + existingState.rawPath
                                + " (owned by GID " + existingState.ownerGid + ")"));
                return;
            }

            int rc = StorageResultCode.OperationSucceeded;
            try {
                mVold.unmount(mObbState.volId);
                mVold.destroyObb(mObbState.volId);
                mObbState.volId = null;
            } catch (Exception e) {
                Slog.w(TAG, e);
                rc = StorageResultCode.OperationFailedInternalError;
            }

            if (rc == StorageResultCode.OperationSucceeded) {
                synchronized (mObbMounts) {
                    removeObbStateLocked(existingState);
                }

                sendNewStatusOrIgnore(OnObbStateChangeListener.UNMOUNTED);
            } else {
                Slog.w(TAG, "Could not unmount OBB: " + existingState);
                sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_COULD_NOT_UNMOUNT);
            }
                notifyObbStateChange(UNMOUNTED);
            } catch (Exception e) {
                throw new ObbException(ERROR_COULD_NOT_UNMOUNT, e);
            }

        @Override
        public void handleError() {
            sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_INTERNAL);
        }

        @Override
+2 −2
Original line number Diff line number Diff line
@@ -553,9 +553,9 @@ public class PackageManagerService extends IPackageManager.Stub
    public static final String PLATFORM_PACKAGE_NAME = "android";
    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
    public static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
    public static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
            DEFAULT_CONTAINER_PACKAGE,
            "com.android.defcontainer.DefaultContainerService");
+13 −8
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package com.android.server.pm.permission;

import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
import static android.os.Process.FIRST_APPLICATION_UID;

import android.Manifest;
import android.annotation.NonNull;
@@ -28,15 +28,14 @@ import android.companion.CompanionDeviceManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageList;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageManagerInternal.PackagesProvider;
import android.content.pm.PackageManagerInternal.SyncAdapterPackagesProvider;
import android.content.pm.PackageParser;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.PackageManagerInternal.PackagesProvider;
import android.content.pm.PackageManagerInternal.SyncAdapterPackagesProvider;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Binder;
@@ -52,15 +51,17 @@ import android.provider.CalendarContract;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.provider.Telephony.Sms.Intents;
import android.telephony.TelephonyManager;
import android.security.Credentials;
import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
import android.util.Xml;

import com.android.internal.util.XmlUtils;
import com.android.server.LocalServices;
import com.android.server.pm.PackageManagerService;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -71,14 +72,11 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static android.os.Process.FIRST_APPLICATION_UID;

/**
 * This class is the policy for granting runtime permissions to
 * platform components and default handlers in the system such
@@ -433,6 +431,13 @@ public final class DefaultPermissionGrantPolicy {
            grantRuntimePermissions(storagePackage, STORAGE_PERMISSIONS, true, userId);
        }

        // Container service
        PackageParser.Package containerPackage = getSystemPackage(
                PackageManagerService.DEFAULT_CONTAINER_PACKAGE);
        if (containerPackage != null) {
            grantRuntimePermissions(containerPackage, STORAGE_PERMISSIONS, true, userId);
        }

        // CertInstaller
        Intent certInstallerIntent = new Intent(Credentials.INSTALL_ACTION);
        PackageParser.Package certInstallerPackage = getDefaultSystemHandlerActivityPackage(