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

Commit d6752c92 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Example system service test under Ravenwood.

This change demonstrates a moderately complex test of a specific
system service, in this case `UriGrantsManagerService`.

Bug: 292141694
Test: atest FrameworksServicesTestsRavenwood FrameworksServicesTests
Change-Id: Ia16632f2c9a1e24deb9c1320fdbb1c099e3d74c3
parent 7178e2b9
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ import java.util.Objects;
 * developer guide.</p>
 * </div>
 */
@android.ravenwood.annotation.RavenwoodKeepPartialClass
public abstract class ContentProvider implements ContentInterface, ComponentCallbacks2 {

    private static final String TAG = "ContentProvider";
@@ -2781,6 +2782,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
    }

    /** @hide */
    @android.ravenwood.annotation.RavenwoodKeep
    private Uri maybeGetUriWithoutUserId(Uri uri) {
        if (mSingleUser) {
            return uri;
@@ -2789,6 +2791,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
    }

    /** @hide */
    @android.ravenwood.annotation.RavenwoodKeep
    public static int getUserIdFromAuthority(String auth, int defaultUserId) {
        if (auth == null) return defaultUserId;
        int end = auth.lastIndexOf('@');
@@ -2803,17 +2806,20 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
    }

    /** @hide */
    @android.ravenwood.annotation.RavenwoodKeep
    public static int getUserIdFromAuthority(String auth) {
        return getUserIdFromAuthority(auth, UserHandle.USER_CURRENT);
    }

    /** @hide */
    @android.ravenwood.annotation.RavenwoodKeep
    public static int getUserIdFromUri(Uri uri, int defaultUserId) {
        if (uri == null) return defaultUserId;
        return getUserIdFromAuthority(uri.getAuthority(), defaultUserId);
    }

    /** @hide */
    @android.ravenwood.annotation.RavenwoodKeep
    public static int getUserIdFromUri(Uri uri) {
        return getUserIdFromUri(uri, UserHandle.USER_CURRENT);
    }
@@ -2824,6 +2830,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
     * @hide
     */
    @TestApi
    @android.ravenwood.annotation.RavenwoodKeep
    public @NonNull static UserHandle getUserHandleFromUri(@NonNull Uri uri) {
        return UserHandle.of(getUserIdFromUri(uri, Process.myUserHandle().getIdentifier()));
    }
@@ -2834,6 +2841,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
     * If there is no userId in the authority, it symply returns the argument
     * @hide
     */
    @android.ravenwood.annotation.RavenwoodKeep
    public static String getAuthorityWithoutUserId(String auth) {
        if (auth == null) return null;
        int end = auth.lastIndexOf('@');
@@ -2841,6 +2849,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
    }

    /** @hide */
    @android.ravenwood.annotation.RavenwoodKeep
    public static Uri getUriWithoutUserId(Uri uri) {
        if (uri == null) return null;
        Uri.Builder builder = uri.buildUpon();
@@ -2849,6 +2858,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
    }

    /** @hide */
    @android.ravenwood.annotation.RavenwoodKeep
    public static boolean uriHasUserId(Uri uri) {
        if (uri == null) return false;
        return !TextUtils.isEmpty(uri.getUserInfo());
@@ -2872,6 +2882,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
     */
    @NonNull
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    @android.ravenwood.annotation.RavenwoodKeep
    public static Uri createContentUriForUser(
            @NonNull Uri contentUri, @NonNull UserHandle userHandle) {
        if (!ContentResolver.SCHEME_CONTENT.equals(contentUri.getScheme())) {
@@ -2898,6 +2909,7 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall

    /** @hide */
    @UnsupportedAppUsage
    @android.ravenwood.annotation.RavenwoodKeep
    public static Uri maybeAddUserId(Uri uri, int userId) {
        if (uri == null) return null;
        if (userId != UserHandle.USER_CURRENT
+2 −0
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@ android.graphics.PointF
android.graphics.Rect
android.graphics.RectF

android.content.ContentProvider

com.android.server.LocalServices

com.android.internal.os.SomeArgs
+28 −7
Original line number Diff line number Diff line
@@ -146,17 +146,31 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub implements
            mGrantedUriPermissions = new SparseArray<>();

    private UriGrantsManagerService() {
        this(SystemServiceManager.ensureSystemDir());
        this(SystemServiceManager.ensureSystemDir(), "uri-grants");
    }

    private UriGrantsManagerService(File systemDir) {
    private UriGrantsManagerService(File systemDir, String commitTag) {
        mH = new H(IoThread.get().getLooper());
        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"), "uri-grants");
        final File file = new File(systemDir, "urigrants.xml");
        mGrantFile = (commitTag != null) ? new AtomicFile(file, commitTag) : new AtomicFile(file);
    }

    @VisibleForTesting
    static UriGrantsManagerService createForTest(File systemDir) {
        final UriGrantsManagerService service = new UriGrantsManagerService(systemDir);
        final UriGrantsManagerService service = new UriGrantsManagerService(systemDir, null) {
            @VisibleForTesting
            protected int checkUidPermission(String permission, int uid) {
                // Tests have no permission granted
                return PackageManager.PERMISSION_DENIED;
            }

            @VisibleForTesting
            protected int checkComponentPermission(String permission, int uid, int owningUid,
                    boolean exported) {
                // Tests have no permission granted
                return PackageManager.PERMISSION_DENIED;
            }
        };
        service.mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
        service.mPmInternal = LocalServices.getService(PackageManagerInternal.class);
        return service;
@@ -202,7 +216,8 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub implements
        }
    }

    private int checkUidPermission(String permission, int uid) {
    @VisibleForTesting
    protected int checkUidPermission(String permission, int uid) {
        try {
            return AppGlobals.getPackageManager().checkUidPermission(permission, uid);
        } catch (RemoteException e) {
@@ -210,6 +225,12 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub implements
        }
    }

    @VisibleForTesting
    protected int checkComponentPermission(String permission, int uid, int owningUid,
            boolean exported) {
        return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported);
    }

    /**
     * Grant uri permissions to the specified app.
     *
@@ -916,7 +937,7 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub implements
            ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
        if (DEBUG) Slog.v(TAG, "checkHoldingPermissions: uri=" + grantUri + " uid=" + uid);
        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
            if (checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
                    != PERMISSION_GRANTED) {
                return false;
            }
@@ -1340,7 +1361,7 @@ public class UriGrantsManagerService extends IUriGrantsManager.Stub implements
        if (uid == Process.SYSTEM_UID || uid == Process.ROOT_UID) {
            return true;
        }
        return ActivityManager.checkComponentPermission(
        return checkComponentPermission(
                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                    uid, /* owningUid = */-1, /* exported = */ true)
                    == PackageManager.PERMISSION_GRANTED;
+18 −0
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ android_test {
        "coretests-aidl",
        "securebox",
        "flag-junit",
        "ravenwood-junit",
    ],

    libs: [
@@ -140,6 +141,23 @@ android_test {
    resource_zips: [":FrameworksServicesTests_apks_as_resources"],
}

android_ravenwood_test {
    name: "FrameworksServicesTestsRavenwood",
    libs: [
        "android.test.mock",
    ],
    static_libs: [
        "androidx.annotation_annotation",
        "androidx.test.rules",
        "mockito_ravenwood",
        "services.core",
    ],
    srcs: [
        "src/com/android/server/uri/**/*.java",
    ],
    auto_gen_config: true,
}

java_library {
    name: "servicestests-core-utils",
    srcs: [
+6 −1
Original line number Diff line number Diff line
@@ -57,17 +57,22 @@ import android.content.pm.ProviderInfo;
import android.net.Uri;
import android.os.Process;
import android.os.UserHandle;
import android.platform.test.ravenwood.RavenwoodRule;
import android.util.ArraySet;

import androidx.test.InstrumentationRegistry;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import java.util.Arrays;
import java.util.Set;

public class UriGrantsManagerServiceTest {
    @Rule
    public final RavenwoodRule mRavenwood = new RavenwoodRule();

    private UriGrantsMockContext mContext;
    private UriGrantsManagerInternal mService;

@@ -79,7 +84,7 @@ public class UriGrantsManagerServiceTest {

    @Before
    public void setUp() throws Exception {
        mContext = new UriGrantsMockContext(InstrumentationRegistry.getContext());
        mContext = new UriGrantsMockContext();
        mService = UriGrantsManagerService.createForTest(mContext.getFilesDir()).getLocalService();
    }

Loading