2022-05-11 14:06:42 +02:00
|
|
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
|
|
|
|
import { Injectable } from '@angular/core';
|
|
|
|
import { CorePlatform } from '@services/platform';
|
2022-06-15 10:17:02 +02:00
|
|
|
import { Network } from '@ionic-native/network/ngx';
|
2022-06-13 12:45:43 +02:00
|
|
|
import { makeSingleton } from '@singletons';
|
|
|
|
import { Observable, Subject, merge } from 'rxjs';
|
|
|
|
|
2022-07-12 10:40:01 +02:00
|
|
|
enum CoreNetworkConnection {
|
|
|
|
UNKNOWN = 'unknown',
|
|
|
|
ETHERNET = 'ethernet',
|
|
|
|
WIFI = 'wifi',
|
|
|
|
CELL_2G = '2g',
|
|
|
|
CELL_3G = '3g',
|
|
|
|
CELL_4G = '4g',
|
|
|
|
CELL = 'cellular',
|
|
|
|
NONE = 'none',
|
|
|
|
};
|
|
|
|
|
2022-05-11 14:06:42 +02:00
|
|
|
/**
|
2022-06-13 12:45:43 +02:00
|
|
|
* Service to manage network connections.
|
2022-05-11 14:06:42 +02:00
|
|
|
*/
|
|
|
|
@Injectable({ providedIn: 'root' })
|
2022-06-15 10:17:02 +02:00
|
|
|
export class CoreNetworkService extends Network {
|
2022-06-13 12:45:43 +02:00
|
|
|
|
|
|
|
type!: string;
|
2022-05-11 14:06:42 +02:00
|
|
|
|
2022-06-13 12:45:43 +02:00
|
|
|
protected connectObservable = new Subject<'connected'>();
|
|
|
|
protected disconnectObservable = new Subject<'disconnected'>();
|
2022-05-11 14:06:42 +02:00
|
|
|
protected forceOffline = false;
|
2022-06-13 12:45:43 +02:00
|
|
|
protected online = false;
|
|
|
|
|
2022-06-15 10:17:02 +02:00
|
|
|
/**
|
|
|
|
* Initialize the service.
|
|
|
|
*/
|
|
|
|
initialize(): void {
|
2022-06-13 12:45:43 +02:00
|
|
|
this.checkOnline();
|
|
|
|
|
|
|
|
if (CorePlatform.isMobile()) {
|
2022-07-12 10:40:01 +02:00
|
|
|
// We cannot directly listen to onChange because it depends on
|
|
|
|
// onConnect and onDisconnect that have been already overriden.
|
|
|
|
super.onConnect().subscribe(() => {
|
|
|
|
this.fireObservable();
|
|
|
|
});
|
|
|
|
super.onDisconnect().subscribe(() => {
|
2022-06-13 12:45:43 +02:00
|
|
|
this.fireObservable();
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
|
|
(<any> window).Connection = {
|
2022-07-12 10:40:01 +02:00
|
|
|
UNKNOWN: CoreNetworkConnection.UNKNOWN, // eslint-disable-line @typescript-eslint/naming-convention
|
|
|
|
ETHERNET: CoreNetworkConnection.ETHERNET, // eslint-disable-line @typescript-eslint/naming-convention
|
|
|
|
WIFI: CoreNetworkConnection.WIFI, // eslint-disable-line @typescript-eslint/naming-convention
|
|
|
|
CELL_2G: CoreNetworkConnection.CELL_2G, // eslint-disable-line @typescript-eslint/naming-convention
|
|
|
|
CELL_3G: CoreNetworkConnection.CELL_3G, // eslint-disable-line @typescript-eslint/naming-convention
|
|
|
|
CELL_4G: CoreNetworkConnection.CELL_4G, // eslint-disable-line @typescript-eslint/naming-convention
|
|
|
|
CELL: CoreNetworkConnection.CELL, // eslint-disable-line @typescript-eslint/naming-convention
|
|
|
|
NONE: CoreNetworkConnection.NONE, // eslint-disable-line @typescript-eslint/naming-convention
|
2022-06-13 12:45:43 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
window.addEventListener('online', () => {
|
|
|
|
this.fireObservable();
|
|
|
|
}, false);
|
|
|
|
|
|
|
|
window.addEventListener('offline', () => {
|
|
|
|
this.fireObservable();
|
|
|
|
}, false);
|
|
|
|
}
|
|
|
|
}
|
2022-05-11 14:06:42 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set value of forceOffline flag. If true, the app will think the device is offline.
|
|
|
|
*
|
|
|
|
* @param value Value to set.
|
|
|
|
*/
|
|
|
|
setForceOffline(value: boolean): void {
|
|
|
|
this.forceOffline = !!value;
|
2022-06-13 12:45:43 +02:00
|
|
|
this.fireObservable();
|
2022-05-11 14:06:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether we are online.
|
|
|
|
*
|
|
|
|
* @return Whether the app is online.
|
|
|
|
*/
|
|
|
|
isOnline(): boolean {
|
2022-06-13 12:45:43 +02:00
|
|
|
return this.online;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether we are online.
|
|
|
|
*
|
|
|
|
* @return Whether the app is online.
|
|
|
|
*/
|
|
|
|
checkOnline(): void {
|
2022-05-11 14:06:42 +02:00
|
|
|
if (this.forceOffline) {
|
2022-06-13 12:45:43 +02:00
|
|
|
this.online = false;
|
2022-07-12 10:40:01 +02:00
|
|
|
this.type = CoreNetworkConnection.NONE;
|
2022-06-13 12:45:43 +02:00
|
|
|
|
|
|
|
return;
|
2022-05-11 14:06:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!CorePlatform.isMobile()) {
|
2022-06-13 12:45:43 +02:00
|
|
|
this.online = navigator.onLine;
|
2022-07-12 10:40:01 +02:00
|
|
|
this.type = this.online
|
|
|
|
? CoreNetworkConnection.WIFI
|
|
|
|
: CoreNetworkConnection.NONE;
|
2022-06-13 12:45:43 +02:00
|
|
|
|
|
|
|
return;
|
2022-05-11 14:06:42 +02:00
|
|
|
}
|
|
|
|
|
2022-07-12 10:40:01 +02:00
|
|
|
let online = this.type !== null && this.type !== CoreNetworkConnection.NONE &&
|
|
|
|
this.type !== CoreNetworkConnection.UNKNOWN;
|
2022-05-11 14:06:42 +02:00
|
|
|
|
|
|
|
// Double check we are not online because we cannot rely 100% in Cordova APIs.
|
|
|
|
if (!online && navigator.onLine) {
|
|
|
|
online = true;
|
|
|
|
}
|
|
|
|
|
2022-06-13 12:45:43 +02:00
|
|
|
this.online = online;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an observable to watch connection changes.
|
|
|
|
*
|
|
|
|
* @return Observable.
|
|
|
|
*/
|
|
|
|
onChange(): Observable<'connected' | 'disconnected'> {
|
|
|
|
return merge(this.connectObservable, this.disconnectObservable);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an observable to notify when the app is connected.
|
2022-07-12 10:40:01 +02:00
|
|
|
* It will also be fired when connection type changes.
|
2022-06-13 12:45:43 +02:00
|
|
|
*
|
|
|
|
* @return Observable.
|
|
|
|
*/
|
|
|
|
onConnect(): Observable<'connected'> {
|
|
|
|
return this.connectObservable;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an observable to notify when the app is disconnected.
|
|
|
|
*
|
|
|
|
* @return Observable.
|
|
|
|
*/
|
|
|
|
onDisconnect(): Observable<'disconnected'> {
|
|
|
|
return this.disconnectObservable;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fires the correct observable depending on the connection status.
|
|
|
|
*/
|
|
|
|
protected fireObservable(): void {
|
|
|
|
this.checkOnline();
|
2022-07-12 10:40:01 +02:00
|
|
|
|
|
|
|
if (this.online) {
|
2022-06-13 12:45:43 +02:00
|
|
|
this.connectObservable.next('connected');
|
2022-07-12 10:40:01 +02:00
|
|
|
} else {
|
2022-06-13 12:45:43 +02:00
|
|
|
this.disconnectObservable.next('disconnected');
|
|
|
|
}
|
2022-05-11 14:06:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if device uses a limited connection.
|
|
|
|
*
|
|
|
|
* @return Whether the device uses a limited connection.
|
|
|
|
*/
|
|
|
|
isNetworkAccessLimited(): boolean {
|
|
|
|
if (!CorePlatform.isMobile()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-07-12 10:40:01 +02:00
|
|
|
const limited: string[] = [
|
|
|
|
CoreNetworkConnection.CELL_2G,
|
|
|
|
CoreNetworkConnection.CELL_3G,
|
|
|
|
CoreNetworkConnection.CELL_4G,
|
|
|
|
CoreNetworkConnection.CELL,
|
2022-05-11 14:06:42 +02:00
|
|
|
];
|
|
|
|
|
2022-06-15 10:17:02 +02:00
|
|
|
return limited.indexOf(this.type) > -1;
|
2022-05-11 14:06:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if device uses a wifi connection.
|
|
|
|
*
|
|
|
|
* @return Whether the device uses a wifi connection.
|
|
|
|
*/
|
|
|
|
isWifi(): boolean {
|
|
|
|
return this.isOnline() && !this.isNetworkAccessLimited();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export const CoreNetwork = makeSingleton(CoreNetworkService);
|