script-astra/Android/Sdk/sources/android-35/android/app/admin/PreferentialNetworkServiceConfig.java
localadmin 4380f00a78 init
2025-01-20 18:15:20 +03:00

572 lines
24 KiB
Java

/*
* Copyright (C) 2022 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 static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.END_TAG;
import static org.xmlpull.v1.XmlPullParser.TEXT;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.IndentingPrintWriter;
import android.util.Log;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Network configuration to be set for the user profile
* {@see DevicePolicyManager#setPreferentialNetworkServiceConfigs}.
*/
public final class PreferentialNetworkServiceConfig implements Parcelable {
final boolean mIsEnabled;
final int mNetworkId;
final boolean mAllowFallbackToDefaultConnection;
final boolean mShouldBlockNonMatchingNetworks;
final int[] mIncludedUids;
final int[] mExcludedUids;
private static final String LOG_TAG = "PreferentialNetworkServiceConfig";
private static final String TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG =
"preferential_network_service_config";
private static final String TAG_CONFIG_ENABLED =
"preferential_network_service_config_enabled";
private static final String TAG_UID = "uid";
private static final String TAG_NETWORK_ID =
"preferential_network_service_network_id";
private static final String TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION =
"allow_fallback_to_default_connection";
private static final String TAG_BLOCK_NON_MATCHING_NETWORKS =
"block_non_matching_networks";
private static final String TAG_INCLUDED_UIDS = "included_uids";
private static final String TAG_EXCLUDED_UIDS = "excluded_uids";
private static final String ATTR_VALUE = "value";
/** @hide */
public static final PreferentialNetworkServiceConfig DEFAULT =
(new PreferentialNetworkServiceConfig.Builder()).build();
/**
* Preferential network identifier 1.
*/
public static final int PREFERENTIAL_NETWORK_ID_1 = 1;
/**
* Preferential network identifier 2.
*/
public static final int PREFERENTIAL_NETWORK_ID_2 = 2;
/**
* Preferential network identifier 3.
*/
public static final int PREFERENTIAL_NETWORK_ID_3 = 3;
/**
* Preferential network identifier 4.
*/
public static final int PREFERENTIAL_NETWORK_ID_4 = 4;
/**
* Preferential network identifier 5.
*/
public static final int PREFERENTIAL_NETWORK_ID_5 = 5;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = { "PREFERENTIAL_NETWORK_ID_" }, value = {
PREFERENTIAL_NETWORK_ID_1,
PREFERENTIAL_NETWORK_ID_2,
PREFERENTIAL_NETWORK_ID_3,
PREFERENTIAL_NETWORK_ID_4,
PREFERENTIAL_NETWORK_ID_5,
})
public @interface PreferentialNetworkPreferenceId {
}
private PreferentialNetworkServiceConfig(boolean isEnabled,
boolean allowFallbackToDefaultConnection, boolean shouldBlockNonMatchingNetworks,
int[] includedUids,
int[] excludedUids, @PreferentialNetworkPreferenceId int networkId) {
mIsEnabled = isEnabled;
mAllowFallbackToDefaultConnection = allowFallbackToDefaultConnection;
mShouldBlockNonMatchingNetworks = shouldBlockNonMatchingNetworks;
mIncludedUids = includedUids;
mExcludedUids = excludedUids;
mNetworkId = networkId;
}
private PreferentialNetworkServiceConfig(Parcel in) {
mIsEnabled = in.readBoolean();
mAllowFallbackToDefaultConnection = in.readBoolean();
mShouldBlockNonMatchingNetworks = in.readBoolean();
mNetworkId = in.readInt();
mIncludedUids = in.createIntArray();
mExcludedUids = in.createIntArray();
}
/**
* Is the preferential network enabled.
* @return true if enabled else false
*/
public boolean isEnabled() {
return mIsEnabled;
}
/**
* Whether fallback to the device-wide default network is allowed.
*
* This boolean configures whether the default connection (e.g. general cell network or wifi)
* should be used if no preferential network service connection is available. If true, the
* default connection will be used when no preferential service is available. If false, the
* UIDs subject to this configuration will have no default network.
* Note that while this boolean determines whether the UIDs subject to this configuration have
* a default network in the absence of a preferential service, apps can still explicitly decide
* to use another network than their default network by requesting them from the system. This
* boolean does not determine whether the UIDs are blocked from using such other networks.
* See {@link #shouldBlockNonMatchingNetworks()} for that configuration.
*
* @return true if fallback is allowed, else false.
*/
public boolean isFallbackToDefaultConnectionAllowed() {
return mAllowFallbackToDefaultConnection;
}
/**
* Whether to block UIDs from using other networks than the preferential service.
*
* Apps can inspect the list of available networks on the device and choose to use multiple
* of them concurrently for performance, privacy or other reasons.
* This boolean configures whether the concerned UIDs should be blocked from using
* networks that do not match the configured preferential network service even if these
* networks are otherwise open to all apps.
*
* @return true if UIDs should be blocked from using the other networks, else false.
*/
public boolean shouldBlockNonMatchingNetworks() {
return mShouldBlockNonMatchingNetworks;
}
/**
* Get the array of uids that are applicable for the profile preference.
*
* {@see #getExcludedUids()}
* Included UIDs and Excluded UIDs can't both be non-empty.
* if both are empty, it means this request applies to all uids in the user profile.
* if included is not empty, then only included UIDs are applied.
* if excluded is not empty, then it is all uids in the user profile except these UIDs.
* @return Array of uids applicable for the profile preference.
* Empty array would mean that this request applies to all uids in the profile.
*/
public @NonNull int[] getIncludedUids() {
return mIncludedUids;
}
/**
* Get the array of uids that are excluded for the profile preference.
*
* {@see #getIncludedUids()}
* Included UIDs and Excluded UIDs can't both be non-empty.
* if both are empty, it means this request applies to all uids in the user profile.
* if included is not empty, then only included UIDs are applied.
* if excluded is not empty, then it is all uids in the user profile except these UIDs.
* @return Array of uids that are excluded for the profile preference.
* Empty array would mean that this request applies to all uids in the profile.
*/
public @NonNull int[] getExcludedUids() {
return mExcludedUids;
}
/**
* @return preference enterprise identifier.
* preference identifier is applicable only if preference network service is enabled
*
*/
public @PreferentialNetworkPreferenceId int getNetworkId() {
return mNetworkId;
}
@Override
public String toString() {
return "PreferentialNetworkServiceConfig{"
+ "mIsEnabled=" + isEnabled()
+ "mAllowFallbackToDefaultConnection=" + isFallbackToDefaultConnectionAllowed()
+ "mBlockNonMatchingNetworks=" + shouldBlockNonMatchingNetworks()
+ "mIncludedUids=" + Arrays.toString(mIncludedUids)
+ "mExcludedUids=" + Arrays.toString(mExcludedUids)
+ "mNetworkId=" + mNetworkId
+ '}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final PreferentialNetworkServiceConfig that = (PreferentialNetworkServiceConfig) o;
return mIsEnabled == that.mIsEnabled
&& mAllowFallbackToDefaultConnection == that.mAllowFallbackToDefaultConnection
&& mShouldBlockNonMatchingNetworks == that.mShouldBlockNonMatchingNetworks
&& mNetworkId == that.mNetworkId
&& Arrays.equals(mIncludedUids, that.mIncludedUids)
&& Arrays.equals(mExcludedUids, that.mExcludedUids);
}
@Override
public int hashCode() {
return Objects.hash(mIsEnabled, mAllowFallbackToDefaultConnection,
mShouldBlockNonMatchingNetworks, Arrays.hashCode(mIncludedUids),
Arrays.hashCode(mExcludedUids), mNetworkId);
}
/**
* Builder used to create {@link PreferentialNetworkServiceConfig} objects.
* Specify the preferred Network preference
*/
public static final class Builder {
boolean mIsEnabled = false;
int mNetworkId = 0;
boolean mAllowFallbackToDefaultConnection = true;
boolean mShouldBlockNonMatchingNetworks = false;
int[] mIncludedUids = new int[0];
int[] mExcludedUids = new int[0];
/**
* Constructs an empty Builder with preferential network disabled by default.
*/
public Builder() {}
/**
* Set the preferential network service enabled state.
* Default value is false.
* @param isEnabled the desired network preference to use, true to enable else false
* @return The builder to facilitate chaining.
*/
@NonNull
public PreferentialNetworkServiceConfig.Builder setEnabled(boolean isEnabled) {
mIsEnabled = isEnabled;
return this;
}
/**
* Set whether fallback to the device-wide default network is allowed.
*
* This boolean configures whether the default connection (e.g. general cell network or
* wifi) should be used if no preferential network service connection is available. If true,
* the default connection will be used when no preferential service is available. If false,
* the UIDs subject to this configuration will have no default network.
* Note that while this boolean determines whether the UIDs subject to this configuration
* have a default network in the absence of a preferential service, apps can still
* explicitly decide to use another network than their default network by requesting them
* from the system. This boolean does not determine whether the UIDs are blocked from using
* such other networks.
* Use {@link #setShouldBlockNonMatchingNetworks(boolean)} to specify this.
*
* The default value is true.
*
* @param allowFallbackToDefaultConnection true if fallback is allowed else false
* @return The builder to facilitate chaining.
*/
@NonNull
@SuppressLint("MissingGetterMatchingBuilder")
public PreferentialNetworkServiceConfig.Builder setFallbackToDefaultConnectionAllowed(
boolean allowFallbackToDefaultConnection) {
mAllowFallbackToDefaultConnection = allowFallbackToDefaultConnection;
return this;
}
/**
* Set whether to block UIDs from using other networks than the preferential service.
*
* Apps can inspect the list of available networks on the device and choose to use multiple
* of them concurrently for performance, privacy or other reasons.
* This boolean configures whether the concerned UIDs should be blocked from using
* networks that do not match the configured preferential network service even if these
* networks are otherwise open to all apps.
*
* The default value is false. This value can only be set to {@code true} if
* {@link #setFallbackToDefaultConnectionAllowed(boolean)} is set to {@code false}, because
* allowing fallback but blocking it does not make sense. Failure to comply with this
* constraint will throw when building the object.
*
* @param blockNonMatchingNetworks true if UIDs should be blocked from using non-matching
* networks.
* @return The builder to facilitate chaining.
*/
@NonNull
public PreferentialNetworkServiceConfig.Builder setShouldBlockNonMatchingNetworks(
boolean blockNonMatchingNetworks) {
mShouldBlockNonMatchingNetworks = blockNonMatchingNetworks;
return this;
}
/**
* Set the array of uids whose network access will go through this preferential
* network service.
* {@see #setExcludedUids(int[])}
* Included UIDs and Excluded UIDs can't both be non-empty.
* if both are empty, it means this request applies to all uids in the user profile.
* if included is not empty, then only included UIDs are applied.
* if excluded is not empty, then it is all uids in the user profile except these UIDs.
* @param uids array of included uids
* @return The builder to facilitate chaining.
*/
@NonNull
public PreferentialNetworkServiceConfig.Builder setIncludedUids(
@NonNull int[] uids) {
Objects.requireNonNull(uids);
mIncludedUids = uids;
return this;
}
/**
* Set the array of uids who are not allowed through this preferential
* network service.
* {@see #setIncludedUids(int[])}
* Included UIDs and Excluded UIDs can't both be non-empty.
* if both are empty, it means this request applies to all uids in the user profile.
* if included is not empty, then only included UIDs are applied.
* if excluded is not empty, then it is all uids in the user profile except these UIDs.
* @param uids array of excluded uids
* @return The builder to facilitate chaining.
*/
@NonNull
public PreferentialNetworkServiceConfig.Builder setExcludedUids(
@NonNull int[] uids) {
Objects.requireNonNull(uids);
mExcludedUids = uids;
return this;
}
/**
* Returns an instance of {@link PreferentialNetworkServiceConfig} created from the
* fields set on this builder.
*/
@NonNull
public PreferentialNetworkServiceConfig build() {
if (mIncludedUids.length > 0 && mExcludedUids.length > 0) {
throw new IllegalStateException("Both includedUids and excludedUids "
+ "cannot be nonempty");
}
if (mShouldBlockNonMatchingNetworks && mAllowFallbackToDefaultConnection) {
throw new IllegalStateException("A config cannot both allow fallback and "
+ "block non-matching networks");
}
return new PreferentialNetworkServiceConfig(mIsEnabled,
mAllowFallbackToDefaultConnection, mShouldBlockNonMatchingNetworks,
mIncludedUids, mExcludedUids, mNetworkId);
}
/**
* Set the preferential network identifier.
* preference identifier is applicable only if preferential network service is enabled.
* @param preferenceId preference Id
* @return The builder to facilitate chaining.
*/
@NonNull
public PreferentialNetworkServiceConfig.Builder setNetworkId(
@PreferentialNetworkPreferenceId int preferenceId) {
if ((preferenceId < PREFERENTIAL_NETWORK_ID_1)
|| (preferenceId > PREFERENTIAL_NETWORK_ID_5)) {
throw new IllegalArgumentException("Invalid preference identifier");
}
mNetworkId = preferenceId;
return this;
}
}
@Override
public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
dest.writeBoolean(mIsEnabled);
dest.writeBoolean(mAllowFallbackToDefaultConnection);
dest.writeBoolean(mShouldBlockNonMatchingNetworks);
dest.writeInt(mNetworkId);
dest.writeIntArray(mIncludedUids);
dest.writeIntArray(mExcludedUids);
}
private void writeAttributeValueToXml(TypedXmlSerializer out, String tag, int value)
throws IOException {
out.startTag(null, tag);
out.attributeInt(null, ATTR_VALUE, value);
out.endTag(null, tag);
}
private void writeAttributeValueToXml(TypedXmlSerializer out, String tag, boolean value)
throws IOException {
out.startTag(null, tag);
out.attributeBoolean(null, ATTR_VALUE, value);
out.endTag(null, tag);
}
private void writeAttributeValuesToXml(TypedXmlSerializer out, String outerTag, String innerTag,
@NonNull Collection<String> values) throws IOException {
out.startTag(null, outerTag);
for (String value : values) {
out.startTag(null, innerTag);
out.attribute(null, ATTR_VALUE, value);
out.endTag(null, innerTag);
}
out.endTag(null, outerTag);
}
private static void readAttributeValues(
TypedXmlPullParser parser, String tag, Collection<String> result)
throws XmlPullParserException, IOException {
result.clear();
int outerDepthDAM = parser.getDepth();
int typeDAM;
while ((typeDAM = parser.next()) != END_DOCUMENT
&& (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
if (typeDAM == END_TAG || typeDAM == TEXT) {
continue;
}
String tagDAM = parser.getName();
if (tag.equals(tagDAM)) {
result.add(parser.getAttributeValue(null, ATTR_VALUE));
} else {
Log.e(LOG_TAG, "Expected tag " + tag + " but found " + tagDAM);
}
}
}
private List<String> intArrayToStringList(int[] array) {
return Arrays.stream(array).mapToObj(String::valueOf).collect(Collectors.toList());
}
private static int[] readStringListToIntArray(TypedXmlPullParser parser, String tag)
throws XmlPullParserException, IOException {
List<String> stringList = new ArrayList<>();
readAttributeValues(parser, tag, stringList);
int[] intArray = stringList.stream()
.map(s -> Integer.parseInt(s))
.mapToInt(Integer::intValue)
.toArray();
return intArray;
}
/**
* @hide
*/
public static PreferentialNetworkServiceConfig getPreferentialNetworkServiceConfig(
TypedXmlPullParser parser, String tag) throws XmlPullParserException, IOException {
int outerDepthDAM = parser.getDepth();
int typeDAM;
PreferentialNetworkServiceConfig.Builder resultBuilder =
new PreferentialNetworkServiceConfig.Builder();
while ((typeDAM = parser.next()) != END_DOCUMENT
&& (typeDAM != END_TAG || parser.getDepth() > outerDepthDAM)) {
if (typeDAM == END_TAG || typeDAM == TEXT) {
continue;
}
String tagDAM = parser.getName();
if (TAG_CONFIG_ENABLED.equals(tagDAM)) {
resultBuilder.setEnabled(parser.getAttributeBoolean(null, ATTR_VALUE,
DevicePolicyManager.PREFERENTIAL_NETWORK_SERVICE_ENABLED_DEFAULT));
} else if (TAG_NETWORK_ID.equals(tagDAM)) {
int val = parser.getAttributeInt(null, ATTR_VALUE, 0);
if (val != 0) {
resultBuilder.setNetworkId(val);
}
} else if (TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION.equals(tagDAM)) {
resultBuilder.setFallbackToDefaultConnectionAllowed(parser.getAttributeBoolean(
null, ATTR_VALUE, true));
} else if (TAG_BLOCK_NON_MATCHING_NETWORKS.equals(tagDAM)) {
resultBuilder.setShouldBlockNonMatchingNetworks(parser.getAttributeBoolean(
null, ATTR_VALUE, false));
} else if (TAG_INCLUDED_UIDS.equals(tagDAM)) {
resultBuilder.setIncludedUids(readStringListToIntArray(parser, TAG_UID));
} else if (TAG_EXCLUDED_UIDS.equals(tagDAM)) {
resultBuilder.setExcludedUids(readStringListToIntArray(parser, TAG_UID));
} else {
Log.w(LOG_TAG, "Unknown tag under " + tag + ": " + tagDAM);
}
}
return resultBuilder.build();
}
/**
* @hide
*/
public void writeToXml(@NonNull TypedXmlSerializer out) throws IOException {
out.startTag(null, TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG);
writeAttributeValueToXml(out, TAG_CONFIG_ENABLED, isEnabled());
writeAttributeValueToXml(out, TAG_NETWORK_ID, getNetworkId());
writeAttributeValueToXml(out, TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION,
isFallbackToDefaultConnectionAllowed());
writeAttributeValueToXml(out, TAG_BLOCK_NON_MATCHING_NETWORKS,
shouldBlockNonMatchingNetworks());
writeAttributeValuesToXml(out, TAG_INCLUDED_UIDS, TAG_UID,
intArrayToStringList(getIncludedUids()));
writeAttributeValuesToXml(out, TAG_EXCLUDED_UIDS, TAG_UID,
intArrayToStringList(getExcludedUids()));
out.endTag(null, TAG_PREFERENTIAL_NETWORK_SERVICE_CONFIG);
}
/**
* @hide
*/
public void dump(IndentingPrintWriter pw) {
pw.print("networkId=");
pw.println(mNetworkId);
pw.print("isEnabled=");
pw.println(mIsEnabled);
pw.print("allowFallbackToDefaultConnection=");
pw.println(mAllowFallbackToDefaultConnection);
pw.print("blockNonMatchingNetworks=");
pw.println(mShouldBlockNonMatchingNetworks);
pw.print("includedUids=");
pw.println(Arrays.toString(mIncludedUids));
pw.print("excludedUids=");
pw.println(Arrays.toString(mExcludedUids));
}
@Override
public int describeContents() {
return 0;
}
@NonNull
public static final Creator<PreferentialNetworkServiceConfig> CREATOR =
new Creator<PreferentialNetworkServiceConfig>() {
@Override
public PreferentialNetworkServiceConfig[] newArray(int size) {
return new PreferentialNetworkServiceConfig[size];
}
@Override
public PreferentialNetworkServiceConfig createFromParcel(
@NonNull android.os.Parcel in) {
return new PreferentialNetworkServiceConfig(in);
}
};
}