blob: ef99fc4452e45954dd61f11b0550579c13af2ab3 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.weblayer_private;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.content.FileProvider;
import android.webkit.ValueCallback;
import org.chromium.base.BuildInfo;
import org.chromium.base.CommandLine;
import org.chromium.base.ContentUriUtils;
import org.chromium.base.ContextUtils;
import org.chromium.base.PathUtils;
import org.chromium.base.annotations.UsedByReflection;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.components.embedder_support.application.ClassLoaderContextWrapperFactory;
import org.chromium.content_public.browser.BrowserStartupController;
import org.chromium.content_public.browser.ChildProcessCreationParams;
import org.chromium.content_public.browser.DeviceUtils;
import org.chromium.ui.base.ResourceBundle;
import org.chromium.weblayer_private.aidl.IBrowserFragment;
import org.chromium.weblayer_private.aidl.IObjectWrapper;
import org.chromium.weblayer_private.aidl.IRemoteFragmentClient;
import org.chromium.weblayer_private.aidl.IWebLayer;
import org.chromium.weblayer_private.aidl.ObjectWrapper;
import org.chromium.weblayer_private.aidl.WebLayerVersion;
import java.io.File;
@UsedByReflection("WebLayer")
public final class WebLayerImpl extends IWebLayer.Stub {
// TODO: should there be one tag for all this code?
private static final String TAG = "WebLayer";
private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "weblayer";
// TODO: Configure this from the client.
private static final String COMMAND_LINE_FILE = "/data/local/tmp/weblayer-command-line";
private final ProfileManager mProfileManager = new ProfileManager();
private static class FileProviderHelper implements ContentUriUtils.FileProviderUtil {
// Keep this variable in sync with the value defined in AndroidManifest.xml.
private static final String API_AUTHORITY_SUFFIX =
".org.chromium.weblayer.client.FileProvider";
@Override
public Uri getContentUriFromFile(File file) {
Context appContext = ContextUtils.getApplicationContext();
return FileProvider.getUriForFile(
appContext, appContext.getPackageName() + API_AUTHORITY_SUFFIX, file);
}
}
@UsedByReflection("WebLayer")
public static IBinder create() {
return new WebLayerImpl();
}
private WebLayerImpl() {}
/**
* Returns true if the client and implementation versions are compatible.
*/
@UsedByReflection("WebLayer")
public static boolean checkVersion(int clientVersion) {
return clientVersion == WebLayerVersion.sVersionNumber;
}
@Override
public void initAndLoadAsync(IObjectWrapper appContextWrapper,
IObjectWrapper packageInfoWrapper, IObjectWrapper loadedCallbackWrapper,
int resourcesPackageId) {
// TODO: The call to onResourcesLoaded() can be slow, we may need to parallelize this with
// other expensive startup tasks.
R.onResourcesLoaded(resourcesPackageId);
// Wrap the app context so that it can be used to load WebLayer implementation classes.
Context appContext = ClassLoaderContextWrapperFactory.get(
ObjectWrapper.unwrap(appContextWrapper, Context.class));
PackageInfo packageInfo = ObjectWrapper.unwrap(packageInfoWrapper, PackageInfo.class);
ContextUtils.initApplicationContext(appContext);
BuildInfo.setBrowserPackageInfo(packageInfo);
ResourceBundle.setAvailablePakLocales(new String[] {}, LocaleConfig.UNCOMPRESSED_LOCALES);
PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX);
ChildProcessCreationParams.set(appContext.getPackageName(), false /* isExternalService */,
LibraryProcessType.PROCESS_WEBLAYER_CHILD, true /* bindToCaller */,
false /* ignoreVisibilityForImportance */,
"org.chromium.weblayer.ChildProcessService$Privileged",
"org.chromium.weblayer.ChildProcessService$Sandboxed");
if (!CommandLine.isInitialized()) {
CommandLine.initFromFile(COMMAND_LINE_FILE);
}
DeviceUtils.addDeviceSpecificUserAgentSwitch();
ContentUriUtils.setFileProviderUtil(new FileProviderHelper());
LibraryLoader.getInstance().ensureInitialized(LibraryProcessType.PROCESS_WEBLAYER);
GmsBridge.getInstance().setSafeBrowsingHandler();
final ValueCallback<Boolean> loadedCallback = (ValueCallback<Boolean>) ObjectWrapper.unwrap(
loadedCallbackWrapper, ValueCallback.class);
BrowserStartupController.get(LibraryProcessType.PROCESS_WEBLAYER)
.startBrowserProcessesAsync(/* startGpu */ false,
/* startServiceManagerOnly */ false,
new BrowserStartupController.StartupCallback() {
@Override
public void onSuccess() {
loadedCallback.onReceiveValue(true);
}
@Override
public void onFailure() {
loadedCallback.onReceiveValue(false);
}
});
}
@Override
public void loadSync() {
BrowserStartupController.get(LibraryProcessType.PROCESS_WEBLAYER)
.startBrowserProcessesSync(
/* singleProcess*/ false);
}
@Override
public IBrowserFragment createBrowserFragmentImpl(IRemoteFragmentClient fragmentClient,
IObjectWrapper fragmentArgs) {
Bundle unwrappedArgs = ObjectWrapper.unwrap(fragmentArgs, Bundle.class);
BrowserFragmentImpl fragment = new BrowserFragmentImpl(mProfileManager, fragmentClient,
unwrappedArgs);
return fragment.asIBrowserFragment();
}
}