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

Commit 9c336445 authored by Mohammed Althaf T's avatar Mohammed Althaf T 😊
Browse files

Updater: Add network ConnectionStateMonitor

Change-Id: I54847a54e1cb0bff262deb3e57cae30fcd85b26f

Updater: Move ConnectionStateMonitor to kotlin

Change-Id: I7e0a1f68b71afe620706813daf76258b0c1682ae

Updater: Improve ConnectionStateMonitor behaviour

- Keep updater app alive till device back online for network callback.
- Remove network callback once the internet is back.
- Wait 10 seconds before doing anything when the device is online.

Change-Id: I55e631cbf6cec9c19ec13e513a54ceaf10f8b2b9

Updater: Simplify activity status for cnstate monitor

Change-Id: I1a46444c35ce40c967a16cc8a5ae2d099e14d62e
parent 6d5dddd5
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3,12 +3,14 @@ android_app {

    srcs: [
           "src/**/*.java",
           "src/**/*.kt",
    ],
    resource_dirs: ["res"],

    static_libs: [
        "com.google.android.material_material",
        "androidx.core_core",
        "androidx.core_core-ktx",
        "androidx.appcompat_appcompat",
        "androidx.cardview_cardview",
        "androidx.preference_preference",
+4 −1
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ buildscript {

    dependencies {
        classpath 'com.android.tools.build:gradle:7.1.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10"
    }
}

@@ -19,6 +20,7 @@ def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))

apply plugin: 'com.android.application'
apply plugin: 'org.jetbrains.kotlin.android'

android {
    compileSdkVersion 30
@@ -58,9 +60,10 @@ android {
dependencies {
    compileOnly fileTree(dir: 'system_libs/', include: ['*.jar'])

    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.appcompat:appcompat:1.3.0'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.core:core-ktx:1.9.0'
    implementation 'androidx.preference:preference:1.1.0'
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
    implementation 'com.google.android.material:material:1.4.0'
}
+38 −2
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
@@ -32,7 +35,9 @@ import androidx.core.app.NotificationCompat;
import androidx.preference.PreferenceManager;

import org.json.JSONException;
import org.lineageos.updater.controller.UpdaterService;
import org.lineageos.updater.download.DownloadClient;
import org.lineageos.updater.misc.ConnectionStateMonitor;
import org.lineageos.updater.misc.Constants;
import org.lineageos.updater.misc.JsonValidator;
import org.lineageos.updater.misc.Utils;
@@ -52,6 +57,15 @@ public class UpdatesCheckReceiver extends BroadcastReceiver {
    private static final String NEW_UPDATES_NOTIFICATION_CHANNEL =
            "new_updates_notification_channel";

    private final NetworkRequest networkRequest = new NetworkRequest.Builder()
            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
            .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
            .build();

    private ConnectivityManager.NetworkCallback cnState;
    private ConnectivityManager connectivityManager;

    @Override
    public void onReceive(final Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
@@ -86,10 +100,17 @@ public class UpdatesCheckReceiver extends BroadcastReceiver {
            scheduleRepeatingUpdatesCheck(context);
        }

        cnState = new ConnectionStateMonitor().getInstance(context);
        connectivityManager = (ConnectivityManager)
                context.getSystemService(Context.CONNECTIVITY_SERVICE);

        if (!Utils.isNetworkAvailable(context)) {
            Log.d(TAG, "Network not available, scheduling new check");
            scheduleUpdatesCheck(context);
            if (!UpdaterService.isNetworkCallBackActive()) {
                setupNetworkCallback(true);
            }
            return;
        } else if (UpdaterService.isNetworkCallBackActive()) {
            setupNetworkCallback(false);
        }

        final File jsonNew = new File(json.getAbsolutePath() + UUID.randomUUID());
@@ -145,6 +166,21 @@ public class UpdatesCheckReceiver extends BroadcastReceiver {
        }
    }

    public void setupNetworkCallback(boolean shouldEnable) {
        if (shouldEnable) {
            connectivityManager.registerNetworkCallback(networkRequest, cnState);
        } else {
            try {
                connectivityManager.unregisterNetworkCallback(cnState);
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "Network callback was not registered");
            }
        }

        UpdaterService.setNetworkCallBackActive(shouldEnable);
        Log.d(TAG, "Network callback enabled: " + shouldEnable);
    }

    private static void showNotification(Context context) {
        NotificationManager notificationManager = context.getSystemService(
                NotificationManager.class);
+9 −1
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ public class UpdaterService extends Service {
    private static final int NOTIFICATION_ID = 10;

    private final IBinder mBinder = new LocalBinder();
    private static boolean isNetworkCallBackActive = false;
    private boolean mHasClients;

    private BroadcastReceiver mBroadcastReceiver;
@@ -246,7 +247,8 @@ public class UpdaterService extends Service {

    private void tryStopSelf() {
        if (!mHasClients && !mUpdaterController.hasActiveDownloads() &&
                !mUpdaterController.isInstallingUpdate() && !areNotificationsActive()) {
                !mUpdaterController.isInstallingUpdate() && !isNetworkCallBackActive()
                && !areNotificationsActive()) {
            Log.d(TAG, "Service no longer needed, stopping");
            stopSelf();
        }
@@ -505,6 +507,12 @@ public class UpdaterService extends Service {
        }
    }

    public static void setNetworkCallBackActive(boolean isActive) {
        isNetworkCallBackActive = isActive;
    }

    public static boolean isNetworkCallBackActive() { return isNetworkCallBackActive; }

    private void handleDownloadProgressChange(UpdateInfo update) {
        int progress = update.getProgress();
        mNotificationBuilder.setProgress(100, progress, false);
+73 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 MURENA SAS
 *
 * 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 org.lineageos.updater.misc

import android.content.Context
import android.content.Intent
import android.net.ConnectivityManager
import android.net.Network
import android.os.Handler
import android.os.Looper
import android.util.Log
import org.lineageos.updater.UpdatesCheckReceiver

class ConnectionStateMonitor {
    companion object {
        private var instance: ConnectivityManager.NetworkCallback? = null
    }

    fun getInstance(context: Context): ConnectivityManager.NetworkCallback {
        if (instance == null) {
            instance = networkCallback(context)
        }

        return instance!!
    }

    /**
     * API callbacks to determine which status we currently in
     * we need the below callbacks:
     * - onAvailable: device connected to a network of course
     * - onLost: when the connection completely lost
     */
    fun networkCallback(context: Context) = object: ConnectivityManager.NetworkCallback() {
        private val tag = "ConnectionStateMonitor"
        private val delayExecute = 10000L // 10 seconds

        private fun startUpdatesCheckReceiver(): Runnable = Runnable {
            val broadcastIntent = Intent()
            broadcastIntent.setClassName(context, UpdatesCheckReceiver::class.java.name)
            context.sendBroadcast(broadcastIntent)
        }

        private fun checkForUpdates() {
            // Delay because some phones takes time go online
            Handler(Looper.getMainLooper()).postDelayed(
                startUpdatesCheckReceiver(), delayExecute
            )
        }

        override fun onAvailable(network: Network) {
            Log.d(tag, "Network available")
            checkForUpdates()
        }

        override fun onLost(network: Network) {
            Log.d(tag, "Network not available")
            checkForUpdates()
        }
    }
}
Loading