1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.layoutlib.bridge.remote.server; 18 19 import com.android.ide.common.rendering.api.DrawableParams; 20 import com.android.ide.common.rendering.api.RenderParams; 21 import com.android.ide.common.rendering.api.Result; 22 import com.android.ide.common.rendering.api.SessionParams; 23 import com.android.layout.remote.api.RemoteBridge; 24 import com.android.layout.remote.api.RemoteDrawableParams; 25 import com.android.layout.remote.api.RemoteLayoutLog; 26 import com.android.layout.remote.api.RemoteRenderParams; 27 import com.android.layout.remote.api.RemoteRenderSession; 28 import com.android.layout.remote.api.RemoteSessionParams; 29 import com.android.layoutlib.bridge.Bridge; 30 import com.android.layoutlib.bridge.remote.server.adapters.RemoteAssetRepositoryAdapter; 31 import com.android.layoutlib.bridge.remote.server.adapters.RemoteILayoutPullParserAdapter; 32 import com.android.layoutlib.bridge.remote.server.adapters.RemoteLayoutLogAdapter; 33 import com.android.layoutlib.bridge.remote.server.adapters.RemoteLayoutlibCallbackAdapter; 34 import com.android.layoutlib.bridge.remote.server.adapters.RemoteRenderResourcesAdapter; 35 import com.android.layoutlib.bridge.remote.server.adapters.RemoteRenderSessionAdapter; 36 import com.android.tools.layoutlib.annotations.NotNull; 37 38 import java.io.File; 39 import java.rmi.RemoteException; 40 import java.util.HashMap; 41 import java.util.HashSet; 42 import java.util.Map; 43 import java.util.Set; 44 45 /** 46 * Remote {@link Bridge} implementation. This class is the remote entry point for the server. Its 47 * responsibility is to receive the remote calls and apply the required transformations to convert 48 * it into a regular call to the {@link Bridge} class. 49 */ 50 public class RemoteBridgeImpl implements RemoteBridge { 51 private Bridge mBridge = new Bridge(); 52 53 /** 54 * The project keys are used as key for some caches. They are usually expected to remain in 55 * memory so WeakReferences are used in the caches. 56 * Because in the remote bridge we do not have a real pointer to the object, we keep the strings 57 * in memory until they are cleared. 58 */ 59 private Map<String, String> mCachedProjectKeys = new HashMap<>(); 60 61 @Override init(Map<String, String> platformProperties, File fontLocation, String nativeLibPath, String icuDataPath, Map<String, Map<String, Integer>> enumValueMap, RemoteLayoutLog log)62 public boolean init(Map<String, String> platformProperties, File fontLocation, 63 String nativeLibPath, String icuDataPath, 64 Map<String, Map<String, Integer>> enumValueMap, RemoteLayoutLog log) { 65 return mBridge.init(platformProperties, fontLocation, nativeLibPath, icuDataPath, 66 enumValueMap, log != null ? new RemoteLayoutLogAdapter(log) : null); 67 } 68 69 @Override dispose()70 public boolean dispose() { 71 return mBridge.dispose(); 72 } 73 setupRenderParams(@otNull RenderParams params, @NotNull RemoteRenderParams remoteParams)74 private static void setupRenderParams(@NotNull RenderParams params, 75 @NotNull RemoteRenderParams remoteParams) throws RemoteException { 76 params.setAssetRepository(new RemoteAssetRepositoryAdapter(remoteParams.getAssets())); 77 params.setActivityName(remoteParams.getActivityName()); 78 params.setAppIcon(remoteParams.getAppIcon()); 79 params.setAppLabel(remoteParams.getAppLabel()); 80 params.setTimeout(remoteParams.getTimeout()); 81 params.setLocale(remoteParams.getLocale()); 82 if (remoteParams.isForceNoDecor()) { 83 params.setForceNoDecor(); 84 } 85 params.setRtlSupport(remoteParams.isRtlSupported()); 86 if (remoteParams.isTransparentBackground()) { 87 params.setTransparentBackground(); 88 } 89 params.setImageFactory(remoteParams.getImageFactory()); 90 // TODO: Also unpack remote flags and pass them to RenderParams 91 } 92 93 @NotNull 94 @Override createSession(@otNull RemoteSessionParams remoteParams)95 public RemoteRenderSession createSession(@NotNull RemoteSessionParams remoteParams) { 96 try { 97 String projectKey = mCachedProjectKeys.putIfAbsent(remoteParams.getProjectKey(), 98 remoteParams.getProjectKey()); 99 100 // Unpack the remote params and convert it into the local SessionParams. 101 SessionParams params = new SessionParams( 102 new RemoteILayoutPullParserAdapter(remoteParams.getLayoutDescription()), 103 remoteParams.getRenderingMode(), projectKey, 104 remoteParams.getRemoteHardwareConfig().getHardwareConfig(), 105 new RemoteRenderResourcesAdapter(remoteParams.getRemoteResources()), 106 new RemoteLayoutlibCallbackAdapter(remoteParams.getRemoteLayoutlibCallback()), 107 remoteParams.getMinSdkVersion(), remoteParams.getTargetSdkVersion(), 108 new RemoteLayoutLogAdapter(remoteParams.getLog())); 109 setupRenderParams(params, remoteParams); 110 return RemoteRenderSessionAdapter.create(mBridge.createSession(params)); 111 112 } catch (RemoteException e) { 113 throw new RuntimeException(e); 114 } 115 } 116 117 @NotNull 118 @Override renderDrawable(@otNull RemoteDrawableParams remoteParams)119 public Result renderDrawable(@NotNull RemoteDrawableParams remoteParams) { 120 try { 121 String projectKey = mCachedProjectKeys.putIfAbsent(remoteParams.getProjectKey(), 122 remoteParams.getProjectKey()); 123 124 DrawableParams params = new DrawableParams( 125 remoteParams.getDrawable(), 126 projectKey, 127 remoteParams.getRemoteHardwareConfig().getHardwareConfig(), 128 new RemoteRenderResourcesAdapter(remoteParams.getRemoteResources()), 129 new RemoteLayoutlibCallbackAdapter(remoteParams.getRemoteLayoutlibCallback()), 130 remoteParams.getMinSdkVersion(), remoteParams.getTargetSdkVersion(), 131 new RemoteLayoutLogAdapter(remoteParams.getLog())); 132 setupRenderParams(params, remoteParams); 133 return mBridge.renderDrawable(params); 134 } catch (RemoteException e) { 135 throw new RuntimeException(e); 136 } 137 } 138 139 @Override clearResourceCaches(String projectKey)140 public void clearResourceCaches(String projectKey) { 141 mCachedProjectKeys.remove(projectKey); 142 mBridge.clearResourceCaches(projectKey); 143 } 144 145 @Override isRtl(String locale)146 public boolean isRtl(String locale) { 147 return mBridge.isRtl(locale); 148 } 149 } 150