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

Commit 59ee1eac authored by Kelvin Kwan's avatar Kelvin Kwan Committed by Android (Google) Code Review
Browse files

Merge "Load RootInfo with current user and store information in it."

parents 430829bd d8c64f5e
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import com.android.documentsui.base.Providers;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.Shared;
import com.android.documentsui.base.State;
import com.android.documentsui.base.UserId;
import com.android.documentsui.dirlist.AnimationView;
import com.android.documentsui.dirlist.AnimationView.AnimationType;
import com.android.documentsui.dirlist.FocusHandler;
@@ -591,7 +592,8 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA

    protected final void loadDeviceRoot() {
        mActivity.onRootPicked(
                mProviders.getRootOneshot(Providers.AUTHORITY_STORAGE, Providers.ROOT_ID_DEVICE));
                mProviders.getRootOneshot(UserId.DEFAULT_USER, Providers.AUTHORITY_STORAGE,
                        Providers.ROOT_ID_DEVICE));
    }

    protected final void loadHomeDir() {
+7 −4
Original line number Diff line number Diff line
@@ -16,17 +16,19 @@

package com.android.documentsui;

import androidx.annotation.Nullable;
import android.app.Activity;
import android.net.Uri;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Path;
import android.util.Log;

import androidx.annotation.Nullable;

import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.DocumentStack;
import com.android.documentsui.base.PairedTask;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.UserId;
import com.android.documentsui.roots.ProvidersAccess;

import java.util.List;
@@ -97,10 +99,11 @@ public class LoadDocStackTask extends PairedTask<Activity, Uri, DocumentStack> {
            throw new IllegalStateException("Provider doesn't provider root id.");
        }

        RootInfo root = mProviders.getRootOneshot(authority, path.getRootId());
        RootInfo root = mProviders.getRootOneshot(UserId.DEFAULT_USER, authority, path.getRootId());
        if (root == null) {
            throw new IllegalStateException("Failed to load root for authority: " + authority +
                    " and root ID: " + path.getRootId() + ".");
            throw new IllegalStateException(
                    "Failed to load root on user " + root.userId + " for authority: " + authority
                            + " and root ID: " + path.getRootId() + ".");
        }

        List<DocumentInfo> docs = mDocs.getDocuments(authority, path.getPath());
+2 −1
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import com.android.documentsui.base.DocumentInfo;
import com.android.documentsui.base.Providers;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.State;
import com.android.documentsui.base.UserId;
import com.android.documentsui.files.LauncherActivity;
import com.android.documentsui.picker.PickResult;
import com.android.documentsui.roots.ProvidersAccess;
@@ -340,7 +341,7 @@ public final class Metrics {
                context.getContentResolver(), Providers.AUTHORITY_STORAGE)) {
            final Path path = DocumentsContract.findDocumentPath(wrap(client), docUri);
            final ProvidersAccess providers = DocumentsApplication.getProvidersCache(context);
            final RootInfo root = providers.getRootOneshot(
            final RootInfo root = providers.getRootOneshot(UserId.DEFAULT_USER,
                    Providers.AUTHORITY_STORAGE, path.getRootId());
            isInternal = !root.supportsEject();
        } catch (FileNotFoundException | RemoteException | RuntimeException e) {
+16 −4
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
    // private static final int VERSION_INIT = 1; // Not used anymore
    private static final int VERSION_DROP_TYPE = 2;
    private static final int VERSION_SEARCH_TYPE = 3;
    private static final int VERSION_USER_ID = 4;

    // The values of these constants determine the sort order of various roots in the RootsFragment.
    @IntDef(flag = false, value = {
@@ -87,6 +88,7 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
    public static final int TYPE_USB = 10;
    public static final int TYPE_OTHER = 11;

    public UserId userId;
    public String authority;
    public String rootId;
    public int flags;
@@ -112,6 +114,7 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {

    @Override
    public void reset() {
        userId = UserId.UNSPECIFIED_USER;
        authority = null;
        rootId = null;
        flags = 0;
@@ -133,7 +136,12 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
    public void read(DataInputStream in) throws IOException {
        final int version = in.readInt();
        switch (version) {
            case VERSION_USER_ID:
                userId = UserId.read(in);
            case VERSION_SEARCH_TYPE:
                if (version < VERSION_USER_ID) {
                    userId = UserId.CURRENT_USER;
                }
                queryArgs = DurableUtils.readNullableString(in);
            case VERSION_DROP_TYPE:
                authority = DurableUtils.readNullableString(in);
@@ -154,7 +162,8 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {

    @Override
    public void write(DataOutputStream out) throws IOException {
        out.writeInt(VERSION_SEARCH_TYPE);
        out.writeInt(VERSION_USER_ID);
        UserId.write(out, userId);
        DurableUtils.writeNullableString(out, queryArgs);
        DurableUtils.writeNullableString(out, authority);
        DurableUtils.writeNullableString(out, rootId);
@@ -191,8 +200,9 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
        }
    };

    public static RootInfo fromRootsCursor(String authority, Cursor cursor) {
    public static RootInfo fromRootsCursor(UserId userId, String authority, Cursor cursor) {
        final RootInfo root = new RootInfo();
        root.userId = userId;
        root.authority = authority;
        root.rootId = getCursorString(cursor, Root.COLUMN_ROOT_ID);
        root.flags = getCursorInt(cursor, Root.COLUMN_FLAGS);
@@ -430,7 +440,8 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {

        if (o instanceof RootInfo) {
            RootInfo other = (RootInfo) o;
            return Objects.equals(authority, other.authority)
            return Objects.equals(userId, other.userId)
                    && Objects.equals(authority, other.authority)
                    && Objects.equals(rootId, other.rootId);
        }

@@ -439,7 +450,7 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {

    @Override
    public int hashCode() {
        return Objects.hash(authority, rootId);
        return Objects.hash(userId, authority, rootId);
    }

    @Override
@@ -461,6 +472,7 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> {
    @Override
    public String toString() {
        return "Root{"
                + "userId=" + userId
                + "authority=" + authority
                + ", rootId=" + rootId
                + ", title=" + title
+151 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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 com.android.documentsui.base;

import static androidx.core.util.Preconditions.checkNotNull;

import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Process;
import android.os.UserHandle;

import androidx.annotation.VisibleForTesting;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ProtocolException;
import java.util.Objects;
/**
 * Representation of a {@link UserHandle}.
 */
public final class UserId {

    // A unspecified user is used as when the user's value is uninitialized. e.g. rootInfo.reset()
    public static UserId UNSPECIFIED_USER = UserId.of(UserHandle.of(-1000));
    // A current user represents the user of the app's process. It is mainly used for comparison.
    public static UserId CURRENT_USER = UserId.of(Process.myUserHandle());
    // A default user represents the user of the app's process. It is mainly used for operation
    // which supports only the current user only.
    public static UserId DEFAULT_USER = CURRENT_USER;

    private static final int VERSION_INIT = 1;

    private final UserHandle mUserHandle;

    private UserId(UserHandle userHandle) {
        checkNotNull(userHandle);
        mUserHandle = userHandle;
    }

    /**
     * Returns a {@link UserId} for a given {@link UserHandle}.
     */
    @VisibleForTesting
    static UserId of(UserHandle userHandle) {
        return new UserId(userHandle);
    }

    /**
     * Returns the given context if the user is the current user or unspecified. Otherwise, returns
     * an "android" package context as the user.
     *
     * @throws IllegalStateException if android package of the other user does not exist
     */
    @VisibleForTesting
    Context asContext(Context context) {
        if (CURRENT_USER.equals(this) || isUnspecified()) {
            return context;
        }
        try {
            return context.createPackageContextAsUser("android", /* flags= */ 0, mUserHandle);
        } catch (PackageManager.NameNotFoundException e) {
            throw new IllegalStateException("android package not found.");
        }
    }

    /**
     * Return a package manager instance of this user.
     */
    public PackageManager getPackageManager(Context context) {
        return asContext(context).getPackageManager();
    }

    /**
     * Return a content resolver instance of this user.
     */
    public ContentResolver getContentResolver(Context context) {
        return asContext(context).getContentResolver();
    }

    private boolean isUnspecified() {
        return UNSPECIFIED_USER.equals(this);
    }

    @Override
    public String toString() {
        return "UserId{"
                + (isUnspecified() ? "UNSPECIFIED" : mUserHandle.getIdentifier())
                + "}";
    }

    @Override
    public boolean equals(Object o) {
        if (o == null) {
            return false;
        }

        if (this == o) {
            return true;
        }

        if (o instanceof UserId) {
            UserId other = (UserId) o;
            return Objects.equals(mUserHandle, other.mUserHandle);
        }

        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mUserHandle);
    }

    /**
     * Reads a {@link UserId} from an input stream.
     */
    public static UserId read(DataInputStream in) throws IOException {
        final int version = in.readInt();
        switch (version) {
            case VERSION_INIT:
                int userId = in.readInt();
                return UserId.of(UserHandle.of(userId));
            default:
                throw new ProtocolException("Unknown version " + version);
        }
    }

    /**
     * Writes a {@link UserId} to an output stream.
     */
    public static void write(DataOutputStream out, UserId userId) throws IOException {
        out.writeInt(VERSION_INIT);
        out.writeInt(userId.mUserHandle.getIdentifier());
    }
}
Loading