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

Commit e8577213 authored by Hai Zhang's avatar Hai Zhang
Browse files

Allow meta data requirement of a role to be optional.

This change allows a meta data requirement of a role to be
optional. This can be used in cases such as when a meta data must have
the value of false or be undeclared to qualify for a role.

Bug: 110557011
Test: manual
Change-Id: I1d6c7c94159be573659422119fbb618adeddb7af
parent c5891061
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.util.ArrayMap;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -35,7 +34,7 @@ import java.util.List;
public class RequiredActivity extends RequiredComponent {

    public RequiredActivity(@NonNull IntentFilterData intentFilterData,
            @Nullable String permission, @NonNull ArrayMap<String, Object> metaData) {
            @Nullable String permission, @NonNull List<RequiredMetaData> metaData) {
        super(intentFilterData, permission, metaData);
    }

+1 −2
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.util.ArrayMap;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -35,7 +34,7 @@ import java.util.List;
public class RequiredBroadcastReceiver extends RequiredComponent {

    public RequiredBroadcastReceiver(@NonNull IntentFilterData intentFilterData,
            @Nullable String permission, @NonNull ArrayMap<String, Object> metaData) {
            @Nullable String permission, @NonNull List<RequiredMetaData> metaData) {
        super(intentFilterData, permission, metaData);
    }

+14 −14
Original line number Diff line number Diff line
@@ -22,8 +22,8 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -37,6 +37,8 @@ import java.util.Objects;
 */
public abstract class RequiredComponent {

    private static final String LOG_TAG = RequiredComponent.class.getSimpleName();

    /**
     * The {@code Intent} or {@code IntentFilter} data to match the components.
     */
@@ -58,10 +60,11 @@ public abstract class RequiredComponent {
     * @see android.content.pm.PackageItemInfo#metaData
     */
    @NonNull
    private final ArrayMap<String, Object> mMetaData;
    private final List<RequiredMetaData> mMetaData;

    public RequiredComponent(@NonNull IntentFilterData intentFilterData,
            @Nullable String permission, @NonNull ArrayMap<String, Object> metaData) {
            @Nullable String permission,
            @NonNull List<RequiredMetaData> metaData) {
        mIntentFilterData = intentFilterData;
        mPermission = permission;
        mMetaData = metaData;
@@ -78,7 +81,7 @@ public abstract class RequiredComponent {
    }

    @NonNull
    public ArrayMap<String, Object> getMetaData() {
    public List<RequiredMetaData> getMetaData() {
        return mMetaData;
    }

@@ -144,23 +147,20 @@ public abstract class RequiredComponent {
            if (hasMetaData) {
                Bundle componentMetaData = getComponentMetaData(resolveInfo);
                if (componentMetaData == null) {
                    Log.w(LOG_TAG, "Component meta data is null");
                    continue;
                }
                boolean isMetaDataQualified = true;
                int metaDataSize = mMetaData.size();
                if (componentMetaData.size() < metaDataSize) {
                    continue;
                }
                boolean containsAllMetaData = true;
                for (int metaDataIndex = 0; metaDataIndex < metaDataSize; metaDataIndex++) {
                    String metaDataName = mMetaData.keyAt(metaDataIndex);
                    Object metaDataValue = mMetaData.valueAt(metaDataIndex);
                    Object componentMetaDataValue = componentMetaData.get(metaDataName);
                    if (!Objects.equals(componentMetaDataValue, metaDataValue)) {
                        containsAllMetaData = false;
                    RequiredMetaData metaData = mMetaData.get(metaDataIndex);

                    if (!metaData.isQualified(componentMetaData)) {
                        isMetaDataQualified = false;
                        break;
                    }
                }
                if (!containsAllMetaData) {
                if (!isMetaDataQualified) {
                    continue;
                }
            }
+1 −2
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.util.ArrayMap;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -35,7 +34,7 @@ import java.util.List;
public class RequiredContentProvider extends RequiredComponent {

    public RequiredContentProvider(@NonNull IntentFilterData intentFilterData,
            @Nullable String permission, @NonNull ArrayMap<String, Object> metaData) {
            @Nullable String permission, @NonNull List<RequiredMetaData> metaData) {
        super(intentFilterData, permission, metaData);
    }

+113 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.packageinstaller.role.model;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.Objects;

/**
 * Specifies the value of a meta data for an application to qualify for a {@link Role}.
 */
public class RequiredMetaData {

    /**
     * The name of this meta data.
     */
    @NonNull
    private final String mName;

    /**
     * The value of this meta data.
     */
    @Nullable
    private final Object mValue;

    /**
     * Whether this meta data is optional.
     *
     * @see #isQualified(Bundle)
     */
    private final boolean mOptional;

    public RequiredMetaData(@NonNull String name, @Nullable Object value, boolean optional) {
        mName = name;
        mValue = value;
        mOptional = optional;
    }

    @NonNull
    public String getName() {
        return mName;
    }

    @Nullable
    public Object getValue() {
        return mValue;
    }

    public boolean isOptional() {
        return mOptional;
    }

    /**
     * Check whether the meta data of a component is qualified.
     *
     * @param metaData the meta data of the component
     *
     * @return whether the meta data of the component is qualified
     */
    public boolean isQualified(@NonNull Bundle metaData) {
        if (metaData.containsKey(mName)) {
            Object metaDataValue = metaData.get(mName);
            return Objects.equals(metaDataValue, mValue);
        } else {
            return mOptional;
        }
    }

    @Override
    public String toString() {
        return "RequiredMetaData{"
                + "mName='" + mName + '\''
                + ", mValue=" + mValue
                + ", mOptional=" + mOptional
                + '}';
    }

    @Override
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if (object == null || getClass() != object.getClass()) {
            return false;
        }
        RequiredMetaData that = (RequiredMetaData) object;
        return mOptional == that.mOptional
                && Objects.equals(mName, that.mName)
                && Objects.equals(mValue, that.mValue);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mName, mValue, mOptional);
    }
}
Loading