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

Commit 0e15574e authored by Weng Su's avatar Weng Su Committed by Android (Google) Code Review
Browse files

Merge "Create Helper Classes for WifiTrackerLib"

parents 9e32ea9d ae838916
Loading
Loading
Loading
Loading
+138 −0
Original line number Diff line number Diff line
/*
 * 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 com.android.settings.wifi.helper;

import android.annotation.TestApi;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.Lifecycle;

import com.android.wifitrackerlib.SavedNetworkTracker;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Helper for saved Wi-Fi networks tracker from WifiTrackerLib.
 */
public class SavedWifiHelper extends WifiTrackerBase {
    private static final String TAG = "SavedWifiHelper";

    private static final Object sInstanceLock = new Object();
    @TestApi
    @GuardedBy("sInstanceLock")
    private static Map<Context, SavedWifiHelper> sTestInstances;

    protected SavedNetworkTracker mSavedNetworkTracker;

    /**
     * Static method to create a SavedWifiHelper class.
     *
     * @param context   The Context this is associated with.
     * @param lifecycle The lifecycle this is associated with.
     * @return an instance of {@link SavedWifiHelper} object.
     */
    public static SavedWifiHelper getInstance(@NonNull Context context,
            @NonNull Lifecycle lifecycle) {
        synchronized (sInstanceLock) {
            if (sTestInstances != null && sTestInstances.containsKey(context)) {
                SavedWifiHelper testInstance = sTestInstances.get(context);
                Log.w(TAG, "The context owner use a test instance:" + testInstance);
                return testInstance;
            }
            return new SavedWifiHelper(context, lifecycle);
        }
    }

    /**
     * A convenience method to set pre-prepared instance or mock(SavedWifiHelper.class) for
     * testing.
     *
     * @param context  The Context this is associated with.
     * @param instance of {@link SavedWifiHelper} object.
     * @hide
     */
    @TestApi
    @VisibleForTesting
    public static void setTestInstance(@NonNull Context context, SavedWifiHelper instance) {
        synchronized (sInstanceLock) {
            if (sTestInstances == null) sTestInstances = new ConcurrentHashMap<>();
            Log.w(TAG, "Set a test instance by context:" + context);
            sTestInstances.put(context, instance);
        }
    }

    public SavedWifiHelper(@NonNull Context context, @NonNull Lifecycle lifecycle) {
        this(context, lifecycle, null);
    }

    @VisibleForTesting
    protected SavedWifiHelper(@NonNull Context context, @NonNull Lifecycle lifecycle,
            SavedNetworkTracker saveNetworkTracker) {
        super(lifecycle);
        mSavedNetworkTracker = (saveNetworkTracker != null) ? saveNetworkTracker
                : createSavedNetworkTracker(context, lifecycle);
    }

    @VisibleForTesting
    protected SavedNetworkTracker createSavedNetworkTracker(@NonNull Context context,
            @NonNull Lifecycle lifecycle) {
        return new SavedNetworkTracker(lifecycle, context.getApplicationContext(),
                context.getApplicationContext().getSystemService(WifiManager.class),
                context.getApplicationContext().getSystemService(ConnectivityManager.class),
                new Handler(Looper.getMainLooper()),
                getWorkerThreadHandler(),
                ELAPSED_REALTIME_CLOCK,
                MAX_SCAN_AGE_MILLIS,
                SCAN_INTERVAL_MILLIS,
                null /* SavedNetworkTrackerCallback */);
    }

    @Override
    protected String getTag() {
        return TAG;
    }

    public SavedNetworkTracker getSavedNetworkTracker() {
        return mSavedNetworkTracker;
    }

    /**
     * Returns true when the certificate is being used by a saved network or network suggestion.
     */
    public boolean isCertificateInUse(String certAlias) {
        return mSavedNetworkTracker.isCertificateRequired(certAlias);
    }

    /**
     * Returns a list of network names which is using the certificate alias.
     *
     * @return a list of network names.
     */
    public List<String> getCertificateNetworkNames(String certAlias) {
        return mSavedNetworkTracker.getCertificateRequesterNames(certAlias);
    }
}
+82 −0
Original line number Diff line number Diff line
/*
 * 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 com.android.settings.wifi.helper;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
import android.os.SimpleClock;
import android.os.SystemClock;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;

import java.time.Clock;
import java.time.ZoneOffset;

/**
 * Base class for the WifiTrackerLib related classes.
 */
public class WifiTrackerBase implements DefaultLifecycleObserver {
    private static final String TAG = "WifiTrackerBase";

    // Max age of tracked WifiEntries
    protected static final long MAX_SCAN_AGE_MILLIS = 15_000;
    // Interval between initiating Wi-Fi Tracker scans
    protected static final long SCAN_INTERVAL_MILLIS = 10_000;
    // Clock used for evaluating the age of scans
    protected static final Clock ELAPSED_REALTIME_CLOCK = new SimpleClock(ZoneOffset.UTC) {
        @Override
        public long millis() {
            return SystemClock.elapsedRealtime();
        }
    };

    @VisibleForTesting
    protected HandlerThread mWorkerThread;

    public WifiTrackerBase(@NonNull Lifecycle lifecycle) {
        this(lifecycle, null /* handlerThread */);
    }

    @VisibleForTesting
    protected WifiTrackerBase(@NonNull Lifecycle lifecycle, HandlerThread handlerThread) {
        lifecycle.addObserver(this);
        mWorkerThread = (handlerThread != null) ? handlerThread :
                new HandlerThread(getTag()
                        + "{" + Integer.toHexString(System.identityHashCode(this)) + "}",
                        Process.THREAD_PRIORITY_BACKGROUND);
        mWorkerThread.start();
    }

    protected String getTag() {
        return TAG;
    }

    @Override
    public void onDestroy(@NonNull LifecycleOwner owner) {
        mWorkerThread.quit();
    }

    /** Returns the worker thread handler. */
    public Handler getWorkerThreadHandler() {
        return mWorkerThread.getThreadHandler();
    }
}
+71 −0
Original line number Diff line number Diff line
/*
 * 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 com.android.settings.wifi.helper;

import static org.mockito.Mockito.verify;

import android.content.Context;

import androidx.lifecycle.Lifecycle;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import com.android.wifitrackerlib.SavedNetworkTracker;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

@RunWith(AndroidJUnit4.class)
public class SavedWifiHelperTest {
    static final String TEST_ALIAS = "test_alias";

    @Rule
    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
    @Spy
    final Context mContext = ApplicationProvider.getApplicationContext();
    @Mock
    Lifecycle mLifecycle;
    @Mock
    SavedNetworkTracker mSaveNetworkTracker;

    SavedWifiHelper mSavedWifiHelper;

    @Before
    public void setUp() {
        mSavedWifiHelper = new SavedWifiHelper(mContext, mLifecycle, mSaveNetworkTracker);
    }

    @Test
    public void isCertificateInUse_redirectToSavedNetworkTracker() {
        mSavedWifiHelper.isCertificateInUse(TEST_ALIAS);

        verify(mSaveNetworkTracker).isCertificateRequired(TEST_ALIAS);
    }

    @Test
    public void getCertificateNetworkNames_redirectToSavedNetworkTracker() {
        mSavedWifiHelper.getCertificateNetworkNames(TEST_ALIAS);

        verify(mSaveNetworkTracker).getCertificateRequesterNames(TEST_ALIAS);
    }
}
+80 −0
Original line number Diff line number Diff line
/*
 * 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 com.android.settings.wifi.helper;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import android.os.HandlerThread;

import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

@RunWith(AndroidJUnit4.class)
public class WifiTrackerBaseTest {

    @Rule
    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
    @Mock
    Lifecycle mLifecycle;
    @Mock
    HandlerThread mWorkerThread;

    WifiTrackerBase mWifiTrackerBase;

    @Before
    public void setUp() {
        mWifiTrackerBase = new WifiTrackerBase(mLifecycle, mWorkerThread);
    }

    @Test
    public void constructor_createWorkerThread() {
        mWifiTrackerBase = new WifiTrackerBase(mLifecycle);

        assertThat(mWifiTrackerBase.mWorkerThread).isNotNull();
    }

    @Test
    public void constructor_startWorkerThread() {
        verify(mWorkerThread).start();
    }

    @Test
    public void onDestroy_quitWorkerThread() {
        mWifiTrackerBase.onDestroy(mock(LifecycleOwner.class));

        verify(mWorkerThread).quit();
    }

    @Test
    public void getWorkerThreadHandler_isNotNull() {
        mWifiTrackerBase = new WifiTrackerBase(mLifecycle);

        assertThat(mWifiTrackerBase.getWorkerThreadHandler()).isNotNull();
    }
}