MOBILE-4113 geolocation: Fix screen locked before allowing
parent
aaa98793aa
commit
8d64282ce8
|
@ -19,6 +19,9 @@ import { CoreApp } from '@services/app';
|
||||||
import { CoreAnyError, CoreError } from '@classes/errors/error';
|
import { CoreAnyError, CoreError } from '@classes/errors/error';
|
||||||
import { Geolocation, Diagnostic, makeSingleton } from '@singletons';
|
import { Geolocation, Diagnostic, makeSingleton } from '@singletons';
|
||||||
import { CoreUtils } from './utils/utils';
|
import { CoreUtils } from './utils/utils';
|
||||||
|
import { CorePlatform } from './platform';
|
||||||
|
import { CoreSilentError } from '@classes/errors/silenterror';
|
||||||
|
import { CoreSubscriptions } from '@singletons/subscriptions';
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class CoreGeolocationProvider {
|
export class CoreGeolocationProvider {
|
||||||
|
@ -97,7 +100,7 @@ export class CoreGeolocationProvider {
|
||||||
}
|
}
|
||||||
// Fall through.
|
// Fall through.
|
||||||
case Diagnostic.permissionStatus.NOT_REQUESTED:
|
case Diagnostic.permissionStatus.NOT_REQUESTED:
|
||||||
await Diagnostic.requestLocationAuthorization();
|
await this.requestLocationAuthorization();
|
||||||
await CoreApp.waitForResume(500);
|
await CoreApp.waitForResume(500);
|
||||||
await this.doAuthorizeLocation(true);
|
await this.doAuthorizeLocation(true);
|
||||||
|
|
||||||
|
@ -133,6 +136,24 @@ export class CoreGeolocationProvider {
|
||||||
return CoreUtils.promiseWorks(Diagnostic.getLocationAuthorizationStatus());
|
return CoreUtils.promiseWorks(Diagnostic.getLocationAuthorizationStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request and return the location authorization status for the application.
|
||||||
|
*/
|
||||||
|
protected async requestLocationAuthorization(): Promise<void> {
|
||||||
|
if (!CoreApp.isIOS()) {
|
||||||
|
await Diagnostic.requestLocationAuthorization();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In iOS, the modal disappears when the screen is locked and the promise never ends. Treat that case.
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// Don't display an error if app is sent to the background, just finish the process.
|
||||||
|
const unsubscribe = CoreSubscriptions.once(CorePlatform.pause, () => reject(new CoreSilentError()));
|
||||||
|
Diagnostic.requestLocationAuthorization().then(() => resolve(), reject).finally(() => unsubscribe());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CoreGeolocation = makeSingleton(CoreGeolocationProvider);
|
export const CoreGeolocation = makeSingleton(CoreGeolocationProvider);
|
||||||
|
|
|
@ -670,7 +670,7 @@ export class CoreDomUtilsProvider {
|
||||||
* @param error Error to check.
|
* @param error Error to check.
|
||||||
* @return Whether it's a canceled error.
|
* @return Whether it's a canceled error.
|
||||||
*/
|
*/
|
||||||
isSilentError(error: CoreError | CoreTextErrorObject | string): boolean {
|
isSilentError(error: CoreAnyError): boolean {
|
||||||
return error instanceof CoreSilentError;
|
return error instanceof CoreSilentError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1378,8 +1378,8 @@ export class CoreDomUtilsProvider {
|
||||||
needsTranslate = false,
|
needsTranslate = false,
|
||||||
autocloseTime?: number,
|
autocloseTime?: number,
|
||||||
): Promise<HTMLIonAlertElement | null> {
|
): Promise<HTMLIonAlertElement | null> {
|
||||||
if (this.isCanceledError(error)) {
|
if (this.isCanceledError(error) || this.isSilentError(error)) {
|
||||||
// It's a canceled error, don't display an error.
|
// It's a canceled or a silent error, don't display an error.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,13 @@ export class CoreSubscriptions {
|
||||||
* @param subscribable Subscribable to listen to.
|
* @param subscribable Subscribable to listen to.
|
||||||
* @param onSuccess Callback to run when the subscription is updated.
|
* @param onSuccess Callback to run when the subscription is updated.
|
||||||
* @param onError Callback to run when the an error happens.
|
* @param onError Callback to run when the an error happens.
|
||||||
|
* @return A function to unsubscribe.
|
||||||
*/
|
*/
|
||||||
static once<T>(subscribable: Subscribable<T>, onSuccess: (value: T) => unknown, onError?: (error: unknown) => unknown): void {
|
static once<T>(
|
||||||
|
subscribable: Subscribable<T>,
|
||||||
|
onSuccess: (value: T) => unknown,
|
||||||
|
onError?: (error: unknown) => unknown,
|
||||||
|
): () => void {
|
||||||
let unsubscribe = false;
|
let unsubscribe = false;
|
||||||
let subscription: Subscription | null = null;
|
let subscription: Subscription | null = null;
|
||||||
|
|
||||||
|
@ -56,6 +61,8 @@ export class CoreSubscriptions {
|
||||||
if (unsubscribe) {
|
if (unsubscribe) {
|
||||||
subscription.unsubscribe();
|
subscription.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return () => subscription?.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,4 +59,18 @@ describe('CoreSubscriptions singleton', () => {
|
||||||
expect(error).not.toHaveBeenCalled();
|
expect(error).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('allows unsubscribing from outside the once function', async () => {
|
||||||
|
const subject = new Subject();
|
||||||
|
const success = jest.fn();
|
||||||
|
const error = jest.fn();
|
||||||
|
|
||||||
|
const unsubscribe = CoreSubscriptions.once(subject, success, error);
|
||||||
|
unsubscribe();
|
||||||
|
|
||||||
|
subject.next('foo');
|
||||||
|
subject.error('bar');
|
||||||
|
expect(success).not.toHaveBeenCalled();
|
||||||
|
expect(error).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue