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

Commit e87c3bee authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 6473661 from 6421197f to rvc-release

Change-Id: If6aa1673935fe83807a747042ea4b889783cd4ff
parents 32b76b74 6421197f
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.net.shared;

import android.annotation.Nullable;
import android.net.Layer2InformationParcelable;
import android.net.MacAddress;

@@ -23,14 +24,18 @@ import java.util.Objects;

/** @hide */
public class Layer2Information {
    @Nullable
    public final String mL2Key;
    @Nullable
    public final String mGroupHint;
    @Nullable
    public final MacAddress mBssid;

    /**
     * Create a Layer2Information with the specified configuration.
     */
    public Layer2Information(String l2Key, String groupHint, MacAddress bssid) {
    public Layer2Information(@Nullable final String l2Key, @Nullable final String groupHint,
            @Nullable final MacAddress bssid) {
        mL2Key = l2Key;
        mGroupHint = groupHint;
        mBssid = bssid;
@@ -41,7 +46,7 @@ public class Layer2Information {
        StringBuffer str = new StringBuffer();
        str.append("L2Key: ").append(mL2Key);
        str.append(", GroupHint: ").append(mGroupHint);
        str.append(", bssid: ").append(mBssid.toString());
        str.append(", bssid: ").append(mBssid);
        return str.toString();
    }

+8 −1
Original line number Diff line number Diff line
@@ -83,6 +83,13 @@ aidl_interface {
        "src/android/net/ip/IIpClientCallbacks.aidl",
    ],
    backend: {
        java: {
            apex_available: [
                "//apex_available:platform",
                "com.android.bluetooth.updatable",
                "com.android.wifi",
            ],
        },
        ndk: {
            enabled: false,
        },
@@ -117,7 +124,7 @@ java_library {
    ],
    static_libs: [
        "ipmemorystore-aidl-interfaces-V5-java",
        "networkstack-aidl-interfaces-unstable-java",
        "networkstack-aidl-interfaces-java",
    ],
    visibility: [
        "//frameworks/base/packages/Tethering",
+12 −0
Original line number Diff line number Diff line
@@ -85,4 +85,16 @@
         failed. -->
    <string name="config_network_validation_failed_content_regexp" translatable="false"></string>
    <string name="config_network_validation_success_content_regexp" translatable="false"></string>

    <!-- URL for evaluating bandwidth. If the download cannot be finished before the timeout, then
         it means the bandwidth check is failed. If the download can be finished before the timeout,
         then it means the bandwidth check is passed. So the OEMs should set this URL appropriately.
         -->
    <string name="config_evaluating_bandwidth_url" translatable="false"></string>
    <!-- A timeout for evaluating bandwidth. -->
    <integer name="config_evaluating_bandwidth_timeout_ms"></integer>
    <!-- The retry timer will start from config_min_retry_timer, and the timer will be exponential
         increased until reaching the config_max_retry_timer. -->
    <integer name="config_evaluating_bandwidth_min_retry_timer_ms"></integer>
    <integer name="config_evaluating_bandwidth_max_retry_timer_ms"></integer>
</resources>
+6 −0
Original line number Diff line number Diff line
@@ -71,6 +71,12 @@
            could result in valid captive portals being incorrectly classified as having no
            connectivity.-->
            <item type="bool" name="config_force_dns_probe_private_ip_no_internet"/>

            <!-- Configurations for bandwidth check. -->
            <item type="string" name="config_evaluating_bandwidth_url"/>
            <item type="integer" name="config_evaluating_bandwidth_timeout_ms"/>
            <item type="integer" name="config_evaluating_bandwidth_min_retry_timer_ms"/>
            <item type="integer" name="config_evaluating_bandwidth_max_retry_timer_ms"/>
        </policy>
    </overlayable>
</resources>
+175 −2
Original line number Diff line number Diff line
@@ -174,6 +174,7 @@ import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException;
@@ -200,6 +201,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -364,9 +366,27 @@ public class NetworkMonitor extends StateMachine {
     * Message to self to poll current tcp status from kernel.
     */
    private static final int EVENT_POLL_TCPINFO = 21;

    /**
     * Message to self to do the bandwidth check in EvaluatingBandwidthState.
     */
    private static final int CMD_EVALUATE_BANDWIDTH = 22;

    /**
     * Message to self to know the bandwidth check is completed.
     */
    private static final int CMD_BANDWIDTH_CHECK_COMPLETE = 23;

    /**
     * Message to self to know the bandwidth check is timeouted.
     */
    private static final int CMD_BANDWIDTH_CHECK_TIMEOUT = 24;

    // Start mReevaluateDelayMs at this value and double.
    private static final int INITIAL_REEVALUATE_DELAY_MS = 1000;
    private static final int MAX_REEVALUATE_DELAY_MS = 10 * 60 * 1000;
    // Default timeout of evaluating network bandwidth.
    private static final int DEFAULT_EVALUATING_BANDWIDTH_TIMEOUT_MS = 10_000;
    // Before network has been evaluated this many times, ignore repeated reevaluate requests.
    private static final int IGNORE_REEVALUATE_ATTEMPTS = 5;
    private int mReevaluateToken = 0;
@@ -406,6 +426,12 @@ public class NetworkMonitor extends StateMachine {
    private final URL[] mCaptivePortalHttpsUrls;
    @Nullable
    private final CaptivePortalProbeSpec[] mCaptivePortalFallbackSpecs;
    // Configuration values for network bandwidth check.
    @Nullable
    private final String mEvaluatingBandwidthUrl;
    private final int mMaxRetryTimerMs;
    private final int mEvaluatingBandwidthTimeoutMs;
    private final AtomicInteger mNextEvaluatingBandwidthThreadId = new AtomicInteger(1);

    private NetworkCapabilities mNetworkCapabilities;
    private LinkProperties mLinkProperties;
@@ -421,6 +447,10 @@ public class NetworkMonitor extends StateMachine {
    private boolean mUserDoesNotWant = false;
    // Avoids surfacing "Sign in to network" notification.
    private boolean mDontDisplaySigninNotification = false;
    // Set to true once the evaluating network bandwidth is passed or the captive portal respond
    // APP_RETURN_WANTED_AS_IS which means the user wants to use this network anyway.
    @VisibleForTesting
    protected boolean mIsBandwidthCheckPassedOrIgnored = false;

    private final State mDefaultState = new DefaultState();
    private final State mValidatedState = new ValidatedState();
@@ -430,6 +460,7 @@ public class NetworkMonitor extends StateMachine {
    private final State mEvaluatingPrivateDnsState = new EvaluatingPrivateDnsState();
    private final State mProbingState = new ProbingState();
    private final State mWaitingForNextProbeState = new WaitingForNextProbeState();
    private final State mEvaluatingBandwidthState = new EvaluatingBandwidthState();

    private CustomIntentReceiver mLaunchCaptivePortalAppBroadcastReceiver = null;

@@ -519,6 +550,7 @@ public class NetworkMonitor extends StateMachine {
                addState(mWaitingForNextProbeState, mEvaluatingState);
            addState(mCaptivePortalState, mMaybeNotifyState);
        addState(mEvaluatingPrivateDnsState, mDefaultState);
        addState(mEvaluatingBandwidthState, mDefaultState);
        addState(mValidatedState, mDefaultState);
        setInitialState(mDefaultState);
        // CHECKSTYLE:ON IndentationCheck
@@ -540,6 +572,15 @@ public class NetworkMonitor extends StateMachine {
        mDnsStallDetector = initDnsStallDetectorIfRequired(mDataStallEvaluationType,
                mConsecutiveDnsTimeoutThreshold);
        mTcpTracker = tst;
        // Read the configurations of evaluating network bandwidth.
        mEvaluatingBandwidthUrl = getResStringConfig(mContext,
                R.string.config_evaluating_bandwidth_url, null);
        mMaxRetryTimerMs = getResIntConfig(mContext,
                R.integer.config_evaluating_bandwidth_max_retry_timer_ms,
                MAX_REEVALUATE_DELAY_MS);
        mEvaluatingBandwidthTimeoutMs = getResIntConfig(mContext,
                R.integer.config_evaluating_bandwidth_timeout_ms,
                DEFAULT_EVALUATING_BANDWIDTH_TIMEOUT_MS);

        // Provide empty LinkProperties and NetworkCapabilities to make sure they are never null,
        // even before notifyNetworkConnected.
@@ -777,6 +818,9 @@ public class NetworkMonitor extends StateMachine {
                            break;
                        case APP_RETURN_WANTED_AS_IS:
                            mDontDisplaySigninNotification = true;
                            // If the user wants to use this network anyway, there is no need to
                            // perform the bandwidth check even if configured.
                            mIsBandwidthCheckPassedOrIgnored = true;
                            // TODO: Distinguish this from a network that actually validates.
                            // Displaying the "x" on the system UI icon may still be a good idea.
                            transitionTo(mEvaluatingPrivateDnsState);
@@ -1270,8 +1314,12 @@ public class NetworkMonitor extends StateMachine {
                        mEvaluationState.removeProbeResult(NETWORK_VALIDATION_PROBE_PRIVDNS);
                    }

                    if (needEvaluatingBandwidth()) {
                        transitionTo(mEvaluatingBandwidthState);
                    } else {
                        // All good!
                        transitionTo(mValidatedState);
                    }
                    break;
                case CMD_PRIVATE_DNS_SETTINGS_CHANGED:
                    // When settings change the reevaluation timer must be reset.
@@ -1464,6 +1512,112 @@ public class NetworkMonitor extends StateMachine {
        }
    }

    private final class EvaluatingBandwidthThread extends Thread {
        final int mThreadId;

        EvaluatingBandwidthThread(int id) {
            mThreadId = id;
        }

        @Override
        public void run() {
            HttpURLConnection urlConnection = null;
            try {
                final URL url = makeURL(mEvaluatingBandwidthUrl);
                urlConnection = makeProbeConnection(url, true /* followRedirects */);
                // In order to exclude the time of DNS lookup, send the delay message of timeout
                // here.
                sendMessageDelayed(CMD_BANDWIDTH_CHECK_TIMEOUT, mEvaluatingBandwidthTimeoutMs);
                readContentFromDownloadUrl(urlConnection);
            } catch (InterruptedIOException e) {
                // There is a timing issue that someone triggers the forcing reevaluation when
                // executing the getInputStream(). The InterruptedIOException is thrown by
                // Timeout#throwIfReached, it will reset the interrupt flag of Thread. So just
                // return and wait for the bandwidth reevaluation, otherwise the
                // CMD_BANDWIDTH_CHECK_COMPLETE will be sent.
                validationLog("The thread is interrupted when executing the getInputStream(),"
                        + " return and wait for the bandwidth reevaluation");
                return;
            } catch (IOException e) {
                validationLog("Evaluating bandwidth failed: " + e + ", if the thread is not"
                        + " interrupted, transition to validated state directly to make sure user"
                        + " can use wifi normally.");
            } finally {
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
            }
            // Don't send CMD_BANDWIDTH_CHECK_COMPLETE if the IO is interrupted or timeout.
            // Only send CMD_BANDWIDTH_CHECK_COMPLETE when the download is finished normally.
            // Add a serial number for CMD_BANDWIDTH_CHECK_COMPLETE to prevent handling the obsolete
            // CMD_BANDWIDTH_CHECK_COMPLETE.
            if (!isInterrupted()) sendMessage(CMD_BANDWIDTH_CHECK_COMPLETE, mThreadId);
        }

        private void readContentFromDownloadUrl(@NonNull final HttpURLConnection conn)
                throws IOException {
            final byte[] buffer = new byte[1000];
            final InputStream is = conn.getInputStream();
            while (!isInterrupted() && is.read(buffer) > 0) { /* read again */ }
        }
    }

    private class EvaluatingBandwidthState extends State {
        private EvaluatingBandwidthThread mEvaluatingBandwidthThread;
        private int mRetryBandwidthDelayMs;
        private int mCurrentThreadId;

        @Override
        public void enter() {
            mRetryBandwidthDelayMs = getResIntConfig(mContext,
                    R.integer.config_evaluating_bandwidth_min_retry_timer_ms,
                    INITIAL_REEVALUATE_DELAY_MS);
            sendMessage(CMD_EVALUATE_BANDWIDTH);
        }

        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case CMD_EVALUATE_BANDWIDTH:
                    mCurrentThreadId = mNextEvaluatingBandwidthThreadId.getAndIncrement();
                    mEvaluatingBandwidthThread = new EvaluatingBandwidthThread(mCurrentThreadId);
                    mEvaluatingBandwidthThread.start();
                    break;
                case CMD_BANDWIDTH_CHECK_COMPLETE:
                    // Only handle the CMD_BANDWIDTH_CHECK_COMPLETE which is sent by the newest
                    // EvaluatingBandwidthThread.
                    if (mCurrentThreadId == msg.arg1) {
                        mIsBandwidthCheckPassedOrIgnored = true;
                        transitionTo(mValidatedState);
                    }
                    break;
                case CMD_BANDWIDTH_CHECK_TIMEOUT:
                    validationLog("Evaluating bandwidth timeout!");
                    mEvaluatingBandwidthThread.interrupt();
                    scheduleReevaluatingBandwidth();
                    break;
                default:
                    return NOT_HANDLED;
            }
            return HANDLED;
        }

        private void scheduleReevaluatingBandwidth() {
            sendMessageDelayed(obtainMessage(CMD_EVALUATE_BANDWIDTH), mRetryBandwidthDelayMs);
            mRetryBandwidthDelayMs *= 2;
            if (mRetryBandwidthDelayMs > mMaxRetryTimerMs) {
                mRetryBandwidthDelayMs = mMaxRetryTimerMs;
            }
        }

        @Override
        public void exit() {
            mEvaluatingBandwidthThread.interrupt();
            removeMessages(CMD_EVALUATE_BANDWIDTH);
            removeMessages(CMD_BANDWIDTH_CHECK_TIMEOUT);
        }
    }

    // Limits the list of IP addresses returned by getAllByName or tried by openConnection to at
    // most one per address family. This ensures we only wait up to 20 seconds for TCP connections
    // to complete, regardless of how many IP addresses a host has.
@@ -1490,6 +1644,25 @@ public class NetworkMonitor extends StateMachine {
        }
    }

    @VisibleForTesting
    boolean onlyWifiTransport() {
        int[] transportTypes = mNetworkCapabilities.getTransportTypes();
        return transportTypes.length == 1
                && transportTypes[0] == NetworkCapabilities.TRANSPORT_WIFI;
    }

    @VisibleForTesting
    boolean needEvaluatingBandwidth() {
        if (mIsBandwidthCheckPassedOrIgnored
                || TextUtils.isEmpty(mEvaluatingBandwidthUrl)
                || !mNetworkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)
                || !onlyWifiTransport()) {
            return false;
        }

        return true;
    }

    private boolean getIsCaptivePortalCheckEnabled() {
        String symbol = CAPTIVE_PORTAL_MODE;
        int defaultValue = CAPTIVE_PORTAL_MODE_PROMPT;
Loading