Skip to content

Commit

Permalink
Location delegation (#366)
Browse files Browse the repository at this point in the history
* Add enableLocation for enabling location delegation

Co-authored-by: Ella Ge <eirage@chromium.org>
  • Loading branch information
chenlevy24 and EiraGe authored Oct 19, 2020
1 parent 218e807 commit 0837fd2
Show file tree
Hide file tree
Showing 11 changed files with 358 additions and 232 deletions.
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 %>
<% } %>
}
}

0 comments on commit 0837fd2

Please sign in to comment.