Loading quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java +18 −4 Original line number Diff line number Diff line Loading @@ -161,8 +161,7 @@ public class QuickstepModelDelegate extends ModelDelegate { } InstanceId instanceId = new InstanceIdSequence().newInstanceId(); for (ItemInfo info : itemsIdMap) { FolderInfo parent = info.container > 0 ? (FolderInfo) itemsIdMap.get(info.container) : null; FolderInfo parent = getContainer(info, itemsIdMap); StatsLogCompatManager.writeSnapshot(info.buildProto(parent), instanceId); } additionalSnapshotEvents(instanceId); Loading Loading @@ -199,8 +198,7 @@ public class QuickstepModelDelegate extends ModelDelegate { } for (ItemInfo info : itemsIdMap) { FolderInfo parent = info.container > 0 ? (FolderInfo) itemsIdMap.get(info.container) : null; FolderInfo parent = getContainer(info, itemsIdMap); LauncherAtom.ItemInfo itemInfo = info.buildProto(parent); Log.d(TAG, itemInfo.toString()); StatsEvent statsEvent = StatsLogCompatManager.buildStatsEvent(itemInfo, Loading @@ -222,6 +220,22 @@ public class QuickstepModelDelegate extends ModelDelegate { } } private static FolderInfo getContainer(ItemInfo info, IntSparseArrayMap<ItemInfo> itemsIdMap) { if (info.container > 0) { ItemInfo containerInfo = itemsIdMap.get(info.container); if (!(containerInfo instanceof FolderInfo)) { Log.e(TAG, String.format( "Item info: %s found with invalid container: %s", info, containerInfo)); } else { return (FolderInfo) containerInfo; } } return null; } @Override public void validateData() { super.validateData(); Loading src/com/android/launcher3/model/BgDataModel.java +15 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; import androidx.annotation.Nullable; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.Workspace; Loading Loading @@ -215,6 +217,19 @@ public class BgDataModel { } public synchronized void addItem(Context context, ItemInfo item, boolean newItem) { addItem(context, item, newItem, null); } public synchronized void addItem( Context context, ItemInfo item, boolean newItem, @Nullable LoaderMemoryLogger logger) { if (logger != null) { logger.addLog( Log.DEBUG, TAG, String.format("Adding item to ID map: %s", item.toString()), /* stackTrace= */ null); } itemsIdMap.put(item.id, item); switch (item.itemType) { case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: Loading src/com/android/launcher3/model/LoaderCursor.java +7 −2 Original line number Diff line number Diff line Loading @@ -383,18 +383,23 @@ public class LoaderCursor extends CursorWrapper { info.cellY = getInt(cellYIndex); } public void checkAndAddItem(ItemInfo info, BgDataModel dataModel) { checkAndAddItem(info, dataModel, null); } /** * Adds the {@param info} to {@param dataModel} if it does not overlap with any other item, * otherwise marks it for deletion. */ public void checkAndAddItem(ItemInfo info, BgDataModel dataModel) { public void checkAndAddItem( ItemInfo info, BgDataModel dataModel, LoaderMemoryLogger logger) { if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { // Ensure that it is a valid intent. An exception here will // cause the item loading to get skipped ShortcutKey.fromItemInfo(info); } if (checkItemPlacement(info)) { dataModel.addItem(mContext, info, false); dataModel.addItem(mContext, info, false, logger); } else { markDeleted("Item position overlap"); } Loading src/com/android/launcher3/model/LoaderMemoryLogger.java 0 → 100644 +91 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * 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. */ package com.android.launcher3.model; import android.util.Log; import androidx.annotation.Nullable; import java.util.ArrayList; /** * Helper logger that collects logs while {@code LoaderTask#run} executes and prints them all iff * an exception is caught in {@code LoaderTask#run}. */ public class LoaderMemoryLogger { private static final String TAG = "LoaderMemoryLogger"; private final ArrayList<LogEntry> mLogEntries = new ArrayList<>(); protected LoaderMemoryLogger() {} protected void addLog(int logLevel, String tag, String log) { addLog(logLevel, tag, log, null); } protected void addLog( int logLevel, String tag, String log, Exception stackTrace) { switch (logLevel) { case Log.ASSERT: case Log.ERROR: case Log.DEBUG: case Log.INFO: case Log.VERBOSE: case Log.WARN: mLogEntries.add(new LogEntry(logLevel, tag, log, stackTrace)); break; default: throw new IllegalArgumentException("Invalid log level provided: " + logLevel); } } protected void clearLogs() { mLogEntries.clear(); } protected void printLogs() { for (LogEntry logEntry : mLogEntries) { String tag = String.format("%s: %s", TAG, logEntry.mLogTag); String logString = logEntry.mStackStrace == null ? logEntry.mLogString : String.format( "%s\n%s", logEntry.mLogString, Log.getStackTraceString(logEntry.mStackStrace)); Log.println(logEntry.mLogLevel, tag, logString); } clearLogs(); } private static class LogEntry { protected final int mLogLevel; protected final String mLogTag; protected final String mLogString; @Nullable protected final Exception mStackStrace; protected LogEntry( int logLevel, String logTag, String logString, @Nullable Exception stackStrace) { mLogLevel = logLevel; mLogTag = logTag; mLogString = logString; mStackStrace = stackStrace; } } } src/com/android/launcher3/model/LoaderTask.java +22 −7 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ import android.util.Log; import android.util.LongSparseArray; import android.util.TimingLogger; import androidx.annotation.Nullable; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; Loading Loading @@ -197,11 +199,12 @@ public class LoaderTask implements Runnable { Object traceToken = TraceHelper.INSTANCE.beginSection(TAG); TimingLogger logger = new TimingLogger(TAG, "run"); LoaderMemoryLogger memoryLogger = new LoaderMemoryLogger(); try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) { List<ShortcutInfo> allShortcuts = new ArrayList<>(); Trace.beginSection("LoadWorkspace"); try { loadWorkspace(allShortcuts); loadWorkspace(allShortcuts, memoryLogger); } finally { Trace.endSection(); } Loading Loading @@ -311,9 +314,13 @@ public class LoaderTask implements Runnable { mModelDelegate.modelLoadComplete(); transaction.commit(); memoryLogger.clearLogs(); } catch (CancellationException e) { // Loader stopped, ignore logASplit(logger, "Cancelled"); } catch (Exception e) { memoryLogger.printLogs(); throw e; } finally { logger.dumpToLog(); } Loading @@ -325,13 +332,21 @@ public class LoaderTask implements Runnable { this.notify(); } private void loadWorkspace(List<ShortcutInfo> allDeepShortcuts) { private void loadWorkspace(List<ShortcutInfo> allDeepShortcuts, LoaderMemoryLogger logger) { loadWorkspace(allDeepShortcuts, LauncherSettings.Favorites.CONTENT_URI, null /* selection */); null /* selection */, logger); } protected void loadWorkspace( List<ShortcutInfo> allDeepShortcuts, Uri contentUri, String selection) { loadWorkspace(allDeepShortcuts, contentUri, selection, null); } protected void loadWorkspace(List<ShortcutInfo> allDeepShortcuts, Uri contentUri, String selection) { protected void loadWorkspace( List<ShortcutInfo> allDeepShortcuts, Uri contentUri, String selection, @Nullable LoaderMemoryLogger logger) { final Context context = mApp.getContext(); final ContentResolver contentResolver = context.getContentResolver(); final PackageManagerHelper pmHelper = new PackageManagerHelper(context); Loading Loading @@ -635,7 +650,7 @@ public class LoaderTask implements Runnable { } } c.checkAndAddItem(info, mBgDataModel); c.checkAndAddItem(info, mBgDataModel, logger); } else { throw new RuntimeException("Unexpected null WorkspaceItemInfo"); } Loading @@ -654,7 +669,7 @@ public class LoaderTask implements Runnable { // no special handling required for restored folders c.markRestored(); c.checkAndAddItem(folderInfo, mBgDataModel); c.checkAndAddItem(folderInfo, mBgDataModel, logger); break; case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: Loading Loading
quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java +18 −4 Original line number Diff line number Diff line Loading @@ -161,8 +161,7 @@ public class QuickstepModelDelegate extends ModelDelegate { } InstanceId instanceId = new InstanceIdSequence().newInstanceId(); for (ItemInfo info : itemsIdMap) { FolderInfo parent = info.container > 0 ? (FolderInfo) itemsIdMap.get(info.container) : null; FolderInfo parent = getContainer(info, itemsIdMap); StatsLogCompatManager.writeSnapshot(info.buildProto(parent), instanceId); } additionalSnapshotEvents(instanceId); Loading Loading @@ -199,8 +198,7 @@ public class QuickstepModelDelegate extends ModelDelegate { } for (ItemInfo info : itemsIdMap) { FolderInfo parent = info.container > 0 ? (FolderInfo) itemsIdMap.get(info.container) : null; FolderInfo parent = getContainer(info, itemsIdMap); LauncherAtom.ItemInfo itemInfo = info.buildProto(parent); Log.d(TAG, itemInfo.toString()); StatsEvent statsEvent = StatsLogCompatManager.buildStatsEvent(itemInfo, Loading @@ -222,6 +220,22 @@ public class QuickstepModelDelegate extends ModelDelegate { } } private static FolderInfo getContainer(ItemInfo info, IntSparseArrayMap<ItemInfo> itemsIdMap) { if (info.container > 0) { ItemInfo containerInfo = itemsIdMap.get(info.container); if (!(containerInfo instanceof FolderInfo)) { Log.e(TAG, String.format( "Item info: %s found with invalid container: %s", info, containerInfo)); } else { return (FolderInfo) containerInfo; } } return null; } @Override public void validateData() { super.validateData(); Loading
src/com/android/launcher3/model/BgDataModel.java +15 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; import androidx.annotation.Nullable; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.Workspace; Loading Loading @@ -215,6 +217,19 @@ public class BgDataModel { } public synchronized void addItem(Context context, ItemInfo item, boolean newItem) { addItem(context, item, newItem, null); } public synchronized void addItem( Context context, ItemInfo item, boolean newItem, @Nullable LoaderMemoryLogger logger) { if (logger != null) { logger.addLog( Log.DEBUG, TAG, String.format("Adding item to ID map: %s", item.toString()), /* stackTrace= */ null); } itemsIdMap.put(item.id, item); switch (item.itemType) { case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: Loading
src/com/android/launcher3/model/LoaderCursor.java +7 −2 Original line number Diff line number Diff line Loading @@ -383,18 +383,23 @@ public class LoaderCursor extends CursorWrapper { info.cellY = getInt(cellYIndex); } public void checkAndAddItem(ItemInfo info, BgDataModel dataModel) { checkAndAddItem(info, dataModel, null); } /** * Adds the {@param info} to {@param dataModel} if it does not overlap with any other item, * otherwise marks it for deletion. */ public void checkAndAddItem(ItemInfo info, BgDataModel dataModel) { public void checkAndAddItem( ItemInfo info, BgDataModel dataModel, LoaderMemoryLogger logger) { if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { // Ensure that it is a valid intent. An exception here will // cause the item loading to get skipped ShortcutKey.fromItemInfo(info); } if (checkItemPlacement(info)) { dataModel.addItem(mContext, info, false); dataModel.addItem(mContext, info, false, logger); } else { markDeleted("Item position overlap"); } Loading
src/com/android/launcher3/model/LoaderMemoryLogger.java 0 → 100644 +91 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * 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. */ package com.android.launcher3.model; import android.util.Log; import androidx.annotation.Nullable; import java.util.ArrayList; /** * Helper logger that collects logs while {@code LoaderTask#run} executes and prints them all iff * an exception is caught in {@code LoaderTask#run}. */ public class LoaderMemoryLogger { private static final String TAG = "LoaderMemoryLogger"; private final ArrayList<LogEntry> mLogEntries = new ArrayList<>(); protected LoaderMemoryLogger() {} protected void addLog(int logLevel, String tag, String log) { addLog(logLevel, tag, log, null); } protected void addLog( int logLevel, String tag, String log, Exception stackTrace) { switch (logLevel) { case Log.ASSERT: case Log.ERROR: case Log.DEBUG: case Log.INFO: case Log.VERBOSE: case Log.WARN: mLogEntries.add(new LogEntry(logLevel, tag, log, stackTrace)); break; default: throw new IllegalArgumentException("Invalid log level provided: " + logLevel); } } protected void clearLogs() { mLogEntries.clear(); } protected void printLogs() { for (LogEntry logEntry : mLogEntries) { String tag = String.format("%s: %s", TAG, logEntry.mLogTag); String logString = logEntry.mStackStrace == null ? logEntry.mLogString : String.format( "%s\n%s", logEntry.mLogString, Log.getStackTraceString(logEntry.mStackStrace)); Log.println(logEntry.mLogLevel, tag, logString); } clearLogs(); } private static class LogEntry { protected final int mLogLevel; protected final String mLogTag; protected final String mLogString; @Nullable protected final Exception mStackStrace; protected LogEntry( int logLevel, String logTag, String logString, @Nullable Exception stackStrace) { mLogLevel = logLevel; mLogTag = logTag; mLogString = logString; mStackStrace = stackStrace; } } }
src/com/android/launcher3/model/LoaderTask.java +22 −7 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ import android.util.Log; import android.util.LongSparseArray; import android.util.TimingLogger; import androidx.annotation.Nullable; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; Loading Loading @@ -197,11 +199,12 @@ public class LoaderTask implements Runnable { Object traceToken = TraceHelper.INSTANCE.beginSection(TAG); TimingLogger logger = new TimingLogger(TAG, "run"); LoaderMemoryLogger memoryLogger = new LoaderMemoryLogger(); try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) { List<ShortcutInfo> allShortcuts = new ArrayList<>(); Trace.beginSection("LoadWorkspace"); try { loadWorkspace(allShortcuts); loadWorkspace(allShortcuts, memoryLogger); } finally { Trace.endSection(); } Loading Loading @@ -311,9 +314,13 @@ public class LoaderTask implements Runnable { mModelDelegate.modelLoadComplete(); transaction.commit(); memoryLogger.clearLogs(); } catch (CancellationException e) { // Loader stopped, ignore logASplit(logger, "Cancelled"); } catch (Exception e) { memoryLogger.printLogs(); throw e; } finally { logger.dumpToLog(); } Loading @@ -325,13 +332,21 @@ public class LoaderTask implements Runnable { this.notify(); } private void loadWorkspace(List<ShortcutInfo> allDeepShortcuts) { private void loadWorkspace(List<ShortcutInfo> allDeepShortcuts, LoaderMemoryLogger logger) { loadWorkspace(allDeepShortcuts, LauncherSettings.Favorites.CONTENT_URI, null /* selection */); null /* selection */, logger); } protected void loadWorkspace( List<ShortcutInfo> allDeepShortcuts, Uri contentUri, String selection) { loadWorkspace(allDeepShortcuts, contentUri, selection, null); } protected void loadWorkspace(List<ShortcutInfo> allDeepShortcuts, Uri contentUri, String selection) { protected void loadWorkspace( List<ShortcutInfo> allDeepShortcuts, Uri contentUri, String selection, @Nullable LoaderMemoryLogger logger) { final Context context = mApp.getContext(); final ContentResolver contentResolver = context.getContentResolver(); final PackageManagerHelper pmHelper = new PackageManagerHelper(context); Loading Loading @@ -635,7 +650,7 @@ public class LoaderTask implements Runnable { } } c.checkAndAddItem(info, mBgDataModel); c.checkAndAddItem(info, mBgDataModel, logger); } else { throw new RuntimeException("Unexpected null WorkspaceItemInfo"); } Loading @@ -654,7 +669,7 @@ public class LoaderTask implements Runnable { // no special handling required for restored folders c.markRestored(); c.checkAndAddItem(folderInfo, mBgDataModel); c.checkAndAddItem(folderInfo, mBgDataModel, logger); break; case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: Loading