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

Commit 05136c4c authored by Leonid Baraz's avatar Leonid Baraz Committed by Android (Google) Code Review
Browse files

Merge "Change resolution mechanism for setPermittedInputMethosd to SetIntersection" into main

parents 9b6681c8 58bfa485
Loading
Loading
Loading
Loading
+80 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.app.admin;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.Set;

/**
 * Class to identify a intersection resolution mechanism for {@code Set<String>} policies, it's
 * used to resolve the enforced policy when being set by multiple admins (see {@link
 * PolicyState#getResolutionMechanism()}).
 *
 * @hide
 */
public final class StringSetIntersection extends ResolutionMechanism<Set<String>> {

    /**
     * Intersection resolution for policies represented {@code Set<String>} which resolves as the
     * intersection of all sets.
     */
    @NonNull
    public static final StringSetIntersection STRING_SET_INTERSECTION = new StringSetIntersection();

    @Override
    public boolean equals(@Nullable Object o) {
        if (this == o) return true;
        return o != null && getClass() == o.getClass();
    }

    @Override
    public int hashCode() {
        return 0;
    }

    @Override
    public String toString() {
        return "StringSetIntersection {}";
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {}

    @NonNull
    public static final Parcelable.Creator<StringSetIntersection> CREATOR =
            new Parcelable.Creator<StringSetIntersection>() {
                @Override
                public StringSetIntersection createFromParcel(Parcel source) {
                    return new StringSetIntersection();
                }

                @Override
                public StringSetIntersection[] newArray(int size) {
                    return new StringSetIntersection[size];
                }
            };
}
+10 −0
Original line number Diff line number Diff line
@@ -412,3 +412,13 @@ flag {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
  name: "use_policy_intersection_for_permitted_input_methods"
  namespace: "enterprise"
  description: "When deciding on permitted input methods, use policy intersection instead of last recorded policy."
  bug: "340914586"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}
+4 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.app.admin.PackagePolicyKey;
import android.app.admin.PolicyKey;
import android.app.admin.PolicyValue;
import android.app.admin.UserRestrictionPolicyKey;
import android.app.admin.flags.Flags;
import android.content.ComponentName;
import android.content.Context;
import android.content.IntentFilter;
@@ -282,7 +283,9 @@ final class PolicyDefinition<V> {

    static PolicyDefinition<Set<String>> PERMITTED_INPUT_METHODS = new PolicyDefinition<>(
            new NoArgsPolicyKey(DevicePolicyIdentifiers.PERMITTED_INPUT_METHODS_POLICY),
            new MostRecent<>(),
            (Flags.usePolicyIntersectionForPermittedInputMethods()
                ? new StringSetIntersection()
                : new MostRecent<>()),
            POLICY_FLAG_LOCAL_ONLY_POLICY | POLICY_FLAG_INHERITABLE,
            PolicyEnforcerCallbacks::noOp,
            new PackageSetPolicySerializer());
+59 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.server.devicepolicy;

import android.annotation.NonNull;
import android.app.admin.PolicyValue;
import android.app.admin.PackageSetPolicyValue;

import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Objects;
import java.util.Set;

final class StringSetIntersection extends ResolutionMechanism<Set<String>> {

    @Override
    PolicyValue<Set<String>> resolve(
            @NonNull LinkedHashMap<EnforcingAdmin, PolicyValue<Set<String>>> adminPolicies) {
        Objects.requireNonNull(adminPolicies);
        Set<String> intersectionOfPolicies = null;
        for (PolicyValue<Set<String>> policy : adminPolicies.values()) {
            if (intersectionOfPolicies == null) {
                intersectionOfPolicies = new HashSet<>(policy.getValue());
            } else {
                intersectionOfPolicies.retainAll(policy.getValue());
            }
        }
        if (intersectionOfPolicies == null) {
            return null;
        }
        // Note that the resulting set below may be empty, but that's fine:
        // particular policy should decide what is the meaning of an empty set.
        return new PackageSetPolicyValue(intersectionOfPolicies);
    }

    @Override
    android.app.admin.StringSetIntersection getParcelableResolutionMechanism() {
        return new android.app.admin.StringSetIntersection();
    }

    @Override
    public String toString() {
        return "StringSetIntersection {}";
    }
}