UNPKG

@nativescript/core

Version:

A JavaScript library providing an easy to use api for interacting with iOS and Android platform APIs.

514 lines • 25.1 kB
import { profile } from '../profiling'; import { isEmbedded } from '../ui/embedding'; import { SDK_VERSION } from '../utils/constants'; import { ApplicationCommon } from './application-common'; let BroadcastReceiver_; function initBroadcastReceiver() { if (BroadcastReceiver_) { return BroadcastReceiver_; } var BroadcastReceiverImpl = /** @class */ (function (_super) { __extends(BroadcastReceiverImpl, _super); function BroadcastReceiverImpl(onReceiveCallback) { var _this = _super.call(this) || this; _this._onReceiveCallback = onReceiveCallback; return global.__native(_this); } BroadcastReceiverImpl.prototype.onReceive = function (context, intent) { if (this._onReceiveCallback) { this._onReceiveCallback(context, intent); } }; return BroadcastReceiverImpl; }(android.content.BroadcastReceiver)); BroadcastReceiver_ = BroadcastReceiverImpl; return BroadcastReceiver_; } let NativeScriptLifecycleCallbacks_; function initNativeScriptLifecycleCallbacks() { if (NativeScriptLifecycleCallbacks_) { return NativeScriptLifecycleCallbacks_; } var NativeScriptLifecycleCallbacksImpl = /** @class */ (function (_super) { __extends(NativeScriptLifecycleCallbacksImpl, _super); function NativeScriptLifecycleCallbacksImpl() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.activitiesCount = 0; return _this; } NativeScriptLifecycleCallbacksImpl.prototype.onActivityCreated = function (activity, savedInstanceState) { // console.log('NativeScriptLifecycleCallbacks onActivityCreated'); this.setThemeOnLaunch(activity); if (!Application.android.startActivity) { Application.android.setStartActivity(activity); } if (!this.nativescriptActivity && 'isNativeScriptActivity' in activity) { this.nativescriptActivity = activity; } this.notifyActivityCreated(activity, savedInstanceState); if (Application.hasListeners(Application.displayedEvent)) { this.subscribeForGlobalLayout(activity); } }; NativeScriptLifecycleCallbacksImpl.prototype.onActivityDestroyed = function (activity) { // console.log('NativeScriptLifecycleCallbacks onActivityDestroyed'); if (activity === Application.android.foregroundActivity) { Application.android.setForegroundActivity(undefined); } if (activity === this.nativescriptActivity) { this.nativescriptActivity = undefined; } if (activity === Application.android.startActivity) { Application.android.setStartActivity(undefined); // Fallback for start activity when it is destroyed but we have a known nativescript activity if (this.nativescriptActivity) { Application.android.setStartActivity(this.nativescriptActivity); } } Application.android.notify({ eventName: Application.android.activityDestroyedEvent, object: Application.android, activity: activity, }); // TODO: This is a temporary workaround to force the V8's Garbage Collector, which will force the related Java Object to be collected. gc(); }; NativeScriptLifecycleCallbacksImpl.prototype.onActivityPaused = function (activity) { // console.log('NativeScriptLifecycleCallbacks onActivityPaused'); if ('isNativeScriptActivity' in activity) { Application.setSuspended(true, { // todo: deprecate event.android in favor of event.activity android: activity, activity: activity, }); } Application.android.notify({ eventName: Application.android.activityPausedEvent, object: Application.android, activity: activity, }); }; NativeScriptLifecycleCallbacksImpl.prototype.onActivityResumed = function (activity) { // console.log('NativeScriptLifecycleCallbacks onActivityResumed'); Application.android.setForegroundActivity(activity); // NOTE: setSuspended(false) is called in frame/index.android.ts inside onPostResume // This is done to ensure proper timing for the event to be raised Application.android.notify({ eventName: Application.android.activityResumedEvent, object: Application.android, activity: activity, }); }; NativeScriptLifecycleCallbacksImpl.prototype.onActivitySaveInstanceState = function (activity, bundle) { // console.log('NativeScriptLifecycleCallbacks onActivitySaveInstanceState'); Application.android.notify({ eventName: Application.android.saveActivityStateEvent, object: Application.android, activity: activity, bundle: bundle, }); }; NativeScriptLifecycleCallbacksImpl.prototype.onActivityStarted = function (activity) { // console.log('NativeScriptLifecycleCallbacks onActivityStarted'); this.activitiesCount++; if (this.activitiesCount === 1) { Application.android.setInBackground(false, { // todo: deprecate event.android in favor of event.activity android: activity, activity: activity, }); } Application.android.notify({ eventName: Application.android.activityStartedEvent, object: Application.android, activity: activity, }); }; NativeScriptLifecycleCallbacksImpl.prototype.onActivityStopped = function (activity) { // console.log('NativeScriptLifecycleCallbacks onActivityStopped'); this.activitiesCount--; if (this.activitiesCount === 0) { Application.android.setInBackground(true, { // todo: deprecate event.android in favor of event.activity android: activity, activity: activity, }); } Application.android.notify({ eventName: Application.android.activityStoppedEvent, object: Application.android, activity: activity, }); }; NativeScriptLifecycleCallbacksImpl.prototype.setThemeOnLaunch = function (activity) { // Set app theme after launch screen was used during startup var activityInfo = activity.getPackageManager().getActivityInfo(activity.getComponentName(), android.content.pm.PackageManager.GET_META_DATA); if (activityInfo.metaData) { var setThemeOnLaunch = activityInfo.metaData.getInt('SET_THEME_ON_LAUNCH', -1); if (setThemeOnLaunch !== -1) { activity.setTheme(setThemeOnLaunch); } } }; NativeScriptLifecycleCallbacksImpl.prototype.notifyActivityCreated = function (activity, bundle) { Application.android.notify({ eventName: Application.android.activityCreatedEvent, object: Application.android, activity: activity, bundle: bundle, }); }; NativeScriptLifecycleCallbacksImpl.prototype.subscribeForGlobalLayout = function (activity) { var rootView = activity.getWindow().getDecorView().getRootView(); // store the listener not to trigger GC collection before collecting the method global.onGlobalLayoutListener = new android.view.ViewTreeObserver.OnGlobalLayoutListener({ onGlobalLayout: function () { Application.android.notify({ eventName: Application.displayedEvent, object: Application, android: Application.android, activity: activity, }); var viewTreeObserver = rootView.getViewTreeObserver(); viewTreeObserver.removeOnGlobalLayoutListener(global.onGlobalLayoutListener); }, }); rootView.getViewTreeObserver().addOnGlobalLayoutListener(global.onGlobalLayoutListener); }; var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11; __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [typeof (_c = typeof androidx !== "undefined" && (_a = androidx.appcompat) !== void 0 && (_b = _a.app) !== void 0 && _b.AppCompatActivity) === "function" ? _c : Object, typeof (_e = typeof android !== "undefined" && (_d = android.os) !== void 0 && _d.Bundle) === "function" ? _e : Object]), __metadata("design:returntype", void 0) ], NativeScriptLifecycleCallbacksImpl.prototype, "onActivityCreated", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [typeof (_h = typeof androidx !== "undefined" && (_f = androidx.appcompat) !== void 0 && (_g = _f.app) !== void 0 && _g.AppCompatActivity) === "function" ? _h : Object]), __metadata("design:returntype", void 0) ], NativeScriptLifecycleCallbacksImpl.prototype, "onActivityDestroyed", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [typeof (_l = typeof androidx !== "undefined" && (_j = androidx.appcompat) !== void 0 && (_k = _j.app) !== void 0 && _k.AppCompatActivity) === "function" ? _l : Object]), __metadata("design:returntype", void 0) ], NativeScriptLifecycleCallbacksImpl.prototype, "onActivityPaused", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [typeof (_p = typeof androidx !== "undefined" && (_m = androidx.appcompat) !== void 0 && (_o = _m.app) !== void 0 && _o.AppCompatActivity) === "function" ? _p : Object]), __metadata("design:returntype", void 0) ], NativeScriptLifecycleCallbacksImpl.prototype, "onActivityResumed", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [typeof (_s = typeof androidx !== "undefined" && (_q = androidx.appcompat) !== void 0 && (_r = _q.app) !== void 0 && _r.AppCompatActivity) === "function" ? _s : Object, typeof (_u = typeof android !== "undefined" && (_t = android.os) !== void 0 && _t.Bundle) === "function" ? _u : Object]), __metadata("design:returntype", void 0) ], NativeScriptLifecycleCallbacksImpl.prototype, "onActivitySaveInstanceState", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [typeof (_x = typeof androidx !== "undefined" && (_v = androidx.appcompat) !== void 0 && (_w = _v.app) !== void 0 && _w.AppCompatActivity) === "function" ? _x : Object]), __metadata("design:returntype", void 0) ], NativeScriptLifecycleCallbacksImpl.prototype, "onActivityStarted", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [typeof (_0 = typeof androidx !== "undefined" && (_y = androidx.appcompat) !== void 0 && (_z = _y.app) !== void 0 && _z.AppCompatActivity) === "function" ? _0 : Object]), __metadata("design:returntype", void 0) ], NativeScriptLifecycleCallbacksImpl.prototype, "onActivityStopped", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [typeof (_3 = typeof androidx !== "undefined" && (_1 = androidx.appcompat) !== void 0 && (_2 = _1.app) !== void 0 && _2.AppCompatActivity) === "function" ? _3 : Object]), __metadata("design:returntype", void 0) ], NativeScriptLifecycleCallbacksImpl.prototype, "setThemeOnLaunch", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [typeof (_6 = typeof androidx !== "undefined" && (_4 = androidx.appcompat) !== void 0 && (_5 = _4.app) !== void 0 && _5.AppCompatActivity) === "function" ? _6 : Object, typeof (_8 = typeof android !== "undefined" && (_7 = android.os) !== void 0 && _7.Bundle) === "function" ? _8 : Object]), __metadata("design:returntype", void 0) ], NativeScriptLifecycleCallbacksImpl.prototype, "notifyActivityCreated", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [typeof (_11 = typeof androidx !== "undefined" && (_9 = androidx.appcompat) !== void 0 && (_10 = _9.app) !== void 0 && _10.AppCompatActivity) === "function" ? _11 : Object]), __metadata("design:returntype", void 0) ], NativeScriptLifecycleCallbacksImpl.prototype, "subscribeForGlobalLayout", null); NativeScriptLifecycleCallbacksImpl = __decorate([ JavaProxy('org.nativescript.NativeScriptLifecycleCallbacks') ], NativeScriptLifecycleCallbacksImpl); return NativeScriptLifecycleCallbacksImpl; }(android.app.Application.ActivityLifecycleCallbacks)); NativeScriptLifecycleCallbacks_ = NativeScriptLifecycleCallbacksImpl; return NativeScriptLifecycleCallbacks_; } let NativeScriptComponentCallbacks_; function initNativeScriptComponentCallbacks() { if (NativeScriptComponentCallbacks_) { return NativeScriptComponentCallbacks_; } var NativeScriptComponentCallbacksImpl = /** @class */ (function (_super) { __extends(NativeScriptComponentCallbacksImpl, _super); function NativeScriptComponentCallbacksImpl() { return _super !== null && _super.apply(this, arguments) || this; } NativeScriptComponentCallbacksImpl.prototype.onLowMemory = function () { gc(); java.lang.System.gc(); Application.notify({ eventName: Application.lowMemoryEvent, object: Application, android: this, }); }; NativeScriptComponentCallbacksImpl.prototype.onTrimMemory = function (level) { // TODO: This is skipped for now, test carefully for OutOfMemory exceptions }; NativeScriptComponentCallbacksImpl.prototype.onConfigurationChanged = function (newConfiguration) { Application.android.onConfigurationChanged(newConfiguration); }; var _a, _b, _c; __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", void 0) ], NativeScriptComponentCallbacksImpl.prototype, "onLowMemory", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [Number]), __metadata("design:returntype", void 0) ], NativeScriptComponentCallbacksImpl.prototype, "onTrimMemory", null); __decorate([ profile, __metadata("design:type", Function), __metadata("design:paramtypes", [typeof (_c = typeof android !== "undefined" && (_a = android.content) !== void 0 && (_b = _a.res) !== void 0 && _b.Configuration) === "function" ? _c : Object]), __metadata("design:returntype", void 0) ], NativeScriptComponentCallbacksImpl.prototype, "onConfigurationChanged", null); NativeScriptComponentCallbacksImpl = __decorate([ JavaProxy('org.nativescript.NativeScriptComponentCallbacks') ], NativeScriptComponentCallbacksImpl); return NativeScriptComponentCallbacksImpl; }(android.content.ComponentCallbacks2)); NativeScriptComponentCallbacks_ = NativeScriptComponentCallbacksImpl; return NativeScriptComponentCallbacks_; } export class AndroidApplication extends ApplicationCommon { constructor() { super(...arguments); this.activityCreatedEvent = AndroidApplication.activityCreatedEvent; this.activityDestroyedEvent = AndroidApplication.activityDestroyedEvent; this.activityStartedEvent = AndroidApplication.activityStartedEvent; this.activityPausedEvent = AndroidApplication.activityPausedEvent; this.activityResumedEvent = AndroidApplication.activityResumedEvent; this.activityStoppedEvent = AndroidApplication.activityStoppedEvent; this.saveActivityStateEvent = AndroidApplication.saveActivityStateEvent; this.activityResultEvent = AndroidApplication.activityResultEvent; this.activityBackPressedEvent = AndroidApplication.activityBackPressedEvent; this.activityNewIntentEvent = AndroidApplication.activityNewIntentEvent; this.activityRequestPermissionsEvent = AndroidApplication.activityRequestPermissionsEvent; this._registeredReceivers = {}; this._pendingReceiverRegistrations = new Array(); } init(nativeApp) { if (this.nativeApp === nativeApp) { return; } if (this.nativeApp) { throw new Error('Application.android already initialized.'); } this._nativeApp = nativeApp; this._context = nativeApp.getApplicationContext(); this._packageName = nativeApp.getPackageName(); // we store those callbacks and add a function for clearing them later so that the objects will be eligable for GC this.lifecycleCallbacks = new (initNativeScriptLifecycleCallbacks())(); this.nativeApp.registerActivityLifecycleCallbacks(this.lifecycleCallbacks); this.componentCallbacks = new (initNativeScriptComponentCallbacks())(); this.nativeApp.registerComponentCallbacks(this.componentCallbacks); this._registerPendingReceivers(); } _registerPendingReceivers() { this._pendingReceiverRegistrations.forEach((func) => func(this.context)); this._pendingReceiverRegistrations.length = 0; } onConfigurationChanged(configuration) { this.setOrientation(this.getOrientationValue(configuration)); this.setSystemAppearance(this.getSystemAppearanceValue(configuration)); } getNativeApplication() { let nativeApp = this.nativeApp; if (nativeApp) { return nativeApp; } // Try getting it from module - check whether application.android.init has been explicitly called // check whether the com.tns.NativeScriptApplication type exists if (com.tns.NativeScriptApplication) { nativeApp = com.tns.NativeScriptApplication.getInstance(); } if (!nativeApp && isEmbedded()) { nativeApp = com.tns.embedding.ApplicationHolder.getInstance(); } // the getInstance might return null if com.tns.NativeScriptApplication exists but is not the starting app type if (!nativeApp) { // TODO: Should we handle the case when a custom application type is provided and the user has not explicitly initialized the application module? const clazz = java.lang.Class.forName('android.app.ActivityThread'); if (clazz) { const method = clazz.getMethod('currentApplication', null); if (method) { nativeApp = method.invoke(null, null); } } } // we cannot work without having the app instance if (!nativeApp) { throw new Error("Failed to retrieve native Android Application object. If you have a custom android.app.Application type implemented make sure that you've called the 'Application.android.init' method."); } return nativeApp; } get nativeApp() { return this._nativeApp; } run(entry) { if (this.started) { throw new Error('Application is already started.'); } this.started = true; this.mainEntry = typeof entry === 'string' ? { moduleName: entry } : entry; if (!this.nativeApp) { const nativeApp = this.getNativeApplication(); this.init(nativeApp); } } get startActivity() { return this._startActivity; } get foregroundActivity() { return this._foregroundActivity; } setStartActivity(value) { this._startActivity = value; } setForegroundActivity(value) { this._foregroundActivity = value; } get paused() { return this.suspended; } get backgrounded() { return this.inBackground; } get context() { return this._context; } get packageName() { return this._packageName; } // Possible flags are: // RECEIVER_EXPORTED (2) // RECEIVER_NOT_EXPORTED (4) // RECEIVER_VISIBLE_TO_INSTANT_APPS (1) registerBroadcastReceiver(intentFilter, onReceiveCallback, flags = 2) { const registerFunc = (context) => { const receiver = new (initBroadcastReceiver())(onReceiveCallback); if (SDK_VERSION >= 26) { context.registerReceiver(receiver, new android.content.IntentFilter(intentFilter), flags); } else { context.registerReceiver(receiver, new android.content.IntentFilter(intentFilter)); } this._registeredReceivers[intentFilter] = receiver; }; if (this.context) { registerFunc(this.context); } else { this._pendingReceiverRegistrations.push(registerFunc); } } unregisterBroadcastReceiver(intentFilter) { const receiver = this._registeredReceivers[intentFilter]; if (receiver) { this.context.unregisterReceiver(receiver); this._registeredReceivers[intentFilter] = undefined; delete this._registeredReceivers[intentFilter]; } } getRegisteredBroadcastReceiver(intentFilter) { return this._registeredReceivers[intentFilter]; } getRootView() { const activity = this.foregroundActivity || this.startActivity; if (!activity) { return undefined; } const callbacks = activity['_callbacks']; return callbacks ? callbacks.getRootView() : undefined; } resetRootView(entry) { super.resetRootView(entry); const activity = this.foregroundActivity || this.startActivity; if (!activity) { throw new Error('Cannot find android activity.'); } // this.mainEntry = typeof entry === 'string' ? { moduleName: entry } : entry; const callbacks = activity['_callbacks']; if (!callbacks) { throw new Error('Cannot find android activity callbacks.'); } callbacks.resetActivityContent(activity); } getSystemAppearance() { const resources = this.context.getResources(); const configuration = resources.getConfiguration(); return this.getSystemAppearanceValue(configuration); } // https://developer.android.com/guide/topics/ui/look-and-feel/darktheme#configuration_changes getSystemAppearanceValue(configuration) { const systemAppearance = configuration.uiMode & android.content.res.Configuration.UI_MODE_NIGHT_MASK; switch (systemAppearance) { case android.content.res.Configuration.UI_MODE_NIGHT_YES: return 'dark'; case android.content.res.Configuration.UI_MODE_NIGHT_NO: case android.content.res.Configuration.UI_MODE_NIGHT_UNDEFINED: return 'light'; } } getOrientation() { const resources = this.context.getResources(); const configuration = resources.getConfiguration(); return this.getOrientationValue(configuration); } getOrientationValue(configuration) { const orientation = configuration.orientation; switch (orientation) { case android.content.res.Configuration.ORIENTATION_LANDSCAPE: return 'landscape'; case android.content.res.Configuration.ORIENTATION_PORTRAIT: return 'portrait'; default: return 'unknown'; } } get android() { // ensures Application.android is defined when running on Android return this; } } AndroidApplication.activityCreatedEvent = 'activityCreated'; AndroidApplication.activityDestroyedEvent = 'activityDestroyed'; AndroidApplication.activityStartedEvent = 'activityStarted'; AndroidApplication.activityPausedEvent = 'activityPaused'; AndroidApplication.activityResumedEvent = 'activityResumed'; AndroidApplication.activityStoppedEvent = 'activityStopped'; AndroidApplication.saveActivityStateEvent = 'saveActivityState'; AndroidApplication.activityResultEvent = 'activityResult'; AndroidApplication.activityBackPressedEvent = 'activityBackPressed'; AndroidApplication.activityNewIntentEvent = 'activityNewIntent'; AndroidApplication.activityRequestPermissionsEvent = 'activityRequestPermissions'; export * from './application-common'; export const Application = new AndroidApplication(); export const iOSApplication = undefined; //# sourceMappingURL=application.android.js.map