1 /* 2 * Copyright (C) 2019 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 package com.android.launcher3.testing; 17 18 import static android.graphics.Bitmap.Config.ARGB_8888; 19 20 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; 21 22 import android.content.Context; 23 import android.graphics.Bitmap; 24 import android.graphics.Color; 25 import android.os.Bundle; 26 import android.os.Debug; 27 28 import com.android.launcher3.DeviceProfile; 29 import com.android.launcher3.InvariantDeviceProfile; 30 import com.android.launcher3.Launcher; 31 import com.android.launcher3.LauncherAppState; 32 import com.android.launcher3.LauncherModel; 33 import com.android.launcher3.LauncherState; 34 import com.android.launcher3.R; 35 import com.android.launcher3.allapps.AllAppsStore; 36 import com.android.launcher3.util.ResourceBasedOverride; 37 38 import java.util.LinkedList; 39 import java.util.concurrent.ExecutionException; 40 41 public class TestInformationHandler implements ResourceBasedOverride { 42 newInstance(Context context)43 public static TestInformationHandler newInstance(Context context) { 44 return Overrides.getObject(TestInformationHandler.class, 45 context, R.string.test_information_handler_class); 46 } 47 48 protected Context mContext; 49 protected DeviceProfile mDeviceProfile; 50 protected LauncherAppState mLauncherAppState; 51 protected Launcher mLauncher; 52 private static LinkedList mLeaks; 53 init(Context context)54 public void init(Context context) { 55 mContext = context; 56 mDeviceProfile = InvariantDeviceProfile.INSTANCE. 57 get(context).getDeviceProfile(context); 58 mLauncherAppState = LauncherAppState.getInstanceNoCreate(); 59 mLauncher = mLauncherAppState != null ? 60 (Launcher) mLauncherAppState.getModel().getCallback() : null; 61 } 62 call(String method)63 public Bundle call(String method) { 64 final Bundle response = new Bundle(); 65 switch (method) { 66 case TestProtocol.REQUEST_ALL_APPS_TO_OVERVIEW_SWIPE_HEIGHT: { 67 if (mLauncher == null) return null; 68 69 final float progress = LauncherState.OVERVIEW.getVerticalProgress(mLauncher) 70 - LauncherState.ALL_APPS.getVerticalProgress(mLauncher); 71 final float distance = mLauncher.getAllAppsController().getShiftRange() * progress; 72 response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) distance); 73 break; 74 } 75 76 case TestProtocol.REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT: { 77 if (mLauncher == null) return null; 78 79 final float progress = LauncherState.NORMAL.getVerticalProgress(mLauncher) 80 - LauncherState.ALL_APPS.getVerticalProgress(mLauncher); 81 final float distance = mLauncher.getAllAppsController().getShiftRange() * progress; 82 response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) distance); 83 break; 84 } 85 86 case TestProtocol.REQUEST_IS_LAUNCHER_INITIALIZED: { 87 response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, isLauncherInitialized()); 88 break; 89 } 90 91 case TestProtocol.REQUEST_ENABLE_DEBUG_TRACING: 92 TestProtocol.sDebugTracing = true; 93 break; 94 95 case TestProtocol.REQUEST_DISABLE_DEBUG_TRACING: 96 TestProtocol.sDebugTracing = false; 97 break; 98 99 case TestProtocol.REQUEST_FREEZE_APP_LIST: 100 MAIN_EXECUTOR.execute(() -> 101 mLauncher.getAppsView().getAppsStore().enableDeferUpdates( 102 AllAppsStore.DEFER_UPDATES_TEST)); 103 break; 104 105 case TestProtocol.REQUEST_UNFREEZE_APP_LIST: 106 MAIN_EXECUTOR.execute(() -> 107 mLauncher.getAppsView().getAppsStore().disableDeferUpdates( 108 AllAppsStore.DEFER_UPDATES_TEST)); 109 break; 110 111 case TestProtocol.REQUEST_APP_LIST_FREEZE_FLAGS: { 112 try { 113 final int deferUpdatesFlags = MAIN_EXECUTOR.submit(() -> 114 mLauncher.getAppsView().getAppsStore().getDeferUpdatesFlags()).get(); 115 response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, 116 deferUpdatesFlags); 117 } catch (ExecutionException e) { 118 throw new RuntimeException(e); 119 } catch (InterruptedException e) { 120 throw new RuntimeException(e); 121 } 122 break; 123 } 124 125 case TestProtocol.REQUEST_TOTAL_PSS_KB: { 126 Debug.MemoryInfo mem = new Debug.MemoryInfo(); 127 Debug.getMemoryInfo(mem); 128 response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, mem.getTotalPss()); 129 break; 130 } 131 132 case TestProtocol.REQUEST_JAVA_LEAK: { 133 if (mLeaks == null) mLeaks = new LinkedList(); 134 135 // Allocate and dirty the memory. 136 final int leakSize = 1024 * 1024; 137 final byte[] bytes = new byte[leakSize]; 138 for (int i = 0; i < leakSize; i += 239) { 139 bytes[i] = (byte) (i % 256); 140 } 141 mLeaks.add(bytes); 142 break; 143 } 144 145 case TestProtocol.REQUEST_NATIVE_LEAK: { 146 if (mLeaks == null) mLeaks = new LinkedList(); 147 148 // Allocate and dirty a bitmap. 149 final Bitmap bitmap = Bitmap.createBitmap(512, 512, ARGB_8888); 150 bitmap.eraseColor(Color.RED); 151 mLeaks.add(bitmap); 152 break; 153 } 154 155 case TestProtocol.REQUEST_ICON_HEIGHT: { 156 response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, 157 mDeviceProfile.allAppsCellHeightPx); 158 break; 159 } 160 } 161 return response; 162 } 163 isLauncherInitialized()164 protected boolean isLauncherInitialized() { 165 final LauncherModel model = LauncherAppState.getInstance(mContext).getModel(); 166 return model.getCallback() == null || model.isModelLoaded(); 167 } 168 } 169 170