Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Location delegation #366

Merged
merged 11 commits into from
Oct 19, 2020
451 changes: 229 additions & 222 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"lerna": "^3.22.1",
"lerna-changelog": "^1.0.1",
"mock-fs": "^4.12.0",
"npm": "^6.14.5",
"npm": "^6.14.8",
"ts-node": "^8.10.2",
"typescript": "^3.9.7"
},
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/lib/TwaGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const JAVA_DIR = 'app/src/main/java/';
const JAVA_FILE_LIST = [
'LauncherActivity.java',
'Application.java',
'DelegationService.java',
];

const DELETE_PROJECT_FILE_LIST = [
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/lib/TwaManifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {ConsoleLog} from './Log';
import {WebManifestIcon, WebManifestJson} from './types/WebManifest';
import {ShortcutInfo} from './ShortcutInfo';
import {AppsFlyerConfig} from './features/AppsFlyerFeature';
import {LocationDelegationConfig} from './features/LocationDelegationFeature';
import {FirstRunFlagConfig} from './features/FirstRunFlagFeature';

// The minimum size needed for the app icon.
Expand Down Expand Up @@ -57,12 +58,14 @@ const DEFAULT_APP_VERSION_NAME = DEFAULT_APP_VERSION_CODE.toString();
const DEFAULT_SIGNING_KEY_PATH = './android.keystore';
const DEFAULT_SIGNING_KEY_ALIAS = 'android';
const DEFAULT_ENABLE_NOTIFICATIONS = false;
const DEFAULT_ENABLE_LOCATION = false;
const DEFAULT_GENERATOR_APP_NAME = 'unknown';

export type FallbackType = 'customtabs' | 'webview';

type Features = {
appsFlyer?: AppsFlyerConfig;
locationDelegation?: LocationDelegationConfig;
firstRunFlag?: FirstRunFlagConfig;
}

Expand Down Expand Up @@ -289,6 +292,9 @@ export class TwaManifest {
enableNotifications: DEFAULT_ENABLE_NOTIFICATIONS,
shortcuts: shortcuts,
webManifestUrl: webManifestUrl.toString(),
features: {
locationDelegation: {enabled: DEFAULT_ENABLE_LOCATION},
},
});
return twaManifest;
}
Expand Down Expand Up @@ -460,6 +466,7 @@ export interface TwaManifestJson {
fallbackType?: FallbackType;
features?: {
appsFlyer?: AppsFlyerConfig;
locationDelegation?: LocationDelegationConfig;
firstRunFlag?: FirstRunFlagConfig;
};
alphaDependencies?: {
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/lib/features/EmptyFeature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ export class EmptyFeature implements Feature {
methods: new Array<string>(),
};

delegationService: {
imports: string[];
classConstructor?: string;
} = {
imports: new Array<string>(),
};

constructor(name: string) {
this.name = name;
}
Expand Down
15 changes: 15 additions & 0 deletions packages/core/src/lib/features/Feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,19 @@ export interface Feature {
*/
launchUrl?: string;
};
/**
* Customizations to be added to `app/src/main/java/<app-package>/DelegationService.java`.
*/
delegationService: {
/**
* Imports to be added. Only the class name must be added. Example:
* `android.net.Uri`
*/
imports: string[];
/**
* Code segment to be added to the constructor. The code will be called
* by each plugin.
*/
classConstructor?: string;
};
}
27 changes: 19 additions & 8 deletions packages/core/src/lib/features/FeatureManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import {Feature} from './Feature';
import {AppsFlyerFeature} from './AppsFlyerFeature';
import {LocationDelegationFeature} from './LocationDelegationFeature';
import {TwaManifest} from '../TwaManifest';
import {FirstRunFlagFeature} from './FirstRunFlagFeature';

Expand Down Expand Up @@ -43,16 +44,24 @@ export class FeatureManager {
variables: new Set<string>(),
launchUrl: new Array<string>(),
};
delegationService = {
imports: new Set<string>(),
classConstructor: new Array<string>(),
};

/**
* Builds a new intance from a TwaManifest.
*/
constructor(twaManifest: TwaManifest) {
if (twaManifest.features.appsFlyer && twaManifest.features.appsFlyer.enabled) {
if (twaManifest.features.locationDelegation?.enabled) {
this.addFeature(new LocationDelegationFeature());
}

if (twaManifest.features.appsFlyer?.enabled) {
this.addFeature(new AppsFlyerFeature(twaManifest.features.appsFlyer));
}

if (twaManifest.features.firstRunFlag && twaManifest.features.firstRunFlag.enabled) {
if (twaManifest.features.firstRunFlag?.enabled) {
this.addFeature(new FirstRunFlagFeature(twaManifest.features.firstRunFlag));
}

Expand All @@ -61,7 +70,7 @@ export class FeatureManager {
this.androidManifest.permissions.add('android.permission.INTERNET');
}

if (twaManifest.alphaDependencies && twaManifest.alphaDependencies.enabled) {
if (twaManifest.alphaDependencies?.enabled) {
this.buildGradle.dependencies.add(
'com.google.androidbrowserhelper:androidbrowserhelper:1.4.0-alpha01');
} else {
Expand All @@ -84,11 +93,9 @@ export class FeatureManager {
feature.applicationClass.imports.forEach((imp) => {
this.applicationClass.imports.add(imp);
});

feature.applicationClass.variables.forEach((imp) => {
this.applicationClass.variables.push(imp);
});

if (feature.applicationClass.onCreate) {
this.applicationClass.onCreate.push(feature.applicationClass.onCreate);
}
Expand All @@ -106,17 +113,21 @@ export class FeatureManager {
feature.launcherActivity.imports.forEach((imp) => {
this.launcherActivity.imports.add(imp);
});

feature.launcherActivity.variables.forEach((imp) => {
this.launcherActivity.variables.add(imp);
});

feature.launcherActivity.methods.forEach((imp) => {
this.launcherActivity.methods.add(imp);
});

if (feature.launcherActivity?.launchUrl) {
if (feature.launcherActivity.launchUrl) {
this.launcherActivity.launchUrl.push(feature.launcherActivity.launchUrl);
}
feature.delegationService.imports.forEach((imp) => {
this.delegationService.imports.add(imp);
});
if (feature.delegationService?.classConstructor) {
this.delegationService.classConstructor.push(feature.delegationService.classConstructor);
}
}
}
36 changes: 36 additions & 0 deletions packages/core/src/lib/features/LocationDelegationFeature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2020 Google Inc. All Rights Reserved.
*
* 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 {EmptyFeature} from './EmptyFeature';

export type LocationDelegationConfig = {
enabled: boolean;
}

export class LocationDelegationFeature extends EmptyFeature {
constructor() {
super('locationDelegation');
this.buildGradle.dependencies.push('com.google.androidbrowserhelper:locationdelegation:1.0.0');

this.androidManifest.components.push(`<activity android:name=
"com.google.androidbrowserhelper.locationdelegation.PermissionRequestActivity"/>`);

this.delegationService.imports.push('com.google.androidbrowserhelper.locationdelegation' +
'.LocationDelegationExtraCommandHandler');
this.delegationService.classConstructor =
'registerExtraCommandHandler(new LocationDelegationExtraCommandHandler());';
}
}
27 changes: 27 additions & 0 deletions packages/core/src/spec/lib/features/FeatureManagerSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import {FeatureManager} from '../../../lib/features/FeatureManager';
import {AppsFlyerConfig, AppsFlyerFeature} from '../../../lib/features/AppsFlyerFeature';
import {LocationDelegationFeature} from '../../../lib/features/LocationDelegationFeature';
import {FirstRunFlagConfig, FirstRunFlagFeature} from '../../../lib/features/FirstRunFlagFeature';
import {TwaManifest} from '../../../lib/TwaManifest';
import {Feature} from '../../../lib/features/Feature';
Expand Down Expand Up @@ -77,6 +78,7 @@ describe('FeatureManager', () => {
expect(features.buildGradle.repositories).toEqual(emptySet);
expect(features.launcherActivity.imports).toEqual(emptySet);
expect(features.launcherActivity.launchUrl).toEqual([]);
expect(features.delegationService.classConstructor).toEqual([]);
});

it('Creates from empty features with alpha features enabled', () => {
Expand Down Expand Up @@ -125,5 +127,30 @@ describe('FeatureManager', () => {
expectFeatureToBeApplied(features, appsFlyerFeature);
expectFeatureToBeApplied(features, firstRunFlagFeature);
});


it('Enables the LocationDelegation feature', () => {
const manifest = {
features: {
locationDelegation: {
enabled: true,
},
},
} as TwaManifest;

const locationDelegationFeature = new LocationDelegationFeature();
const features = new FeatureManager(manifest);

locationDelegationFeature.androidManifest.components.forEach((component) => {
expect(features.androidManifest.components).toContain(component);
});

locationDelegationFeature.delegationService.imports.forEach((imp) => {
expect(features.delegationService.imports).toContain(imp);
});

expect(features.delegationService.classConstructor!)
.toContain(locationDelegationFeature.delegationService.classConstructor!);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
</provider>

<service
android:name="com.google.androidbrowserhelper.trusted.DelegationService"
android:name=".DelegationService"
android:enabled="@bool/enableNotification"
android:exported="@bool/enableNotification">

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package <%= packageId %>;

<% for(const imp of delegationService.imports) { %>
import <%= imp %>;
<% } %>

public class DelegationService extends
com.google.androidbrowserhelper.trusted.DelegationService {
public DelegationService() {
<% for(const code of delegationService.constructor) { %>
<%= code %>
<% } %>
}
}