diff options
168 files changed, 1828 insertions, 14969 deletions
diff --git a/ProtoLibraries.bp b/ProtoLibraries.bp index 7e3cc2739cd0..d18154a761ec 100644 --- a/ProtoLibraries.bp +++ b/ProtoLibraries.bp @@ -33,6 +33,7 @@ gensrcs { "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)", srcs: [ + ":framework-connectivity-protos", ":ipconnectivity-proto-src", ":libstats_atom_enum_protos", ":libstats_atom_message_protos", @@ -63,6 +64,7 @@ gensrcs { " $(in)", srcs: [ + ":framework-connectivity-protos", ":ipconnectivity-proto-src", ":libstats_atom_enum_protos", ":libstats_atom_message_protos", @@ -78,6 +80,7 @@ gensrcs { java_library_host { name: "platformprotos", srcs: [ + ":framework-connectivity-protos", ":ipconnectivity-proto-src", ":libstats_atom_enum_protos", ":libstats_atom_message_protos", @@ -117,6 +120,7 @@ java_library { ], sdk_version: "9", srcs: [ + ":framework-connectivity-protos", ":ipconnectivity-proto-src", ":libstats_atom_enum_protos", ":libstats_atom_message_protos", @@ -135,6 +139,7 @@ java_library { }, srcs: [ + ":framework-connectivity-protos", ":ipconnectivity-proto-src", ":libstats_atom_enum_protos", ":libstats_atom_message_protos", @@ -172,6 +177,7 @@ cc_defaults { ], srcs: [ + ":framework-connectivity-protos", ":ipconnectivity-proto-src", ":libstats_atom_enum_protos", ":libstats_atom_message_protos", diff --git a/core/api/current.txt b/core/api/current.txt index 4036c988f3e5..a09a3597dab8 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -42283,7 +42283,8 @@ package android.telephony.euicc { method public boolean isEnabled(); method public boolean isSimPortAvailable(int); method public void startResolutionActivity(android.app.Activity, int, android.content.Intent, android.app.PendingIntent) throws android.content.IntentSender.SendIntentException; - method @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void switchToSubscription(int, android.app.PendingIntent); + method @Deprecated @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void switchToSubscription(int, android.app.PendingIntent); + method @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void switchToSubscription(int, int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.euicc.EuiccManager.ResultListener); method @RequiresPermission("android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS") public void updateSubscriptionNickname(int, @Nullable String, @NonNull android.app.PendingIntent); field public static final String ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS = "android.telephony.euicc.action.MANAGE_EMBEDDED_SUBSCRIPTIONS"; field public static final String ACTION_NOTIFY_CARRIER_SETUP_INCOMPLETE = "android.telephony.euicc.action.NOTIFY_CARRIER_SETUP_INCOMPLETE"; @@ -42329,6 +42330,10 @@ package android.telephony.euicc { field public static final int OPERATION_SYSTEM = 1; // 0x1 } + public static interface EuiccManager.ResultListener { + method public void onComplete(int, @Nullable android.content.Intent); + } + } package android.telephony.gsm { diff --git a/core/api/system-current.txt b/core/api/system-current.txt index cbfd86e5478f..d5be20f326ba 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -9641,7 +9641,8 @@ package android.service.euicc { method @android.telephony.euicc.EuiccManager.OtaStatus public abstract int onGetOtaStatus(int); method public abstract int onRetainSubscriptionsForFactoryReset(int); method public abstract void onStartOtaIfNecessary(int, android.service.euicc.EuiccService.OtaStatusChangedCallback); - method public abstract int onSwitchToSubscription(int, @Nullable String, boolean); + method @Deprecated public abstract int onSwitchToSubscription(int, @Nullable String, boolean); + method public int onSwitchToSubscriptionWithPort(int, int, @Nullable String, boolean); method public abstract int onUpdateSubscriptionNickname(int, String, String); field public static final String ACTION_BIND_CARRIER_PROVISIONING_SERVICE = "android.service.euicc.action.BIND_CARRIER_PROVISIONING_SERVICE"; field public static final String ACTION_DELETE_SUBSCRIPTION_PRIVILEGED = "android.service.euicc.action.DELETE_SUBSCRIPTION_PRIVILEGED"; @@ -9663,6 +9664,7 @@ package android.service.euicc { field public static final String EXTRA_RESOLUTION_CONFIRMATION_CODE = "android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE"; field public static final String EXTRA_RESOLUTION_CONFIRMATION_CODE_RETRIED = "android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE_RETRIED"; field public static final String EXTRA_RESOLUTION_CONSENT = "android.service.euicc.extra.RESOLUTION_CONSENT"; + field public static final String EXTRA_RESOLUTION_PORT_INDEX = "android.service.euicc.extra.RESOLUTION_PORT_INDEX"; field public static final String EXTRA_RESOLVABLE_ERRORS = "android.service.euicc.extra.RESOLVABLE_ERRORS"; field public static final int RESOLVABLE_ERROR_CONFIRMATION_CODE = 1; // 0x1 field public static final int RESOLVABLE_ERROR_POLICY_RULES = 2; // 0x2 @@ -11661,10 +11663,14 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoiceActivationState(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmi(String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handlePinMmiForSubscriber(int, String); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean iccCloseLogicalChannelBySlot(int, int); - method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(int, @Nullable String, int); - method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelBySlot(int, int, int, int, int, int, @Nullable String); - method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void iccCloseLogicalChannelByPort(int, int, int); + method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean iccCloseLogicalChannelBySlot(int, int); + method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannelByPort(int, int, @Nullable String, int); + method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(int, @Nullable String, int); + method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelByPort(int, int, int, int, int, int, int, @Nullable String); + method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduBasicChannelBySlot(int, int, int, int, int, int, @Nullable String); + method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelByPort(int, int, int, int, int, int, int, int, @Nullable String); + method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public String iccTransmitApduLogicalChannelBySlot(int, int, int, int, int, int, int, @Nullable String); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAnyRadioPoweredOn(); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApnMetered(int); method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isApplicationOnUicc(int); diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java index ab741990430f..82d4443ea724 100644 --- a/core/java/android/os/SystemProperties.java +++ b/core/java/android/os/SystemProperties.java @@ -218,14 +218,15 @@ public class SystemProperties { /** * Set the value for the given {@code key} to {@code val}. * - * @throws IllegalArgumentException if the {@code val} exceeds 91 characters + * @throws IllegalArgumentException for non read-only properties if the {@code val} exceeds + * 91 characters * @throws RuntimeException if the property cannot be set, for example, if it was blocked by * SELinux. libc will log the underlying reason. * @hide */ @UnsupportedAppUsage public static void set(@NonNull String key, @Nullable String val) { - if (val != null && !val.startsWith("ro.") && val.length() > PROP_VALUE_MAX) { + if (val != null && !key.startsWith("ro.") && val.length() > PROP_VALUE_MAX) { throw new IllegalArgumentException("value of system property '" + key + "' is longer than " + PROP_VALUE_MAX + " characters: " + val); } diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 6dd878cbfe95..134cfa12b0ee 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -286,28 +286,7 @@ public class StorageManager { /** @hide The volume is not encrypted. */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static final int ENCRYPTION_STATE_NONE = - IVold.ENCRYPTION_STATE_NONE; - - /** @hide The volume has been encrypted succesfully. */ - public static final int ENCRYPTION_STATE_OK = - IVold.ENCRYPTION_STATE_OK; - - /** @hide The volume is in a bad state. */ - public static final int ENCRYPTION_STATE_ERROR_UNKNOWN = - IVold.ENCRYPTION_STATE_ERROR_UNKNOWN; - - /** @hide Encryption is incomplete */ - public static final int ENCRYPTION_STATE_ERROR_INCOMPLETE = - IVold.ENCRYPTION_STATE_ERROR_INCOMPLETE; - - /** @hide Encryption is incomplete and irrecoverable */ - public static final int ENCRYPTION_STATE_ERROR_INCONSISTENT = - IVold.ENCRYPTION_STATE_ERROR_INCONSISTENT; - - /** @hide Underlying data is corrupt */ - public static final int ENCRYPTION_STATE_ERROR_CORRUPT = - IVold.ENCRYPTION_STATE_ERROR_CORRUPT; + public static final int ENCRYPTION_STATE_NONE = 1; private static volatile IStorageManager sStorageManager = null; @@ -2893,15 +2872,10 @@ public class StorageManager { @GuardedBy("mFuseAppLoopLock") private @Nullable FuseAppLoop mFuseAppLoop = null; - /// Consts to match the password types in cryptfs.h /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static final int CRYPT_TYPE_PASSWORD = IVold.PASSWORD_TYPE_PASSWORD; + public static final int CRYPT_TYPE_PASSWORD = 0; /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - public static final int CRYPT_TYPE_DEFAULT = IVold.PASSWORD_TYPE_DEFAULT; - /** @hide */ - public static final int CRYPT_TYPE_PATTERN = IVold.PASSWORD_TYPE_PATTERN; - /** @hide */ - public static final int CRYPT_TYPE_PIN = IVold.PASSWORD_TYPE_PIN; + public static final int CRYPT_TYPE_DEFAULT = 1; } diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index 542de3fad8b0..0d8b1f83b7fe 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -27,6 +27,7 @@ import android.os.Binder; import android.os.Build; import android.os.RemoteException; import android.os.ServiceManager; +import android.service.carrier.CarrierService; import android.telephony.Annotation.CallState; import android.telephony.Annotation.DataActivityType; import android.telephony.Annotation.DisconnectCauses; @@ -36,6 +37,7 @@ import android.telephony.Annotation.PreciseDisconnectCauses; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SimActivationState; import android.telephony.Annotation.SrvccState; +import android.telephony.TelephonyManager.CarrierPrivilegesCallback; import android.telephony.TelephonyManager.CarrierPrivilegesListener; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; @@ -44,17 +46,19 @@ import android.util.Log; import com.android.internal.annotations.GuardedBy; import com.android.internal.listeners.ListenerExecutor; -import com.android.internal.telephony.ICarrierPrivilegesListener; +import com.android.internal.telephony.ICarrierPrivilegesCallback; import com.android.internal.telephony.IOnSubscriptionsChangedListener; import com.android.internal.telephony.ITelephonyRegistry; import java.lang.ref.WeakReference; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.Executor; +import java.util.stream.Collectors; /** * A centralized place to notify telephony related status changes, e.g, {@link ServiceState} update @@ -1258,34 +1262,78 @@ public class TelephonyRegistryManager { pkgName, attributionTag, callback, new int[0], notifyNow); } - private static class CarrierPrivilegesListenerWrapper extends ICarrierPrivilegesListener.Stub + // TODO(b/216549778): Remove listener logic once all clients switch to CarrierPrivilegesCallback + private static class CarrierPrivilegesCallbackWrapper extends ICarrierPrivilegesCallback.Stub implements ListenerExecutor { - private final WeakReference<CarrierPrivilegesListener> mListener; - private final Executor mExecutor; + // Either mListener or mCallback may be null, never both + @Nullable private final WeakReference<CarrierPrivilegesListener> mListener; + @Nullable private final WeakReference<CarrierPrivilegesCallback> mCallback; + @NonNull private final Executor mExecutor; + + CarrierPrivilegesCallbackWrapper( + @NonNull CarrierPrivilegesCallback callback, @NonNull Executor executor) { + mListener = null; + mCallback = new WeakReference<>(callback); + mExecutor = executor; + } - CarrierPrivilegesListenerWrapper(CarrierPrivilegesListener listener, Executor executor) { + CarrierPrivilegesCallbackWrapper( + @NonNull CarrierPrivilegesListener listener, @NonNull Executor executor) { mListener = new WeakReference<>(listener); + mCallback = null; mExecutor = executor; } @Override public void onCarrierPrivilegesChanged( - List<String> privilegedPackageNames, int[] privilegedUids) { - Binder.withCleanCallingIdentity( - () -> - executeSafely( - mExecutor, - mListener::get, - cpl -> - cpl.onCarrierPrivilegesChanged( - privilegedPackageNames, privilegedUids))); + @NonNull List<String> privilegedPackageNames, @NonNull int[] privilegedUids) { + if (mListener != null) { + Binder.withCleanCallingIdentity( + () -> + executeSafely( + mExecutor, + mListener::get, + cpl -> + cpl.onCarrierPrivilegesChanged( + privilegedPackageNames, privilegedUids))); + } + + if (mCallback != null) { + // AIDL interface does not support Set, keep the List/Array and translate them here + Set<String> privilegedPkgNamesSet = Set.copyOf(privilegedPackageNames); + Set<Integer> privilegedUidsSet = Arrays.stream(privilegedUids).boxed().collect( + Collectors.toSet()); + Binder.withCleanCallingIdentity( + () -> + executeSafely( + mExecutor, + mCallback::get, + cpc -> + cpc.onCarrierPrivilegesChanged( + privilegedPkgNamesSet, privilegedUidsSet))); + } + } + + @Override + public void onCarrierServiceChanged(@Nullable String packageName, int uid) { + if (mCallback != null) { + Binder.withCleanCallingIdentity( + () -> + executeSafely( + mExecutor, + mCallback::get, + cpc -> cpc.onCarrierServiceChanged(packageName, uid))); + } } } - @GuardedBy("sCarrierPrivilegeListeners") - private static final WeakHashMap< - CarrierPrivilegesListener, WeakReference<CarrierPrivilegesListenerWrapper>> - sCarrierPrivilegeListeners = new WeakHashMap<>(); + // TODO(b/216549778): Change the map key to CarrierPrivilegesCallback once all clients switch to + // CarrierPrivilegesCallback. Before that, the key is either CarrierPrivilegesCallback or + // CarrierPrivilegesListener, no logic actually depends on the type. + @NonNull + @GuardedBy("sCarrierPrivilegeCallbacks") + private static final WeakHashMap<Object, WeakReference<CarrierPrivilegesCallbackWrapper>> + sCarrierPrivilegeCallbacks = new WeakHashMap<>(); /** * Registers a {@link CarrierPrivilegesListener} on the given {@code logicalSlotIndex} to @@ -1295,7 +1343,11 @@ public class TelephonyRegistryManager { * @param logicalSlotIndex The SIM slot to listen on * @param executor The executor where {@code listener} will be invoked * @param listener The callback to register + * + * @deprecated Use {@link #addCarrierPrivilegesCallback} instead. This API will be removed + * prior to API finalization. */ + @Deprecated public void addCarrierPrivilegesListener( int logicalSlotIndex, @NonNull @CallbackExecutor Executor executor, @@ -1303,18 +1355,18 @@ public class TelephonyRegistryManager { if (listener == null || executor == null) { throw new IllegalArgumentException("listener and executor must be non-null"); } - synchronized (sCarrierPrivilegeListeners) { - WeakReference<CarrierPrivilegesListenerWrapper> existing = - sCarrierPrivilegeListeners.get(listener); + synchronized (sCarrierPrivilegeCallbacks) { + WeakReference<CarrierPrivilegesCallbackWrapper> existing = + sCarrierPrivilegeCallbacks.get(listener); if (existing != null && existing.get() != null) { Log.d(TAG, "addCarrierPrivilegesListener: listener already registered"); return; } - CarrierPrivilegesListenerWrapper wrapper = - new CarrierPrivilegesListenerWrapper(listener, executor); - sCarrierPrivilegeListeners.put(listener, new WeakReference<>(wrapper)); + CarrierPrivilegesCallbackWrapper wrapper = + new CarrierPrivilegesCallbackWrapper(listener, executor); + sCarrierPrivilegeCallbacks.put(listener, new WeakReference<>(wrapper)); try { - sRegistry.addCarrierPrivilegesListener( + sRegistry.addCarrierPrivilegesCallback( logicalSlotIndex, wrapper, mContext.getOpPackageName(), @@ -1329,19 +1381,84 @@ public class TelephonyRegistryManager { * Unregisters a {@link CarrierPrivilegesListener}. * * @param listener The callback to unregister + * + * @deprecated Use {@link #removeCarrierPrivilegesCallback} instead. The callback will prior + * to API finalization. */ + @Deprecated public void removeCarrierPrivilegesListener(@NonNull CarrierPrivilegesListener listener) { if (listener == null) { throw new IllegalArgumentException("listener must be non-null"); } - synchronized (sCarrierPrivilegeListeners) { - WeakReference<CarrierPrivilegesListenerWrapper> ref = - sCarrierPrivilegeListeners.remove(listener); + synchronized (sCarrierPrivilegeCallbacks) { + WeakReference<CarrierPrivilegesCallbackWrapper> ref = + sCarrierPrivilegeCallbacks.remove(listener); if (ref == null) return; - CarrierPrivilegesListenerWrapper wrapper = ref.get(); + CarrierPrivilegesCallbackWrapper wrapper = ref.get(); if (wrapper == null) return; try { - sRegistry.removeCarrierPrivilegesListener(wrapper, mContext.getOpPackageName()); + sRegistry.removeCarrierPrivilegesCallback(wrapper, mContext.getOpPackageName()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Registers a {@link CarrierPrivilegesCallback} on the given {@code logicalSlotIndex} to + * receive callbacks when the set of packages with carrier privileges changes. The callback will + * immediately be called with the latest state. + * + * @param logicalSlotIndex The SIM slot to listen on + * @param executor The executor where {@code listener} will be invoked + * @param callback The callback to register + */ + public void addCarrierPrivilegesCallback( + int logicalSlotIndex, + @NonNull @CallbackExecutor Executor executor, + @NonNull CarrierPrivilegesCallback callback) { + if (callback == null || executor == null) { + throw new IllegalArgumentException("callback and executor must be non-null"); + } + synchronized (sCarrierPrivilegeCallbacks) { + WeakReference<CarrierPrivilegesCallbackWrapper> existing = + sCarrierPrivilegeCallbacks.get(callback); + if (existing != null && existing.get() != null) { + Log.d(TAG, "addCarrierPrivilegesCallback: callback already registered"); + return; + } + CarrierPrivilegesCallbackWrapper wrapper = + new CarrierPrivilegesCallbackWrapper(callback, executor); + sCarrierPrivilegeCallbacks.put(callback, new WeakReference<>(wrapper)); + try { + sRegistry.addCarrierPrivilegesCallback( + logicalSlotIndex, + wrapper, + mContext.getOpPackageName(), + mContext.getAttributionTag()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + /** + * Unregisters a {@link CarrierPrivilegesCallback}. + * + * @param callback The callback to unregister + */ + public void removeCarrierPrivilegesCallback(@NonNull CarrierPrivilegesCallback callback) { + if (callback == null) { + throw new IllegalArgumentException("listener must be non-null"); + } + synchronized (sCarrierPrivilegeCallbacks) { + WeakReference<CarrierPrivilegesCallbackWrapper> ref = + sCarrierPrivilegeCallbacks.remove(callback); + if (ref == null) return; + CarrierPrivilegesCallbackWrapper wrapper = ref.get(); + if (wrapper == null) return; + try { + sRegistry.removeCarrierPrivilegesCallback(wrapper, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1357,15 +1474,33 @@ public class TelephonyRegistryManager { */ public void notifyCarrierPrivilegesChanged( int logicalSlotIndex, - @NonNull List<String> privilegedPackageNames, - @NonNull int[] privilegedUids) { + @NonNull Set<String> privilegedPackageNames, + @NonNull Set<Integer> privilegedUids) { if (privilegedPackageNames == null || privilegedUids == null) { throw new IllegalArgumentException( "privilegedPackageNames and privilegedUids must be non-null"); } try { - sRegistry.notifyCarrierPrivilegesChanged( - logicalSlotIndex, privilegedPackageNames, privilegedUids); + // AIDL doesn't support Set yet. Convert Set to List/Array + List<String> pkgList = List.copyOf(privilegedPackageNames); + int[] uids = privilegedUids.stream().mapToInt(Number::intValue).toArray(); + sRegistry.notifyCarrierPrivilegesChanged(logicalSlotIndex, pkgList, uids); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Notify listeners that the {@link CarrierService} for current user has changed. + * + * @param logicalSlotIndex the SIM slot the change occurred on + * @param packageName the package name of the changed {@link CarrierService} + * @param uid the UID of the changed {@link CarrierService} + */ + public void notifyCarrierServiceChanged(int logicalSlotIndex, @Nullable String packageName, + int uid) { + try { + sRegistry.notifyCarrierServiceChanged(logicalSlotIndex, packageName, uid); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 9cb0d1ff2c3f..a06b0e0355d8 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -741,35 +741,42 @@ public final class Display { } /** - * Gets the size of the display, in pixels. - * Value returned by this method does not necessarily represent the actual raw size - * (native resolution) of the display. - * <p> - * 1. The returned size may be adjusted to exclude certain system decor elements - * that are always visible. - * </p><p> - * 2. It may be scaled to provide compatibility with older applications that - * were originally designed for smaller displays. - * </p><p> - * 3. It can be different depending on the WindowManager to which the display belongs. - * </p><p> - * - If requested from non-Activity context (e.g. Application context via - * {@code (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE)}) - * it will report the size of the entire display based on current rotation and with subtracted - * system decoration areas. - * </p><p> - * - If requested from activity (either using {@code getWindowManager()} or - * {@code (WindowManager) getSystemService(Context.WINDOW_SERVICE)}) resulting size will - * correspond to current app window size. In this case it can be smaller than physical size in - * multi-window mode. - * </p><p> - * Typically for the purposes of layout apps should make a request from activity context - * to obtain size available for the app content. - * </p> + * Gets the size of the display in pixels. + * + * <p>The return value does not necessarily represent the actual size (native resolution) of the + * display. The returned size might be adjusted to exclude certain system decor elements that + * are always visible, or the size might be scaled to provide compatibility with older + * applications that were originally designed for smaller displays. + * + * <p>The returned size can also be different depending on the WindowManager bound to the + * display: + * <ul> + * <li>If size is requested from an activity (either using a WindowManager accessed by + * {@code getWindowManager()} or {@code getSystemService(Context.WINDOW_SERVICE)}), the + * size of the current app window is returned. As a result, in multi-window mode, the + * returned size can be smaller than the size of the device screen. + * <li>If size is requested from a non-activity context (for example, the application + * context, where the WindowManager is accessed by + * {@code getApplicationContext().getSystemService(Context.WINDOW_SERVICE)}), the + * returned size can vary depending on API level: + * <ul> + * <li>API level 29 and below — The size of the entire display (based on + * current rotation) minus system decoration areas is returned. + * <li>API level 30 and above — The size of the top running activity in the + * current process is returned. If the current process has no running + * activities, the size of the device default display, including system + * decoration areas, is returned. + * </ul> + * </ul> + * + * <p>For layout purposes, apps should make a request from an activity context to obtain the + * size of the display area available for app content. + * + * @param outSize A {@link Point} object which receives the display size information. * - * @param outSize A {@link Point} object to receive the size information. - * @deprecated Use {@link WindowManager#getCurrentWindowMetrics()} to obtain an instance of - * {@link WindowMetrics} and use {@link WindowMetrics#getBounds()} instead. + * @deprecated Use {@link WindowMetrics} instead. Obtain a {@code WindowMetrics} instance by + * calling {@link WindowManager#getCurrentWindowMetrics()}, then call + * {@link WindowMetrics#getBounds()} to get the dimensions of the application window. */ @Deprecated public void getSize(Point outSize) { @@ -785,8 +792,9 @@ public final class Display { * Gets the size of the display as a rectangle, in pixels. * * @param outSize A {@link Rect} object to receive the size information. + * * @deprecated Use {@link WindowMetrics#getBounds()} to get the dimensions of the application - * window area. + * window. */ @Deprecated public void getRectSize(Rect outSize) { @@ -1275,32 +1283,39 @@ public final class Display { } /** - * Gets display metrics that describe the size and density of this display. - * The size returned by this method does not necessarily represent the - * actual raw size (native resolution) of the display. - * <p> - * 1. The returned size may be adjusted to exclude certain system decor elements - * that are always visible. - * </p><p> - * 2. It may be scaled to provide compatibility with older applications that - * were originally designed for smaller displays. - * </p><p> - * 3. It can be different depending on the WindowManager to which the display belongs. - * </p><p> - * - If requested from non-Activity context (e.g. Application context via - * {@code (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE)}) - * metrics will report the size of the entire display based on current rotation and with - * subtracted system decoration areas. - * </p><p> - * - If requested from activity (either using {@code getWindowManager()} or - * {@code (WindowManager) getSystemService(Context.WINDOW_SERVICE)}) resulting metrics will - * correspond to current app window metrics. In this case the size can be smaller than physical - * size in multi-window mode. - * </p> + * Gets the size and density of this display. + * + * <p>The size returned does not necessarily represent the actual size (native resolution) of + * the display. The returned size might be adjusted to exclude certain system decor elements + * that are always visible, or the size might be scaled to provide compatibility with older + * applications that were originally designed for smaller displays. + * + * <p>The returned size can also be different depending on the WindowManager associated with the + * display: + * <ul> + * <li>If metrics are requested from an activity (either using a WindowManager accessed by + * {@code getWindowManager()} or {@code getSystemService(Context.WINDOW_SERVICE)}), the + * returned metrics provide the size of the current app window. As a result, in + * multi-window mode, the returned size can be smaller than the size of the device + * screen. + * <li>If metrics are requested from a non-activity context (for example, the application + * context, where the WindowManager is accessed by + * {@code getApplicationContext().getSystemService(Context.WINDOW_SERVICE)}), the + * returned size can vary depending on API level: + * <ul> + * <li>API level 29 and below — The returned metrics provide the size of the + * entire display (based on current rotation) minus system decoration areas. + * <li>API level 30 and above — The returned metrics provide the size of the + * top running activity in the current process. If the current process has no + * running activities, the metrics provide the size of the default display of + * the device, including system decoration areas. + * </ul> + * </ul> + * + * @param outMetrics A {@link DisplayMetrics} object which receives the display metrics. * - * @param outMetrics A {@link DisplayMetrics} object to receive the metrics. * @deprecated Use {@link WindowMetrics#getBounds()} to get the dimensions of the application - * window area, and {@link Configuration#densityDpi} to get the current density. + * window. Use {@link Configuration#densityDpi} to get the display density. */ @Deprecated public void getMetrics(DisplayMetrics outMetrics) { diff --git a/core/java/com/android/internal/infra/ServiceConnector.java b/core/java/com/android/internal/infra/ServiceConnector.java index 9ced6097804d..c379385429b5 100644 --- a/core/java/com/android/internal/infra/ServiceConnector.java +++ b/core/java/com/android/internal/infra/ServiceConnector.java @@ -507,10 +507,21 @@ public interface ServiceConnector<I extends IInterface> { void unbindJobThread() { cancelTimeout(); I service = mService; + // TODO(b/224695239): This is actually checking wasConnected. Rename and/or fix + // implementation based on what this should actually be checking. At least the first + // check for calling unbind is the correct behavior, though. boolean wasBound = service != null; + if (wasBound || mBinding) { + try { + mContext.unbindService(mServiceConnection); + } catch (IllegalArgumentException e) { // TODO(b/224697137): Fix the race condition + // that requires catching this (crashes if + // service isn't currently bound). + Log.e(LOG_TAG, "Failed to unbind: " + e); + } + } if (wasBound) { onServiceConnectionStatusChanged(service, false); - mContext.unbindService(mServiceConnection); service.asBinder().unlinkToDeath(this, 0); mService = null; } diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index c9b652ca1142..ce212e28e884 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -4672,7 +4672,6 @@ public class BatteryStatsImpl extends BatteryStats { public void noteLongPartialWakelockStart(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs) { - uid = mapUid(uid); noteLongPartialWakeLockStartInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); } @@ -4704,15 +4703,21 @@ public class BatteryStatsImpl extends BatteryStats { private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs) { + final int mappedUid = mapUid(uid); if (historyName == null) { historyName = name; } - if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid, - 0)) { + if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, + mappedUid, 0)) { return; } addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START, - historyName, uid); + historyName, mappedUid); + if (mappedUid != uid) { + // Prevent the isolated uid mapping from being removed while the wakelock is + // being held. + incrementIsolatedUidRefCount(uid); + } } public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { @@ -4722,7 +4727,6 @@ public class BatteryStatsImpl extends BatteryStats { public void noteLongPartialWakelockFinish(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs) { - uid = mapUid(uid); noteLongPartialWakeLockFinishInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs); } @@ -4754,15 +4758,20 @@ public class BatteryStatsImpl extends BatteryStats { private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid, long elapsedRealtimeMs, long uptimeMs) { + final int mappedUid = mapUid(uid); if (historyName == null) { historyName = name; } - if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid, - 0)) { + if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, + mappedUid, 0)) { return; } addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, - historyName, uid); + historyName, mappedUid); + if (mappedUid != uid) { + // Decrement the ref count for the isolated uid and delete the mapping if uneeded. + maybeRemoveIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs); + } } void aggregateLastWakeupUptimeLocked(long elapsedRealtimeMs, long uptimeMs) { diff --git a/core/java/com/android/internal/telephony/ICarrierPrivilegesListener.aidl b/core/java/com/android/internal/telephony/ICarrierPrivilegesCallback.aidl index 6ca8cecba3c8..0c8e73fb2b67 100644 --- a/core/java/com/android/internal/telephony/ICarrierPrivilegesListener.aidl +++ b/core/java/com/android/internal/telephony/ICarrierPrivilegesCallback.aidl @@ -16,7 +16,8 @@ package com.android.internal.telephony; -oneway interface ICarrierPrivilegesListener { +oneway interface ICarrierPrivilegesCallback { void onCarrierPrivilegesChanged( in List<String> privilegedPackageNames, in int[] privilegedUids); + void onCarrierServiceChanged(in String carrierServicePackageName, in int carrierServiceUid); } diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 9712d7e38a4b..c7fa757ac0b7 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -32,7 +32,7 @@ import android.telephony.PreciseDataConnectionState; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.emergency.EmergencyNumber; -import com.android.internal.telephony.ICarrierPrivilegesListener; +import com.android.internal.telephony.ICarrierPrivilegesCallback; import com.android.internal.telephony.IPhoneStateListener; import com.android.internal.telephony.IOnSubscriptionsChangedListener; @@ -102,9 +102,11 @@ interface ITelephonyRegistry { void notifyLinkCapacityEstimateChanged(in int phoneId, in int subId, in List<LinkCapacityEstimate> linkCapacityEstimateList); - void addCarrierPrivilegesListener( - int phoneId, ICarrierPrivilegesListener callback, String pkg, String featureId); - void removeCarrierPrivilegesListener(ICarrierPrivilegesListener callback, String pkg); + void addCarrierPrivilegesCallback( + int phoneId, ICarrierPrivilegesCallback callback, String pkg, String featureId); + void removeCarrierPrivilegesCallback(ICarrierPrivilegesCallback callback, String pkg); void notifyCarrierPrivilegesChanged( int phoneId, in List<String> privilegedPackageNames, in int[] privilegedUids); + void notifyCarrierServiceChanged(int phoneId, in String packageName, int uid); + } diff --git a/core/java/com/android/internal/widget/LockscreenCredential.java b/core/java/com/android/internal/widget/LockscreenCredential.java index 361ba958f759..1074004b4c33 100644 --- a/core/java/com/android/internal/widget/LockscreenCredential.java +++ b/core/java/com/android/internal/widget/LockscreenCredential.java @@ -175,27 +175,6 @@ public class LockscreenCredential implements Parcelable, AutoCloseable { return mCredential; } - /** - * Returns the credential type recognized by {@link StorageManager}. Can be one of - * {@link StorageManager#CRYPT_TYPE_DEFAULT}, {@link StorageManager#CRYPT_TYPE_PATTERN}, - * {@link StorageManager#CRYPT_TYPE_PIN} or {@link StorageManager#CRYPT_TYPE_PASSWORD}. - */ - public int getStorageCryptType() { - if (isNone()) { - return StorageManager.CRYPT_TYPE_DEFAULT; - } - if (isPattern()) { - return StorageManager.CRYPT_TYPE_PATTERN; - } - if (isPin()) { - return StorageManager.CRYPT_TYPE_PIN; - } - if (isPassword()) { - return StorageManager.CRYPT_TYPE_PASSWORD; - } - throw new IllegalStateException("Unhandled credential type"); - } - /** Returns whether this is an empty credential */ public boolean isNone() { ensureNotZeroized(); diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 13ca13322cc7..f28e2f636dac 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -396,6 +396,9 @@ protected: { JNIEnv* env = javavm_to_jnienv(mVM); + LOG_ALWAYS_FATAL_IF(env == nullptr, + "Binder thread started or Java binder used, but env null. Attach JVM?"); + ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM); IPCThreadState* thread_state = IPCThreadState::self(); diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto index 51e150e28437..15a6bc4369b3 100644 --- a/core/proto/android/os/incident.proto +++ b/core/proto/android/os/incident.proto @@ -48,7 +48,6 @@ import "frameworks/base/core/proto/android/service/batterystats.proto"; import "frameworks/base/core/proto/android/service/diskstats.proto"; import "frameworks/base/core/proto/android/service/dropbox.proto"; import "frameworks/base/core/proto/android/service/graphicsstats.proto"; -import "frameworks/base/core/proto/android/service/netstats.proto"; import "frameworks/base/core/proto/android/service/notification.proto"; import "frameworks/base/core/proto/android/service/package.proto"; import "frameworks/base/core/proto/android/service/print.proto"; @@ -62,6 +61,7 @@ import "frameworks/base/core/proto/android/util/textdump.proto"; import "frameworks/base/core/proto/android/privacy.proto"; import "frameworks/base/core/proto/android/section.proto"; import "frameworks/base/proto/src/ipconnectivity.proto"; +import "packages/modules/Connectivity/framework/proto/netstats.proto"; import "packages/modules/Permission/service/proto/com/android/role/roleservice.proto"; package android.os; diff --git a/core/proto/android/service/netstats.proto b/core/proto/android/service/netstats.proto deleted file mode 100644 index ba2b6d6bd7e0..000000000000 --- a/core/proto/android/service/netstats.proto +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -syntax = "proto2"; -package android.service; - -option java_multiple_files = true; -option java_outer_classname = "NetworkStatsServiceProto"; - -// Represents dumpsys from NetworkStatsService (netstats). -message NetworkStatsServiceDumpProto { - repeated NetworkInterfaceProto active_interfaces = 1; - - repeated NetworkInterfaceProto active_uid_interfaces = 2; - - // Device level network stats, which may include non-IP layer traffic. - optional NetworkStatsRecorderProto dev_stats = 3; - - // IP-layer traffic stats. - optional NetworkStatsRecorderProto xt_stats = 4; - - // Per-UID network stats. - optional NetworkStatsRecorderProto uid_stats = 5; - - // Per-UID, per-tag network stats, excluding the default tag (i.e. tag=0). - optional NetworkStatsRecorderProto uid_tag_stats = 6; -} - -// Corresponds to NetworkStatsService.mActiveIfaces/mActiveUidIfaces. -message NetworkInterfaceProto { - // Name of the network interface (eg: wlan). - optional string interface = 1; - - optional NetworkIdentitySetProto identities = 2; -} - -// Corresponds to NetworkIdentitySet. -message NetworkIdentitySetProto { - repeated NetworkIdentityProto identities = 1; -} - -// Corresponds to NetworkIdentity. -message NetworkIdentityProto { - // Constants from ConnectivityManager.TYPE_*. - optional int32 type = 1; - - optional bool roaming = 4; - - optional bool metered = 5; - - optional bool default_network = 6; - - optional int32 oem_managed_network = 7; -} - -// Corresponds to NetworkStatsRecorder. -message NetworkStatsRecorderProto { - optional int64 pending_total_bytes = 1; - - optional NetworkStatsCollectionProto complete_history = 2; -} - -// Corresponds to NetworkStatsCollection. -message NetworkStatsCollectionProto { - repeated NetworkStatsCollectionStatsProto stats = 1; -} - -// Corresponds to NetworkStatsCollection.mStats. -message NetworkStatsCollectionStatsProto { - optional NetworkStatsCollectionKeyProto key = 1; - - optional NetworkStatsHistoryProto history = 2; -} - -// Corresponds to NetworkStatsCollection.Key. -message NetworkStatsCollectionKeyProto { - optional NetworkIdentitySetProto identity = 1; - - optional int32 uid = 2; - - optional int32 set = 3; - - optional int32 tag = 4; -} - -// Corresponds to NetworkStatsHistory. -message NetworkStatsHistoryProto { - // Duration for this bucket in milliseconds. - optional int64 bucket_duration_ms = 1; - - repeated NetworkStatsHistoryBucketProto buckets = 2; -} - -// Corresponds to each bucket in NetworkStatsHistory. -message NetworkStatsHistoryBucketProto { - // Bucket start time in milliseconds since epoch. - optional int64 bucket_start_ms = 1; - - optional int64 rx_bytes = 2; - - optional int64 rx_packets = 3; - - optional int64 tx_bytes = 4; - - optional int64 tx_packets = 5; - - optional int64 operations = 6; -} diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index c037e7c3ef29..659790b84ee3 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -6352,10 +6352,6 @@ android:resource="@xml/autofill_compat_accessibility_service" /> </service> - <service android:name="com.google.android.startop.iorap.IorapForwardingService$IorapdJobServiceProxy" - android:permission="android.permission.BIND_JOB_SERVICE" > - </service> - <service android:name="com.android.server.blob.BlobStoreIdleJobService" android:permission="android.permission.BIND_JOB_SERVICE"> </service> diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java index 3e2885a74287..a6bc456cbe6d 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java @@ -23,6 +23,8 @@ import static android.os.BatteryStats.WAKE_TYPE_PARTIAL; import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU; import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_DISPLAY; +import static com.google.common.truth.Truth.assertThat; + import android.app.ActivityManager; import android.os.BatteryStats; import android.os.BatteryStats.HistoryItem; @@ -206,6 +208,116 @@ public class BatteryStatsNoteTest extends TestCase { assertEquals(120_000, bgTime); } + /** + * Test BatteryStatsImpl.Uid.noteLongPartialWakelockStart for an isolated uid. + */ + @SmallTest + public void testNoteLongPartialWakelockStart_isolatedUid() throws Exception { + final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms + MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); + + + bi.setRecordAllHistoryLocked(true); + bi.forceRecordAllHistory(); + + int pid = 10; + String name = "name"; + String historyName = "historyName"; + + WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain(); + isolatedWorkChain.addNode(ISOLATED_UID, name); + + // Map ISOLATED_UID to UID. + bi.addIsolatedUidLocked(ISOLATED_UID, UID); + + bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); + bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); + bi.noteLongPartialWakelockStart(name, historyName, ISOLATED_UID); + + clocks.realtime = clocks.uptime = 100; + bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); + + clocks.realtime = clocks.uptime = 220; + bi.noteLongPartialWakelockFinish(name, historyName, ISOLATED_UID); + + final BatteryStatsHistoryIterator iterator = + bi.createBatteryStatsHistoryIterator(); + + BatteryStats.HistoryItem item = new BatteryStats.HistoryItem(); + + while (iterator.next(item)) { + if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_START) break; + } + assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_START); + assertThat(item.eventTag).isNotNull(); + assertThat(item.eventTag.string).isEqualTo(historyName); + assertThat(item.eventTag.uid).isEqualTo(UID); + + while (iterator.next(item)) { + if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH) break; + } + assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH); + assertThat(item.eventTag).isNotNull(); + assertThat(item.eventTag.string).isEqualTo(historyName); + assertThat(item.eventTag.uid).isEqualTo(UID); + } + + /** + * Test BatteryStatsImpl.Uid.noteLongPartialWakelockStart for an isolated uid. + */ + @SmallTest + public void testNoteLongPartialWakelockStart_isolatedUidRace() throws Exception { + final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms + MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); + + + bi.setRecordAllHistoryLocked(true); + bi.forceRecordAllHistory(); + + int pid = 10; + String name = "name"; + String historyName = "historyName"; + + WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain(); + isolatedWorkChain.addNode(ISOLATED_UID, name); + + // Map ISOLATED_UID to UID. + bi.addIsolatedUidLocked(ISOLATED_UID, UID); + + bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); + bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); + bi.noteLongPartialWakelockStart(name, historyName, ISOLATED_UID); + + clocks.realtime = clocks.uptime = 100; + bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); + + clocks.realtime = clocks.uptime = 150; + bi.maybeRemoveIsolatedUidLocked(ISOLATED_UID, clocks.realtime, clocks.uptime); + + clocks.realtime = clocks.uptime = 220; + bi.noteLongPartialWakelockFinish(name, historyName, ISOLATED_UID); + + final BatteryStatsHistoryIterator iterator = + bi.createBatteryStatsHistoryIterator(); + + BatteryStats.HistoryItem item = new BatteryStats.HistoryItem(); + + while (iterator.next(item)) { + if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_START) break; + } + assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_START); + assertThat(item.eventTag).isNotNull(); + assertThat(item.eventTag.string).isEqualTo(historyName); + assertThat(item.eventTag.uid).isEqualTo(UID); + + while (iterator.next(item)) { + if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH) break; + } + assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH); + assertThat(item.eventTag).isNotNull(); + assertThat(item.eventTag.string).isEqualTo(historyName); + assertThat(item.eventTag.uid).isEqualTo(UID); + } /** * Test BatteryStatsImpl.noteUidProcessStateLocked. diff --git a/data/etc/car/com.android.car.shell.xml b/data/etc/car/com.android.car.shell.xml index 3e5775357d2f..f29f6ee07af0 100644 --- a/data/etc/car/com.android.car.shell.xml +++ b/data/etc/car/com.android.car.shell.xml @@ -37,6 +37,6 @@ <permission name="android.car.permission.USE_CAR_WATCHDOG" /> <permission name="android.car.permission.COLLECT_CAR_WATCHDOG_METRICS" /> <permission name="android.car.permission.CONTROL_CAR_WATCHDOG_CONFIG" /> - <permission name="android.car.permission.USE_CAR_TELEMETRY_SERVICE"/> + <permission name="com.android.car.permission.USE_CAR_TELEMETRY_SERVICE"/> </privapp-permissions> </permissions> diff --git a/data/etc/car/com.google.android.car.kitchensink.xml b/data/etc/car/com.google.android.car.kitchensink.xml index 2c59c7390ebf..313fa308801a 100644 --- a/data/etc/car/com.google.android.car.kitchensink.xml +++ b/data/etc/car/com.google.android.car.kitchensink.xml @@ -95,6 +95,6 @@ <permission name="android.car.permission.CONTROL_CAR_EVS_ACTIVITY" /> <permission name="android.car.permission.USE_CAR_EVS_CAMERA" /> <permission name="android.car.permission.MONITOR_CAR_EVS_STATUS" /> - <permission name="android.car.permission.USE_CAR_TELEMETRY_SERVICE" /> + <permission name="com.android.car.permission.USE_CAR_TELEMETRY_SERVICE" /> </privapp-permissions> </permissions> diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java index 05fb4c3cf76f..919a93b8f107 100644 --- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java +++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java @@ -20,7 +20,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.ServiceManager; import android.os.ServiceSpecificException; -import android.security.keystore.KeyProperties; import android.security.maintenance.IKeystoreMaintenance; import android.system.keystore2.Domain; import android.system.keystore2.KeyDescriptor; @@ -158,11 +157,6 @@ public class AndroidKeyStoreMaintenance { * Migrates a key given by the source descriptor to the location designated by the destination * descriptor. * - * If Domain::APP is selected in either source or destination, nspace must be set to - * {@link KeyProperties#NAMESPACE_APPLICATION}, implying the caller's UID. - * If the caller has the MIGRATE_ANY_KEY permission, Domain::APP may be used with - * other nspace values which then indicates the UID of a different application. - * * @param source - The key to migrate may be specified by Domain.APP, Domain.SELINUX, or * Domain.KEY_ID. The caller needs the permissions use, delete, and grant for the * source namespace. @@ -189,20 +183,4 @@ public class AndroidKeyStoreMaintenance { return SYSTEM_ERROR; } } - - /** - * @see IKeystoreMaintenance#listEntries(int, long) - */ - @Nullable - public static KeyDescriptor[] listEntries(int domain, long nspace) { - try { - return getService().listEntries(domain, nspace); - } catch (ServiceSpecificException e) { - Log.e(TAG, "listEntries failed", e); - return null; - } catch (Exception e) { - Log.e(TAG, "Can not connect to keystore", e); - return null; - } - } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java index 624d130e8698..8733c152dca9 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java @@ -80,7 +80,7 @@ public final class CommonFoldingFeature { /** * The possible states for a folding hinge. */ - @IntDef({COMMON_STATE_FLAT, COMMON_STATE_HALF_OPENED}) + @IntDef({COMMON_STATE_UNKNOWN, COMMON_STATE_FLAT, COMMON_STATE_HALF_OPENED}) @Retention(RetentionPolicy.SOURCE) public @interface State { } @@ -236,7 +236,8 @@ public final class CommonFoldingFeature { } private static void assertValidState(@Nullable Integer state) { - if (state != null && state != COMMON_STATE_FLAT && state != COMMON_STATE_HALF_OPENED) { + if (state != null && state != COMMON_STATE_FLAT + && state != COMMON_STATE_HALF_OPENED && state != COMMON_STATE_UNKNOWN) { throw new IllegalArgumentException("Invalid state: " + state + "must be either COMMON_STATE_FLAT or COMMON_STATE_HALF_OPENED"); } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java index e9d213e06fa9..0e696eb8efb7 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/common/SettingsDisplayFeatureProducer.java @@ -16,6 +16,8 @@ package androidx.window.common; +import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT; +import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED; import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_UNKNOWN; import static androidx.window.common.CommonFoldingFeature.parseListFromString; @@ -42,7 +44,10 @@ import java.util.Optional; public final class SettingsDisplayFeatureProducer extends BaseDataProducer<List<CommonFoldingFeature>> { private static final String DISPLAY_FEATURES = "display_features"; + private static final String DEVICE_POSTURE = "device_posture"; + private final Uri mDevicePostureUri = + Settings.Global.getUriFor(DEVICE_POSTURE); private final Uri mDisplayFeaturesUri = Settings.Global.getUriFor(DISPLAY_FEATURES); @@ -55,6 +60,15 @@ public final class SettingsDisplayFeatureProducer mObserver = new SettingsObserver(); } + private int getPosture() { + int posture = Settings.Global.getInt(mResolver, DEVICE_POSTURE, COMMON_STATE_UNKNOWN); + if (posture == COMMON_STATE_HALF_OPENED || posture == COMMON_STATE_FLAT) { + return posture; + } else { + return COMMON_STATE_UNKNOWN; + } + } + @Override @NonNull public Optional<List<CommonFoldingFeature>> getData() { @@ -66,7 +80,7 @@ public final class SettingsDisplayFeatureProducer if (TextUtils.isEmpty(displayFeaturesString)) { return Optional.of(Collections.emptyList()); } - return Optional.of(parseListFromString(displayFeaturesString, COMMON_STATE_UNKNOWN)); + return Optional.of(parseListFromString(displayFeaturesString, getPosture())); } /** @@ -80,6 +94,7 @@ public final class SettingsDisplayFeatureProducer mRegisteredObservers = true; mResolver.registerContentObserver(mDisplayFeaturesUri, false /* notifyForDescendants */, mObserver /* ContentObserver */); + mResolver.registerContentObserver(mDevicePostureUri, false, mObserver); } /** @@ -101,7 +116,7 @@ public final class SettingsDisplayFeatureProducer @Override public void onChange(boolean selfChange, Uri uri) { - if (mDisplayFeaturesUri.equals(uri)) { + if (mDisplayFeaturesUri.equals(uri) || mDevicePostureUri.equals(uri)) { notifyDataChanged(); } } diff --git a/packages/ConnectivityT/OWNERS b/packages/ConnectivityT/OWNERS index e267d19ad7e2..adbcd4b5a36b 100644 --- a/packages/ConnectivityT/OWNERS +++ b/packages/ConnectivityT/OWNERS @@ -1,2 +1,5 @@ -file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking -per-file **IpSec* = file:/services/core/java/com/android/server/vcn/OWNERS +# OWNERS block for code move: b/222234190 +reminv@google.com + +# file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking +# per-file **IpSec* = file:/services/core/java/com/android/server/vcn/OWNERS diff --git a/packages/ConnectivityT/framework-t/Android.bp b/packages/ConnectivityT/framework-t/Android.bp index 217a1f67c336..bc278528570f 100644 --- a/packages/ConnectivityT/framework-t/Android.bp +++ b/packages/ConnectivityT/framework-t/Android.bp @@ -131,8 +131,8 @@ filegroup { "src/android/net/EthernetNetworkUpdateRequest.java", "src/android/net/EthernetNetworkUpdateRequest.aidl", "src/android/net/IEthernetManager.aidl", - "src/android/net/IEthernetNetworkManagementListener.aidl", "src/android/net/IEthernetServiceListener.aidl", + "src/android/net/INetworkInterfaceOutcomeReceiver.aidl", "src/android/net/ITetheredInterfaceCallback.aidl", ], path: "src", diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java index 793f28d5aa59..217d670743d7 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java +++ b/packages/ConnectivityT/framework-t/src/android/net/EthernetManager.java @@ -30,6 +30,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; import android.os.Build; +import android.os.OutcomeReceiver; import android.os.RemoteException; import com.android.internal.annotations.GuardedBy; @@ -40,7 +41,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Objects; import java.util.concurrent.Executor; -import java.util.function.BiConsumer; +import java.util.function.IntConsumer; /** * A class that manages and configures Ethernet interfaces. @@ -53,15 +54,31 @@ public class EthernetManager { private static final String TAG = "EthernetManager"; private final IEthernetManager mService; - @GuardedBy("mListeners") - private final ArrayList<ListenerInfo> mListeners = new ArrayList<>(); + @GuardedBy("mListenerLock") + private final ArrayList<ListenerInfo<InterfaceStateListener>> mIfaceListeners = + new ArrayList<>(); + @GuardedBy("mListenerLock") + private final ArrayList<ListenerInfo<IntConsumer>> mEthernetStateListeners = + new ArrayList<>(); + final Object mListenerLock = new Object(); private final IEthernetServiceListener.Stub mServiceListener = new IEthernetServiceListener.Stub() { @Override + public void onEthernetStateChanged(int state) { + synchronized (mListenerLock) { + for (ListenerInfo<IntConsumer> li : mEthernetStateListeners) { + li.executor.execute(() -> { + li.listener.accept(state); + }); + } + } + } + + @Override public void onInterfaceStateChanged(String iface, int state, int role, IpConfiguration configuration) { - synchronized (mListeners) { - for (ListenerInfo li : mListeners) { + synchronized (mListenerLock) { + for (ListenerInfo<InterfaceStateListener> li : mIfaceListeners) { li.executor.execute(() -> li.listener.onInterfaceStateChanged(iface, state, role, configuration)); @@ -70,13 +87,29 @@ public class EthernetManager { } }; - private static class ListenerInfo { + /** + * Indicates that Ethernet is disabled. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int ETHERNET_STATE_DISABLED = 0; + + /** + * Indicates that Ethernet is enabled. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int ETHERNET_STATE_ENABLED = 1; + + private static class ListenerInfo<T> { @NonNull public final Executor executor; @NonNull - public final InterfaceStateListener listener; + public final T listener; - private ListenerInfo(@NonNull Executor executor, @NonNull InterfaceStateListener listener) { + private ListenerInfo(@NonNull Executor executor, @NonNull T listener) { this.executor = executor; this.listener = listener; } @@ -289,18 +322,24 @@ public class EthernetManager { if (listener == null || executor == null) { throw new NullPointerException("listener and executor must not be null"); } - synchronized (mListeners) { - mListeners.add(new ListenerInfo(executor, listener)); - if (mListeners.size() == 1) { - try { - mService.addListener(mServiceListener); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } + synchronized (mListenerLock) { + maybeAddServiceListener(); + mIfaceListeners.add(new ListenerInfo<InterfaceStateListener>(executor, listener)); } } + @GuardedBy("mListenerLock") + private void maybeAddServiceListener() { + if (!mIfaceListeners.isEmpty() || !mEthernetStateListeners.isEmpty()) return; + + try { + mService.addListener(mServiceListener); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + + } + /** * Returns an array of available Ethernet interface names. * @hide @@ -323,15 +362,20 @@ public class EthernetManager { @SystemApi(client = MODULE_LIBRARIES) public void removeInterfaceStateListener(@NonNull InterfaceStateListener listener) { Objects.requireNonNull(listener); - synchronized (mListeners) { - mListeners.removeIf(l -> l.listener == listener); - if (mListeners.isEmpty()) { - try { - mService.removeListener(mServiceListener); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } + synchronized (mListenerLock) { + mIfaceListeners.removeIf(l -> l.listener == listener); + maybeRemoveServiceListener(); + } + } + + @GuardedBy("mListenerLock") + private void maybeRemoveServiceListener() { + if (!mIfaceListeners.isEmpty() || !mEthernetStateListeners.isEmpty()) return; + + try { + mService.removeListener(mServiceListener); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); } } @@ -443,41 +487,45 @@ public class EthernetManager { return new TetheredInterfaceRequest(mService, cbInternal); } - private static final class InternalNetworkManagementListener - extends IEthernetNetworkManagementListener.Stub { + private static final class NetworkInterfaceOutcomeReceiver + extends INetworkInterfaceOutcomeReceiver.Stub { @NonNull private final Executor mExecutor; @NonNull - private final BiConsumer<Network, EthernetNetworkManagementException> mListener; + private final OutcomeReceiver<String, EthernetNetworkManagementException> mCallback; - InternalNetworkManagementListener( + NetworkInterfaceOutcomeReceiver( @NonNull final Executor executor, - @NonNull final BiConsumer<Network, EthernetNetworkManagementException> listener) { + @NonNull final OutcomeReceiver<String, EthernetNetworkManagementException> + callback) { Objects.requireNonNull(executor, "Pass a non-null executor"); - Objects.requireNonNull(listener, "Pass a non-null listener"); + Objects.requireNonNull(callback, "Pass a non-null callback"); mExecutor = executor; - mListener = listener; + mCallback = callback; + } + + @Override + public void onResult(@NonNull String iface) { + mExecutor.execute(() -> mCallback.onResult(iface)); } @Override - public void onComplete( - @Nullable final Network network, - @Nullable final EthernetNetworkManagementException e) { - mExecutor.execute(() -> mListener.accept(network, e)); + public void onError(@NonNull EthernetNetworkManagementException e) { + mExecutor.execute(() -> mCallback.onError(e)); } } - private InternalNetworkManagementListener getInternalNetworkManagementListener( + private NetworkInterfaceOutcomeReceiver makeNetworkInterfaceOutcomeReceiver( @Nullable final Executor executor, - @Nullable final BiConsumer<Network, EthernetNetworkManagementException> listener) { - if (null != listener) { - Objects.requireNonNull(executor, "Pass a non-null executor, or a null listener"); + @Nullable final OutcomeReceiver<String, EthernetNetworkManagementException> callback) { + if (null != callback) { + Objects.requireNonNull(executor, "Pass a non-null executor, or a null callback"); } - final InternalNetworkManagementListener proxy; - if (null == listener) { + final NetworkInterfaceOutcomeReceiver proxy; + if (null == callback) { proxy = null; } else { - proxy = new InternalNetworkManagementListener(executor, listener); + proxy = new NetworkInterfaceOutcomeReceiver(executor, callback); } return proxy; } @@ -492,14 +540,17 @@ public class EthernetManager { * Similarly, use {@link NetworkCapabilities.Builder} to build a {@code NetworkCapabilities} * object for this network to put inside the {@code request}. * - * If non-null, the listener will be called exactly once after this is called, unless - * a synchronous exception was thrown. + * This function accepts an {@link OutcomeReceiver} that is called once the operation has + * finished execution. * * @param iface the name of the interface to act upon. * @param request the {@link EthernetNetworkUpdateRequest} used to set an ethernet network's * {@link StaticIpConfiguration} and {@link NetworkCapabilities} values. - * @param executor an {@link Executor} to execute the listener on. Optional if listener is null. - * @param listener an optional {@link BiConsumer} to listen for completion of the operation. + * @param executor an {@link Executor} to execute the callback on. Optional if callback is null. + * @param callback an optional {@link OutcomeReceiver} to listen for completion of the + * operation. On success, {@link OutcomeReceiver#onResult} is called with the + * interface name. On error, {@link OutcomeReceiver#onError} is called with more + * information about the error. * @throws SecurityException if the process doesn't hold * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}. * @throws UnsupportedOperationException if called on a non-automotive device or on an @@ -515,11 +566,11 @@ public class EthernetManager { @NonNull String iface, @NonNull EthernetNetworkUpdateRequest request, @Nullable @CallbackExecutor Executor executor, - @Nullable BiConsumer<Network, EthernetNetworkManagementException> listener) { + @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) { Objects.requireNonNull(iface, "iface must be non-null"); Objects.requireNonNull(request, "request must be non-null"); - final InternalNetworkManagementListener proxy = getInternalNetworkManagementListener( - executor, listener); + final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver( + executor, callback); try { mService.updateConfiguration(iface, request, proxy); } catch (RemoteException e) { @@ -530,15 +581,17 @@ public class EthernetManager { /** * Set an ethernet network's link state up. * - * When the link is successfully turned up, the listener will be called with the resulting - * network. If any error or unexpected condition happens while the system tries to turn the - * interface up, the listener will be called with an appropriate exception. - * The listener is guaranteed to be called exactly once for each call to this method, but this - * may take an unbounded amount of time depending on the actual network conditions. + * When the link is successfully turned up, the callback will be called with the network + * interface was torn down, if any. If any error or unexpected condition happens while the + * system tries to turn the interface down, the callback will be called with an appropriate + * exception. The callback is guaranteed to be called exactly once for each call to this method. * * @param iface the name of the interface to act upon. - * @param executor an {@link Executor} to execute the listener on. Optional if listener is null. - * @param listener an optional {@link BiConsumer} to listen for completion of the operation. + * @param executor an {@link Executor} to execute the callback on. Optional if callback is null. + * @param callback an optional {@link OutcomeReceiver} to listen for completion of the + * operation. On success, {@link OutcomeReceiver#onResult} is called with the + * interface name. On error, {@link OutcomeReceiver#onError} is called with more + * information about the error. * @throws SecurityException if the process doesn't hold * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}. * @throws UnsupportedOperationException if called on a non-automotive device. @@ -553,10 +606,10 @@ public class EthernetManager { public void connectNetwork( @NonNull String iface, @Nullable @CallbackExecutor Executor executor, - @Nullable BiConsumer<Network, EthernetNetworkManagementException> listener) { + @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) { Objects.requireNonNull(iface, "iface must be non-null"); - final InternalNetworkManagementListener proxy = getInternalNetworkManagementListener( - executor, listener); + final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver( + executor, callback); try { mService.connectNetwork(iface, proxy); } catch (RemoteException e) { @@ -567,14 +620,17 @@ public class EthernetManager { /** * Set an ethernet network's link state down. * - * When the link is successfully turned down, the listener will be called with the network that - * was torn down, if any. If any error or unexpected condition happens while the system tries to - * turn the interface down, the listener will be called with an appropriate exception. - * The listener is guaranteed to be called exactly once for each call to this method. + * When the link is successfully turned down, the callback will be called with the network + * interface was torn down, if any. If any error or unexpected condition happens while the + * system tries to turn the interface down, the callback will be called with an appropriate + * exception. The callback is guaranteed to be called exactly once for each call to this method. * * @param iface the name of the interface to act upon. - * @param executor an {@link Executor} to execute the listener on. Optional if listener is null. - * @param listener an optional {@link BiConsumer} to listen for completion of the operation. + * @param executor an {@link Executor} to execute the callback on. Optional if callback is null. + * @param callback an optional {@link OutcomeReceiver} to listen for completion of the + * operation. On success, {@link OutcomeReceiver#onResult} is called with the + * interface name. On error, {@link OutcomeReceiver#onError} is called with more + * information about the error. * @throws SecurityException if the process doesn't hold * {@link android.Manifest.permission.MANAGE_ETHERNET_NETWORKS}. * @throws UnsupportedOperationException if called on a non-automotive device. @@ -589,14 +645,71 @@ public class EthernetManager { public void disconnectNetwork( @NonNull String iface, @Nullable @CallbackExecutor Executor executor, - @Nullable BiConsumer<Network, EthernetNetworkManagementException> listener) { + @Nullable OutcomeReceiver<String, EthernetNetworkManagementException> callback) { Objects.requireNonNull(iface, "iface must be non-null"); - final InternalNetworkManagementListener proxy = getInternalNetworkManagementListener( - executor, listener); + final NetworkInterfaceOutcomeReceiver proxy = makeNetworkInterfaceOutcomeReceiver( + executor, callback); try { mService.disconnectNetwork(iface, proxy); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } + + /** + * Change ethernet setting. + * + * @param enabled enable or disable ethernet settings. + * + * @hide + */ + @RequiresPermission(anyOf = { + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_STACK, + android.Manifest.permission.NETWORK_SETTINGS}) + @SystemApi(client = MODULE_LIBRARIES) + public void setEthernetEnabled(boolean enabled) { + try { + mService.setEthernetEnabled(enabled); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Listen to changes in the state of ethernet. + * + * @param executor to run callbacks on. + * @param listener to listen ethernet state changed. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @SystemApi(client = MODULE_LIBRARIES) + public void addEthernetStateListener(@NonNull Executor executor, + @NonNull IntConsumer listener) { + Objects.requireNonNull(executor); + Objects.requireNonNull(listener); + synchronized (mListenerLock) { + maybeAddServiceListener(); + mEthernetStateListeners.add(new ListenerInfo<IntConsumer>(executor, listener)); + } + } + + /** + * Removes a listener. + * + * @param listener to listen ethernet state changed. + * + * @hide + */ + @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) + @SystemApi(client = MODULE_LIBRARIES) + public void removeEthernetStateListener(@NonNull IntConsumer listener) { + Objects.requireNonNull(listener); + synchronized (mListenerLock) { + mEthernetStateListeners.removeIf(l -> l.listener == listener); + maybeRemoveServiceListener(); + } + } } diff --git a/packages/ConnectivityT/framework-t/src/android/net/IEthernetManager.aidl b/packages/ConnectivityT/framework-t/src/android/net/IEthernetManager.aidl index 544d02ba76ff..44e27e26f5d2 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/IEthernetManager.aidl +++ b/packages/ConnectivityT/framework-t/src/android/net/IEthernetManager.aidl @@ -18,8 +18,9 @@ package android.net; import android.net.IpConfiguration; import android.net.IEthernetServiceListener; -import android.net.IEthernetNetworkManagementListener; +import android.net.EthernetNetworkManagementException; import android.net.EthernetNetworkUpdateRequest; +import android.net.INetworkInterfaceOutcomeReceiver; import android.net.ITetheredInterfaceCallback; /** @@ -39,7 +40,8 @@ interface IEthernetManager void requestTetheredInterface(in ITetheredInterfaceCallback callback); void releaseTetheredInterface(in ITetheredInterfaceCallback callback); void updateConfiguration(String iface, in EthernetNetworkUpdateRequest request, - in IEthernetNetworkManagementListener listener); - void connectNetwork(String iface, in IEthernetNetworkManagementListener listener); - void disconnectNetwork(String iface, in IEthernetNetworkManagementListener listener); + in INetworkInterfaceOutcomeReceiver listener); + void connectNetwork(String iface, in INetworkInterfaceOutcomeReceiver listener); + void disconnectNetwork(String iface, in INetworkInterfaceOutcomeReceiver listener); + void setEthernetEnabled(boolean enabled); } diff --git a/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl b/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl index 6d2ba03f78d4..751605bb3849 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl +++ b/packages/ConnectivityT/framework-t/src/android/net/IEthernetServiceListener.aidl @@ -21,6 +21,7 @@ import android.net.IpConfiguration; /** @hide */ oneway interface IEthernetServiceListener { + void onEthernetStateChanged(int state); void onInterfaceStateChanged(String iface, int state, int role, in IpConfiguration configuration); } diff --git a/packages/ConnectivityT/framework-t/src/android/net/IEthernetNetworkManagementListener.aidl b/packages/ConnectivityT/framework-t/src/android/net/INetworkInterfaceOutcomeReceiver.aidl index 93edccfdafd9..85795ead7aea 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/IEthernetNetworkManagementListener.aidl +++ b/packages/ConnectivityT/framework-t/src/android/net/INetworkInterfaceOutcomeReceiver.aidl @@ -17,9 +17,9 @@ package android.net; import android.net.EthernetNetworkManagementException; -import android.net.Network; /** @hide */ -oneway interface IEthernetNetworkManagementListener { - void onComplete(in Network network, in EthernetNetworkManagementException exception); +oneway interface INetworkInterfaceOutcomeReceiver { + void onResult(in String iface); + void onError(in EthernetNetworkManagementException e); }
\ No newline at end of file diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java index a48f94b66def..da5f88dc3b7e 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java @@ -189,14 +189,14 @@ public class NetworkIdentity { public void dumpDebug(ProtoOutputStream proto, long tag) { final long start = proto.start(tag); - proto.write(NetworkIdentityProto.TYPE_FIELD_NUMBER, mType); + proto.write(NetworkIdentityProto.TYPE, mType); // TODO: dump mRatType as well. - proto.write(NetworkIdentityProto.ROAMING_FIELD_NUMBER, mRoaming); - proto.write(NetworkIdentityProto.METERED_FIELD_NUMBER, mMetered); - proto.write(NetworkIdentityProto.DEFAULT_NETWORK_FIELD_NUMBER, mDefaultNetwork); - proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK_FIELD_NUMBER, mOemManaged); + proto.write(NetworkIdentityProto.ROAMING, mRoaming); + proto.write(NetworkIdentityProto.METERED, mMetered); + proto.write(NetworkIdentityProto.DEFAULT_NETWORK, mDefaultNetwork); + proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK, mOemManaged); proto.end(start); } diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java index 56461babfe49..ad3a958a680e 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java @@ -222,7 +222,7 @@ public class NetworkIdentitySet extends HashSet<NetworkIdentity> { final long start = proto.start(tag); for (NetworkIdentity ident : this) { - ident.dumpDebug(proto, NetworkIdentitySetProto.IDENTITIES_FIELD_NUMBER); + ident.dumpDebug(proto, NetworkIdentitySetProto.IDENTITIES); } proto.end(start); diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java index 1ddc78bb4d7c..e385b33447f0 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java @@ -733,19 +733,19 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W final long start = proto.start(tag); for (Key key : getSortedKeys()) { - final long startStats = proto.start(NetworkStatsCollectionProto.STATS_FIELD_NUMBER); + final long startStats = proto.start(NetworkStatsCollectionProto.STATS); // Key - final long startKey = proto.start(NetworkStatsCollectionStatsProto.KEY_FIELD_NUMBER); - key.ident.dumpDebug(proto, NetworkStatsCollectionKeyProto.IDENTITY_FIELD_NUMBER); - proto.write(NetworkStatsCollectionKeyProto.UID_FIELD_NUMBER, key.uid); - proto.write(NetworkStatsCollectionKeyProto.SET_FIELD_NUMBER, key.set); - proto.write(NetworkStatsCollectionKeyProto.TAG_FIELD_NUMBER, key.tag); + final long startKey = proto.start(NetworkStatsCollectionStatsProto.KEY); + key.ident.dumpDebug(proto, NetworkStatsCollectionKeyProto.IDENTITY); + proto.write(NetworkStatsCollectionKeyProto.UID, key.uid); + proto.write(NetworkStatsCollectionKeyProto.SET, key.set); + proto.write(NetworkStatsCollectionKeyProto.TAG, key.tag); proto.end(startKey); // Value final NetworkStatsHistory history = mStats.get(key); - history.dumpDebug(proto, NetworkStatsCollectionStatsProto.HISTORY_FIELD_NUMBER); + history.dumpDebug(proto, NetworkStatsCollectionStatsProto.HISTORY); proto.end(startStats); } diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java index 822a16e0bb41..301fef944169 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java @@ -915,18 +915,18 @@ public final class NetworkStatsHistory implements Parcelable { public void dumpDebug(ProtoOutputStream proto, long tag) { final long start = proto.start(tag); - proto.write(NetworkStatsHistoryProto.BUCKET_DURATION_MS_FIELD_NUMBER, bucketDuration); + proto.write(NetworkStatsHistoryProto.BUCKET_DURATION_MS, bucketDuration); for (int i = 0; i < bucketCount; i++) { - final long startBucket = proto.start(NetworkStatsHistoryProto.BUCKETS_FIELD_NUMBER); + final long startBucket = proto.start(NetworkStatsHistoryProto.BUCKETS); - proto.write(NetworkStatsHistoryBucketProto.BUCKET_START_MS_FIELD_NUMBER, + proto.write(NetworkStatsHistoryBucketProto.BUCKET_START_MS, bucketStart[i]); - dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_BYTES_FIELD_NUMBER, rxBytes, i); - dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_PACKETS_FIELD_NUMBER, rxPackets, i); - dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_BYTES_FIELD_NUMBER, txBytes, i); - dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_PACKETS_FIELD_NUMBER, txPackets, i); - dumpDebug(proto, NetworkStatsHistoryBucketProto.OPERATIONS_FIELD_NUMBER, operations, i); + dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_BYTES, rxBytes, i); + dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_PACKETS, rxPackets, i); + dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_BYTES, txBytes, i); + dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_PACKETS, txPackets, i); + dumpDebug(proto, NetworkStatsHistoryBucketProto.OPERATIONS, operations, i); proto.end(startBucket); } diff --git a/packages/ConnectivityT/framework-t/src/android/net/nsd/NsdManager.java b/packages/ConnectivityT/framework-t/src/android/net/nsd/NsdManager.java index 512fbcee9330..209f372fd377 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/nsd/NsdManager.java +++ b/packages/ConnectivityT/framework-t/src/android/net/nsd/NsdManager.java @@ -45,6 +45,7 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import java.util.Objects; +import java.util.concurrent.Executor; /** * The Network Service Discovery Manager class provides the API to discover services @@ -285,8 +286,12 @@ public final class NsdManager { private final Context mContext; private int mListenerKey = FIRST_LISTENER_KEY; + @GuardedBy("mMapLock") private final SparseArray mListenerMap = new SparseArray(); + @GuardedBy("mMapLock") private final SparseArray<NsdServiceInfo> mServiceMap = new SparseArray<>(); + @GuardedBy("mMapLock") + private final SparseArray<Executor> mExecutorMap = new SparseArray<>(); private final Object mMapLock = new Object(); // Map of listener key sent by client -> per-network discovery tracker @GuardedBy("mPerNetworkDiscoveryMap") @@ -299,6 +304,7 @@ public final class NsdManager { final String mServiceType; final int mProtocolType; final DiscoveryListener mBaseListener; + final Executor mBaseExecutor; final ArrayMap<Network, DelegatingDiscoveryListener> mPerNetworkListeners = new ArrayMap<>(); @@ -308,7 +314,8 @@ public final class NsdManager { final DelegatingDiscoveryListener wrappedListener = new DelegatingDiscoveryListener( network, mBaseListener); mPerNetworkListeners.put(network, wrappedListener); - discoverServices(mServiceType, mProtocolType, network, wrappedListener); + discoverServices(mServiceType, mProtocolType, network, mBaseExecutor, + wrappedListener); } @Override @@ -355,9 +362,10 @@ public final class NsdManager { } private PerNetworkDiscoveryTracker(String serviceType, int protocolType, - DiscoveryListener baseListener) { + Executor baseExecutor, DiscoveryListener baseListener) { mServiceType = serviceType; mProtocolType = protocolType; + mBaseExecutor = baseExecutor; mBaseListener = baseListener; } @@ -644,9 +652,11 @@ public final class NsdManager { final int key = message.arg2; final Object listener; final NsdServiceInfo ns; + final Executor executor; synchronized (mMapLock) { listener = mListenerMap.get(key); ns = mServiceMap.get(key); + executor = mExecutorMap.get(key); } if (listener == null) { Log.d(TAG, "Stale key " + message.arg2); @@ -657,56 +667,64 @@ public final class NsdManager { } switch (what) { case DISCOVER_SERVICES_STARTED: - String s = getNsdServiceInfoType((NsdServiceInfo) message.obj); - ((DiscoveryListener) listener).onDiscoveryStarted(s); + final String s = getNsdServiceInfoType((NsdServiceInfo) message.obj); + executor.execute(() -> ((DiscoveryListener) listener).onDiscoveryStarted(s)); break; case DISCOVER_SERVICES_FAILED: removeListener(key); - ((DiscoveryListener) listener).onStartDiscoveryFailed(getNsdServiceInfoType(ns), - message.arg1); + executor.execute(() -> ((DiscoveryListener) listener).onStartDiscoveryFailed( + getNsdServiceInfoType(ns), message.arg1)); break; case SERVICE_FOUND: - ((DiscoveryListener) listener).onServiceFound((NsdServiceInfo) message.obj); + executor.execute(() -> ((DiscoveryListener) listener).onServiceFound( + (NsdServiceInfo) message.obj)); break; case SERVICE_LOST: - ((DiscoveryListener) listener).onServiceLost((NsdServiceInfo) message.obj); + executor.execute(() -> ((DiscoveryListener) listener).onServiceLost( + (NsdServiceInfo) message.obj)); break; case STOP_DISCOVERY_FAILED: // TODO: failure to stop discovery should be internal and retried internally, as // the effect for the client is indistinguishable from STOP_DISCOVERY_SUCCEEDED removeListener(key); - ((DiscoveryListener) listener).onStopDiscoveryFailed(getNsdServiceInfoType(ns), - message.arg1); + executor.execute(() -> ((DiscoveryListener) listener).onStopDiscoveryFailed( + getNsdServiceInfoType(ns), message.arg1)); break; case STOP_DISCOVERY_SUCCEEDED: removeListener(key); - ((DiscoveryListener) listener).onDiscoveryStopped(getNsdServiceInfoType(ns)); + executor.execute(() -> ((DiscoveryListener) listener).onDiscoveryStopped( + getNsdServiceInfoType(ns))); break; case REGISTER_SERVICE_FAILED: removeListener(key); - ((RegistrationListener) listener).onRegistrationFailed(ns, message.arg1); + executor.execute(() -> ((RegistrationListener) listener).onRegistrationFailed( + ns, message.arg1)); break; case REGISTER_SERVICE_SUCCEEDED: - ((RegistrationListener) listener).onServiceRegistered( - (NsdServiceInfo) message.obj); + executor.execute(() -> ((RegistrationListener) listener).onServiceRegistered( + (NsdServiceInfo) message.obj)); break; case UNREGISTER_SERVICE_FAILED: removeListener(key); - ((RegistrationListener) listener).onUnregistrationFailed(ns, message.arg1); + executor.execute(() -> ((RegistrationListener) listener).onUnregistrationFailed( + ns, message.arg1)); break; case UNREGISTER_SERVICE_SUCCEEDED: // TODO: do not unregister listener until service is unregistered, or provide // alternative way for unregistering ? removeListener(message.arg2); - ((RegistrationListener) listener).onServiceUnregistered(ns); + executor.execute(() -> ((RegistrationListener) listener).onServiceUnregistered( + ns)); break; case RESOLVE_SERVICE_FAILED: removeListener(key); - ((ResolveListener) listener).onResolveFailed(ns, message.arg1); + executor.execute(() -> ((ResolveListener) listener).onResolveFailed( + ns, message.arg1)); break; case RESOLVE_SERVICE_SUCCEEDED: removeListener(key); - ((ResolveListener) listener).onServiceResolved((NsdServiceInfo) message.obj); + executor.execute(() -> ((ResolveListener) listener).onServiceResolved( + (NsdServiceInfo) message.obj)); break; default: Log.d(TAG, "Ignored " + message); @@ -722,7 +740,7 @@ public final class NsdManager { } // Assert that the listener is not in the map, then add it and returns its key - private int putListener(Object listener, NsdServiceInfo s) { + private int putListener(Object listener, Executor e, NsdServiceInfo s) { checkListener(listener); final int key; synchronized (mMapLock) { @@ -733,6 +751,7 @@ public final class NsdManager { key = nextListenerKey(); mListenerMap.put(key, listener); mServiceMap.put(key, s); + mExecutorMap.put(key, e); } return key; } @@ -741,6 +760,7 @@ public final class NsdManager { synchronized (mMapLock) { mListenerMap.remove(key); mServiceMap.remove(key); + mExecutorMap.remove(key); } } @@ -779,12 +799,33 @@ public final class NsdManager { */ public void registerService(NsdServiceInfo serviceInfo, int protocolType, RegistrationListener listener) { + registerService(serviceInfo, protocolType, Runnable::run, listener); + } + + /** + * Register a service to be discovered by other services. + * + * <p> The function call immediately returns after sending a request to register service + * to the framework. The application is notified of a successful registration + * through the callback {@link RegistrationListener#onServiceRegistered} or a failure + * through {@link RegistrationListener#onRegistrationFailed}. + * + * <p> The application should call {@link #unregisterService} when the service + * registration is no longer required, and/or whenever the application is stopped. + * @param serviceInfo The service being registered + * @param protocolType The service discovery protocol + * @param executor Executor to run listener callbacks with + * @param listener The listener notifies of a successful registration and is used to + * unregister this service through a call on {@link #unregisterService}. Cannot be null. + */ + public void registerService(@NonNull NsdServiceInfo serviceInfo, int protocolType, + @NonNull Executor executor, @NonNull RegistrationListener listener) { if (serviceInfo.getPort() <= 0) { throw new IllegalArgumentException("Invalid port number"); } checkServiceInfo(serviceInfo); checkProtocol(protocolType); - int key = putListener(listener, serviceInfo); + int key = putListener(listener, executor, serviceInfo); try { mService.registerService(key, serviceInfo); } catch (RemoteException e) { @@ -815,11 +856,35 @@ public final class NsdManager { } /** - * Same as {@link #discoverServices(String, int, Network, DiscoveryListener)} with a null - * {@link Network}. + * Initiate service discovery to browse for instances of a service type. Service discovery + * consumes network bandwidth and will continue until the application calls + * {@link #stopServiceDiscovery}. + * + * <p> The function call immediately returns after sending a request to start service + * discovery to the framework. The application is notified of a success to initiate + * discovery through the callback {@link DiscoveryListener#onDiscoveryStarted} or a failure + * through {@link DiscoveryListener#onStartDiscoveryFailed}. + * + * <p> Upon successful start, application is notified when a service is found with + * {@link DiscoveryListener#onServiceFound} or when a service is lost with + * {@link DiscoveryListener#onServiceLost}. + * + * <p> Upon failure to start, service discovery is not active and application does + * not need to invoke {@link #stopServiceDiscovery} + * + * <p> The application should call {@link #stopServiceDiscovery} when discovery of this + * service type is no longer required, and/or whenever the application is paused or + * stopped. + * + * @param serviceType The service type being discovered. Examples include "_http._tcp" for + * http services or "_ipp._tcp" for printers + * @param protocolType The service discovery protocol + * @param listener The listener notifies of a successful discovery and is used + * to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}. + * Cannot be null. Cannot be in use for an active service discovery. */ public void discoverServices(String serviceType, int protocolType, DiscoveryListener listener) { - discoverServices(serviceType, protocolType, (Network) null, listener); + discoverServices(serviceType, protocolType, (Network) null, Runnable::run, listener); } /** @@ -842,17 +907,17 @@ public final class NsdManager { * <p> The application should call {@link #stopServiceDiscovery} when discovery of this * service type is no longer required, and/or whenever the application is paused or * stopped. - * * @param serviceType The service type being discovered. Examples include "_http._tcp" for * http services or "_ipp._tcp" for printers * @param protocolType The service discovery protocol * @param network Network to discover services on, or null to discover on all available networks + * @param executor Executor to run listener callbacks with * @param listener The listener notifies of a successful discovery and is used * to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}. - * Cannot be null. Cannot be in use for an active service discovery. */ public void discoverServices(@NonNull String serviceType, int protocolType, - @Nullable Network network, @NonNull DiscoveryListener listener) { + @Nullable Network network, @NonNull Executor executor, + @NonNull DiscoveryListener listener) { if (TextUtils.isEmpty(serviceType)) { throw new IllegalArgumentException("Service type cannot be empty"); } @@ -862,7 +927,7 @@ public final class NsdManager { s.setServiceType(serviceType); s.setNetwork(network); - int key = putListener(listener, s); + int key = putListener(listener, executor, s); try { mService.discoverServices(key, s); } catch (RemoteException e) { @@ -899,18 +964,18 @@ public final class NsdManager { * themselves are encouraged to use this method instead of other overloads of * {@code discoverServices}, as they will receive proper notifications when a service becomes * available or unavailable due to network changes. - * * @param serviceType The service type being discovered. Examples include "_http._tcp" for * http services or "_ipp._tcp" for printers * @param protocolType The service discovery protocol * @param networkRequest Request specifying networks that should be considered when discovering + * @param executor Executor to run listener callbacks with * @param listener The listener notifies of a successful discovery and is used * to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}. - * Cannot be null. Cannot be in use for an active service discovery. */ @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void discoverServices(@NonNull String serviceType, int protocolType, - @NonNull NetworkRequest networkRequest, @NonNull DiscoveryListener listener) { + @NonNull NetworkRequest networkRequest, @NonNull Executor executor, + @NonNull DiscoveryListener listener) { if (TextUtils.isEmpty(serviceType)) { throw new IllegalArgumentException("Service type cannot be empty"); } @@ -920,10 +985,10 @@ public final class NsdManager { NsdServiceInfo s = new NsdServiceInfo(); s.setServiceType(serviceType); - final int baseListenerKey = putListener(listener, s); + final int baseListenerKey = putListener(listener, executor, s); final PerNetworkDiscoveryTracker discoveryInfo = new PerNetworkDiscoveryTracker( - serviceType, protocolType, listener); + serviceType, protocolType, executor, listener); synchronized (mPerNetworkDiscoveryMap) { mPerNetworkDiscoveryMap.put(baseListenerKey, discoveryInfo); @@ -974,8 +1039,21 @@ public final class NsdManager { * Cannot be in use for an active service resolution. */ public void resolveService(NsdServiceInfo serviceInfo, ResolveListener listener) { + resolveService(serviceInfo, Runnable::run, listener); + } + + /** + * Resolve a discovered service. An application can resolve a service right before + * establishing a connection to fetch the IP and port details on which to setup + * the connection. + * @param serviceInfo service to be resolved + * @param executor Executor to run listener callbacks with + * @param listener to receive callback upon success or failure. + */ + public void resolveService(@NonNull NsdServiceInfo serviceInfo, + @NonNull Executor executor, @NonNull ResolveListener listener) { checkServiceInfo(serviceInfo); - int key = putListener(listener, serviceInfo); + int key = putListener(listener, executor, serviceInfo); try { mService.resolveService(key, serviceInfo); } catch (RemoteException e) { diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java index a006cd597568..f62765d07427 100644 --- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java +++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java @@ -471,11 +471,11 @@ public class NetworkStatsRecorder { public void dumpDebugLocked(ProtoOutputStream proto, long tag) { final long start = proto.start(tag); if (mPending != null) { - proto.write(NetworkStatsRecorderProto.PENDING_TOTAL_BYTES_FIELD_NUMBER, + proto.write(NetworkStatsRecorderProto.PENDING_TOTAL_BYTES, mPending.getTotalBytes()); } getOrLoadCompleteLocked().dumpDebug(proto, - NetworkStatsRecorderProto.COMPLETE_HISTORY_FIELD_NUMBER); + NetworkStatsRecorderProto.COMPLETE_HISTORY); proto.end(start); } diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java index 7db4b8c849d6..e3794e441a23 100644 --- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java +++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java @@ -2132,15 +2132,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // TODO Right now it writes all history. Should it limit to the "since-boot" log? - dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES_FIELD_NUMBER, + dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES, mActiveIfaces); - dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES_FIELD_NUMBER, + dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES, mActiveUidIfaces); - mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS_FIELD_NUMBER); - mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS_FIELD_NUMBER); - mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS_FIELD_NUMBER); + mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS); + mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS); + mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS); mUidTagRecorder.dumpDebugLocked(proto, - NetworkStatsServiceDumpProto.UID_TAG_STATS_FIELD_NUMBER); + NetworkStatsServiceDumpProto.UID_TAG_STATS); proto.flush(); } @@ -2150,8 +2150,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { for (int i = 0; i < ifaces.size(); i++) { final long start = proto.start(tag); - proto.write(NetworkInterfaceProto.INTERFACE_FIELD_NUMBER, ifaces.keyAt(i)); - ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES_FIELD_NUMBER); + proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i)); + ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES); proto.end(start); } diff --git a/services/Android.bp b/services/Android.bp index e73032198343..3613c58dbeb5 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -92,7 +92,6 @@ filegroup { ":services.searchui-sources", ":services.smartspace-sources", ":services.speech-sources", - ":services.startop.iorap-sources", ":services.systemcaptions-sources", ":services.translation-sources", ":services.texttospeech-sources", @@ -147,7 +146,6 @@ java_library { "services.searchui", "services.smartspace", "services.speech", - "services.startop", "services.systemcaptions", "services.translation", "services.texttospeech", @@ -200,7 +198,6 @@ stubs_defaults { " --hide-annotation android.annotation.Hide" + " --hide InternalClasses" + // com.android.* classes are okay in this interface // TODO: remove the --hide options below - " --hide-package com.google.android.startop.iorap" + " --hide DeprecationMismatch" + " --hide HiddenTypedefConstant", visibility: ["//frameworks/base:__subpackages__"], diff --git a/services/core/java/com/android/server/FactoryResetter.java b/services/core/java/com/android/server/FactoryResetter.java new file mode 100644 index 000000000000..30314a3683a6 --- /dev/null +++ b/services/core/java/com/android/server/FactoryResetter.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2022 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.server; + +import android.content.Context; +import android.content.pm.PackageManager; + +import com.android.internal.util.Preconditions; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * TODO(b/225012970): add javadoc from {@code com.android.server.devicepolicy.FactoryResetter} + */ +public final class FactoryResetter { + + private static final AtomicBoolean sFactoryResetting = new AtomicBoolean(false); + + /** + * Checks whether a factory reset is in progress. + */ + public static boolean isFactoryResetting() { + return sFactoryResetting.get(); + } + + /** + * @deprecated called by {@code com.android.server.devicepolicy.FactoryResetter}, won't be + * needed once that class logic is moved into this. + */ + @Deprecated + public static void setFactoryResetting(Context context) { + Preconditions.checkCallAuthorization(context.checkCallingOrSelfPermission( + android.Manifest.permission.MASTER_CLEAR) == PackageManager.PERMISSION_GRANTED); + sFactoryResetting.set(true); + } + + private FactoryResetter() { + throw new UnsupportedOperationException("Provides only static methods"); + } +} diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 9f32888262ee..210613ef3925 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -38,7 +38,6 @@ import static android.os.ParcelFileDescriptor.MODE_READ_WRITE; import static android.os.storage.OnObbStateChangeListener.ERROR_ALREADY_MOUNTED; import static android.os.storage.OnObbStateChangeListener.ERROR_COULD_NOT_MOUNT; import static android.os.storage.OnObbStateChangeListener.ERROR_COULD_NOT_UNMOUNT; -import static android.os.storage.OnObbStateChangeListener.ERROR_INTERNAL; import static android.os.storage.OnObbStateChangeListener.ERROR_NOT_MOUNTED; import static android.os.storage.OnObbStateChangeListener.ERROR_PERMISSION_DENIED; import static android.os.storage.OnObbStateChangeListener.MOUNTED; @@ -595,12 +594,6 @@ class StorageManagerService extends IStorageManager.Stub } } - /** List of crypto types. - * These must match CRYPT_TYPE_XXX in cryptfs.h AND their - * corresponding commands in CommandListener.cpp */ - public static final String[] CRYPTO_TYPES - = { "password", "default", "pattern", "pin" }; - private final Context mContext; private final ContentResolver mResolver; @@ -619,18 +612,6 @@ class StorageManagerService extends IStorageManager.Stub private final Callbacks mCallbacks; private final LockPatternUtils mLockPatternUtils; - /** - * The size of the crypto algorithm key in bits for OBB files. Currently - * Twofish is used which takes 128-bit keys. - */ - private static final int CRYPTO_ALGORITHM_KEY_SIZE = 128; - - /** - * The number of times to run SHA1 in the PBKDF2 function for OBB files. - * 1024 is reasonably secure and not too slow. - */ - private static final int PBKDF2_HASH_ROUNDS = 1024; - private static final String ANR_DELAY_MILLIS_DEVICE_CONFIG_KEY = "anr_delay_millis"; diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index fa1422bd6f63..2bb3952a346b 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -91,7 +91,7 @@ import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; -import com.android.internal.telephony.ICarrierPrivilegesListener; +import com.android.internal.telephony.ICarrierPrivilegesCallback; import com.android.internal.telephony.IOnSubscriptionsChangedListener; import com.android.internal.telephony.IPhoneStateListener; import com.android.internal.telephony.ITelephonyRegistry; @@ -151,7 +151,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { IPhoneStateListener callback; IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback; IOnSubscriptionsChangedListener onOpportunisticSubscriptionsChangedListenerCallback; - ICarrierPrivilegesListener carrierPrivilegesListener; + ICarrierPrivilegesCallback carrierPrivilegesCallback; int callerUid; int callerPid; @@ -176,8 +176,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { return (onOpportunisticSubscriptionsChangedListenerCallback != null); } - boolean matchCarrierPrivilegesListener() { - return carrierPrivilegesListener != null; + boolean matchCarrierPrivilegesCallback() { + return carrierPrivilegesCallback != null; } boolean canReadCallLog() { @@ -197,7 +197,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { + onSubscriptionsChangedListenerCallback + " onOpportunisticSubscriptionsChangedListenererCallback=" + onOpportunisticSubscriptionsChangedListenerCallback - + " carrierPrivilegesListener=" + carrierPrivilegesListener + + " carrierPrivilegesCallback=" + carrierPrivilegesCallback + " subId=" + subId + " phoneId=" + phoneId + " events=" + eventList + "}"; } } @@ -412,7 +412,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mPreciseDataConnectionStates; /** Per-phoneId snapshot of privileged packages (names + UIDs). */ - private List<Pair<List<String>, int[]>> mCarrierPrivilegeStates; + @NonNull private List<Pair<List<String>, int[]>> mCarrierPrivilegeStates; + /** Per-phoneId of CarrierService (PackageName, UID) pair. */ + @NonNull private List<Pair<String, Integer>> mCarrierServiceStates; /** * Support backward compatibility for {@link android.telephony.TelephonyDisplayInfo}. @@ -702,22 +704,23 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { cutListToSize(mPhysicalChannelConfigs, mNumPhones); cutListToSize(mLinkCapacityEstimateLists, mNumPhones); cutListToSize(mCarrierPrivilegeStates, mNumPhones); + cutListToSize(mCarrierServiceStates, mNumPhones); return; } // mNumPhones > oldNumPhones: ss -> ds switch for (int i = oldNumPhones; i < mNumPhones; i++) { - mCallState[i] = TelephonyManager.CALL_STATE_IDLE; + mCallState[i] = TelephonyManager.CALL_STATE_IDLE; mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE; mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN; mVoiceActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; - mCallIncomingNumber[i] = ""; - mServiceState[i] = new ServiceState(); - mSignalStrength[i] = null; + mCallIncomingNumber[i] = ""; + mServiceState[i] = new ServiceState(); + mSignalStrength[i] = null; mUserMobileDataState[i] = false; - mMessageWaiting[i] = false; - mCallForwarding[i] = false; + mMessageWaiting[i] = false; + mCallForwarding[i] = false; mCellIdentity[i] = null; mCellInfo.add(i, null); mImsReasonInfo.add(i, null); @@ -743,6 +746,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mAllowedNetworkTypeValue[i] = -1; mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST); mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0])); + mCarrierServiceStates.add(i, new Pair<>(null, Process.INVALID_UID)); } } @@ -809,6 +813,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mDataEnabledReason = new int[numPhones]; mLinkCapacityEstimateLists = new ArrayList<>(); mCarrierPrivilegeStates = new ArrayList<>(); + mCarrierServiceStates = new ArrayList<>(); for (int i = 0; i < numPhones; i++) { mCallState[i] = TelephonyManager.CALL_STATE_IDLE; @@ -847,6 +852,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mAllowedNetworkTypeValue[i] = -1; mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST); mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0])); + mCarrierServiceStates.add(i, new Pair<>(null, Process.INVALID_UID)); } mAppOps = mContext.getSystemService(AppOpsManager.class); @@ -2780,16 +2786,16 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override - public void addCarrierPrivilegesListener( + public void addCarrierPrivilegesCallback( int phoneId, - ICarrierPrivilegesListener callback, - String callingPackage, - String callingFeatureId) { + @NonNull ICarrierPrivilegesCallback callback, + @NonNull String callingPackage, + @NonNull String callingFeatureId) { int callerUserId = UserHandle.getCallingUserId(); mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); mContext.enforceCallingOrSelfPermission( android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, - "addCarrierPrivilegesListener"); + "addCarrierPrivilegesCallback"); if (VDBG) { log( "listen carrier privs: E pkg=" + pii(callingPackage) + " phoneId=" + phoneId @@ -2809,7 +2815,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (r == null) return; r.context = mContext; - r.carrierPrivilegesListener = callback; + r.carrierPrivilegesCallback = callback; r.callingPackage = callingPackage; r.callingFeatureId = callingFeatureId; r.callerUid = Binder.getCallingUid(); @@ -2821,10 +2827,18 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } Pair<List<String>, int[]> state = mCarrierPrivilegeStates.get(phoneId); + Pair<String, Integer> carrierServiceState = mCarrierServiceStates.get(phoneId); try { - r.carrierPrivilegesListener.onCarrierPrivilegesChanged( - Collections.unmodifiableList(state.first), - Arrays.copyOf(state.second, state.second.length)); + if (r.matchCarrierPrivilegesCallback()) { + // Here, two callbacks are triggered in quick succession on the same binder. + // In typical case, we expect the callers to care about only one or the other. + r.carrierPrivilegesCallback.onCarrierPrivilegesChanged( + Collections.unmodifiableList(state.first), + Arrays.copyOf(state.second, state.second.length)); + + r.carrierPrivilegesCallback.onCarrierServiceChanged(carrierServiceState.first, + carrierServiceState.second); + } } catch (RemoteException ex) { remove(r.binder); } @@ -2832,12 +2846,12 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override - public void removeCarrierPrivilegesListener( - ICarrierPrivilegesListener callback, String callingPackage) { + public void removeCarrierPrivilegesCallback( + @NonNull ICarrierPrivilegesCallback callback, @NonNull String callingPackage) { mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); mContext.enforceCallingOrSelfPermission( android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, - "removeCarrierPrivilegesListener"); + "removeCarrierPrivilegesCallback"); remove(callback.asBinder()); } @@ -2860,13 +2874,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { for (Record r : mRecords) { // Listeners are per-slot, not per-subscription. This is to provide a stable // view across SIM profile switches. - if (!r.matchCarrierPrivilegesListener() + if (!r.matchCarrierPrivilegesCallback() || !idMatch(r, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phoneId)) { continue; } try { // Make sure even in-process listeners can't modify the values. - r.carrierPrivilegesListener.onCarrierPrivilegesChanged( + r.carrierPrivilegesCallback.onCarrierPrivilegesChanged( Collections.unmodifiableList(privilegedPackageNames), Arrays.copyOf(privilegedUids, privilegedUids.length)); } catch (RemoteException ex) { @@ -2878,6 +2892,34 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override + public void notifyCarrierServiceChanged(int phoneId, @Nullable String packageName, int uid) { + if (!checkNotifyPermission("notifyCarrierServiceChanged")) return; + if (!validatePhoneId(phoneId)) return; + if (VDBG) { + log("notifyCarrierServiceChanged: phoneId=" + phoneId + + ", package=" + pii(packageName) + ", uid=" + uid); + } + + synchronized (mRecords) { + mCarrierServiceStates.set( + phoneId, new Pair<>(packageName, uid)); + for (Record r : mRecords) { + // Listeners are per-slot, not per-subscription. + if (!r.matchCarrierPrivilegesCallback() + || !idMatch(r, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phoneId)) { + continue; + } + try { + r.carrierPrivilegesCallback.onCarrierServiceChanged(packageName, uid); + } catch (RemoteException ex) { + mRemoveList.add(r.binder); + } + } + handleRemoveListLocked(); + } + } + + @Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); @@ -2931,6 +2973,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println( "mCarrierPrivilegeState=<packages=" + pii(carrierPrivilegeState.first) + ", uids=" + Arrays.toString(carrierPrivilegeState.second) + ">"); + Pair<String, Integer> carrierServiceState = mCarrierServiceStates.get(i); + pw.println("mCarrierServiceState=<package=" + pii(carrierServiceState.first) + + ", uid=" + carrierServiceState.second + ">"); pw.decreaseIndent(); } diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 5a43f4d6c3dc..c465be149ac2 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -106,6 +106,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.widget.LockPatternUtils; +import com.android.server.FactoryResetter; import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.SystemServiceManager; @@ -1756,6 +1757,10 @@ class UserController implements Handler.Callback { Slogf.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user"); return false; } + if (FactoryResetter.isFactoryResetting()) { + Slogf.w(TAG, "Cannot switch to User #" + targetUserId + ": factory reset in progress"); + return false; + } boolean userSwitchUiEnabled; synchronized (mLock) { if (!mInitialized) { diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java index 108e7bcb23bb..b9efdf551646 100644 --- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java +++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java @@ -71,7 +71,6 @@ import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; -import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @@ -222,8 +221,10 @@ public class MultipathPolicyTracker { "Can't get TelephonyManager for subId %d", mSubId)); } - subscriberId = Objects.requireNonNull(tele.getSubscriberId(), - "Null subscriber Id for subId " + mSubId); + subscriberId = tele.getSubscriberId(); + if (subscriberId == null) { + throw new IllegalStateException("Null subscriber Id for subId " + mSubId); + } mNetworkTemplate = new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE) .setSubscriberIds(Set.of(subscriberId)) .setMeteredness(NetworkStats.METERED_YES) diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java index 5a5f9ef3b6aa..f16ee9275879 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -256,6 +256,17 @@ public class Installer extends SystemService { } /** + * Sets in Installd that it is first boot after data wipe + */ + public void setFirstBoot() throws InstallerException { + try { + mInstalld.setFirstBoot(); + } catch (RemoteException e) { + throw InstallerException.from(e); + } + } + + /** * Class that collects multiple {@code installd} operations together in an * attempt to more efficiently execute them in bulk. * <p> diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 94dd4beeab9b..fad18d235001 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -7554,6 +7554,16 @@ public class PackageManagerService extends IPackageManager.Stub /* excludePreCreated= */ false)); t.traceEnd(); + if (mFirstBoot) { + t.traceBegin("setFirstBoot: "); + try { + mInstaller.setFirstBoot(); + } catch (InstallerException e) { + Slog.w(TAG, "Could not set First Boot: ", e); + } + t.traceEnd(); + } + mPermissionManager.readLegacyPermissionsTEMP(mSettings.mPermissions); mPermissionManager.readLegacyPermissionStateTEMP(); diff --git a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java index 30e261725a73..092853f298c2 100644 --- a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java +++ b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java @@ -39,7 +39,7 @@ import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; -import android.telephony.TelephonyManager.CarrierPrivilegesListener; +import android.telephony.TelephonyManager.CarrierPrivilegesCallback; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; @@ -98,8 +98,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver { @NonNull private final OnSubscriptionsChangedListener mSubscriptionChangedListener; @NonNull - private final List<CarrierPrivilegesListener> mCarrierPrivilegesChangedListeners = - new ArrayList<>(); + private final List<CarrierPrivilegesCallback> mCarrierPrivilegesCallbacks = new ArrayList<>(); @NonNull private TelephonySubscriptionSnapshot mCurrentSnapshot; @@ -151,20 +150,21 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver { executor, mSubscriptionChangedListener); mTelephonyManager.registerTelephonyCallback(executor, mActiveDataSubIdListener); - registerCarrierPrivilegesListeners(); + registerCarrierPrivilegesCallbacks(); } - private void registerCarrierPrivilegesListeners() { + // TODO(b/221306368): Refactor with the new onCarrierServiceChange in the new CPCallback + private void registerCarrierPrivilegesCallbacks() { final HandlerExecutor executor = new HandlerExecutor(mHandler); final int modemCount = mTelephonyManager.getActiveModemCount(); try { for (int i = 0; i < modemCount; i++) { - CarrierPrivilegesListener carrierPrivilegesListener = - new CarrierPrivilegesListener() { + CarrierPrivilegesCallback carrierPrivilegesCallback = + new CarrierPrivilegesCallback() { @Override public void onCarrierPrivilegesChanged( - @NonNull List<String> privilegedPackageNames, - @NonNull int[] privilegedUids) { + @NonNull Set<String> privilegedPackageNames, + @NonNull Set<Integer> privilegedUids) { // Re-trigger the synchronous check (which is also very cheap due // to caching in CarrierPrivilegesTracker). This allows consistency // with the onSubscriptionsChangedListener and broadcasts. @@ -172,9 +172,9 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver { } }; - mTelephonyManager.addCarrierPrivilegesListener( - i, executor, carrierPrivilegesListener); - mCarrierPrivilegesChangedListeners.add(carrierPrivilegesListener); + mTelephonyManager.registerCarrierPrivilegesCallback( + i, executor, carrierPrivilegesCallback); + mCarrierPrivilegesCallbacks.add(carrierPrivilegesCallback); } } catch (IllegalArgumentException e) { Slog.wtf(TAG, "Encounted exception registering carrier privileges listeners", e); @@ -191,15 +191,15 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver { mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionChangedListener); mTelephonyManager.unregisterTelephonyCallback(mActiveDataSubIdListener); - unregisterCarrierPrivilegesListeners(); + unregisterCarrierPrivilegesCallbacks(); } - private void unregisterCarrierPrivilegesListeners() { - for (CarrierPrivilegesListener carrierPrivilegesListener : - mCarrierPrivilegesChangedListeners) { - mTelephonyManager.removeCarrierPrivilegesListener(carrierPrivilegesListener); + private void unregisterCarrierPrivilegesCallbacks() { + for (CarrierPrivilegesCallback carrierPrivilegesCallback : + mCarrierPrivilegesCallbacks) { + mTelephonyManager.unregisterCarrierPrivilegesCallback(carrierPrivilegesCallback); } - mCarrierPrivilegesChangedListeners.clear(); + mCarrierPrivilegesCallbacks.clear(); } /** @@ -283,7 +283,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver { } private void handleActionMultiSimConfigChanged(Context context, Intent intent) { - unregisterCarrierPrivilegesListeners(); + unregisterCarrierPrivilegesCallbacks(); // Clear invalid slotIds from the mReadySubIdsBySlotId map. final int modemCount = mTelephonyManager.getActiveModemCount(); @@ -296,7 +296,7 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver { } } - registerCarrierPrivilegesListeners(); + registerCarrierPrivilegesCallbacks(); handleSubscriptionsChanged(); } diff --git a/services/core/java/com/android/server/wm/HighRefreshRateDenylist.java b/services/core/java/com/android/server/wm/HighRefreshRateDenylist.java index 92baadf5ee69..7a6e86ce7919 100644 --- a/services/core/java/com/android/server/wm/HighRefreshRateDenylist.java +++ b/services/core/java/com/android/server/wm/HighRefreshRateDenylist.java @@ -41,9 +41,6 @@ class HighRefreshRateDenylist { private final String[] mDefaultDenylist; private final Object mLock = new Object(); - private DeviceConfigInterface mDeviceConfig; - private OnPropertiesChangedListener mListener = new OnPropertiesChangedListener(); - static HighRefreshRateDenylist create(@NonNull Resources r) { return new HighRefreshRateDenylist(r, DeviceConfigInterface.REAL); } @@ -51,10 +48,9 @@ class HighRefreshRateDenylist { @VisibleForTesting HighRefreshRateDenylist(Resources r, DeviceConfigInterface deviceConfig) { mDefaultDenylist = r.getStringArray(R.array.config_highRefreshRateBlacklist); - mDeviceConfig = deviceConfig; - mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, - BackgroundThread.getExecutor(), mListener); - final String property = mDeviceConfig.getProperty(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, + deviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, + BackgroundThread.getExecutor(), new OnPropertiesChangedListener()); + final String property = deviceConfig.getProperty(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, KEY_HIGH_REFRESH_RATE_BLACKLIST); updateDenylist(property); } @@ -95,14 +91,6 @@ class HighRefreshRateDenylist { } } - /** Used to prevent WmTests leaking issues. */ - @VisibleForTesting - void dispose() { - mDeviceConfig.removeOnPropertiesChangedListener(mListener); - mDeviceConfig = null; - mDenylistedPackages.clear(); - } - private class OnPropertiesChangedListener implements DeviceConfig.OnPropertiesChangedListener { public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) { if (properties.getKeyset().contains(KEY_HIGH_REFRESH_RATE_BLACKLIST)) { diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index db6d3ce69cc8..15a294ee7484 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -971,9 +971,19 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { } void setBackgroundColor(@ColorInt int colorInt) { + setBackgroundColor(colorInt, false /* restore */); + } + + void setBackgroundColor(@ColorInt int colorInt, boolean restore) { mBackgroundColor = colorInt; Color color = Color.valueOf(colorInt); - mColorLayerCounter++; + + // We don't want to increment the mColorLayerCounter if we are restoring the background + // color after a surface migration because in that case the mColorLayerCounter already + // accounts for setting that background color. + if (!restore) { + mColorLayerCounter++; + } // Only apply the background color if the TDA is actually attached and has a valid surface // to set the background color on. We still want to keep track of the background color state @@ -1002,7 +1012,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { super.migrateToNewSurfaceControl(t); if (mColorLayerCounter > 0) { - setBackgroundColor(mBackgroundColor); + setBackgroundColor(mBackgroundColor, true /* restore */); } // As TaskDisplayArea is getting a new surface, reparent and reorder the child surfaces. diff --git a/services/core/java/com/android/server/wm/WindowManagerConstants.java b/services/core/java/com/android/server/wm/WindowManagerConstants.java index a5ebf9ac74b9..ba62091c694d 100644 --- a/services/core/java/com/android/server/wm/WindowManagerConstants.java +++ b/services/core/java/com/android/server/wm/WindowManagerConstants.java @@ -91,12 +91,6 @@ final class WindowManagerConstants { updateSystemGestureExcludedByPreQStickyImmersive(); } - @VisibleForTesting - void dispose() { - mDeviceConfig.removeOnPropertiesChangedListener(mListenerAndroid); - mDeviceConfig.removeOnPropertiesChangedListener(mListenerWindowManager); - } - private void onAndroidPropertiesChanged(DeviceConfig.Properties properties) { synchronized (mGlobalLock) { boolean updateSystemGestureExclusionLimit = false; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/FactoryResetter.java b/services/devicepolicy/java/com/android/server/devicepolicy/FactoryResetter.java index 964be38943bf..c72e1eabb086 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/FactoryResetter.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/FactoryResetter.java @@ -16,6 +16,8 @@ package com.android.server.devicepolicy; +import static com.android.server.FactoryResetter.setFactoryResetting; + import android.annotation.Nullable; import android.app.admin.DevicePolicySafetyChecker; import android.content.Context; @@ -36,7 +38,10 @@ import java.util.Objects; /** * Entry point for "factory reset" requests. + * + * @deprecated TODO(b/225012970): should be moved to {@code com.android.server.FactoryResetter} */ +@Deprecated public final class FactoryResetter { private static final String TAG = FactoryResetter.class.getSimpleName(); @@ -60,6 +65,8 @@ public final class FactoryResetter { Preconditions.checkCallAuthorization(mContext.checkCallingOrSelfPermission( android.Manifest.permission.MASTER_CLEAR) == PackageManager.PERMISSION_GRANTED); + setFactoryResetting(mContext); + if (mSafetyChecker == null) { factoryResetInternalUnchecked(); return true; diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 67b656bf2bfc..77d40d247622 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -206,8 +206,6 @@ import com.android.server.wm.WindowManagerService; import dalvik.system.VMRuntime; -import com.google.android.startop.iorap.IorapForwardingService; - import java.io.File; import java.io.FileDescriptor; import java.io.IOException; @@ -1552,10 +1550,6 @@ public final class SystemServer implements Dumpable { mSystemServiceManager.startService(PinnerService.class); t.traceEnd(); - t.traceBegin("IorapForwardingService"); - mSystemServiceManager.startService(IorapForwardingService.class); - t.traceEnd(); - if (Build.IS_DEBUGGABLE && ProfcollectForwardingService.enabled()) { t.traceBegin("ProfcollectForwardingService"); mSystemServiceManager.startService(ProfcollectForwardingService.class); diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java index d0205ae24f85..ca31efcdf3d2 100644 --- a/services/midi/java/com/android/server/midi/MidiService.java +++ b/services/midi/java/com/android/server/midi/MidiService.java @@ -340,6 +340,11 @@ public class MidiService extends IMidiManager.Stub { IBinder binder = server.asBinder(); mDevicesByServer.remove(binder); + // Clearing mDeviceStatus is needed because setDeviceStatus() + // relies on finding the device in mDevicesByServer. + // So the status can no longer be updated after we remove it. + // Then we can end up with input ports that are stuck open. + mDeviceStatus = null; try { server.closeDevice(); diff --git a/services/startop/Android.bp b/services/startop/Android.bp deleted file mode 100644 index c56c463d0168..000000000000 --- a/services/startop/Android.bp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2018 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 { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - // SPDX-license-identifier-MIT - // SPDX-license-identifier-Unicode-DFS - default_applicable_licenses: ["frameworks_base_license"], -} - -java_library_static { - name: "services.startop", - defaults: ["platform_service_defaults"], - - static_libs: [ - // frameworks/base/startop/iorap - "services.startop.iorap", - ], -} diff --git a/services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java b/services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java index 457c8db9fdf3..4ffa0fbec758 100644 --- a/services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/devicepolicy/FactoryResetterTest.java @@ -14,11 +14,13 @@ * limitations under the License. */ +// TODO(b/225012970): should be moved to com.android.server package com.android.server.devicepolicy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; +import static com.android.server.FactoryResetter.isFactoryResetting; import static com.google.common.truth.Truth.assertThat; @@ -165,6 +167,7 @@ public final class FactoryResetterTest { .factoryReset(); assertThat(success).isTrue(); + assertThat(isFactoryResetting()).isTrue(); verifyWipeAdoptableStorageCalled(); verifyWipeFactoryResetProtectionNotCalled(); verifyRebootWipeUserDataMinimumArgsCalled(); @@ -179,6 +182,7 @@ public final class FactoryResetterTest { .build().factoryReset(); assertThat(success).isTrue(); + assertThat(isFactoryResetting()).isTrue(); verifyWipeAdoptableStorageNotCalled(); verifyWipeFactoryResetProtectionCalled(); verifyRebootWipeUserDataMinimumArgsCalled(); @@ -198,6 +202,7 @@ public final class FactoryResetterTest { .build().factoryReset(); assertThat(success).isTrue(); + assertThat(isFactoryResetting()).isTrue(); verifyWipeAdoptableStorageCalled(); verifyWipeFactoryResetProtectionCalled(); verifyRebootWipeUserDataAllArgsCalled(); @@ -211,6 +216,7 @@ public final class FactoryResetterTest { .setSafetyChecker(mSafetyChecker).build().factoryReset(); assertThat(success).isFalse(); + assertThat(isFactoryResetting()).isTrue(); verifyWipeAdoptableStorageNotCalled(); verifyWipeFactoryResetProtectionNotCalled(); verifyRebootWipeUserDataNotCalled(); @@ -238,6 +244,7 @@ public final class FactoryResetterTest { .build().factoryReset(); assertThat(success).isFalse(); + assertThat(isFactoryResetting()).isTrue(); verifyWipeAdoptableStorageCalled(); verifyWipeFactoryResetProtectionCalled(); verifyRebootWipeUserDataAllArgsCalled(); diff --git a/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateDenylistTest.java b/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateDenylistTest.java index dfc2e35ffedf..38ab683f81fe 100644 --- a/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateDenylistTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/HighRefreshRateDenylistTest.java @@ -33,7 +33,6 @@ import com.android.internal.R; import com.android.internal.util.Preconditions; import com.android.server.testutils.FakeDeviceConfigInterface; -import org.junit.After; import org.junit.Test; import java.util.concurrent.Executor; @@ -51,11 +50,6 @@ public class HighRefreshRateDenylistTest { private HighRefreshRateDenylist mDenylist; - @After - public void tearDown() { - mDenylist.dispose(); - } - @Test public void testDefaultDenylist() { final Resources r = createResources(APP1, APP2); diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java index f41ca65c9439..db937c100b62 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java @@ -18,6 +18,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.provider.DeviceConfig.NAMESPACE_CONSTRAIN_DISPLAY_APIS; import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader; import static android.view.Display.DEFAULT_DISPLAY; @@ -27,6 +28,7 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean; import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyString; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq; @@ -36,6 +38,9 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.nullable; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; +import static org.mockito.Mockito.CALLS_REAL_METHODS; +import static org.mockito.Mockito.withSettings; + import android.app.ActivityManagerInternal; import android.app.AppOpsManager; import android.app.usage.UsageStatsManagerInternal; @@ -57,6 +62,7 @@ import android.os.PowerManagerInternal; import android.os.PowerSaveState; import android.os.StrictMode; import android.os.UserHandle; +import android.provider.DeviceConfig; import android.util.Log; import android.view.InputChannel; import android.view.Surface; @@ -83,10 +89,12 @@ import com.android.server.uri.UriGrantsManagerInternal; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; +import org.mockito.MockSettings; import org.mockito.Mockito; import org.mockito.quality.Strictness; import java.io.File; +import java.util.ArrayList; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; @@ -107,6 +115,13 @@ public class SystemServicesTestRule implements TestRule { .getSystemService(PowerManager.class).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); private PowerManager.WakeLock mStubbedWakeLock; + /** + * The captured listeners will be unregistered in {@link #tearDown()} to avoid keeping static + * references of test instances from DeviceConfig. + */ + private final ArrayList<DeviceConfig.OnPropertiesChangedListener> mDeviceConfigListeners = + new ArrayList<>(); + private Description mDescription; private Context mContext; private StaticMockitoSession mMockitoSession; @@ -144,19 +159,27 @@ public class SystemServicesTestRule implements TestRule { Log.e("SystemServicesTestRule", "Suppressed: ", throwable); t.addSuppressed(throwable); } - throw t; + throwable = t; } - if (throwable != null) throw throwable; } + if (throwable != null) throw throwable; } }; } private void setUp() { + // Use stubOnly() to reduce memory usage if it doesn't need verification. + final MockSettings spyStubOnly = withSettings().stubOnly() + .defaultAnswer(CALLS_REAL_METHODS); + final MockSettings mockStubOnly = withSettings().stubOnly(); + // Return mocked services: LocalServices.getService + // Avoid leakage: DeviceConfig.addOnPropertiesChangedListener, LockGuard.installLock + // Watchdog.getInstance/addMonitor mMockitoSession = mockitoSession() - .spyStatic(LocalServices.class) - .mockStatic(LockGuard.class) - .mockStatic(Watchdog.class) + .mockStatic(LocalServices.class, spyStubOnly) + .mockStatic(DeviceConfig.class, spyStubOnly) + .mockStatic(LockGuard.class, mockStubOnly) + .mockStatic(Watchdog.class, mockStubOnly) .strictness(Strictness.LENIENT) .startMocking(); @@ -168,6 +191,16 @@ public class SystemServicesTestRule implements TestRule { private void setUpSystemCore() { doReturn(mock(Watchdog.class)).when(Watchdog::getInstance); + doAnswer(invocation -> { + // Exclude CONSTRAIN_DISPLAY_APIS because ActivityRecord#sConstrainDisplayApisConfig + // only registers once and it doesn't reference to outside. + if (!NAMESPACE_CONSTRAIN_DISPLAY_APIS.equals(invocation.getArgument(0))) { + mDeviceConfigListeners.add(invocation.getArgument(2)); + } + // SizeCompatTests uses setNeverConstrainDisplayApisFlag, and ActivityRecordTests + // uses splash_screen_exception_list. So still execute real registration. + return invocation.callRealMethod(); + }).when(() -> DeviceConfig.addOnPropertiesChangedListener(anyString(), any(), any())); mContext = getInstrumentation().getTargetContext(); spyOn(mContext); @@ -346,11 +379,10 @@ public class SystemServicesTestRule implements TestRule { // Unregister display listener from root to avoid issues with subsequent tests. mContext.getSystemService(DisplayManager.class) .unregisterDisplayListener(mAtmService.mRootWindowContainer); - // The constructor of WindowManagerService registers WindowManagerConstants and - // HighRefreshRateBlacklist with DeviceConfig. We need to undo that here to avoid - // leaking mWmService. - mWmService.mConstants.dispose(); - mWmService.mHighRefreshRateDenylist.dispose(); + + for (int i = mDeviceConfigListeners.size() - 1; i >= 0; i--) { + DeviceConfig.removeOnPropertiesChangedListener(mDeviceConfigListeners.get(i)); + } // This makes sure the posted messages without delay are processed, e.g. // DisplayPolicy#release, WindowManagerService#setAnimationScale. diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRuleTest.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRuleTest.java index 4056c7195c9b..2e7cc2736410 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRuleTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRuleTest.java @@ -16,59 +16,64 @@ package com.android.server.wm; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.fail; import android.platform.test.annotations.Presubmit; -import org.junit.Rule; +import com.android.internal.util.GcUtils; + import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.runners.model.Statement; -import java.io.IOException; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.function.Predicate; @Presubmit public class SystemServicesTestRuleTest { - @Rule - public ExpectedException mExpectedException = ExpectedException.none(); @Test - public void testRule_rethrows_unchecked_exceptions() throws Throwable { - final SystemServicesTestRule mWmsRule = new SystemServicesTestRule(); - Statement statement = new Statement() { - @Override - public void evaluate() throws Throwable { - throw new RuntimeException("A failing test!"); - } - }; - mExpectedException.expect(RuntimeException.class); - mWmsRule.apply(statement, null /* Description*/).evaluate(); + public void testRule_rethrows_throwable() { + assertThrows(Throwable.class, () -> applyRule(rule -> false)); } @Test - public void testRule_rethrows_checked_exceptions() throws Throwable { - final SystemServicesTestRule mWmsRule = new SystemServicesTestRule(); - Statement statement = new Statement() { - @Override - public void evaluate() throws Throwable { - throw new IOException("A failing test!"); + public void testRule_ranSuccessfully() throws Throwable { + final int iterations = 5; + final ArrayList<WeakReference<WindowManagerService>> wmsRefs = new ArrayList<>(); + for (int i = 0; i < iterations; i++) { + applyRule(rule -> { + final WindowManagerService wms = rule.getWindowManagerService(); + assertNotNull(wms); + wmsRefs.add(new WeakReference<>(wms)); + return true; + }); + } + assertEquals(iterations, wmsRefs.size()); + + GcUtils.runGcAndFinalizersSync(); + // Only ensure that at least one instance is released because some references may be kept + // temporally by the message of other thread or single static reference. + for (int i = wmsRefs.size() - 1; i >= 0; i--) { + if (wmsRefs.get(i).get() == null) { + return; } - }; - mExpectedException.expect(IOException.class); - mWmsRule.apply(statement, null /* Description*/).evaluate(); + } + fail("WMS instance is leaked"); } - @Test - public void testRule_ranSuccessfully() throws Throwable { - final boolean[] testRan = {false}; - final SystemServicesTestRule mWmsRule = new SystemServicesTestRule(); - Statement statement = new Statement() { + private static void applyRule(Predicate<SystemServicesTestRule> action) throws Throwable { + final SystemServicesTestRule wmsRule = new SystemServicesTestRule(); + wmsRule.apply(new Statement() { @Override public void evaluate() throws Throwable { - testRan[0] = true; + if (!action.test(wmsRule)) { + throw new Throwable("A failing test!"); + } } - }; - mWmsRule.apply(statement, null /* Description*/).evaluate(); - assertTrue(testRan[0]); + }, null /* description */).evaluate(); } } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java index 823cc07d9f7b..d7a5f0a52ddf 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java @@ -115,6 +115,7 @@ final class HotwordDetectionConnection { private static final Duration MAX_UPDATE_TIMEOUT_DURATION = Duration.ofMillis(MAX_UPDATE_TIMEOUT_MILLIS); private static final long RESET_DEBUG_HOTWORD_LOGGING_TIMEOUT_MILLIS = 60 * 60 * 1000; // 1 hour + private static final int MAX_ISOLATED_PROCESS_NUMBER = 10; // Hotword metrics private static final int METRICS_INIT_UNKNOWN_TIMEOUT = @@ -873,7 +874,8 @@ final class HotwordDetectionConnection { ServiceConnection createLocked() { ServiceConnection connection = new ServiceConnection(mContext, mIntent, mBindingFlags, mUser, - IHotwordDetectionService.Stub::asInterface, ++mRestartCount); + IHotwordDetectionService.Stub::asInterface, + mRestartCount++ % MAX_ISOLATED_PROCESS_NUMBER); connection.connect(); updateAudioFlinger(connection, mAudioFlinger); diff --git a/startop/iorap/Android.bp b/startop/iorap/Android.bp deleted file mode 100644 index 4fdf34cc1814..000000000000 --- a/startop/iorap/Android.bp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2018 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 { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -filegroup { - name: "services.startop.iorap-javasources", - srcs: ["src/**/*.java"], - path: "src", - visibility: ["//visibility:private"], -} - -filegroup { - name: "services.startop.iorap-sources", - srcs: [ - ":services.startop.iorap-javasources", - ":iorap-aidl", - ], - visibility: ["//frameworks/base/services:__subpackages__"], -} - -java_library_static { - name: "services.startop.iorap", - srcs: [":services.startop.iorap-sources"], - libs: ["services.core"], -} diff --git a/startop/iorap/TEST_MAPPING b/startop/iorap/TEST_MAPPING deleted file mode 100644 index 8c9d4dfb0894..000000000000 --- a/startop/iorap/TEST_MAPPING +++ /dev/null @@ -1,12 +0,0 @@ -{ - "presubmit": [ - { - "name": "libiorap-java-tests" - } - ], - "imports": [ - { - "path": "system/iorap" - } - ] -} diff --git a/startop/iorap/functional_tests/Android.bp b/startop/iorap/functional_tests/Android.bp deleted file mode 100644 index 43c61551cdec..000000000000 --- a/startop/iorap/functional_tests/Android.bp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2020 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 { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -android_test { - name: "iorap-functional-tests", - srcs: ["src/**/*.java"], - data: [":iorap-functional-test-apps"], - static_libs: [ - // Non-test dependencies - // library under test - "services.startop.iorap", - // Test Dependencies - // test android dependencies - "platform-test-annotations", - "androidx.test.rules", - "androidx.test.ext.junit", - "androidx.test.uiautomator_uiautomator", - // test framework dependencies - "truth-prebuilt", - ], - dxflags: ["--multi-dex"], - test_suites: ["device-tests"], - compile_multilib: "both", - libs: [ - "android.test.base", - "android.test.runner", - ], - certificate: "platform", - platform_apis: true, -} diff --git a/startop/iorap/functional_tests/AndroidManifest.xml b/startop/iorap/functional_tests/AndroidManifest.xml deleted file mode 100644 index 6bddc4a39577..000000000000 --- a/startop/iorap/functional_tests/AndroidManifest.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2020 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. ---> -<!--suppress AndroidUnknownAttribute --> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.google.android.startop.iorap.tests" - android:sharedUserId="com.google.android.startop.iorap.tests.functional" - android:versionCode="1" - android:versionName="1.0" > - - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - <!--suppress AndroidDomInspection --> - <instrumentation - android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="com.google.android.startop.iorap.tests" /> - - <!-- - 'debuggable=true' is required to properly load mockito jvmti dependencies, - otherwise it gives the following error at runtime: - - Openjdkjvmti plugin was loaded on a non-debuggable Runtime. - Plugin was loaded too late to change runtime state to DEBUGGABLE. --> - <application android:debuggable="true"> - <uses-library android:name="android.test.runner" /> - </application> -</manifest> diff --git a/startop/iorap/functional_tests/AndroidTest.xml b/startop/iorap/functional_tests/AndroidTest.xml deleted file mode 100644 index 31d4f6c47b11..000000000000 --- a/startop/iorap/functional_tests/AndroidTest.xml +++ /dev/null @@ -1,70 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2020 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. ---> - -<configuration description="Runs iorap-functional-tests."> - <option name="test-suite-tag" value="apct" /> - <option name="test-suite-tag" value="apct-instrumentation" /> - <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> - <option name="cleanup-apks" value="true" /> - <option name="test-file-name" value="iorap-functional-tests.apk" /> - </target_preparer> - - <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/> - - <target_preparer - class="com.android.tradefed.targetprep.DeviceSetup"> - - <!-- iorapd does not pick up the above changes until we restart it --> - <option name="run-command" value="stop iorapd" /> - - <!-- Clean up the existing iorap database. --> - <option name="run-command" value="rm -r /data/misc/iorapd/*" /> - <option name="run-command" value="sleep 1" /> - - <!-- Set system properties to enable perfetto tracing, readahead and detailed logging. --> - <option name="run-command" value="setprop iorapd.perfetto.enable true" /> - <option name="run-command" value="setprop iorapd.readahead.enable true" /> - <option name="run-command" value="setprop iorapd.log.verbose true" /> - - <option name="run-command" value="start iorapd" /> - - <!-- give it some time to restart the service; otherwise the first unit test might fail --> - <option name="run-command" value="sleep 1" /> - </target_preparer> - - <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"> - <option name="cleanup" value="true" /> - <option name="abort-on-push-failure" value="true" /> - <option name="push-file" - key="iorap_test_app_v1.apk" - value="/data/misc/iorapd/iorap_test_app_v1.apk" /> - <option name="push-file" - key="iorap_test_app_v2.apk" - value="/data/misc/iorapd/iorap_test_app_v2.apk" /> - <option name="push-file" - key="iorap_test_app_v3.apk" - value="/data/misc/iorapd/iorap_test_app_v3.apk" /> - </target_preparer> - - <test class="com.android.tradefed.testtype.AndroidJUnitTest" > - <option name="package" value="com.google.android.startop.iorap.tests" /> - <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> - <!-- test-timeout unit is ms, value = 30 min --> - <option name="test-timeout" value="1800000" /> - </test> - -</configuration> - diff --git a/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java b/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java deleted file mode 100644 index 5352be6f283f..000000000000 --- a/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Copyright (C) 2020 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.google.android.startop.iorapd; - -import static androidx.test.core.app.ApplicationProvider.getApplicationContext; -import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; - -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - -import android.content.Context; -import android.content.Intent; -import android.database.Cursor; -import android.database.DatabaseUtils; -import android.database.sqlite.SQLiteDatabase; -import android.util.Log; - -import androidx.test.InstrumentationRegistry; -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.UiDevice; -import androidx.test.uiautomator.Until; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.File; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.time.Duration; -import java.util.ArrayList; -import java.util.concurrent.TimeUnit; -import java.util.Date; -import java.util.function.BooleanSupplier; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.List; -import java.text.SimpleDateFormat; - -/** - * Test for the work flow of iorap. - * - * <p> This test tests the function of iorap from: - * perfetto collection -> compilation -> prefetching -> version update -> perfetto collection. - */ -@RunWith(AndroidJUnit4.class) -public class IorapWorkFlowTest { - private static final String TAG = "IorapWorkFlowTest"; - - private static final String TEST_APP_VERSION_ONE_PATH = "/data/misc/iorapd/iorap_test_app_v1.apk"; - private static final String TEST_APP_VERSION_TWO_PATH = "/data/misc/iorapd/iorap_test_app_v2.apk"; - private static final String TEST_APP_VERSION_THREE_PATH = "/data/misc/iorapd/iorap_test_app_v3.apk"; - - private static final String DB_PATH = "/data/misc/iorapd/sqlite.db"; - private static final Duration TIMEOUT = Duration.ofSeconds(300L); - - private UiDevice mDevice; - - @Before - public void setUp() throws Exception { - // Initialize UiDevice instance - mDevice = UiDevice.getInstance(getInstrumentation()); - - // Start from the home screen - mDevice.pressHome(); - - // Wait for launcher - final String launcherPackage = mDevice.getLauncherPackageName(); - assertThat(launcherPackage, notNullValue()); - mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), TIMEOUT.getSeconds()); - } - - @After - public void tearDown() throws Exception { - String packageName = "com.example.ioraptestapp"; - uninstallApk(packageName); - } - - @Test (timeout = 300000) - public void testNormalWorkFlow() throws Exception { - assertThat(mDevice, notNullValue()); - - // Install test app version one - installApk(TEST_APP_VERSION_ONE_PATH); - String packageName = "com.example.ioraptestapp"; - String activityName = "com.example.ioraptestapp.MainActivity"; - - // Perfetto trace collection phase. - assertTrue(startAppForPerfettoTrace( - packageName, activityName, /*version=*/1L)); - assertTrue(startAppForPerfettoTrace( - packageName, activityName, /*version=*/1L)); - assertTrue(startAppForPerfettoTrace( - packageName, activityName, /*version=*/1L)); - - // Trigger maintenance service for compilation. - TimeUnit.SECONDS.sleep(5L); - assertTrue(compile(packageName, activityName, /*version=*/1L)); - - // Run app with prefetching - assertTrue(startAppWithCompiledTrace( - packageName, activityName, /*version=*/1L)); - } - - @Test (timeout = 300000) - public void testUpdateApp() throws Exception { - assertThat(mDevice, notNullValue()); - - // Install test app version two, - String packageName = "com.example.ioraptestapp"; - String activityName = "com.example.ioraptestapp.MainActivity"; - installApk(TEST_APP_VERSION_TWO_PATH); - - // Perfetto trace collection phase. - assertTrue(startAppForPerfettoTrace( - packageName, activityName, /*version=*/2L)); - assertTrue(startAppForPerfettoTrace( - packageName, activityName, /*version=*/2L)); - assertTrue(startAppForPerfettoTrace( - packageName, activityName, /*version=*/2L)); - - // Trigger maintenance service for compilation. - TimeUnit.SECONDS.sleep(5L); - assertTrue(compile(packageName, activityName, /*version=*/2L)); - - // Run app with prefetching - assertTrue(startAppWithCompiledTrace( - packageName, activityName, /*version=*/2L)); - - // Update test app to version 3 - installApk(TEST_APP_VERSION_THREE_PATH); - - // Rerun app, should do pefetto tracing. - assertTrue(startAppForPerfettoTrace( - packageName, activityName, /*version=*/3L)); - } - - private static void installApk(String apkPath) throws Exception { - // Disable the selinux to allow pm install apk in the dir. - executeShellCommand("setenforce 0"); - executeShellCommand("pm install -r -d " + apkPath); - executeShellCommand("setenforce 1"); - - } - - private static void uninstallApk(String apkPath) throws Exception { - executeShellCommand("pm uninstall " + apkPath); - } - - /** - * Starts the testing app to collect the perfetto trace. - * - * @param expectPerfettoTraceCount is the expected count of perfetto traces. - */ - private boolean startAppForPerfettoTrace( - String packageName, String activityName, long version) - throws Exception { - LogcatTimestamp timestamp = runAppOnce(packageName, activityName); - return waitForPerfettoTraceSavedFromLogcat( - packageName, activityName, version, timestamp); - } - - private boolean startAppWithCompiledTrace( - String packageName, String activityName, long version) - throws Exception { - LogcatTimestamp timestamp = runAppOnce(packageName, activityName); - return waitForPrefetchingFromLogcat( - packageName, activityName, version, timestamp); - } - - private LogcatTimestamp runAppOnce(String packageName, String activityName) throws Exception { - // Close the specified app if it's open - closeApp(packageName); - LogcatTimestamp timestamp = new LogcatTimestamp(); - // Launch the specified app - startApp(packageName, activityName); - // Wait for the app to appear - mDevice.wait(Until.hasObject(By.pkg(packageName).depth(0)), TIMEOUT.getSeconds()); - return timestamp; - } - - // Invokes the maintenance to compile the perfetto traces to compiled trace. - private boolean compile( - String packageName, String activityName, long version) throws Exception { - // The job id (283673059) is defined in class IorapForwardingService. - executeShellCommandViaTmpFile("cmd jobscheduler run -f android 283673059"); - return waitForFileExistence(getCompiledTracePath(packageName, activityName, version)); - } - - private String getCompiledTracePath( - String packageName, String activityName, long version) { - return String.format( - "/data/misc/iorapd/%s/%d/%s/compiled_traces/compiled_trace.pb", - packageName, version, activityName); - } - - /** - * Starts the testing app. - */ - private void startApp(String packageName, String activityName) throws Exception { - executeShellCommandViaTmpFile( - String.format("am start %s/%s", packageName, activityName)); - } - - /** - * Closes the testing app. - * <p> Keep trying to kill the process of the app until no process of the app package - * appears.</p> - */ - private void closeApp(String packageName) throws Exception { - while (true) { - String pid = executeShellCommand("pidof " + packageName); - if (pid.isEmpty()) { - Log.i(TAG, "Closed app " + packageName); - return; - } - executeShellCommand("kill -9 " + pid); - TimeUnit.SECONDS.sleep(1L); - } - } - - /** Waits for a file to appear. */ - private boolean waitForFileExistence(String fileName) throws Exception { - return retryWithTimeout(TIMEOUT, () -> { - try { - String fileExists = executeShellCommandViaTmpFile( - String.format("test -f %s; echo $?", fileName)); - Log.i(TAG, fileName + " existence is " + fileExists); - return fileExists.trim().equals("0"); - } catch (Exception e) { - Log.i(TAG, e.getMessage()); - return false; - } - }); - } - - /** Waits for the perfetto trace saved message from logcat. */ - private boolean waitForPerfettoTraceSavedFromLogcat( - String packageName, String activityName, long version, LogcatTimestamp timestamp) - throws Exception { - Pattern p = Pattern.compile(".*" - + getPerfettoTraceSavedIndicator(packageName, activityName, version) - + "(.*[.]perfetto_trace[.]pb)\n.*", Pattern.DOTALL); - - return retryWithTimeout(TIMEOUT, () -> { - try { - String log = timestamp.getLogcatAfter(); - Matcher m = p.matcher(log); - Log.d(TAG, "Tries to find perfetto trace..."); - if (!m.matches()) { - Log.i(TAG, "Cannot find perfetto trace saved in log."); - return false; - } - String filePath = m.group(1); - Log.i(TAG, "Perfetto trace is saved to " + filePath); - return true; - } catch(Exception e) { - Log.e(TAG, e.getMessage()); - return false; - } - }); - } - - private String getPerfettoTraceSavedIndicator( - String packageName, String activityName, long version) { - return String.format( - "Perfetto TraceBuffer saved to file: /data/misc/iorapd/%s/%d/%s/raw_traces/", - packageName, version, activityName); - } - - /** - * Waits for the prefetching log in the logcat. - * - * <p> When prefetching works, the perfetto traces should not be collected. </p> - */ - private boolean waitForPrefetchingFromLogcat( - String packageName, String activityName, long version, LogcatTimestamp timestamp) - throws Exception { - Pattern p = Pattern.compile( - ".*" + getReadaheadIndicator(packageName, activityName, version) + - ".*Total File Paths=(\\d+) \\(good: (\\d+[.]?\\d*)%\\)\n" - + ".*Total Entries=(\\d+) \\(good: (\\d+[.]?\\d*)%\\)\n" - + ".*Total Bytes=(\\d+) \\(good: (\\d+[.]?\\d*)%\\).*", - Pattern.DOTALL); - - return retryWithTimeout(TIMEOUT, () -> { - try { - String log = timestamp.getLogcatAfter(); - Matcher m = p.matcher(log); - if (!m.matches()) { - Log.i(TAG, "Cannot find readahead log."); - return false; - } - - int totalFilePath = Integer.parseInt(m.group(1)); - float totalFilePathGoodRate = Float.parseFloat(m.group(2)) / 100; - int totalEntries = Integer.parseInt(m.group(3)); - float totalEntriesGoodRate = Float.parseFloat(m.group(4)) / 100; - int totalBytes = Integer.parseInt(m.group(5)); - float totalBytesGoodRate = Float.parseFloat(m.group(6)) / 100; - - Log.i(TAG, String.format( - "totalFilePath: %d (good %.2f) totalEntries: %d (good %.2f) totalBytes: %d (good %.2f)", - totalFilePath, totalFilePathGoodRate, totalEntries, totalEntriesGoodRate, totalBytes, - totalBytesGoodRate)); - - return totalFilePath > 0 && - totalEntries > 0 && - totalBytes > 0 && - totalFilePathGoodRate > 0.5 && - totalEntriesGoodRate > 0.5 && - totalBytesGoodRate > 0.5; - } catch(Exception e) { - return false; - } - }); - } - - private static String getReadaheadIndicator( - String packageName, String activityName, long version) { - return String.format( - "Description = /data/misc/iorapd/%s/%d/%s/compiled_traces/compiled_trace.pb", - packageName, version, activityName); - } - - /** Retry until timeout. */ - private boolean retryWithTimeout(Duration timeout, BooleanSupplier supplier) throws Exception { - long totalSleepTimeSeconds = 0L; - long sleepIntervalSeconds = 2L; - while (true) { - if (supplier.getAsBoolean()) { - return true; - } - TimeUnit.SECONDS.sleep(sleepIntervalSeconds); - totalSleepTimeSeconds += sleepIntervalSeconds; - if (totalSleepTimeSeconds > timeout.getSeconds()) { - return false; - } - } - } - - /** - * Executes command in adb shell via a tmp file. - * - * <p> This should be run as root.</p> - */ - private static String executeShellCommandViaTmpFile(String cmd) throws Exception { - Log.i(TAG, "Execute via tmp file: " + cmd); - Path tmp = null; - try { - tmp = Files.createTempFile(/*prefix=*/null, /*suffix=*/".sh"); - Files.write(tmp, cmd.getBytes(StandardCharsets.UTF_8)); - tmp.toFile().setExecutable(true); - return UiDevice.getInstance( - InstrumentationRegistry.getInstrumentation()). - executeShellCommand(tmp.toString()); - } finally { - if (tmp != null) { - Files.delete(tmp); - } - } - } - - /** - * Executes command in adb shell. - * - * <p> This should be run as root.</p> - */ - private static String executeShellCommand(String cmd) throws Exception { - Log.i(TAG, "Execute: " + cmd); - return UiDevice.getInstance( - InstrumentationRegistry.getInstrumentation()).executeShellCommand(cmd); - } - - static class LogcatTimestamp { - private String epochTime; - - public LogcatTimestamp() throws Exception{ - long currentTimeMillis = System.currentTimeMillis(); - epochTime = String.format( - "%d.%03d", currentTimeMillis/1000, currentTimeMillis%1000); - Log.i(TAG, "Current logcat timestamp is " + epochTime); - } - - // For example, 1585264100.000 - public String getEpochTime() { - return epochTime; - } - - // Gets the logcat after this epoch time. - public String getLogcatAfter() throws Exception { - return executeShellCommandViaTmpFile( - "logcat -v epoch -t '" + epochTime + "'"); - } - } -} - diff --git a/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java b/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java deleted file mode 100644 index 1d38f4c1e23d..000000000000 --- a/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2018 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.google.android.startop.iorap; - -import android.os.Parcelable; -import android.os.Parcel; - -import android.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Objects; - -/** - * Provide a hint to iorapd that an activity has transitioned state.<br /><br /> - * - * Knowledge of when an activity starts/stops can be used by iorapd to increase system - * performance (e.g. by launching perfetto tracing to record an io profile, or by - * playing back an ioprofile via readahead) over the long run.<br /><br /> - * - * /@see com.google.android.startop.iorap.IIorap#onActivityHintEvent<br /><br /> - * - * Once an activity hint is in {@link #TYPE_STARTED} it must transition to another type. - * All other states could be terminal, see below: <br /><br /> - * - * <pre> - * - * ┌──────────────────────────────────────┐ - * │ ▼ - * ┌─────────┐ ╔════════════════╗ ╔═══════════╗ - * ──▶ │ STARTED │ ──▶ ║ COMPLETED ║ ──▶ ║ CANCELLED ║ - * └─────────┘ ╚════════════════╝ ╚═══════════╝ - * │ - * │ - * ▼ - * ╔════════════════╗ - * ║ POST_COMPLETED ║ - * ╚════════════════╝ - * - * </pre> <!-- system/iorap/docs/binder/ActivityHint.dot --> - * - * @hide - */ -public class ActivityHintEvent implements Parcelable { - - public static final int TYPE_STARTED = 0; - public static final int TYPE_CANCELLED = 1; - public static final int TYPE_COMPLETED = 2; - public static final int TYPE_POST_COMPLETED = 3; - private static final int TYPE_MAX = TYPE_POST_COMPLETED; - - /** @hide */ - @IntDef(flag = true, prefix = { "TYPE_" }, value = { - TYPE_STARTED, - TYPE_CANCELLED, - TYPE_COMPLETED, - TYPE_POST_COMPLETED, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface Type {} - - @Type public final int type; - public final ActivityInfo activityInfo; - - public ActivityHintEvent(@Type int type, ActivityInfo activityInfo) { - this.type = type; - this.activityInfo = activityInfo; - checkConstructorArguments(); - } - - private void checkConstructorArguments() { - CheckHelpers.checkTypeInRange(type, TYPE_MAX); - Objects.requireNonNull(activityInfo, "activityInfo"); - } - - @Override - public String toString() { - return String.format("{type: %d, activityInfo: %s}", type, activityInfo); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } else if (other instanceof ActivityHintEvent) { - return equals((ActivityHintEvent) other); - } - return false; - } - - private boolean equals(ActivityHintEvent other) { - return type == other.type && - Objects.equals(activityInfo, other.activityInfo); - } - - //<editor-fold desc="Binder boilerplate"> - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(type); - activityInfo.writeToParcel(out, flags); - } - - private ActivityHintEvent(Parcel in) { - this.type = in.readInt(); - this.activityInfo = ActivityInfo.CREATOR.createFromParcel(in); - checkConstructorArguments(); - } - - @Override - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator<ActivityHintEvent> CREATOR - = new Parcelable.Creator<ActivityHintEvent>() { - public ActivityHintEvent createFromParcel(Parcel in) { - return new ActivityHintEvent(in); - } - - public ActivityHintEvent[] newArray(int size) { - return new ActivityHintEvent[size]; - } - }; - //</editor-fold> -} diff --git a/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java b/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java deleted file mode 100644 index f47a42cffdd8..000000000000 --- a/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2018 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.google.android.startop.iorap; - -import java.util.Objects; - -import android.os.Parcelable; -import android.os.Parcel; - -/** - * Provide minimal information for launched activities to iorap.<br /><br /> - * - * This uniquely identifies a system-wide activity by providing the {@link #packageName} and - * {@link #activityName}. - * - * @see ActivityHintEvent - * @see AppIntentEvent - * - * @hide - */ -public class ActivityInfo implements Parcelable { - - /** The name of the package, for example {@code com.android.calculator}. */ - public final String packageName; - /** The name of the activity, for example {@code .activities.activity.MainActivity} */ - public final String activityName; - - public ActivityInfo(String packageName, String activityName) { - this.packageName = packageName; - this.activityName = activityName; - - checkConstructorArguments(); - } - - private void checkConstructorArguments() { - Objects.requireNonNull(packageName, "packageName"); - Objects.requireNonNull(activityName, "activityName"); - } - - @Override - public String toString() { - return String.format("{packageName: %s, activityName: %s}", packageName, activityName); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } else if (other instanceof ActivityInfo) { - return equals((ActivityInfo) other); - } - return false; - } - - private boolean equals(ActivityInfo other) { - return Objects.equals(packageName, other.packageName) && - Objects.equals(activityName, other.activityName); - } - - //<editor-fold desc="Binder boilerplate"> - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeString(packageName); - out.writeString(activityName); - } - - private ActivityInfo(Parcel in) { - packageName = in.readString(); - activityName = in.readString(); - - checkConstructorArguments(); - } - - @Override - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator<ActivityInfo> CREATOR - = new Parcelable.Creator<ActivityInfo>() { - public ActivityInfo createFromParcel(Parcel in) { - return new ActivityInfo(in); - } - - public ActivityInfo[] newArray(int size) { - return new ActivityInfo[size]; - } - }; - //</editor-fold> -} diff --git a/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java b/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java deleted file mode 100644 index 1cd37b5546b9..000000000000 --- a/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2018 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.google.android.startop.iorap; - -import android.os.Parcelable; -import android.os.Parcel; - -import android.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Objects; - -/** - * Notifications for iorapd specifying when a system-wide intent defaults change.<br /><br /> - * - * Intent defaults provide a mechanism for an app to register itself as an automatic handler. - * For example the camera app might be registered as the default handler for - * {@link android.provider.MediaStore#INTENT_ACTION_STILL_IMAGE_CAMERA} intent. Subsequently, - * if an arbitrary other app requests for a still image camera photo to be taken, the system - * will launch the respective default camera app to be launched to handle that request.<br /><br /> - * - * In some cases iorapd might need to know default intents, e.g. for boot-time pinning of - * applications that resolve from the default intent. If the application would now be resolved - * differently, iorapd would unpin the old application and pin the new application.<br /><br /> - * - * @hide - */ -public class AppIntentEvent implements Parcelable { - - /** @see android.content.Intent#CATEGORY_DEFAULT */ - public static final int TYPE_DEFAULT_INTENT_CHANGED = 0; - private static final int TYPE_MAX = 0; - - /** @hide */ - @IntDef(flag = true, prefix = { "TYPE_" }, value = { - TYPE_DEFAULT_INTENT_CHANGED, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface Type {} - - @Type public final int type; - - public final ActivityInfo oldActivityInfo; - public final ActivityInfo newActivityInfo; - - // TODO: Probably need the corresponding action here as well. - - public static AppIntentEvent createDefaultIntentChanged(ActivityInfo oldActivityInfo, - ActivityInfo newActivityInfo) { - return new AppIntentEvent(TYPE_DEFAULT_INTENT_CHANGED, oldActivityInfo, - newActivityInfo); - } - - private AppIntentEvent(@Type int type, ActivityInfo oldActivityInfo, - ActivityInfo newActivityInfo) { - this.type = type; - this.oldActivityInfo = oldActivityInfo; - this.newActivityInfo = newActivityInfo; - - checkConstructorArguments(); - } - - private void checkConstructorArguments() { - CheckHelpers.checkTypeInRange(type, TYPE_MAX); - Objects.requireNonNull(oldActivityInfo, "oldActivityInfo"); - Objects.requireNonNull(oldActivityInfo, "newActivityInfo"); - } - - @Override - public String toString() { - return String.format("{oldActivityInfo: %s, newActivityInfo: %s}", oldActivityInfo, - newActivityInfo); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } else if (other instanceof AppIntentEvent) { - return equals((AppIntentEvent) other); - } - return false; - } - - private boolean equals(AppIntentEvent other) { - return type == other.type && - Objects.equals(oldActivityInfo, other.oldActivityInfo) && - Objects.equals(newActivityInfo, other.newActivityInfo); - } - - //<editor-fold desc="Binder boilerplate"> - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(type); - oldActivityInfo.writeToParcel(out, flags); - newActivityInfo.writeToParcel(out, flags); - } - - private AppIntentEvent(Parcel in) { - this.type = in.readInt(); - this.oldActivityInfo = ActivityInfo.CREATOR.createFromParcel(in); - this.newActivityInfo = ActivityInfo.CREATOR.createFromParcel(in); - - checkConstructorArguments(); - } - - @Override - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator<AppIntentEvent> CREATOR - = new Parcelable.Creator<AppIntentEvent>() { - public AppIntentEvent createFromParcel(Parcel in) { - return new AppIntentEvent(in); - } - - public AppIntentEvent[] newArray(int size) { - return new AppIntentEvent[size]; - } - }; - //</editor-fold> -} diff --git a/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java b/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java deleted file mode 100644 index 8263e0af4422..000000000000 --- a/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (C) 2018 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.google.android.startop.iorap; - -import android.annotation.LongDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.ComponentName; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.proto.ProtoOutputStream; - -import com.android.server.wm.ActivityMetricsLaunchObserver; -import com.android.server.wm.ActivityMetricsLaunchObserver.ActivityRecordProto; -import com.android.server.wm.ActivityMetricsLaunchObserver.Temperature; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; -import java.util.Objects; - -/** - * Provide a hint to iorapd that an app launch sequence has transitioned state.<br /><br /> - * - * Knowledge of when an activity starts/stops can be used by iorapd to increase system - * performance (e.g. by launching perfetto tracing to record an io profile, or by - * playing back an ioprofile via readahead) over the long run.<br /><br /> - * - * /@see com.google.android.startop.iorap.IIorap#onAppLaunchEvent <br /><br /> - * @see com.android.server.wm.ActivityMetricsLaunchObserver - * ActivityMetricsLaunchObserver for the possible event states. - * @hide - */ -public abstract class AppLaunchEvent implements Parcelable { - @LongDef - @Retention(RetentionPolicy.SOURCE) - public @interface SequenceId {} - - public final @SequenceId - long sequenceId; - - protected AppLaunchEvent(@SequenceId long sequenceId) { - this.sequenceId = sequenceId; - } - - @Override - public boolean equals(Object other) { - if (other instanceof AppLaunchEvent) { - return equals((AppLaunchEvent) other); - } - return false; - } - - protected boolean equals(AppLaunchEvent other) { - return sequenceId == other.sequenceId; - } - - - @Override - public String toString() { - return getClass().getSimpleName() + - "{" + "sequenceId=" + Long.toString(sequenceId) + - toStringBody() + "}"; - } - - protected String toStringBody() { return ""; }; - - // List of possible variants: - - public static final class IntentStarted extends AppLaunchEvent { - @NonNull - public final Intent intent; - public final long timestampNs; - - public IntentStarted(@SequenceId long sequenceId, - Intent intent, - long timestampNs) { - super(sequenceId); - this.intent = intent; - this.timestampNs = timestampNs; - - Objects.requireNonNull(intent, "intent"); - } - - @Override - public boolean equals(Object other) { - if (other instanceof IntentStarted) { - return intent.equals(((IntentStarted)other).intent) && - timestampNs == ((IntentStarted)other).timestampNs && - super.equals(other); - } - return false; - } - - @Override - protected String toStringBody() { - return ", intent=" + intent.toString() + - " , timestampNs=" + Long.toString(timestampNs); - } - - - @Override - protected void writeToParcelImpl(Parcel p, int flags) { - super.writeToParcelImpl(p, flags); - IntentProtoParcelable.write(p, intent, flags); - p.writeLong(timestampNs); - } - - IntentStarted(Parcel p) { - super(p); - intent = IntentProtoParcelable.create(p); - timestampNs = p.readLong(); - } - } - - public static final class IntentFailed extends AppLaunchEvent { - public IntentFailed(@SequenceId long sequenceId) { - super(sequenceId); - } - - @Override - public boolean equals(Object other) { - if (other instanceof IntentFailed) { - return super.equals(other); - } - return false; - } - - IntentFailed(Parcel p) { - super(p); - } - } - - public static abstract class BaseWithActivityRecordData extends AppLaunchEvent { - public final @NonNull - @ActivityRecordProto byte[] activityRecordSnapshot; - - protected BaseWithActivityRecordData(@SequenceId long sequenceId, - @NonNull @ActivityRecordProto byte[] snapshot) { - super(sequenceId); - activityRecordSnapshot = snapshot; - - Objects.requireNonNull(snapshot, "snapshot"); - } - - @Override - public boolean equals(Object other) { - if (other instanceof BaseWithActivityRecordData) { - return (Arrays.equals(activityRecordSnapshot, - ((BaseWithActivityRecordData)other).activityRecordSnapshot)) && - super.equals(other); - } - return false; - } - - @Override - protected String toStringBody() { - return ", " + new String(activityRecordSnapshot); - } - - @Override - protected void writeToParcelImpl(Parcel p, int flags) { - super.writeToParcelImpl(p, flags); - ActivityRecordProtoParcelable.write(p, activityRecordSnapshot, flags); - } - - BaseWithActivityRecordData(Parcel p) { - super(p); - activityRecordSnapshot = ActivityRecordProtoParcelable.create(p); - } - } - - public static final class ActivityLaunched extends BaseWithActivityRecordData { - public final @ActivityMetricsLaunchObserver.Temperature - int temperature; - - public ActivityLaunched(@SequenceId long sequenceId, - @NonNull @ActivityRecordProto byte[] snapshot, - @ActivityMetricsLaunchObserver.Temperature int temperature) { - super(sequenceId, snapshot); - this.temperature = temperature; - } - - @Override - public boolean equals(Object other) { - if (other instanceof ActivityLaunched) { - return temperature == ((ActivityLaunched)other).temperature && - super.equals(other); - } - return false; - } - - @Override - protected String toStringBody() { - return super.toStringBody() + ", temperature=" + Integer.toString(temperature); - } - - @Override - protected void writeToParcelImpl(Parcel p, int flags) { - super.writeToParcelImpl(p, flags); - p.writeInt(temperature); - } - - ActivityLaunched(Parcel p) { - super(p); - temperature = p.readInt(); - } - } - - public static final class ActivityLaunchFinished extends BaseWithActivityRecordData { - public final long timestampNs; - - public ActivityLaunchFinished(@SequenceId long sequenceId, - @NonNull @ActivityRecordProto byte[] snapshot, - long timestampNs) { - super(sequenceId, snapshot); - this.timestampNs = timestampNs; - } - - @Override - public boolean equals(Object other) { - if (other instanceof ActivityLaunchFinished) { - return timestampNs == ((ActivityLaunchFinished)other).timestampNs && - super.equals(other); - } - return false; - } - - @Override - protected String toStringBody() { - return super.toStringBody() + ", timestampNs=" + Long.toString(timestampNs); - } - - @Override - protected void writeToParcelImpl(Parcel p, int flags) { - super.writeToParcelImpl(p, flags); - p.writeLong(timestampNs); - } - - ActivityLaunchFinished(Parcel p) { - super(p); - timestampNs = p.readLong(); - } - } - - public static class ActivityLaunchCancelled extends AppLaunchEvent { - public final @Nullable @ActivityRecordProto byte[] activityRecordSnapshot; - - public ActivityLaunchCancelled(@SequenceId long sequenceId, - @Nullable @ActivityRecordProto byte[] snapshot) { - super(sequenceId); - activityRecordSnapshot = snapshot; - } - - @Override - public boolean equals(Object other) { - if (other instanceof ActivityLaunchCancelled) { - return Arrays.equals(activityRecordSnapshot, - ((ActivityLaunchCancelled)other).activityRecordSnapshot) && - super.equals(other); - } - return false; - } - - @Override - protected String toStringBody() { - return super.toStringBody() + ", " + new String(activityRecordSnapshot); - } - - @Override - protected void writeToParcelImpl(Parcel p, int flags) { - super.writeToParcelImpl(p, flags); - if (activityRecordSnapshot != null) { - p.writeBoolean(true); - ActivityRecordProtoParcelable.write(p, activityRecordSnapshot, flags); - } else { - p.writeBoolean(false); - } - } - - ActivityLaunchCancelled(Parcel p) { - super(p); - if (p.readBoolean()) { - activityRecordSnapshot = ActivityRecordProtoParcelable.create(p); - } else { - activityRecordSnapshot = null; - } - } - } - - public static final class ReportFullyDrawn extends BaseWithActivityRecordData { - public final long timestampNs; - - public ReportFullyDrawn(@SequenceId long sequenceId, - @NonNull @ActivityRecordProto byte[] snapshot, - long timestampNs) { - super(sequenceId, snapshot); - this.timestampNs = timestampNs; - } - - @Override - public boolean equals(Object other) { - if (other instanceof ReportFullyDrawn) { - return timestampNs == ((ReportFullyDrawn)other).timestampNs && - super.equals(other); - } - return false; - } - - @Override - protected String toStringBody() { - return super.toStringBody() + ", timestampNs=" + Long.toString(timestampNs); - } - - @Override - protected void writeToParcelImpl(Parcel p, int flags) { - super.writeToParcelImpl(p, flags); - p.writeLong(timestampNs); - } - - ReportFullyDrawn(Parcel p) { - super(p); - timestampNs = p.readLong(); - } - } - - @Override - public @ContentsFlags int describeContents() { return 0; } - - @Override - public void writeToParcel(Parcel p, @WriteFlags int flags) { - p.writeInt(getTypeIndex()); - - writeToParcelImpl(p, flags); - } - - - public static Creator<AppLaunchEvent> CREATOR = - new Creator<AppLaunchEvent>() { - @Override - public AppLaunchEvent createFromParcel(Parcel source) { - int typeIndex = source.readInt(); - - Class<?> kls = getClassFromTypeIndex(typeIndex); - if (kls == null) { - throw new IllegalArgumentException("Invalid type index: " + typeIndex); - } - - try { - return (AppLaunchEvent) kls.getConstructor(Parcel.class).newInstance(source); - } catch (InstantiationException e) { - throw new AssertionError(e); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } catch (InvocationTargetException e) { - throw new AssertionError(e); - } catch (NoSuchMethodException e) { - throw new AssertionError(e); - } - } - - @Override - public AppLaunchEvent[] newArray(int size) { - return new AppLaunchEvent[0]; - } - }; - - protected void writeToParcelImpl(Parcel p, int flags) { - p.writeLong(sequenceId); - } - - protected AppLaunchEvent(Parcel p) { - sequenceId = p.readLong(); - } - - private int getTypeIndex() { - for (int i = 0; i < sTypes.length; ++i) { - if (sTypes[i].equals(this.getClass())) { - return i; - } - } - throw new AssertionError("sTypes did not include this type: " + this.getClass()); - } - - private static @Nullable Class<?> getClassFromTypeIndex(int typeIndex) { - if (typeIndex >= 0 && typeIndex < sTypes.length) { - return sTypes[typeIndex]; - } - return null; - } - - // Index position matters: It is used to encode the specific type in parceling. - // Keep up-to-date with C++ side. - private static Class<?>[] sTypes = new Class[] { - IntentStarted.class, - IntentFailed.class, - ActivityLaunched.class, - ActivityLaunchFinished.class, - ActivityLaunchCancelled.class, - ReportFullyDrawn.class, - }; - - public static class ActivityRecordProtoParcelable { - public static void write(Parcel p, @ActivityRecordProto byte[] activityRecordSnapshot, - int flags) { - p.writeByteArray(activityRecordSnapshot); - } - - public static @ActivityRecordProto byte[] create(Parcel p) { - byte[] data = p.createByteArray(); - - return data; - } - } - - public static class IntentProtoParcelable { - private static final int INTENT_PROTO_CHUNK_SIZE = 1024; - - public static void write(Parcel p, @NonNull Intent intent, int flags) { - // There does not appear to be a way to 'reset' a ProtoOutputBuffer stream, - // so create a new one every time. - final ProtoOutputStream protoOutputStream = - new ProtoOutputStream(INTENT_PROTO_CHUNK_SIZE); - // Write this data out as the top-most IntentProto (i.e. it is not a sub-object). - intent.dumpDebug(protoOutputStream); - final byte[] bytes = protoOutputStream.getBytes(); - - p.writeByteArray(bytes); - } - - // TODO: Should be mockable for testing? - // We cannot deserialize in the platform because we don't have a 'readFromProto' - // code. - public static @NonNull Intent create(Parcel p) { - // This will "read" the correct amount of data, but then we discard it. - byte[] data = p.createByteArray(); - - // Never called by real code in a platform, this binder API is implemented only in C++. - return new Intent("<cannot deserialize IntentProto>"); - } - } -} diff --git a/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java b/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java deleted file mode 100644 index 34aedd7685d8..000000000000 --- a/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2018 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.google.android.startop.iorap; - -/** - * Convenience short-hand to throw {@link IllegalAccessException} when the arguments - * are out-of-range. - */ -public class CheckHelpers { - /** @throws IllegalAccessException if {@param type} is not in {@code [0..maxValue]} */ - public static void checkTypeInRange(int type, int maxValue) { - if (type < 0) { - throw new IllegalArgumentException( - String.format("type must be non-negative (value=%d)", type)); - } - if (type > maxValue) { - throw new IllegalArgumentException( - String.format("type out of range (value=%d, max=%d)", type, maxValue)); - } - } - - /** @throws IllegalAccessException if {@param state} is not in {@code [0..maxValue]} */ - public static void checkStateInRange(int state, int maxValue) { - if (state < 0) { - throw new IllegalArgumentException( - String.format("state must be non-negative (value=%d)", state)); - } - if (state > maxValue) { - throw new IllegalArgumentException( - String.format("state out of range (value=%d, max=%d)", state, maxValue)); - } - } -} diff --git a/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java b/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java deleted file mode 100644 index 72c5eaa84c96..000000000000 --- a/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2020 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.google.android.startop.iorap; - -import android.annotation.NonNull; -import android.os.Parcelable; -import android.os.Parcel; - -import android.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Objects; - -/** - * Notifications for iorapd specifying when a package is updated by dexopt service.<br /><br /> - * - * @hide - */ -public class DexOptEvent implements Parcelable { - public static final int TYPE_PACKAGE_UPDATE = 0; - private static final int TYPE_MAX = 0; - - /** @hide */ - @IntDef(flag = true, prefix = { "TYPE_" }, value = { - TYPE_PACKAGE_UPDATE, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface Type {} - - @Type public final int type; - public final String packageName; - - @NonNull - public static DexOptEvent createPackageUpdate(String packageName) { - return new DexOptEvent(TYPE_PACKAGE_UPDATE, packageName); - } - - private DexOptEvent(@Type int type, String packageName) { - this.type = type; - this.packageName = packageName; - - checkConstructorArguments(); - } - - private void checkConstructorArguments() { - CheckHelpers.checkTypeInRange(type, TYPE_MAX); - Objects.requireNonNull(packageName, "packageName"); - } - - @Override - public String toString() { - return String.format("{DexOptEvent: packageName: %s}", packageName); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } else if (other instanceof DexOptEvent) { - return equals((DexOptEvent) other); - } - return false; - } - - private boolean equals(DexOptEvent other) { - return packageName.equals(other.packageName); - } - - //<editor-fold desc="Binder boilerplate"> - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(type); - out.writeString(packageName); - } - - private DexOptEvent(Parcel in) { - this.type = in.readInt(); - this.packageName = in.readString(); - - checkConstructorArguments(); - } - - @Override - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator<DexOptEvent> CREATOR - = new Parcelable.Creator<DexOptEvent>() { - public DexOptEvent createFromParcel(Parcel in) { - return new DexOptEvent(in); - } - - public DexOptEvent[] newArray(int size) { - return new DexOptEvent[size]; - } - }; - //</editor-fold> -} diff --git a/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java b/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java deleted file mode 100644 index dcaff26b79c6..000000000000 --- a/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (C) 2019 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.google.android.startop.iorap; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.Intent; -import android.util.Log; - -import com.android.server.wm.ActivityMetricsLaunchObserver; - -import java.io.StringWriter; -import java.io.PrintWriter; - -/** - * A validator to check the correctness of event sequence during app startup. - * - * <p> A valid state transition of event sequence is shown as the following: - * - * <pre> - * - * +--------------------+ - * | | - * | INIT | - * | | - * +--------------------+ - * | - * | - * ↓ - * +--------------------+ - * | | - * +-------------------| INTENT_STARTED | ←--------------------------------+ - * | | | | - * | +--------------------+ | - * | | | - * | | | - * ↓ ↓ | - * +--------------------+ +--------------------+ | - * | | | | | - * | INTENT_FAILED | | ACTIVITY_LAUNCHED |------------------+ | - * | | | | | | - * +--------------------+ +--------------------+ | | - * | | | | - * | ↓ ↓ | - * | +--------------------+ +--------------------+ | - * | | | | | | - * +------------------ | ACTIVITY_FINISHED | | ACTIVITY_CANCELLED | | - * | | | | | | - * | +--------------------+ +--------------------+ | - * | | | | - * | | | | - * | ↓ | | - * | +--------------------+ | | - * | | | | | - * | | REPORT_FULLY_DRAWN | | | - * | | | | | - * | +--------------------+ | | - * | | | | - * | | | | - * | ↓ | | - * | +--------------------+ | | - * | | | | | - * +-----------------→ | END |←-----------------+ | - * | | | - * +--------------------+ | - * | | - * | | - * | | - * +--------------------------------------------- - * - * <p> END is not a real state in implementation. All states that points to END directly - * could transition to INTENT_STARTED. - * - * <p> If any bad transition happened, the state becomse UNKNOWN. The UNKNOWN state - * could be accumulated, because during the UNKNOWN state more IntentStarted may - * be triggered. To recover from UNKNOWN to INIT, all the accumualted IntentStarted - * should termniate. - * - * <p> During UNKNOWN state, each IntentStarted increases the accumulation, and any of - * IntentFailed, ActivityLaunchCancelled and ActivityFinished decreases the accumulation. - * ReportFullyDrawn doesn't impact the accumulation. - */ -public class EventSequenceValidator implements ActivityMetricsLaunchObserver { - static final String TAG = "EventSequenceValidator"; - /** $> adb shell 'setprop log.tag.EventSequenceValidator VERBOSE' */ - public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - private State state = State.INIT; - private long accIntentStartedEvents = 0; - - @Override - public void onIntentStarted(@NonNull Intent intent, long timestampNs) { - if (state == State.UNKNOWN) { - logWarningWithStackTrace("IntentStarted during UNKNOWN. " + intent); - incAccIntentStartedEvents(); - return; - } - - if (state != State.INIT && - state != State.INTENT_FAILED && - state != State.ACTIVITY_CANCELLED && - state != State.ACTIVITY_FINISHED && - state != State.REPORT_FULLY_DRAWN) { - logWarningWithStackTrace( - String.format("Cannot transition from %s to %s", state, State.INTENT_STARTED)); - incAccIntentStartedEvents(); - incAccIntentStartedEvents(); - return; - } - - Log.i(TAG, String.format("Transition from %s to %s", state, State.INTENT_STARTED)); - state = State.INTENT_STARTED; - } - - @Override - public void onIntentFailed() { - if (state == State.UNKNOWN) { - logWarningWithStackTrace("onIntentFailed during UNKNOWN."); - decAccIntentStartedEvents(); - return; - } - if (state != State.INTENT_STARTED) { - logWarningWithStackTrace( - String.format("Cannot transition from %s to %s", state, State.INTENT_FAILED)); - incAccIntentStartedEvents(); - return; - } - - Log.i(TAG, String.format("Transition from %s to %s", state, State.INTENT_FAILED)); - state = State.INTENT_FAILED; - } - - @Override - public void onActivityLaunched(@NonNull @ActivityRecordProto byte[] activity, - @Temperature int temperature) { - if (state == State.UNKNOWN) { - logWarningWithStackTrace("onActivityLaunched during UNKNOWN."); - return; - } - if (state != State.INTENT_STARTED) { - logWarningWithStackTrace( - String.format("Cannot transition from %s to %s", state, State.ACTIVITY_LAUNCHED)); - incAccIntentStartedEvents(); - return; - } - - Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_LAUNCHED)); - state = State.ACTIVITY_LAUNCHED; - } - - @Override - public void onActivityLaunchCancelled(@Nullable @ActivityRecordProto byte[] activity) { - if (state == State.UNKNOWN) { - logWarningWithStackTrace("onActivityLaunchCancelled during UNKNOWN."); - decAccIntentStartedEvents(); - return; - } - if (state != State.ACTIVITY_LAUNCHED) { - logWarningWithStackTrace( - String.format("Cannot transition from %s to %s", state, State.ACTIVITY_CANCELLED)); - incAccIntentStartedEvents(); - return; - } - - Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_CANCELLED)); - state = State.ACTIVITY_CANCELLED; - } - - @Override - public void onActivityLaunchFinished(@NonNull @ActivityRecordProto byte[] activity, - long timestampNs) { - if (state == State.UNKNOWN) { - logWarningWithStackTrace("onActivityLaunchFinished during UNKNOWN."); - decAccIntentStartedEvents(); - return; - } - - if (state != State.ACTIVITY_LAUNCHED) { - logWarningWithStackTrace( - String.format("Cannot transition from %s to %s", state, State.ACTIVITY_FINISHED)); - incAccIntentStartedEvents(); - return; - } - - Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_FINISHED)); - state = State.ACTIVITY_FINISHED; - } - - @Override - public void onReportFullyDrawn(@NonNull @ActivityRecordProto byte[] activity, - long timestampNs) { - if (state == State.UNKNOWN) { - logWarningWithStackTrace("onReportFullyDrawn during UNKNOWN."); - return; - } - if (state == State.INIT) { - return; - } - - if (state != State.ACTIVITY_FINISHED) { - logWarningWithStackTrace( - String.format("Cannot transition from %s to %s", state, State.REPORT_FULLY_DRAWN)); - return; - } - - Log.i(TAG, String.format("Transition from %s to %s", state, State.REPORT_FULLY_DRAWN)); - state = State.REPORT_FULLY_DRAWN; - } - - enum State { - INIT, - INTENT_STARTED, - INTENT_FAILED, - ACTIVITY_LAUNCHED, - ACTIVITY_CANCELLED, - ACTIVITY_FINISHED, - REPORT_FULLY_DRAWN, - UNKNOWN, - } - - private void incAccIntentStartedEvents() { - if (accIntentStartedEvents < 0) { - throw new AssertionError("The number of unknowns cannot be negative"); - } - if (accIntentStartedEvents == 0) { - state = State.UNKNOWN; - } - ++accIntentStartedEvents; - Log.i(TAG, - String.format("inc AccIntentStartedEvents to %d", accIntentStartedEvents)); - } - - private void decAccIntentStartedEvents() { - if (accIntentStartedEvents <= 0) { - throw new AssertionError("The number of unknowns cannot be negative"); - } - if(accIntentStartedEvents == 1) { - state = State.INIT; - } - --accIntentStartedEvents; - Log.i(TAG, - String.format("dec AccIntentStartedEvents to %d", accIntentStartedEvents)); - } - - private void logWarningWithStackTrace(String log) { - if (DEBUG) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - new Throwable("EventSequenceValidator#getStackTrace").printStackTrace(pw); - Log.wtf(TAG, String.format("%s\n%s", log, sw)); - } - } -} - diff --git a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java b/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java deleted file mode 100644 index 1a0e5269d51a..000000000000 --- a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java +++ /dev/null @@ -1,812 +0,0 @@ -/* - * Copyright (C) 2018 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.google.android.startop.iorap; -// TODO: rename to com.android.server.startop.iorap - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.job.JobInfo; -import android.app.job.JobParameters; -import android.app.job.JobService; -import android.app.job.JobScheduler; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.os.IBinder; -import android.os.IBinder.DeathRecipient; -import android.os.Handler; -import android.os.Parcel; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.SystemProperties; -import android.provider.DeviceConfig; -import android.util.ArraySet; -import android.util.Log; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.server.IoThread; -import com.android.server.LocalServices; -import com.android.server.SystemService; -import com.android.server.pm.BackgroundDexOptService; -import com.android.server.pm.PackageManagerService; -import com.android.server.wm.ActivityMetricsLaunchObserver; -import com.android.server.wm.ActivityMetricsLaunchObserver.ActivityRecordProto; -import com.android.server.wm.ActivityMetricsLaunchObserver.Temperature; -import com.android.server.wm.ActivityMetricsLaunchObserverRegistry; -import com.android.server.wm.ActivityTaskManagerInternal; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.BooleanSupplier; -import java.util.HashMap; -import java.util.List; - -/** - * System-server-local proxy into the {@code IIorap} native service. - */ -public class IorapForwardingService extends SystemService { - - public static final String TAG = "IorapForwardingService"; - /** $> adb shell 'setprop log.tag.IorapForwardingService VERBOSE' */ - public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); - /** $> adb shell 'setprop ro.iorapd.enable true' */ - private static boolean IS_ENABLED = SystemProperties.getBoolean("ro.iorapd.enable", true); - /** $> adb shell 'setprop iorapd.forwarding_service.wtf_crash true' */ - private static boolean WTF_CRASH = SystemProperties.getBoolean( - "iorapd.forwarding_service.wtf_crash", false); - private static final Duration TIMEOUT = Duration.ofSeconds(600L); - - // "Unique" job ID from the service name. Also equal to 283673059. - public static final int JOB_ID_IORAPD = encodeEnglishAlphabetStringIntoInt("iorapd"); - // Run every 24 hours. - public static final long JOB_INTERVAL_MS = TimeUnit.HOURS.toMillis(24); - - private IIorap mIorapRemote; - private final Object mLock = new Object(); - /** Handle onBinderDeath by periodically trying to reconnect. */ - private final Handler mHandler = - new BinderConnectionHandler(IoThread.getHandler().getLooper()); - - private volatile IorapdJobService mJobService; // Write-once (null -> non-null forever). - private volatile static IorapForwardingService sSelfService; // Write once (null -> non-null). - - - /** - * Atomics set to true if the JobScheduler requests an abort. - */ - private final AtomicBoolean mAbortIdleCompilation = new AtomicBoolean(false); - - /** - * Initializes the system service. - * <p> - * Subclasses must define a single argument constructor that accepts the context - * and passes it to super. - * </p> - * - * @param context The system server context. - */ - public IorapForwardingService(Context context) { - super(context); - - if (DEBUG) { - Log.v(TAG, "IorapForwardingService (Context=" + context.toString() + ")"); - } - - if (sSelfService != null) { - throw new AssertionError("only one service instance allowed"); - } - sSelfService = this; - } - - //<editor-fold desc="Providers"> - /* - * Providers for external dependencies: - * - These are marked as protected to allow tests to inject different values via mocks. - */ - - @VisibleForTesting - protected ActivityMetricsLaunchObserverRegistry provideLaunchObserverRegistry() { - ActivityTaskManagerInternal amtInternal = - LocalServices.getService(ActivityTaskManagerInternal.class); - ActivityMetricsLaunchObserverRegistry launchObserverRegistry = - amtInternal.getLaunchObserverRegistry(); - return launchObserverRegistry; - } - - @VisibleForTesting - protected IIorap provideIorapRemote() { - IIorap iorap; - try { - iorap = IIorap.Stub.asInterface(ServiceManager.getServiceOrThrow("iorapd")); - } catch (ServiceManager.ServiceNotFoundException e) { - Log.w(TAG, e.getMessage()); - return null; - } - - try { - iorap.asBinder().linkToDeath(provideDeathRecipient(), /*flags*/0); - } catch (RemoteException e) { - handleRemoteError(e); - return null; - } - - return iorap; - } - - @VisibleForTesting - protected DeathRecipient provideDeathRecipient() { - return new DeathRecipient() { - @Override - public void binderDied() { - Log.w(TAG, "iorapd has died"); - retryConnectToRemoteAndConfigure(/*attempts*/0); - - if (mJobService != null) { - mJobService.onIorapdDisconnected(); - } - } - }; - } - - @VisibleForTesting - protected boolean isIorapEnabled() { - // These two mendel flags should match those in iorapd native process - // system/iorapd/src/common/property.h - boolean isTracingEnabled = - getMendelFlag("iorap_perfetto_enable", "iorapd.perfetto.enable", false); - boolean isReadAheadEnabled = - getMendelFlag("iorap_readahead_enable", "iorapd.readahead.enable", false); - // Same as the property in iorapd.rc -- disabling this will mean the 'iorapd' binder process - // never comes up, so all binder connections will fail indefinitely. - return IS_ENABLED && (isTracingEnabled || isReadAheadEnabled); - } - - private boolean getMendelFlag(String mendelFlag, String sysProperty, boolean defaultValue) { - // TODO(yawanng) use DeviceConfig to get mendel property. - // DeviceConfig doesn't work and the reason is not clear. - // Provider service is already up before IORapForwardService. - String mendelProperty = "persist.device_config." - + DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT - + "." - + mendelFlag; - return SystemProperties.getBoolean(mendelProperty, - SystemProperties.getBoolean(sysProperty, defaultValue)); - } - - //</editor-fold> - - @Override - public void onStart() { - if (DEBUG) { - Log.v(TAG, "onStart"); - } - - retryConnectToRemoteAndConfigure(/*attempts*/0); - } - - @Override - public void onBootPhase(int phase) { - if (phase == PHASE_BOOT_COMPLETED) { - if (DEBUG) { - Log.v(TAG, "onBootPhase(PHASE_BOOT_COMPLETED)"); - } - - if (isIorapEnabled()) { - // Set up a recurring background job. This has to be done in a later phase since it - // has a dependency the job scheduler. - // - // Doing this too early can result in a ServiceNotFoundException for 'jobservice' - // or a null reference for #getSystemService(JobScheduler.class) - mJobService = new IorapdJobService(getContext()); - } - } - } - - private class BinderConnectionHandler extends Handler { - public BinderConnectionHandler(android.os.Looper looper) { - super(looper); - } - - public static final int MESSAGE_BINDER_CONNECT = 0; - - private int mAttempts = 0; - - @Override - public void handleMessage(android.os.Message message) { - switch (message.what) { - case MESSAGE_BINDER_CONNECT: - if (!retryConnectToRemoteAndConfigure(mAttempts)) { - mAttempts++; - } else { - mAttempts = 0; - } - break; - default: - throw new AssertionError("Unknown message: " + message.toString()); - } - } - } - - /** - * Handle iorapd shutdowns and crashes, by attempting to reconnect - * until the service is reached again. - * - * <p>The first connection attempt is synchronous, - * subsequent attempts are done by posting delayed tasks to the IoThread.</p> - * - * @return true if connection succeeded now, or false if it failed now [and needs to requeue]. - */ - private boolean retryConnectToRemoteAndConfigure(int attempts) { - final int sleepTime = 1000; // ms - - if (DEBUG) { - Log.v(TAG, "retryConnectToRemoteAndConfigure - attempt #" + attempts); - } - - if (connectToRemoteAndConfigure()) { - return true; - } - - // Either 'iorapd' is stuck in a crash loop (ouch!!) or we manually - // called 'adb shell stop iorapd' , which means this would loop until it comes back - // up. - // - // TODO: it would be good to get nodified of 'adb shell stop iorapd' to avoid - // printing this warning. - if (DEBUG) { - Log.v(TAG, "Failed to connect to iorapd, is it down? Delay for " + sleepTime); - } - - // Use a handler instead of Thread#sleep to avoid backing up the binder thread - // when this is called from the death recipient callback. - mHandler.sendMessageDelayed( - mHandler.obtainMessage(BinderConnectionHandler.MESSAGE_BINDER_CONNECT), - sleepTime); - - return false; - - // Log.e(TAG, "Can't connect to iorapd - giving up after " + attempts + " attempts"); - } - - private boolean connectToRemoteAndConfigure() { - synchronized (mLock) { - // Synchronize against any concurrent calls to this via the DeathRecipient. - return connectToRemoteAndConfigureLocked(); - } - } - - private boolean connectToRemoteAndConfigureLocked() { - if (!isIorapEnabled()) { - if (DEBUG) { - Log.v(TAG, "connectToRemoteAndConfigure - iorapd is disabled, skip rest of work"); - } - // When we see that iorapd is disabled (when system server comes up), - // it stays disabled permanently until the next system server reset. - - // TODO: consider listening to property changes as a callback, then we can - // be more dynamic about handling enable/disable. - return true; - } - - // Connect to the native binder service. - mIorapRemote = provideIorapRemote(); - if (mIorapRemote == null) { - if (DEBUG) { - Log.e(TAG, "connectToRemoteAndConfigure - null iorap remote. check for Log.wtf?"); - } - return false; - } - invokeRemote(mIorapRemote, - (IIorap remote) -> remote.setTaskListener(new RemoteTaskListener()) ); - registerInProcessListenersLocked(); - - Log.i(TAG, "Connected to iorapd native service."); - - return true; - } - - private final AppLaunchObserver mAppLaunchObserver = new AppLaunchObserver(); - private final EventSequenceValidator mEventSequenceValidator = new EventSequenceValidator(); - private final DexOptPackagesUpdated mDexOptPackagesUpdated = new DexOptPackagesUpdated(); - private boolean mRegisteredListeners = false; - - private void registerInProcessListenersLocked() { - if (mRegisteredListeners) { - // Listeners are registered only once (idempotent operation). - // - // Today listeners are tolerant of the remote side going away - // by handling remote errors. - // - // We could try to 'unregister' the listener when we get a binder disconnect, - // but we'd still have to handle the case of encountering synchronous errors so - // it really wouldn't be a win (other than having less log spew). - return; - } - - // Listen to App Launch Sequence events from ActivityTaskManager, - // and forward them to the native binder service. - ActivityMetricsLaunchObserverRegistry launchObserverRegistry = - provideLaunchObserverRegistry(); - launchObserverRegistry.registerLaunchObserver(mAppLaunchObserver); - launchObserverRegistry.registerLaunchObserver(mEventSequenceValidator); - - BackgroundDexOptService.addPackagesUpdatedListener(mDexOptPackagesUpdated); - - - mRegisteredListeners = true; - } - - private class DexOptPackagesUpdated implements BackgroundDexOptService.PackagesUpdatedListener { - @Override - public void onPackagesUpdated(ArraySet<String> updatedPackages) { - String[] updated = updatedPackages.toArray(new String[0]); - for (String packageName : updated) { - Log.d(TAG, "onPackagesUpdated: " + packageName); - invokeRemote(mIorapRemote, - (IIorap remote) -> - remote.onDexOptEvent(RequestId.nextValueForSequence(), - DexOptEvent.createPackageUpdate(packageName)) - ); - } - } - } - - private class AppLaunchObserver implements ActivityMetricsLaunchObserver { - // We add a synthetic sequence ID here to make it easier to differentiate new - // launch sequences on the native side. - private @AppLaunchEvent.SequenceId long mSequenceId = -1; - - // All callbacks occur on the same background thread. Don't synchronize explicitly. - - @Override - public void onIntentStarted(@NonNull Intent intent, long timestampNs) { - // #onIntentStarted [is the only transition that] initiates a new launch sequence. - ++mSequenceId; - - if (DEBUG) { - Log.v(TAG, String.format("AppLaunchObserver#onIntentStarted(%d, %s, %d)", - mSequenceId, intent, timestampNs)); - } - - invokeRemote(mIorapRemote, - (IIorap remote) -> - remote.onAppLaunchEvent(RequestId.nextValueForSequence(), - new AppLaunchEvent.IntentStarted(mSequenceId, intent, timestampNs)) - ); - } - - @Override - public void onIntentFailed() { - if (DEBUG) { - Log.v(TAG, String.format("AppLaunchObserver#onIntentFailed(%d)", mSequenceId)); - } - - invokeRemote(mIorapRemote, - (IIorap remote) -> - remote.onAppLaunchEvent(RequestId.nextValueForSequence(), - new AppLaunchEvent.IntentFailed(mSequenceId)) - ); - } - - @Override - public void onActivityLaunched(@NonNull @ActivityRecordProto byte[] activity, - @Temperature int temperature) { - if (DEBUG) { - Log.v(TAG, String.format("AppLaunchObserver#onActivityLaunched(%d, %s, %d)", - mSequenceId, activity, temperature)); - } - - invokeRemote(mIorapRemote, - (IIorap remote) -> - remote.onAppLaunchEvent(RequestId.nextValueForSequence(), - new AppLaunchEvent.ActivityLaunched(mSequenceId, activity, temperature)) - ); - } - - @Override - public void onActivityLaunchCancelled(@Nullable @ActivityRecordProto byte[] activity) { - if (DEBUG) { - Log.v(TAG, String.format("AppLaunchObserver#onActivityLaunchCancelled(%d, %s)", - mSequenceId, activity)); - } - - invokeRemote(mIorapRemote, - (IIorap remote) -> - remote.onAppLaunchEvent(RequestId.nextValueForSequence(), - new AppLaunchEvent.ActivityLaunchCancelled(mSequenceId, - activity))); - } - - @Override - public void onActivityLaunchFinished(@NonNull @ActivityRecordProto byte[] activity, - long timestampNs) { - if (DEBUG) { - Log.v(TAG, String.format("AppLaunchObserver#onActivityLaunchFinished(%d, %s, %d)", - mSequenceId, activity, timestampNs)); - } - - invokeRemote(mIorapRemote, - (IIorap remote) -> - remote.onAppLaunchEvent(RequestId.nextValueForSequence(), - new AppLaunchEvent.ActivityLaunchFinished(mSequenceId, - activity, - timestampNs)) - ); - } - - @Override - public void onReportFullyDrawn(@NonNull @ActivityRecordProto byte[] activity, - long timestampNs) { - if (DEBUG) { - Log.v(TAG, String.format("AppLaunchObserver#onReportFullyDrawn(%d, %s, %d)", - mSequenceId, activity, timestampNs)); - } - - invokeRemote(mIorapRemote, - (IIorap remote) -> - remote.onAppLaunchEvent(RequestId.nextValueForSequence(), - new AppLaunchEvent.ReportFullyDrawn(mSequenceId, activity, timestampNs)) - ); - } - } - - /** - * Debugging: - * - * $> adb shell dumpsys jobscheduler - * - * Search for 'IorapdJobServiceProxy'. - * - * JOB #1000/283673059: 6e54ed android/com.google.android.startop.iorap.IorapForwardingService$IorapdJobServiceProxy - * ^ ^ ^ - * (uid, job id) ComponentName(package/class) - * - * Forcing the job to be run, ignoring constraints: - * - * $> adb shell cmd jobscheduler run -f android 283673059 - * ^ ^ - * package job_id - * - * ------------------------------------------------------------ - * - * This class is instantiated newly by the JobService every time - * it wants to run a new job. - * - * We need to forward invocations to the current running instance of - * IorapForwardingService#IorapdJobService. - * - * Visibility: Must be accessible from android.app.AppComponentFactory - */ - public static class IorapdJobServiceProxy extends JobService { - - public IorapdJobServiceProxy() { - getActualIorapdJobService().bindProxy(this); - } - - - @NonNull - private IorapdJobService getActualIorapdJobService() { - // Can't ever be null, because the guarantee is that the - // IorapForwardingService is always running. - // We are in the same process as Job Service. - return sSelfService.mJobService; - } - - // Called by system to start the job. - @Override - public boolean onStartJob(JobParameters params) { - return getActualIorapdJobService().onStartJob(params); - } - - // Called by system to prematurely stop the job. - @Override - public boolean onStopJob(JobParameters params) { - return getActualIorapdJobService().onStopJob(params); - } - } - - private class IorapdJobService extends JobService { - private final ComponentName IORAPD_COMPONENT_NAME; - - private final Object mLock = new Object(); - // Jobs currently running remotely on iorapd. - // They were started by the JobScheduler and need to be finished. - private final HashMap<RequestId, JobParameters> mRunningJobs = new HashMap<>(); - - private final JobInfo IORAPD_JOB_INFO; - - private volatile IorapdJobServiceProxy mProxy; - - public void bindProxy(IorapdJobServiceProxy proxy) { - mProxy = proxy; - } - - // Create a new job service which immediately schedules a 24-hour idle maintenance mode - // background job to execute. - public IorapdJobService(Context context) { - if (DEBUG) { - Log.v(TAG, "IorapdJobService (Context=" + context.toString() + ")"); - } - - // Schedule the proxy class to be instantiated by the JobScheduler - // when it is time to invoke background jobs for IorapForwardingService. - - - // This also needs a BIND_JOB_SERVICE permission in - // frameworks/base/core/res/AndroidManifest.xml - IORAPD_COMPONENT_NAME = new ComponentName(context, IorapdJobServiceProxy.class); - - JobInfo.Builder builder = new JobInfo.Builder(JOB_ID_IORAPD, IORAPD_COMPONENT_NAME); - builder.setPeriodic(JOB_INTERVAL_MS); - builder.setPrefetch(true); - - builder.setRequiresCharging(true); - builder.setRequiresDeviceIdle(true); - - builder.setRequiresStorageNotLow(true); - - IORAPD_JOB_INFO = builder.build(); - - JobScheduler js = context.getSystemService(JobScheduler.class); - js.schedule(IORAPD_JOB_INFO); - Log.d(TAG, - "BgJob Scheduled (jobId=" + JOB_ID_IORAPD - + ", interval: " + JOB_INTERVAL_MS + "ms)"); - } - - // Called by system to start the job. - @Override - public boolean onStartJob(JobParameters params) { - // Tell iorapd to start a background job. - Log.d(TAG, "Starting background job: " + params.toString()); - - mAbortIdleCompilation.set(false); - // PackageManagerService starts before IORap service. - PackageManagerService pm = (PackageManagerService)ServiceManager.getService("package"); - List<String> pkgs = pm.getAllPackages(); - runIdleCompilationAsync(params, pkgs); - return true; - } - - private void runIdleCompilationAsync(final JobParameters params, final List<String> pkgs) { - new Thread("IORap_IdleCompilation") { - @Override - public void run() { - for (int i = 0; i < pkgs.size(); i++) { - String pkg = pkgs.get(i); - if (mAbortIdleCompilation.get()) { - Log.i(TAG, "The idle compilation is aborted"); - return; - } - - // We wait until that job's sequence ID returns to us with 'Completed', - RequestId request; - synchronized (mLock) { - // TODO: would be cleaner if we got the request from the - // 'invokeRemote' function. Better yet, consider - // a Pair<RequestId, Future<TaskResult>> or similar. - request = RequestId.nextValueForSequence(); - mRunningJobs.put(request, params); - } - - Log.i(TAG, String.format("IORap compile package: %s, [%d/%d]", - pkg, i + 1, pkgs.size())); - boolean shouldUpdateVersions = (i == 0); - if (!invokeRemote(mIorapRemote, (IIorap remote) -> - remote.onJobScheduledEvent(request, - JobScheduledEvent.createIdleMaintenance( - JobScheduledEvent.TYPE_START_JOB, - params, - pkg, - shouldUpdateVersions)))) { - synchronized (mLock) { - mRunningJobs.remove(request); // Avoid memory leaks. - } - } - - // Wait until the job is complete and removed from the running jobs. - retryWithTimeout(TIMEOUT, () -> { - synchronized (mLock) { - return !mRunningJobs.containsKey(request); - } - }); - } - - // Finish the job after all packages are compiled. - if (mProxy != null) { - mProxy.jobFinished(params, /*reschedule*/false); - } - } - }.start(); - } - - /** Retry until timeout. */ - private boolean retryWithTimeout(final Duration timeout, BooleanSupplier supplier) { - long totalSleepTimeMs = 0L; - long sleepIntervalMs = 10L; - while (true) { - if (supplier.getAsBoolean()) { - return true; - } - try { - TimeUnit.MILLISECONDS.sleep(sleepIntervalMs); - } catch (InterruptedException e) { - Log.e(TAG, e.getMessage()); - return false; - } - - totalSleepTimeMs += sleepIntervalMs; - if (totalSleepTimeMs > timeout.toMillis()) { - return false; - } - } - } - - // Called by system to prematurely stop the job. - @Override - public boolean onStopJob(JobParameters params) { - // As this is unexpected behavior, print a warning. - Log.w(TAG, "onStopJob(params=" + params.toString() + ")"); - mAbortIdleCompilation.set(true); - - // Yes, retry the job at a later time no matter what. - return true; - } - - // Listen to *all* task completes for all requests. - // The majority of these might be unrelated to background jobs. - public void onIorapdTaskCompleted(RequestId requestId) { - JobParameters jobParameters; - synchronized (mLock) { - jobParameters = mRunningJobs.remove(requestId); - } - - // Typical case: This was a task callback unrelated to our jobs. - if (jobParameters == null) { - return; - } - - if (DEBUG) { - Log.v(TAG, - String.format("IorapdJobService#onIorapdTaskCompleted(%s), found params=%s", - requestId, jobParameters)); - } - - Log.d(TAG, "Finished background job: " + jobParameters.toString()); - } - - public void onIorapdDisconnected() { - synchronized (mLock) { - mRunningJobs.clear(); - } - - if (DEBUG) { - Log.v(TAG, String.format("IorapdJobService#onIorapdDisconnected")); - } - - // TODO: should we try to resubmit all incomplete jobs after it's reconnected? - } - } - - private class RemoteTaskListener extends ITaskListener.Stub { - @Override - public void onProgress(RequestId requestId, TaskResult result) throws RemoteException { - if (DEBUG) { - Log.v(TAG, - String.format("RemoteTaskListener#onProgress(%s, %s)", requestId, result)); - } - - // TODO: implement rest. - } - - @Override - public void onComplete(RequestId requestId, TaskResult result) throws RemoteException { - if (DEBUG) { - Log.v(TAG, - String.format("RemoteTaskListener#onComplete(%s, %s)", requestId, result)); - } - - if (mJobService != null) { - mJobService.onIorapdTaskCompleted(requestId); - } - - // TODO: implement rest. - } - } - - /** Allow passing lambdas to #invokeRemote */ - private interface RemoteRunnable { - // TODO: run(RequestId) ? - void run(IIorap iorap) throws RemoteException; - } - - // Always pass in the iorap directly here to avoid data race. - private static boolean invokeRemote(IIorap iorap, RemoteRunnable r) { - if (iorap == null) { - Log.w(TAG, "IIorap went to null in this thread, drop invokeRemote."); - return false; - } - try { - r.run(iorap); - return true; - } catch (RemoteException e) { - // This could be a logic error (remote side returning error), which we need to fix. - // - // This could also be a DeadObjectException in which case its probably just iorapd - // being manually restarted. - // - // Don't make any assumption, since DeadObjectException could also mean iorapd crashed - // unexpectedly. - // - // DeadObjectExceptions are recovered from using DeathRecipient and #linkToDeath. - handleRemoteError(e); - return false; - } - } - - private static void handleRemoteError(Throwable t) { - if (WTF_CRASH) { - // In development modes, we just want to crash. - throw new AssertionError("unexpected remote error", t); - } else { - // Log to wtf which gets sent to dropbox, and in system_server this does not crash. - Log.wtf(TAG, t); - } - } - - // Encode A-Z bitstring into bits. Every character is bits. - // Characters outside of the range [a,z] are considered out of range. - // - // The least significant bits hold the last character. - // First 2 bits are left as 0. - private static int encodeEnglishAlphabetStringIntoInt(String name) { - int value = 0; - - final int CHARS_PER_INT = 6; - final int BITS_PER_CHAR = 5; - // Note: 2 top bits are unused, this also means our values are non-negative. - final char CHAR_LOWER = 'a'; - final char CHAR_UPPER = 'z'; - - if (name.length() > CHARS_PER_INT) { - throw new IllegalArgumentException( - "String too long. Cannot encode more than 6 chars: " + name); - } - - for (int i = 0; i < name.length(); ++i) { - char c = name.charAt(i); - - if (c < CHAR_LOWER || c > CHAR_UPPER) { - throw new IllegalArgumentException("String has out-of-range [a-z] chars: " + name); - } - - // Avoid sign extension during promotion. - int cur_value = (c & 0xFFFF) - (CHAR_LOWER & 0xFFFF); - if (cur_value >= (1 << BITS_PER_CHAR)) { - throw new AssertionError("wtf? i=" + i + ", name=" + name); - } - - value = value << BITS_PER_CHAR; - value = value | cur_value; - } - - return value; - } -} diff --git a/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java b/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java deleted file mode 100644 index b91dd71fd28c..000000000000 --- a/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2018 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.google.android.startop.iorap; - -import android.app.job.JobParameters; -import android.annotation.NonNull; -import android.os.Parcelable; -import android.os.Parcel; - -import android.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Forward JobService events to iorapd. <br /><br /> - * - * iorapd sometimes need to use background jobs. Forwarding these events to iorapd - * notifies iorapd when it is an opportune time to execute these background jobs. - * - * @hide - */ -public class JobScheduledEvent implements Parcelable { - - /** JobService#onJobStarted */ - public static final int TYPE_START_JOB = 0; - /** JobService#onJobStopped */ - public static final int TYPE_STOP_JOB = 1; - private static final int TYPE_MAX = 1; - - /** @hide */ - @IntDef(flag = true, prefix = { "TYPE_" }, value = { - TYPE_START_JOB, - TYPE_STOP_JOB, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface Type {} - - @Type public final int type; - - /** @see JobParameters#getJobId() */ - public final int jobId; - - public final String packageName; - - public final boolean shouldUpdateVersions; - - /** Device is 'idle' and it's charging (plugged in). */ - public static final int SORT_IDLE_MAINTENANCE = 0; - private static final int SORT_MAX = 0; - - /** @hide */ - @IntDef(flag = true, prefix = { "SORT_" }, value = { - SORT_IDLE_MAINTENANCE, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface Sort {} - - /** - * Roughly corresponds to the {@code extras} fields in a JobParameters. - */ - @Sort public final int sort; - - /** - * Creates a {@link #SORT_IDLE_MAINTENANCE} event from the type and job parameters. - * - * Only the job ID is retained from {@code jobParams}, all other param info is dropped. - */ - @NonNull - public static JobScheduledEvent createIdleMaintenance( - @Type int type, JobParameters jobParams, String packageName, boolean shouldUpdateVersions) { - return new JobScheduledEvent( - type, jobParams.getJobId(), SORT_IDLE_MAINTENANCE, packageName, shouldUpdateVersions); - } - - private JobScheduledEvent(@Type int type, - int jobId, - @Sort int sort, - String packageName, - boolean shouldUpdateVersions) { - this.type = type; - this.jobId = jobId; - this.sort = sort; - this.packageName = packageName; - this.shouldUpdateVersions = shouldUpdateVersions; - - checkConstructorArguments(); - } - - private void checkConstructorArguments() { - CheckHelpers.checkTypeInRange(type, TYPE_MAX); - // No check for 'jobId': any int is valid. - CheckHelpers.checkTypeInRange(sort, SORT_MAX); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } else if (other instanceof JobScheduledEvent) { - return equals((JobScheduledEvent) other); - } - return false; - } - - private boolean equals(JobScheduledEvent other) { - return type == other.type && - jobId == other.jobId && - sort == other.sort && - packageName.equals(other.packageName) && - shouldUpdateVersions == other.shouldUpdateVersions; - } - - @Override - public String toString() { - return String.format( - "{type: %d, jobId: %d, sort: %d, packageName: %s, shouldUpdateVersions %b}", - type, jobId, sort, packageName, shouldUpdateVersions); - } - - //<editor-fold desc="Binder boilerplate"> - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(type); - out.writeInt(jobId); - out.writeInt(sort); - out.writeString(packageName); - out.writeBoolean(shouldUpdateVersions); - - // We do not parcel the entire JobParameters here because there is no C++ equivalent - // of that class [which the iorapd side of the binder interface requires]. - } - - private JobScheduledEvent(Parcel in) { - this.type = in.readInt(); - this.jobId = in.readInt(); - this.sort = in.readInt(); - this.packageName = in.readString(); - this.shouldUpdateVersions = in.readBoolean(); - - checkConstructorArguments(); - } - - @Override - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator<JobScheduledEvent> CREATOR - = new Parcelable.Creator<JobScheduledEvent>() { - public JobScheduledEvent createFromParcel(Parcel in) { - return new JobScheduledEvent(in); - } - - public JobScheduledEvent[] newArray(int size) { - return new JobScheduledEvent[size]; - } - }; - //</editor-fold> -} diff --git a/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java b/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java deleted file mode 100644 index aa4eea716363..000000000000 --- a/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2018 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.google.android.startop.iorap; - -import android.annotation.NonNull; -import android.os.Parcelable; -import android.os.Parcel; -import android.net.Uri; - -import android.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Objects; - -/** - * Forward package manager events to iorapd. <br /><br /> - * - * Knowing when packages are modified by the system are a useful tidbit to help with performance: - * for example when a package is replaced, it could be a hint used to invalidate any collected - * io profiles used for prefetching or pinning. - * - * @hide - */ -public class PackageEvent implements Parcelable { - - /** @see android.content.Intent#ACTION_PACKAGE_REPLACED */ - public static final int TYPE_REPLACED = 0; - private static final int TYPE_MAX = 0; - - /** @hide */ - @IntDef(flag = true, prefix = { "TYPE_" }, value = { - TYPE_REPLACED, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface Type {} - - @Type public final int type; - - /** The path that a package is installed in, for example {@code /data/app/.../base.apk}. */ - public final Uri packageUri; - /** The name of the package, for example {@code com.android.calculator}. */ - public final String packageName; - - @NonNull - public static PackageEvent createReplaced(Uri packageUri, String packageName) { - return new PackageEvent(TYPE_REPLACED, packageUri, packageName); - } - - private PackageEvent(@Type int type, Uri packageUri, String packageName) { - this.type = type; - this.packageUri = packageUri; - this.packageName = packageName; - - checkConstructorArguments(); - } - - private void checkConstructorArguments() { - CheckHelpers.checkTypeInRange(type, TYPE_MAX); - Objects.requireNonNull(packageUri, "packageUri"); - Objects.requireNonNull(packageName, "packageName"); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } else if (other instanceof PackageEvent) { - return equals((PackageEvent) other); - } - return false; - } - - private boolean equals(PackageEvent other) { - return type == other.type && - Objects.equals(packageUri, other.packageUri) && - Objects.equals(packageName, other.packageName); - } - - @Override - public String toString() { - return String.format("{packageUri: %s, packageName: %s}", packageUri, packageName); - } - - //<editor-fold desc="Binder boilerplate"> - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(type); - packageUri.writeToParcel(out, flags); - out.writeString(packageName); - } - - private PackageEvent(Parcel in) { - this.type = in.readInt(); - this.packageUri = Uri.CREATOR.createFromParcel(in); - this.packageName = in.readString(); - - checkConstructorArguments(); - } - - @Override - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator<PackageEvent> CREATOR - = new Parcelable.Creator<PackageEvent>() { - public PackageEvent createFromParcel(Parcel in) { - return new PackageEvent(in); - } - - public PackageEvent[] newArray(int size) { - return new PackageEvent[size]; - } - }; - //</editor-fold> -} diff --git a/startop/iorap/src/com/google/android/startop/iorap/RequestId.java b/startop/iorap/src/com/google/android/startop/iorap/RequestId.java deleted file mode 100644 index 503e1c633581..000000000000 --- a/startop/iorap/src/com/google/android/startop/iorap/RequestId.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2018 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.google.android.startop.iorap; - -import android.os.Parcelable; -import android.os.Parcel; - -import android.annotation.NonNull; - -/** - * Uniquely identify an {@link com.google.android.startop.iorap.IIorap} method invocation, - * used for asynchronous callbacks by the server. <br /><br /> - * - * As all system server binder calls must be {@code oneway}, this means all invocations - * into {@link com.google.android.startop.iorap.IIorap} are non-blocking. The request ID - * exists to associate all calls with their respective callbacks in - * {@link com.google.android.startop.iorap.ITaskListener}. - * - * @see com.google.android.startop.iorap.IIorap - * - * @hide - */ -public class RequestId implements Parcelable { - - public final long requestId; - - private static Object mLock = new Object(); - private static long mNextRequestId = 0; - - /** - * Create a monotonically increasing request ID.<br /><br /> - * - * It is invalid to re-use the same request ID for multiple method calls on - * {@link com.google.android.startop.iorap.IIorap}; a new request ID must be created - * each time. - */ - @NonNull public static RequestId nextValueForSequence() { - long currentRequestId; - synchronized (mLock) { - currentRequestId = mNextRequestId; - ++mNextRequestId; - } - return new RequestId(currentRequestId); - } - - private RequestId(long requestId) { - this.requestId = requestId; - - checkConstructorArguments(); - } - - private void checkConstructorArguments() { - if (requestId < 0) { - throw new IllegalArgumentException("request id must be non-negative"); - } - } - - @Override - public String toString() { - return String.format("{requestId: %d}", requestId); - } - - @Override - public int hashCode() { - return Long.hashCode(requestId); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } else if (other instanceof RequestId) { - return equals((RequestId) other); - } - return false; - } - - private boolean equals(RequestId other) { - return requestId == other.requestId; - } - - - //<editor-fold desc="Binder boilerplate"> - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeLong(requestId); - } - - private RequestId(Parcel in) { - requestId = in.readLong(); - - checkConstructorArguments(); - } - - @Override - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator<RequestId> CREATOR - = new Parcelable.Creator<RequestId>() { - public RequestId createFromParcel(Parcel in) { - return new RequestId(in); - } - - public RequestId[] newArray(int size) { - return new RequestId[size]; - } - }; - //</editor-fold> -} diff --git a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java b/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java deleted file mode 100644 index 75d47f9e3d17..000000000000 --- a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2018 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.google.android.startop.iorap; - -import android.os.Parcelable; -import android.os.Parcel; - -import android.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Forward system service events to iorapd. - * - * @see com.android.server.SystemService - * - * @hide - */ -public class SystemServiceEvent implements Parcelable { - - /** @see com.android.server.SystemService#onBootPhase */ - public static final int TYPE_BOOT_PHASE = 0; - /** @see com.android.server.SystemService#onStart */ - public static final int TYPE_START = 1; - private static final int TYPE_MAX = TYPE_START; - - /** @hide */ - @IntDef(flag = true, prefix = { "TYPE_" }, value = { - TYPE_BOOT_PHASE, - TYPE_START, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface Type {} - - @Type public final int type; - - // TODO: do we want to pass the exact build phase enum? - - public SystemServiceEvent(@Type int type) { - this.type = type; - checkConstructorArguments(); - } - - private void checkConstructorArguments() { - CheckHelpers.checkTypeInRange(type, TYPE_MAX); - } - - @Override - public String toString() { - return String.format("{type: %d}", type); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } else if (other instanceof SystemServiceEvent) { - return equals((SystemServiceEvent) other); - } - return false; - } - - private boolean equals(SystemServiceEvent other) { - return type == other.type; - } - - //<editor-fold desc="Binder boilerplate"> - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(type); - } - - private SystemServiceEvent(Parcel in) { - this.type = in.readInt(); - checkConstructorArguments(); - } - - @Override - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator<SystemServiceEvent> CREATOR - = new Parcelable.Creator<SystemServiceEvent>() { - public SystemServiceEvent createFromParcel(Parcel in) { - return new SystemServiceEvent(in); - } - - public SystemServiceEvent[] newArray(int size) { - return new SystemServiceEvent[size]; - } - }; - //</editor-fold> -} diff --git a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java b/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java deleted file mode 100644 index 2e7bafe7bdbf..000000000000 --- a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2018 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.google.android.startop.iorap; - -import android.os.Parcelable; -import android.os.Parcel; - -import android.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Forward user events to iorapd.<br /><br /> - * - * Knowledge of the logged-in user is reserved to be used to set-up appropriate policies - * by iorapd (e.g. to handle user default pinned applications changing). - * - * @see com.android.server.SystemService - * - * @hide - */ -public class SystemServiceUserEvent implements Parcelable { - - /** @see com.android.server.SystemService#onUserStarting */ - public static final int TYPE_START_USER = 0; - /** @see com.android.server.SystemService#onUserUnlocking */ - public static final int TYPE_UNLOCK_USER = 1; - /** @see com.android.server.SystemService#onUserSwitching*/ - public static final int TYPE_SWITCH_USER = 2; - /** @see com.android.server.SystemService#onUserStopping */ - public static final int TYPE_STOP_USER = 3; - /** @see com.android.server.SystemService#onUserStopped */ - public static final int TYPE_CLEANUP_USER = 4; - private static final int TYPE_MAX = TYPE_CLEANUP_USER; - - /** @hide */ - @IntDef(flag = true, prefix = { "TYPE_" }, value = { - TYPE_START_USER, - TYPE_UNLOCK_USER, - TYPE_SWITCH_USER, - TYPE_STOP_USER, - TYPE_CLEANUP_USER, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface Type {} - - @Type public final int type; - public final int userHandle; - - public SystemServiceUserEvent(@Type int type, int userHandle) { - this.type = type; - this.userHandle = userHandle; - checkConstructorArguments(); - } - - private void checkConstructorArguments() { - CheckHelpers.checkTypeInRange(type, TYPE_MAX); - if (userHandle < 0) { - throw new IllegalArgumentException("userHandle must be non-negative"); - } - } - - @Override - public String toString() { - return String.format("{type: %d, userHandle: %d}", type, userHandle); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } else if (other instanceof SystemServiceUserEvent) { - return equals((SystemServiceUserEvent) other); - } - return false; - } - - private boolean equals(SystemServiceUserEvent other) { - return type == other.type && - userHandle == other.userHandle; - } - - //<editor-fold desc="Binder boilerplate"> - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(type); - out.writeInt(userHandle); - } - - private SystemServiceUserEvent(Parcel in) { - this.type = in.readInt(); - this.userHandle = in.readInt(); - checkConstructorArguments(); - } - - @Override - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator<SystemServiceUserEvent> CREATOR - = new Parcelable.Creator<SystemServiceUserEvent>() { - public SystemServiceUserEvent createFromParcel(Parcel in) { - return new SystemServiceUserEvent(in); - } - - public SystemServiceUserEvent[] newArray(int size) { - return new SystemServiceUserEvent[size]; - } - }; - //</editor-fold> -} diff --git a/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java b/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java deleted file mode 100644 index b5fd6d8d1c45..000000000000 --- a/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2018 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.google.android.startop.iorap; - -import android.os.Parcelable; -import android.os.Parcel; - -import android.annotation.IntDef; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Result data accompanying a request for {@link com.google.android.startop.iorap.ITaskListener} - * callbacks.<br /><br /> - * - * Following {@link com.google.android.startop.iorap.IIorap} method invocation, - * iorapd will issue in-order callbacks for that corresponding {@link RequestId}.<br /><br /> - * - * State transitions are as follows: <br /><br /> - * - * <pre> - * ┌─────────────────────────────┐ - * │ ▼ - * ┌───────┐ ┌─────────┐ ╔═══════════╗ - * ──▶ │ BEGAN │ ──▶ │ ONGOING │ ──▶ ║ COMPLETED ║ - * └───────┘ └─────────┘ ╚═══════════╝ - * │ │ - * │ │ - * ▼ │ - * ╔═══════╗ │ - * ──▶ ║ ERROR ║ ◀─────┘ - * ╚═══════╝ - * - * </pre> <!-- system/iorap/docs/binder/TaskResult.dot --> - * - * @hide - */ -public class TaskResult implements Parcelable { - - public static final int STATE_BEGAN = 0; - public static final int STATE_ONGOING = 1; - public static final int STATE_COMPLETED = 2; - public static final int STATE_ERROR = 3; - private static final int STATE_MAX = STATE_ERROR; - - /** @hide */ - @IntDef(flag = true, prefix = { "STATE_" }, value = { - STATE_BEGAN, - STATE_ONGOING, - STATE_COMPLETED, - STATE_ERROR, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface State {} - - @State public final int state; - - @Override - public String toString() { - return String.format("{state: %d}", state); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } else if (other instanceof TaskResult) { - return equals((TaskResult) other); - } - return false; - } - - private boolean equals(TaskResult other) { - return state == other.state; - } - - public TaskResult(@State int state) { - this.state = state; - - checkConstructorArguments(); - } - - private void checkConstructorArguments() { - CheckHelpers.checkStateInRange(state, STATE_MAX); - } - - //<editor-fold desc="Binder boilerplate"> - @Override - public void writeToParcel(Parcel out, int flags) { - out.writeInt(state); - } - - private TaskResult(Parcel in) { - state = in.readInt(); - - checkConstructorArguments(); - } - - @Override - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator<TaskResult> CREATOR - = new Parcelable.Creator<TaskResult>() { - public TaskResult createFromParcel(Parcel in) { - return new TaskResult(in); - } - - public TaskResult[] newArray(int size) { - return new TaskResult[size]; - } - }; - //</editor-fold> -} diff --git a/startop/iorap/stress/Android.bp b/startop/iorap/stress/Android.bp deleted file mode 100644 index 6e8725d091fb..000000000000 --- a/startop/iorap/stress/Android.bp +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (C) 2020 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 { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -cc_binary { - name: "iorap.stress.memory", - srcs: ["main_memory.cc"], - - cflags: [ - "-Wall", - "-Wextra", - "-Werror", - "-Wno-unused-parameter" - ], - - shared_libs: [ - "libbase" - ], - - host_supported: true, -} diff --git a/startop/iorap/stress/main_memory.cc b/startop/iorap/stress/main_memory.cc deleted file mode 100644 index 1f268619e4d9..000000000000 --- a/startop/iorap/stress/main_memory.cc +++ /dev/null @@ -1,126 +0,0 @@ -// -// Copyright (C) 2020 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. -// - -#include <chrono> -#include <fstream> -#include <iostream> -#include <random> -#include <string> - -#include <string.h> -#include <stdlib.h> -#include <sys/mman.h> - -#include <android-base/parseint.h> - -static constexpr size_t kBytesPerMb = 1048576; -const size_t kMemoryAllocationSize = 2 * 1024 * kBytesPerMb; - -#define USE_MLOCKALL 0 - -std::string GetProcessStatus(const char* key) { - // Build search pattern of key and separator. - std::string pattern(key); - pattern.push_back(':'); - - // Search for status lines starting with pattern. - std::ifstream fs("/proc/self/status"); - std::string line; - while (std::getline(fs, line)) { - if (strncmp(pattern.c_str(), line.c_str(), pattern.size()) == 0) { - // Skip whitespace in matching line (if any). - size_t pos = line.find_first_not_of(" \t", pattern.size()); - if (pos == std::string::npos) { - break; - } - return std::string(line, pos); - } - } - return "<unknown>"; -} - -int main(int argc, char** argv) { - size_t allocationSize = 0; - if (argc >= 2) { - if (!android::base::ParseUint(argv[1], /*out*/&allocationSize)) { - std::cerr << "Failed to parse the allocation size (must be 0,MAX_SIZE_T)" << std::endl; - return 1; - } - } else { - allocationSize = kMemoryAllocationSize; - } - - void* mem = malloc(allocationSize); - if (mem == nullptr) { - std::cerr << "Malloc failed" << std::endl; - return 1; - } - - volatile int* imem = static_cast<int *>(mem); // don't optimize out memory usage - - size_t imemCount = allocationSize / sizeof(int); - - std::cout << "Allocated " << allocationSize << " bytes" << std::endl; - - auto seed = std::chrono::high_resolution_clock::now().time_since_epoch().count(); - std::mt19937 mt_rand(seed); - - size_t randPrintCount = 10; - - // Write random numbers: - // * Ensures each page is resident - // * Avoids zeroed out pages (zRAM) - // * Avoids same-page merging - for (size_t i = 0; i < imemCount; ++i) { - imem[i] = mt_rand(); - - if (i < randPrintCount) { - std::cout << "Generated random value: " << imem[i] << std::endl; - } - } - -#if USE_MLOCKALL - /* - * Lock all pages from the address space of this process. - */ - if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { - std::cerr << "Mlockall failed" << std::endl; - return 1; - } -#else - // Use mlock because of the predictable VmLck size. - // Using mlockall tends to bring in anywhere from 2-2.5GB depending on the device. - if (mlock(mem, allocationSize) != 0) { - std::cerr << "Mlock failed" << std::endl; - return 1; - } -#endif - - // Validate memory is actually resident and locked with: - // $> cat /proc/$(pidof iorap.stress.memory)/status | grep VmLck - std::cout << "Locked memory (VmLck) = " << GetProcessStatus("VmLck") << std::endl; - - std::cout << "Press any key to terminate" << std::endl; - int any_input; - std::cin >> any_input; - - std::cout << "Terminating..." << std::endl; - - munlockall(); - free(mem); - - return 0; -} diff --git a/startop/iorap/tests/Android.bp b/startop/iorap/tests/Android.bp deleted file mode 100644 index ad3d001ad7d4..000000000000 --- a/startop/iorap/tests/Android.bp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2018 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. - -// TODO: once b/80095087 is fixed, rewrite this back to android_test -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -java_library { - name: "libiorap-java-test-lib", - srcs: ["src/**/*.kt"], - static_libs: [ - // Non-test dependencies - // library under test - "services.startop.iorap", - // need the system_server code to be on the classpath, - "services.core", - // Test Dependencies - // test android dependencies - "platform-test-annotations", - "androidx.test.rules", - // test framework dependencies - "mockito-target-inline-minus-junit4", - // "mockito-target-minus-junit4", - // Mockito also requires JNI (see Android.mk) - // and android:debuggable=true (see AndroidManifest.xml) - "truth-prebuilt", - ], - // sdk_version: "current", - // certificate: "platform", - libs: [ - "android.test.base", - "android.test.runner", - ], - // test_suites: ["device-tests"], -} - -android_test { - name: "libiorap-java-tests", - dxflags: ["--multi-dex"], - test_suites: ["device-tests"], - static_libs: ["libiorap-java-test-lib"], - compile_multilib: "both", - jni_libs: [ - "libdexmakerjvmtiagent", - "libstaticjvmtiagent", - "libmultiplejvmtiagentsinterferenceagent", - ], - libs: [ - "android.test.base", - "android.test.runner", - ], - // Use private APIs - certificate: "platform", - platform_apis: true, -} diff --git a/startop/iorap/tests/AndroidManifest.xml b/startop/iorap/tests/AndroidManifest.xml deleted file mode 100644 index b967e7207a3f..000000000000 --- a/startop/iorap/tests/AndroidManifest.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2018 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. ---> -<!--suppress AndroidUnknownAttribute --> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.google.android.startop.iorap.tests" - android:sharedUserId="com.google.android.startop.iorap.tests" - android:versionCode="1" - android:versionName="1.0" > - - <!--suppress AndroidDomInspection --> - <instrumentation - android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="com.google.android.startop.iorap.tests" /> - - <!-- - 'debuggable=true' is required to properly load mockito jvmti dependencies, - otherwise it gives the following error at runtime: - - Openjdkjvmti plugin was loaded on a non-debuggable Runtime. - Plugin was loaded too late to change runtime state to DEBUGGABLE. --> - <application android:debuggable="true"> - <uses-library android:name="android.test.runner" /> - </application> -</manifest> diff --git a/startop/iorap/tests/AndroidTest.xml b/startop/iorap/tests/AndroidTest.xml deleted file mode 100644 index 6102c44e61bf..000000000000 --- a/startop/iorap/tests/AndroidTest.xml +++ /dev/null @@ -1,66 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2018 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. ---> - -<configuration description="Runs libiorap-java-tests."> - <option name="test-suite-tag" value="apct" /> - <option name="test-suite-tag" value="apct-instrumentation" /> - <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> - <option name="cleanup-apks" value="true" /> - <option name="test-file-name" value="libiorap-java-tests.apk" /> - </target_preparer> - - <!-- - Our IIorapIntegrationTest.kt requires setlinux to be disabled: - it connects to the iorapd binder service but this requires selinux permissions: - - avc: denied { find } for service=iorapd pid=2738 uid=10050 - scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:iorapd_service:s0 - tclass=service_manager permissive=0 - --> - <target_preparer class="com.android.tradefed.targetprep.DisableSELinuxTargetPreparer"> - </target_preparer> - - <!-- do not use DeviceSetup#set-property because it reboots the device b/136200738. - furthermore the changes in /data/local.prop don't actually seem to get picked up. - --> - <target_preparer - class="com.android.tradefed.targetprep.DeviceSetup"> - <!-- we need this magic flag, otherwise it always reboots and breaks the selinux --> - <option name="force-skip-system-props" value="true" /> - - <!-- Crash instead of using Log.wtf within the system_server iorap code. --> - <option name="run-command" value="setprop iorapd.forwarding_service.wtf_crash true" /> - <!-- IIorapd has fake behavior: it doesn't do anything but reply with 'DONE' status --> - <option name="run-command" value="setprop iorapd.binder.fake true" /> - - <!-- iorapd does not pick up the above changes until we restart it --> - <option name="run-command" value="stop iorapd" /> - <option name="run-command" value="start iorapd" /> - <!-- give it some time to restart the service; otherwise the first unit test might fail --> - <option name="run-command" value="sleep 1" /> - </target_preparer> - - <test class="com.android.tradefed.testtype.AndroidJUnitTest" > - <option name="package" value="com.google.android.startop.iorap.tests" /> - <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> - </test> - - <!-- using DeviceSetup again does not work. we simply leave the device in a semi-bad - state. there is no way to clean this up as far as I know. - --> - -</configuration> - diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/AppLaunchEventTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/AppLaunchEventTest.kt deleted file mode 100644 index 51e407d4cbff..000000000000 --- a/startop/iorap/tests/src/com/google/android/startop/iorap/AppLaunchEventTest.kt +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2019 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.google.android.startop.iorap - -import android.content.Intent; -import android.net.Uri -import android.os.Parcel -import android.os.Parcelable -import androidx.test.filters.SmallTest -import com.google.android.startop.iorap.AppLaunchEvent; -import com.google.android.startop.iorap.AppLaunchEvent.ActivityLaunched -import com.google.android.startop.iorap.AppLaunchEvent.ActivityLaunchCancelled -import com.google.android.startop.iorap.AppLaunchEvent.ActivityLaunchFinished -import com.google.android.startop.iorap.AppLaunchEvent.IntentStarted; -import com.google.android.startop.iorap.AppLaunchEvent.IntentFailed; -import com.google.android.startop.iorap.AppLaunchEvent.ReportFullyDrawn -import com.google.common.truth.Truth.assertThat -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.Parameterized - - -/** - * Basic unit tests to test all of the [AppLaunchEvent]s in [com.google.android.startop.iorap]. - */ -@SmallTest -class AppLaunchEventTest { - /** - * Test for IntentStarted. - */ - @Test - fun testIntentStarted() { - var intent = Intent() - val valid = IntentStarted(/* sequenceId= */2L, intent, /* timestampNs= */ 1L) - val copy = IntentStarted(/* sequenceId= */2L, intent, /* timestampNs= */ 1L) - val noneCopy1 = IntentStarted(/* sequenceId= */1L, intent, /* timestampNs= */ 1L) - val noneCopy2 = IntentStarted(/* sequenceId= */2L, intent, /* timestampNs= */ 2L) - val noneCopy3 = IntentStarted(/* sequenceId= */2L, Intent(), /* timestampNs= */ 1L) - - // equals(Object other) - assertThat(valid).isEqualTo(copy) - assertThat(valid).isNotEqualTo(noneCopy1) - assertThat(valid).isNotEqualTo(noneCopy2) - assertThat(valid).isNotEqualTo(noneCopy3) - - // test toString() - val result = valid.toString() - assertThat(result).isEqualTo("IntentStarted{sequenceId=2, intent=Intent { } , timestampNs=1}") - } - - /** - * Test for IntentFailed. - */ - @Test - fun testIntentFailed() { - val valid = IntentFailed(/* sequenceId= */2L) - val copy = IntentFailed(/* sequenceId= */2L) - val noneCopy = IntentFailed(/* sequenceId= */1L) - - // equals(Object other) - assertThat(valid).isEqualTo(copy) - assertThat(valid).isNotEqualTo(noneCopy) - - // test toString() - val result = valid.toString() - assertThat(result).isEqualTo("IntentFailed{sequenceId=2}") - } - - /** - * Test for ActivityLaunched. - */ - @Test - fun testActivityLaunched() { - //var activityRecord = - val valid = ActivityLaunched(/* sequenceId= */2L, "test".toByteArray(), - /* temperature= */ 0) - val copy = ActivityLaunched(/* sequenceId= */2L, "test".toByteArray(), - /* temperature= */ 0) - val noneCopy1 = ActivityLaunched(/* sequenceId= */1L, "test".toByteArray(), - /* temperature= */ 0) - val noneCopy2 = ActivityLaunched(/* sequenceId= */1L, "test".toByteArray(), - /* temperature= */ 1) - val noneCopy3 = ActivityLaunched(/* sequenceId= */1L, "test1".toByteArray(), - /* temperature= */ 0) - - // equals(Object other) - assertThat(valid).isEqualTo(copy) - assertThat(valid).isNotEqualTo(noneCopy1) - assertThat(valid).isNotEqualTo(noneCopy2) - assertThat(valid).isNotEqualTo(noneCopy3) - - // test toString() - val result = valid.toString() - assertThat(result).isEqualTo("ActivityLaunched{sequenceId=2, test, temperature=0}") - } - - - /** - * Test for ActivityLaunchFinished. - */ - @Test - fun testActivityLaunchFinished() { - val valid = ActivityLaunchFinished(/* sequenceId= */2L, "test".toByteArray(), - /* timestampNs= */ 1L) - val copy = ActivityLaunchFinished(/* sequenceId= */2L, "test".toByteArray(), - /* timestampNs= */ 1L) - val noneCopy1 = ActivityLaunchFinished(/* sequenceId= */1L, "test".toByteArray(), - /* timestampNs= */ 1L) - val noneCopy2 = ActivityLaunchFinished(/* sequenceId= */1L, "test".toByteArray(), - /* timestampNs= */ 2L) - val noneCopy3 = ActivityLaunchFinished(/* sequenceId= */2L, "test1".toByteArray(), - /* timestampNs= */ 1L) - - // equals(Object other) - assertThat(valid).isEqualTo(copy) - assertThat(valid).isNotEqualTo(noneCopy1) - assertThat(valid).isNotEqualTo(noneCopy2) - assertThat(valid).isNotEqualTo(noneCopy3) - - // test toString() - val result = valid.toString() - assertThat(result).isEqualTo("ActivityLaunchFinished{sequenceId=2, test, timestampNs=1}") - } - - /** - * Test for ActivityLaunchCancelled. - */ - @Test - fun testActivityLaunchCancelled() { - val valid = ActivityLaunchCancelled(/* sequenceId= */2L, "test".toByteArray()) - val copy = ActivityLaunchCancelled(/* sequenceId= */2L, "test".toByteArray()) - val noneCopy1 = ActivityLaunchCancelled(/* sequenceId= */1L, "test".toByteArray()) - val noneCopy2 = ActivityLaunchCancelled(/* sequenceId= */2L, "test1".toByteArray()) - - // equals(Object other) - assertThat(valid).isEqualTo(copy) - assertThat(valid).isNotEqualTo(noneCopy1) - assertThat(valid).isNotEqualTo(noneCopy2) - - // test toString() - val result = valid.toString() - assertThat(result).isEqualTo("ActivityLaunchCancelled{sequenceId=2, test}") - } - - /** - * Test for ReportFullyDrawn. - */ - @Test - fun testReportFullyDrawn() { - val valid = ReportFullyDrawn(/* sequenceId= */2L, "test".toByteArray(), /* timestampNs= */ 1L) - val copy = ReportFullyDrawn(/* sequenceId= */2L, "test".toByteArray(), /* timestampNs= */ 1L) - val noneCopy1 = ReportFullyDrawn(/* sequenceId= */1L, "test".toByteArray(), - /* timestampNs= */ 1L) - val noneCopy2 = ReportFullyDrawn(/* sequenceId= */1L, "test".toByteArray(), - /* timestampNs= */ 1L) - val noneCopy3 = ReportFullyDrawn(/* sequenceId= */2L, "test1".toByteArray(), - /* timestampNs= */ 1L) - - // equals(Object other) - assertThat(valid).isEqualTo(copy) - assertThat(valid).isNotEqualTo(noneCopy1) - assertThat(valid).isNotEqualTo(noneCopy2) - assertThat(valid).isNotEqualTo(noneCopy3) - - // test toString() - val result = valid.toString() - assertThat(result).isEqualTo("ReportFullyDrawn{sequenceId=2, test, timestampNs=1}") - } -} diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt deleted file mode 100644 index 18c249136d05..000000000000 --- a/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2018 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.google.android.startop.iorap - -import android.net.Uri -import android.os.ServiceManager -import androidx.test.filters.FlakyTest -import androidx.test.filters.MediumTest -import org.junit.Test -import org.mockito.Mockito.argThat -import org.mockito.Mockito.eq -import org.mockito.Mockito.inOrder -import org.mockito.Mockito.spy -import org.mockito.Mockito.timeout - -// @Ignore("Test is disabled until iorapd is added to init and there's selinux policies for it") -@MediumTest -@FlakyTest(bugId = 149098310) // Failing on cuttlefish with SecurityException. -class IIorapIntegrationTest { - /** - * @throws ServiceManager.ServiceNotFoundException if iorapd service could not be found - */ - private val iorapService: IIorap by lazy { - // TODO: connect to 'iorapd.stub' which doesn't actually do any work other than reply. - IIorap.Stub.asInterface(ServiceManager.getServiceOrThrow("iorapd")) - - // Use 'adb shell setenforce 0' otherwise this whole test fails, - // because the servicemanager is not allowed to hand out the binder token for iorapd. - - // TODO: implement the selinux policies for iorapd. - } - - // A dummy binder stub implementation is required to use with mockito#spy. - // Mockito overrides the methods at runtime and tracks how methods were invoked. - open class DummyTaskListener : ITaskListener.Stub() { - // Note: make parameters nullable to avoid the kotlin IllegalStateExceptions - // from using the mockito matchers (eq, argThat, etc). - override fun onProgress(requestId: RequestId?, result: TaskResult?) { - } - - override fun onComplete(requestId: RequestId?, result: TaskResult?) { - } - } - - private fun testAnyMethod(func: (RequestId) -> Unit) { - val taskListener = spy(DummyTaskListener())!! - - // FIXME: b/149098310 - return - - try { - iorapService.setTaskListener(taskListener) - // Note: Binder guarantees total order for oneway messages sent to the same binder - // interface, so we don't need any additional blocking here before sending later calls. - - // Every new method call should have a unique request id. - val requestId = RequestId.nextValueForSequence()!! - - // Apply the specific function under test. - func(requestId) - - // Typical mockito behavior is to allow any-order callbacks, but we want to test order. - val inOrder = inOrder(taskListener) - - // The "stub" behavior of iorapd is that every request immediately gets a response of - // BEGAN,ONGOING,COMPLETED - inOrder.verify(taskListener, timeout(100)) - .onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_BEGAN }) - inOrder.verify(taskListener, timeout(100)) - .onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_ONGOING }) - inOrder.verify(taskListener, timeout(100)) - .onComplete(eq(requestId), argThat { it!!.state == TaskResult.STATE_COMPLETED }) - inOrder.verifyNoMoreInteractions() - } finally { - // iorapService.setTaskListener(null) - // FIXME: null is broken, C++ side sees a non-null object. - } - } - - @Test - fun testOnPackageEvent() { - // FIXME (b/137134253): implement PackageEvent parsing on the C++ side. - // This is currently (silently: b/137135024) failing because IIorap is 'oneway' and the - // C++ PackageEvent un-parceling fails since its not implemented fully. - /* - testAnyMethod { requestId : RequestId -> - iorapService.onPackageEvent(requestId, - PackageEvent.createReplaced( - Uri.parse("https://www.google.com"), "com.fake.package")) - } - */ - } - - @Test - fun testOnAppIntentEvent() { - testAnyMethod { requestId: RequestId -> - iorapService.onAppIntentEvent(requestId, AppIntentEvent.createDefaultIntentChanged( - ActivityInfo("dont care", "dont care"), - ActivityInfo("dont care 2", "dont care 2"))) - } - } - - @Test - fun testOnAppLaunchEvent() { - testAnyMethod { requestId : RequestId -> - iorapService.onAppLaunchEvent(requestId, AppLaunchEvent.IntentFailed(/*sequenceId*/123)) - } - } - - @Test - fun testOnSystemServiceEvent() { - testAnyMethod { requestId: RequestId -> - iorapService.onSystemServiceEvent(requestId, - SystemServiceEvent(SystemServiceEvent.TYPE_START)) - } - } - - @Test - fun testOnSystemServiceUserEvent() { - testAnyMethod { requestId: RequestId -> - iorapService.onSystemServiceUserEvent(requestId, - SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 0)) - } - } -} diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt deleted file mode 100644 index 150577a21f5a..000000000000 --- a/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2018 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.google.android.startop.iorap - -import android.net.Uri -import android.os.Parcel -import android.os.Parcelable -import androidx.test.filters.SmallTest -import org.junit.Test -import org.junit.runner.RunWith -import com.google.common.truth.Truth.assertThat -import org.junit.runners.Parameterized - -/** - * Basic unit tests to ensure that all of the [Parcelable]s in [com.google.android.startop.iorap] - * have a valid-conforming interface implementation. - */ -@SmallTest -@RunWith(Parameterized::class) -class ParcelablesTest<T : Parcelable>(private val inputData: InputData<T>) { - companion object { - private val initialRequestId = RequestId.nextValueForSequence()!! - - @JvmStatic - @Parameterized.Parameters - fun data() = listOf( - InputData( - newActivityInfo(), - newActivityInfo(), - ActivityInfo("some package", "some other activity")), - InputData( - ActivityHintEvent(ActivityHintEvent.TYPE_COMPLETED, newActivityInfo()), - ActivityHintEvent(ActivityHintEvent.TYPE_COMPLETED, newActivityInfo()), - ActivityHintEvent(ActivityHintEvent.TYPE_POST_COMPLETED, - newActivityInfo())), - InputData( - AppIntentEvent.createDefaultIntentChanged(newActivityInfo(), - newActivityInfoOther()), - AppIntentEvent.createDefaultIntentChanged(newActivityInfo(), - newActivityInfoOther()), - AppIntentEvent.createDefaultIntentChanged(newActivityInfoOther(), - newActivityInfo())), - InputData( - PackageEvent.createReplaced(newUri(), "some package"), - PackageEvent.createReplaced(newUri(), "some package"), - PackageEvent.createReplaced(newUri(), "some other package") - ), - InputData(initialRequestId, cloneRequestId(initialRequestId), - RequestId.nextValueForSequence()), - InputData( - SystemServiceEvent(SystemServiceEvent.TYPE_BOOT_PHASE), - SystemServiceEvent(SystemServiceEvent.TYPE_BOOT_PHASE), - SystemServiceEvent(SystemServiceEvent.TYPE_START)), - InputData( - SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 12345), - SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 12345), - SystemServiceUserEvent(SystemServiceUserEvent.TYPE_CLEANUP_USER, 12345)), - InputData( - TaskResult(TaskResult.STATE_COMPLETED), - TaskResult(TaskResult.STATE_COMPLETED), - TaskResult(TaskResult.STATE_ONGOING)) - ) - - private fun newActivityInfo(): ActivityInfo { - return ActivityInfo("some package", "some activity") - } - - private fun newActivityInfoOther(): ActivityInfo { - return ActivityInfo("some package 2", "some activity 2") - } - - private fun newUri(): Uri { - return Uri.parse("https://www.google.com") - } - - private fun cloneRequestId(requestId: RequestId): RequestId { - val constructor = requestId::class.java.declaredConstructors[0] - constructor.isAccessible = true - return constructor.newInstance(requestId.requestId) as RequestId - } - } - - /** - * Test for [Object.equals] implementation. - */ - @Test - fun testEquality() { - assertThat(inputData.valid).isEqualTo(inputData.valid) - assertThat(inputData.valid).isEqualTo(inputData.validCopy) - assertThat(inputData.valid).isNotEqualTo(inputData.validOther) - } - - /** - * Test for [Parcelable] implementation. - */ - @Test - fun testParcelRoundTrip() { - // calling writeToParcel and then T::CREATOR.createFromParcel would return the same data. - val assertParcels = { it: T, data: InputData<T> -> - val parcel = Parcel.obtain() - it.writeToParcel(parcel, 0) - parcel.setDataPosition(0) // future reads will see all previous writes. - assertThat(it).isEqualTo(data.createFromParcel(parcel)) - parcel.recycle() - } - - assertParcels(inputData.valid, inputData) - assertParcels(inputData.validCopy, inputData) - assertParcels(inputData.validOther, inputData) - } - - data class InputData<T : Parcelable>(val valid: T, val validCopy: T, val validOther: T) { - val kls = valid.javaClass - init { - assertThat(valid).isNotSameInstanceAs(validCopy) - // Don't use isInstanceOf because of phantom warnings in intellij about Class! - assertThat(validCopy.javaClass).isEqualTo(valid.javaClass) - assertThat(validOther.javaClass).isEqualTo(valid.javaClass) - } - - fun createFromParcel(parcel: Parcel): T { - val field = kls.getDeclaredField("CREATOR") - val creator = field.get(null) as Parcelable.Creator<T> - - return creator.createFromParcel(parcel) - } - } -} diff --git a/startop/scripts/app_startup/analyze_metrics.py b/startop/scripts/app_startup/analyze_metrics.py deleted file mode 100755 index d74d6f68d823..000000000000 --- a/startop/scripts/app_startup/analyze_metrics.py +++ /dev/null @@ -1,457 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018, 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. - -""" -Perform statistical analysis on measurements produced by app_startup_runner.py - -Install: -$> sudo apt-get install python3-scipy - -Usage: -$> ./analyze_metrics.py <filename.csv> [<filename2.csv> ...] -$> ./analyze_metrics.py --help -""" - -import argparse -import csv -import itertools -import os -import subprocess -import sys -import tempfile -from typing import Any, List, Dict, Iterable, TextIO, Tuple - -from scipy import stats as sc -import numpy as np - - -# These CSV columns are considered labels. Everything after them in the same row are metrics. -_LABEL_COLUMNS=['packages', 'readaheads', 'compiler_filters'] -# The metric series with the 'cold' readahead is the baseline. -# All others (warm, jit, etc) are the potential improvements. - -#fixme: this should probably be an option -_BASELINE=('readaheads', 'cold') -# ignore this for some statistic calculations -_IGNORE_PAIR=('readaheads', 'warm') -_PLOT_SUBKEY='readaheads' -_PLOT_GROUPKEY='packages' -_PLOT_DATA_INDEX = 0 -_DELTA=50 -_DELTA2=100 -_PVALUE_THRESHOLD=0.10 -_debug = False # See -d/--debug flag. - -def parse_options(argv: List[str] = None): - """Parse command line arguments and return an argparse Namespace object.""" - parser = argparse.ArgumentParser(description="Perform statistical analysis on measurements produced by app_start_runner.py.") - parser.add_argument('input_files', metavar='file.csv', nargs='+', help='CSV file produced by app_startup_runner.py') - - parser.add_argument('-d', '--debug', dest='debug', action='store_true', help='Add extra debugging output') - parser.add_argument('-os', '--output-samples', dest='output_samples', default='/dev/null', action='store', help='Store CSV for per-sample data') - parser.add_argument('-oc', '--output-comparable', dest='output_comparable', default='/dev/null', action='store', help='Output CSV for comparable against baseline') - parser.add_argument('-ocs', '--output-comparable-significant', dest='output_comparable_significant', default='/dev/null', action='store', help='Output CSV for comparable against baseline (significant only)') - parser.add_argument('-pt', '--pvalue-threshold', dest='pvalue_threshold', type=float, default=_PVALUE_THRESHOLD, action='store') - parser.add_argument('-dt', '--delta-threshold', dest='delta_threshold', type=int, default=_DELTA, action='store') - - return parser.parse_args(argv) - -def _debug_print(*args, **kwargs): - """Print the args to sys.stderr if the --debug/-d flag was passed in.""" - global _debug - if _debug: - print(*args, **kwargs, file=sys.stderr) - -def _expand_gen_repr(args): - new_args_list = [] - for i in args: - # detect iterable objects that do not have their own override of __str__ - if hasattr(i, '__iter__'): - to_str = getattr(i, '__str__') - if to_str.__objclass__ == object: - # the repr for a generator is just type+address, expand it out instead. - new_args_list.append([_expand_gen_repr([j])[0] for j in i]) - continue - # normal case: uses the built-in to-string - new_args_list.append(i) - return new_args_list - -def _debug_print_gen(*args, **kwargs): - """Like _debug_print but will turn any iterable args into a list.""" - if not _debug: - return - - new_args_list = _expand_gen_repr(args) - _debug_print(*new_args_list, **kwargs) - -def read_headers(input_file: TextIO) -> Tuple[List[str], List[str]]: - _debug_print("read_headers for file: ", input_file.name) - csv_reader = csv.reader(input_file) - - label_num_columns = len(_LABEL_COLUMNS) - - try: - header = next(csv_reader) - except StopIteration: - header = None - _debug_print('header', header) - - if not header: - return (None, None) - - labels = header[0:label_num_columns] - data = header[label_num_columns:] - - return (labels, data) - -def read_labels_and_data(input_file: TextIO) -> Iterable[Tuple[List[str], List[int]]]: - _debug_print("print_analysis for file: ", input_file.name) - csv_reader = csv.reader(input_file) - - # Skip the header because it doesn't contain any data. - # To get the header see read_headers function. - try: - header = next(csv_reader) - except StopIteration: - header = None - - label_num_columns = len(_LABEL_COLUMNS) - - for row in csv_reader: - if len(row) > 0 and row[0][0] == ';': - _debug_print("skip comment line", row) - continue - - labels = row[0:label_num_columns] - data = [int(i) for i in row[label_num_columns:]] - -# _debug_print("labels:", labels) -# _debug_print("data:", data) - - yield (labels, data) - -def group_metrics_by_label(it: Iterable[Tuple[List[str], List[int]]]): - prev_labels = None - data_2d = [] - - for label_list, data_list in it: - if prev_labels != label_list: - if prev_labels: -# _debug_print("grouped labels:", prev_labels, "data_2d:", data_2d) - yield (prev_labels, data_2d) - data_2d = [] - - data_2d.append(data_list) - prev_labels = label_list - - if prev_labels: -# _debug_print("grouped labels:", prev_labels, "data_2d:", data_2d) - yield (prev_labels, data_2d) - -def data_to_numpy(it: Iterable[Tuple[List[str], List[List[int]]]]) -> Iterable[Tuple[List[str], Any]]: - for label_list, data_2d in it: - yield (label_list, np.asarray(data_2d, dtype=int)) - -def iterate_columns(np_data_2d): - for col in range(np_data_2d.shape[1]): - col_as_array = np_data_2d[:, col] - yield col_as_array - -def confidence_interval(np_data_2d, percent=0.95): - """ - Given some data [[a,b,c],[d,e,f,]...] - - We assume the same metric is in the column (e.g. [a,d]) - and that data in the rows (e.g. [b,e]) are separate metric values. - - We then calculate the CI for each metric individually returning it as a list of tuples. - """ - arr = [] - for col_2d in iterate_columns(np_data_2d): - mean = col_2d.mean() - sigma = col_2d.std() - - ci = sc.norm.interval(percent, loc=mean, scale=sigma / np.sqrt(len(col_2d))) - arr.append(ci) - - # TODO: This seems to be returning NaN when all the samples have the same exact value - # (e.g. stddev=0, which can trivially happen when sample count = 1). - - return arr - -def print_analysis(it, label_header: List[str], data_header: List[str], output_samples: str): - print(label_header) - - with open(output_samples, "w") as output_file: - - csv_writer = csv.writer(output_file) - csv_writer.writerow(label_header + ['mean', 'std', 'confidence_interval_a', 'confidence_interval_b']) - - for label_list, np_data_2d in it: - print("**********************") - print(label_list) - print() - print(" ", data_header) - # aggregate computation column-wise - print("Mean: ", np_data_2d.mean(axis=0)) - print("Std: ", np_data_2d.std(axis=0)) - print("CI95%:", confidence_interval(np_data_2d)) - print("SEM: ", stats_standard_error_one(np_data_2d, axis=0)) - - #ci = confidence_interval(np_data_2d)[_PLOT_DATA_INDEX] - sem = stats_standard_error_one(np_data_2d, axis=0)[_PLOT_DATA_INDEX] - mean = np_data_2d.mean(axis=0)[_PLOT_DATA_INDEX] - - ci = (mean - sem, mean + sem) - - csv_writer.writerow(label_list + [mean, np_data_2d.std(axis=0)[_PLOT_DATA_INDEX], ci[0], ci[1]]) - -def from_file_group_by_labels(input_file): - (label_header, data_header) = read_headers(input_file) - label_data_iter = read_labels_and_data(input_file) - grouped_iter = group_metrics_by_label(label_data_iter) - grouped_numpy_iter = data_to_numpy(grouped_iter) - - return grouped_numpy_iter, label_header, data_header - -def list_without_index(list, index): - return list[:index] + list[index+1:] - -def group_by_without_baseline_key(grouped_numpy_iter, label_header): - """ - Data is considered comparable if the only difference is the baseline key - (i.e. the readahead is different but the package, compilation filter, etc, are the same). - - Returns iterator that's grouped by the non-baseline labels to an iterator of - (label_list, data_2d). - """ - baseline_index = label_header.index(_BASELINE[0]) - - def get_label_without_baseline(tpl): - label_list, _ = tpl - return list_without_index(label_list, baseline_index) - # [['pkgname', 'compfilter', 'warm'], [data]] - # [['pkgname', 'compfilter', 'cold'], [data2]] - # [['pkgname2', 'compfilter', 'warm'], [data3]] - # - # -> - # ( [['pkgname', 'compfilter', 'warm'], [data]] # ignore baseline label change. - # [['pkgname', 'compfilter', 'cold'], [data2]] ), # split here because the pkgname changed. - # ( [['pkgname2', 'compfilter', 'warm'], [data3]] ) - for group_info, it in itertools.groupby(grouped_numpy_iter, key = get_label_without_baseline): - yield it - - # TODO: replace this messy manual iteration/grouping with pandas - -def iterate_comparable_metrics(without_baseline_iter, label_header): - baseline_index = label_header.index(_BASELINE[0]) - baseline_value = _BASELINE[1] - - _debug_print("iterate comparables") - - def is_baseline_fun(tp): - ll, dat = tp - return ll[baseline_index] == baseline_value - - # iterating here when everything but the baseline key is the same. - for it in without_baseline_iter: - it1, it2 = itertools.tee(it) - - # find all the baseline data. - baseline_filter_it = filter(is_baseline_fun, it1) - - # find non-baseline data. - nonbaseline_filter_it = itertools.filterfalse(is_baseline_fun, it2) - - yield itertools.product(baseline_filter_it, nonbaseline_filter_it) - -def stats_standard_error_one(a, axis): - a_std = a.std(axis=axis, ddof=0) - a_len = a.shape[axis] - - return a_std / np.sqrt(a_len) - -def stats_standard_error(a, b, axis): - a_std = a.std(axis=axis, ddof=0) - b_std = b.std(axis=axis, ddof=0) - - a_len = a.shape[axis] - b_len = b.shape[axis] - - temp1 = a_std*a_std/a_len - temp2 = b_std*b_std/b_len - - return np.sqrt(temp1 + temp2) - -def stats_tvalue(a, b, axis, delta = 0): - a_mean = a.mean(axis=axis) - b_mean = b.mean(axis=axis) - - return (a_mean - b_mean - delta) / stats_standard_error(a, b, axis) - -def stats_pvalue(a, b, axis, delta, left:bool = False): - """ - Single-tailed 2-sample t-test. - - Returns p-value for the null hypothesis: mean(a) - mean(b) >= delta. - :param a: numpy 2d array - :param b: numpy 2d array - :param axis: which axis to do the calculations across - :param delta: test value of mean differences - :param left: if true then use <= delta instead of >= delta - :return: p-value - """ - # implement our own pvalue calculation because the built-in t-test (t,p values) - # only offer delta=0 , e.g. m1-m1 ? 0 - # we are however interested in m1-m2 ? delta - t_value = stats_tvalue(a, b, axis, delta) - - # 2-sample degrees of freedom is using the array sizes - 2. - dof = a.shape[axis] + b.shape[axis] - 2 - - if left: - # left tailed test. e.g. m1-m2 <= delta - return sc.t.cdf(t_value, dof) - else: - # right tailed test. e.g. m1-m2 >= delta - return sc.t.sf(t_value, dof) - # a left+right tailed test is a 2-tail t-test and can be done using ttest_ind for delta=0 - -def print_comparable_analysis(comparable_metrics_iter, label_header, data_header, output_comparable: str, output_comparable_significant: str): - baseline_value = _BASELINE[1] - baseline_index = label_header.index(_BASELINE[0]) - - old_baseline_label_list = None - delta = _DELTA - filter_value = _IGNORE_PAIR[1] - filter_index = label_header.index(_IGNORE_PAIR[0]) - - pvalue_threshold = _PVALUE_THRESHOLD - ci_threshold = (1 - _PVALUE_THRESHOLD) * 100.0 - - with open(output_comparable, "w") as output_file: - - csv_writer = csv.writer(output_file) - csv_writer.writerow(label_header + ['mean', 'mean_diff', 'sem', 'pvalue_2tailed', 'pvalue_gt%d' %(_DELTA), 'pvalue_gt%d' %(_DELTA2)]) - - print("------------------------------------------------------------------") - print("Comparison against the baseline %s = %s" %(_BASELINE, baseline_value)) - print("--- Right-tailed t-test checks if the baseline >= current %s by at least %d" %(_BASELINE[0], delta)) - print() - - global_stats = {'better_than_delta': [], 'better_than_delta_p95': []} - - for nested_it in comparable_metrics_iter: - print("************************") - - better_than_delta = [] - better_than_delta_p95 = [] - - saw_baseline_once = False - - for ((baseline_label_list, baseline_np_data_2d), (rest_label_list, rest_np_data_2d)) in nested_it: - _debug_print("baseline_label_list:", baseline_label_list) - _debug_print("baseline_np_data_2d:", baseline_np_data_2d) - _debug_print("rest_label_list:", rest_label_list) - _debug_print("rest_np_data_2d:", rest_np_data_2d) - - mean_diff = baseline_np_data_2d.mean(axis=0) - rest_np_data_2d.mean(axis=0) - # 2-sample 2-tailed t-test with delta=0 - # e.g. "Is it true that usually the two sample means are different?" - t_statistic, t_pvalue = sc.ttest_ind(baseline_np_data_2d, rest_np_data_2d, axis=0) - - # 2-sample 1-tailed t-test with delta=50 - # e.g. "Is it true that usually the sample means better than 50ms?" - t2 = stats_tvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=delta) - p2 = stats_pvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=delta) - - t2_b = stats_tvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=_DELTA2) - p2_b = stats_pvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=_DELTA2) - - print("%s vs %s" %(rest_label_list, baseline_value)) - print(" ", data_header) - print("Mean Difference: ", mean_diff) - print("T-test (2-tailed) != 0: t=%s, p=%s" %(t_statistic, t_pvalue)) - print("T-test (right-tailed) >= %d: t=%s, p=%s" %(_DELTA, t2, p2)) - print("T-test (right-tailed) >= %d: t=%s, p=%s" %(_DELTA2, t2_b, p2_b)) - - def write_out_values(label_list, *args): - csv_writer.writerow(label_list + [i[_PLOT_DATA_INDEX] for i in args]) - - sem = stats_standard_error(baseline_np_data_2d, rest_np_data_2d, axis=0) - if saw_baseline_once == False: - saw_baseline_once = True - base_sem = stats_standard_error_one(baseline_np_data_2d, axis=0) - write_out_values(baseline_label_list, baseline_np_data_2d.mean(axis=0), [0], base_sem, [None], [None], [None]) - write_out_values(rest_label_list, rest_np_data_2d.mean(axis=0), mean_diff, sem, t_pvalue, p2, p2_b) - - # now do the global statistics aggregation - - if rest_label_list[filter_index] == filter_value: - continue - - if mean_diff > delta: - better_than_delta.append((mean_diff, p2, rest_label_list)) - - if p2 <= pvalue_threshold: - better_than_delta_p95.append((mean_diff, rest_label_list)) - - if better_than_delta: - global_stats['better_than_delta'].append(better_than_delta) - if better_than_delta_p95: - global_stats['better_than_delta_p95'].append(better_than_delta_p95) - - print("------------------------") - print("Global statistics:") - print("//// Rows with %s=%s are ignored here." %_IGNORE_PAIR) - print("- # of results with mean diff better than delta(%d) = %d" %(delta, len(global_stats['better_than_delta']))) - print(" > (meandiff, pvalue, labels)") - for i in global_stats['better_than_delta']: - print(" > %s" %i) - print("- # of results with mean diff better than delta(%d) CI%d%% = %d" %(delta, ci_threshold, len(global_stats['better_than_delta_p95']))) - print(" > (meandiff, labels)") - for i in global_stats['better_than_delta_p95']: - print(" > %s" %i) - -def main(): - global _debug - global _DELTA - global _PVALUE_THRESHOLD - - opts = parse_options() - _debug = opts.debug - _debug_print("parsed options: ", opts) - - _PVALUE_THRESHOLD = opts.pvalue_threshold or _PVALUE_THRESHOLD - - for file_name in opts.input_files: - with open(file_name, 'r') as input_file: - (grouped_numpy_iter, label_header, data_header) = from_file_group_by_labels(input_file) - print_analysis(grouped_numpy_iter, label_header, data_header, opts.output_samples) - - with open(file_name, 'r') as input_file: - (grouped_numpy_iter, label_header, data_header) = from_file_group_by_labels(input_file) - without_baseline_iter = group_by_without_baseline_key(grouped_numpy_iter, label_header) - #_debug_print_gen(without_baseline_iter) - - comparable_metrics_iter = iterate_comparable_metrics(without_baseline_iter, label_header) - print_comparable_analysis(comparable_metrics_iter, label_header, data_header, opts.output_comparable, opts.output_comparable_significant) - - return 0 - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/startop/scripts/app_startup/app_startup_runner.py b/startop/scripts/app_startup/app_startup_runner.py deleted file mode 100755 index 25ee6f7368c8..000000000000 --- a/startop/scripts/app_startup/app_startup_runner.py +++ /dev/null @@ -1,393 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018, 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. - -# -# -# Measure application start-up time by launching applications under various combinations. -# See --help for more details. -# -# -# Sample usage: -# $> ./app_startup_runner.py -p com.google.android.calculator -r warm -r cold -lc 10 -o out.csv -# $> ./analyze_metrics.py out.csv -# -# - -import argparse -import csv -import itertools -import os -import sys -import tempfile -from datetime import timedelta -from typing import Any, Callable, Iterable, List, NamedTuple, TextIO, Tuple, \ - TypeVar, Union, Optional - -# local import -DIR = os.path.abspath(os.path.dirname(__file__)) -sys.path.append(os.path.dirname(DIR)) -import lib.cmd_utils as cmd_utils -import lib.print_utils as print_utils -from app_startup.run_app_with_prefetch import PrefetchAppRunner -import app_startup.lib.args_utils as args_utils -from app_startup.lib.data_frame import DataFrame -from app_startup.lib.perfetto_trace_collector import PerfettoTraceCollector -from iorap.compiler import CompilerType -import iorap.compiler as compiler - -# The following command line options participate in the combinatorial generation. -# All other arguments have a global effect. -_COMBINATORIAL_OPTIONS = ['package', 'readahead', 'compiler_filter', - 'activity', 'trace_duration'] -_TRACING_READAHEADS = ['mlock', 'fadvise'] -_FORWARD_OPTIONS = {'loop_count': '--count'} -_RUN_SCRIPT = os.path.join(os.path.dirname(os.path.realpath(__file__)), - 'run_app_with_prefetch.py') - -CollectorPackageInfo = NamedTuple('CollectorPackageInfo', - [('package', str), ('compiler_filter', str)]) -# by 2; systrace starts up slowly. - -_UNLOCK_SCREEN_SCRIPT = os.path.join( - os.path.dirname(os.path.realpath(__file__)), 'unlock_screen') - -RunCommandArgs = NamedTuple('RunCommandArgs', - [('package', str), - ('readahead', str), - ('activity', Optional[str]), - ('compiler_filter', Optional[str]), - ('timeout', Optional[int]), - ('debug', bool), - ('simulate', bool), - ('input', Optional[str]), - ('trace_duration', Optional[timedelta])]) - -# This must be the only mutable global variable. All other global variables are constants to avoid magic literals. -_debug = False # See -d/--debug flag. -_DEBUG_FORCE = None # Ignore -d/--debug if this is not none. -_PERFETTO_TRACE_DURATION_MS = 5000 # milliseconds -_PERFETTO_TRACE_DURATION = timedelta(milliseconds=_PERFETTO_TRACE_DURATION_MS) - -# Type hinting names. -T = TypeVar('T') -NamedTupleMeta = Callable[ - ..., T] # approximation of a (S : NamedTuple<T> where S() == T) metatype. - -def parse_options(argv: List[str] = None): - """Parse command line arguments and return an argparse Namespace object.""" - parser = argparse.ArgumentParser(description="Run one or more Android " - "applications under various " - "settings in order to measure " - "startup time.") - # argparse considers args starting with - and -- optional in --help, even though required=True. - # by using a named argument group --help will clearly say that it's required instead of optional. - required_named = parser.add_argument_group('required named arguments') - required_named.add_argument('-p', '--package', action='append', - dest='packages', - help='package of the application', required=True) - required_named.add_argument('-r', '--readahead', action='append', - dest='readaheads', - help='which readahead mode to use', - choices=('warm', 'cold', 'mlock', 'fadvise'), - required=True) - - # optional arguments - # use a group here to get the required arguments to appear 'above' the optional arguments in help. - optional_named = parser.add_argument_group('optional named arguments') - optional_named.add_argument('-c', '--compiler-filter', action='append', - dest='compiler_filters', - help='which compiler filter to use. if omitted it does not enforce the app\'s compiler filter', - choices=('speed', 'speed-profile', 'quicken')) - optional_named.add_argument('-s', '--simulate', dest='simulate', - action='store_true', - help='Print which commands will run, but don\'t run the apps') - optional_named.add_argument('-d', '--debug', dest='debug', - action='store_true', - help='Add extra debugging output') - optional_named.add_argument('-o', '--output', dest='output', action='store', - help='Write CSV output to file.') - optional_named.add_argument('-t', '--timeout', dest='timeout', action='store', - type=int, default=10, - help='Timeout after this many seconds when executing a single run.') - optional_named.add_argument('-lc', '--loop-count', dest='loop_count', - default=1, type=int, action='store', - help='How many times to loop a single run.') - optional_named.add_argument('-in', '--inodes', dest='inodes', type=str, - action='store', - help='Path to inodes file (system/extras/pagecache/pagecache.py -d inodes)') - optional_named.add_argument('--compiler-trace-duration-ms', - dest='trace_duration', - type=lambda ms_str: timedelta(milliseconds=int(ms_str)), - action='append', - help='The trace duration (milliseconds) in ' - 'compilation') - optional_named.add_argument('--compiler-type', dest='compiler_type', - type=CompilerType, choices=list(CompilerType), - default=CompilerType.DEVICE, - help='The type of compiler.') - - return parser.parse_args(argv) - -def key_to_cmdline_flag(key: str) -> str: - """Convert key into a command line flag, e.g. 'foo-bars' -> '--foo-bar' """ - if key.endswith("s"): - key = key[:-1] - return "--" + key.replace("_", "-") - -def as_run_command(tpl: NamedTuple) -> List[Union[str, Any]]: - """ - Convert a named tuple into a command-line compatible arguments list. - - Example: ABC(1, 2, 3) -> ['--a', 1, '--b', 2, '--c', 3] - """ - args = [] - for key, value in tpl._asdict().items(): - if value is None: - continue - args.append(key_to_cmdline_flag(key)) - args.append(value) - return args - -def run_perfetto_collector(collector_info: CollectorPackageInfo, - timeout: int, - simulate: bool) -> Tuple[bool, TextIO]: - """Run collector to collect prefetching trace. - - Returns: - A tuple of whether the collection succeeds and the generated trace file. - """ - tmp_output_file = tempfile.NamedTemporaryFile() - - collector = PerfettoTraceCollector(package=collector_info.package, - activity=None, - compiler_filter=collector_info.compiler_filter, - timeout=timeout, - simulate=simulate, - trace_duration=_PERFETTO_TRACE_DURATION, - save_destination_file_path=tmp_output_file.name) - result = collector.run() - - return result is not None, tmp_output_file - -def parse_run_script_csv_file(csv_file: TextIO) -> DataFrame: - """Parse a CSV file full of integers into a DataFrame.""" - csv_reader = csv.reader(csv_file) - - try: - header_list = next(csv_reader) - except StopIteration: - header_list = [] - - if not header_list: - return None - - headers = [i for i in header_list] - - d = {} - for row in csv_reader: - header_idx = 0 - - for i in row: - v = i - if i: - v = int(i) - - header_key = headers[header_idx] - l = d.get(header_key, []) - l.append(v) - d[header_key] = l - - header_idx = header_idx + 1 - - return DataFrame(d) - -def build_ri_compiler_argv(inodes_path: str, - perfetto_trace_file: str, - trace_duration: Optional[timedelta] - ) -> str: - argv = ['-i', inodes_path, '--perfetto-trace', - perfetto_trace_file] - - if trace_duration is not None: - argv += ['--duration', str(int(trace_duration.total_seconds() - * PerfettoTraceCollector.MS_PER_SEC))] - - print_utils.debug_print(argv) - return argv - -def execute_run_using_perfetto_trace(collector_info, - run_combos: Iterable[RunCommandArgs], - simulate: bool, - inodes_path: str, - timeout: int, - compiler_type: CompilerType, - requires_trace_collection: bool) -> DataFrame: - """ Executes run based on perfetto trace. """ - if requires_trace_collection: - passed, perfetto_trace_file = run_perfetto_collector(collector_info, - timeout, - simulate) - if not passed: - raise RuntimeError('Cannot run perfetto collector!') - else: - perfetto_trace_file = tempfile.NamedTemporaryFile() - - with perfetto_trace_file: - for combos in run_combos: - if combos.readahead in _TRACING_READAHEADS: - if simulate: - compiler_trace_file = tempfile.NamedTemporaryFile() - else: - ri_compiler_argv = build_ri_compiler_argv(inodes_path, - perfetto_trace_file.name, - combos.trace_duration) - compiler_trace_file = compiler.compile(compiler_type, - inodes_path, - ri_compiler_argv, - combos.package, - combos.activity) - - with compiler_trace_file: - combos = combos._replace(input=compiler_trace_file.name) - print_utils.debug_print(combos) - output = PrefetchAppRunner(**combos._asdict()).run() - else: - print_utils.debug_print(combos) - output = PrefetchAppRunner(**combos._asdict()).run() - - yield DataFrame(dict((x, [y]) for x, y in output)) if output else None - -def execute_run_combos( - grouped_run_combos: Iterable[Tuple[CollectorPackageInfo, Iterable[RunCommandArgs]]], - simulate: bool, - inodes_path: str, - timeout: int, - compiler_type: CompilerType, - requires_trace_collection: bool): - # nothing will work if the screen isn't unlocked first. - cmd_utils.execute_arbitrary_command([_UNLOCK_SCREEN_SCRIPT], - timeout, - simulate=simulate, - shell=False) - - for collector_info, run_combos in grouped_run_combos: - yield from execute_run_using_perfetto_trace(collector_info, - run_combos, - simulate, - inodes_path, - timeout, - compiler_type, - requires_trace_collection) - -def gather_results(commands: Iterable[Tuple[DataFrame]], - key_list: List[str], value_list: List[Tuple[str, ...]]): - print_utils.debug_print("gather_results: key_list = ", key_list) - stringify_none = lambda s: s is None and "<none>" or s - # yield key_list + ["time(ms)"] - for (run_result_list, values) in itertools.zip_longest(commands, value_list): - print_utils.debug_print("run_result_list = ", run_result_list) - print_utils.debug_print("values = ", values) - - if not run_result_list: - continue - - # RunCommandArgs(package='com.whatever', readahead='warm', compiler_filter=None) - # -> {'package':['com.whatever'], 'readahead':['warm'], 'compiler_filter':[None]} - values_dict = {} - for k, v in values._asdict().items(): - if not k in key_list: - continue - values_dict[k] = [stringify_none(v)] - - values_df = DataFrame(values_dict) - # project 'values_df' to be same number of rows as run_result_list. - values_df = values_df.repeat(run_result_list.data_row_len) - - # the results are added as right-hand-side columns onto the existing labels for the table. - values_df.merge_data_columns(run_result_list) - - yield values_df - -def eval_and_save_to_csv(output, annotated_result_values): - printed_header = False - - csv_writer = csv.writer(output) - for row in annotated_result_values: - if not printed_header: - headers = row.headers - csv_writer.writerow(headers) - printed_header = True - # TODO: what about when headers change? - - for data_row in row.data_table: - data_row = [d for d in data_row] - csv_writer.writerow(data_row) - - output.flush() # see the output live. - -def coerce_to_list(opts: dict): - """Tranform values of the dictionary to list. - For example: - 1 -> [1], None -> [None], [1,2,3] -> [1,2,3] - [[1],[2]] -> [[1],[2]], {1:1, 2:2} -> [{1:1, 2:2}] - """ - result = {} - for key in opts: - val = opts[key] - result[key] = val if issubclass(type(val), list) else [val] - return result - -def main(): - global _debug - - opts = parse_options() - _debug = opts.debug - if _DEBUG_FORCE is not None: - _debug = _DEBUG_FORCE - - print_utils.DEBUG = _debug - cmd_utils.SIMULATE = opts.simulate - - print_utils.debug_print("parsed options: ", opts) - - output_file = opts.output and open(opts.output, 'w') or sys.stdout - - combos = lambda: args_utils.generate_run_combinations( - RunCommandArgs, - coerce_to_list(vars(opts)), - opts.loop_count) - print_utils.debug_print_gen("run combinations: ", combos()) - - grouped_combos = lambda: args_utils.generate_group_run_combinations(combos(), - CollectorPackageInfo) - - print_utils.debug_print_gen("grouped run combinations: ", grouped_combos()) - requires_trace_collection = any(i in _TRACING_READAHEADS for i in opts.readaheads) - exec = execute_run_combos(grouped_combos(), - opts.simulate, - opts.inodes, - opts.timeout, - opts.compiler_type, - requires_trace_collection) - - results = gather_results(exec, _COMBINATORIAL_OPTIONS, combos()) - - eval_and_save_to_csv(output_file, results) - - return 1 - -if __name__ == '__main__': - sys.exit(main()) diff --git a/startop/scripts/app_startup/app_startup_runner_test.py b/startop/scripts/app_startup/app_startup_runner_test.py deleted file mode 100755 index 0c2bbea04f6a..000000000000 --- a/startop/scripts/app_startup/app_startup_runner_test.py +++ /dev/null @@ -1,176 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018, 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. -# - -""" -Unit tests for the app_startup_runner.py script. - -Install: - $> sudo apt-get install python3-pytest ## OR - $> pip install -U pytest -See also https://docs.pytest.org/en/latest/getting-started.html - -Usage: - $> ./app_startup_runner_test.py - $> pytest app_startup_runner_test.py - $> python -m pytest app_startup_runner_test.py - -See also https://docs.pytest.org/en/latest/usage.html -""" - -import io -import shlex -import sys -import typing -# global imports -from contextlib import contextmanager - -# local imports -import app_startup_runner as asr -# pip imports -import pytest - -# -# Argument Parsing Helpers -# - -@contextmanager -def ignore_stdout_stderr(): - """Ignore stdout/stderr output for duration of this context.""" - old_stdout = sys.stdout - old_stderr = sys.stderr - sys.stdout = io.StringIO() - sys.stderr = io.StringIO() - try: - yield - finally: - sys.stdout = old_stdout - sys.stderr = old_stderr - -@contextmanager -def argparse_bad_argument(msg): - """ - Assert that a SystemExit is raised when executing this context. - If the assertion fails, print the message 'msg'. - """ - with pytest.raises(SystemExit, message=msg): - with ignore_stdout_stderr(): - yield - -def assert_bad_argument(args, msg): - """ - Assert that the command line arguments in 'args' are malformed. - Prints 'msg' if the assertion fails. - """ - with argparse_bad_argument(msg): - parse_args(args) - -def parse_args(args): - """ - :param args: command-line like arguments as a single string - :return: dictionary of parsed key/values - """ - # "-a b -c d" => ['-a', 'b', '-c', 'd'] - return vars(asr.parse_options(shlex.split(args))) - -def default_dict_for_parsed_args(**kwargs): - """ - # Combine it with all of the "optional" parameters' default values. - """ - d = {'compiler_filters': None, 'simulate': False, 'debug': False, - 'output': None, 'timeout': 10, 'loop_count': 1, 'inodes': None, - 'trace_duration': None, 'compiler_type': asr.CompilerType.DEVICE} - d.update(kwargs) - return d - -def default_mock_dict_for_parsed_args(include_optional=True, **kwargs): - """ - Combine default dict with all optional parameters with some mock required parameters. - """ - d = {'packages': ['com.fake.package'], 'readaheads': ['warm']} - if include_optional: - d.update(default_dict_for_parsed_args()) - d.update(kwargs) - return d - -def parse_optional_args(str): - """ - Parse an argument string which already includes all the required arguments - in default_mock_dict_for_parsed_args. - """ - req = "--package com.fake.package --readahead warm" - return parse_args("%s %s" % (req, str)) - -def test_argparse(): - # missing arguments - assert_bad_argument("", "-p and -r are required") - assert_bad_argument("-r warm", "-p is required") - assert_bad_argument("--readahead warm", "-p is required") - assert_bad_argument("-p com.fake.package", "-r is required") - assert_bad_argument("--package com.fake.package", "-r is required") - - # required arguments are parsed correctly - ad = default_dict_for_parsed_args # assert dict - - assert parse_args("--package xyz --readahead warm") == ad(packages=['xyz'], - readaheads=['warm']) - assert parse_args("-p xyz -r warm") == ad(packages=['xyz'], - readaheads=['warm']) - - assert parse_args("-p xyz -r warm -s") == ad(packages=['xyz'], - readaheads=['warm'], - simulate=True) - assert parse_args("-p xyz -r warm --simulate") == ad(packages=['xyz'], - readaheads=['warm'], - simulate=True) - - # optional arguments are parsed correctly. - mad = default_mock_dict_for_parsed_args # mock assert dict - assert parse_optional_args("--output filename.csv") == mad( - output='filename.csv') - assert parse_optional_args("-o filename.csv") == mad(output='filename.csv') - - assert parse_optional_args("--timeout 123") == mad(timeout=123) - assert parse_optional_args("-t 456") == mad(timeout=456) - - assert parse_optional_args("--loop-count 123") == mad(loop_count=123) - assert parse_optional_args("-lc 456") == mad(loop_count=456) - - assert parse_optional_args("--inodes bar") == mad(inodes="bar") - assert parse_optional_args("-in baz") == mad(inodes="baz") - - - -def test_key_to_cmdline_flag(): - assert asr.key_to_cmdline_flag("abc") == "--abc" - assert asr.key_to_cmdline_flag("foos") == "--foo" - assert asr.key_to_cmdline_flag("ba_r") == "--ba-r" - assert asr.key_to_cmdline_flag("ba_zs") == "--ba-z" - -def test_parse_run_script_csv_file(): - # empty file -> empty list - f = io.StringIO("") - assert asr.parse_run_script_csv_file(f) == None - - # common case - f = io.StringIO("TotalTime_ms,Displayed_ms\n1,2") - df = asr.DataFrame({'TotalTime_ms': [1], 'Displayed_ms': [2]}) - - pf = asr.parse_run_script_csv_file(f) - assert pf == df - -if __name__ == '__main__': - pytest.main() diff --git a/startop/scripts/app_startup/force_compiler_filter b/startop/scripts/app_startup/force_compiler_filter deleted file mode 100755 index 08f983d92bea..000000000000 --- a/startop/scripts/app_startup/force_compiler_filter +++ /dev/null @@ -1,143 +0,0 @@ -#!/bin/bash -# -# Copyright 2018, 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. - -# -# Forces an application APK to be compiled (by ART's dex2oat) -# with a specific compiler filter. -# -# Example usage: -# $> ./force_compiler_filter -p com.google.android.apps.maps -c speed-profile -# -# (The application may be started/stopped as a side effect) -# - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -source "$DIR/lib/common" - -usage() { - cat <<EOF -Usage: $(basename $0) [OPTION]... - - Required: - -p, --package package of the app to recompile - -c, --compiler-filter override the compiler filter if set (default none) - valid options are listed by: adb shell cmd package, under compile -m - - Optional: - -a, --activity activity of the app to recompile - -h, --help usage information (this) - -v, --verbose enable extra verbose printing - -w, --wait_time how long to wait for app startup (default 10) in seconds -EOF -} - -wait_time="10" # seconds - -parse_arguments() { - while [[ $# -gt 0 ]]; do - case "$1" in - -a|--activity) - activity="$2" - shift - ;; - -h|--help) - usage - exit 0 - ;; - -p|--package) - package="$2" - shift - ;; - -w|--wait_time) - wait_time="$2" - shift - ;; - -c|--compiler-filter) - compiler_filter="$2" - shift - ;; - -v|--verbose) - verbose="y" - ;; - esac - shift - done - - if [[ -z "$compiler_filter" ]]; then - echo "Missing required --compiler-filter" >&2 - echo "" - usage - exit 1 - fi - if [[ -z "$package" ]]; then - echo "Missing required --package" >&2 - echo "" - usage - exit 1 - fi - - if [[ "$activity" == "" ]]; then - activity="$(get_activity_name "$package")" - if [[ "$activity" == "" ]]; then - echo "Activity name could not be found, invalid package name?" 1>&2 - exit 1 - else - verbose_print "Activity name inferred: " "$activity" - fi - fi -} - -force_package_compilation() { - local arg_compiler_filter="$1" - local arg_package="$2" - - if [[ $arg_compiler_filter == speed-profile ]]; then - # Force the running app to dump its profiles to disk. - remote_pkill "$arg_package" -SIGUSR1 - sleep 1 # give some time for above to complete. - fi - - adb shell cmd package compile -m "$arg_compiler_filter" -f "$arg_package" -} - -main() { - parse_arguments "$@" - - if [[ $compiler_filter == speed-profile ]]; then - # screen needs to be unlocked in order to run an app - "$DIR"/unlock_screen - - local output=$("$DIR"/launch_application "$package" "$activity") - if [[ $? -ne 0 ]]; then - echo "launching application failed" >&2 - exit 1 - fi - - verbose_print "$output" - # give some time for app startup to complete. - # this is supposed to be an upper bound for measuring startup time. - sleep "$wait_time" - fi - - force_package_compilation "$compiler_filter" "$package" - - # kill the application to ensure next time it's started, - # it picks up the correct compilation filter. - adb shell am force-stop "$package" - remote_pkill "$package" -} - -main "$@" diff --git a/startop/scripts/app_startup/launch_application b/startop/scripts/app_startup/launch_application deleted file mode 100755 index 6704a5a97aa0..000000000000 --- a/startop/scripts/app_startup/launch_application +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash -# -# Copyright 2018, 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. - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -source "$DIR/lib/common" - -launch_application_usage() { - cat <<EOF -Usage: $(basename $0) <package> <activity> - - Positional Arguments: - <package> package of the app to test - <activity> activity to use - - Named Arguments: - -h, --help usage information (this) -EOF -} - -launch_application() { - local package="$1" - local activity="$2" - - # if there's any $s inside of the activity name, it needs to be escaped to \$. - # example '.app.honeycomb.Shell$HomeActivity' - # if the $ is not escaped, adb shell will try to evaluate $HomeActivity to a variable. - activity=${activity//\$/\\$} - - adb shell am start -S -W "$package"/"$activity" - - # pipe this into 'parse_metrics' to parse the output. -} - -if [[ $# -lt 2 ]]; then - launch_application_usage - exit 1 -fi - -launch_application "$@" diff --git a/startop/scripts/app_startup/lib/adb_utils.py b/startop/scripts/app_startup/lib/adb_utils.py deleted file mode 100644 index 3cebc9a97a50..000000000000 --- a/startop/scripts/app_startup/lib/adb_utils.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. - -"""Helper util libraries for calling adb command line.""" - -import datetime -import os -import re -import sys -import time -from typing import Optional - -sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname( - os.path.abspath(__file__))))) -import lib.cmd_utils as cmd_utils -import lib.logcat_utils as logcat_utils - - -def logcat_save_timestamp() -> str: - """Gets the current logcat timestamp. - - Returns: - A string of timestamp. - """ - _, output = cmd_utils.run_adb_shell_command( - "date -u +\'%Y-%m-%d %H:%M:%S.%N\'") - return output - -def vm_drop_cache(): - """Free pagecache and slab object.""" - cmd_utils.run_adb_shell_command('echo 3 > /proc/sys/vm/drop_caches') - # Sleep a little bit to provide enough time for cache cleanup. - time.sleep(1) - -def root(): - """Roots adb and successive adb commands will run under root.""" - cmd_utils.run_shell_command('adb root') - -def disable_selinux(): - """Disables selinux setting.""" - _, output = cmd_utils.run_adb_shell_command('getenforce') - if output == 'Permissive': - return - - print('Disable selinux permissions and restart framework.') - cmd_utils.run_adb_shell_command('setenforce 0') - cmd_utils.run_adb_shell_command('stop') - cmd_utils.run_adb_shell_command('start') - cmd_utils.run_shell_command('adb wait-for-device') - -def pkill(procname: str): - """Kills a process on device specified by the substring pattern in procname""" - _, pids = cmd_utils.run_shell_command('adb shell ps | grep "{}" | ' - 'awk \'{{print $2;}}\''. - format(procname)) - - for pid in pids.split('\n'): - pid = pid.strip() - if pid: - passed,_ = cmd_utils.run_adb_shell_command('kill {}'.format(pid)) - time.sleep(1) - -def parse_time_to_milliseconds(time: str) -> int: - """Parses the time string to milliseconds.""" - # Example: +1s56ms, +56ms - regex = r'\+((?P<second>\d+?)s)?(?P<millisecond>\d+?)ms' - result = re.search(regex, time) - second = 0 - if result.group('second'): - second = int(result.group('second')) - ms = int(result.group('millisecond')) - return second * 1000 + ms - -def blocking_wait_for_logcat_displayed_time(timestamp: datetime.datetime, - package: str, - timeout: int) -> Optional[int]: - """Parses the displayed time in the logcat. - - Returns: - the displayed time. - """ - pattern = re.compile('.*ActivityTaskManager: Displayed {}.*'.format(package)) - # 2019-07-02 22:28:34.469453349 -> 2019-07-02 22:28:34.469453 - timestamp = datetime.datetime.strptime(timestamp[:-3], - '%Y-%m-%d %H:%M:%S.%f') - timeout_dt = timestamp + datetime.timedelta(0, timeout) - # 2019-07-01 14:54:21.946 27365 27392 I ActivityTaskManager: - # Displayed com.android.settings/.Settings: +927ms - result = logcat_utils.blocking_wait_for_logcat_pattern(timestamp, - pattern, - timeout_dt) - if not result or not '+' in result: - return None - displayed_time = result[result.rfind('+'):] - - return parse_time_to_milliseconds(displayed_time) - -def delete_file_on_device(file_path: str) -> None: - """ Deletes a file on the device. """ - cmd_utils.run_adb_shell_command( - "[[ -f '{file_path}' ]] && rm -f '{file_path}' || " - "exit 0".format(file_path=file_path)) - -def set_prop(property: str, value: str) -> None: - """ Sets property using adb shell. """ - cmd_utils.run_adb_shell_command('setprop "{property}" "{value}"'.format( - property=property, value=value)) - -def pull_file(device_file_path: str, output_file_path: str) -> None: - """ Pulls file from device to output """ - cmd_utils.run_shell_command('adb pull "{device_file_path}" "{output_file_path}"'. - format(device_file_path=device_file_path, - output_file_path=output_file_path)) diff --git a/startop/scripts/app_startup/lib/adb_utils_test.py b/startop/scripts/app_startup/lib/adb_utils_test.py deleted file mode 100644 index e590fed568e3..000000000000 --- a/startop/scripts/app_startup/lib/adb_utils_test.py +++ /dev/null @@ -1,16 +0,0 @@ -import adb_utils - -# pip imports -import pytest - -def test_parse_time_to_milliseconds(): - # Act - result1 = adb_utils.parse_time_to_milliseconds('+1s7ms') - result2 = adb_utils.parse_time_to_milliseconds('+523ms') - - # Assert - assert result1 == 1007 - assert result2 == 523 - -if __name__ == '__main__': - pytest.main() diff --git a/startop/scripts/app_startup/lib/app_runner.py b/startop/scripts/app_startup/lib/app_runner.py deleted file mode 100644 index 78873fa51ab5..000000000000 --- a/startop/scripts/app_startup/lib/app_runner.py +++ /dev/null @@ -1,266 +0,0 @@ -# Copyright 2019, 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. - -"""Class to run an app.""" -import os -import sys -from typing import Optional, List, Tuple - -# local import -sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname( - os.path.abspath(__file__))))) - -import app_startup.lib.adb_utils as adb_utils -import lib.cmd_utils as cmd_utils -import lib.print_utils as print_utils - -class AppRunnerListener(object): - """Interface for lisenter of AppRunner. """ - - def preprocess(self) -> None: - """Preprocess callback to initialized before the app is running. """ - pass - - def postprocess(self, pre_launch_timestamp: str) -> None: - """Postprocess callback to cleanup after the app is running. - - param: - 'pre_launch_timestamp': indicates the timestamp when the app is - launching.. """ - pass - - def metrics_selector(self, am_start_output: str, - pre_launch_timestamp: str) -> None: - """A metrics selection callback that waits for the desired metrics to - show up in logcat. - params: - 'am_start_output': indicates the output of app startup. - 'pre_launch_timestamp': indicates the timestamp when the app is - launching. - returns: - a string in the format of "<metric>=<value>\n<metric>=<value>\n..." - for further parsing. For example "TotalTime=123\nDisplayedTime=121". - Return an empty string if no metrics need to be parsed further. - """ - pass - -class AppRunner(object): - """ Class to run an app. """ - # static variables - DIR = os.path.abspath(os.path.dirname(__file__)) - APP_STARTUP_DIR = os.path.dirname(DIR) - IORAP_COMMON_BASH_SCRIPT = os.path.realpath(os.path.join(DIR, - '../../iorap/common')) - DEFAULT_TIMEOUT = 30 # seconds - - def __init__(self, - package: str, - activity: Optional[str], - compiler_filter: Optional[str], - timeout: Optional[int], - simulate: bool): - self.package = package - self.simulate = simulate - - # If the argument activity is None, try to set it. - self.activity = activity - if self.simulate: - self.activity = 'act' - if self.activity is None: - self.activity = AppRunner.get_activity(self.package) - - self.compiler_filter = compiler_filter - self.timeout = timeout if timeout else AppRunner.DEFAULT_TIMEOUT - - self.listeners = [] - - def add_callbacks(self, listener: AppRunnerListener): - self.listeners.append(listener) - - def remove_callbacks(self, listener: AppRunnerListener): - self.listeners.remove(listener) - - @staticmethod - def get_activity(package: str) -> str: - """ Tries to set the activity based on the package. """ - passed, activity = cmd_utils.run_shell_func( - AppRunner.IORAP_COMMON_BASH_SCRIPT, - 'get_activity_name', - [package]) - - if not passed or not activity: - raise ValueError( - 'Activity name could not be found, invalid package name?!') - - return activity - - def configure_compiler_filter(self) -> bool: - """Configures compiler filter (e.g. speed). - - Returns: - A bool indicates whether configure of compiler filer succeeds or not. - """ - if not self.compiler_filter: - print_utils.debug_print('No --compiler-filter specified, don\'t' - ' need to force it.') - return True - - passed, current_compiler_filter_info = \ - cmd_utils.run_shell_command( - '{} --package {}'.format(os.path.join(AppRunner.APP_STARTUP_DIR, - 'query_compiler_filter.py'), - self.package)) - - if passed != 0: - return passed - - # TODO: call query_compiler_filter directly as a python function instead of - # these shell calls. - current_compiler_filter, current_reason, current_isa = \ - current_compiler_filter_info.split(' ') - print_utils.debug_print('Compiler Filter={} Reason={} Isa={}'.format( - current_compiler_filter, current_reason, current_isa)) - - # Don't trust reasons that aren't 'unknown' because that means - # we didn't manually force the compilation filter. - # (e.g. if any automatic system-triggered compilations are not unknown). - if current_reason != 'unknown' or \ - current_compiler_filter != self.compiler_filter: - passed, _ = adb_utils.run_shell_command('{}/force_compiler_filter ' - '--compiler-filter "{}" ' - '--package "{}"' - ' --activity "{}'. - format(AppRunner.APP_STARTUP_DIR, - self.compiler_filter, - self.package, - self.activity)) - else: - adb_utils.debug_print('Queried compiler-filter matched requested ' - 'compiler-filter, skip forcing.') - passed = False - return passed - - def run(self) -> Optional[List[Tuple[str]]]: - """Runs an app. - - Returns: - A list of (metric, value) tuples. - """ - print_utils.debug_print('==========================================') - print_utils.debug_print('===== START =====') - print_utils.debug_print('==========================================') - # Run the preprocess. - for listener in self.listeners: - listener.preprocess() - - # Ensure the APK is currently compiled with whatever we passed in - # via --compiler-filter. - # No-op if this option was not passed in. - if not self.configure_compiler_filter(): - print_utils.error_print('Compiler filter configuration failed!') - return None - - pre_launch_timestamp = adb_utils.logcat_save_timestamp() - # Launch the app. - results = self.launch_app(pre_launch_timestamp) - - # Run the postprocess. - for listener in self.listeners: - listener.postprocess(pre_launch_timestamp) - - return results - - def launch_app(self, pre_launch_timestamp: str) -> Optional[List[Tuple[str]]]: - """ Launches the app. - - Returns: - A list of (metric, value) tuples. - """ - print_utils.debug_print('Running with timeout {}'.format(self.timeout)) - - passed, am_start_output = cmd_utils.run_shell_command('timeout {timeout} ' - '"{DIR}/launch_application" ' - '"{package}" ' - '"{activity}"'. - format(timeout=self.timeout, - DIR=AppRunner.APP_STARTUP_DIR, - package=self.package, - activity=self.activity)) - if not passed and not self.simulate: - return None - - return self.wait_for_app_finish(pre_launch_timestamp, am_start_output) - - def wait_for_app_finish(self, - pre_launch_timestamp: str, - am_start_output: str) -> Optional[List[Tuple[str]]]: - """ Wait for app finish and all metrics are shown in logcat. - - Returns: - A list of (metric, value) tuples. - """ - if self.simulate: - return [('TotalTime', '123')] - - ret = [] - for listener in self.listeners: - output = listener.metrics_selector(am_start_output, - pre_launch_timestamp) - ret = ret + AppRunner.parse_metrics_output(output) - - return ret - - @staticmethod - def parse_metrics_output(input: str) -> List[ - Tuple[str, str, str]]: - """Parses output of app startup to metrics and corresponding values. - - It converts 'a=b\nc=d\ne=f\n...' into '[(a,b,''),(c,d,''),(e,f,'')]' - - Returns: - A list of tuples that including metric name, metric value and rest info. - """ - all_metrics = [] - for line in input.split('\n'): - if not line: - continue - splits = line.split('=') - if len(splits) < 2: - print_utils.error_print('Bad line "{}"'.format(line)) - continue - metric_name = splits[0] - metric_value = splits[1] - rest = splits[2] if len(splits) > 2 else '' - if rest: - print_utils.error_print('Corrupt line "{}"'.format(line)) - print_utils.debug_print('metric: "{metric_name}", ' - 'value: "{metric_value}" '. - format(metric_name=metric_name, - metric_value=metric_value)) - - all_metrics.append((metric_name, metric_value)) - return all_metrics - - @staticmethod - def parse_total_time( am_start_output: str) -> Optional[str]: - """Parses the total time from 'adb shell am start pkg' output. - - Returns: - the total time of app startup. - """ - for line in am_start_output.split('\n'): - if 'TotalTime:' in line: - return line[len('TotalTime:'):].strip() - return None - diff --git a/startop/scripts/app_startup/lib/app_runner_test.py b/startop/scripts/app_startup/lib/app_runner_test.py deleted file mode 100644 index 33d233b03aab..000000000000 --- a/startop/scripts/app_startup/lib/app_runner_test.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright 2019, 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. -# - -"""Unit tests for the AppRunner.""" -import os -import sys -from pathlib import Path - -from app_runner import AppRunner, AppRunnerListener -from mock import Mock, call, patch - -# The path is "frameworks/base/startop/scripts/" -sys.path.append(Path(os.path.realpath(__file__)).parents[2]) -import lib.cmd_utils as cmd_utils - -class AppRunnerTestListener(AppRunnerListener): - def preprocess(self) -> None: - cmd_utils.run_shell_command('pre'), - - def postprocess(self, pre_launch_timestamp: str) -> None: - cmd_utils.run_shell_command('post'), - - def metrics_selector(self, am_start_output: str, - pre_launch_timestamp: str) -> None: - return 'TotalTime=123\n' - -RUNNER = AppRunner(package='music', - activity='MainActivity', - compiler_filter='speed', - timeout=None, - simulate=False) - - - -def test_configure_compiler_filter(): - with patch('lib.cmd_utils.run_shell_command', - new_callable=Mock) as mock_run_shell_command: - mock_run_shell_command.return_value = (True, 'speed arm64 kUpToDate') - - RUNNER.configure_compiler_filter() - - calls = [call(os.path.realpath( - os.path.join(RUNNER.DIR, - '../query_compiler_filter.py')) + ' --package music')] - mock_run_shell_command.assert_has_calls(calls) - -def test_parse_metrics_output(): - input = 'a1=b1\nc1=d1\ne1=f1' - ret = RUNNER.parse_metrics_output(input) - - assert ret == [('a1', 'b1'), ('c1', 'd1'), ('e1', 'f1')] - -def _mocked_run_shell_command(*args, **kwargs): - if args[0] == 'adb shell "date -u +\'%Y-%m-%d %H:%M:%S.%N\'"': - return (True, "2019-07-02 23:20:06.972674825") - elif args[0] == 'adb shell ps | grep "music" | awk \'{print $2;}\'': - return (True, '9999') - else: - return (True, 'a1=b1\nc1=d1=d2\ne1=f1') - -@patch('app_startup.lib.adb_utils.blocking_wait_for_logcat_displayed_time') -@patch('lib.cmd_utils.run_shell_command') -def test_run(mock_run_shell_command, - mock_blocking_wait_for_logcat_displayed_time): - mock_run_shell_command.side_effect = _mocked_run_shell_command - mock_blocking_wait_for_logcat_displayed_time.return_value = 123 - - test_listener = AppRunnerTestListener() - RUNNER.add_callbacks(test_listener) - - result = RUNNER.run() - - RUNNER.remove_callbacks(test_listener) - - calls = [call('pre'), - call(os.path.realpath( - os.path.join(RUNNER.DIR, - '../query_compiler_filter.py')) + - ' --package music'), - call('adb shell "date -u +\'%Y-%m-%d %H:%M:%S.%N\'"'), - call( - 'timeout {timeout} "{DIR}/launch_application" "{package}" "{activity}"' - .format(timeout=30, - DIR=os.path.realpath(os.path.dirname(RUNNER.DIR)), - package='music', - activity='MainActivity', - timestamp='2019-07-02 23:20:06.972674825')), - call('post') - ] - mock_run_shell_command.assert_has_calls(calls) - assert result == [('TotalTime', '123')] - assert len(RUNNER.listeners) == 0
\ No newline at end of file diff --git a/startop/scripts/app_startup/lib/args_utils.py b/startop/scripts/app_startup/lib/args_utils.py deleted file mode 100644 index 080f3b53157b..000000000000 --- a/startop/scripts/app_startup/lib/args_utils.py +++ /dev/null @@ -1,77 +0,0 @@ -import itertools -import os -import sys -from typing import Any, Callable, Dict, Iterable, List, NamedTuple, Tuple, \ - TypeVar, Optional - -# local import -sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname( - os.path.abspath(__file__))))) -import lib.print_utils as print_utils - -T = TypeVar('T') -NamedTupleMeta = Callable[ - ..., T] # approximation of a (S : NamedTuple<T> where S() == T) metatype. -FilterFuncType = Callable[[NamedTuple], bool] - -def dict_lookup_any_key(dictionary: dict, *keys: List[Any]): - for k in keys: - if k in dictionary: - return dictionary[k] - - - print_utils.debug_print("None of the keys {} were in the dictionary".format( - keys)) - return [None] - -def generate_run_combinations(named_tuple: NamedTupleMeta[T], - opts_dict: Dict[str, List[Optional[object]]], - loop_count: int = 1) -> Iterable[T]: - """ - Create all possible combinations given the values in opts_dict[named_tuple._fields]. - - :type T: type annotation for the named_tuple type. - :param named_tuple: named tuple type, whose fields are used to make combinations for - :param opts_dict: dictionary of keys to value list. keys correspond to the named_tuple fields. - :param loop_count: number of repetitions. - :return: an iterable over named_tuple instances. - """ - combinations_list = [] - for k in named_tuple._fields: - # the key can be either singular or plural , e.g. 'package' or 'packages' - val = dict_lookup_any_key(opts_dict, k, k + "s") - - # treat {'x': None} key value pairs as if it was [None] - # otherwise itertools.product throws an exception about not being able to iterate None. - combinations_list.append(val or [None]) - - print_utils.debug_print("opts_dict: ", opts_dict) - print_utils.debug_print_nd("named_tuple: ", named_tuple) - print_utils.debug_print("combinations_list: ", combinations_list) - - for i in range(loop_count): - for combo in itertools.product(*combinations_list): - yield named_tuple(*combo) - -def filter_run_combinations(named_tuple: NamedTuple, - filters: List[FilterFuncType]) -> bool: - for filter in filters: - if filter(named_tuple): - return False - return True - -def generate_group_run_combinations(run_combinations: Iterable[NamedTuple], - dst_nt: NamedTupleMeta[T]) \ - -> Iterable[Tuple[T, Iterable[NamedTuple]]]: - def group_by_keys(src_nt): - src_d = src_nt._asdict() - # now remove the keys that aren't legal in dst. - for illegal_key in set(src_d.keys()) - set(dst_nt._fields): - if illegal_key in src_d: - del src_d[illegal_key] - - return dst_nt(**src_d) - - for args_list_it in itertools.groupby(run_combinations, group_by_keys): - (group_key_value, args_it) = args_list_it - yield (group_key_value, args_it) diff --git a/startop/scripts/app_startup/lib/args_utils_test.py b/startop/scripts/app_startup/lib/args_utils_test.py deleted file mode 100644 index 4b7e0fa20627..000000000000 --- a/startop/scripts/app_startup/lib/args_utils_test.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018, 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. -# - -"""Unit tests for the args_utils.py script.""" - -import typing - -import args_utils - -def generate_run_combinations(*args): - # expand out the generator values so that assert x == y works properly. - return [i for i in args_utils.generate_run_combinations(*args)] - -def test_generate_run_combinations(): - blank_nd = typing.NamedTuple('Blank') - assert generate_run_combinations(blank_nd, {}, 1) == [()], "empty" - assert generate_run_combinations(blank_nd, {'a': ['a1', 'a2']}) == [ - ()], "empty filter" - a_nd = typing.NamedTuple('A', [('a', str)]) - assert generate_run_combinations(a_nd, {'a': None}) == [(None,)], "None" - assert generate_run_combinations(a_nd, {'a': ['a1', 'a2']}) == [('a1',), ( - 'a2',)], "one item" - assert generate_run_combinations(a_nd, - {'a': ['a1', 'a2'], 'b': ['b1', 'b2']}) == [ - ('a1',), ('a2',)], \ - "one item filter" - assert generate_run_combinations(a_nd, {'a': ['a1', 'a2']}, 2) == [('a1',), ( - 'a2',), ('a1',), ('a2',)], "one item" - ab_nd = typing.NamedTuple('AB', [('a', str), ('b', str)]) - assert generate_run_combinations(ab_nd, - {'a': ['a1', 'a2'], - 'b': ['b1', 'b2']}) == [ab_nd('a1', 'b1'), - ab_nd('a1', 'b2'), - ab_nd('a2', 'b1'), - ab_nd('a2', 'b2')], \ - "two items" - - assert generate_run_combinations(ab_nd, - {'as': ['a1', 'a2'], - 'bs': ['b1', 'b2']}) == [ab_nd('a1', 'b1'), - ab_nd('a1', 'b2'), - ab_nd('a2', 'b1'), - ab_nd('a2', 'b2')], \ - "two items plural" diff --git a/startop/scripts/app_startup/lib/common b/startop/scripts/app_startup/lib/common deleted file mode 100755 index bedaa1e10288..000000000000 --- a/startop/scripts/app_startup/lib/common +++ /dev/null @@ -1,198 +0,0 @@ -#!/bin/bash -# Copyright 2018, 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. - -if [[ -z $ANDROID_BUILD_TOP ]]; then - echo "Please run source build/envsetup.sh first" >&2 - exit 1 -fi - -source $ANDROID_BUILD_TOP/build/envsetup.sh - -verbose_print() { - if [[ "$verbose" == "y" ]]; then - echo "$@" >&2 - fi -} - -remote_pidof() { - local procname="$1" - adb shell ps | grep "$procname" | awk '{print $2;}' -} - -remote_pkill() { - local procname="$1" - shift - - local the_pids=$(remote_pidof "$procname") - local pid - - for pid in $the_pids; do - verbose_print adb shell kill "$@" "$pid" - adb shell kill "$@" "$pid" - done -} - -get_activity_name() { - local package="$1" - local action_key="android.intent.action.MAIN:" - - # Example query-activities output being parsed: - # - # Activity #14: - # priority=0 preferredOrder=0 match=0x108000 specificIndex=-1 isDefault=true - # com.google.android.videos/com.google.android.youtube.videos.EntryPoint - # Activity #15: - # priority=0 preferredOrder=0 match=0x108000 specificIndex=-1 isDefault=true - # com.google.android.youtube/.app.honeycomb.Shell$HomeActivity - - # Given package 'com.google.android.youtube' return '.app.honeycomb.Shell$HomeActivity' - - local activity_line="$(adb shell cmd package query-activities --brief -a android.intent.action.MAIN -c android.intent.category.LAUNCHER | grep "$package/")" - IFS="/" read -a array <<< "$activity_line" - local activity_name="${array[1]}" - - # Activities starting with '.' are shorthand for having their package name prefixed. - if [[ $activity_name == .* ]]; then - activity_name="${package}${activity_name}" - fi - echo "$activity_name" -} - -# Use with logcat_from_timestamp to skip all past log-lines. -logcat_save_timestamp() { - adb shell 'date -u +"%Y-%m-%d %H:%M:%S.%N"' -} - -# Roll forward logcat to only show events -# since the specified timestamp. -# -# i.e. don't look at historical logcat, -# only look at FUTURE logcat. -# -# First use 'logcat_save_timestamp' -# Then do whatever action you want. -# Then use 'logcat_from_timestamp_bg $timestamp' -logcat_from_timestamp_bg() { - local timestamp="$1" - shift # drop timestamp from args. - verbose_print adb logcat -T \"$timestamp\" \"$@\" - adb logcat -v UTC -T "$timestamp" "$@" & - logcat_from_timestamp_pid=$! -} - -# Starting at timestamp $2, wait until we seen pattern $3 -# or until a timeout happens in $1 seconds. -# If successful, also echo the line that matched the pattern. -# -# Set VERBOSE_LOGCAT=1 to debug every line of logcat it tries to parse. -logcat_select_pattern() { - local timeout="$1" - local timestamp="$2" - local pattern="$3" - - local logcat_fd - - coproc logcat_fd { - kill_children_quietly() { - kill "$logcat_pidd" - wait "$logcat_pidd" 2>/dev/null - } - - trap 'kill_children_quietly' EXIT # kill logcat when this coproc is killed. - - # run logcat in the background so it can be killed. - logcat_from_timestamp_bg "$timestamp" - logcat_pidd=$logcat_from_timestamp_pid - wait "$logcat_pidd" - } - local logcat_pid="$!" - verbose_print "[LOGCAT] Spawn pid $logcat_pid" - - local timeout_ts="$(date -d "now + ${timeout} seconds" '+%s')" - local now_ts="0" - - local return_code=1 - - verbose_print "logcat_wait_for_pattern begin" - - while read -t "$timeout" -r -u "${logcat_fd[0]}" logcat_output; do - if (( $VERBOSE_LOGCAT )); then - verbose_print "LOGCAT: $logcat_output" - fi - if [[ "$logcat_output:" == *"$pattern"* ]]; then - verbose_print "LOGCAT: " "$logcat_output" - verbose_print "WE DID SEE PATTERN" '<<' "$pattern" '>>.' - echo "$logcat_output" - return_code=0 - break - fi - now_ts="$(date -d "now" '+%s')" - if (( now_ts >= timeout_ts )); then - verbose_print "DID TIMEOUT BEFORE SEEING ANYTHING (timeout=$timeout seconds) " '<<' "$pattern" '>>.' - break - fi - done - - # Don't leave logcat lying around since it will keep going. - kill "$logcat_pid" - # Suppress annoying 'Terminated...' message. - wait "$logcat_pid" 2>/dev/null - - verbose_print "[LOGCAT] $logcat_pid should be killed" - - return $return_code -} - -# Starting at timestamp $2, wait until we seen pattern $3 -# or until a timeout happens in $1 seconds. -# -# Set VERBOSE_LOGCAT=1 to debug every line of logcat it tries to parse. -logcat_wait_for_pattern() { - logcat_select_pattern "$@" > /dev/null -} - -# Starting at timestamp $2, wait until we seen pattern $3 -# or until a timeout happens in $1 seconds. -# If successful, extract with the regular expression pattern in #4 -# and return the first capture group. -# -# Set VERBOSE_LOGCAT=1 to debug every line of logcat it tries to parse. -logcat_extract_pattern() { - local timeout="$1" - local timestamp="$2" - local pattern="$3" - local re_pattern="$4" - - local result - local exit_code - - result="$(logcat_select_pattern "$@")" - exit_code=$? - - if [[ $exit_code -ne 0 ]]; then - return $exit_code - fi - - echo "$result" | sed 's/'"$re_pattern"'/\1/g' -} - -# Join array -# FOO=(a b c) -# join_by , "${FOO[@]}" #a,b,c -join_by() { - local IFS="$1" - shift - echo "$*" -} diff --git a/startop/scripts/app_startup/lib/data_frame.py b/startop/scripts/app_startup/lib/data_frame.py deleted file mode 100644 index 20a2308637f2..000000000000 --- a/startop/scripts/app_startup/lib/data_frame.py +++ /dev/null @@ -1,201 +0,0 @@ -import itertools -from typing import Dict, List - -class DataFrame: - """Table-like class for storing a 2D cells table with named columns.""" - def __init__(self, data: Dict[str, List[object]] = {}): - """ - Create a new DataFrame from a dictionary (keys = headers, - values = columns). - """ - self._headers = [i for i in data.keys()] - self._rows = [] - - row_num = 0 - - def get_data_row(idx): - r = {} - for header, header_data in data.items(): - - if not len(header_data) > idx: - continue - - r[header] = header_data[idx] - - return r - - while True: - row_dict = get_data_row(row_num) - if len(row_dict) == 0: - break - - self._append_row(row_dict.keys(), row_dict.values()) - row_num = row_num + 1 - - def concat_rows(self, other: 'DataFrame') -> None: - """ - In-place concatenate rows of other into the rows of the - current DataFrame. - - None is added in pre-existing cells if new headers - are introduced. - """ - other_datas = other._data_only() - - other_headers = other.headers - - for d in other_datas: - self._append_row(other_headers, d) - - def _append_row(self, headers: List[str], data: List[object]): - new_row = {k:v for k,v in zip(headers, data)} - self._rows.append(new_row) - - for header in headers: - if not header in self._headers: - self._headers.append(header) - - def __repr__(self): -# return repr(self._rows) - repr = "" - - header_list = self._headers_only() - - row_format = u"" - for header in header_list: - row_format = row_format + u"{:>%d}" %(len(header) + 1) - - repr = row_format.format(*header_list) + "\n" - - for v in self._data_only(): - repr = repr + row_format.format(*v) + "\n" - - return repr - - def __eq__(self, other): - if isinstance(other, self.__class__): - return self.headers == other.headers and self.data_table == other.data_table - else: - print("wrong instance", other.__class__) - return False - - @property - def headers(self) -> List[str]: - return [i for i in self._headers_only()] - - @property - def data_table(self) -> List[List[object]]: - return list(self._data_only()) - - @property - def data_table_transposed(self) -> List[List[object]]: - return list(self._transposed_data()) - - @property - def data_row_len(self) -> int: - return len(self._rows) - - def data_row_at(self, idx) -> List[object]: - """ - Return a single data row at the specified index (0th based). - - Accepts negative indices, e.g. -1 is last row. - """ - row_dict = self._rows[idx] - l = [] - - for h in self._headers_only(): - l.append(row_dict.get(h)) # Adds None in blank spots. - - return l - - def copy(self) -> 'DataFrame': - """ - Shallow copy of this DataFrame. - """ - return self.repeat(count=0) - - def repeat(self, count: int) -> 'DataFrame': - """ - Returns a new DataFrame where each row of this dataframe is repeated count times. - A repeat of a row is adjacent to other repeats of that same row. - """ - df = DataFrame() - df._headers = self._headers.copy() - - rows = [] - for row in self._rows: - for i in range(count): - rows.append(row.copy()) - - df._rows = rows - - return df - - def merge_data_columns(self, other: 'DataFrame'): - """ - Merge self and another DataFrame by adding the data from other column-wise. - For any headers that are the same, data from 'other' is preferred. - """ - for h in other._headers: - if not h in self._headers: - self._headers.append(h) - - append_rows = [] - - for self_dict, other_dict in itertools.zip_longest(self._rows, other._rows): - if not self_dict: - d = {} - append_rows.append(d) - else: - d = self_dict - - d_other = other_dict - if d_other: - for k,v in d_other.items(): - d[k] = v - - for r in append_rows: - self._rows.append(r) - - def data_row_reduce(self, fnc) -> 'DataFrame': - """ - Reduces the data row-wise by applying the fnc to each row (column-wise). - Empty cells are skipped. - - fnc(Iterable[object]) -> object - fnc is applied over every non-empty cell in that column (descending row-wise). - - Example: - DataFrame({'a':[1,2,3]}).data_row_reduce(sum) == DataFrame({'a':[6]}) - - Returns a new single-row DataFrame. - """ - df = DataFrame() - df._headers = self._headers.copy() - - def yield_by_column(header_key): - for row_dict in self._rows: - val = row_dict.get(header_key) - if val: - yield val - - new_row_dict = {} - for h in df._headers: - cell_value = fnc(yield_by_column(h)) - new_row_dict[h] = cell_value - - df._rows = [new_row_dict] - return df - - def _headers_only(self): - return self._headers - - def _data_only(self): - row_len = len(self._rows) - - for i in range(row_len): - yield self.data_row_at(i) - - def _transposed_data(self): - return zip(*self._data_only())
\ No newline at end of file diff --git a/startop/scripts/app_startup/lib/data_frame_test.py b/startop/scripts/app_startup/lib/data_frame_test.py deleted file mode 100644 index 1cbc1cbe45cb..000000000000 --- a/startop/scripts/app_startup/lib/data_frame_test.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018, 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. -# - -"""Unit tests for the data_frame.py script.""" - -from data_frame import DataFrame - -def test_data_frame(): - # trivial empty data frame - df = DataFrame() - assert df.headers == [] - assert df.data_table == [] - assert df.data_table_transposed == [] - - # common case, same number of values in each place. - df = DataFrame({'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [4, 5, 6]}) - assert df.headers == ['TotalTime_ms', 'Displayed_ms'] - assert df.data_table == [[1, 4], [2, 5], [3, 6]] - assert df.data_table_transposed == [(1, 2, 3), (4, 5, 6)] - - # varying num values. - df = DataFrame({'many': [1, 2], 'none': []}) - assert df.headers == ['many', 'none'] - assert df.data_table == [[1, None], [2, None]] - assert df.data_table_transposed == [(1, 2), (None, None)] - - df = DataFrame({'many': [], 'none': [1, 2]}) - assert df.headers == ['many', 'none'] - assert df.data_table == [[None, 1], [None, 2]] - assert df.data_table_transposed == [(None, None), (1, 2)] - - # merge multiple data frames - df = DataFrame() - df.concat_rows(DataFrame()) - assert df.headers == [] - assert df.data_table == [] - assert df.data_table_transposed == [] - - df = DataFrame() - df2 = DataFrame({'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [4, 5, 6]}) - - df.concat_rows(df2) - assert df.headers == ['TotalTime_ms', 'Displayed_ms'] - assert df.data_table == [[1, 4], [2, 5], [3, 6]] - assert df.data_table_transposed == [(1, 2, 3), (4, 5, 6)] - - df = DataFrame({'TotalTime_ms': [1, 2]}) - df2 = DataFrame({'Displayed_ms': [4, 5]}) - - df.concat_rows(df2) - assert df.headers == ['TotalTime_ms', 'Displayed_ms'] - assert df.data_table == [[1, None], [2, None], [None, 4], [None, 5]] - - df = DataFrame({'TotalTime_ms': [1, 2]}) - df2 = DataFrame({'TotalTime_ms': [3, 4], 'Displayed_ms': [5, 6]}) - - df.concat_rows(df2) - assert df.headers == ['TotalTime_ms', 'Displayed_ms'] - assert df.data_table == [[1, None], [2, None], [3, 5], [4, 6]] - - # data_row_at - df = DataFrame({'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [4, 5, 6]}) - assert df.data_row_at(-1) == [3, 6] - assert df.data_row_at(2) == [3, 6] - assert df.data_row_at(1) == [2, 5] - - # repeat - df = DataFrame({'TotalTime_ms': [1], 'Displayed_ms': [4]}) - df2 = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]}) - assert df.repeat(3) == df2 - - # repeat - df = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]}) - assert df.data_row_len == 3 - df = DataFrame({'TotalTime_ms': [1, 1]}) - assert df.data_row_len == 2 - - # repeat - df = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]}) - assert df.data_row_len == 3 - df = DataFrame({'TotalTime_ms': [1, 1]}) - assert df.data_row_len == 2 - - # data_row_reduce - df = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]}) - df_sum = DataFrame({'TotalTime_ms': [3], 'Displayed_ms': [12]}) - assert df.data_row_reduce(sum) == df_sum - - # merge_data_columns - df = DataFrame({'TotalTime_ms': [1, 2, 3]}) - df2 = DataFrame({'Displayed_ms': [3, 4, 5, 6]}) - - df.merge_data_columns(df2) - assert df == DataFrame( - {'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [3, 4, 5, 6]}) - - df = DataFrame({'TotalTime_ms': [1, 2, 3]}) - df2 = DataFrame({'Displayed_ms': [3, 4]}) - - df.merge_data_columns(df2) - assert df == DataFrame( - {'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [3, 4]}) - - df = DataFrame({'TotalTime_ms': [1, 2, 3]}) - df2 = DataFrame({'TotalTime_ms': [10, 11]}) - - df.merge_data_columns(df2) - assert df == DataFrame({'TotalTime_ms': [10, 11, 3]}) - - df = DataFrame({'TotalTime_ms': []}) - df2 = DataFrame({'TotalTime_ms': [10, 11]}) - - df.merge_data_columns(df2) - assert df == DataFrame({'TotalTime_ms': [10, 11]}) diff --git a/startop/scripts/app_startup/lib/perfetto_trace_collector.py b/startop/scripts/app_startup/lib/perfetto_trace_collector.py deleted file mode 100644 index 9ffb3494da49..000000000000 --- a/startop/scripts/app_startup/lib/perfetto_trace_collector.py +++ /dev/null @@ -1,166 +0,0 @@ -# Copyright 2019, 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. - -"""Class to collector perfetto trace.""" -import datetime -import os -import re -import sys -import time -from datetime import timedelta -from typing import Optional, List, Tuple - -# global variables -DIR = os.path.abspath(os.path.dirname(__file__)) - -sys.path.append(os.path.dirname(os.path.dirname(DIR))) - -import app_startup.lib.adb_utils as adb_utils -from app_startup.lib.app_runner import AppRunner, AppRunnerListener -import lib.print_utils as print_utils -import lib.logcat_utils as logcat_utils -import iorap.lib.iorapd_utils as iorapd_utils - -class PerfettoTraceCollector(AppRunnerListener): - """ Class to collect perfetto trace. - - To set trace duration of perfetto, change the 'trace_duration_ms'. - To pull the generated perfetto trace on device, set the 'output'. - """ - TRACE_FILE_SUFFIX = 'perfetto_trace.pb' - TRACE_DURATION_PROP = 'iorapd.perfetto.trace_duration_ms' - MS_PER_SEC = 1000 - DEFAULT_TRACE_DURATION = timedelta(milliseconds=5000) # 5 seconds - _COLLECTOR_TIMEOUT_MULTIPLIER = 10 # take the regular timeout and multiply - - def __init__(self, - package: str, - activity: Optional[str], - compiler_filter: Optional[str], - timeout: Optional[int], - simulate: bool, - trace_duration: timedelta = DEFAULT_TRACE_DURATION, - save_destination_file_path: Optional[str] = None): - """ Initialize the perfetto trace collector. """ - self.app_runner = AppRunner(package, - activity, - compiler_filter, - timeout, - simulate) - self.app_runner.add_callbacks(self) - - self.trace_duration = trace_duration - self.save_destination_file_path = save_destination_file_path - - def purge_file(self, suffix: str) -> None: - print_utils.debug_print('iorapd-perfetto: purge file in ' + - self._get_remote_path()) - adb_utils.delete_file_on_device(self._get_remote_path()) - - def run(self) -> Optional[List[Tuple[str]]]: - """Runs an app. - - Returns: - A list of (metric, value) tuples. - """ - return self.app_runner.run() - - def preprocess(self): - # Sets up adb environment. - adb_utils.root() - adb_utils.disable_selinux() - time.sleep(1) - - # Kill any existing process of this app - adb_utils.pkill(self.app_runner.package) - - # Remove existing trace and compiler files - self.purge_file(PerfettoTraceCollector.TRACE_FILE_SUFFIX) - - # Set perfetto trace duration prop to milliseconds. - adb_utils.set_prop(PerfettoTraceCollector.TRACE_DURATION_PROP, - int(self.trace_duration.total_seconds()* - PerfettoTraceCollector.MS_PER_SEC)) - - if not iorapd_utils.stop_iorapd(): - raise RuntimeError('Cannot stop iorapd!') - - if not iorapd_utils.enable_iorapd_perfetto(): - raise RuntimeError('Cannot enable perfetto!') - - if not iorapd_utils.disable_iorapd_readahead(): - raise RuntimeError('Cannot disable readahead!') - - if not iorapd_utils.start_iorapd(): - raise RuntimeError('Cannot start iorapd!') - - # Drop all caches to get cold starts. - adb_utils.vm_drop_cache() - - def postprocess(self, pre_launch_timestamp: str): - # Kill any existing process of this app - adb_utils.pkill(self.app_runner.package) - - iorapd_utils.disable_iorapd_perfetto() - - if self.save_destination_file_path is not None: - adb_utils.pull_file(self._get_remote_path(), - self.save_destination_file_path) - - def metrics_selector(self, am_start_output: str, - pre_launch_timestamp: str) -> str: - """Parses the metric after app startup by reading from logcat in a blocking - manner until all metrics have been found". - - Returns: - An empty string because the metric needs no further parsing. - """ - if not self._wait_for_perfetto_trace(pre_launch_timestamp): - raise RuntimeError('Could not save perfetto app trace file!') - - return '' - - def _wait_for_perfetto_trace(self, pre_launch_timestamp) -> Optional[str]: - """ Waits for the perfetto trace being saved to file. - - The string is in the format of r".*Perfetto TraceBuffer saved to file: - <file path>.*" - - Returns: - the string what the program waits for. If the string doesn't show up, - return None. - """ - pattern = re.compile(r'.*Perfetto TraceBuffer saved to file: {}.*'. - format(self._get_remote_path())) - - # The pre_launch_timestamp is longer than what the datetime can parse. Trim - # last three digits to make them align. For example: - # 2019-07-02 23:20:06.972674825999 -> 2019-07-02 23:20:06.972674825 - assert len(pre_launch_timestamp) == len('2019-07-02 23:20:06.972674825') - timestamp = datetime.datetime.strptime(pre_launch_timestamp[:-3], - '%Y-%m-%d %H:%M:%S.%f') - - # The timeout of perfetto trace is longer than the normal app run timeout. - timeout_dt = self.app_runner.timeout * PerfettoTraceCollector._COLLECTOR_TIMEOUT_MULTIPLIER - timeout_end = timestamp + datetime.timedelta(seconds=timeout_dt) - - return logcat_utils.blocking_wait_for_logcat_pattern(timestamp, - pattern, - timeout_end) - - def _get_remote_path(self): - # For example: android.music%2Fmusic.TopLevelActivity.perfetto_trace.pb - return iorapd_utils._iorapd_path_to_data_file(self.app_runner.package, - self.app_runner.activity, - PerfettoTraceCollector.TRACE_FILE_SUFFIX) diff --git a/startop/scripts/app_startup/lib/perfetto_trace_collector_test.py b/startop/scripts/app_startup/lib/perfetto_trace_collector_test.py deleted file mode 100644 index 8d94fc58bede..000000000000 --- a/startop/scripts/app_startup/lib/perfetto_trace_collector_test.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. -# - -"""Unit tests for the data_frame.py script.""" -import os -import sys -from pathlib import Path -from datetime import timedelta - -from mock import call, patch -from perfetto_trace_collector import PerfettoTraceCollector - -sys.path.append(Path(os.path.realpath(__file__)).parents[2]) -from app_startup.lib.app_runner import AppRunner - -RUNNER = PerfettoTraceCollector(package='music', - activity='MainActivity', - compiler_filter=None, - timeout=10, - simulate=False, - trace_duration = timedelta(milliseconds=1000), - # No actual file will be created. Just to - # check the command. - save_destination_file_path='/tmp/trace.pb') - -def _mocked_run_shell_command(*args, **kwargs): - if args[0] == 'adb shell ps | grep "music" | awk \'{print $2;}\'': - return (True, '9999') - else: - return (True, '') - -@patch('lib.logcat_utils.blocking_wait_for_logcat_pattern') -@patch('lib.cmd_utils.run_shell_command') -def test_perfetto_trace_collector_preprocess(mock_run_shell_command, - mock_blocking_wait_for_logcat_pattern): - mock_run_shell_command.side_effect = _mocked_run_shell_command - mock_blocking_wait_for_logcat_pattern.return_value = "Succeed!" - - RUNNER.preprocess() - - calls = [call('adb root'), - call('adb shell "getenforce"'), - call('adb shell "setenforce 0"'), - call('adb shell "stop"'), - call('adb shell "start"'), - call('adb wait-for-device'), - call('adb shell ps | grep "music" | awk \'{print $2;}\''), - call('adb shell "kill 9999"'), - call( - 'adb shell "[[ -f \'/data/misc/iorapd/music%2FMainActivity.perfetto_trace.pb\' ]] ' - '&& rm -f \'/data/misc/iorapd/music%2FMainActivity.perfetto_trace.pb\' || exit 0"'), - call('adb shell "setprop "iorapd.perfetto.trace_duration_ms" "1000""'), - call( - 'bash -c "source {}; iorapd_stop"'.format( - AppRunner.IORAP_COMMON_BASH_SCRIPT)), - call( - 'bash -c "source {}; iorapd_perfetto_enable"'.format( - AppRunner.IORAP_COMMON_BASH_SCRIPT)), - call( - 'bash -c "source {}; iorapd_readahead_disable"'.format( - AppRunner.IORAP_COMMON_BASH_SCRIPT)), - call( - 'bash -c "source {}; iorapd_start"'.format( - AppRunner.IORAP_COMMON_BASH_SCRIPT)), - call('adb shell "echo 3 > /proc/sys/vm/drop_caches"')] - - mock_run_shell_command.assert_has_calls(calls) - -@patch('lib.logcat_utils.blocking_wait_for_logcat_pattern') -@patch('lib.cmd_utils.run_shell_command') -def test_perfetto_trace_collector_postprocess(mock_run_shell_command, - mock_blocking_wait_for_logcat_pattern): - mock_run_shell_command.side_effect = _mocked_run_shell_command - mock_blocking_wait_for_logcat_pattern.return_value = "Succeed!" - - RUNNER.postprocess('2019-07-02 23:20:06.972674825') - - calls = [call('adb shell ps | grep "music" | awk \'{print $2;}\''), - call('adb shell "kill 9999"'), - call( - 'bash -c "source {}; iorapd_perfetto_disable"'.format( - AppRunner.IORAP_COMMON_BASH_SCRIPT)), - call('adb pull ' - '"/data/misc/iorapd/music%2FMainActivity.perfetto_trace.pb" ' - '"/tmp/trace.pb"')] - - mock_run_shell_command.assert_has_calls(calls) diff --git a/startop/scripts/app_startup/parse_metrics b/startop/scripts/app_startup/parse_metrics deleted file mode 100755 index 3fa1462bc56e..000000000000 --- a/startop/scripts/app_startup/parse_metrics +++ /dev/null @@ -1,215 +0,0 @@ -#!/bin/bash -# -# Copyright 2019, 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. - -usage() { - cat <<EOF -Usage: launch_application package activity | parse_metrics --package <name> --timestamp <timestamp> [OPTIONS]... - - Reads from stdin the result of 'am start' metrics. May also parse logcat - for additional metrics. - - Output form: - - MetricName_unit=numeric_value - MetricName2_unit=numeric_value2 - - This may block until all desired metrics are parsed from logcat. - To get a list of metrics without doing real parsing, use --simulate. - - To add package-specific metrics, add a script called 'metrics/\$full_package_name' - that exposes additional metrics in same way as above. - - (required) - -p, --package <name> package of the app that is being used - -ts, --timestamp <name> logcat timestamp [only looks at logcat entries after this timestamp]. - - (optional) - -s, --simulate prints dummy values instead of real metrics - -a, --activity <name> activity to use (default: inferred) - -h, --help usage information (this) - -v, --verbose enable extra verbose printing - -t, --timeout <sec> how many seconds to timeout when trying to wait for logcat to change - -rfd, --reportfullydrawn wait for report fully drawn (default: off) -EOF -} - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -source "$DIR/lib/common" - -report_fully_drawn="n" -package="" -activity="" -timeout=5 -simulate="n" -parse_arguments() { - while [[ $# -gt 0 ]]; do - case "$1" in - -h|--help) - usage - exit 0 - ;; - -p|--package) - package="$2" - shift - ;; - -a|--activity) - activity="$2" - shift - ;; - -v|--verbose) - export verbose="y" - ;; - -t|--timeout) - timeout="$2" - shift - ;; - -ts|--timestamp) - timestamp="$2" - shift - ;; - -s|--simulate) - simulate="y" - ;; - -rfd|--reportfullydrawn) - report_fully_drawn="y" - ;; - - - *) - echo "Invalid argument: $1" >&2 - exit 1 - esac - shift - done -} - -# Main entry point -if [[ $# -eq 0 ]]; then - usage - exit 1 -else - parse_arguments "$@" - - # if we do not have have package exit early with an error - [[ "$package" == "" ]] && echo "--package not specified" 1>&2 && exit 64 - - # ignore timestamp for --simulate. it's optional. - if [[ $simulate == y ]]; then - timestamp=0 - fi - - # if we do not have timestamp, exit early with an error - [[ "$timestamp" == "" ]] && echo "--timestamp not specified" 1>&2 && exit 64 - - if [[ "$activity" == "" ]] && [[ "$simulate" != "y" ]]; then - activity="$(get_activity_name "$package")" - if [[ "$activity" == "" ]]; then - echo "Activity name could not be found, invalid package name?" 1>&2 - exit 64 - else - verbose_print "Activity name inferred: " "$activity" - fi - fi -fi - -parse_metric_from_logcat() { - local metric_name="$1" - local pattern="$2" - local re_pattern="$3" - local retcode - local result - local sec - local ms - - # parse logcat for 'Displayed...' and that other one... - - # 05-06 14:34:08.854 29460 29481 I ActivityTaskManager: Displayed com.google.android.dialer/.extensions.GoogleDialtactsActivity: +361ms - verbose_print "parse_metric_from_logcat: $re_pattern" - - - echo -ne "$metric_name=" - - if [[ $simulate == y ]]; then - echo "-1" - return 0 - fi - - result="$(logcat_extract_pattern "$timeout" "$timestamp" "$pattern" "$re_pattern")" - retcode=$? - - if [[ $retcode -ne 0 ]]; then - # Timed out before finding the pattern. Could also mean the pattern is wrong. - echo "Parse $re_pattern from logcat TIMED OUT after $timeout seconds." >&2 - echo "-$?" - return $retcode - fi - - # "10s123ms" -> "10s123" - result=${result/ms/} - if [[ $result =~ s ]]; then - ms=${result/*s/} - sec=${result/s*/} - else - sec=0 - ms=$result - fi - ((result=sec*1000+ms)) - - echo "$result" - return $retcode -} - - -total_time="-1" -if [[ $simulate != y ]]; then - verbose_print 'logcat timestamp NOW: ' $(logcat_save_timestamp) - - # parse stdin for 'am start' result - while read -t "$timeout" -r input_line; do - verbose_print 'stdin:' "$input_line" - if [[ $input_line == *TotalTime:* ]]; then - total_time="$(echo "$input_line" | sed 's/TotalTime: \([[:digit:]]\+\)/\1/g')" - # but keep reading the rest from stdin until <EOF> - fi - done -fi - -echo "TotalTime_ms=$total_time" - -# parse logcat for 'Displayed...' and that other one... - -# 05-06 14:34:08.854 29460 29481 I ActivityTaskManager: Displayed com.google.android.dialer/.extensions.GoogleDialtactsActivity: +361ms -pattern="ActivityTaskManager: Displayed ${package}" -re_pattern='.*Displayed[[:blank:]]\+'"${package}"'[/][^[:blank:]]\+[[:blank:]]+\([[:digit:]]\+ms\|[[:digit:]]\+s[[:digit:]]\+ms\).*' - -parse_metric_from_logcat "Displayed_ms" "$pattern" "$re_pattern" - -# Only track ReportFullyDrawn with --reportfullydrawn/-rfd flags -if [[ $report_fully_drawn == y ]]; then - # 01-16 17:31:44.550 11172 11204 I ActivityTaskManager: Fully drawn com.google.android.GoogleCamera/com.android.camera.CameraLauncher: +10s897ms - pattern="ActivityTaskManager: Fully drawn ${package}" - #re_pattern='.*Fully drawn[[:blank:]]\+'"${package}"'[/][^[:blank:]]\+[[:blank:]]+\([[:digit:]]\+\).*' - re_pattern='.*Fully drawn[[:blank:]]\+'"${package}"'[/][^[:blank:]]\+[[:blank:]]+\([[:digit:]]\+ms\|[[:digit:]]\+s[[:digit:]]\+ms\).*' - - parse_metric_from_logcat "Fully_drawn_ms" "$pattern" "$re_pattern" -fi - -# also call into package-specific scripts if there are additional metrics -if [[ -x "$DIR/metrics/$package" ]]; then - source "$DIR/metrics/$package" "$timestamp" -else - verbose_print parse_metrics: no per-package metrics script found at "$DIR/metrics/$package" -fi diff --git a/startop/scripts/app_startup/query_compiler_filter.py b/startop/scripts/app_startup/query_compiler_filter.py deleted file mode 100755 index ea14264b4a1c..000000000000 --- a/startop/scripts/app_startup/query_compiler_filter.py +++ /dev/null @@ -1,232 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018, 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. - -# -# -# Query the current compiler filter for an application by its package name. -# (By parsing the results of the 'adb shell dumpsys package $package' command). -# The output is a string "$compilation_filter $compilation_reason $isa". -# -# See --help for more details. -# -# ----------------------------------- -# -# Sample usage: -# -# $> ./query_compiler_filter.py --package com.google.android.calculator -# speed-profile unknown arm64 -# - -import argparse -import os -import re -import sys - -# TODO: refactor this with a common library file with analyze_metrics.py -DIR = os.path.abspath(os.path.dirname(__file__)) -sys.path.append(os.path.dirname(DIR)) -import lib.cmd_utils as cmd_utils -import lib.print_utils as print_utils - -from typing import List, NamedTuple, Iterable - -_DEBUG_FORCE = None # Ignore -d/--debug if this is not none. - -def parse_options(argv: List[str] = None): - """Parse command line arguments and return an argparse Namespace object.""" - parser = argparse.ArgumentParser(description="Query the compiler filter for a package.") - # argparse considers args starting with - and -- optional in --help, even though required=True. - # by using a named argument group --help will clearly say that it's required instead of optional. - required_named = parser.add_argument_group('required named arguments') - required_named.add_argument('-p', '--package', action='store', dest='package', help='package of the application', required=True) - - # optional arguments - # use a group here to get the required arguments to appear 'above' the optional arguments in help. - optional_named = parser.add_argument_group('optional named arguments') - optional_named.add_argument('-i', '--isa', '--instruction-set', action='store', dest='instruction_set', help='which instruction set to select. defaults to the first one available if not specified.', choices=('arm64', 'arm', 'x86_64', 'x86')) - optional_named.add_argument('-s', '--simulate', dest='simulate', action='store_true', help='Print which commands will run, but don\'t run the apps') - optional_named.add_argument('-d', '--debug', dest='debug', action='store_true', help='Add extra debugging output') - - return parser.parse_args(argv) - -def remote_dumpsys_package(package: str, simulate: bool) -> str: - # --simulate is used for interactive debugging/development, but also for the unit test. - if simulate: - return """ -Dexopt state: - [%s] - path: /data/app/%s-D7s8PLidqqEq7Jc7UH_a5A==/base.apk - arm64: [status=speed-profile] [reason=unknown] - path: /data/app/%s-D7s8PLidqqEq7Jc7UH_a5A==/base.apk - arm: [status=speed] [reason=first-boot] - path: /data/app/%s-D7s8PLidqqEq7Jc7UH_a5A==/base.apk - x86: [status=quicken] [reason=install] -""" %(package, package, package, package) - - code, res = cmd_utils.execute_arbitrary_command(['adb', 'shell', 'dumpsys', - 'package', package], - simulate=False, - timeout=5, - shell=False) - if code: - return res - else: - raise AssertionError("Failed to dumpsys package, errors = %s", res) - -ParseTree = NamedTuple('ParseTree', [('label', str), ('children', List['ParseTree'])]) -DexoptState = ParseTree # With the Dexopt state: label -ParseResult = NamedTuple('ParseResult', [('remainder', List[str]), ('tree', ParseTree)]) - -def find_parse_subtree(parse_tree: ParseTree, match_regex: str) -> ParseTree: - if re.match(match_regex, parse_tree.label): - return parse_tree - - for node in parse_tree.children: - res = find_parse_subtree(node, match_regex) - if res: - return res - - return None - -def find_parse_children(parse_tree: ParseTree, match_regex: str) -> Iterable[ParseTree]: - for node in parse_tree.children: - if re.match(match_regex, node.label): - yield node - -def parse_tab_subtree(label: str, str_lines: List[str], separator=' ', indent=-1) -> ParseResult: - children = [] - - get_indent_level = lambda line: len(line) - len(line.lstrip()) - - line_num = 0 - - keep_going = True - while keep_going: - keep_going = False - - for line_num in range(len(str_lines)): - line = str_lines[line_num] - current_indent = get_indent_level(line) - - print_utils.debug_print("INDENT=%d, LINE=%s" %(current_indent, line)) - - current_label = line.lstrip() - - # skip empty lines - if line.lstrip() == "": - continue - - if current_indent > indent: - parse_result = parse_tab_subtree(current_label, str_lines[line_num+1::], separator, current_indent) - str_lines = parse_result.remainder - children.append(parse_result.tree) - keep_going = True - else: - # current_indent <= indent - keep_going = False - - break - - new_remainder = str_lines[line_num::] - print_utils.debug_print("NEW REMAINDER: ", new_remainder) - - parse_tree = ParseTree(label, children) - return ParseResult(new_remainder, parse_tree) - -def parse_tab_tree(str_tree: str, separator=' ', indentation_level=-1) -> ParseTree: - - label = None - lst = [] - - line_num = 0 - line_lst = str_tree.split("\n") - - return parse_tab_subtree("", line_lst, separator, indentation_level).tree - -def parse_dexopt_state(dumpsys_tree: ParseTree) -> DexoptState: - res = find_parse_subtree(dumpsys_tree, "Dexopt(\s+)state[:]?") - if not res: - raise AssertionError("Could not find the Dexopt state") - return res - -def find_first_compiler_filter(dexopt_state: DexoptState, package: str, instruction_set: str) -> str: - lst = find_all_compiler_filters(dexopt_state, package) - - print_utils.debug_print("all compiler filters: ", lst) - - for compiler_filter_info in lst: - if not instruction_set: - return compiler_filter_info - - if compiler_filter_info.isa == instruction_set: - return compiler_filter_info - - return None - -CompilerFilterInfo = NamedTuple('CompilerFilterInfo', [('isa', str), ('status', str), ('reason', str)]) - -def find_all_compiler_filters(dexopt_state: DexoptState, package: str) -> List[CompilerFilterInfo]: - - lst = [] - package_tree = find_parse_subtree(dexopt_state, re.escape("[%s]" %package)) - - if not package_tree: - raise AssertionError("Could not find any package subtree for package %s" %(package)) - - print_utils.debug_print("package tree: ", package_tree) - - for path_tree in find_parse_children(package_tree, "path: "): - print_utils.debug_print("path tree: ", path_tree) - - matchre = re.compile("([^:]+):\s+\[status=([^\]]+)\]\s+\[reason=([^\]]+)\]") - - for isa_node in find_parse_children(path_tree, matchre): - - matches = re.match(matchre, isa_node.label).groups() - - info = CompilerFilterInfo(*matches) - lst.append(info) - - return lst - -def main() -> int: - opts = parse_options() - cmd_utils._debug = opts.debug - if _DEBUG_FORCE is not None: - cmd_utils._debug = _DEBUG_FORCE - print_utils.debug_print("parsed options: ", opts) - - # Note: This can often 'fail' if the package isn't actually installed. - package_dumpsys = remote_dumpsys_package(opts.package, opts.simulate) - print_utils.debug_print("package dumpsys: ", package_dumpsys) - dumpsys_parse_tree = parse_tab_tree(package_dumpsys, package_dumpsys) - print_utils.debug_print("parse tree: ", dumpsys_parse_tree) - dexopt_state = parse_dexopt_state(dumpsys_parse_tree) - - filter = find_first_compiler_filter(dexopt_state, opts.package, opts.instruction_set) - - if filter: - print(filter.status, end=' ') - print(filter.reason, end=' ') - print(filter.isa) - else: - print("ERROR: Could not find any compiler-filter for package %s, isa %s" %(opts.package, opts.instruction_set), file=sys.stderr) - return 1 - - return 0 - -if __name__ == '__main__': - sys.exit(main()) diff --git a/startop/scripts/app_startup/query_compiler_filter_test.py b/startop/scripts/app_startup/query_compiler_filter_test.py deleted file mode 100755 index a751a43d1d6c..000000000000 --- a/startop/scripts/app_startup/query_compiler_filter_test.py +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018, 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. -# - -""" -Unit tests for the query_compiler_filter.py script. - -Install: - $> sudo apt-get install python3-pytest ## OR - $> pip install -U pytest -See also https://docs.pytest.org/en/latest/getting-started.html - -Usage: - $> ./query_compiler_filter.py - $> pytest query_compiler_filter.py - $> python -m pytest query_compiler_filter.py - -See also https://docs.pytest.org/en/latest/usage.html -""" - -# global imports -from contextlib import contextmanager -import io -import shlex -import sys -import typing - -# pip imports -import pytest - -# local imports -import query_compiler_filter as qcf - -@contextmanager -def redirect_stdout_stderr(): - """Redirect stdout/stderr to a new StringIO for duration of context.""" - old_stdout = sys.stdout - old_stderr = sys.stderr - new_stdout = io.StringIO() - sys.stdout = new_stdout - new_stderr = io.StringIO() - sys.stderr = new_stderr - try: - yield (new_stdout, new_stderr) - finally: - sys.stdout = old_stdout - sys.stderr = old_stderr - # Seek back to the beginning so we can read whatever was written into it. - new_stdout.seek(0) - new_stderr.seek(0) - -@contextmanager -def replace_argv(argv): - """ Temporarily replace argv for duration of this context.""" - old_argv = sys.argv - sys.argv = [sys.argv[0]] + argv - try: - yield - finally: - sys.argv = old_argv - -def exec_main(argv): - """Run the query_compiler_filter main function with the provided arguments. - - Returns the stdout result when successful, assertion failure otherwise. - """ - try: - with redirect_stdout_stderr() as (the_stdout, the_stderr): - with replace_argv(argv): - code = qcf.main() - assert 0 == code, the_stderr.readlines() - - all_lines = the_stdout.readlines() - return "".join(all_lines) - finally: - the_stdout.close() - the_stderr.close() - -def test_query_compiler_filter(): - # no --instruction-set specified: provide whatever was the 'first' filter. - assert exec_main(['--simulate', - '--package', 'com.google.android.apps.maps']) == \ - "speed-profile unknown arm64\n" - - # specifying an instruction set finds the exact compiler filter match. - assert exec_main(['--simulate', - '--package', 'com.google.android.apps.maps', - '--instruction-set', 'arm64']) == \ - "speed-profile unknown arm64\n" - - assert exec_main(['--simulate', - '--package', 'com.google.android.apps.maps', - '--instruction-set', 'arm']) == \ - "speed first-boot arm\n" - - assert exec_main(['--simulate', - '--debug', - '--package', 'com.google.android.apps.maps', - '--instruction-set', 'x86']) == \ - "quicken install x86\n" - -if __name__ == '__main__': - pytest.main() diff --git a/startop/scripts/app_startup/run_app_with_prefetch b/startop/scripts/app_startup/run_app_with_prefetch deleted file mode 100755 index 31f625334b1e..000000000000 --- a/startop/scripts/app_startup/run_app_with_prefetch +++ /dev/null @@ -1,487 +0,0 @@ -#!/bin/bash -# -# Copyright 2018, 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. - -usage() { - cat <<EOF -Usage: run_app_with_prefetch --package <name> [OPTIONS]... - - -p, --package <name> package of the app to test - -a, --activity <name> activity to use - -h, --help usage information (this) - -v, --verbose enable extra verbose printing - -i, --input <file> trace file protobuf (default 'TraceFile.pb') - -r, --readahead <mode> cold, warm, fadvise, mlock (default 'warm') - -w, --when <when> aot or jit (default 'jit') - -c, --count <count> how many times to run (default 1) - -s, --sleep <sec> how long to sleep after readahead - -t, --timeout <sec> how many seconds to timeout in between each app run (default 10) - -o, --output <file.csv> what file to write the performance results into as csv (default stdout) -EOF -} - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -source "$DIR/../iorap/common" - -report_fully_drawn="n" -needs_trace_file="n" -input_file="" -package="" -mode='warm' -count=2 -sleep_time=2 -timeout=10 -output="" # stdout by default -when="jit" -parse_arguments() { - while [[ $# -gt 0 ]]; do - case "$1" in - -h|--help) - usage - exit 0 - ;; - -p|--package) - package="$2" - shift - ;; - -a|--activity) - activity="$2" - shift - ;; - -i|--input) - input_file="$2" - shift - ;; - -v|--verbose) - export verbose="y" - ;; - -r|--readahead) - mode="$2" - shift - ;; - -rfd|--reportfullydrawn) - report_fully_drawn="y" - shift - ;; - -c|--count) - count="$2" - ((count+=1)) - shift - ;; - -s|--sleep) - sleep_time="$2" - shift - ;; - -t|--timeout) - timeout="$2" - shift - ;; - -o|--output) - output="$2" - shift - ;; - -w|--when) - when="$2" - shift - ;; - --compiler-filter) - compiler_filter="$2" - shift - ;; - *) - echo "Invalid argument: $1" >&2 - exit 1 - esac - shift - done - - if [[ $when == "aot" ]]; then - # TODO: re-implement aot later for experimenting. - echo "Error: --when $when is unsupported" >&2 - exit 1 - elif [[ $when != "jit" ]]; then - echo "Error: --when must be one of (aot jit)." >&2 - exit 1 - fi -} - -echo_to_output_file() { - if [[ "x$output" != x ]]; then - echo "$@" >> $output - fi - # Always echo to stdout as well. - echo "$@" -} - -find_package_path() { - local pkg="$1" - - res="$(adb shell find "/data/app/$pkg"-'*' -maxdepth 0 2> /dev/null)" - if [[ -z $res ]]; then - res="$(adb shell find "/system/app/$pkg"-'*' -maxdepth 0 2> /dev/null)" - fi - echo "$res" -} - -# Main entry point -if [[ $# -eq 0 ]]; then - usage - exit 1 -else - parse_arguments "$@" - - # if we do not have have package exit early with an error - [[ "$package" == "" ]] && echo "--package not specified" 1>&2 && exit 1 - - if [[ $mode != "cold" && $mode != "warm" ]]; then - needs_trace_file="y" - if [[ -z "$input_file" ]] || ! [[ -f $input_file ]]; then - echo "--input not specified" 1>&2 - exit 1 - fi - fi - - if [[ "$activity" == "" ]]; then - activity="$(get_activity_name "$package")" - if [[ "$activity" == "" ]]; then - echo "Activity name could not be found, invalid package name?" 1>&2 - exit 1 - else - verbose_print "Activity name inferred: " "$activity" - fi - fi -fi - -adb root > /dev/null - -if [[ ($when == jit) || ($when == aot) ]] && [[ "$(adb shell getenforce)" != "Permissive" ]]; then - echo "Disable selinux permissions and restart framework." - adb shell setenforce 0 - adb shell stop - adb shell start - adb wait-for-device -fi - -# TODO: set performance governor etc, preferrably only once -# before every single app run. - -# Kill everything before running. -remote_pkill "$package" -sleep 1 - -timings_array=() - -package_path="$(find_package_path "$package")" -if [[ $? -ne 0 ]]; then - echo "Failed to detect package path for '$package'" >&2 - exit 1 -fi -verbose_print "Package was in path '$package_path'" - -application_trace_file_path="$package_path/TraceFile.pb" -trace_file_directory="$package_path" -if [[ $needs_trace_file == y ]]; then - # system server always passes down the package path in a hardcoded spot. - if [[ $when == "jit" ]]; then - if ! iorapd_compiler_install_trace_file "$package" "$activity" "$input_file"; then - echo "Error: Failed to install compiled TraceFile.pb for '$package/$activity'" >&2 - exit 1 - fi - keep_application_trace_file="y" - else - echo "TODO: --readahead=aot is non-functional and needs to be fixed." >&2 - exit 1 - # otherwise use a temporary directory to get normal non-jit behavior. - trace_file_directory="/data/local/tmp/prefetch/$package" - adb shell mkdir -p "$trace_file_directory" - verbose_print adb push "$input_file" "$trace_file_directory/TraceFile.pb" - adb push "$input_file" "$trace_file_directory/TraceFile.pb" - fi -fi - -# Everything other than JIT: remove the trace file, -# otherwise system server activity hints will kick in -# and the new just-in-time app pre-warmup will happen. -if [[ $keep_application_trace_file == "n" ]]; then - iorapd_compiler_purge_trace_file "$package" "$activity" -fi - -# Perform AOT readahead/pinning/etc when an application is about to be launched. -# For JIT readahead, we allow the system to handle it itself (this is a no-op). -# -# For warm, cold, etc modes which don't need readahead this is always a no-op. -perform_aot() { - local the_when="$1" # user: aot, jit - local the_mode="$2" # warm, cold, fadvise, mlock, etc. - - # iorapd readahead for jit+(mlock/fadvise) - if [[ $the_when == "jit" && $the_mode != 'warm' && $the_mode != 'cold' ]]; then - iorapd_readahead_enable - return 0 - fi - - if [[ $the_when != "aot" ]]; then - # TODO: just in time implementation.. should probably use system server. - return 0 - fi - - # any non-warm/non-cold modes should use the iorap-activity-hint wrapper script. - if [[ $the_mode != 'warm' && $the_mode != 'cold' ]]; then - - # TODO: add activity_hint_sender.exp - verbose_print "starting with package=$package package_path=$trace_file_directory" - coproc hint_sender_fd { $ANDROID_BUILD_TOP/system/iorap/src/sh/activity_hint_sender.exp "$package" "$trace_file_directory" "$the_mode"; } - hint_sender_pid=$! - verbose_print "Activity hint sender began" - - notification_success="n" - while read -r -u "${hint_sender_fd[0]}" hint_sender_output; do - verbose_print "$hint_sender_output" - if [[ "$hint_sender_output" == "Press any key to send completed event..."* ]]; then - verbose_print "WE DID SEE NOTIFICATION SUCCESS." - notification_success='y' - # Give it some time to actually perform the readaheads. - sleep $sleep_time - break - fi - done - - if [[ $notification_success == 'n' ]]; then - echo "[FATAL] Activity hint notification failed." 1>&2 - exit 1 - fi - fi -} - -# Perform cleanup at the end of each loop iteration. -perform_post_launch_cleanup() { - local the_when="$1" # user: aot, jit - local the_mode="$2" # warm, cold, fadvise, mlock, etc. - local logcat_timestamp="$3" # timestamp from before am start. - local res - - if [[ $the_when != "aot" ]]; then - if [[ $the_mode != 'warm' && $the_mode != 'cold' ]]; then - # Validate that readahead completes. - # If this fails for some reason, then this will also discard the timing of the run. - iorapd_readahead_wait_until_finished "$package" "$activity" "$logcat_timestamp" "$timeout" - res=$? - - iorapd_readahead_disable - - return $res - fi - # Don't need to do anything for warm or cold. - return 0 - fi - - # any non-warm/non-cold modes should use the iorap-activity-hint wrapper script. - if [[ $the_mode != 'warm' && $the_mode != 'cold' ]]; then - # Clean up the hint sender by telling it that the launch was completed, - # and to shutdown the watcher. - echo "Done\n" >&"${hint_sender_fd[1]}" - - while read -r -u "${hint_sender_fd[0]}" hint_sender_output; do - verbose_print "$hint_sender_output" - done - - wait $hint_sender_pid - fi -} - -configure_compiler_filter() { - local the_compiler_filter="$1" - local the_package="$2" - local the_activity="$3" - - if [[ -z $the_compiler_filter ]]; then - verbose_print "No --compiler-filter specified, don't need to force it." - return 0 - fi - - local current_compiler_filter_info="$("$DIR"/query_compiler_filter.py --package "$the_package")" - local res=$? - if [[ $res -ne 0 ]]; then - return $res - fi - - local current_compiler_filter - local current_reason - local current_isa - read current_compiler_filter current_reason current_isa <<< "$current_compiler_filter_info" - - verbose_print "Compiler Filter="$current_compiler_filter "Reason="$current_reason "Isa="$current_isa - - # Don't trust reasons that aren't 'unknown' because that means we didn't manually force the compilation filter. - # (e.g. if any automatic system-triggered compilations are not unknown). - if [[ $current_reason != "unknown" ]] || [[ $current_compiler_filter != $the_compiler_filter ]]; then - verbose_print "$DIR"/force_compiler_filter --compiler-filter "$the_compiler_filter" --package "$the_package" --activity "$the_activity" - "$DIR"/force_compiler_filter --compiler-filter "$the_compiler_filter" --package "$the_package" --activity "$the_activity" - res=$? - else - verbose_print "Queried compiler-filter matched requested compiler-filter, skip forcing." - res=0 - fi - - return $res -} - -# Ensure the APK is currently compiled with whatever we passed in via --compiler-filter. -# No-op if this option was not passed in. -configure_compiler_filter "$compiler_filter" "$package" "$activity" || exit 1 - -# convert 'a=b\nc=d\ne=f\n...' into 'b,d,f,...' -parse_metrics_output_string() { - # single string with newlines in it. - local input="$1" - - local metric_name - local metric_value - local rest - - local all_metrics=() - - # (n1=v1 n2=v2 n3=v3 ...) - readarray -t all_metrics <<< "$input" - - local kv_pair=() - local i - - for i in "${all_metrics[@]}" - do - verbose_print "parse_metrics_output: element '$i'" - # name=value - - IFS='=' read -r metric_name metric_value rest <<< "$i" - - verbose_print "parse_metrics_output: metric_value '$metric_value'" - - # (value1 value2 value3 ...) - all_metrics+=(${metric_value}) - done - - # "value1,value2,value3,..." - join_by ',' "${all_metrics[@]}" -} - -# convert 'a=b\nc=d\ne=f\n... into b,d,f,...' -parse_metrics_output() { - local metric_name - local metric_value - local rest - - local all_metrics=() - - while IFS='=' read -r metric_name metric_value rest; do - verbose_print "metric: $metric_name, value: $metric_value; rest: $rest" - all_metrics+=($metric_value) - done - - join_by ',' "${all_metrics[@]}" -} - -# convert 'a=b\nc=d\ne=f\n... into b,d,f,...' -parse_metrics_header() { - local metric_name - local metric_value - local rest - - local all_metrics=() - - while IFS='=' read -r metric_name metric_value rest; do - verbose_print "metric: $metric_name, value: $metric_value; rest: $rest" - all_metrics+=($metric_name) - done - - join_by ',' "${all_metrics[@]}" -} - -if [[ $report_fully_drawn == y ]]; then - metrics_header="$("$DIR/parse_metrics" --package "$package" --activity "$activity" --simulate --reportfullydrawn | parse_metrics_header)" -else - metrics_header="$("$DIR/parse_metrics" --package "$package" --activity "$activity" --simulate | parse_metrics_header)" -fi - -# TODO: This loop logic could probably be moved into app_startup_runner.py -for ((i=0;i<count;++i)) do - verbose_print "==========================================" - verbose_print "==== ITERATION $i ====" - verbose_print "==========================================" - if [[ $mode != "warm" ]]; then - # The package must be killed **before** we drop caches, otherwise pages will stay resident. - verbose_print "Kill package for non-warm start." - remote_pkill "$package" - verbose_print "Drop caches for non-warm start." - # Drop all caches to get cold starts. - adb shell "echo 3 > /proc/sys/vm/drop_caches" - fi - - perform_aot "$when" "$mode" - - verbose_print "Running with timeout $timeout" - - pre_launch_timestamp="$(logcat_save_timestamp)" - - # TODO: multiple metrics output. - -if [[ $report_fully_drawn == y ]]; then - total_time="$(timeout $timeout "$DIR/launch_application" "$package" "$activity" | "$DIR/parse_metrics" --package "$package" --activity "$activity" --timestamp "$pre_launch_timestamp" --reportfullydrawn | parse_metrics_output)" -else - total_time="$(timeout $timeout "$DIR/launch_application" "$package" "$activity" | "$DIR/parse_metrics" --package "$package" --activity "$activity" --timestamp "$pre_launch_timestamp" | parse_metrics_output)" -fi - - if [[ $? -ne 0 ]]; then - echo "WARNING: Skip bad result, try iteration again." >&2 - ((i=i-1)) - continue - fi - - perform_post_launch_cleanup "$when" "$mode" "$pre_launch_timestamp" - - if [[ $? -ne 0 ]]; then - echo "WARNING: Skip bad cleanup, try iteration again." >&2 - ((i=i-1)) - continue - fi - - echo "Iteration $i. Total time was: $total_time" - - timings_array+=("$total_time") -done - -# drop the first result which is usually garbage. -timings_array=("${timings_array[@]:1}") - -# Print the CSV header first. -echo_to_output_file "$metrics_header" - -# Print out interactive/debugging timings and averages. -# Other scripts should use the --output flag and parse the CSV. -for tim in "${timings_array[@]}"; do - echo_to_output_file "$tim" -done - -if [[ x$output != x ]]; then - echo " Saved results to '$output'" -fi - -if [[ $needs_trace_file == y ]] ; then - iorapd_compiler_purge_trace_file "$package" "$activity" -fi - -# Kill the process to ensure AM isn't keeping it around. -remote_pkill "$package" - -exit 0 diff --git a/startop/scripts/app_startup/run_app_with_prefetch.py b/startop/scripts/app_startup/run_app_with_prefetch.py deleted file mode 100755 index 2f1eff2c41f6..000000000000 --- a/startop/scripts/app_startup/run_app_with_prefetch.py +++ /dev/null @@ -1,230 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. - -"""Runner of one test given a setting. - -Run app and gather the measurement in a certain configuration. -Print the result to stdout. -See --help for more details. - -Sample usage: - $> ./python run_app_with_prefetch.py -p com.android.settings -a - com.android.settings.Settings -r fadvise -i input - -""" - -import argparse -import os -import sys -import time -from typing import List, Tuple, Optional - -# local imports -import lib.adb_utils as adb_utils -from lib.app_runner import AppRunner, AppRunnerListener - -# global variables -DIR = os.path.abspath(os.path.dirname(__file__)) - -sys.path.append(os.path.dirname(DIR)) -import lib.print_utils as print_utils -import lib.cmd_utils as cmd_utils -import iorap.lib.iorapd_utils as iorapd_utils - -class PrefetchAppRunner(AppRunnerListener): - def __init__(self, - package: str, - activity: Optional[str], - readahead: str, - compiler_filter: Optional[str], - timeout: Optional[int], - simulate: bool, - debug: bool, - input:Optional[str], - **kwargs): - self.app_runner = AppRunner(package, - activity, - compiler_filter, - timeout, - simulate) - self.app_runner.add_callbacks(self) - - self.simulate = simulate - self.readahead = readahead - self.debug = debug - self.input = input - print_utils.DEBUG = self.debug - cmd_utils.SIMULATE = self.simulate - - - def run(self) -> Optional[List[Tuple[str]]]: - """Runs an app. - - Returns: - A list of (metric, value) tuples. - """ - return self.app_runner.run() - - def preprocess(self): - passed = self.validate_options() - if not passed: - return - - # Sets up adb environment. - adb_utils.root() - adb_utils.disable_selinux() - time.sleep(1) - - # Kill any existing process of this app - adb_utils.pkill(self.app_runner.package) - - if self.readahead != 'warm': - print_utils.debug_print('Drop caches for non-warm start.') - # Drop all caches to get cold starts. - adb_utils.vm_drop_cache() - - if self.readahead != 'warm' and self.readahead != 'cold': - iorapd_utils.enable_iorapd_readahead() - - def postprocess(self, pre_launch_timestamp: str): - passed = self._perform_post_launch_cleanup(pre_launch_timestamp) - if not passed and not self.app_runner.simulate: - print_utils.error_print('Cannot perform post launch cleanup!') - return None - - # Kill any existing process of this app - adb_utils.pkill(self.app_runner.package) - - def _perform_post_launch_cleanup(self, logcat_timestamp: str) -> bool: - """Performs cleanup at the end of each loop iteration. - - Returns: - A bool indicates whether the cleanup succeeds or not. - """ - if self.readahead != 'warm' and self.readahead != 'cold': - passed = iorapd_utils.wait_for_iorapd_finish(self.app_runner.package, - self.app_runner.activity, - self.app_runner.timeout, - self.debug, - logcat_timestamp) - - if not passed: - return passed - - return iorapd_utils.disable_iorapd_readahead() - - # Don't need to do anything for warm or cold. - return True - - def metrics_selector(self, am_start_output: str, - pre_launch_timestamp: str) -> str: - """Parses the metric after app startup by reading from logcat in a blocking - manner until all metrics have been found". - - Returns: - the total time and displayed time of app startup. - For example: "TotalTime=123\nDisplayedTime=121 - """ - total_time = AppRunner.parse_total_time(am_start_output) - displayed_time = adb_utils.blocking_wait_for_logcat_displayed_time( - pre_launch_timestamp, self.app_runner.package, self.app_runner.timeout) - - return 'TotalTime={}\nDisplayedTime={}'.format(total_time, displayed_time) - - def validate_options(self) -> bool: - """Validates the activity and trace file if needed. - - Returns: - A bool indicates whether the activity is valid. - """ - needs_trace_file = self.readahead != 'cold' and self.readahead != 'warm' - if needs_trace_file and (self.input is None or - not os.path.exists(self.input)): - print_utils.error_print('--input not specified!') - return False - - # Install necessary trace file. This must be after the activity checking. - if needs_trace_file: - passed = iorapd_utils.iorapd_compiler_install_trace_file( - self.app_runner.package, self.app_runner.activity, self.input) - if not cmd_utils.SIMULATE and not passed: - print_utils.error_print('Failed to install compiled TraceFile.pb for ' - '"{}/{}"'. - format(self.app_runner.package, - self.app_runner.activity)) - return False - - return True - - - -def parse_options(argv: List[str] = None): - """Parses command line arguments and return an argparse Namespace object.""" - parser = argparse.ArgumentParser( - description='Run an Android application once and measure startup time.' - ) - - required_named = parser.add_argument_group('required named arguments') - required_named.add_argument('-p', '--package', action='store', dest='package', - help='package of the application', required=True) - - # optional arguments - # use a group here to get the required arguments to appear 'above' the - # optional arguments in help. - optional_named = parser.add_argument_group('optional named arguments') - optional_named.add_argument('-a', '--activity', action='store', - dest='activity', - help='launch activity of the application') - optional_named.add_argument('-s', '--simulate', dest='simulate', - action='store_true', - help='simulate the process without executing ' - 'any shell commands') - optional_named.add_argument('-d', '--debug', dest='debug', - action='store_true', - help='Add extra debugging output') - optional_named.add_argument('-i', '--input', action='store', dest='input', - help='perfetto trace file protobuf', - default='TraceFile.pb') - optional_named.add_argument('-r', '--readahead', action='store', - dest='readahead', - help='which readahead mode to use', - default='cold', - choices=('warm', 'cold', 'mlock', 'fadvise')) - optional_named.add_argument('-t', '--timeout', dest='timeout', action='store', - type=int, - help='Timeout after this many seconds when ' - 'executing a single run.', - default=10) - optional_named.add_argument('--compiler-filter', dest='compiler_filter', - action='store', - help='Which compiler filter to use.', - default=None) - - return parser.parse_args(argv) - -def main(): - opts = parse_options() - runner = PrefetchAppRunner(**vars(opts)) - result = runner.run() - - if result is None: - return 1 - - print(result) - return 0 - -if __name__ == '__main__': - sys.exit(main()) diff --git a/startop/scripts/app_startup/run_app_with_prefetch_test.py b/startop/scripts/app_startup/run_app_with_prefetch_test.py deleted file mode 100644 index 8a588e4463e9..000000000000 --- a/startop/scripts/app_startup/run_app_with_prefetch_test.py +++ /dev/null @@ -1,286 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. -# -"""Unit tests for the run_app_with_prefetch_test.py script. - -Install: - $> sudo apt-get install python3-pytest ## OR - $> pip install -U pytest -See also https://docs.pytest.org/en/latest/getting-started.html - -Usage: - $> ./run_app_with_prefetch_test.py - $> pytest run_app_with_prefetch_test.py - $> python -m pytest run_app_with_prefetch_test.py - -See also https://docs.pytest.org/en/latest/usage.html -""" - -import io -import os -import shlex -import sys -import tempfile -# global imports -from contextlib import contextmanager - -# pip imports -import pytest -# local imports -import run_app_with_prefetch as runner -from mock import call, patch, Mock - -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -from app_startup.lib.app_runner import AppRunner -# -# Argument Parsing Helpers -# - -@contextmanager -def ignore_stdout_stderr(): - """Ignore stdout/stderr output for duration of this context.""" - old_stdout = sys.stdout - old_stderr = sys.stderr - sys.stdout = io.StringIO() - sys.stderr = io.StringIO() - try: - yield - finally: - sys.stdout = old_stdout - sys.stderr = old_stderr - -@contextmanager -def argparse_bad_argument(msg): - """Asserts that a SystemExit is raised when executing this context. - - If the assertion fails, print the message 'msg'. - """ - with pytest.raises(SystemExit, message=msg): - with ignore_stdout_stderr(): - yield - -def assert_bad_argument(args, msg): - """Asserts that the command line arguments in 'args' are malformed. - - Prints 'msg' if the assertion fails. - """ - with argparse_bad_argument(msg): - parse_args(args) - -def parse_args(args): - """ - :param args: command-line like arguments as a single string - :return: dictionary of parsed key/values - """ - # "-a b -c d" => ['-a', 'b', '-c', 'd'] - return vars(runner.parse_options(shlex.split(args))) - -def default_dict_for_parsed_args(**kwargs): - """Combines it with all of the "optional" parameters' default values.""" - d = { - 'readahead': 'cold', - 'simulate': None, - 'simulate': False, - 'debug': False, - 'input': 'TraceFile.pb', - 'timeout': 10, - 'compiler_filter': None, - 'activity': None - } - d.update(kwargs) - return d - -def default_mock_dict_for_parsed_args(include_optional=True, **kwargs): - """Combines default dict with all optional parameters with some mock required - parameters. - """ - d = {'package': 'com.fake.package'} - if include_optional: - d.update(default_dict_for_parsed_args()) - d.update(kwargs) - return d - -def parse_optional_args(str): - """ - Parses an argument string which already includes all the required arguments - in default_mock_dict_for_parsed_args. - """ - req = '--package com.fake.package' - return parse_args('%s %s' % (req, str)) - -def test_argparse(): - # missing arguments - assert_bad_argument('', '-p are required') - - # required arguments are parsed correctly - ad = default_dict_for_parsed_args # assert dict - assert parse_args('--package xyz') == ad(package='xyz') - - assert parse_args('-p xyz') == ad(package='xyz') - - assert parse_args('-p xyz -s') == ad(package='xyz', simulate=True) - assert parse_args('-p xyz --simulate') == ad(package='xyz', simulate=True) - - # optional arguments are parsed correctly. - mad = default_mock_dict_for_parsed_args # mock assert dict - assert parse_optional_args('--input trace.pb') == mad(input='trace.pb') - - assert parse_optional_args('--compiler-filter speed') == \ - mad(compiler_filter='speed') - - assert parse_optional_args('-d') == mad(debug=True) - assert parse_optional_args('--debug') == mad(debug=True) - - assert parse_optional_args('--timeout 123') == mad(timeout=123) - assert parse_optional_args('-t 456') == mad(timeout=456) - - assert parse_optional_args('-r warm') == mad(readahead='warm') - assert parse_optional_args('--readahead warm') == mad(readahead='warm') - - assert parse_optional_args('-a act') == mad(activity='act') - assert parse_optional_args('--activity act') == mad(activity='act') - -def test_main(): - args = '--package com.fake.package --activity act -s' - opts = runner.parse_options(shlex.split(args)) - result = runner.PrefetchAppRunner(**vars(opts)).run() - assert result == [('TotalTime', '123')] - -def _mocked_run_shell_command(*args, **kwargs): - if args[0] == 'adb shell ps | grep "music" | awk \'{print $2;}\'': - return (True, '9999') - else: - return (True, '') - -def test_preprocess_no_cache_drop(): - with patch('lib.cmd_utils.run_shell_command', - new_callable=Mock) as mock_run_shell_command: - mock_run_shell_command.side_effect = _mocked_run_shell_command - prefetch_app_runner = runner.PrefetchAppRunner(package='music', - activity='MainActivity', - readahead='warm', - compiler_filter=None, - timeout=None, - simulate=False, - debug=False, - input=None) - - prefetch_app_runner.preprocess() - - calls = [call('adb root'), - call('adb shell "getenforce"'), - call('adb shell "setenforce 0"'), - call('adb shell "stop"'), - call('adb shell "start"'), - call('adb wait-for-device'), - call('adb shell ps | grep "music" | awk \'{print $2;}\''), - call('adb shell "kill 9999"')] - mock_run_shell_command.assert_has_calls(calls) - -def test_preprocess_with_cache_drop(): - with patch('lib.cmd_utils.run_shell_command', - new_callable=Mock) as mock_run_shell_command: - mock_run_shell_command.side_effect = _mocked_run_shell_command - prefetch_app_runner = runner.PrefetchAppRunner(package='music', - activity='MainActivity', - readahead='cold', - compiler_filter=None, - timeout=None, - simulate=False, - debug=False, - input=None) - - prefetch_app_runner.preprocess() - - calls = [call('adb root'), - call('adb shell "getenforce"'), - call('adb shell "setenforce 0"'), - call('adb shell "stop"'), - call('adb shell "start"'), - call('adb wait-for-device'), - call('adb shell ps | grep "music" | awk \'{print $2;}\''), - call('adb shell "kill 9999"'), - call('adb shell "echo 3 > /proc/sys/vm/drop_caches"')] - mock_run_shell_command.assert_has_calls(calls) - -def test_preprocess_with_cache_drop_and_iorapd_enabled(): - with patch('lib.cmd_utils.run_shell_command', - new_callable=Mock) as mock_run_shell_command: - mock_run_shell_command.side_effect = _mocked_run_shell_command - - with tempfile.NamedTemporaryFile() as input: - prefetch_app_runner = runner.PrefetchAppRunner(package='music', - activity='MainActivity', - readahead='fadvise', - compiler_filter=None, - timeout=None, - simulate=False, - debug=False, - input=input.name) - - prefetch_app_runner.preprocess() - - calls = [call('adb root'), - call('adb shell "getenforce"'), - call('adb shell "setenforce 0"'), - call('adb shell "stop"'), - call('adb shell "start"'), - call('adb wait-for-device'), - call( - 'adb shell ps | grep "music" | awk \'{print $2;}\''), - call('adb shell "kill 9999"'), - call('adb shell "echo 3 > /proc/sys/vm/drop_caches"'), - call('bash -c "source {}; iorapd_readahead_enable"'. - format(AppRunner.IORAP_COMMON_BASH_SCRIPT))] - mock_run_shell_command.assert_has_calls(calls) - -@patch('lib.adb_utils.blocking_wait_for_logcat_displayed_time') -@patch('lib.cmd_utils.run_shell_command') -def test_postprocess_with_launch_cleanup( - mock_run_shell_command, - mock_blocking_wait_for_logcat_displayed_time): - mock_run_shell_command.side_effect = _mocked_run_shell_command - mock_blocking_wait_for_logcat_displayed_time.return_value = 123 - - with tempfile.NamedTemporaryFile() as input: - prefetch_app_runner = runner.PrefetchAppRunner(package='music', - activity='MainActivity', - readahead='fadvise', - compiler_filter=None, - timeout=10, - simulate=False, - debug=False, - input=input.name) - - prefetch_app_runner.postprocess('2019-07-02 23:20:06.972674825') - - calls = [ - call('bash -c "source {script_path}; ' - 'iorapd_readahead_wait_until_finished ' - '\'{package}\' \'{activity}\' \'{timestamp}\' \'{timeout}\'"'. - format(timeout=10, - package='music', - activity='MainActivity', - timestamp='2019-07-02 23:20:06.972674825', - script_path=AppRunner.IORAP_COMMON_BASH_SCRIPT)), - call('bash -c "source {}; iorapd_readahead_disable"'. - format(AppRunner.IORAP_COMMON_BASH_SCRIPT)), - call('adb shell ps | grep "music" | awk \'{print $2;}\''), - call('adb shell "kill 9999"')] - mock_run_shell_command.assert_has_calls(calls) - -if __name__ == '__main__': - pytest.main() diff --git a/startop/scripts/app_startup/unlock_screen b/startop/scripts/app_startup/unlock_screen deleted file mode 100755 index 478294c9f35d..000000000000 --- a/startop/scripts/app_startup/unlock_screen +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# -# Copyright 2018, 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. - -# This turns the screen on if it's off. -# If it's on it does nothing unless its on the home screen, in which case it opens up some background -# menu. -# -# However, this menu is ignored because "am start" commands still work as expected. -adb shell input keyevent MENU diff --git a/startop/scripts/iorap/analyze_prefetch_file.py b/startop/scripts/iorap/analyze_prefetch_file.py deleted file mode 100755 index 343cd54b7174..000000000000 --- a/startop/scripts/iorap/analyze_prefetch_file.py +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2020, 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. - -import argparse -import os -import sys -from typing import Dict, List, NamedTuple, Tuple - -DIR = os.path.abspath(os.path.dirname(__file__)) -sys.path.append(os.path.dirname(DIR)) # framework/base/startop/script -import lib.print_utils as print_utils - -# Include generated protos. -dir_name = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(dir_name + "/generated") - -from TraceFile_pb2 import * - -def parse_options(argv: List[str] = None): - """Parses command line arguments and returns an argparse Namespace object.""" - parser = argparse.ArgumentParser(description="Analyze compiled_trace iorap protos.") - required_named = parser.add_argument_group('required named arguments') - - required_named.add_argument('-i', dest='input', metavar='FILE', - help='Read protobuf file as input') - - optional_named = parser.add_argument_group('optional named arguments') - - optional_named.add_argument('-up', dest='upper_percent', type=float, - default=95.0, - help='Only show the top-most entries up to this value.') - - optional_named.add_argument('-r', dest='raw', action='store_true', - help='Output entire raw file.') - optional_named.add_argument('-o', dest='output', - help='The results are stored into the output file') - optional_named.add_argument('-d', dest='debug', action='store_true' - , help='Activity of the app to be compiled') - - return parser.parse_args(argv) - -def open_iorap_prefetch_file(file_path: str) -> TraceFile: - with open(file_path, "rb") as f: - tf = TraceFile() - tf.ParseFromString(f.read()) - return tf - -def print_stats_summary(trace_file: TraceFile, upper_percent): - tf_dict = convert_to_dict(trace_file) - print_utils.debug_print(tf_dict) - - total_length = 0 - summaries = [] - for name, entries_list in tf_dict.items(): - summary = entries_sum(entries_list) - summaries.append(summary) - - total_length += summary.length - - # Sort by length - summaries.sort(reverse=True, key=lambda s: s.length) - - percent_sum = 0.0 - skipped_entries = 0 - - print("===========================================") - print("Total length: {:,} bytes".format(total_length)) - print("Displayed upper percent: {:0.2f}%".format(upper_percent)) - print("===========================================") - print("") - print("name,length,percent_of_total,upper_percent") - for sum in summaries: - percent_of_total = (sum.length * 1.0) / (total_length * 1.0) * 100.0 - - percent_sum += percent_of_total - - if percent_sum > upper_percent: - skipped_entries = skipped_entries + 1 - continue - - #print("%s,%d,%.2f%%" %(sum.name, sum.length, percent_of_total)) - print("{:s},{:d},{:0.2f}%,{:0.2f}%".format(sum.name, sum.length, percent_of_total, percent_sum)) - - if skipped_entries > 0: - print("[WARNING] Skipped {:d} entries, use -up=100 to show everything".format(skipped_entries)) - - pass - -class FileEntry(NamedTuple): - id: int - name: str - offset: int - length: int - -class FileEntrySummary(NamedTuple): - name: str - length: int - -def entries_sum(entries: List[FileEntry]) -> FileEntrySummary: - if not entries: - return None - - summary = FileEntrySummary(name=entries[0].name, length=0) - for entry in entries: - summary = FileEntrySummary(summary.name, summary.length + entry.length) - - return summary - -def convert_to_dict(trace_file: TraceFile) -> Dict[str, FileEntry]: - trace_file_index = trace_file.index - - # entries.id -> entry.file_name - entries_map = {} - - index_entries = trace_file_index.entries - for entry in index_entries: - entries_map[entry.id] = entry.file_name - - final_map = {} - - file_entries_map = {} - file_entries = trace_file.list.entries - for entry in file_entries: - print_utils.debug_print(entry) - - lst = file_entries_map.get(entry.index_id, []) - file_entries_map[entry.index_id] = lst - - file_name = entries_map[entry.index_id] - file_entry = \ - FileEntry(id=entry.index_id, name=file_name, offset=entry.file_offset, length=entry.file_length) - - lst.append(file_entry) - - final_map[file_name] = lst - - return final_map - -def main(argv: List[str]) -> int: - opts = parse_options(argv[1:]) - if opts.debug: - print_utils.DEBUG = opts.debug - print_utils.debug_print(opts) - - prefetch_file = open_iorap_prefetch_file(opts.input) - - if opts.raw: - print(prefetch_file) - - print_stats_summary(prefetch_file, opts.upper_percent) - - return 0 - -if __name__ == '__main__': - sys.exit(main(sys.argv)) diff --git a/startop/scripts/iorap/collector b/startop/scripts/iorap/collector deleted file mode 100755 index 3dc080a5ac9c..000000000000 --- a/startop/scripts/iorap/collector +++ /dev/null @@ -1,403 +0,0 @@ -#!/bin/bash -# -# Copyright 2017, 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. - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -APP_STARTUP_DIR="$DIR/../app_startup/" -source "$DIR/common" - -usage() { - cat <<EOF -Usage: collector [OPTIONS]... - -Runs an application, causes an iorap trace to be collected for it, and then invokes the iorap -compiler to generate a TraceFile.pb. - - -p, --package package of the app to test - -a, --activity activity of the app to test - -h, --help usage information (this) - -v, --verbose enable extra verbose printing - -i, --inodes path to inodes file (system/extras/pagecache/pagecache.py -d inodes) - -b, --trace_buffer_size how big to make trace buffer size (default 32768) - -w, --wait_time how long to run systrace for (default 10) in seconds - -c, --compiler-filter override the compilation filter if set (default none) - -o, --output output trace file protobuf (default 'TraceFile.pb') -EOF -} - - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -trace_buffer_size=32768 -wait_time=10 -comp_filter="" -output_dest="TraceFile.pb" - -parse_arguments() { - while [[ $# -gt 0 ]]; do - case "$1" in - -a|--activity) - activity="$2" - shift - ;; - -h|--help) - usage - exit 0 - ;; - -p|--package) - package="$2" - shift - ;; - -i|--inodes) - inodes="$2" - shift - ;; - -b|--trace_buffer_size) - trace_buffer_size="$2" - shift - ;; - -w|--wait_time) - wait_time="$2" - shift - ;; - -c|--compiler-filter) - comp_filter="$2" - shift - ;; - -o|--output) - output_dest="$2" - shift - ;; - -v|--verbose) - verbose="y" - ;; - esac - shift - done -} - -remote_pidof() { - local procname="$1" - adb shell ps | grep "$procname" | awk '{print $2;}' -} - -remote_pkill() { - local procname="$1" - shift - - local the_pids=$(remote_pidof "$procname") - local pid - - for pid in $the_pids; do - verbose_print adb shell kill "$@" "$pid" - adb shell kill "$@" "$pid" - done -} - -force_package_compilation() { - local arg_comp_filter="$1" - local arg_package="$2" - - if [[ $arg_comp_filter == speed-profile ]]; then - # Force the running app to dump its profiles to disk. - remote_pkill "$arg_package" -SIGUSR1 - sleep 1 # give some time for above to complete. - fi - - adb shell cmd package compile -m "$arg_comp_filter" -f "$arg_package" -} - -parse_package_dumpsys_line() { - local what_left="$1" - local what_right="$2" - local line="$3" - - if [[ $line == *${what_left}*${what_right}* ]]; then - found="${line#*$what_left}" - found="${found%$what_right*}" - echo "$found" - return 0 - fi - - return 1 -} - -parse_package_dumpsys_section() { - local what_left="$1" - local what_right="$2" - shift - local lines="$@" - - lines="${lines//$'\n'/}" - - local new_lines=() - - local current_line="" - local newline=n - local line - for line in "${lines[@]}"; do - if [[ $line == *: ]]; then - newline=y - current_line="" - new_lines+=("$current_line") - - parse_package_dumpsys_line "$what_left" "$what_right" "$current_line" && return 0 - else - # strip all spaces from the start - line="${line//$' '/}" - current_line+="$line" - #prepend to current line - fi - done - [[ "$current_line" != "" ]] && new_lines+=("$current_line") - - parse_package_dumpsys_line "$what_left" "$what_right" "$current_line" && return 0 - - return 1 -} - -parse_package_compilation() { - local pkg="$1" -# [com.google.android.apps.maps] - - local compilation_filter - local is_prebuilt - local isa - local etc - - local ret_code - - read compilation_filter is_prebuilt isa etc <<< "$("$APP_STARTUP_DIR"/query_compiler_filter.py --package "$pkg")" - ret_code=$? - - if [[ $ret_code -eq 0 && x$compilation_filter != x ]]; then - verbose_print "Package compilation info for $pkg was '$compilation_filter'" - echo "$compilation_filter" - return 0 - else - verbose_print "query failed ret code $ret_code filter=$compilation_filter" - fi - - return $ret_code -} - -# Main entry point -if [[ $# -eq 0 ]]; then - usage - exit 1 -else - parse_arguments "$@" - - # if we do not have have package exit early with an error - [[ "$package" == "" ]] && echo "--package not specified" 1>&2 && exit 1 - - if [[ -z "$inodes" ]] || ! [[ -f $inodes ]]; then - echo "--inodes not specified" 1>&2 - exit 1 - fi - - if [[ "$activity" == "" ]]; then - activity="$(get_activity_name "$package")" - if [[ "$activity" == "" ]]; then - echo "Activity name could not be found, invalid package name?" 1>&2 - exit 1 - else - verbose_print "Activity name inferred: " "$activity" - fi - fi -fi - -adb root > /dev/null - -if [[ "$(adb shell getenforce)" != "Permissive" ]]; then - adb shell setenforce 0 - adb shell stop - adb shell start - adb wait-for-device -fi - -compilation_was="$(parse_package_compilation "$package")" -if [[ $? -ne 0 ]]; then - echo "Could not determine package compilation filter; was this package installed?" >&2 - exit 1 -fi -verbose_print "Package compilation: $compilation_was" - -# Cannot downgrade (e.g. from speed-profile to quicken) without forceful recompilation. -# Forceful recompilation will recompile even if compilation filter was unchanged. -# Therefore avoid recompiling unless the filter is actually different than what we asked for. -if [[ "x$comp_filter" != "x" ]] && [[ "$compilation_was" != "$comp_filter" ]]; then - echo "Current compilation filter is '$compilation_was'; force recompile to '$comp_filter'" >&2 - #TODO: this matching seems hopelessly broken, it will always recompile. - - force_package_compilation "$comp_filter" "$package" -fi - -# Drop all caches prior to beginning a systrace, otherwise we won't record anything already in pagecache. -adb shell "echo 3 > /proc/sys/vm/drop_caches" - -trace_tmp_file="$(mktemp -t trace.XXXXXXXXX.html)" - -function finish { - [[ -f "$trace_tmp_file" ]] && rm "$trace_tmp_file" -} -trap finish EXIT - -launch_application_and_wait_for_trace() { - local package="$1" - local activity="$2" - local timeout=30 # seconds - - # Ensure application isn't running already. - remote_pkill "$package" - - # 5 second trace of Home screen causes - # a trace of the home screen. - # There is no way to abort the trace - # so just wait for it to complete instead. - sleep 30 - - local time_now="$(logcat_save_timestamp)" - local retcode=0 - - verbose_print "Drop caches for non-warm start." - # Drop all caches to get cold starts. - adb shell "echo 3 > /proc/sys/vm/drop_caches" - - verbose_print "now launching application" - # Launch an application - "$APP_STARTUP_DIR"/launch_application "$package" "$activity" - retcode=$? - if [[ $retcode -ne 0 ]]; then - echo "FATAL: Application launch failed." >&2 - return $retcode - fi - - # This blocks until 'am start' returns at which point the application is - # already to be considered "started" as the first frame has been drawn. - - # TODO: check for cold start w.r.t to activitymanager? - - # Wait for application to start from the point of view of ActivityTaskManager. - local pattern="ActivityTaskManager: Displayed $package" - logcat_wait_for_pattern "$timeout" "$time_now" "$pattern" - retcode=$? - if [[ $retcode -ne 0 ]]; then - echo "FATAL: Could not find '$pattern' in logcat." >&2 - return $retcode - fi - - # Wait for iorapd to finish writing out the perfetto traces for this app. - iorapd_perfetto_wait_for_app_trace "$package" "$activity" "$timeout" "$time_now" - retcode=$? - if [[ $retcode -ne 0 ]]; then - echo "FATAL: Could not save perfetto app trace file." >&2 - return $retcode - fi - - verbose_print "iorapd has finished collecting app trace file for $package/$activity" -} - -collector_main() { - # don't even bother trying to run anything until the screen is unlocked. - "$APP_STARTUP_DIR"/unlock_screen - - # Don't mutate state while iorapd is running. - iorapd_stop || return $? - - # Remove all existing metadata for a package/activity in iorapd. - iorapd_perfetto_purge_app_trace "$package" "$activity" || return $? - iorapd_compiler_purge_trace_file "$package" "$activity" || return $? - - iorapd_perfetto_enable || return $? - iorapd_readahead_disable || return $? - iorapd_start || return $? - - # Wait for perfetto trace to finished writing itself out. - launch_application_and_wait_for_trace "$package" "$activity" || return $? - - # Pull the perfetto trace for manual inspection. - iorapd_perfetto_pull_trace_file "$package" "$activity" "perfetto_trace.pb" - - # Compile the trace so that the next app run can use prefetching. - iorapd_compiler_for_app_trace "$package" "$activity" "$inodes" || return $? - - # Save TraceFile.pb to local file. - iorapd_compiler_pull_trace_file "$package" "$activity" "$output_dest" || return $? - # Remove the TraceFile.pb from the device. - iorapd_compiler_purge_trace_file "$package" "$activity" || return $? - - # TODO: better transactional support for restoring iorapd global properties - iorapd_perfetto_disable || return $? -} - -collector_main "$@" - -verbose_print "Collector finished. Children: " -if [[ $verbose == y ]]; then - jobs -p - ps f -g$$ -fi - -exit $? - - -verbose_print "About to begin systrace" -coproc systrace_fd { - # Disable stdout buffering since we need to know the output of systrace RIGHT AWAY. - stdbuf -oL "$ANDROID_BUILD_TOP"/external/chromium-trace/systrace.py --target=android -b "$trace_buffer_size" -t "$wait_time" am pagecache dalvik -o "$trace_tmp_file" -} - -verbose_print "Systrace began" - -systrace_pid="$!" - -while read -r -u "${systrace_fd[0]}" systrace_output; do - verbose_print "$systrace_output" - if [[ "$systrace_output" == *"Starting tracing"* ]]; then - verbose_print "WE DID SEE STARTING TRACING." - break - fi -done -# Systrace has begun recording the tracing. -# Run the application and collect the results. - -am_output="$(adb shell am start -S -W "$package"/"$activity")" -if [[ $? -ne 0 ]]; then - echo "am start failed" >&2 - - exit 1 -fi - -verbose_print "$am_output" -total_time="$(echo "$am_output" | grep 'TotalTime:' | sed 's/TotalTime: //g')" -verbose_print "total time: $total_time" - -# Now wait for systrace to finish. - -wait "$systrace_pid" || { echo "Systrace finished before am start was finished, try a longer --wait_time"; exit 1; } -verbose_print "Systrace has now finished" -verbose_print "$(ls -la "$trace_tmp_file")" - - -iorapd_perfetto_disable - -# Now that systrace has finished, convert the trace file html file to a protobuf. - -"$ANDROID_BUILD_TOP"/system/iorap/src/py/collector/trace_parser.py -i "$inodes" -t "$trace_tmp_file" -o "$output_dest" || exit 1 - -echo "Trace file collection complete, trace file saved to \"$output_dest\"!" >&2 - -finish diff --git a/startop/scripts/iorap/common b/startop/scripts/iorap/common deleted file mode 100755 index 387e45d431bd..000000000000 --- a/startop/scripts/iorap/common +++ /dev/null @@ -1,253 +0,0 @@ -#!/bin/bash -# -# Copyright 2019, 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. - -DIR_IORAP_COMMON="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -APP_STARTUP_DIR="$DIR_IORAP_COMMON/../app_startup/" -source "$APP_STARTUP_DIR/lib/common" - -IORAPD_DATA_PATH="/data/misc/iorapd" - -iorapd_start() { - verbose_print 'iorapd_start' - adb shell start iorapd - sleep 1 - # TODO: block until logcat prints successfully connecting -} - -iorapd_stop() { - verbose_print 'iorapd_stop' - adb shell stop iorapd -} - -iorapd_reset() { - iorapd_stop - iorapd_start -} - -# Enable perfetto tracing. -# Subsequent launches of an application will record a perfetto trace protobuf. -iorapd_perfetto_enable() { - verbose_print 'enable perfetto' - adb shell setprop iorapd.perfetto.enable true - iorapd_reset # iorapd only reads this flag when initializing -} - -# Disable perfetto tracing. -# Subsequent launches of applications will no longer record perfetto trace protobufs. -iorapd_perfetto_disable() { - verbose_print 'disable perfetto' - adb shell setprop iorapd.perfetto.enable false - iorapd_reset # iorapd only reads this flag when initializing -} - -# Enable readahead -# Subsequent launches of an application will be sped up by iorapd readahead prefetching -# (Provided an appropriate compiled trace exists for that application) -iorapd_readahead_enable() { - if [[ "$(adb shell getprop iorapd.readahead.enable)" == true ]]; then - verbose_print 'enable readahead [already enabled]' - return 0 - fi - verbose_print 'enable readahead [reset iorapd]' - adb shell setprop iorapd.readahead.enable true - iorapd_reset # iorapd only reads this flag when initializing -} - -# Disable readahead -# Subsequent launches of an application will be not be sped up by iorapd readahead prefetching. -iorapd_readahead_disable() { - if [[ "$(adb shell getprop iorapd.readahead.enable)" == false ]]; then - verbose_print 'disable readahead [already disabled]' - return 0 - fi - verbose_print 'disable readahead [reset iorapd]' - adb shell setprop iorapd.readahead.enable false - iorapd_reset # iorapd only reads this flag when initializing -} - -_iorapd_path_to_data_file() { - local package="$1" - local activity="$2" - local suffix="$3" - - # Match logic of 'AppComponentName' in iorap::compiler C++ code. - echo "${IORAPD_DATA_PATH}/${package}%2F${activity}.${suffix}" -} - -iorapd_perfetto_wait_for_app_trace() { - local package="$1" - local activity="$2" - local timeout="$3" - local timestamp="$4" - - local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")" - - verbose_print "iorapd_perfetto_wait_for_app_trace on file '$remote_path'" - - # see event_manager.cc - local pattern="Perfetto TraceBuffer saved to file: $remote_path" - logcat_wait_for_pattern "$timeout" "$timestamp" "$pattern" -} - -# Purge all perfetto traces for a given application. -iorapd_perfetto_purge_app_trace() { - local package="$1" - local activity="$2" - - local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")" - - verbose_print 'iorapd-perfetto: purge app trace in ' "$remote_path" - adb shell "[[ -f '$remote_path' ]] && rm -f '$remote_path' || exit 0" -} - -# Pull the remote perfetto trace file into a local file. -iorapd_perfetto_pull_trace_file() { - local package="$1" - local activity="$2" - local output_file="$3" # local path - - local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")" - - if ! adb shell "[[ -f '$compiled_path' ]]"; then - echo "Error: Remote path '$compiled_path' invalid" >&2 - return 1 - fi - if ! mkdir -p "$(dirname "$output_file")"; then - echo "Error: Fail to make output directory for '$output_file'" >&2 - return 1 - fi - verbose_print adb pull "$compiled_path" "$output_file" - adb pull "$compiled_path" "$output_file" -} - -# Compile a perfetto trace for a given application. -# This requires the app has run at least once with perfetto tracing enabled. -iorapd_compiler_for_app_trace() { - local package="$1" - local activity="$2" - local inodes="$3" # local path - - # remote path calculations - local input_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")" - local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.tmp.pb")" - local compiled_path_final="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")" - - if ! adb shell "[[ -f '$input_path' ]]"; then - echo "Error: Missing perfetto traces; nothing to compile. Expected: '$input_path'" >&2 - return 1 - fi - - if ! [[ -f $inodes ]]; then - # We could compile using 'diskscan' but it's non-deterministic, so refuse instead. - echo "Error: Missing inodes textcache at '$inodes'; refusing to compile." >&2 - return 1 - fi - - # inodes file needs to be on the device for iorap.cmd.compiler to access it - local remote_inodes=/data/local/tmp/prefetch/inodes.txt - adb shell "mkdir -p \"$(dirname "$remote_inodes")\"" || return 1 - verbose_print adb push "$inodes" "$remote_inodes" - adb push "$inodes" "$remote_inodes" - - verbose_print 'iorapd-compiler: compile app trace in ' "$input_path" - verbose_print adb shell "iorap.cmd.compiler '$input_path' --inode-textcache '$remote_inodes' --output-proto '$compiled_path'" - adb shell "iorap.cmd.compiler '$input_path' --inode-textcache '$remote_inodes' --output-proto '$compiled_path'" - retcode=$? - - # Don't overwrite the true 'compiled_trace.pb' unless the compiler completed without error. - # TODO: The native compiler code should be handling its own transaction-safety. - if [[ $retcode -eq 0 ]]; then - adb shell "mv '$compiled_path' '$compiled_path_final'" - else - adb shell "[[ -f '$compiled_path' ]] && rm -f '$compiled_path'" - fi - - # Clean up inodes file we just pushed. -# adb shell "[[ -f '$remote_inodes' ]] && rm -f '$remote_inodes'" - - return $retcode -} - -# Pull the remote compiled trace file into a local file. -iorapd_compiler_pull_trace_file() { - local package="$1" - local activity="$2" - local output_file="$3" # local path - - local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")" - - if ! adb shell "[[ -f '$compiled_path' ]]"; then - echo "Error: Remote path '$compiled_path' invalid" >&2 - return 1 - fi - if ! mkdir -p "$(dirname "$output_file")"; then - echo "Error: Fail to make output directory for '$output_file'" >&2 - return 1 - fi - verbose_print adb pull "$compiled_path" "$output_file" - adb pull "$compiled_path" "$output_file" -} - -# Install a compiled trace file. -iorapd_compiler_install_trace_file() { - local package="$1" - local activity="$2" - local input_file="$3" # local path - - # remote path calculations - local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")" - - if ! [[ -f $input_file ]]; then - echo "Error: File '$input_file' does not exist." >&2 - return 1 - fi - - adb shell "mkdir -p \"$(dirname "$compiled_path")\"" || return 1 - - verbose_print adb push "$input_file" "$compiled_path" - adb push "$input_file" "$compiled_path" -} - -iorapd_compiler_purge_trace_file() { - local package="$1" - local activity="$2" - local input_file="$3" # local path - - local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")" - - adb shell "[[ -f '$remote_path' ]] && rm -f '$remote_path' || exit 0" -} - -# Blocks until the readahead for the requested package/activity has finished. -# This assumes that the trace file was already installed, and also that -# the application launched but not completed yet. -iorapd_readahead_wait_until_finished() { - local package="$1" - local activity="$2" - local timestamp="$3" - local timeout="$4" - - if [[ $# -lt 4 ]]; then - echo "FATAL: Expected 4 arguments (actual $# $@)" >&2 - exit 1 - fi - - local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")" - - # See 'read_ahead.cc' LOG(INFO). - local pattern="Description = $remote_path" - logcat_wait_for_pattern "$timeout" "$timestamp" "$pattern" -} diff --git a/startop/scripts/iorap/compile_handcrafted_file.py b/startop/scripts/iorap/compile_handcrafted_file.py deleted file mode 100755 index 6dbbeaf91571..000000000000 --- a/startop/scripts/iorap/compile_handcrafted_file.py +++ /dev/null @@ -1,297 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. - -import argparse -import asyncio -import csv -import itertools -import os -import re -import struct -import sys -import tempfile -import time -import zipfile -from typing import Any, Callable, Dict, Generic, Iterable, List, NamedTuple, TextIO, Tuple, TypeVar, Optional, Union - -# Include generated protos. -dir_name = os.path.dirname(os.path.realpath(__file__)) -sys.path.append(dir_name + "/generated") - -from TraceFile_pb2 import * - - -def parse_options(argv: List[str] = None): - """Parse command line arguments and return an argparse Namespace object.""" - parser = argparse.ArgumentParser(description="Compile a TraceFile.proto from a manual text file.") - # argparse considers args starting with - and -- optional in --help, even though required=True. - # by using a named argument group --help will clearly say that it's required instead of optional. - required_named = parser.add_argument_group('required named arguments') - - # optional arguments - # use a group here to get the required arguments to appear 'above' the optional arguments in help. - optional_named = parser.add_argument_group('optional named arguments') - optional_named.add_argument('-opb', '--output-proto-binary', dest='output_proto_binary', action='store', help='Write binary proto output to file.') - optional_named.add_argument('-pm', '--pinlist-meta', dest='pinlist_meta', action='store', help='Path to pinlist.meta (default=none) binary file.') - optional_named.add_argument('-pmp', '--pinlist-meta-parent', dest='pinlist_meta_parent', action='store', help='Device path that the pinlist.meta applies to (e.g. /data/.../somefile.apk)') - optional_named.add_argument('-i', '--input', dest='input', action='store', help='Input text file (default stdin).') - optional_named.add_argument('-zp', '--zip_path', dest='zip_path', action='append', help='Directory containing zip files.') - optional_named.add_argument('-d', '--debug', dest='debug', action='store_true', help='Add extra debugging output') - optional_named.add_argument('-ot', '--output-text', dest='output_text', action='store', help='Output text file (default stdout).') - - return parser.parse_args(argv) - -# TODO: refactor this with a common library file with analyze_metrics.py -def _debug_print(*args, **kwargs): - """Print the args to sys.stderr if the --debug/-d flag was passed in.""" - if _debug: - print(*args, **kwargs, file=sys.stderr) - -class BadInputError(Exception): - pass - -InputRecord = NamedTuple('InputRecord', [('filepath', str), ('offset', int), ('length', int), ('remark', str)]) - -def find_zip_in_paths(original_name, zip_paths): - # /foo/bar/bax.zip -> bax.zip - file_basename = os.path.split(original_name)[1] - - # the file must be located in one of the --zip-path arguments - matched = None - for zip_path in zip_paths: - for dir_entry in os.listdir(zip_path): - if dir_entry == file_basename: - matched = os.path.join(zip_path, dir_entry) - break - if matched: - break - - if not matched: - raise ValueError("%s could not be found in any of the --zip_path specified." %(file_basename)) - - _debug_print("found zip file ", file_basename, " in ", matched) - - if not zipfile.is_zipfile(matched): - raise ValueError("%s is not a zip file" %(matched)) - - return matched - -def handle_zip_entry(input_record, zip_paths): - - res = re.match("([^!]+)[!](.*)", input_record.filepath) - - if not res: - return input_record - - # 'foo!bar' - in_filepath = res[1] # -> 'foo' - in_zip_entry = res[2] # -> 'bar' - - matched = find_zip_in_paths(in_filepath, zip_paths) - - zip = zipfile.ZipFile(matched) - - try: - zip_info = zip.getinfo(in_zip_entry) - except KeyError: - raise ValueError("%s is not an item in the zip file %s" %(in_zip_entry, matched)) - - # TODO: do we also need to add header size to this? - in_offset = zip_info.header_offset - - # TODO: if a range is specified, use that instead. - in_length = zip_info.compress_size - - return InputRecord(in_filepath, in_offset, in_length, 'zip entry (%s)' %(in_zip_entry)) - -def parse_input_file(input: Iterable[str], zip_paths: List[str]) -> Iterable[InputRecord]: - for line in input: - line = line.strip() - - _debug_print("Line = ", line) - if not line: - _debug_print(" skip empty line", line) - continue - elif line[0] == "#": - _debug_print(" skip commented line", line) - continue - - res = re.match("([^\s]+)\s+(\d+)\s+(\d+)", line) - if not res: - raise BadInputError("Expected input of form: <str:filepath> <int:offset> <int:length>") - - in_filepath = res[1] - in_offset = int(res[2]) - in_length = int(res[3]) - - yield handle_zip_entry(InputRecord(in_filepath, in_offset, in_length, 'regular file'), zip_paths) - -# format: -# (<big_endian(i32):file_offset> <big_endian(i32):range_length>)+ -PIN_META_FORMAT = ">ii" -PIN_META_READ_SIZE = struct.calcsize(PIN_META_FORMAT) - -def parse_pin_meta(pin_meta_file, pinlist_meta_parent, zip_paths): - if not pin_meta_file: - return () - - global PIN_META_FORMAT - global PIN_META_READ_SIZE - - # '/data/app/com.google.android.GoogleCamera-aNQhzSznf4h_bvJ_MRbweQ==/base.apk' - # -> 'com.google.android.GoogleCamera' - package_name_match = re.match('/.*/(.*)-.*=/base.apk', pinlist_meta_parent) - - if not package_name_match: - raise ValueError("%s did not contain the <packagename>.apk" %(pinlist_meta_parent)) - - package_name = package_name_match[1] - # "com.google.android.GoogleCamera" -> "GoogleCamera.apk" - apk_name = package_name.split(".")[-1] + ".apk" - - path_to_zip_on_host = find_zip_in_paths(apk_name, zip_paths) - apk_file_size = os.path.getsize(path_to_zip_on_host) - _debug_print("APK path '%s' file size '%d'" %(path_to_zip_on_host, apk_file_size)) - - while True: - data = pin_meta_file.read(PIN_META_READ_SIZE) - - if not data: - break - - (pin_offset, pin_length) = struct.unpack(PIN_META_FORMAT, data) # (offset, length) - - remark = 'regular file (pinlist.meta)' - - remaining_size = apk_file_size - pin_offset - if remaining_size < 0: - print("WARNING: Clamp entry (%d, %d), offset too large (max file size = %d)" %(pin_offset, pin_length, apk_file_size)) - - pin_length = pin_length + remaining_size - pin_offset = pin_offset + remaining_size - - if pin_offset < 0: - pin_offset = 0 - - remark += '[clamped.offset]' - - pin_last_offset = pin_offset + pin_length - remaining_size = apk_file_size - pin_last_offset - - if remaining_size < 0: - print("WARNING: Clamp entry (%d, %d), length too large (max file size = %d)" %(pin_offset, pin_length, apk_file_size)) - pin_length = pin_length + remaining_size - - remark += '[clamped.length]' - - yield InputRecord(pinlist_meta_parent, pin_offset, pin_length, remark) - -def write_text_file_output(input_records: Iterable[InputRecord], output_text_file): - for rec in input_records: - output_text_file.write("%s %d %d #%s\n" %(rec.filepath, rec.offset, rec.length, rec.remark)) - -def build_trace_file(input_records: Iterable[InputRecord]) -> TraceFile: - trace_file = TraceFile() - trace_file_index = trace_file.index - - file_id_counter = 0 - file_id_map = {} # filename -> id - - stats_length_total = 0 - filename_stats = {} # filename -> total size - - for rec in input_records: - filename = rec.filepath - - file_id = file_id_map.get(filename) - if not file_id: - file_id = file_id_counter - file_id_map[filename] = file_id_counter - file_id_counter = file_id_counter + 1 - - file_index_entry = trace_file_index.entries.add() - file_index_entry.id = file_id - file_index_entry.file_name = filename - - # already in the file index, add the file entry. - file_entry = trace_file.list.entries.add() - file_entry.index_id = file_id - file_entry.file_length = rec.length - stats_length_total += file_entry.file_length - file_entry.file_offset = rec.offset - - filename_stats[filename] = filename_stats.get(filename, 0) + file_entry.file_length - - return trace_file - -def main(): - global _debug - - options= parse_options() - _debug = options.debug - _debug_print("parsed options: ", options) - - if not options.input: - input_file = sys.stdin - _debug_print("input = stdin") - else: - input_file = open(options.input) - _debug_print("input = (file)", options.input) - - if not options.output_proto_binary: - output_proto_file = None - else: - output_proto_file = open(options.output_proto_binary, 'wb') - _debug_print("output_proto_binary = ", output_proto_file) - - pinlist_meta_parent = options.pinlist_meta_parent - if options.pinlist_meta: - pin_meta_file = open(options.pinlist_meta, 'rb') - else: - pin_meta_file = None - - if (pinlist_meta_parent == None) != (pin_meta_file == None): - print("Options must be used together: --pinlist-meta and --pinlist-meta-path") - return 1 - - if not options.output_text: - output_text_file = sys.stdout - _debug_print("output = stdout") - else: - output_text_file = open(options.output_text, 'w') - _debug_print("output = (file)", options.output_text) - - zip_paths = options.zip_path or [] - - input_records = list(parse_pin_meta(pin_meta_file, pinlist_meta_parent, zip_paths)) - input_records = input_records + list(parse_input_file(input_file, zip_paths)) - - for p in input_records: - _debug_print(p) - - write_text_file_output(input_records, output_text_file) - output_text_file.close() - - out_proto = build_trace_file(input_records) - - if output_proto_file: - output_proto_file.write(out_proto.SerializeToString()) - output_proto_file.close() - - return 0 - -if __name__ == '__main__': - sys.exit(main()) diff --git a/startop/scripts/iorap/compiler.py b/startop/scripts/iorap/compiler.py deleted file mode 100644 index 1426d34f325d..000000000000 --- a/startop/scripts/iorap/compiler.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. - -import importlib -import os -import sys -import tempfile -from enum import Enum -from typing import TextIO, List - -# local import -DIR = os.path.abspath(os.path.dirname(__file__)) -sys.path.append(os.path.dirname(DIR)) -import lib.print_utils as print_utils - -# Type of compiler. -class CompilerType(Enum): - HOST = 1 # iorap.cmd.compiler on host - DEVICE = 2 # adb shell iorap.cmd.compiler - RI = 3 # compiler.py - -def compile_perfetto_trace_ri( - argv: List[str], - compiler) -> TextIO: - print_utils.debug_print('Compile using RI compiler.') - compiler_trace_file = tempfile.NamedTemporaryFile() - argv.extend(['-o', compiler_trace_file.name]) - print_utils.debug_print(argv) - compiler.main([''] + argv) - return compiler_trace_file - -def compile_perfetto_trace_device(inodes_path: str, - package: str, - activity: str, - compiler) -> TextIO: - print_utils.debug_print('Compile using on-device compiler.') - compiler_trace_file = tempfile.NamedTemporaryFile() - compiler.main(inodes_path, package, activity, compiler_trace_file.name) - return compiler_trace_file - -def compile(compiler_type: CompilerType, - inodes_path: str, - ri_compiler_argv, - package: str, - activity: str) -> TextIO: - if compiler_type == CompilerType.RI: - compiler = importlib.import_module('iorap.compiler_ri') - compiler_trace_file = compile_perfetto_trace_ri(ri_compiler_argv, - compiler) - return compiler_trace_file - if compiler_type == CompilerType.DEVICE: - compiler = importlib.import_module('iorap.compiler_device') - compiler_trace_file = compile_perfetto_trace_device(inodes_path, - package, - activity, - compiler) - return compiler_trace_file - - # Should not arrive here. - raise ValueError('Unknown compiler type') diff --git a/startop/scripts/iorap/compiler_device.py b/startop/scripts/iorap/compiler_device.py deleted file mode 100644 index d941cd913fe1..000000000000 --- a/startop/scripts/iorap/compiler_device.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. - -import argparse -import os -import sys -from typing import List - -DIR = os.path.abspath(os.path.dirname(__file__)) -sys.path.append(os.path.dirname(DIR)) # framework/base/startop/script -import lib.print_utils as print_utils -import iorap.lib.iorapd_utils as iorapd_utils -from app_startup.lib.app_runner import AppRunner - -IORAP_COMMON_BASH_SCRIPT = os.path.join(DIR, 'common') - -def parse_options(argv: List[str] = None): - """Parses command line arguments and returns an argparse Namespace object.""" - parser = argparse.ArgumentParser(description="Compile perfetto trace file") - required_named = parser.add_argument_group('required named arguments') - - required_named.add_argument('-i', dest='inodes', metavar='FILE', - help='Read cached inode data from a file saved ' - 'earlier with pagecache.py -d') - required_named.add_argument('-p', dest='package', - help='Package of the app to be compiled') - - optional_named = parser.add_argument_group('optional named arguments') - optional_named.add_argument('-o', dest='output', - help='The compiled trace is stored into the output file') - optional_named.add_argument('-a', dest='activity', - help='Activity of the app to be compiled') - optional_named.add_argument('-d', dest='debug', action='store_true' - , help='Activity of the app to be compiled') - - return parser.parse_args(argv) - -def main(inodes, package, activity, output, **kwargs) -> int: - """Entries of the program.""" - if not activity: - activity = AppRunner.get_activity(package) - - passed = iorapd_utils.compile_perfetto_trace_on_device(package, activity, - inodes) - if passed and output: - iorapd_utils.get_iorapd_compiler_trace(package, activity, output) - - return 0 - -if __name__ == '__main__': - opts = parse_options() - if opts.debug: - print_utils.DEBUG = opts.debug - print_utils.debug_print(opts) - sys.exit(main(**(vars(opts)))) diff --git a/startop/scripts/iorap/compiler_ri.py b/startop/scripts/iorap/compiler_ri.py deleted file mode 100755 index 90fc8a8123c5..000000000000 --- a/startop/scripts/iorap/compiler_ri.py +++ /dev/null @@ -1,325 +0,0 @@ -#!/usr/bin/env python3 - -# -# Copyright (C) 2019 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. -# - -# -# Dependencies: -# -# $> sudo apt-get install python3-pip -# $> pip3 install --user protobuf sqlalchemy sqlite3 -# - -import optparse -import os -import re -import sys -import tempfile -from pathlib import Path -from datetime import timedelta -from typing import Iterable, Optional, List - -DIR = os.path.abspath(os.path.dirname(__file__)) -sys.path.append(os.path.dirname(DIR)) -from iorap.generated.TraceFile_pb2 import * -from iorap.lib.inode2filename import Inode2Filename - -parent_dir_name = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) -sys.path.append(parent_dir_name) -from trace_analyzer.lib.trace2db import Trace2Db, MmFilemapAddToPageCache, \ - RawFtraceEntry -import lib.cmd_utils as cmd_utils - -_PAGE_SIZE = 4096 # adb shell getconf PAGESIZE ## size of a memory page in bytes. -ANDROID_BUILD_TOP = Path(parent_dir_name).parents[3] -TRACECONV_BIN = ANDROID_BUILD_TOP.joinpath( - 'external/perfetto/tools/traceconv') - -class PageRun: - """ - Intermediate representation for a run of one or more pages. - """ - def __init__(self, device_number: int, inode: int, offset: int, length: int): - self.device_number = device_number - self.inode = inode - self.offset = offset - self.length = length - - def __str__(self): - return "PageRun(device_number=%d, inode=%d, offset=%d, length=%d)" \ - %(self.device_number, self.inode, self.offset, self.length) - -def debug_print(msg): - #print(msg) - pass - -UNDER_LAUNCH = False - -def page_cache_entries_to_runs(page_cache_entries: Iterable[MmFilemapAddToPageCache]): - global _PAGE_SIZE - - runs = [ - PageRun(device_number=pg_entry.dev, inode=pg_entry.ino, offset=pg_entry.ofs, - length=_PAGE_SIZE) - for pg_entry in page_cache_entries - ] - - for r in runs: - debug_print(r) - - print("Stats: Page runs totaling byte length: %d" %(len(runs) * _PAGE_SIZE)) - - return runs - -def optimize_page_runs(page_runs): - new_entries = [] - last_entry = None - for pg_entry in page_runs: - if last_entry: - if pg_entry.device_number == last_entry.device_number and pg_entry.inode == last_entry.inode: - # we are dealing with a run for the same exact file as a previous run. - if pg_entry.offset == last_entry.offset + last_entry.length: - # trivially contiguous entries. merge them together. - last_entry.length += pg_entry.length - continue - # Default: Add the run without merging it to a previous run. - last_entry = pg_entry - new_entries.append(pg_entry) - return new_entries - -def is_filename_matching_filter(file_name, filters=[]): - """ - Blacklist-style regular expression filters. - - :return: True iff file_name has an RE match in one of the filters. - """ - for filt in filters: - res = re.search(filt, file_name) - if res: - return True - - return False - -def build_protobuf(page_runs, inode2filename, filters=[]): - trace_file = TraceFile() - trace_file_index = trace_file.index - - file_id_counter = 0 - file_id_map = {} # filename -> id - - stats_length_total = 0 - filename_stats = {} # filename -> total size - - skipped_inode_map = {} - filtered_entry_map = {} # filename -> count - - for pg_entry in page_runs: - fn = inode2filename.resolve(pg_entry.device_number, pg_entry.inode) - if not fn: - skipped_inode_map[pg_entry.inode] = skipped_inode_map.get(pg_entry.inode, 0) + 1 - continue - - filename = fn - - if filters and not is_filename_matching_filter(filename, filters): - filtered_entry_map[filename] = filtered_entry_map.get(filename, 0) + 1 - continue - - file_id = file_id_map.get(filename) - # file_id could 0, which satisfies "if file_id" and causes duplicate - # filename for file id 0. - if file_id is None: - file_id = file_id_counter - file_id_map[filename] = file_id_counter - file_id_counter = file_id_counter + 1 - - file_index_entry = trace_file_index.entries.add() - file_index_entry.id = file_id - file_index_entry.file_name = filename - - # already in the file index, add the file entry. - file_entry = trace_file.list.entries.add() - file_entry.index_id = file_id - file_entry.file_length = pg_entry.length - stats_length_total += file_entry.file_length - file_entry.file_offset = pg_entry.offset - - filename_stats[filename] = filename_stats.get(filename, 0) + file_entry.file_length - - for inode, count in skipped_inode_map.items(): - print("WARNING: Skip inode %s because it's not in inode map (%d entries)" %(inode, count)) - - print("Stats: Sum of lengths %d" %(stats_length_total)) - - if filters: - print("Filter: %d total files removed." %(len(filtered_entry_map))) - - for fn, count in filtered_entry_map.items(): - print("Filter: File '%s' removed '%d' entries." %(fn, count)) - - for filename, file_size in filename_stats.items(): - print("%s,%s" %(filename, file_size)) - - return trace_file - -def calc_trace_end_time(trace2db: Trace2Db, - trace_duration: Optional[timedelta]) -> float: - """ - Calculates the end time based on the trace duration. - The start time is the first receiving mm file map event. - The end time is the start time plus the trace duration. - All of them are in milliseconds. - """ - # If the duration is not set, assume all time is acceptable. - if trace_duration is None: - # float('inf') - return RawFtraceEntry.__table__.c.timestamp.type.python_type('inf') - - first_event = trace2db.session.query(MmFilemapAddToPageCache).join( - MmFilemapAddToPageCache.raw_ftrace_entry).order_by( - RawFtraceEntry.timestamp).first() - - # total_seconds() will return a float number. - return first_event.raw_ftrace_entry.timestamp + trace_duration.total_seconds() - -def query_add_to_page_cache(trace2db: Trace2Db, trace_duration: Optional[timedelta]): - end_time = calc_trace_end_time(trace2db, trace_duration) - # SELECT * FROM tbl ORDER BY id; - return trace2db.session.query(MmFilemapAddToPageCache).join( - MmFilemapAddToPageCache.raw_ftrace_entry).filter( - RawFtraceEntry.timestamp <= end_time).order_by( - MmFilemapAddToPageCache.id).all() - -def transform_perfetto_trace_to_systrace(path_to_perfetto_trace: str, - path_to_tmp_systrace: str) -> None: - """ Transforms the systrace file from perfetto trace. """ - cmd_utils.run_command_nofail([str(TRACECONV_BIN), - 'systrace', - path_to_perfetto_trace, - path_to_tmp_systrace]) - - -def run(sql_db_path:str, - trace_file:str, - trace_duration:Optional[timedelta], - output_file:str, - inode_table:str, - filter:List[str]) -> int: - trace2db = Trace2Db(sql_db_path) - # Speed optimization: Skip any entries that aren't mm_filemap_add_to_pagecache. - trace2db.set_raw_ftrace_entry_filter(\ - lambda entry: entry['function'] == 'mm_filemap_add_to_page_cache') - # TODO: parse multiple trace files here. - parse_count = trace2db.parse_file_into_db(trace_file) - - mm_filemap_add_to_page_cache_rows = query_add_to_page_cache(trace2db, - trace_duration) - print("DONE. Parsed %d entries into sql db." %(len(mm_filemap_add_to_page_cache_rows))) - - page_runs = page_cache_entries_to_runs(mm_filemap_add_to_page_cache_rows) - print("DONE. Converted %d entries" %(len(page_runs))) - - # TODO: flags to select optimizations. - optimized_page_runs = optimize_page_runs(page_runs) - print("DONE. Optimized down to %d entries" %(len(optimized_page_runs))) - - print("Build protobuf...") - trace_file = build_protobuf(optimized_page_runs, inode_table, filter) - - print("Write protobuf to file...") - output_file = open(output_file, 'wb') - output_file.write(trace_file.SerializeToString()) - output_file.close() - - print("DONE") - - # TODO: Silent running mode [no output except on error] for build runs. - - return 0 - -def main(argv): - parser = optparse.OptionParser(usage="Usage: %prog [options]", description="Compile systrace file into TraceFile.pb") - parser.add_option('-i', dest='inode_data_file', metavar='FILE', - help='Read cached inode data from a file saved earlier with pagecache.py -d') - parser.add_option('-t', dest='trace_file', metavar='FILE', - help='Path to systrace file (trace.html) that will be parsed') - parser.add_option('--perfetto-trace', dest='perfetto_trace_file', - metavar='FILE', - help='Path to perfetto trace that will be parsed') - - parser.add_option('--db', dest='sql_db', metavar='FILE', - help='Path to intermediate sqlite3 database [default: in-memory].') - - parser.add_option('-f', dest='filter', action="append", default=[], - help="Add file filter. All file entries not matching one of the filters are discarded.") - - parser.add_option('-l', dest='launch_lock', action="store_true", default=False, - help="Exclude all events not inside launch_lock") - - parser.add_option('-o', dest='output_file', metavar='FILE', - help='Output protobuf file') - - parser.add_option('--duration', dest='trace_duration', action="store", - type=int, help='The duration of trace in milliseconds.') - - options, categories = parser.parse_args(argv[1:]) - - # TODO: OptionParser should have some flags to make these mandatory. - if not options.inode_data_file: - parser.error("-i is required") - if not options.trace_file and not options.perfetto_trace_file: - parser.error("one of -t or --perfetto-trace is required") - if options.trace_file and options.perfetto_trace_file: - parser.error("please enter either -t or --perfetto-trace, not both") - if not options.output_file: - parser.error("-o is required") - - if options.launch_lock: - print("INFO: Launch lock flag (-l) enabled; filtering all events not inside launch_lock.") - - inode_table = Inode2Filename.new_from_filename(options.inode_data_file) - - sql_db_path = ":memory:" - if options.sql_db: - sql_db_path = options.sql_db - - trace_duration = timedelta(milliseconds=options.trace_duration) if \ - options.trace_duration is not None else None - - # if the input is systrace - if options.trace_file: - return run(sql_db_path, - options.trace_file, - trace_duration, - options.output_file, - inode_table, - options.filter) - - # if the input is perfetto trace - # TODO python 3.7 switch to using nullcontext - with tempfile.NamedTemporaryFile() as trace_file: - transform_perfetto_trace_to_systrace(options.perfetto_trace_file, - trace_file.name) - return run(sql_db_path, - trace_file.name, - trace_duration, - options.output_file, - inode_table, - options.filter) - -if __name__ == '__main__': - print(sys.argv) - sys.exit(main(sys.argv)) diff --git a/startop/scripts/iorap/compiler_test.py b/startop/scripts/iorap/compiler_test.py deleted file mode 100644 index b8de70147565..000000000000 --- a/startop/scripts/iorap/compiler_test.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. -# - -""" -Unit tests for the compiler.py script. - -Install: - $> sudo apt-get install python3-pytest ## OR - $> pip install -U pytest -See also https://docs.pytest.org/en/latest/getting-started.html - -Usage: - $> pytest compiler_test.py - -See also https://docs.pytest.org/en/latest/usage.html -""" -import os - -import compiler_ri as compiler - -DIR = os.path.abspath(os.path.dirname(__file__)) -TEXTCACHE = os.path.join(DIR, 'test_fixtures/compiler/common_textcache') -SYSTRACE = os.path.join(DIR, 'test_fixtures/compiler/common_systrace') -ARGV = [os.path.join(DIR, 'compiler.py'), '-i', TEXTCACHE, '-t', SYSTRACE] -PERFETTO_TRACE = os.path.join(DIR, - 'test_fixtures/compiler/common_perfetto_trace.pb') - -def assert_compile_result(output, expected, *extra_argv): - argv = ARGV + ['-o', output] + [args for args in extra_argv] - - compiler.main(argv) - - with open(output, 'rb') as f1, open(expected, 'rb') as f2: - assert f1.read() == f2.read() - -### Unit tests - testing compiler code directly -def test_transform_perfetto_trace_to_systrace(tmpdir): - expected = os.path.join(DIR, - 'test_fixtures/compiler/test_result_systrace') - output = tmpdir.mkdir('compiler').join('tmp_systrace') - - compiler.transform_perfetto_trace_to_systrace(PERFETTO_TRACE, str(output)) - - with open(output, 'rb') as f1, open(expected, 'rb') as f2: - assert f1.read() == f2.read() - -### Functional tests - calls 'compiler.py --args...' -def test_compiler_main(tmpdir): - output = tmpdir.mkdir('compiler').join('output') - - # No duration - expected = os.path.join(DIR, - 'test_fixtures/compiler/test_result_without_duration.TraceFile.pb') - assert_compile_result(output, expected) - - # 10ms duration - expected = os.path.join(DIR, - 'test_fixtures/compiler/test_result_with_duration.TraceFile.pb') - assert_compile_result(output, expected, '--duration', '10000') - - # 30ms duration - expected = os.path.join(DIR, - 'test_fixtures/compiler/test_result_without_duration.TraceFile.pb') - assert_compile_result(output, expected, '--duration', '30000') diff --git a/startop/scripts/iorap/dump_compiled_pb b/startop/scripts/iorap/dump_compiled_pb deleted file mode 100755 index ad26a7d72c53..000000000000 --- a/startop/scripts/iorap/dump_compiled_pb +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -# -# Copyright 2019, 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. - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -# -# Dumps an iorap compiler protobuf from iorap.cmd.compiler into text -# with gqui. -# - -if [[ "$#" -lt 1 ]]; then - echo "Usage: $0 <compiler_trace_file.pb> [...args]" >&2 - exit 1 -fi - -path_to_proto="$DIR/../../../../../system/iorap/src/serialize/TraceFile.proto" - -filename="$1" -shift -if ! [[ -f $filename ]]; then - echo "Error: $filename does not exist." >&2 - exit 1 -fi - -gqui "rawproto:$filename" proto "$path_to_proto":iorap.serialize.proto.TraceFile "$@" diff --git a/startop/scripts/iorap/dump_trace_pb b/startop/scripts/iorap/dump_trace_pb deleted file mode 100755 index bcec4a524994..000000000000 --- a/startop/scripts/iorap/dump_trace_pb +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -# -# Copyright 2019, 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. - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -# -# Dumps a perfetto protobuf collected by iorapd (from perfetto) into text -# with gqui. -# - -if [[ "$#" -lt 1 ]]; then - echo "Usage: $0 <perfetto_trace.pb> [...args]" >&2 - exit 1 -fi - -path_to_perfetto_proto="$DIR/../../../../../external/perfetto/protos/perfetto/trace/perfetto_trace.proto" - -filename="$1" -shift -if ! [[ -f $filename ]]; then - echo "Error: $filename does not exist." >&2 - exit 1 -fi - -gqui "rawproto:$filename" proto "$path_to_perfetto_proto":perfetto.protos.Trace "$@" diff --git a/startop/scripts/iorap/generated/TraceFile_pb2.py b/startop/scripts/iorap/generated/TraceFile_pb2.py deleted file mode 100644 index f005bed427ca..000000000000 --- a/startop/scripts/iorap/generated/TraceFile_pb2.py +++ /dev/null @@ -1,259 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: TraceFile.proto - -import sys -_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -from google.protobuf import descriptor_pb2 -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor.FileDescriptor( - name='TraceFile.proto', - package='iorap.serialize.proto', - syntax='proto2', - serialized_pb=_b('\n\x0fTraceFile.proto\x12\x15iorap.serialize.proto\"u\n\tTraceFile\x12\x34\n\x05index\x18\x01 \x02(\x0b\x32%.iorap.serialize.proto.TraceFileIndex\x12\x32\n\x04list\x18\x02 \x02(\x0b\x32$.iorap.serialize.proto.TraceFileList\"M\n\x0eTraceFileIndex\x12;\n\x07\x65ntries\x18\x01 \x03(\x0b\x32*.iorap.serialize.proto.TraceFileIndexEntry\"4\n\x13TraceFileIndexEntry\x12\n\n\x02id\x18\x01 \x02(\x03\x12\x11\n\tfile_name\x18\x02 \x02(\t\"G\n\rTraceFileList\x12\x36\n\x07\x65ntries\x18\x01 \x03(\x0b\x32%.iorap.serialize.proto.TraceFileEntry\"L\n\x0eTraceFileEntry\x12\x10\n\x08index_id\x18\x01 \x02(\x03\x12\x13\n\x0b\x66ile_offset\x18\x02 \x02(\x03\x12\x13\n\x0b\x66ile_length\x18\x03 \x02(\x03\x42\x1c\n\x18\x63om.google.android.iorapH\x03') -) -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - - - - -_TRACEFILE = _descriptor.Descriptor( - name='TraceFile', - full_name='iorap.serialize.proto.TraceFile', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='index', full_name='iorap.serialize.proto.TraceFile.index', index=0, - number=1, type=11, cpp_type=10, label=2, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='list', full_name='iorap.serialize.proto.TraceFile.list', index=1, - number=2, type=11, cpp_type=10, label=2, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - serialized_start=42, - serialized_end=159, -) - - -_TRACEFILEINDEX = _descriptor.Descriptor( - name='TraceFileIndex', - full_name='iorap.serialize.proto.TraceFileIndex', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='entries', full_name='iorap.serialize.proto.TraceFileIndex.entries', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - serialized_start=161, - serialized_end=238, -) - - -_TRACEFILEINDEXENTRY = _descriptor.Descriptor( - name='TraceFileIndexEntry', - full_name='iorap.serialize.proto.TraceFileIndexEntry', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='id', full_name='iorap.serialize.proto.TraceFileIndexEntry.id', index=0, - number=1, type=3, cpp_type=2, label=2, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='file_name', full_name='iorap.serialize.proto.TraceFileIndexEntry.file_name', index=1, - number=2, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=_b("").decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - serialized_start=240, - serialized_end=292, -) - - -_TRACEFILELIST = _descriptor.Descriptor( - name='TraceFileList', - full_name='iorap.serialize.proto.TraceFileList', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='entries', full_name='iorap.serialize.proto.TraceFileList.entries', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - serialized_start=294, - serialized_end=365, -) - - -_TRACEFILEENTRY = _descriptor.Descriptor( - name='TraceFileEntry', - full_name='iorap.serialize.proto.TraceFileEntry', - filename=None, - file=DESCRIPTOR, - containing_type=None, - fields=[ - _descriptor.FieldDescriptor( - name='index_id', full_name='iorap.serialize.proto.TraceFileEntry.index_id', index=0, - number=1, type=3, cpp_type=2, label=2, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='file_offset', full_name='iorap.serialize.proto.TraceFileEntry.file_offset', index=1, - number=2, type=3, cpp_type=2, label=2, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - _descriptor.FieldDescriptor( - name='file_length', full_name='iorap.serialize.proto.TraceFileEntry.file_length', index=2, - number=3, type=3, cpp_type=2, label=2, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - options=None), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - serialized_start=367, - serialized_end=443, -) - -_TRACEFILE.fields_by_name['index'].message_type = _TRACEFILEINDEX -_TRACEFILE.fields_by_name['list'].message_type = _TRACEFILELIST -_TRACEFILEINDEX.fields_by_name['entries'].message_type = _TRACEFILEINDEXENTRY -_TRACEFILELIST.fields_by_name['entries'].message_type = _TRACEFILEENTRY -DESCRIPTOR.message_types_by_name['TraceFile'] = _TRACEFILE -DESCRIPTOR.message_types_by_name['TraceFileIndex'] = _TRACEFILEINDEX -DESCRIPTOR.message_types_by_name['TraceFileIndexEntry'] = _TRACEFILEINDEXENTRY -DESCRIPTOR.message_types_by_name['TraceFileList'] = _TRACEFILELIST -DESCRIPTOR.message_types_by_name['TraceFileEntry'] = _TRACEFILEENTRY - -TraceFile = _reflection.GeneratedProtocolMessageType('TraceFile', (_message.Message,), dict( - DESCRIPTOR = _TRACEFILE, - __module__ = 'TraceFile_pb2' - # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFile) - )) -_sym_db.RegisterMessage(TraceFile) - -TraceFileIndex = _reflection.GeneratedProtocolMessageType('TraceFileIndex', (_message.Message,), dict( - DESCRIPTOR = _TRACEFILEINDEX, - __module__ = 'TraceFile_pb2' - # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileIndex) - )) -_sym_db.RegisterMessage(TraceFileIndex) - -TraceFileIndexEntry = _reflection.GeneratedProtocolMessageType('TraceFileIndexEntry', (_message.Message,), dict( - DESCRIPTOR = _TRACEFILEINDEXENTRY, - __module__ = 'TraceFile_pb2' - # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileIndexEntry) - )) -_sym_db.RegisterMessage(TraceFileIndexEntry) - -TraceFileList = _reflection.GeneratedProtocolMessageType('TraceFileList', (_message.Message,), dict( - DESCRIPTOR = _TRACEFILELIST, - __module__ = 'TraceFile_pb2' - # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileList) - )) -_sym_db.RegisterMessage(TraceFileList) - -TraceFileEntry = _reflection.GeneratedProtocolMessageType('TraceFileEntry', (_message.Message,), dict( - DESCRIPTOR = _TRACEFILEENTRY, - __module__ = 'TraceFile_pb2' - # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileEntry) - )) -_sym_db.RegisterMessage(TraceFileEntry) - - -DESCRIPTOR.has_options = True -DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\030com.google.android.iorapH\003')) -# @@protoc_insertion_point(module_scope) diff --git a/startop/scripts/iorap/generated/codegen_protos b/startop/scripts/iorap/generated/codegen_protos deleted file mode 100755 index 5688711ec25d..000000000000 --- a/startop/scripts/iorap/generated/codegen_protos +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash -# -# Copyright 2019, 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. - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -APROTOC="$(which aprotoc)" - -IORAP_SERIALIZE_DIR="${DIR}/../../../../../../system/iorap/src/serialize" -IORAP_PROTOS=($IORAP_SERIALIZE_DIR/*.proto) - -if [[ $? -ne 0 ]]; then - echo "Fatal: Missing aprotoc. Set APROTOC=... or lunch build/envsetup.sh?" >&2 - exit 1 -fi - -if ! [[ -d $IORAP_SERIALIZE_DIR ]]; then - echo "Fatal: Directory '$IORAP_SERIALIZE_DIR' does not exist." >&2 - exit 1 -fi - -# codegen the .py files into the same directory as this script. -echo "$APROTOC" --proto_path="$IORAP_SERIALIZE_DIR" --python_out="$DIR" "${IORAP_PROTOS[@]}" -"$APROTOC" --proto_path="$IORAP_SERIALIZE_DIR" --python_out="$DIR" "${IORAP_PROTOS[@]}" diff --git a/startop/scripts/iorap/lib/inode2filename.py b/startop/scripts/iorap/lib/inode2filename.py deleted file mode 100644 index 2e713936319a..000000000000 --- a/startop/scripts/iorap/lib/inode2filename.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python3 - -# -# Copyright (C) 2019 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. -# - -from typing import Any, Callable, Dict, Generic, Iterable, List, NamedTuple, TextIO, Tuple, TypeVar, Optional, Union, TextIO - -import re - -class Inode2Filename: - """ - Parses a text file of the format - "uint(dev_t) uint(ino_t) int(file_size) string(filepath)\\n"* - - Lines not matching this format are ignored. - """ - - def __init__(self, inode_data_file: TextIO): - """ - Create an Inode2Filename that reads cached inode from a file saved earlier - (e.g. with pagecache.py -d or with inode2filename --format=textcache) - - :param inode_data_file: a file object (e.g. created with open or StringIO). - - Lifetime: inode_data_file is only used during the construction of the object. - """ - self._inode_table = Inode2Filename.build_inode_lookup_table(inode_data_file) - - @classmethod - def new_from_filename(cls, textcache_filename: str) -> 'Inode2Filename': - """ - Create an Inode2Filename that reads cached inode from a file saved earlier - (e.g. with pagecache.py -d or with inode2filename --format=textcache) - - :param textcache_filename: path to textcache - """ - with open(textcache_filename) as inode_data_file: - return cls(inode_data_file) - - @staticmethod - def build_inode_lookup_table(inode_data_file: TextIO) -> Dict[Tuple[int, int], Tuple[str, str]]: - """ - :return: map { (device_int, inode_int) -> (filename_str, size_str) } - """ - inode2filename = {} - for line in inode_data_file: - # stat -c "%d %i %s %n - # device number, inode number, total size in bytes, file name - result = re.match('([0-9]+)d? ([0-9]+) -?([0-9]+) (.*)', line) - if result: - inode2filename[(int(result.group(1)), int(result.group(2)))] = \ - (result.group(4), result.group(3)) - - return inode2filename - - def resolve(self, dev_t: int, ino_t: int) -> Optional[str]: - """ - Return a filename (str) from a (dev_t, ino_t) inode pair. - - Returns None if the lookup fails. - """ - maybe_result = self._inode_table.get((dev_t, ino_t)) - - if not maybe_result: - return None - - return maybe_result[0] # filename str - - def __len__(self) -> int: - """ - :return: the number of inode entries parsed from the file. - """ - return len(self._inode_table) - - def __repr__(self) -> str: - """ - :return: string representation for debugging/test failures. - """ - return "Inode2Filename%s" %(repr(self._inode_table)) - - # end of class. diff --git a/startop/scripts/iorap/lib/inode2filename_test.py b/startop/scripts/iorap/lib/inode2filename_test.py deleted file mode 100755 index 1224c61da641..000000000000 --- a/startop/scripts/iorap/lib/inode2filename_test.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. -# - -""" -Unit tests for inode2filename module. - -Install: - $> sudo apt-get install python3-pytest ## OR - $> pip install -U pytest -See also https://docs.pytest.org/en/latest/getting-started.html - -Usage: - $> ./inode2filename_test.py - $> pytest inode2filename_test.py - $> python -m pytest inode2filename_test.py - -See also https://docs.pytest.org/en/latest/usage.html -""" - -# global imports -from contextlib import contextmanager -import io -import shlex -import sys -import typing - -# pip imports -import pytest - -# local imports -from inode2filename import * - -def create_inode2filename(*contents): - buf = io.StringIO() - - for c in contents: - buf.write(c) - buf.write("\n") - - buf.seek(0) - - i2f = Inode2Filename(buf) - - buf.close() - - return i2f - -def test_inode2filename(): - a = create_inode2filename("") - assert len(a) == 0 - assert a.resolve(1, 2) == None - - a = create_inode2filename("1 2 3 foo.bar") - assert len(a) == 1 - assert a.resolve(1, 2) == "foo.bar" - assert a.resolve(4, 5) == None - - a = create_inode2filename("1 2 3 foo.bar", "4 5 6 bar.baz") - assert len(a) == 2 - assert a.resolve(1, 2) == "foo.bar" - assert a.resolve(4, 5) == "bar.baz" - - a = create_inode2filename("1567d 8910 -1 /a/b/c/", "4 5 6 bar.baz") - assert len(a) == 2 - assert a.resolve(1567, 8910) == "/a/b/c/" - assert a.resolve(4, 5) == "bar.baz" - -if __name__ == '__main__': - pytest.main() diff --git a/startop/scripts/iorap/lib/iorapd_utils.py b/startop/scripts/iorap/lib/iorapd_utils.py deleted file mode 100644 index f6f21fd70005..000000000000 --- a/startop/scripts/iorap/lib/iorapd_utils.py +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. - -"""Helper util libraries for iorapd related operations.""" - -import os -import sys - -# up to two level -sys.path.append(os.path.join(os.path.abspath(__file__),'../..')) -import lib.cmd_utils as cmd_utils - -IORAPID_LIB_DIR = os.path.abspath(os.path.dirname(__file__)) -IORAPD_DATA_PATH = '/data/misc/iorapd' -IORAP_COMMON_BASH_SCRIPT = os.path.realpath(os.path.join(IORAPID_LIB_DIR, - '../common')) - -def _iorapd_path_to_data_file(package: str, activity: str, suffix: str) -> str: - """Gets conventional data filename. - - Returns: - The path of iorapd data file. - - """ - # Match logic of 'AppComponentName' in iorap::compiler C++ code. - return '{}/{}%2F{}.{}'.format(IORAPD_DATA_PATH, package, activity, suffix) - -def compile_perfetto_trace_on_device(package: str, activity: str, - inodes: str) -> bool: - """Compiles the perfetto trace using on-device compiler.""" - passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT, - 'iorapd_compiler_for_app_trace', - [package, activity, inodes]) - return passed - -def get_iorapd_compiler_trace(package: str, activity: str, dest: str) -> str: - """Gets compiler trace to dest file.""" - src = _iorapd_path_to_data_file(package, activity, 'compiled_trace.pb') - passed, _ = cmd_utils.run_shell_command('adb pull "{}" "{}"'.format(src, dest)) - if not passed: - return False - return True - -def iorapd_compiler_install_trace_file(package: str, activity: str, - input_file: str) -> bool: - """Installs a compiled trace file. - - Returns: - Whether the trace file is installed successful or not. - """ - # remote path calculations - compiled_path = _iorapd_path_to_data_file(package, activity, - 'compiled_trace.pb') - - if not os.path.exists(input_file): - print('Error: File {} does not exist'.format(input_file)) - return False - - passed, _ = cmd_utils.run_adb_shell_command( - 'mkdir -p "$(dirname "{}")"'.format(compiled_path)) - if not passed: - return False - - passed, _ = cmd_utils.run_shell_command('adb push "{}" "{}"'.format( - input_file, compiled_path)) - - return passed - -def wait_for_iorapd_finish(package: str, - activity: str, - timeout: int, - debug: bool, - logcat_timestamp: str)->bool: - """Waits for the finish of iorapd. - - Returns: - A bool indicates whether the iorapd is done successfully or not. - """ - # Set verbose for bash script based on debug flag. - if debug: - os.putenv('verbose', 'y') - - # Validate that readahead completes. - # If this fails for some reason, then this will also discard the timing of - # the run. - passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT, - 'iorapd_readahead_wait_until_finished', - [package, activity, logcat_timestamp, - str(timeout)]) - return passed - - -def enable_iorapd_readahead() -> bool: - """ - Disable readahead. Subsequent launches of an application will be sped up - by iorapd readahead prefetching. - - Returns: - A bool indicates whether the enabling is done successfully or not. - """ - passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT, - 'iorapd_readahead_enable', []) - return passed - -def disable_iorapd_readahead() -> bool: - """ - Disable readahead. Subsequent launches of an application will be not be sped - up by iorapd readahead prefetching. - - Returns: - A bool indicates whether the disabling is done successfully or not. - """ - passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT, - 'iorapd_readahead_disable', []) - return passed - -def enable_iorapd_perfetto() -> bool: - """ - Enable Perfetto. Subsequent launches of an application will record a perfetto - trace protobuf. - - Returns: - A bool indicates whether the enabling is done successfully or not. - """ - passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT, - 'iorapd_perfetto_enable', []) - return passed - -def disable_iorapd_perfetto() -> bool: - """ - Disable Perfetto. Subsequent launches of applications will no longer record - perfetto trace protobufs. - - Returns: - A bool indicates whether the disabling is done successfully or not. - """ - passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT, - 'iorapd_perfetto_disable', []) - return passed - -def start_iorapd() -> bool: - """ - Starts iorapd. - - Returns: - A bool indicates whether the starting is done successfully or not. - """ - passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT, - 'iorapd_start', []) - return passed - -def stop_iorapd() -> bool: - """ - Stops iorapd. - - Returns: - A bool indicates whether the stopping is done successfully or not. - """ - passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT, - 'iorapd_stop', []) - return passed - diff --git a/startop/scripts/iorap/pull_textcache b/startop/scripts/iorap/pull_textcache deleted file mode 100755 index 05544263957d..000000000000 --- a/startop/scripts/iorap/pull_textcache +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -# -# Copyright 2019, 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. - -if [[ $# -lt 1 ]]; then - echo "Usage: $0 <output-filename>" >&2 - exit 1 -fi - -# see compiler/main.cc for list of roots -adb shell iorap.inode2filename --output-format=textcache --output=/data/local/tmp/dumpcache --all --root=/system --root=/apex --root=/vendor --root=/data --root=/product --root=/metadata -adb pull /data/local/tmp/dumpcache "$1" diff --git a/startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pb b/startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pb Binary files differdeleted file mode 100644 index a47ad3d5d9ec..000000000000 --- a/startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pb +++ /dev/null diff --git a/startop/scripts/iorap/test_fixtures/compiler/common_systrace b/startop/scripts/iorap/test_fixtures/compiler/common_systrace deleted file mode 100644 index 4573738db5c6..000000000000 --- a/startop/scripts/iorap/test_fixtures/compiler/common_systrace +++ /dev/null @@ -1,5 +0,0 @@ -<...>-2965 (-----) [001] .... 10000.746629: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000679ee1ec pfn=1299913 ofs=192512 -<...>-2965 (-----) [001] .... 10010.746664: mm_filemap_add_to_page_cache: dev 253:6 ino 2 page=0000000006cd2fb7 pfn=1296251 ofs=196608 -<...>-2965 (-----) [001] .... 10020.746677: mm_filemap_add_to_page_cache: dev 253:6 ino 3 page=00000000af82f3d6 pfn=1419330 ofs=200704 -<...>-2965 (-----) [001] .... 10030.746693: mm_filemap_add_to_page_cache: dev 253:6 ino 4 page=000000002840f054 pfn=1304928 ofs=204800 -<...>-2965 (-----) [001] .... 10040.746706: mm_filemap_add_to_page_cache: dev 253:6 ino 5 page=000000004a59da17 pfn=1288069 ofs=208896 diff --git a/startop/scripts/iorap/test_fixtures/compiler/common_textcache b/startop/scripts/iorap/test_fixtures/compiler/common_textcache deleted file mode 100644 index da03004ec6fb..000000000000 --- a/startop/scripts/iorap/test_fixtures/compiler/common_textcache +++ /dev/null @@ -1,2 +0,0 @@ -64774 1 -1 /system/test1 -64774 3 -1 /data/test2 diff --git a/startop/scripts/iorap/test_fixtures/compiler/test_result_systrace b/startop/scripts/iorap/test_fixtures/compiler/test_result_systrace deleted file mode 100644 index 59ff7537180b..000000000000 --- a/startop/scripts/iorap/test_fixtures/compiler/test_result_systrace +++ /dev/null @@ -1,748 +0,0 @@ -TRACE: -# tracer: nop -# -# entries-in-buffer/entries-written: 30624/30624 #P:4 -# -# _-----=> irqs-off -# / _----=> need-resched -# | / _---=> hardirq/softirq -# || / _--=> preempt-depth -# ||| / delay -# TASK-PID TGID CPU# |||| TIMESTAMP FUNCTION -# | | | | |||| | | - <unknown>-27388 (-----) [004] .... 1920260.530929: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1461937 ofs=9535488 - <unknown>-27388 (-----) [005] .... 1920260.532161: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1344589 ofs=9474048 - <unknown>-27388 (-----) [005] .... 1920260.532183: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1153671 ofs=9478144 - <unknown>-27388 (-----) [005] .... 1920260.532184: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1219563 ofs=9482240 - <unknown>-27388 (-----) [005] .... 1920260.532185: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1083162 ofs=9486336 - <unknown>-27388 (-----) [005] .... 1920260.532185: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1147318 ofs=9490432 - <unknown>-27388 (-----) [005] .... 1920260.532186: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1333594 ofs=9494528 - <unknown>-27388 (-----) [005] .... 1920260.532186: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1375715 ofs=9498624 - <unknown>-27388 (-----) [005] .... 1920260.532186: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1184831 ofs=9502720 - <unknown>-27388 (-----) [005] .... 1920260.532187: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1241653 ofs=9506816 - <unknown>-27388 (-----) [005] .... 1920260.532187: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1134975 ofs=9510912 - <unknown>-27388 (-----) [005] .... 1920260.532190: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1145772 ofs=9515008 - <unknown>-27388 (-----) [005] .... 1920260.532190: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1090457 ofs=9519104 - <unknown>-27388 (-----) [005] .... 1920260.532190: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1137942 ofs=9523200 - <unknown>-27388 (-----) [005] .... 1920260.532191: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1130123 ofs=9527296 - <unknown>-27388 (-----) [005] .... 1920260.532191: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1208783 ofs=9531392 - <unknown>-27388 (-----) [005] .... 1920260.532192: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1294989 ofs=9539584 - <unknown>-27388 (-----) [005] .... 1920260.532206: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1163979 ofs=9543680 - <unknown>-27388 (-----) [005] .... 1920260.532206: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1350628 ofs=9547776 - <unknown>-27388 (-----) [005] .... 1920260.532206: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1386717 ofs=9551872 - <unknown>-27388 (-----) [005] .... 1920260.532207: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1316148 ofs=9555968 - <unknown>-27388 (-----) [005] .... 1920260.532208: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1316419 ofs=9560064 - <unknown>-27388 (-----) [005] .... 1920260.532208: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1149076 ofs=9564160 - <unknown>-27388 (-----) [005] .... 1920260.532209: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1372772 ofs=9568256 - <unknown>-27388 (-----) [005] .... 1920260.532209: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1116389 ofs=9572352 - <unknown>-27388 (-----) [005] .... 1920260.532211: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1325458 ofs=9576448 - <unknown>-27388 (-----) [005] .... 1920260.532211: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1195423 ofs=9580544 - <unknown>-27388 (-----) [005] .... 1920260.532211: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1250964 ofs=9584640 - <unknown>-27388 (-----) [005] .... 1920260.532212: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1196027 ofs=9588736 - <unknown>-27388 (-----) [005] .... 1920260.532212: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1354059 ofs=9592832 - <unknown>-27388 (-----) [005] .... 1920260.532213: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1264649 ofs=9596928 - <unknown>-27388 (-----) [005] .... 1920260.532213: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1245285 ofs=9601024 - <unknown>-27388 (-----) [005] .... 1920260.535119: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1411552 ofs=44244992 - <unknown>-27388 (-----) [005] .... 1920260.535129: mm_filemap_add_to_page_cache: dev 0:3 ino 0 page=0000000000000000 pfn=1483081 ofs=433524736 - <unknown>-27388 (-----) [004] .... 1920260.536144: mm_filemap_add_to_page_cache: dev 0:3 ino 0 page=0000000000000000 pfn=1276173 ofs=438185984 - <unknown>-27388 (-----) [004] .... 1920260.536462: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1174575 ofs=44249088 - <unknown>-27388 (-----) [004] .... 1920260.536464: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1126294 ofs=44253184 - <unknown>-27388 (-----) [004] .... 1920260.536464: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1248232 ofs=44257280 - <unknown>-27388 (-----) [004] .... 1920260.537065: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1332993 ofs=44240896 - <unknown>-27388 (-----) [006] .... 1920260.537646: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1153343 ofs=44400640 - <unknown>-27388 (-----) [005] .... 1920260.538777: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1358397 ofs=44474368 - <unknown>-12683 (-----) [006] .... 1920260.560094: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1426577 ofs=0 - <unknown>-12683 (-----) [006] .... 1920260.560105: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1117587 ofs=1171456 - <unknown>-12683 (-----) [006] .... 1920260.561199: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099987 ofs=4096 - <unknown>-12683 (-----) [006] .... 1920260.561411: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099910 ofs=16384 - <unknown>-12683 (-----) [006] .... 1920260.561598: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099905 ofs=20480 - <unknown>-12683 (-----) [006] .... 1920260.561758: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099883 ofs=32768 - <unknown>-12683 (-----) [006] .... 1920260.562088: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099809 ofs=36864 - <unknown>-12683 (-----) [006] .... 1920260.562325: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099803 ofs=98304 - <unknown>-12683 (-----) [006] .... 1920260.562516: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099795 ofs=102400 - <unknown>-12683 (-----) [006] .... 1920260.563094: mm_filemap_add_to_page_cache: dev 0:64768 ino 5f3 page=0000000000000000 pfn=1107649 ofs=12288 - <unknown>-12683 (-----) [006] .... 1920260.563105: mm_filemap_add_to_page_cache: dev 0:64768 ino 5f3 page=0000000000000000 pfn=1269029 ofs=16384 - <unknown>-12683 (-----) [006] .... 1920260.563785: mm_filemap_add_to_page_cache: dev 0:64768 ino 4da page=0000000000000000 pfn=1451096 ofs=8192 - <unknown>-12683 (-----) [006] .... 1920260.563790: mm_filemap_add_to_page_cache: dev 0:64768 ino 4da page=0000000000000000 pfn=1301480 ofs=12288 - <unknown>-12683 (-----) [006] .... 1920260.563790: mm_filemap_add_to_page_cache: dev 0:64768 ino 4da page=0000000000000000 pfn=1314353 ofs=16384 - <unknown>-12683 (-----) [006] .... 1920260.563791: mm_filemap_add_to_page_cache: dev 0:64768 ino 4da page=0000000000000000 pfn=1216744 ofs=24576 - <unknown>-12683 (-----) [006] .... 1920260.564309: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099787 ofs=49152 - <unknown>-12683 (-----) [006] .... 1920260.564514: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099778 ofs=53248 - <unknown>-12683 (-----) [005] .... 1920260.564756: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1148849 ofs=114688 - <unknown>-12683 (-----) [005] .... 1920260.564973: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1164731 ofs=118784 - <unknown>-12683 (-----) [005] .... 1920260.565000: mm_filemap_add_to_page_cache: dev 0:2053 ino 1a page=0000000000000000 pfn=1170255 ofs=0 - <unknown>-12683 (-----) [005] .... 1920260.565003: mm_filemap_add_to_page_cache: dev 0:2053 ino 1a page=0000000000000000 pfn=1181043 ofs=4096 - <unknown>-12683 (-----) [005] .... 1920260.565004: mm_filemap_add_to_page_cache: dev 0:2053 ino 1a page=0000000000000000 pfn=1296004 ofs=8192 - <unknown>-12683 (-----) [005] .... 1920260.565004: mm_filemap_add_to_page_cache: dev 0:2053 ino 1a page=0000000000000000 pfn=1102004 ofs=12288 - <unknown>-12683 (-----) [005] .... 1920260.565626: mm_filemap_add_to_page_cache: dev 0:3 ino 0 page=0000000000000000 pfn=1351232 ofs=470597632 - <unknown>-12683 (-----) [005] .... 1920260.565982: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1391336 ofs=40210432 - <unknown>-12683 (-----) [005] .... 1920260.565985: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1267536 ofs=12668928 - <unknown>-27388 (-----) [007] .... 1920260.566082: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1256752 ofs=43921408 - <unknown>-12683 (-----) [005] .... 1920260.566516: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1110966 ofs=176226304 - <unknown>-12683 (-----) [005] .... 1920260.566519: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1060586 ofs=12967936 - <unknown>-12683 (-----) [004] .... 1920260.567773: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1117234 ofs=421888 - <unknown>-12683 (-----) [005] .... 1920260.568604: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1210571 ofs=430080 - <unknown>-12683 (-----) [005] .... 1920260.568887: mm_filemap_add_to_page_cache: dev 0:64771 ino 69 page=0000000000000000 pfn=1055640 ofs=0 - <unknown>-12683 (-----) [005] .... 1920260.568908: mm_filemap_add_to_page_cache: dev 0:64771 ino 49 page=0000000000000000 pfn=1142694 ofs=0 - <unknown>-12683 (-----) [005] .... 1920260.568910: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1060788 ofs=299008 - <unknown>-12683 (-----) [005] .... 1920260.569418: mm_filemap_add_to_page_cache: dev 0:64771 ino 49 page=0000000000000000 pfn=1085046 ofs=4096 - <unknown>-12683 (-----) [005] .... 1920260.569640: mm_filemap_add_to_page_cache: dev 0:64771 ino 49 page=0000000000000000 pfn=1057135 ofs=8192 - <unknown>-12683 (-----) [005] .... 1920260.569833: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1058976 ofs=19406848 - <unknown>-12683 (-----) [005] .... 1920260.569835: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1477947 ofs=10526720 - <unknown>-12683 (-----) [005] .... 1920260.572285: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1237492 ofs=299008 - <unknown>-12683 (-----) [005] .... 1920260.572297: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1264914 ofs=339968 - <unknown>-12683 (-----) [005] .... 1920260.572314: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1434748 ofs=348160 - <unknown>-12683 (-----) [005] .... 1920260.572316: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1372959 ofs=352256 - <unknown>-12683 (-----) [005] .... 1920260.572317: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1258955 ofs=356352 - <unknown>-12683 (-----) [005] .... 1920260.572317: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1113420 ofs=360448 - <unknown>-12683 (-----) [005] .... 1920260.572318: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1137083 ofs=364544 - <unknown>-12683 (-----) [004] .... 1920260.575490: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1379679 ofs=65536 - <unknown>-12683 (-----) [006] .... 1920260.576194: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1323898 ofs=69632 - <unknown>-12683 (-----) [006] .... 1920260.576248: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323895 ofs=262623232 - <unknown>-12683 (-----) [006] .... 1920260.576251: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1323861 ofs=13156352 - <unknown>-12683 (-----) [005] .... 1920260.576810: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1477585 ofs=262590464 - <unknown>-12683 (-----) [004] .... 1920260.577197: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1267617 ofs=25206784 - <unknown>-12683 (-----) [004] .... 1920260.577200: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1267618 ofs=12636160 - <unknown>-12683 (-----) [005] .... 1920260.577725: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1056225 ofs=228618240 - <unknown>-12683 (-----) [005] .... 1920260.577727: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1164942 ofs=13082624 - <unknown>-12683 (-----) [007] .... 1920260.578411: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1372616 ofs=0 - <unknown>-12683 (-----) [007] .... 1920260.578422: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1307468 ofs=4096 - <unknown>-12683 (-----) [007] .... 1920260.578428: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1120117 ofs=8192 - <unknown>-12683 (-----) [007] .... 1920260.578428: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1217989 ofs=12288 - <unknown>-12683 (-----) [007] .... 1920260.578650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1475011 ofs=5419008 - <unknown>-12683 (-----) [007] .... 1920260.578653: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1066084 ofs=236453888 - <unknown>-12683 (-----) [007] .... 1920260.578654: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1100271 ofs=13099008 - <unknown>-12683 (-----) [004] .... 1920260.579004: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1485156 ofs=5423104 - <unknown>-12683 (-----) [004] .... 1920260.579005: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1124212 ofs=5427200 - <unknown>-12683 (-----) [004] .... 1920260.579006: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1195377 ofs=5431296 - <unknown>-12683 (-----) [004] .... 1920260.579006: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1265888 ofs=5435392 - <unknown>-12683 (-----) [004] .... 1920260.579007: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1170194 ofs=5439488 - <unknown>-12683 (-----) [004] .... 1920260.579007: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1403742 ofs=5443584 - <unknown>-12683 (-----) [004] .... 1920260.579008: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1123826 ofs=5447680 - <unknown>-12683 (-----) [004] .... 1920260.579008: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1255034 ofs=5451776 - <unknown>-12683 (-----) [004] .... 1920260.579011: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1190447 ofs=5455872 - <unknown>-12683 (-----) [004] .... 1920260.579011: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1286864 ofs=5459968 - <unknown>-12683 (-----) [004] .... 1920260.579012: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1428535 ofs=5464064 - <unknown>-12683 (-----) [004] .... 1920260.579012: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1184092 ofs=5468160 - <unknown>-12683 (-----) [004] .... 1920260.579013: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1411906 ofs=5472256 - <unknown>-12683 (-----) [004] .... 1920260.579013: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1342349 ofs=5476352 - <unknown>-12683 (-----) [004] .... 1920260.579013: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1188185 ofs=5480448 - <unknown>-12683 (-----) [004] .... 1920260.579014: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1158702 ofs=5484544 - <unknown>-12683 (-----) [005] .... 1920260.579430: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1299421 ofs=5230592 - <unknown>-12683 (-----) [005] .... 1920260.579435: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1317097 ofs=5234688 - <unknown>-12683 (-----) [005] .... 1920260.579435: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1441714 ofs=5238784 - <unknown>-12683 (-----) [005] .... 1920260.579438: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1081974 ofs=5242880 - <unknown>-12683 (-----) [005] .... 1920260.579439: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1128684 ofs=5246976 - <unknown>-12683 (-----) [005] .... 1920260.579439: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1447381 ofs=5251072 - <unknown>-12683 (-----) [005] .... 1920260.579440: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1466410 ofs=5255168 - <unknown>-12683 (-----) [005] .... 1920260.579440: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1259909 ofs=5259264 - <unknown>-12683 (-----) [005] .... 1920260.579441: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1125784 ofs=5263360 - <unknown>-12683 (-----) [005] .... 1920260.579441: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1270592 ofs=5267456 - <unknown>-12683 (-----) [005] .... 1920260.579442: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1246070 ofs=5271552 - <unknown>-12683 (-----) [005] .... 1920260.579442: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1472544 ofs=5275648 - <unknown>-12683 (-----) [005] .... 1920260.579442: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1113357 ofs=5279744 - <unknown>-12683 (-----) [005] .... 1920260.579443: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1202021 ofs=5283840 - <unknown>-12683 (-----) [005] .... 1920260.579443: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1078639 ofs=5287936 - <unknown>-12683 (-----) [005] .... 1920260.579449: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1176171 ofs=5292032 - <unknown>-12683 (-----) [005] .... 1920260.579450: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1089516 ofs=5296128 - <unknown>-12683 (-----) [005] .... 1920260.579451: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1400065 ofs=5300224 - <unknown>-12683 (-----) [005] .... 1920260.579452: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1300489 ofs=5304320 - <unknown>-12683 (-----) [005] .... 1920260.579452: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1452081 ofs=5308416 - <unknown>-12683 (-----) [005] .... 1920260.579452: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1161862 ofs=5312512 - <unknown>-12683 (-----) [005] .... 1920260.579453: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1161871 ofs=5316608 - <unknown>-12683 (-----) [005] .... 1920260.579453: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1263798 ofs=5320704 - <unknown>-12683 (-----) [005] .... 1920260.579454: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1126887 ofs=5324800 - <unknown>-12683 (-----) [005] .... 1920260.579454: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1375498 ofs=5328896 - <unknown>-12683 (-----) [005] .... 1920260.579455: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1328067 ofs=5332992 - <unknown>-12683 (-----) [005] .... 1920260.579455: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1420691 ofs=5337088 - <unknown>-12683 (-----) [005] .... 1920260.579456: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1298707 ofs=5341184 - <unknown>-12683 (-----) [005] .... 1920260.579456: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1078670 ofs=5345280 - <unknown>-12683 (-----) [005] .... 1920260.579457: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1430498 ofs=5349376 - <unknown>-12683 (-----) [005] .... 1920260.579458: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1338720 ofs=5353472 - <unknown>-12683 (-----) [005] .... 1920260.579476: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1452611 ofs=5357568 - <unknown>-12683 (-----) [006] .... 1920260.580451: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1241967 ofs=0 - <unknown>-12683 (-----) [006] .... 1920260.580454: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1116541 ofs=4096 - <unknown>-12683 (-----) [006] .... 1920260.580461: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1145049 ofs=8192 - <unknown>-12683 (-----) [006] .... 1920260.580462: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1277255 ofs=12288 - <unknown>-12683 (-----) [006] .... 1920260.580462: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1098037 ofs=16384 - <unknown>-12683 (-----) [006] .... 1920260.580463: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1135986 ofs=20480 - <unknown>-12683 (-----) [006] .... 1920260.580464: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1154455 ofs=24576 - <unknown>-12683 (-----) [006] .... 1920260.580464: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1221822 ofs=28672 - <unknown>-12683 (-----) [006] .... 1920260.580465: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1078684 ofs=32768 - <unknown>-12683 (-----) [006] .... 1920260.580465: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1158876 ofs=36864 - <unknown>-12683 (-----) [006] .... 1920260.580465: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1289644 ofs=40960 - <unknown>-12683 (-----) [006] .... 1920260.580466: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1289386 ofs=45056 - <unknown>-12683 (-----) [006] .... 1920260.580466: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1131002 ofs=49152 - <unknown>-12683 (-----) [006] .... 1920260.580467: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1464335 ofs=53248 - <unknown>-12683 (-----) [006] .... 1920260.580468: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1135789 ofs=57344 - <unknown>-12683 (-----) [006] .... 1920260.580469: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1240897 ofs=61440 - <unknown>-12683 (-----) [006] .... 1920260.580469: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1241770 ofs=65536 - <unknown>-12683 (-----) [006] .... 1920260.580470: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1421959 ofs=69632 - <unknown>-12683 (-----) [006] .... 1920260.580470: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1230007 ofs=73728 - <unknown>-12683 (-----) [006] .... 1920260.580471: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1109271 ofs=77824 - <unknown>-12683 (-----) [006] .... 1920260.580471: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1159974 ofs=81920 - <unknown>-12683 (-----) [006] .... 1920260.580471: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1154528 ofs=86016 - <unknown>-12683 (-----) [006] .... 1920260.580472: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1315790 ofs=90112 - <unknown>-12683 (-----) [006] .... 1920260.580473: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1185583 ofs=94208 - <unknown>-12683 (-----) [006] .... 1920260.580473: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1253153 ofs=98304 - <unknown>-12683 (-----) [006] .... 1920260.580473: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103982 ofs=102400 - <unknown>-12683 (-----) [006] .... 1920260.580474: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1284589 ofs=106496 - <unknown>-12683 (-----) [006] .... 1920260.580474: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1169601 ofs=110592 - <unknown>-12683 (-----) [006] .... 1920260.580476: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1206248 ofs=114688 - <unknown>-12683 (-----) [006] .... 1920260.580476: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1261161 ofs=118784 - <unknown>-12683 (-----) [006] .... 1920260.580477: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1305841 ofs=122880 - <unknown>-12683 (-----) [006] .... 1920260.580477: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1468293 ofs=126976 - <unknown>-12683 (-----) [004] .... 1920260.580646: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1318816 ofs=16384 - <unknown>-12683 (-----) [004] .... 1920260.580649: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1472922 ofs=20480 - <unknown>-12683 (-----) [004] .... 1920260.580650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1473229 ofs=24576 - <unknown>-12683 (-----) [004] .... 1920260.580650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1524262 ofs=28672 - <unknown>-12683 (-----) [004] .... 1920260.580656: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1205714 ofs=32768 - <unknown>-12683 (-----) [004] .... 1920260.580657: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1310560 ofs=36864 - <unknown>-12683 (-----) [004] .... 1920260.580658: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1295070 ofs=40960 - <unknown>-12683 (-----) [004] .... 1920260.580659: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1404093 ofs=45056 - <unknown>-12683 (-----) [004] .... 1920260.580659: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1435814 ofs=49152 - <unknown>-12683 (-----) [004] .... 1920260.580660: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1435442 ofs=53248 - <unknown>-12683 (-----) [004] .... 1920260.580660: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1096077 ofs=57344 - <unknown>-12683 (-----) [004] .... 1920260.580661: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1483793 ofs=61440 - <unknown>-12683 (-----) [004] .... 1920260.580661: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1231298 ofs=65536 - <unknown>-12683 (-----) [004] .... 1920260.580661: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1215648 ofs=69632 - <unknown>-12683 (-----) [004] .... 1920260.580662: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1327326 ofs=73728 - <unknown>-12683 (-----) [004] .... 1920260.580662: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1108894 ofs=77824 - <unknown>-12683 (-----) [004] .... 1920260.580663: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1327545 ofs=81920 - <unknown>-12683 (-----) [004] .... 1920260.580663: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1328804 ofs=86016 - <unknown>-12683 (-----) [004] .... 1920260.580664: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1300171 ofs=90112 - <unknown>-12683 (-----) [004] .... 1920260.580664: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1353250 ofs=94208 - <unknown>-12683 (-----) [004] .... 1920260.580668: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1333681 ofs=98304 - <unknown>-12683 (-----) [004] .... 1920260.580668: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1144969 ofs=102400 - <unknown>-12683 (-----) [004] .... 1920260.580669: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1450962 ofs=106496 - <unknown>-12683 (-----) [004] .... 1920260.580669: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1255701 ofs=110592 - <unknown>-12683 (-----) [004] .... 1920260.580670: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1294782 ofs=114688 - <unknown>-12683 (-----) [004] .... 1920260.580670: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1226912 ofs=118784 - <unknown>-12683 (-----) [004] .... 1920260.580671: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1294579 ofs=122880 - <unknown>-12683 (-----) [004] .... 1920260.580671: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1246960 ofs=126976 - <unknown>-12683 (-----) [004] .... 1920260.580671: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1199086 ofs=131072 - <unknown>-12683 (-----) [004] .... 1920260.580672: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1449590 ofs=135168 - <unknown>-12683 (-----) [004] .... 1920260.580672: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1276363 ofs=139264 - <unknown>-12683 (-----) [004] .... 1920260.580675: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1389998 ofs=143360 - <unknown>-12683 (-----) [004] .... 1920260.580739: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1423031 ofs=1249280 - <unknown>-12683 (-----) [004] .... 1920260.580741: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1171032 ofs=1253376 - <unknown>-12683 (-----) [004] .... 1920260.580742: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1320946 ofs=1257472 - <unknown>-12683 (-----) [004] .... 1920260.580743: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1314696 ofs=1261568 - <unknown>-12683 (-----) [004] .... 1920260.580743: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1414864 ofs=1265664 - <unknown>-12683 (-----) [004] .... 1920260.580744: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1334933 ofs=1269760 - <unknown>-12683 (-----) [004] .... 1920260.580744: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1242845 ofs=1273856 - <unknown>-12683 (-----) [004] .... 1920260.580747: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1289488 ofs=1277952 - <unknown>-12683 (-----) [004] .... 1920260.580748: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1335445 ofs=1282048 - <unknown>-12683 (-----) [004] .... 1920260.580748: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1289663 ofs=1286144 - <unknown>-12683 (-----) [004] .... 1920260.580749: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1080462 ofs=1290240 - <unknown>-12683 (-----) [004] .... 1920260.580749: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1286303 ofs=1294336 - <unknown>-12683 (-----) [004] .... 1920260.580750: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1353531 ofs=1298432 - <unknown>-12683 (-----) [004] .... 1920260.580750: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1280701 ofs=1302528 - <unknown>-12683 (-----) [004] .... 1920260.580751: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1107730 ofs=1306624 - <unknown>-12683 (-----) [004] .... 1920260.580752: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1242729 ofs=1310720 - <unknown>-12683 (-----) [004] .... 1920260.580753: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1078336 ofs=1314816 - <unknown>-12683 (-----) [004] .... 1920260.580753: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1372425 ofs=1318912 - <unknown>-12683 (-----) [004] .... 1920260.580754: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1248813 ofs=1323008 - <unknown>-12683 (-----) [004] .... 1920260.580754: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1201155 ofs=1327104 - <unknown>-12683 (-----) [004] .... 1920260.580755: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1250103 ofs=1331200 - <unknown>-12683 (-----) [004] .... 1920260.580755: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1359710 ofs=1335296 - <unknown>-12683 (-----) [004] .... 1920260.580756: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1272462 ofs=1339392 - <unknown>-12683 (-----) [004] .... 1920260.580758: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1097035 ofs=1343488 - <unknown>-12683 (-----) [004] .... 1920260.580759: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1233124 ofs=1347584 - <unknown>-12683 (-----) [004] .... 1920260.580759: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1455812 ofs=1351680 - <unknown>-12683 (-----) [004] .... 1920260.580759: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1355689 ofs=1355776 - <unknown>-12683 (-----) [004] .... 1920260.580760: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1263593 ofs=1359872 - <unknown>-12683 (-----) [004] .... 1920260.580760: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1230789 ofs=1363968 - <unknown>-12683 (-----) [004] .... 1920260.580761: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1143766 ofs=1368064 - <unknown>-12683 (-----) [004] .... 1920260.580762: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1269666 ofs=1372160 - <unknown>-12683 (-----) [004] .... 1920260.580762: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1353022 ofs=1376256 - <unknown>-12683 (-----) [004] .... 1920260.581613: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1355509 ofs=258048 - <unknown>-12683 (-----) [004] .... 1920260.581615: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1178902 ofs=262144 - <unknown>-12683 (-----) [004] .... 1920260.581616: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1193649 ofs=266240 - <unknown>-12683 (-----) [004] .... 1920260.581618: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1225497 ofs=270336 - <unknown>-12683 (-----) [004] .... 1920260.581618: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1228259 ofs=274432 - <unknown>-12683 (-----) [004] .... 1920260.581635: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1309674 ofs=278528 - <unknown>-12683 (-----) [004] .... 1920260.581635: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1239390 ofs=282624 - <unknown>-12683 (-----) [004] .... 1920260.581636: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1468083 ofs=286720 - <unknown>-12683 (-----) [004] .... 1920260.581636: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1292751 ofs=290816 - <unknown>-12683 (-----) [004] .... 1920260.581637: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1318066 ofs=294912 - <unknown>-12683 (-----) [004] .... 1920260.581637: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1489314 ofs=299008 - <unknown>-12683 (-----) [004] .... 1920260.581637: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1169867 ofs=303104 - <unknown>-12683 (-----) [004] .... 1920260.581639: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1314256 ofs=307200 - <unknown>-12683 (-----) [004] .... 1920260.581639: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1310230 ofs=311296 - <unknown>-12683 (-----) [004] .... 1920260.581640: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1356180 ofs=315392 - <unknown>-12683 (-----) [004] .... 1920260.581640: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1419179 ofs=319488 - <unknown>-12683 (-----) [004] .... 1920260.581641: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1307265 ofs=323584 - <unknown>-12683 (-----) [004] .... 1920260.581641: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1218590 ofs=327680 - <unknown>-12683 (-----) [004] .... 1920260.581642: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1447586 ofs=331776 - <unknown>-12683 (-----) [004] .... 1920260.581642: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1209382 ofs=335872 - <unknown>-12683 (-----) [004] .... 1920260.581642: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1072148 ofs=339968 - <unknown>-12683 (-----) [004] .... 1920260.581645: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1227195 ofs=344064 - <unknown>-12683 (-----) [004] .... 1920260.581646: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1246369 ofs=348160 - <unknown>-12683 (-----) [004] .... 1920260.581646: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1193845 ofs=352256 - <unknown>-12683 (-----) [004] .... 1920260.581647: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1137553 ofs=356352 - <unknown>-12683 (-----) [004] .... 1920260.581647: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1475215 ofs=360448 - <unknown>-12683 (-----) [004] .... 1920260.581648: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1258935 ofs=364544 - <unknown>-12683 (-----) [004] .... 1920260.581649: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1448788 ofs=368640 - <unknown>-12683 (-----) [004] .... 1920260.581649: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1447611 ofs=372736 - <unknown>-12683 (-----) [004] .... 1920260.581650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1290842 ofs=376832 - <unknown>-12683 (-----) [004] .... 1920260.581650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1447826 ofs=380928 - <unknown>-12683 (-----) [004] .... 1920260.581650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1181016 ofs=385024 - <unknown>-12683 (-----) [005] .... 1920260.582230: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1216810 ofs=1662976 - <unknown>-12683 (-----) [005] .... 1920260.582234: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1175966 ofs=1667072 - <unknown>-12683 (-----) [005] .... 1920260.582235: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1449798 ofs=1671168 - <unknown>-12683 (-----) [005] .... 1920260.582236: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1273480 ofs=1675264 - <unknown>-12683 (-----) [005] .... 1920260.582236: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1152779 ofs=1679360 - <unknown>-12683 (-----) [005] .... 1920260.582237: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1272810 ofs=1683456 - <unknown>-12683 (-----) [005] .... 1920260.582237: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1248634 ofs=1687552 - <unknown>-12683 (-----) [005] .... 1920260.582237: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1203376 ofs=1691648 - <unknown>-12683 (-----) [005] .... 1920260.582238: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1138880 ofs=1695744 - <unknown>-12683 (-----) [005] .... 1920260.582238: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1344591 ofs=1699840 - <unknown>-12683 (-----) [005] .... 1920260.582239: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1416060 ofs=1703936 - <unknown>-12683 (-----) [005] .... 1920260.582246: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1128676 ofs=1708032 - <unknown>-12683 (-----) [005] .... 1920260.582247: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1301921 ofs=1712128 - <unknown>-12683 (-----) [005] .... 1920260.582248: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1384569 ofs=1716224 - <unknown>-12683 (-----) [005] .... 1920260.582248: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1249106 ofs=1720320 - <unknown>-12683 (-----) [005] .... 1920260.582249: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1206596 ofs=1724416 - <unknown>-12683 (-----) [005] .... 1920260.582249: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1429831 ofs=1728512 - <unknown>-12683 (-----) [005] .... 1920260.582252: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1107796 ofs=1732608 - <unknown>-12683 (-----) [005] .... 1920260.582255: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1098336 ofs=1736704 - <unknown>-12683 (-----) [005] .... 1920260.582255: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1230286 ofs=1740800 - <unknown>-12683 (-----) [005] .... 1920260.582256: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1100370 ofs=1744896 - <unknown>-12683 (-----) [005] .... 1920260.582256: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1241930 ofs=1748992 - <unknown>-12683 (-----) [005] .... 1920260.582257: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1366807 ofs=1753088 - <unknown>-12683 (-----) [005] .... 1920260.582257: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1136252 ofs=1757184 - <unknown>-12683 (-----) [005] .... 1920260.582258: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1274291 ofs=1761280 - <unknown>-12683 (-----) [005] .... 1920260.582258: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1254775 ofs=1765376 - <unknown>-12683 (-----) [005] .... 1920260.582259: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1194679 ofs=1769472 - <unknown>-12683 (-----) [005] .... 1920260.582262: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1177090 ofs=1773568 - <unknown>-12683 (-----) [005] .... 1920260.582263: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1343925 ofs=1777664 - <unknown>-12683 (-----) [005] .... 1920260.582263: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1159217 ofs=1781760 - <unknown>-12683 (-----) [005] .... 1920260.582263: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1435471 ofs=1785856 - <unknown>-12683 (-----) [005] .... 1920260.582264: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1435529 ofs=1789952 - <unknown>-12683 (-----) [004] .... 1920260.582524: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1181910 ofs=0 - <unknown>-12683 (-----) [004] .... 1920260.582528: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1212021 ofs=4096 - <unknown>-12683 (-----) [004] .... 1920260.582529: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1162778 ofs=8192 - <unknown>-12683 (-----) [004] .... 1920260.582529: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1107700 ofs=12288 - <unknown>-12683 (-----) [004] .... 1920260.583553: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1093394 ofs=3399680 - <unknown>-12683 (-----) [004] .... 1920260.583984: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1121431 ofs=242503680 - <unknown>-12683 (-----) [004] .... 1920260.583986: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1168551 ofs=13115392 - <unknown>-12683 (-----) [004] .... 1920260.584304: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1347409 ofs=0 - <unknown>-12683 (-----) [004] .... 1920260.584307: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1428681 ofs=4096 - <unknown>-12683 (-----) [004] .... 1920260.584307: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1259106 ofs=8192 - <unknown>-12683 (-----) [004] .... 1920260.584308: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1343229 ofs=12288 - <unknown>-12694 (-----) [005] .... 1920260.584622: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1098733 ofs=1531904 - <unknown>-12696 (-----) [006] .... 1920260.584626: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331319 ofs=1536000 - <unknown>-12694 (-----) [005] .... 1920260.584626: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1278537 ofs=1540096 - <unknown>-12696 (-----) [006] .... 1920260.584631: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1492534 ofs=1544192 - <unknown>-12694 (-----) [005] .... 1920260.584636: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1460878 ofs=1548288 - <unknown>-12694 (-----) [005] .... 1920260.584640: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092973 ofs=1552384 - <unknown>-12694 (-----) [005] .... 1920260.584641: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1103200 ofs=1556480 - <unknown>-12694 (-----) [005] .... 1920260.584642: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1257426 ofs=1560576 - <unknown>-12694 (-----) [005] .... 1920260.584642: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1219424 ofs=1564672 - <unknown>-12683 (-----) [004] .... 1920260.584660: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1279352 ofs=1568768 - <unknown>-12696 (-----) [006] .... 1920260.584662: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1260572 ofs=1572864 - <unknown>-12683 (-----) [004] .... 1920260.584663: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1225809 ofs=1576960 - <unknown>-12696 (-----) [006] .... 1920260.584665: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1350766 ofs=1585152 - <unknown>-12697 (-----) [007] .... 1920260.584666: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1107173 ofs=1581056 - <unknown>-12683 (-----) [004] .... 1920260.584668: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1305885 ofs=1589248 - <unknown>-12694 (-----) [005] .... 1920260.584669: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1293385 ofs=1593344 - <unknown>-12696 (-----) [006] .... 1920260.584670: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1173841 ofs=1597440 - <unknown>-12697 (-----) [007] .... 1920260.584670: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1080021 ofs=1601536 - <unknown>-12683 (-----) [004] .... 1920260.584673: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1147419 ofs=1605632 - <unknown>-12696 (-----) [006] .... 1920260.584673: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1252762 ofs=1609728 - <unknown>-12694 (-----) [005] .... 1920260.584674: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1323916 ofs=1613824 - <unknown>-12683 (-----) [004] .... 1920260.584675: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1155631 ofs=1617920 - <unknown>-12696 (-----) [006] .... 1920260.584676: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1449815 ofs=1622016 - <unknown>-12694 (-----) [005] .... 1920260.584678: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1227069 ofs=1626112 - <unknown>-12696 (-----) [006] .... 1920260.584680: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1317692 ofs=1630208 - <unknown>-12694 (-----) [005] .... 1920260.584681: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1492244 ofs=1634304 - <unknown>-12683 (-----) [004] .... 1920260.584682: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1241876 ofs=1638400 - <unknown>-12697 (-----) [007] .... 1920260.585446: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1402958 ofs=167936 - <unknown>-12697 (-----) [007] .... 1920260.585449: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1133263 ofs=172032 - <unknown>-12697 (-----) [007] .... 1920260.585450: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1295502 ofs=176128 - <unknown>-12697 (-----) [007] .... 1920260.585450: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1249495 ofs=180224 - <unknown>-12697 (-----) [007] .... 1920260.585451: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1237999 ofs=184320 - <unknown>-12697 (-----) [007] .... 1920260.585451: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1280965 ofs=188416 - <unknown>-12697 (-----) [007] .... 1920260.585454: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1208361 ofs=192512 - <unknown>-12697 (-----) [007] .... 1920260.585454: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1308840 ofs=196608 - <unknown>-12695 (-----) [004] .... 1920260.585455: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1138875 ofs=569344 - <unknown>-12695 (-----) [004] .... 1920260.585458: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1314886 ofs=573440 - <unknown>-12697 (-----) [007] .... 1920260.585458: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242734 ofs=200704 - <unknown>-12695 (-----) [004] .... 1920260.585458: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1447386 ofs=577536 - <unknown>-12697 (-----) [007] .... 1920260.585459: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1241302 ofs=204800 - <unknown>-12695 (-----) [004] .... 1920260.585459: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1328663 ofs=581632 - <unknown>-12697 (-----) [007] .... 1920260.585459: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1476101 ofs=208896 - <unknown>-12695 (-----) [004] .... 1920260.585460: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1209461 ofs=585728 - <unknown>-12697 (-----) [007] .... 1920260.585460: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1080147 ofs=212992 - <unknown>-12697 (-----) [007] .... 1920260.585461: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1128509 ofs=217088 - <unknown>-12697 (-----) [007] .... 1920260.585461: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1371915 ofs=221184 - <unknown>-12697 (-----) [007] .... 1920260.585461: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1264015 ofs=225280 - <unknown>-12697 (-----) [007] .... 1920260.585462: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1211695 ofs=229376 - <unknown>-12697 (-----) [007] .... 1920260.585462: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1150386 ofs=233472 - <unknown>-12697 (-----) [007] .... 1920260.585463: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1135747 ofs=237568 - <unknown>-12697 (-----) [007] .... 1920260.585463: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1128230 ofs=241664 - <unknown>-12697 (-----) [007] .... 1920260.585464: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1155451 ofs=245760 - <unknown>-12697 (-----) [007] .... 1920260.585465: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1246841 ofs=249856 - <unknown>-12697 (-----) [007] .... 1920260.585465: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1462971 ofs=253952 - <unknown>-12697 (-----) [007] .... 1920260.585466: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1131333 ofs=258048 - <unknown>-12697 (-----) [007] .... 1920260.585466: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1289407 ofs=262144 - <unknown>-12695 (-----) [004] .... 1920260.585467: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1134730 ofs=589824 - <unknown>-12697 (-----) [007] .... 1920260.585467: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1289873 ofs=266240 - <unknown>-12697 (-----) [007] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1448734 ofs=270336 - <unknown>-12695 (-----) [004] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1129776 ofs=593920 - <unknown>-12697 (-----) [007] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1524090 ofs=274432 - <unknown>-12695 (-----) [004] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1399725 ofs=598016 - <unknown>-12697 (-----) [007] .... 1920260.585469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1524081 ofs=278528 - <unknown>-12695 (-----) [004] .... 1920260.585469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1276535 ofs=602112 - <unknown>-12697 (-----) [007] .... 1920260.585469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1524060 ofs=282624 - <unknown>-12695 (-----) [004] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1449847 ofs=606208 - <unknown>-12697 (-----) [007] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1158944 ofs=286720 - <unknown>-12695 (-----) [004] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1384536 ofs=610304 - <unknown>-12697 (-----) [007] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1116785 ofs=290816 - <unknown>-12695 (-----) [004] .... 1920260.585471: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1308118 ofs=614400 - <unknown>-12697 (-----) [007] .... 1920260.585471: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1448669 ofs=294912 - <unknown>-12695 (-----) [004] .... 1920260.585471: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1227050 ofs=618496 - <unknown>-12695 (-----) [004] .... 1920260.585473: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1289324 ofs=622592 - <unknown>-12695 (-----) [004] .... 1920260.585473: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1187869 ofs=626688 - <unknown>-12695 (-----) [004] .... 1920260.585474: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1400523 ofs=630784 - <unknown>-12695 (-----) [004] .... 1920260.585474: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1344176 ofs=634880 - <unknown>-12695 (-----) [004] .... 1920260.585475: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092871 ofs=638976 - <unknown>-12695 (-----) [004] .... 1920260.585475: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092021 ofs=643072 - <unknown>-12695 (-----) [004] .... 1920260.585476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1198169 ofs=647168 - <unknown>-12695 (-----) [004] .... 1920260.585476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1371540 ofs=651264 - <unknown>-12683 (-----) [005] .... 1920260.585476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1195003 ofs=348160 - <unknown>-12695 (-----) [004] .... 1920260.585477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1228787 ofs=655360 - <unknown>-12695 (-----) [004] .... 1920260.585477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1236123 ofs=659456 - <unknown>-12695 (-----) [004] .... 1920260.585477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1137213 ofs=663552 - <unknown>-12695 (-----) [004] .... 1920260.585478: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1294618 ofs=667648 - <unknown>-12695 (-----) [004] .... 1920260.585478: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1241048 ofs=671744 - <unknown>-12695 (-----) [004] .... 1920260.585479: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1228779 ofs=675840 - <unknown>-12683 (-----) [005] .... 1920260.585479: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1199292 ofs=352256 - <unknown>-12683 (-----) [005] .... 1920260.585480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1200861 ofs=356352 - <unknown>-12695 (-----) [004] .... 1920260.585480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1309572 ofs=679936 - <unknown>-12683 (-----) [005] .... 1920260.585480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1215770 ofs=360448 - <unknown>-12695 (-----) [004] .... 1920260.585481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1409002 ofs=684032 - <unknown>-12683 (-----) [005] .... 1920260.585481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1151883 ofs=364544 - <unknown>-12695 (-----) [004] .... 1920260.585481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1103729 ofs=688128 - <unknown>-12683 (-----) [005] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1468126 ofs=368640 - <unknown>-12695 (-----) [004] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1162720 ofs=692224 - <unknown>-12683 (-----) [005] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1251672 ofs=372736 - <unknown>-12695 (-----) [004] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1199221 ofs=696320 - <unknown>-12683 (-----) [005] .... 1920260.585483: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1283325 ofs=376832 - <unknown>-12683 (-----) [005] .... 1920260.585483: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1190489 ofs=380928 - <unknown>-12683 (-----) [005] .... 1920260.585484: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1489117 ofs=385024 - <unknown>-12683 (-----) [005] .... 1920260.585484: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1273899 ofs=389120 - <unknown>-12683 (-----) [005] .... 1920260.585485: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1274459 ofs=393216 - <unknown>-12683 (-----) [005] .... 1920260.585486: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1316649 ofs=397312 - <unknown>-12683 (-----) [005] .... 1920260.585491: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1375678 ofs=401408 - <unknown>-12683 (-----) [005] .... 1920260.585491: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1483317 ofs=405504 - <unknown>-12683 (-----) [005] .... 1920260.585492: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1240286 ofs=409600 - <unknown>-12683 (-----) [005] .... 1920260.585492: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1131345 ofs=413696 - <unknown>-12683 (-----) [005] .... 1920260.585493: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1200483 ofs=417792 - <unknown>-12683 (-----) [005] .... 1920260.585493: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1384693 ofs=421888 - <unknown>-12683 (-----) [005] .... 1920260.585493: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1161385 ofs=425984 - <unknown>-12683 (-----) [005] .... 1920260.585494: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1452025 ofs=430080 - <unknown>-12683 (-----) [005] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1253654 ofs=434176 - <unknown>-12683 (-----) [005] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1116697 ofs=438272 - <unknown>-12683 (-----) [005] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1432645 ofs=442368 - <unknown>-12694 (-----) [006] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1337397 ofs=16384 - <unknown>-12683 (-----) [005] .... 1920260.585496: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1304229 ofs=446464 - <unknown>-12683 (-----) [005] .... 1920260.585496: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1419147 ofs=450560 - <unknown>-12683 (-----) [005] .... 1920260.585498: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1349246 ofs=454656 - <unknown>-12683 (-----) [005] .... 1920260.585499: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1128519 ofs=458752 - <unknown>-12683 (-----) [005] .... 1920260.585499: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1125168 ofs=462848 - <unknown>-12694 (-----) [006] .... 1920260.585509: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1081031 ofs=20480 - <unknown>-12694 (-----) [006] .... 1920260.585509: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1293022 ofs=24576 - <unknown>-12694 (-----) [006] .... 1920260.585510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1113007 ofs=28672 - <unknown>-12694 (-----) [006] .... 1920260.585510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1339312 ofs=32768 - <unknown>-12694 (-----) [006] .... 1920260.585511: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1412311 ofs=36864 - <unknown>-12694 (-----) [006] .... 1920260.585511: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1260960 ofs=40960 - <unknown>-12694 (-----) [006] .... 1920260.585512: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1189529 ofs=45056 - <unknown>-12694 (-----) [006] .... 1920260.585512: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1412184 ofs=49152 - <unknown>-12694 (-----) [006] .... 1920260.585513: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1481227 ofs=53248 - <unknown>-12694 (-----) [006] .... 1920260.585513: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1455940 ofs=57344 - <unknown>-12694 (-----) [006] .... 1920260.585514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1299132 ofs=61440 - <unknown>-12694 (-----) [006] .... 1920260.585514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1337375 ofs=65536 - <unknown>-12694 (-----) [006] .... 1920260.585529: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1328742 ofs=69632 - <unknown>-12694 (-----) [006] .... 1920260.585529: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1315646 ofs=73728 - <unknown>-12694 (-----) [006] .... 1920260.585531: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1225475 ofs=77824 - <unknown>-12694 (-----) [006] .... 1920260.585531: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1146097 ofs=81920 - <unknown>-12694 (-----) [006] .... 1920260.585532: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1318775 ofs=86016 - <unknown>-12694 (-----) [006] .... 1920260.585532: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1448391 ofs=90112 - <unknown>-12694 (-----) [006] .... 1920260.585532: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1441412 ofs=94208 - <unknown>-12694 (-----) [006] .... 1920260.585533: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1138111 ofs=98304 - <unknown>-12694 (-----) [006] .... 1920260.585533: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1143223 ofs=102400 - <unknown>-12683 (-----) [005] .... 1920260.585534: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1079876 ofs=466944 - <unknown>-12694 (-----) [006] .... 1920260.585534: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1447637 ofs=106496 - <unknown>-12694 (-----) [006] .... 1920260.585534: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1220585 ofs=110592 - <unknown>-12694 (-----) [006] .... 1920260.585535: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1449051 ofs=114688 - <unknown>-12694 (-----) [006] .... 1920260.585535: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1313180 ofs=118784 - <unknown>-12694 (-----) [006] .... 1920260.585535: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1313166 ofs=122880 - <unknown>-12694 (-----) [006] .... 1920260.585536: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1313154 ofs=126976 - <unknown>-12683 (-----) [005] .... 1920260.585536: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1218394 ofs=471040 - <unknown>-12694 (-----) [006] .... 1920260.585536: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1144047 ofs=131072 - <unknown>-12683 (-----) [005] .... 1920260.585537: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1218579 ofs=475136 - <unknown>-12694 (-----) [006] .... 1920260.585543: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1241332 ofs=135168 - <unknown>-12694 (-----) [006] .... 1920260.585543: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1097199 ofs=139264 - <unknown>-12694 (-----) [006] .... 1920260.585545: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1214197 ofs=143360 - <unknown>-12694 (-----) [006] .... 1920260.585645: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1197633 ofs=147456 - <unknown>-12694 (-----) [006] .... 1920260.585647: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1311536 ofs=151552 - <unknown>-12694 (-----) [006] .... 1920260.585647: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1322952 ofs=155648 - <unknown>-12694 (-----) [006] .... 1920260.585647: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1346974 ofs=159744 - <unknown>-12694 (-----) [006] .... 1920260.585648: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1257232 ofs=163840 - <unknown>-12695 (-----) [004] .... 1920260.586355: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1204484 ofs=700416 - <unknown>-12695 (-----) [004] .... 1920260.586357: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1326426 ofs=704512 - <unknown>-12695 (-----) [004] .... 1920260.586358: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1151808 ofs=708608 - <unknown>-12695 (-----) [004] .... 1920260.586358: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1209422 ofs=712704 - <unknown>-12695 (-----) [004] .... 1920260.586359: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1408387 ofs=716800 - <unknown>-12695 (-----) [004] .... 1920260.586359: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1197336 ofs=720896 - <unknown>-12695 (-----) [004] .... 1920260.586363: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1205652 ofs=724992 - <unknown>-12695 (-----) [004] .... 1920260.586363: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1133421 ofs=729088 - <unknown>-12695 (-----) [004] .... 1920260.586364: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092173 ofs=733184 - <unknown>-12695 (-----) [004] .... 1920260.586365: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1124430 ofs=737280 - <unknown>-12695 (-----) [004] .... 1920260.586365: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1143926 ofs=741376 - <unknown>-12695 (-----) [004] .... 1920260.586366: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1090109 ofs=745472 - <unknown>-12695 (-----) [004] .... 1920260.586366: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1102012 ofs=749568 - <unknown>-12695 (-----) [004] .... 1920260.586367: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1154930 ofs=753664 - <unknown>-12695 (-----) [004] .... 1920260.586368: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1132993 ofs=757760 - <unknown>-12695 (-----) [004] .... 1920260.586369: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1430780 ofs=761856 - <unknown>-12695 (-----) [004] .... 1920260.586369: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1197452 ofs=765952 - <unknown>-12695 (-----) [004] .... 1920260.586369: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1075111 ofs=770048 - <unknown>-12695 (-----) [004] .... 1920260.586370: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1275616 ofs=774144 - <unknown>-12695 (-----) [004] .... 1920260.586370: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1444981 ofs=778240 - <unknown>-12695 (-----) [004] .... 1920260.586371: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1452592 ofs=782336 - <unknown>-12695 (-----) [004] .... 1920260.586374: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1102857 ofs=786432 - <unknown>-12695 (-----) [004] .... 1920260.586376: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1406969 ofs=790528 - <unknown>-12695 (-----) [004] .... 1920260.586378: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1522553 ofs=794624 - <unknown>-12695 (-----) [004] .... 1920260.586378: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1260771 ofs=798720 - <unknown>-12695 (-----) [004] .... 1920260.586379: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1474649 ofs=802816 - <unknown>-12695 (-----) [004] .... 1920260.586379: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1268708 ofs=806912 - <unknown>-12695 (-----) [004] .... 1920260.586379: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1346144 ofs=811008 - <unknown>-12695 (-----) [004] .... 1920260.586380: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1081167 ofs=815104 - <unknown>-12695 (-----) [004] .... 1920260.586380: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1137677 ofs=819200 - <unknown>-12695 (-----) [004] .... 1920260.586381: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1161175 ofs=823296 - <unknown>-12695 (-----) [004] .... 1920260.586381: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1461331 ofs=827392 - <unknown>-12695 (-----) [004] .... 1920260.586492: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1347219 ofs=831488 - <unknown>-12695 (-----) [004] .... 1920260.586494: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1290004 ofs=835584 - <unknown>-12695 (-----) [004] .... 1920260.586494: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1299174 ofs=839680 - <unknown>-12695 (-----) [004] .... 1920260.586496: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1317595 ofs=843776 - <unknown>-12695 (-----) [004] .... 1920260.586496: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1484924 ofs=847872 - <unknown>-12695 (-----) [004] .... 1920260.586497: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1169920 ofs=851968 - <unknown>-12695 (-----) [004] .... 1920260.586501: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1359189 ofs=856064 - <unknown>-12695 (-----) [004] .... 1920260.586501: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1307842 ofs=860160 - <unknown>-12695 (-----) [004] .... 1920260.586502: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1237858 ofs=864256 - <unknown>-12695 (-----) [004] .... 1920260.586502: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1189461 ofs=868352 - <unknown>-12695 (-----) [004] .... 1920260.586503: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1223232 ofs=872448 - <unknown>-12695 (-----) [004] .... 1920260.586503: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1104076 ofs=876544 - <unknown>-12695 (-----) [004] .... 1920260.586504: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1079223 ofs=880640 - <unknown>-12695 (-----) [004] .... 1920260.586504: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092537 ofs=884736 - <unknown>-12695 (-----) [004] .... 1920260.586505: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1353960 ofs=888832 - <unknown>-12695 (-----) [004] .... 1920260.586505: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1346330 ofs=892928 - <unknown>-12695 (-----) [004] .... 1920260.586506: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1345764 ofs=897024 - <unknown>-12695 (-----) [004] .... 1920260.586507: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1363913 ofs=901120 - <unknown>-12695 (-----) [004] .... 1920260.586508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1319570 ofs=905216 - <unknown>-12695 (-----) [004] .... 1920260.586508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1367024 ofs=909312 - <unknown>-12695 (-----) [004] .... 1920260.586508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1333808 ofs=913408 - <unknown>-12695 (-----) [004] .... 1920260.586509: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1158627 ofs=917504 - <unknown>-12695 (-----) [004] .... 1920260.586509: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1300368 ofs=921600 - <unknown>-12695 (-----) [004] .... 1920260.586510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1245363 ofs=925696 - <unknown>-12695 (-----) [004] .... 1920260.586510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1345609 ofs=929792 - <unknown>-12695 (-----) [004] .... 1920260.586510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1393826 ofs=933888 - <unknown>-12695 (-----) [004] .... 1920260.586511: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1200552 ofs=937984 - <unknown>-12695 (-----) [004] .... 1920260.586511: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1170885 ofs=942080 - <unknown>-12695 (-----) [004] .... 1920260.586512: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1536209 ofs=946176 - <unknown>-12695 (-----) [004] .... 1920260.586512: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1189630 ofs=950272 - <unknown>-12695 (-----) [004] .... 1920260.586513: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1121010 ofs=954368 - <unknown>-12695 (-----) [004] .... 1920260.586514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1324474 ofs=958464 - <unknown>-12697 (-----) [007] .... 1920260.586578: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1129628 ofs=299008 - <unknown>-12697 (-----) [007] .... 1920260.586579: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1307120 ofs=303104 - <unknown>-12697 (-----) [007] .... 1920260.586580: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1347284 ofs=307200 - <unknown>-12697 (-----) [007] .... 1920260.586580: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1312996 ofs=311296 - <unknown>-12697 (-----) [007] .... 1920260.586581: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1170623 ofs=315392 - <unknown>-12697 (-----) [007] .... 1920260.586581: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1359281 ofs=319488 - <unknown>-12697 (-----) [007] .... 1920260.586582: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1180021 ofs=323584 - <unknown>-12697 (-----) [007] .... 1920260.586582: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1195728 ofs=327680 - <unknown>-12697 (-----) [007] .... 1920260.586582: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1163642 ofs=331776 - <unknown>-12697 (-----) [007] .... 1920260.586587: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1152538 ofs=335872 - <unknown>-12697 (-----) [007] .... 1920260.586589: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1345922 ofs=339968 - <unknown>-12697 (-----) [007] .... 1920260.586589: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1343604 ofs=344064 - <unknown>-12697 (-----) [007] .... 1920260.586721: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1399371 ofs=479232 - <unknown>-12697 (-----) [007] .... 1920260.586723: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1106549 ofs=483328 - <unknown>-12697 (-----) [007] .... 1920260.586724: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331546 ofs=487424 - <unknown>-12697 (-----) [007] .... 1920260.586724: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1299299 ofs=491520 - <unknown>-12697 (-----) [007] .... 1920260.586725: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1288883 ofs=495616 - <unknown>-12697 (-----) [007] .... 1920260.586725: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1399049 ofs=499712 - <unknown>-12697 (-----) [007] .... 1920260.586726: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1146931 ofs=503808 - <unknown>-12697 (-----) [007] .... 1920260.586726: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1296592 ofs=507904 - <unknown>-12697 (-----) [007] .... 1920260.586727: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1468397 ofs=512000 - <unknown>-12697 (-----) [007] .... 1920260.586727: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1215698 ofs=516096 - <unknown>-12697 (-----) [007] .... 1920260.586727: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1177341 ofs=520192 - <unknown>-12697 (-----) [007] .... 1920260.586731: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1189162 ofs=524288 - <unknown>-12697 (-----) [007] .... 1920260.586732: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1435997 ofs=528384 - <unknown>-12697 (-----) [007] .... 1920260.586732: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1209896 ofs=532480 - <unknown>-12697 (-----) [007] .... 1920260.586733: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1255888 ofs=536576 - <unknown>-12697 (-----) [007] .... 1920260.586734: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1234200 ofs=540672 - <unknown>-12697 (-----) [007] .... 1920260.586734: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1422854 ofs=544768 - <unknown>-12697 (-----) [007] .... 1920260.586735: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1435794 ofs=548864 - <unknown>-12697 (-----) [007] .... 1920260.586735: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1236279 ofs=552960 - <unknown>-12697 (-----) [007] .... 1920260.586736: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1485732 ofs=557056 - <unknown>-12683 (-----) [005] .... 1920260.586743: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1417198 ofs=561152 - <unknown>-12683 (-----) [005] .... 1920260.586746: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1469450 ofs=565248 - <unknown>-12696 (-----) [004] .... 1920260.587465: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1489023 ofs=1040384 - <unknown>-12696 (-----) [004] .... 1920260.587469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1449498 ofs=1044480 - <unknown>-12696 (-----) [004] .... 1920260.587469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1447737 ofs=1048576 - <unknown>-12696 (-----) [004] .... 1920260.587470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1124530 ofs=1052672 - <unknown>-12696 (-----) [004] .... 1920260.587476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1246743 ofs=1056768 - <unknown>-12696 (-----) [004] .... 1920260.587476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1441927 ofs=1060864 - <unknown>-12696 (-----) [004] .... 1920260.587477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1280581 ofs=1064960 - <unknown>-12696 (-----) [004] .... 1920260.587477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1289438 ofs=1069056 - <unknown>-12696 (-----) [004] .... 1920260.587477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1464236 ofs=1073152 - <unknown>-12696 (-----) [004] .... 1920260.587478: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1125808 ofs=1077248 - <unknown>-12696 (-----) [004] .... 1920260.587478: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1329385 ofs=1081344 - <unknown>-12696 (-----) [004] .... 1920260.587480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1314093 ofs=1085440 - <unknown>-12696 (-----) [004] .... 1920260.587480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1201837 ofs=1089536 - <unknown>-12696 (-----) [004] .... 1920260.587481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1327734 ofs=1093632 - <unknown>-12696 (-----) [004] .... 1920260.587481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1406568 ofs=1097728 - <unknown>-12696 (-----) [004] .... 1920260.587481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331873 ofs=1101824 - <unknown>-12696 (-----) [004] .... 1920260.587482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331898 ofs=1105920 - <unknown>-12696 (-----) [004] .... 1920260.587482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331917 ofs=1110016 - <unknown>-12696 (-----) [004] .... 1920260.587483: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1332091 ofs=1114112 - <unknown>-12696 (-----) [004] .... 1920260.587483: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1108186 ofs=1118208 - <unknown>-12696 (-----) [004] .... 1920260.587486: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1182631 ofs=1122304 - <unknown>-12696 (-----) [004] .... 1920260.587486: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1085941 ofs=1126400 - <unknown>-12696 (-----) [004] .... 1920260.587487: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1433982 ofs=1130496 - <unknown>-12696 (-----) [004] .... 1920260.587487: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1387028 ofs=1134592 - <unknown>-12696 (-----) [004] .... 1920260.587488: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1353117 ofs=1138688 - <unknown>-12696 (-----) [004] .... 1920260.587489: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1352364 ofs=1142784 - <unknown>-12696 (-----) [004] .... 1920260.587489: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1144513 ofs=1146880 - <unknown>-12696 (-----) [004] .... 1920260.587490: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1403984 ofs=1150976 - <unknown>-12696 (-----) [004] .... 1920260.587490: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1278970 ofs=1155072 - <unknown>-12696 (-----) [004] .... 1920260.587491: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1326743 ofs=1159168 - <unknown>-12696 (-----) [004] .... 1920260.587491: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1221809 ofs=1163264 - <unknown>-12696 (-----) [004] .... 1920260.587492: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1268668 ofs=1167360 - <unknown>-12695 (-----) [005] .... 1920260.587502: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1074544 ofs=962560 - <unknown>-12695 (-----) [005] .... 1920260.587506: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1074294 ofs=966656 - <unknown>-12695 (-----) [005] .... 1920260.587506: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1075097 ofs=970752 - <unknown>-12695 (-----) [005] .... 1920260.587507: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1162407 ofs=974848 - <unknown>-12695 (-----) [005] .... 1920260.587507: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1141370 ofs=978944 - <unknown>-12695 (-----) [005] .... 1920260.587508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306487 ofs=983040 - <unknown>-12695 (-----) [005] .... 1920260.587508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306434 ofs=987136 - <unknown>-12695 (-----) [005] .... 1920260.587514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306347 ofs=991232 - <unknown>-12695 (-----) [005] .... 1920260.587514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306247 ofs=995328 - <unknown>-12695 (-----) [005] .... 1920260.587515: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306195 ofs=999424 - <unknown>-12695 (-----) [005] .... 1920260.587516: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306039 ofs=1003520 - <unknown>-12695 (-----) [005] .... 1920260.587516: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1305983 ofs=1007616 - <unknown>-12694 (-----) [006] .... 1920260.587701: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1216391 ofs=1171456 - <unknown>-12694 (-----) [006] .... 1920260.587705: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1262462 ofs=1175552 - <unknown>-12694 (-----) [006] .... 1920260.587706: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1358114 ofs=1179648 - <unknown>-12694 (-----) [006] .... 1920260.587706: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1357898 ofs=1183744 - <unknown>-12694 (-----) [006] .... 1920260.587707: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1237003 ofs=1187840 - <unknown>-12694 (-----) [006] .... 1920260.587707: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1126319 ofs=1191936 - <unknown>-12694 (-----) [006] .... 1920260.587708: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1415489 ofs=1196032 - <unknown>-12694 (-----) [006] .... 1920260.587708: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1279558 ofs=1200128 - <unknown>-12694 (-----) [006] .... 1920260.587708: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1434022 ofs=1204224 - <unknown>-12694 (-----) [006] .... 1920260.587709: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1220130 ofs=1208320 - <unknown>-12694 (-----) [006] .... 1920260.587710: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1163037 ofs=1212416 - <unknown>-12694 (-----) [006] .... 1920260.587711: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1404501 ofs=1216512 - <unknown>-12694 (-----) [006] .... 1920260.587711: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1406287 ofs=1220608 - <unknown>-12697 (-----) [007] .... 1920260.588132: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1355143 ofs=1376256 - <unknown>-12697 (-----) [007] .... 1920260.588136: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1213923 ofs=1380352 - <unknown>-12697 (-----) [007] .... 1920260.588136: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1243190 ofs=1384448 - <unknown>-12697 (-----) [007] .... 1920260.588143: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1300698 ofs=1388544 - <unknown>-12697 (-----) [007] .... 1920260.588144: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1482568 ofs=1392640 - <unknown>-12697 (-----) [007] .... 1920260.588144: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1461789 ofs=1396736 - <unknown>-12697 (-----) [007] .... 1920260.588145: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242314 ofs=1400832 - <unknown>-12697 (-----) [007] .... 1920260.588145: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1471996 ofs=1404928 - <unknown>-12697 (-----) [007] .... 1920260.588146: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242742 ofs=1409024 - <unknown>-12697 (-----) [007] .... 1920260.588146: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242579 ofs=1413120 - <unknown>-12697 (-----) [007] .... 1920260.588148: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242553 ofs=1417216 - <unknown>-12697 (-----) [007] .... 1920260.588148: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1457332 ofs=1421312 - <unknown>-12697 (-----) [007] .... 1920260.588149: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1315431 ofs=1425408 - <unknown>-12697 (-----) [007] .... 1920260.588149: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1080653 ofs=1429504 - <unknown>-12697 (-----) [007] .... 1920260.588149: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1324174 ofs=1433600 - <unknown>-12697 (-----) [007] .... 1920260.588150: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1324142 ofs=1437696 - <unknown>-12697 (-----) [007] .... 1920260.588150: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1157760 ofs=1441792 - <unknown>-12697 (-----) [007] .... 1920260.588151: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1075059 ofs=1445888 - <unknown>-12683 (-----) [006] .... 1920260.589785: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1279192 ofs=1486848 - <unknown>-12683 (-----) [006] .... 1920260.589790: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1278527 ofs=1490944 - <unknown>-12683 (-----) [006] .... 1920260.589791: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1091778 ofs=1495040 - <unknown>-12683 (-----) [006] .... 1920260.589791: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1339447 ofs=1499136 - <unknown>-12683 (-----) [006] .... 1920260.589792: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1254007 ofs=1503232 - <unknown>-12683 (-----) [006] .... 1920260.589793: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1115173 ofs=1507328 - <unknown>-12683 (-----) [006] .... 1920260.589793: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1393985 ofs=1511424 - <unknown>-12683 (-----) [006] .... 1920260.589794: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1369123 ofs=1515520 - <unknown>-12683 (-----) [006] .... 1920260.589794: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1314257 ofs=1519616 - <unknown>-12683 (-----) [006] .... 1920260.589802: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1404487 ofs=1523712 - <unknown>-12683 (-----) [006] .... 1920260.589803: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1354554 ofs=1527808 - <unknown>-12683 (-----) [006] .... 1920260.594312: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1141445 ofs=9801728 - <unknown>-12683 (-----) [006] .... 1920260.594322: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323774 ofs=231460864 - <unknown>-12683 (-----) [006] .... 1920260.594326: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1323772 ofs=10993664 - <unknown>-12683 (-----) [006] .... 1920260.595212: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1481305 ofs=9805824 - <unknown>-12683 (-----) [006] .... 1920260.595214: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1481306 ofs=9809920 - <unknown>-12683 (-----) [006] .... 1920260.595214: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1481316 ofs=9814016 - <unknown>-12683 (-----) [006] .... 1920260.595215: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1481340 ofs=9818112 - <unknown>-12683 (-----) [006] .... 1920260.595216: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1394587 ofs=9822208 - <unknown>-12683 (-----) [006] .... 1920260.595216: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103455 ofs=9826304 - <unknown>-12683 (-----) [006] .... 1920260.595217: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103271 ofs=9830400 - <unknown>-12683 (-----) [006] .... 1920260.595218: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103168 ofs=9834496 - <unknown>-12683 (-----) [006] .... 1920260.595218: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103145 ofs=9838592 - <unknown>-12683 (-----) [006] .... 1920260.595219: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103115 ofs=9842688 - <unknown>-12683 (-----) [006] .... 1920260.595222: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103057 ofs=9846784 - <unknown>-12683 (-----) [006] .... 1920260.595222: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1331958 ofs=9850880 - <unknown>-12683 (-----) [006] .... 1920260.595227: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1356305 ofs=9854976 - <unknown>-12683 (-----) [006] .... 1920260.595228: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103708 ofs=9859072 - <unknown>-12683 (-----) [006] .... 1920260.595228: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1099286 ofs=9863168 - <unknown>-12683 (-----) [006] .... 1920260.595229: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1435190 ofs=9867264 - <unknown>-12683 (-----) [006] .... 1920260.595229: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1395504 ofs=9871360 - <unknown>-12683 (-----) [006] .... 1920260.595230: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1352916 ofs=9875456 - <unknown>-12683 (-----) [006] .... 1920260.595231: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1255529 ofs=9879552 - <unknown>-12683 (-----) [006] .... 1920260.595231: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1336145 ofs=9883648 - <unknown>-12683 (-----) [006] .... 1920260.595232: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1334143 ofs=9887744 - <unknown>-12683 (-----) [006] .... 1920260.595232: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1328548 ofs=9891840 - <unknown>-12683 (-----) [006] .... 1920260.595232: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1222215 ofs=9895936 - <unknown>-12683 (-----) [006] .... 1920260.595233: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1461056 ofs=9900032 - <unknown>-12683 (-----) [006] .... 1920260.595234: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1228276 ofs=9904128 - <unknown>-12683 (-----) [006] .... 1920260.595235: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1151188 ofs=9908224 - <unknown>-12683 (-----) [006] .... 1920260.595236: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1443605 ofs=9912320 - <unknown>-12683 (-----) [006] .... 1920260.595236: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1146821 ofs=9916416 - <unknown>-12683 (-----) [006] .... 1920260.595237: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103669 ofs=9920512 - <unknown>-12683 (-----) [006] .... 1920260.595238: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103744 ofs=9924608 - <unknown>-12683 (-----) [006] .... 1920260.595238: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103868 ofs=9928704 - <unknown>-12683 (-----) [006] .... 1920260.595789: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1465942 ofs=15855616 - <unknown>-12683 (-----) [006] .... 1920260.595792: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323712 ofs=261189632 - <unknown>-12683 (-----) [006] .... 1920260.595998: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323701 ofs=262094848 - <unknown>-12683 (-----) [006] .... 1920260.596191: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1222287 ofs=15859712 - <unknown>-12683 (-----) [006] .... 1920260.596192: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1213146 ofs=15863808 - <unknown>-12683 (-----) [006] .... 1920260.596192: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1310396 ofs=15867904 - <unknown>-12683 (-----) [006] .... 1920260.596193: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1310177 ofs=15872000 - <unknown>-12683 (-----) [006] .... 1920260.596194: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1187914 ofs=15876096 - <unknown>-12683 (-----) [006] .... 1920260.596195: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1322409 ofs=15880192 - <unknown>-12683 (-----) [006] .... 1920260.596195: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1282484 ofs=15884288 - <unknown>-12683 (-----) [006] .... 1920260.596200: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1097245 ofs=15888384 - <unknown>-12683 (-----) [006] .... 1920260.596200: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1416816 ofs=15892480 - <unknown>-12683 (-----) [006] .... 1920260.596201: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1257125 ofs=15896576 - <unknown>-12683 (-----) [006] .... 1920260.596201: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1403527 ofs=15900672 - <unknown>-12683 (-----) [006] .... 1920260.596202: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1218006 ofs=15904768 - <unknown>-12683 (-----) [006] .... 1920260.596202: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1153893 ofs=15908864 - <unknown>-12683 (-----) [006] .... 1920260.596202: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1328023 ofs=15912960 - <unknown>-12683 (-----) [006] .... 1920260.596203: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1465412 ofs=15917056 - <unknown>-12683 (-----) [006] .... 1920260.596203: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1092448 ofs=15921152 - <unknown>-12683 (-----) [006] .... 1920260.596204: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1239220 ofs=15925248 - <unknown>-12683 (-----) [006] .... 1920260.596204: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1276491 ofs=15929344 - <unknown>-12683 (-----) [006] .... 1920260.596205: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1262240 ofs=15933440 - <unknown>-12683 (-----) [006] .... 1920260.596206: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1323793 ofs=15937536 - <unknown>-12683 (-----) [006] .... 1920260.596206: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1074937 ofs=15941632 - <unknown>-12683 (-----) [006] .... 1920260.596207: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1311157 ofs=15945728 - <unknown>-12683 (-----) [006] .... 1920260.596207: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1308442 ofs=15949824 - <unknown>-12683 (-----) [006] .... 1920260.596210: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1467709 ofs=15953920 - <unknown>-12683 (-----) [006] .... 1920260.596211: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1394299 ofs=15958016 - <unknown>-12683 (-----) [004] .... 1920260.612586: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1316156 ofs=344064 - <unknown>-12683 (-----) [004] .... 1920260.612591: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1406323 ofs=348160 - <unknown>-12683 (-----) [004] .... 1920260.612601: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1216972 ofs=352256 - <unknown>-12683 (-----) [004] .... 1920260.612605: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1271924 ofs=356352 - <unknown>-12683 (-----) [004] .... 1920260.612605: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1369225 ofs=360448 - <unknown>-12683 (-----) [004] .... 1920260.612608: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1318474 ofs=364544 - <unknown>-12683 (-----) [004] .... 1920260.612609: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1227283 ofs=368640 - <unknown>-12683 (-----) [004] .... 1920260.612613: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1364376 ofs=372736 - <unknown>-12683 (-----) [004] .... 1920260.612613: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1073400 ofs=376832 diff --git a/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb b/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb Binary files differdeleted file mode 100644 index ab3df45f8c54..000000000000 --- a/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb +++ /dev/null diff --git a/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb b/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb Binary files differdeleted file mode 100644 index 17cb11662172..000000000000 --- a/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb +++ /dev/null diff --git a/startop/scripts/lib/cmd_utils.py b/startop/scripts/lib/cmd_utils.py deleted file mode 100644 index 6071f145fe1d..000000000000 --- a/startop/scripts/lib/cmd_utils.py +++ /dev/null @@ -1,184 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. - -"""Helper util libraries for command line operations.""" - -import asyncio -import sys -import time -from typing import Tuple, Optional, List - -import lib.print_utils as print_utils - -TIMEOUT = 50 -SIMULATE = False - -def run_command_nofail(cmd: List[str], **kwargs) -> None: - """Runs cmd list with default timeout. - - Throws exception if the execution fails. - """ - my_kwargs = {"timeout": TIMEOUT, "shell": False, "simulate": False} - my_kwargs.update(kwargs) - passed, out = execute_arbitrary_command(cmd, **my_kwargs) - if not passed: - raise RuntimeError( - "Failed to execute %s (kwargs=%s), output=%s" % (cmd, kwargs, out)) - -def run_adb_shell_command(cmd: str) -> Tuple[bool, str]: - """Runs command using adb shell. - - Returns: - A tuple of running status (True=succeeded, False=failed or timed out) and - std output (string contents of stdout with trailing whitespace removed). - """ - return run_shell_command('adb shell "{}"'.format(cmd)) - -def run_shell_func(script_path: str, - func: str, - args: List[str]) -> Tuple[bool, str]: - """Runs shell function with default timeout. - - Returns: - A tuple of running status (True=succeeded, False=failed or timed out) and - std output (string contents of stdout with trailing whitespace removed) . - """ - if args: - cmd = 'bash -c "source {script_path}; {func} {args}"'.format( - script_path=script_path, - func=func, - args=' '.join("'{}'".format(arg) for arg in args)) - else: - cmd = 'bash -c "source {script_path}; {func}"'.format( - script_path=script_path, - func=func) - - print_utils.debug_print(cmd) - return run_shell_command(cmd) - -def run_shell_command(cmd: str) -> Tuple[bool, str]: - """Runs shell command with default timeout. - - Returns: - A tuple of running status (True=succeeded, False=failed or timed out) and - std output (string contents of stdout with trailing whitespace removed) . - """ - return execute_arbitrary_command([cmd], - TIMEOUT, - shell=True, - simulate=SIMULATE) - -def execute_arbitrary_command(cmd: List[str], - timeout: int, - shell: bool, - simulate: bool) -> Tuple[bool, str]: - """Run arbitrary shell command with default timeout. - - Mostly copy from - frameworks/base/startop/scripts/app_startup/app_startup_runner.py. - - Args: - cmd: list of cmd strings. - timeout: the time limit of running cmd. - shell: indicate if the cmd is a shell command. - simulate: if it's true, do not run the command and assume the running is - successful. - - Returns: - A tuple of running status (True=succeeded, False=failed or timed out) and - std output (string contents of stdout with trailing whitespace removed) . - """ - if simulate: - print(cmd) - return True, '' - - print_utils.debug_print('[EXECUTE]', cmd) - # block until either command finishes or the timeout occurs. - loop = asyncio.get_event_loop() - - (return_code, script_output) = loop.run_until_complete( - _run_command(*cmd, shell=shell, timeout=timeout)) - - script_output = script_output.decode() # convert bytes to str - - passed = (return_code == 0) - print_utils.debug_print('[$?]', return_code) - if not passed: - print('[FAILED, code:%s]' % (return_code), script_output, file=sys.stderr) - - return passed, script_output.rstrip() - -async def _run_command(*args: List[str], - shell: bool = False, - timeout: Optional[int] = None) -> Tuple[int, bytes]: - if shell: - process = await asyncio.create_subprocess_shell( - *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT) - else: - process = await asyncio.create_subprocess_exec( - *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT) - - script_output = b'' - - print_utils.debug_print('[PID]', process.pid) - - timeout_remaining = timeout - time_started = time.time() - - # read line (sequence of bytes ending with b'\n') asynchronously - while True: - try: - line = await asyncio.wait_for(process.stdout.readline(), - timeout_remaining) - print_utils.debug_print('[STDOUT]', line) - script_output += line - - if timeout_remaining: - time_elapsed = time.time() - time_started - timeout_remaining = timeout - time_elapsed - except asyncio.TimeoutError: - print_utils.debug_print('[TIMEDOUT] Process ', process.pid) - - print_utils.debug_print('[TIMEDOUT] Sending SIGTERM.') - process.terminate() - - # 5 second timeout for process to handle SIGTERM nicely. - try: - (remaining_stdout, - remaining_stderr) = await asyncio.wait_for(process.communicate(), 5) - script_output += remaining_stdout - except asyncio.TimeoutError: - print_utils.debug_print('[TIMEDOUT] Sending SIGKILL.') - process.kill() - - # 5 second timeout to finish with SIGKILL. - try: - (remaining_stdout, - remaining_stderr) = await asyncio.wait_for(process.communicate(), 5) - script_output += remaining_stdout - except asyncio.TimeoutError: - # give up, this will leave a zombie process. - print_utils.debug_print('[TIMEDOUT] SIGKILL failed for process ', - process.pid) - time.sleep(100) - - return -1, script_output - else: - if not line: # EOF - break - - code = await process.wait() # wait for child process to exit - return code, script_output diff --git a/startop/scripts/lib/logcat_utils.py b/startop/scripts/lib/logcat_utils.py deleted file mode 100644 index 8a3d00b46771..000000000000 --- a/startop/scripts/lib/logcat_utils.py +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. - -"""Helper util libraries for parsing logcat logs.""" - -import asyncio -import re -from datetime import datetime -from typing import Optional, Pattern - -# local import -import lib.print_utils as print_utils - -def parse_logcat_datetime(timestamp: str) -> Optional[datetime]: - """Parses the timestamp of logcat. - - Params: - timestamp: for example "2019-07-01 16:13:55.221". - - Returns: - a datetime of timestamp with the year now. - """ - try: - # Match the format of logcat. For example: "2019-07-01 16:13:55.221", - # because it doesn't have year, set current year to it. - timestamp = datetime.strptime(timestamp, - '%Y-%m-%d %H:%M:%S.%f') - return timestamp - except ValueError as ve: - print_utils.debug_print('Invalid line: ' + timestamp) - return None - -def _is_time_out(timeout: datetime, line: str) -> bool: - """Checks if the timestamp of this line exceeds the timeout. - - Returns: - true if the timestamp exceeds the timeout. - """ - # Get the timestampe string. - cur_timestamp_str = ' '.join(re.split(r'\s+', line)[0:2]) - timestamp = parse_logcat_datetime(cur_timestamp_str) - if not timestamp: - return False - - return timestamp > timeout - -async def _blocking_wait_for_logcat_pattern(timestamp: datetime, - pattern: Pattern, - timeout: datetime) -> Optional[str]: - # Show the year in the timestampe. - logcat_cmd = 'adb logcat -v UTC -v year -v threadtime -T'.split() - logcat_cmd.append(str(timestamp)) - print_utils.debug_print('[LOGCAT]:' + ' '.join(logcat_cmd)) - - # Create subprocess - process = await asyncio.create_subprocess_exec( - *logcat_cmd, - # stdout must a pipe to be accessible as process.stdout - stdout=asyncio.subprocess.PIPE) - - while (True): - # Read one line of output. - data = await process.stdout.readline() - line = data.decode('utf-8').rstrip() - - # 2019-07-01 14:54:21.946 27365 27392 I ActivityTaskManager: Displayed - # com.android.settings/.Settings: +927ms - # TODO: Detect timeouts even when there is no logcat output. - if _is_time_out(timeout, line): - print_utils.debug_print('DID TIMEOUT BEFORE SEEING ANYTHING (' - 'timeout={timeout} seconds << {pattern} ' - '>>'.format(timeout=timeout, pattern=pattern)) - return None - - if pattern.match(line): - print_utils.debug_print( - 'WE DID SEE PATTERN << "{}" >>.'.format(pattern)) - return line - -def blocking_wait_for_logcat_pattern(timestamp: datetime, - pattern: Pattern, - timeout: datetime) -> Optional[str]: - """Selects the line that matches the pattern and within the timeout. - - Returns: - the line that matches the pattern and within the timeout. - """ - loop = asyncio.get_event_loop() - result = loop.run_until_complete( - _blocking_wait_for_logcat_pattern(timestamp, pattern, timeout)) - return result diff --git a/startop/scripts/lib/logcat_utils_test.py b/startop/scripts/lib/logcat_utils_test.py deleted file mode 100644 index ab82515bc4fa..000000000000 --- a/startop/scripts/lib/logcat_utils_test.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. -# -"""Unit tests for the logcat_utils.py script.""" - -import asyncio -import datetime -import re - -import logcat_utils -from mock import MagicMock, patch - -def test_parse_logcat_datatime(): - # Act - result = logcat_utils.parse_logcat_datetime('2019-07-01 16:13:55.221') - - # Assert - assert result == datetime.datetime(2019, 7, 1, 16, 13, 55, 221000) - -class AsyncMock(MagicMock): - async def __call__(self, *args, **kwargs): - return super(AsyncMock, self).__call__(*args, **kwargs) - -def _async_return(): - f = asyncio.Future() - f.set_result( - b'2019-07-01 15:51:53.290 27365 27392 I ActivityTaskManager: ' - b'Displayed com.google.android.music/com.android.music.activitymanagement.' - b'TopLevelActivity: +1s7ms') - return f - -def test_parse_displayed_time_succeed(): - # Act - with patch('asyncio.create_subprocess_exec', - new_callable=AsyncMock) as asyncio_mock: - asyncio_mock.return_value.stdout.readline = _async_return - timestamp = datetime.datetime(datetime.datetime.now().year, 7, 1, 16, 13, - 55, 221000) - timeout_dt = timestamp + datetime.timedelta(0, 10) - pattern = re.compile('.*ActivityTaskManager: Displayed ' - 'com.google.android.music/com.android.music.*') - result = logcat_utils.blocking_wait_for_logcat_pattern(timestamp, - pattern, - timeout_dt) - - # Assert - assert result == '2019-07-01 15:51:53.290 27365 27392 I ' \ - 'ActivityTaskManager: ' \ - 'Displayed com.google.android.music/com.android.music.' \ - 'activitymanagement.TopLevelActivity: +1s7ms' - -def _async_timeout_return(): - f = asyncio.Future() - f.set_result( - b'2019-07-01 17:51:53.290 27365 27392 I ActivityTaskManager: ' - b'Displayed com.google.android.music/com.android.music.activitymanagement.' - b'TopLevelActivity: +1s7ms') - return f - -def test_parse_displayed_time_timeout(): - # Act - with patch('asyncio.create_subprocess_exec', - new_callable=AsyncMock) as asyncio_mock: - asyncio_mock.return_value.stdout.readline = _async_timeout_return - timestamp = datetime.datetime(datetime.datetime.now().year, - 7, 1, 16, 13, 55, 221000) - timeout_dt = timestamp + datetime.timedelta(0, 10) - pattern = re.compile('.*ActivityTaskManager: Displayed ' - 'com.google.android.music/com.android.music.*') - result = logcat_utils.blocking_wait_for_logcat_pattern(timestamp, - pattern, - timeout_dt) - - # Assert - assert result == None diff --git a/startop/scripts/lib/print_utils.py b/startop/scripts/lib/print_utils.py deleted file mode 100644 index 8c5999d99d6e..000000000000 --- a/startop/scripts/lib/print_utils.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. - -"""Helper util libraries for debug printing.""" - -import sys - -DEBUG = False - -def debug_print(*args, **kwargs): - """Prints the args to sys.stderr if the DEBUG is set.""" - if DEBUG: - print(*args, **kwargs, file=sys.stderr) - -def error_print(*args, **kwargs): - print('[ERROR]:', *args, file=sys.stderr, **kwargs) - -def _expand_gen_repr(args): - """Like repr but any generator-like object has its iterator consumed - and then called repr on.""" - new_args_list = [] - for i in args: - # detect iterable objects that do not have their own override of __str__ - if hasattr(i, '__iter__'): - to_str = getattr(i, '__str__') - if to_str.__objclass__ == object: - # the repr for a generator is just type+address, expand it out instead. - new_args_list.append([_expand_gen_repr([j])[0] for j in i]) - continue - # normal case: uses the built-in to-string - new_args_list.append(i) - return new_args_list - -def debug_print_gen(*args, **kwargs): - """Like _debug_print but will turn any iterable args into a list.""" - if not DEBUG: - return - - new_args_list = _expand_gen_repr(args) - debug_print(*new_args_list, **kwargs) - -def debug_print_nd(*args, **kwargs): - """Like _debug_print but will turn any NamedTuple-type args into a string.""" - if not DEBUG: - return - - new_args_list = [] - for i in args: - if hasattr(i, '_field_types'): - new_args_list.append("%s: %s" % (i.__name__, i._field_types)) - else: - new_args_list.append(i) - - debug_print(*new_args_list, **kwargs) diff --git a/startop/scripts/trace_analyzer/lib/trace2db.py b/startop/scripts/trace_analyzer/lib/trace2db.py deleted file mode 100644 index 42a33aff046d..000000000000 --- a/startop/scripts/trace_analyzer/lib/trace2db.py +++ /dev/null @@ -1,355 +0,0 @@ -#!/usr/bin/python3 -# Copyright (C) 2019 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. - -import re -import sys - -from sqlalchemy import create_engine -from sqlalchemy import Column, Date, Integer, Float, String, ForeignKey -from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import relationship - -from sqlalchemy.orm import sessionmaker - -import sqlalchemy - -from typing import Optional, Tuple - -_DEBUG = False # print sql commands to console -_FLUSH_LIMIT = 10000 # how many entries are parsed before flushing to DB from memory - -Base = declarative_base() - -class RawFtraceEntry(Base): - __tablename__ = 'raw_ftrace_entries' - - id = Column(Integer, primary_key=True) - task_name = Column(String, nullable=True) # <...> -> None. - task_pid = Column(String, nullable=False) - tgid = Column(Integer, nullable=True) # ----- -> None. - cpu = Column(Integer, nullable=False) - timestamp = Column(Float, nullable=False) - function = Column(String, nullable=False) - function_args = Column(String, nullable=False) - - # 1:1 relation with MmFilemapAddToPageCache. - mm_filemap_add_to_page_cache = relationship("MmFilemapAddToPageCache", - back_populates="raw_ftrace_entry") - - @staticmethod - def parse_dict(line): - # ' <...>-5521 (-----) [003] ...1 17148.446877: tracing_mark_write: trace_event_clock_sync: parent_ts=17148.447266' - m = re.match('\s*(.*)-(\d+)\s+\(([^\)]+)\)\s+\[(\d+)\]\s+([\w.]{4})\s+(\d+[.]\d+):\s+(\w+):\s+(.*)', line) - if not m: - return None - - groups = m.groups() - # groups example: - # ('<...>', - # '5521', - # '-----', - # '003', - # '...1', - # '17148.446877', - # 'tracing_mark_write', - # 'trace_event_clock_sync: parent_ts=17148.447266') - task_name = groups[0] - if task_name == '<...>': - task_name = None - - task_pid = int(groups[1]) - tgid = groups[2] - if tgid == '-----': - tgid = None - - cpu = int(groups[3]) - # irq_flags = groups[4] - timestamp = float(groups[5]) - function = groups[6] - function_args = groups[7] - - return {'task_name': task_name, 'task_pid': task_pid, 'tgid': tgid, 'cpu': cpu, 'timestamp': timestamp, 'function': function, 'function_args': function_args} - -class SchedSwitch(Base): - __tablename__ = 'sched_switches' - - id = Column(Integer, ForeignKey('raw_ftrace_entries.id'), primary_key=True) - - prev_comm = Column(String, nullable=False) - prev_pid = Column(Integer, nullable=False) - prev_prio = Column(Integer, nullable=False) - prev_state = Column(String, nullable=False) - - next_comm = Column(String, nullable=False) - next_pid = Column(Integer, nullable=False) - next_prio = Column(Integer, nullable=False) - - @staticmethod - def parse_dict(function_args, id = None): - # 'prev_comm=kworker/u16:5 prev_pid=13971 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120' - m = re.match("prev_comm=(.*) prev_pid=(\d+) prev_prio=(\d+) prev_state=(.*) ==> next_comm=(.*) next_pid=(\d+) next_prio=(\d+) ?", function_args) - if not m: - return None - - groups = m.groups() - # ('kworker/u16:5', '13971', '120', 'S', 'swapper/4', '0', '120') - d = {} - if id is not None: - d['id'] = id - d['prev_comm'] = groups[0] - d['prev_pid'] = int(groups[1]) - d['prev_prio'] = int(groups[2]) - d['prev_state'] = groups[3] - d['next_comm'] = groups[4] - d['next_pid'] = int(groups[5]) - d['next_prio'] = int(groups[6]) - - return d - -class SchedBlockedReason(Base): - __tablename__ = 'sched_blocked_reasons' - - id = Column(Integer, ForeignKey('raw_ftrace_entries.id'), primary_key=True) - - pid = Column(Integer, nullable=False) - iowait = Column(Integer, nullable=False) - caller = Column(String, nullable=False) - - @staticmethod - def parse_dict(function_args, id = None): - # 'pid=2289 iowait=1 caller=wait_on_page_bit_common+0x2a8/0x5f' - m = re.match("pid=(\d+) iowait=(\d+) caller=(.*) ?", function_args) - if not m: - return None - - groups = m.groups() - # ('2289', '1', 'wait_on_page_bit_common+0x2a8/0x5f8') - d = {} - if id is not None: - d['id'] = id - d['pid'] = int(groups[0]) - d['iowait'] = int(groups[1]) - d['caller'] = groups[2] - - return d - -class MmFilemapAddToPageCache(Base): - __tablename__ = 'mm_filemap_add_to_page_caches' - - id = Column(Integer, ForeignKey('raw_ftrace_entries.id'), primary_key=True) - - dev = Column(Integer, nullable=False) # decoded from ${major}:${minor} syntax. - dev_major = Column(Integer, nullable=False) # original ${major} value. - dev_minor = Column(Integer, nullable=False) # original ${minor} value. - - ino = Column(Integer, nullable=False) # decoded from hex to base 10 - page = Column(Integer, nullable=False) # decoded from hex to base 10 - - pfn = Column(Integer, nullable=False) - ofs = Column(Integer, nullable=False) - - # 1:1 relation with RawFtraceEntry. - raw_ftrace_entry = relationship("RawFtraceEntry", uselist=False) - - @staticmethod - def parse_dict(function_args, id = None): - # dev 253:6 ino b2c7 page=00000000ec787cd9 pfn=1478539 ofs=4096 - m = re.match("dev (\d+):(\d+) ino ([0-9a-fA-F]+) page=([0-9a-fA-F]+) pfn=(\d+) ofs=(\d+)", function_args) - if not m: - return None - - groups = m.groups() - # ('253', '6', 'b2c7', '00000000ec787cd9', '1478539', '4096') - d = {} - if id is not None: - d['id'] = id - - device_major = d['dev_major'] = int(groups[0]) - device_minor = d['dev_minor'] = int(groups[1]) - d['dev'] = device_major << 8 | device_minor - d['ino'] = int(groups[2], 16) - d['page'] = int(groups[3], 16) - d['pfn'] = int(groups[4]) - d['ofs'] = int(groups[5]) - - return d - -class Trace2Db: - def __init__(self, db_filename: str): - (s, e) = self._init_sqlalchemy(db_filename) - self._session = s - self._engine = e - self._raw_ftrace_entry_filter = lambda x: True - - def set_raw_ftrace_entry_filter(self, flt): - """ - Install a function dict(RawFtraceEntry) -> bool - - If this returns 'false', then we skip adding the RawFtraceEntry to the database. - """ - self._raw_ftrace_entry_filter = flt - - @staticmethod - def _init_sqlalchemy(db_filename: str) -> Tuple[object, object]: - global _DEBUG - engine = create_engine('sqlite:///' + db_filename, echo=_DEBUG) - - # CREATE ... (tables) - Base.metadata.create_all(engine) - - Session = sessionmaker(bind=engine) - session = Session() - return (session, engine) - - def parse_file_into_db(self, filename: str, limit: Optional[int] = None): - """ - Parse the ftrace/systrace at 'filename', - inserting the values into the current sqlite database. - - :return: number of RawFtraceEntry inserted. - """ - return parse_file(filename, self._session, self._engine, self._raw_ftrace_entry_filter, limit) - - def parse_file_buf_into_db(self, file_buf, limit: Optional[int] = None): - """ - Parse the ftrace/systrace at 'filename', - inserting the values into the current sqlite database. - - :return: number of RawFtraceEntry inserted. - """ - return parse_file_buf(file_buf, self._session, self._engine, self._raw_ftrace_entry_filter, limit) - - - @property - def session(self): - return self._session - -def insert_pending_entries(engine, kls, lst): - if len(lst) > 0: - # for some reason, it tries to generate an empty INSERT statement with len=0, - # which of course violates the first non-null constraint. - try: - # Performance-sensitive parsing according to: - # https://docs.sqlalchemy.org/en/13/faq/performance.html#i-m-inserting-400-000-rows-with-the-orm-and-it-s-really-slow - engine.execute(kls.__table__.insert(), lst) - lst.clear() - except sqlalchemy.exc.IntegrityError as err: - # possibly violating some SQL constraint, print data here. - print(err) - print(lst) - raise - -def parse_file(filename: str, *args, **kwargs) -> int: - # use explicit encoding to avoid UnicodeDecodeError. - with open(filename, encoding="ISO-8859-1") as f: - return parse_file_buf(f, *args, **kwargs) - -def parse_file_buf(filebuf, session, engine, raw_ftrace_entry_filter, limit=None) -> int: - global _FLUSH_LIMIT - count = 0 - # count and id are not equal, because count still increases for invalid lines. - id = 0 - - pending_entries = [] - pending_sched_switch = [] - pending_sched_blocked_reasons = [] - pending_mm_filemap_add_to_pagecaches = [] - - def insert_all_pending_entries(): - insert_pending_entries(engine, RawFtraceEntry, pending_entries) - insert_pending_entries(engine, SchedSwitch, pending_sched_switch) - insert_pending_entries(engine, SchedBlockedReason, pending_sched_blocked_reasons) - insert_pending_entries(engine, MmFilemapAddToPageCache, pending_mm_filemap_add_to_pagecaches) - - # for trace.html files produced by systrace, - # the actual ftrace is in the 'second' trace-data script class. - parsing_trace_data = 0 - parsing_systrace_file = False - - f = filebuf - for l in f: - if parsing_trace_data == 0 and l == "<!DOCTYPE html>\n": - parsing_systrace_file = True - continue - if parsing_trace_data != 2 and parsing_systrace_file: - if l == ' <script class="trace-data" type="application/text">\n': - parsing_trace_data = parsing_trace_data + 1 - continue - - if parsing_systrace_file and parsing_trace_data != 2: - continue - elif parsing_systrace_file and parsing_trace_data == 2 and l == " </script>\n": - # the rest of this file is just random html - break - - # now parsing the ftrace data. - if len(l) > 1 and l[0] == '#': - continue - - count = count + 1 - - if limit and count >= limit: - break - - raw_ftrace_entry = RawFtraceEntry.parse_dict(l) - if not raw_ftrace_entry: - print("WARNING: Failed to parse raw ftrace entry: " + l) - continue - - if not raw_ftrace_entry_filter(raw_ftrace_entry): - # Skip processing raw ftrace entries that don't match a filter. - # This is an optimization for when Trace2Db is used programatically - # to avoid having an overly large database. - continue - - pending_entries.append(raw_ftrace_entry) - id = id + 1 - - if raw_ftrace_entry['function'] == 'sched_switch': - sched_switch = SchedSwitch.parse_dict(raw_ftrace_entry['function_args'], id) - - if not sched_switch: - print("WARNING: Failed to parse sched_switch: " + l) - else: - pending_sched_switch.append(sched_switch) - - elif raw_ftrace_entry['function'] == 'sched_blocked_reason': - sbr = SchedBlockedReason.parse_dict(raw_ftrace_entry['function_args'], id) - - if not sbr: - print("WARNING: Failed to parse sched_blocked_reason: " + l) - else: - pending_sched_blocked_reasons.append(sbr) - - elif raw_ftrace_entry['function'] == 'mm_filemap_add_to_page_cache': - d = MmFilemapAddToPageCache.parse_dict(raw_ftrace_entry['function_args'], - id) - if not d: - print("WARNING: Failed to parse mm_filemap_add_to_page_cache: " + l) - else: - pending_mm_filemap_add_to_pagecaches.append(d) - - # Objects are cached in python memory, not yet sent to SQL database. - - # Send INSERT/UPDATE/etc statements to the underlying SQL database. - if count % _FLUSH_LIMIT == 0: - insert_all_pending_entries() - - insert_all_pending_entries() - - # Ensure underlying database commits changes from memory to disk. - session.commit() - - return count diff --git a/startop/scripts/trace_analyzer/lib/trace2db_test.py b/startop/scripts/trace_analyzer/lib/trace2db_test.py deleted file mode 100755 index 3b326f000a7d..000000000000 --- a/startop/scripts/trace_analyzer/lib/trace2db_test.py +++ /dev/null @@ -1,222 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. -# - -""" -Unit tests for inode2filename module. - -Install: - $> sudo apt-get install python3-pytest ## OR - $> pip install -U pytest -See also https://docs.pytest.org/en/latest/getting-started.html - -Usage: - $> ./inode2filename_test.py - $> pytest inode2filename_test.py - $> python -m pytest inode2filename_test.py - -See also https://docs.pytest.org/en/latest/usage.html -""" - -# global imports -import io -from copy import deepcopy - -# pip imports -# local imports -from trace2db import * - -# This pretty-prints the raw dictionary of the sqlalchemy object if it fails. -class EqualsSqlAlchemyObject: - # For convenience to write shorter tests, we also add 'ignore_fields' which allow us to specify - # which fields to ignore when doing the comparison. - def __init__(self_, self, ignore_fields=[]): - self_.self = self - self_.ignore_fields = ignore_fields - - # Do field-by-field comparison. - # It seems that SQLAlchemy does not implement __eq__ itself so we have to do it ourselves. - def __eq__(self_, other): - if isinstance(other, EqualsSqlAlchemyObject): - other = other.self - - self = self_.self - - classes_match = isinstance(other, self.__class__) - a, b = deepcopy(self.__dict__), deepcopy(other.__dict__) - - #compare based on equality our attributes, ignoring SQLAlchemy internal stuff - - a.pop('_sa_instance_state', None) - b.pop('_sa_instance_state', None) - - for f in self_.ignore_fields: - a.pop(f, None) - b.pop(f, None) - - attrs_match = (a == b) - return classes_match and attrs_match - - def __repr__(self): - return repr(self.self.__dict__) - - -def assert_eq_ignore_id(left, right): - # This pretty-prints the raw dictionary of the sqlalchemy object if it fails. - # It does field-by-field comparison, but ignores the 'id' field. - assert EqualsSqlAlchemyObject(left, ignore_fields=['id']) == EqualsSqlAlchemyObject(right) - -def parse_trace_file_to_db(*contents): - """ - Make temporary in-memory sqlite3 database by parsing the string contents as a trace. - - :return: Trace2Db instance - """ - buf = io.StringIO() - - for c in contents: - buf.write(c) - buf.write("\n") - - buf.seek(0) - - t2d = Trace2Db(":memory:") - t2d.parse_file_buf_into_db(buf) - - buf.close() - - return t2d - -def test_ftrace_mm_filemap_add_to_pagecache(): - test_contents = """ -MediaStoreImpor-27212 (27176) [000] .... 16136.595194: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744 -MediaStoreImpor-27212 (27176) [000] .... 16136.595920: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000048e2e156 pfn=677645 ofs=126976 -MediaStoreImpor-27212 (27176) [000] .... 16136.597793: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000051eabfb2 pfn=677644 ofs=122880 -MediaStoreImpor-27212 (27176) [000] .... 16136.597815: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000ce7cd606 pfn=677643 ofs=131072 -MediaStoreImpor-27212 (27176) [000] .... 16136.603732: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=000000008ffd3030 pfn=730119 ofs=186482688 -MediaStoreImpor-27212 (27176) [000] .... 16136.604126: mm_filemap_add_to_page_cache: dev 253:6 ino b1d8 page=0000000098d4d2e2 pfn=829676 ofs=0 - <...>-27197 (-----) [002] .... 16136.613471: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000aca88a97 pfn=743346 ofs=241664 - <...>-27197 (-----) [002] .... 16136.615979: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000351f2bc1 pfn=777799 ofs=106496 - <...>-27224 (-----) [006] .... 16137.400090: mm_filemap_add_to_page_cache: dev 253:6 ino 712d page=000000006ff7ffdb pfn=754861 ofs=0 - <...>-1396 (-----) [000] .... 16137.451660: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000ba0cbb34 pfn=769173 ofs=187191296 - <...>-1396 (-----) [000] .... 16137.453020: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000f6ef038e pfn=820291 ofs=0 - <...>-1396 (-----) [000] .... 16137.453067: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=0000000083ebc446 pfn=956463 ofs=4096 - <...>-1396 (-----) [000] .... 16137.453101: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000009dc2cd25 pfn=822813 ofs=8192 - <...>-1396 (-----) [000] .... 16137.453113: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000a11167fb pfn=928650 ofs=12288 - <...>-1396 (-----) [000] .... 16137.453126: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000c1c3311b pfn=621110 ofs=16384 - <...>-1396 (-----) [000] .... 16137.453139: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000009aa78342 pfn=689370 ofs=20480 - <...>-1396 (-----) [000] .... 16137.453151: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=0000000082cddcd6 pfn=755584 ofs=24576 - <...>-1396 (-----) [000] .... 16137.453162: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000b0249bc7 pfn=691431 ofs=28672 - <...>-1396 (-----) [000] .... 16137.453183: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000006a776ff0 pfn=795084 ofs=32768 - <...>-1396 (-----) [000] .... 16137.453203: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000001a4918a7 pfn=806998 ofs=36864 - <...>-2578 (-----) [002] .... 16137.561871: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000d65af9d2 pfn=719246 ofs=187015168 - <...>-2578 (-----) [002] .... 16137.562846: mm_filemap_add_to_page_cache: dev 253:6 ino b25a page=000000002f6ba74f pfn=864982 ofs=0 - <...>-2578 (-----) [000] .... 16138.104500: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000f888d0f6 pfn=805812 ofs=192794624 - <...>-2578 (-----) [000] .... 16138.105836: mm_filemap_add_to_page_cache: dev 253:6 ino b7dd page=000000003749523b pfn=977196 ofs=0 - <...>-27215 (-----) [001] .... 16138.256881: mm_filemap_add_to_page_cache: dev 253:6 ino 758f page=000000001b375de1 pfn=755928 ofs=0 - <...>-27215 (-----) [001] .... 16138.257526: mm_filemap_add_to_page_cache: dev 253:6 ino 7591 page=000000004e039481 pfn=841534 ofs=0 - NonUserFacing6-5246 ( 1322) [005] .... 16138.356491: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000d65af9d2 pfn=719246 ofs=161890304 - NonUserFacing6-5246 ( 1322) [005] .... 16138.357538: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000002f6ba74f pfn=864982 ofs=0 - NonUserFacing6-5246 ( 1322) [005] .... 16138.357581: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096 - <...>-27197 (-----) [005] .... 16140.143224: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000a42527c6 pfn=1076669 ofs=32768 - """ - - t2d = parse_trace_file_to_db(test_contents) - session = t2d.session - - first_row = session.query(MmFilemapAddToPageCache).order_by(MmFilemapAddToPageCache.id).first() - - #dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744 - assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6, - ino=0x7580, page=0x0000000060e990c7, pfn=677646, ofs=159744), first_row) - - second_to_last_row = session.query(MmFilemapAddToPageCache).filter(MmFilemapAddToPageCache.page.in_([0x000000006e0f8322])).first() - - # dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096 - assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6, - ino=0x9a64, page=0x000000006e0f8322, pfn=797894, ofs=4096), second_to_last_row) - -def test_systrace_mm_filemap_add_to_pagecache(): - test_contents = """ -<!DOCTYPE html> -<html> -<head i18n-values="dir:textdirection;"> -<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> -<meta charset="utf-8"/> -<title>Android System Trace</title> - <script class="trace-data" type="application/text"> -PROCESS DUMP -USER PID PPID VSZ RSS WCHAN PC S NAME COMM -root 1 0 62148 5976 0 0 S init [init] -root 2 0 0 0 0 0 S [kthreadd] [kthreadd] - </script> - - <script class="trace-data" type="application/text"> -MediaStoreImpor-27212 (27176) [000] .... 16136.595194: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744 -NonUserFacing6-5246 ( 1322) [005] .... 16138.357581: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096 - </script> - - <script class="trace-data" type="application/text"> -{"traceEvents": [{"category": "process_argv", "name": "process_argv", "args": {"argv": ["/mnt/ssd3/workspace/master/external/chromium-trace/systrace.py", "-t", "5", "pagecache"]}, "pid": 160383, "ts": 1037300940509.7991, "tid": 139628672526080, "ph": "M"}, {"category": "python", "name": "clock_sync", "args": {"issue_ts": 1037307346185.212, "sync_id": "9a7e4fe3-89ad-441f-8226-8fe533fe973e"}, "pid": 160383, "ts": 1037307351643.906, "tid": 139628726089536, "ph": "c"}], "metadata": {"clock-domain": "SYSTRACE"}} - </script> -<!-- END TRACE --> - """ - - t2d = parse_trace_file_to_db(test_contents) - session = t2d.session - - first_row = session.query(MmFilemapAddToPageCache).order_by(MmFilemapAddToPageCache.id).first() - - #dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744 - assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6, - ino=0x7580, page=0x0000000060e990c7, pfn=677646, ofs=159744), first_row) - - second_to_last_row = session.query(MmFilemapAddToPageCache).filter(MmFilemapAddToPageCache.page.in_([0x000000006e0f8322])).first() - - # dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096 - assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6, - ino=0x9a64, page=0x000000006e0f8322, pfn=797894, ofs=4096), second_to_last_row) - -def test_timestamp_filter(): - test_contents = """ - MediaStoreImpor-27212 (27176) [000] .... 16136.595194: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744 - NonUserFacing6-5246 ( 1322) [005] .... 16139.357581: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096 - MediaStoreImpor-27212 (27176) [000] .... 16136.604126: mm_filemap_add_to_page_cache: dev 253:6 ino b1d8 page=0000000098d4d2e2 pfn=829676 ofs=0 - """ - - t2d = parse_trace_file_to_db(test_contents) - session = t2d.session - - end_time = 16137.0 - - results = session.query(MmFilemapAddToPageCache).join( - MmFilemapAddToPageCache.raw_ftrace_entry).filter( - RawFtraceEntry.timestamp <= end_time).order_by( - MmFilemapAddToPageCache.id).all() - - assert len(results) == 2 - assert_eq_ignore_id( - MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6, - ino=0x7580, page=0x0000000060e990c7, pfn=677646, - ofs=159744), results[0]) - assert_eq_ignore_id( - MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6, - ino=0xb1d8, page=0x0000000098d4d2e2, pfn=829676, - ofs=0), results[1]) - - -if __name__ == '__main__': - pytest.main() diff --git a/startop/scripts/trace_analyzer/queries_all.sql b/startop/scripts/trace_analyzer/queries_all.sql deleted file mode 100644 index 41d1c0804a7f..000000000000 --- a/startop/scripts/trace_analyzer/queries_all.sql +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - --- filter for atrace writes -CREATE VIEW IF NOT EXISTS tracing_mark_writes AS - SELECT * - FROM raw_ftrace_entries - WHERE function = 'tracing_mark_write'; - --- split the tracing_mark_write function args by ||s -DROP TABLE IF exists tracing_mark_write_split_array; - -CREATE TABLE tracing_mark_write_split_array ( - predictorset_id INT REFERENCES raw_ftrace_entries (id), - predictor_name, - rest, - gen, - - UNIQUE(predictorset_id, gen) -- drops redundant inserts into table -); - -CREATE INDEX "tracing_mark_write_split_array_id" ON tracing_mark_write_split_array ( - predictorset_id COLLATE BINARY COLLATE BINARY -); - -INSERT INTO tracing_mark_write_split_array - WITH - split(predictorset_id, predictor_name, rest, gen) AS ( - -- split by | - SELECT id, '', function_args || '|', 0 FROM tracing_mark_writes WHERE id - UNION ALL - SELECT predictorset_id, - substr(rest, 0, instr(rest, '|')), - substr(rest, instr(rest, '|')+1), - gen + 1 - FROM split - WHERE rest <> ''), - split_results AS ( - SELECT * FROM split WHERE predictor_name <> '' - ) - SELECT * from split_results -; - - diff --git a/startop/scripts/trace_analyzer/queries_app_launch_spans_with_name.sql b/startop/scripts/trace_analyzer/queries_app_launch_spans_with_name.sql deleted file mode 100644 index c28475eec73d..000000000000 --- a/startop/scripts/trace_analyzer/queries_app_launch_spans_with_name.sql +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - --- use the 'launching: $process_name' async slice to figure out launch duration. -DROP VIEW IF EXISTS launch_durations_named; - -CREATE VIEW launch_durations_named AS -WITH - launch_traces_raw AS ( - SELECT * - FROM tracing_mark_write_split AS tmw, - raw_ftrace_entries AS rfe - WHERE atrace_message LIKE 'launching: %' AND rfe.id = tmw.raw_ftrace_entry_id - ), - launch_traces_joined AS ( - SELECT started.timestamp AS started_timestamp, - finished.timestamp AS finished_timestamp, - started.id AS started_id, - finished.id AS finished_id, - SUBSTR(started.atrace_message, 12) AS proc_name -- crop out "launching: " from the string. - FROM launch_traces_raw AS started, - launch_traces_raw AS finished - -- async slices ('S' -> 'F') have matching counters given the same PID. - WHERE started.atrace_type == 'S' - AND finished.atrace_type == 'F' - AND started.atrace_count == finished.atrace_count - AND started.atrace_pid == finished.atrace_pid - ) -SELECT * from launch_traces_joined; - -SELECT * FROM launch_durations_named; diff --git a/startop/scripts/trace_analyzer/queries_block_launch.sql b/startop/scripts/trace_analyzer/queries_block_launch.sql deleted file mode 100644 index 34e5f03d0c48..000000000000 --- a/startop/scripts/trace_analyzer/queries_block_launch.sql +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - -DROP VIEW IF EXISTS blocked_iowait_for_app_launches; - -CREATE VIEW blocked_iowait_for_app_launches AS -WITH - block_launch_join AS ( - SELECT * - FROM blocking_durations AS bd, - launch_durations_named AS ld - WHERE bd.block_timestamp >= ld.started_timestamp - AND bd.unblock_timestamp <= ld.finished_timestamp - ), - blocked_ui_threads AS ( - SELECT * - FROM start_process_ui_threads AS sp, - block_launch_join AS blj - WHERE sp.atm_ui_thread_tid == unblock_pid - AND sp.process_name = blj.proc_name - ), - summed_raw AS ( - SELECT SUM(unblock_timestamp-block_timestamp)*1000 AS sum_block_duration_ms, - * - FROM blocked_ui_threads - GROUP BY unblock_pid - ), - summed_neat AS ( - SELECT sum_block_duration_ms AS blocked_iowait_duration_ms, - process_name, - (finished_timestamp - started_timestamp) * 1000 AS launching_duration_ms, - started_timestamp * 1000 AS launching_started_timestamp_ms, - finished_timestamp * 1000 AS launching_finished_timestamp_ms - -- filter out the rest because its just selecting 1 arbitrary row (due to the SUM aggregate)., - FROM summed_raw - ) -SELECT * FROM summed_neat; - -SELECT * FROM blocked_iowait_for_app_launches; diff --git a/startop/scripts/trace_analyzer/queries_find_sched_switch_unblocked.sql b/startop/scripts/trace_analyzer/queries_find_sched_switch_unblocked.sql deleted file mode 100644 index 788d0dae47d3..000000000000 --- a/startop/scripts/trace_analyzer/queries_find_sched_switch_unblocked.sql +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - -DROP VIEW IF EXISTS sched_switch_iowaits_pre; - --- scan for the closest pair such that: --- sched_block_reason pid=$PID iowait=1 ... --- ... --- sched_switch next_pid=$PID -CREATE VIEW sched_switch_iowaits_pre AS - SELECT MAX(sbr.id) AS blocked_id, - ss.id AS sched_switch_id, - pid, -- iow.pid - iowait, -- iowait=0 or iowait=1 - caller, - sbr_f.timestamp AS blocked_timestamp, - ss_f.timestamp AS sched_switch_timestamp, - next_comm, -- name of next_pid - next_pid -- same as iow.pid - FROM sched_blocked_reasons AS sbr, - raw_ftrace_entries AS sbr_f, - sched_switches AS ss, - raw_ftrace_entries AS ss_f - WHERE sbr_f.id == sbr.id - AND ss_f.id == ss.id - AND sbr.pid == ss.next_pid - AND sbr.iowait = 1 - AND sbr_f.timestamp < ss_f.timestamp -- ensures the 'closest' sched_blocked_reason is selected. - GROUP BY ss.id -; - -DROP VIEW IF EXISTS sched_switch_iowaits; - -CREATE VIEW sched_switch_iowaits AS - SELECT *, MIN(sched_switch_timestamp) AS ss_timestamp -- drop all of the 'too large' sched_switch entries except the closest one. - FROM sched_switch_iowaits_pre - GROUP BY blocked_id; - -SELECT * FROM sched_switch_iowaits; - --- use a real table here instead of a view, otherwise SQLiteStudio segfaults for some reason. -DROP TABLE IF EXISTS blocking_durations; - -CREATE TABLE blocking_durations AS -WITH - blocking_durations_raw AS ( - SELECT MAX(ss.id) AS block_id, - ssf.timestamp AS block_timestamp, - iow.sched_switch_timestamp AS unblock_timestamp, - ss.prev_comm as block_prev_comm, - iow.next_comm AS unblock_next_comm, - ss.prev_state AS block_prev_state, - iow.sched_switch_id AS unblock_id, - iow.pid AS unblock_pid, - iow.caller AS unblock_caller - FROM sched_switches AS ss, -- this is the sched_switch that caused a block (in the future when it unblocks, the reason is iowait=1). - sched_switch_iowaits AS iow, -- this is the sched_switch that removes the block (it is now running again). - raw_ftrace_entries AS ssf - WHERE ssf.id = ss.id AND ss.prev_pid == iow.next_pid AND ssf.timestamp < iow.sched_switch_timestamp - GROUP BY unblock_timestamp - ), - blocking_durations_tmp AS ( - SELECT block_id, - unblock_timestamp, - block_timestamp, - block_prev_comm as comm, - block_prev_state as block_state, - unblock_id, - unblock_pid, - unblock_caller - FROM blocking_durations_raw - ) - SELECT * FROM blocking_durations_tmp;-- ORDER BY block_id ASC; - --SELECT SUM(block_duration_ms) AS sum, * FROM blocking_durations GROUP BY unblock_pid ORDER BY sum DESC; - -DROP INDEX IF EXISTS "blocking_durations_block_timestamp"; - -CREATE INDEX "blocking_durations_block_timestamp" ON blocking_durations ( - block_timestamp COLLATE BINARY COLLATE BINARY -); - -DROP INDEX IF EXISTS "blocking_durations_unblock_timestamp"; - -CREATE INDEX "blocking_durations_unblock_timestamp" ON blocking_durations ( - unblock_timestamp COLLATE BINARY COLLATE BINARY -); - -SELECT * FROM blocking_durations; diff --git a/startop/scripts/trace_analyzer/queries_get_comm_and_pids.sql b/startop/scripts/trace_analyzer/queries_get_comm_and_pids.sql deleted file mode 100644 index 0c166b09784c..000000000000 --- a/startop/scripts/trace_analyzer/queries_get_comm_and_pids.sql +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - -DROP VIEW IF EXISTS sched_switch_next_comm_pids; - -CREATE VIEW IF NOT EXISTS sched_switch_next_comm_pids AS - --- TODO: switch to using sched_switches table. - -WITH - sched_switchs AS ( - SELECT * FROM raw_ftrace_entries WHERE function = 'sched_switch' AND function_args LIKE '% next_pid=%' AND function_args NOT LIKE '% next_comm=main %' - ), - comm_and_pids_raws AS ( - SELECT id, - SUBSTR(function_args, instr(function_args, "next_comm="), instr(function_args, "next_pid=") - instr(function_args, "next_comm=")) AS next_comm_raw, - SUBSTR(function_args, instr(function_args, "next_pid="), instr(function_args, "next_prio=") - instr(function_args, "next_pid=")) AS next_pid_raw - FROM sched_switchs - ), - comm_and_pids AS ( - SELECT id, - id AS raw_ftrace_entry_id, - TRIM(SUBSTR(next_pid_raw, 10)) AS next_pid, -- len("next_pid=") is 10 - TRIM(SUBSTR(next_comm_raw, 11)) AS next_comm -- len("next_comm=") is 11 - FROM comm_and_pids_raws - ) -SELECT * from comm_and_pids; - -SELECT * from sched_switch_next_comm_pids; diff --git a/startop/scripts/trace_analyzer/queries_get_procs.sql b/startop/scripts/trace_analyzer/queries_get_procs.sql deleted file mode 100644 index 06871c6e16b6..000000000000 --- a/startop/scripts/trace_analyzer/queries_get_procs.sql +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - -DROP VIEW IF EXISTS start_procs; - -CREATE VIEW IF NOT EXISTS start_procs AS -WITH - start_procs_raw AS ( - SELECT * from tracing_mark_write_split WHERE atrace_message LIKE 'Start proc: %' - ), - start_procs_substr AS ( - -- note: "12" is len("Start proc: ")+1. sqlite indices start at 1. - SELECT raw_ftrace_entry_id, atrace_pid, SUBSTR(atrace_message, 13) AS process_name FROM start_procs_raw - ) -SELECT * from start_procs_substr; - -SELECT * from start_procs; diff --git a/startop/scripts/trace_analyzer/queries_get_ui_threads.sql b/startop/scripts/trace_analyzer/queries_get_ui_threads.sql deleted file mode 100644 index 876e50e9880a..000000000000 --- a/startop/scripts/trace_analyzer/queries_get_ui_threads.sql +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - --- note: These queries do comparisons based on raw_ftrace_entries.id by treating it as if it was equivalent to the temporal timestamp. --- in practice, the ID of raw_ftrace_entries is based on its order in the ftrace buffer [and on the same cpu its equivalent]. --- we can always resort raw_ftrace_entries to ensure id order matches timestamp order. We should rarely need to compare by timestamp directly. --- accessing 'floats' is inferior as they are harder to index, and will result in slower queries. --- --- Naming convention note: '_fid' corresponds to 'raw_ftrace_entry.id'. -DROP VIEW IF EXISTS start_process_ui_threads; - --- Map of started process names to their UI thread's TID (as returned by gettid). -CREATE VIEW IF NOT EXISTS start_process_ui_threads AS -WITH - start_proc_tids AS ( - SELECT sp.raw_ftrace_entry_id AS start_proc_fid, - sp.atrace_pid AS atrace_pid, - sp.process_name AS process_name, - --MIN(nc.raw_ftrace_entry_id) as next_comm_fid, - nc.raw_ftrace_entry_id AS next_comm_fid, - nc.next_pid as next_pid, - nc.next_comm as next_comm, - SUBSTR(sp.process_name, -15) AS cut -- why -15? See TASK_MAX in kernel, the sched_switch name is truncated to 16 bytes. - FROM start_procs AS sp, - sched_switch_next_comm_pids AS nc - WHERE sp.process_name LIKE '%' || nc.next_comm -- kernel truncates the sched_switch::next_comm event, so we must match the prefix of the full name. - --WHERE SUBSTR(sp.process_name, -16) == nc.next_comm - --WHERE cut == nc.next_comm - ), - start_proc_tids_filtered AS ( - SELECT * - FROM start_proc_tids - WHERE next_comm_fid > start_proc_fid -- safeguard that avoids choosing "earlier" sched_switch before process was even started. - --ORDER BY start_proc_fid, next_comm_fid - ), - start_proc_all_threads AS ( - SELECT DISTINCT - start_proc_fid, -- this is the ftrace entry of the system server 'Start proc: $process_name'. only need this to join for timestamp. - process_name, -- this is the '$process_name' from the system server entry. - -- next up we have all the possible thread IDs as parsed from sched_switch that corresponds most closest to the start proc. - next_pid AS ui_thread_tpid, -- sched_switch.next_pid. This can be any of the threads in that process, it's not necessarily the main UI thread yet. - next_comm, - MIN(next_comm_fid) AS next_comm_fid -- don't pick the 'later' next_comm_fid because it could correspond to another app start. - FROM start_proc_tids_filtered - GROUP BY start_proc_fid, ui_thread_tpid - ), - activity_thread_mains AS ( - SELECT * FROM tracing_mark_write_split WHERE atrace_message = 'ActivityThreadMain' - ), - start_proc_ui_threads AS ( - SELECT start_proc_fid, - process_name, - ui_thread_tpid, - next_comm, - next_comm_fid, - atm.raw_ftrace_entry_id as atm_fid, - atm.atrace_pid as atm_ui_thread_tid - FROM start_proc_all_threads AS spt, - activity_thread_mains AS atm - WHERE atm.atrace_pid == spt.ui_thread_tpid AND atm.raw_ftrace_entry_id > spt.start_proc_fid -- Ensure we ignore earlier ActivityThreadMains prior to their Start proc. - ), - start_proc_ui_threads_filtered AS ( - SELECT start_proc_fid, - process_name, -- e.g. 'com.android.settings' - --ui_thread_tpid, - --next_comm, - --next_comm_fid, - MIN(atm_fid) AS atm_fid, - atm_ui_thread_tid -- equivalent to gettid() for the process's UI thread. - FROM start_proc_ui_threads - GROUP BY start_proc_fid, atm_ui_thread_tid -- find the temporally closest ActivityTaskMain to a "Start proc: $process_name" - ) -SELECT * FROM start_proc_ui_threads_filtered; - -SELECT * FROM start_process_ui_threads; diff --git a/startop/scripts/trace_analyzer/queries_mark_write_join.sql b/startop/scripts/trace_analyzer/queries_mark_write_join.sql deleted file mode 100644 index 100f07403423..000000000000 --- a/startop/scripts/trace_analyzer/queries_mark_write_join.sql +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - -DROP TABLE IF EXISTS tracing_mark_write_split; - -CREATE TABLE tracing_mark_write_split ( - raw_ftrace_entry_id INT REFERENCES raw_ftrace_entries (id), - atrace_type CHAR(1), -- only null for the first 2 sync timers. usually 'B', 'C', E', ... - atrace_pid INT, -- only null for first 2 sync timers - atrace_message, -- usually null for type='E' etc. - atrace_count, -- usually non-null only for 'C' - - UNIQUE(raw_ftrace_entry_id) -- drops redundant inserts into table -); - -INSERT INTO tracing_mark_write_split -WITH - pivoted AS ( - SELECT tx.predictorset_id, - --ty.predictorset_id, - --tz.predictorset_id, - --tzz.predictorset_id, - tx.predictor_name AS atrace_type, - CAST(ty.predictor_name AS integer) AS atrace_pid, - tz.predictor_name AS atrace_message, - CAST(tzz.predictor_name AS integer) AS atrace_count - FROM (SELECT * from tracing_mark_write_split_array WHERE gen = 1) AS tx - LEFT JOIN - (SELECT * FROM tracing_mark_write_split_array WHERE gen = 2) AS ty - ON tx.predictorset_id = ty.predictorset_id - LEFT JOIN - (SELECT * FROM tracing_mark_write_split_array WHERE gen = 3) AS tz - ON tx.predictorset_id = tz.predictorset_id - LEFT JOIN - (SELECT * FROM tracing_mark_write_split_array WHERE gen = 4) AS tzz - ON tx.predictorset_id = tzz.predictorset_id - ) -SELECT * from pivoted ORDER BY predictorset_id;-- LIMIT 100; - -SELECT * FROM tracing_mark_write_split; diff --git a/startop/scripts/trace_analyzer/run-sql-queries b/startop/scripts/trace_analyzer/run-sql-queries deleted file mode 100755 index 61a0ad42a339..000000000000 --- a/startop/scripts/trace_analyzer/run-sql-queries +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/bash -# Copyright (C) 2019 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. - -DIR="$( cd "$(dirname "$0")" ; pwd -P )" - -if [[ $# -lt 1 ]]; then - echo "Usage: $0 <db-file>" -fi - -DB_TARGET=$1 - -if ! [[ -f $DB_TARGET ]]; then - echo "ERROR: File '$DB_TARGET' does not exist." >&2 - exit 1 -fi - -exec_sql_file() { - local filename="$1" - if ! [[ -f $filename ]]; then - echo "ERROR: Can't exec SQL file, '$filename' does not exist." >&2 - return 1 - fi - - sqlite3 "$DB_TARGET" < "$DIR"/"$filename" -} - -exec_sql_file_quiet() { - exec_sql_file "$@" > /dev/null -} - -# Some views/tables need other views already created, so order does matter. -# x -> y , means x depends on y. - -# View: tracing_mark_writes -# Table: tracing_mark_write_split_array -> tracing_mark_writes -exec_sql_file_quiet "queries_all.sql" - -# Table: tracing_mark_write_split -> tracing_mark_write_split_array -exec_sql_file_quiet "queries_mark_write_join.sql" - -# View: start_procs -> tracing_mark_write_split -exec_sql_file_quiet "queries_get_procs.sql" - -# View: sched_switch_next_comm_pids -exec_sql_file_quiet "queries_get_comm_and_pids.sql" - -# View: start_process_ui_threads -> start_procs, sched_switch_next_comm_pids -exec_sql_file_quiet "queries_get_ui_threads.sql" - -# View: launch_durations_named -> tracing_mark_write_split -exec_sql_file_quiet "queries_app_launch_spans_with_name.sql" - -# View: sched_switch_iowaits_pre -# View: sched_switch_iowaits -> sched_switch_iowaits_pre -# Table: blocking_durations -> sched_switch_iowaits -exec_sql_file_quiet "queries_find_sched_switch_unblocked.sql" - -# View: blocked_iowait_for_app_launches -> launch_durations_named, blocking_durations -exec_sql_file_quiet "queries_block_launch.sql" - -##### -##### -##### - -# Final queries - -exec_sql_file "queries_pretty_print_block_launch.sql" diff --git a/startop/scripts/trace_analyzer/test_fixtures/common_systrace b/startop/scripts/trace_analyzer/test_fixtures/common_systrace deleted file mode 100644 index 802cb5562593..000000000000 --- a/startop/scripts/trace_analyzer/test_fixtures/common_systrace +++ /dev/null @@ -1,518 +0,0 @@ -# tracer: nop -# -# entries-in-buffer/entries-written: 411983/411983 #P:8 -# -# _-----=> irqs-off -# / _----=> need-resched -# | / _---=> hardirq/softirq -# || / _--=> preempt-depth -# ||| / delay -# TASK-PID TGID CPU# |||| TIMESTAMP FUNCTION -# | | | | |||| | | - <...>-14603 (-----) [000] ...1 14592.893157: tracing_mark_write: trace_event_clock_sync: parent_ts=14592.892578 - <...>-14603 (-----) [000] ...1 14592.893172: tracing_mark_write: trace_event_clock_sync: realtime_ts=1557129597951 - <...>-18150 (-----) [004] d..2 14594.182110: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=kworker/u16:16 next_pid=23269 next_prio=120 - kworker/u16:16-23269 (23269) [004] d.h3 14594.182228: sched_blocked_reason: pid=18150 iowait=0 caller=a6xx_oob_set+0x194/0x3dc - kworker/u16:16-23269 (23269) [004] d..2 14594.182248: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=D ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120 - <...>-18150 (-----) [004] d..2 14594.182312: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120 - <...>-18150 (-----) [004] d..2 14594.182488: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120 - kworker/u16:16-23269 (23269) [005] d..2 14594.182610: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120 - <...>-18150 (-----) [004] d..2 14594.182626: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120 - <...>-18150 (-----) [004] d..2 14594.182755: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120 - <...>-18150 (-----) [004] d..2 14594.182975: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120 - <...>-18150 (-----) [004] d..2 14594.183209: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120 - <...>-18150 (-----) [004] d..2 14594.183371: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120 - <...>-18150 (-----) [004] d..2 14594.184286: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120 - kworker/u16:16-23269 (23269) [005] d..2 14594.184495: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120 - <...>-18150 (-----) [004] d..2 14594.184498: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120 - ksoftirqd/4-47 ( 47) [004] d..2 14594.185678: sched_switch: prev_comm=ksoftirqd/4 prev_pid=47 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120 - kworker/6:2-10610 (10610) [006] d..2 14594.186012: sched_switch: prev_comm=kworker/6:2 prev_pid=10610 prev_prio=120 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120 - <...>-656 (-----) [001] .... 14594.219464: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120 - <...>-1803 (-----) [000] d..2 14594.219595: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120 - <...>-3359 (-----) [001] ...1 14594.219856: tracing_mark_write: S|1368|launching: com.google.android.dialer|0 - <...>-3359 (-----) [001] ...1 14594.219863: tracing_mark_write: B|1368|MetricsLogger:launchObserverNotifyActivityLaunched - <...>-3359 (-----) [001] ...1 14594.219869: tracing_mark_write: B|1368|MetricsLogger:convertActivityRecordToProto - <...>-1398 (-----) [006] ...1 14594.220160: tracing_mark_write: B|1368|updateInputWindows - <...>-3359 (-----) [001] .... 14594.220230: binder_set_priority: proc=1368 thread=3359 old=110 => new=120 desired=120 - <...>-1398 (-----) [006] ...1 14594.220588: tracing_mark_write: B|1368|android.os.Handler: com.android.server.wm.AppWindowToken$1 - <...>-1398 (-----) [006] ...1 14594.220722: tracing_mark_write: B|1368|ResourcesManager#getResources - <...>-1052 (-----) [002] d..2 14594.220884: sched_switch: prev_comm=statsd.writer prev_pid=1052 prev_prio=120 prev_state=S ==> next_comm=UiThreadHelper next_pid=2045 next_prio=118 - <...>-1398 (-----) [006] ...1 14594.220926: tracing_mark_write: B|1368|Theme::ApplyStyle - <...>-1398 (-----) [006] ...1 14594.220929: tracing_mark_write: B|1368|AssetManager::GetBag - <...>-2007 (-----) [007] ...1 14594.220996: tracing_mark_write: B|2007|Choreographer#doFrame - <...>-2007 (-----) [007] ...1 14594.221005: tracing_mark_write: B|2007|animation - <...>-1398 (-----) [006] ...1 14594.221015: tracing_mark_write: B|1368|ResourcesManager#getResources - <...>-2045 (-----) [002] ...2 14594.221035: binder_set_priority: proc=1368 thread=1903 old=120 => new=118 desired=118 - <...>-2045 (-----) [002] d..2 14594.221065: sched_switch: prev_comm=UiThreadHelper prev_pid=2045 prev_prio=118 prev_state=S ==> next_comm=Binder:1368_4 next_pid=1903 next_prio=118 - <...>-1398 (-----) [006] ...1 14594.221080: tracing_mark_write: B|1368|AssetManager::SetApkAssets - <...>-2007 (-----) [007] ...1 14594.221110: tracing_mark_write: B|2007|traversal - <...>-656 (-----) [000] ...1 14594.221137: tracing_mark_write: B|625|requestNextVsync - <...>-656 (-----) [000] ...1 14594.221141: tracing_mark_write: B|625|resetIdleTimer - <...>-2007 (-----) [007] ...1 14594.221146: tracing_mark_write: B|2007|draw - <...>-2007 (-----) [007] ...1 14594.221160: tracing_mark_write: B|2007|Record View#draw() - <...>-660 (-----) [005] d..2 14594.221285: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110 - <...>-658 (-----) [004] d..2 14594.221327: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=android.display next_pid=1397 next_prio=117 - <...>-2738 (-----) [005] ...1 14594.221342: tracing_mark_write: B|2007|notifyFramePending - <...>-2738 (-----) [005] ...1 14594.221362: tracing_mark_write: B|2007|DrawFrame - <...>-2738 (-----) [005] ...1 14594.221369: tracing_mark_write: B|2007|query - <...>-2007 (-----) [007] d..2 14594.221369: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120 - <...>-1903 (-----) [002] .... 14594.221397: binder_set_priority: proc=1368 thread=1903 old=118 => new=120 desired=120 - <...>-2738 (-----) [005] ...2 14594.221400: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110 - <...>-2738 (-----) [005] d..2 14594.221430: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110 - <...>-1368 (-----) [003] ...1 14594.221431: tracing_mark_write: B|1368|Lock contention on GC thread flip lock (owner tid: 0) - <...>-656 (-----) [005] ...1 14594.221460: tracing_mark_write: B|625|query - <...>-656 (-----) [005] .... 14594.221528: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120 - <...>-2738 (-----) [007] ...1 14594.221552: tracing_mark_write: B|2007|query - <...>-2738 (-----) [007] ...2 14594.221563: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110 - <...>-2738 (-----) [007] d..2 14594.221600: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110 - <...>-1368 (-----) [003] d..2 14594.221623: sched_switch: prev_comm=system_server prev_pid=1368 prev_prio=118 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120 - <...>-656 (-----) [007] ...1 14594.221628: tracing_mark_write: B|625|query - <...>-23031 (-----) [001] d..2 14594.221643: sched_switch: prev_comm=UiAutomation prev_pid=23031 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120 - <...>-2738 (-----) [007] ...1 14594.221664: tracing_mark_write: B|2007|syncFrameState - <...>-2738 (-----) [007] ...1 14594.221697: tracing_mark_write: B|2007|prepareTree - <...>-23008 (-----) [005] d..2 14594.221706: sched_switch: prev_comm=hub.uiautomator prev_pid=23008 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120 - <...>-656 (-----) [000] .... 14594.221737: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120 - <...>-1803 (-----) [003] d..2 14594.221747: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120 - <...>-1397 (-----) [004] d..2 14594.221806: sched_switch: prev_comm=android.display prev_pid=1397 prev_prio=117 prev_state=S ==> next_comm=Binder:2007_A next_pid=4180 next_prio=120 - <...>-1398 (-----) [006] d..2 14594.221816: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=110 prev_state=R ==> next_comm=s.nexuslauncher next_pid=2007 next_prio=110 - <...>-2738 (-----) [007] ...1 14594.221824: tracing_mark_write: B|2007|query - <...>-2738 (-----) [007] ...1 14594.221830: tracing_mark_write: B|2007|query - <...>-2738 (-----) [007] ...1 14594.221834: tracing_mark_write: B|2007|query - <...>-2738 (-----) [007] ...1 14594.221841: tracing_mark_write: B|2007|query - <...>-2738 (-----) [007] ...1 14594.221843: tracing_mark_write: B|2007|query - <...>-2738 (-----) [007] ...1 14594.221846: tracing_mark_write: B|2007|query - <...>-2738 (-----) [007] ...1 14594.221850: tracing_mark_write: B|2007|dequeueBuffer - <...>-2738 (-----) [007] ...2 14594.221864: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110 - <...>-2738 (-----) [007] d..2 14594.221985: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=crtc_event:97 next_pid=303 next_prio=83 - <...>-2007 (-----) [006] ...1 14594.221989: tracing_mark_write: B|2007|topResumedActivityChangeItem - <...>-303 (-----) [007] d..2 14594.222016: sched_switch: prev_comm=crtc_event:97 prev_pid=303 prev_prio=83 prev_state=S ==> next_comm=rcu_preempt next_pid=7 next_prio=120 - rcu_preempt-7 ( 7) [007] d..2 14594.222035: sched_switch: prev_comm=rcu_preempt prev_pid=7 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110 - migration/4-46 ( 46) [004] d..2 14594.222037: sched_switch: prev_comm=migration/4 prev_pid=46 prev_prio=0 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110 - <...>-2738 (-----) [007] d..2 14594.222039: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120 - <...>-656 (-----) [004] ...1 14594.222100: tracing_mark_write: B|625|dequeueBuffer - <...>-656 (-----) [004] ...1 14594.222114: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2 - <...>-2007 (-----) [006] ...2 14594.222131: binder_set_priority: proc=1368 thread=1903 old=120 => new=110 desired=110 - <...>-2007 (-----) [006] d..2 14594.222143: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=UiThreadHelper next_pid=2045 next_prio=118 - <...>-2613 (-----) [001] d..2 14594.222158: sched_switch: prev_comm=ogle.android.as prev_pid=2613 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120 - <...>-18150 (-----) [007] d..2 14594.222193: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120 - <...>-656 (-----) [004] .... 14594.222220: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120 - <...>-2738 (-----) [007] ...1 14594.222267: tracing_mark_write: B|2007|HWC release fence 36027 has signaled - <...>-656 (-----) [007] ...1 14594.223842: tracing_mark_write: B|625|queueBuffer - <...>-656 (-----) [007] ...1 14594.223845: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2 - <...>-656 (-----) [007] ...1 14594.223871: tracing_mark_write: B|625|requestNextVsync - <...>-656 (-----) [007] ...1 14594.223873: tracing_mark_write: B|625|resetIdleTimer - <...>-656 (-----) [007] ...1 14594.223881: tracing_mark_write: B|625|addAndGetFrameTimestamps - <...>-1395 (-----) [001] d..2 14594.223909: sched_switch: prev_comm=android.ui prev_pid=1395 prev_prio=118 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120 - <...>-2738 (-----) [007] ...1 14594.223959: tracing_mark_write: B|2007|Trace GPU completion fence 36027 - <...>-11799 (-----) [006] ...1 14594.224006: tracing_mark_write: B|2007|waiting for GPU completion 36027 - <...>-11799 (-----) [006] ...1 14594.224009: tracing_mark_write: B|2007|waitForever - <...>-2613 (-----) [004] d..2 14594.224014: sched_switch: prev_comm=ogle.android.as prev_pid=2613 prev_prio=120 prev_state=S ==> next_comm=Binder:1803_6 next_pid=2173 next_prio=120 - <...>-11799 (-----) [006] d..1 14594.224014: fence_enable_signal: driver=kgsl-timeline timeline=kgsl-3d0_13-s.nexuslauncher(200 context=27 seqno=78002 - <...>-11799 (-----) [006] d..2 14594.224021: sched_switch: prev_comm=GPU completion prev_pid=11799 prev_prio=110 prev_state=S ==> next_comm=rcuop/6 next_pid=68 next_prio=120 - rcuop/6-68 ( 68) [006] d..2 14594.224044: sched_switch: prev_comm=rcuop/6 prev_pid=68 prev_prio=120 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120 - <...>-259 (-----) [006] d..2 14594.224132: sched_switch: prev_comm=kgsl_worker_thr prev_pid=259 prev_prio=97 prev_state=S ==> next_comm=Binder:2007_A next_pid=4180 next_prio=120 - <...>-3206 (-----) [001] d..2 14594.224167: sched_switch: prev_comm=aiai-vc-0 prev_pid=3206 prev_prio=139 prev_state=R ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120 - lowpool[847]-14589 ( 2446) [005] d..1 14594.224300: mm_filemap_delete_from_page_cache: dev 0:1 ino 3d0034 page=000000008247d586 pfn=676904 ofs=0 - <...>-1803 (-----) [001] d..2 14594.224302: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=aiai-vc-0 next_pid=3206 next_prio=139 - <...>-3206 (-----) [001] d..2 14594.224433: sched_switch: prev_comm=aiai-vc-0 prev_pid=3206 prev_prio=139 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120 - <...>-1903 (-----) [003] ...1 14594.224490: tracing_mark_write: B|1368|dispatchingStartProcess:com.google.android.dialer - <...>-1903 (-----) [003] ...1 14594.224659: tracing_mark_write: B|1368|wmLayout - <...>-1903 (-----) [003] ...1 14594.224666: tracing_mark_write: B|1368|performSurfacePlacement - <...>-1903 (-----) [003] ...1 14594.224683: tracing_mark_write: B|1368|applySurfaceChanges - <...>-1903 (-----) [003] ...1 14594.224688: tracing_mark_write: B|1368|openSurfaceTransaction - <...>-2738 (-----) [007] ...1 14594.224711: tracing_mark_write: B|2007|query - <...>-1903 (-----) [003] ...1 14594.224714: tracing_mark_write: B|1368|performLayout - <...>-2738 (-----) [007] ...1 14594.224714: tracing_mark_write: B|2007|query - <...>-1903 (-----) [003] ...1 14594.224723: tracing_mark_write: B|1368|applyPostLayoutPolicy - <...>-2738 (-----) [007] d..2 14594.224752: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110 - <...>-656 (-----) [007] .... 14594.224766: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120 - <...>-1398 (-----) [002] ...1 14594.224801: tracing_mark_write: B|1368|Theme::ApplyStyle - <...>-1398 (-----) [002] ...1 14594.224805: tracing_mark_write: B|1368|AssetManager::GetBag - <...>-1398 (-----) [002] ...1 14594.224820: tracing_mark_write: B|1368|AssetManager::GetBag - <...>-1398 (-----) [002] ...1 14594.224826: tracing_mark_write: B|1368|AssetManager::GetBag - <...>-1398 (-----) [002] ...1 14594.224833: tracing_mark_write: B|1368|AssetManager::GetBag - <...>-1398 (-----) [002] ...1 14594.224838: tracing_mark_write: B|1368|AssetManager::GetBag - <...>-1398 (-----) [002] ...1 14594.224846: tracing_mark_write: B|1368|AssetManager::GetBag - <...>-1398 (-----) [002] ...1 14594.224853: tracing_mark_write: B|1368|AssetManager::GetBag - <...>-1398 (-----) [002] ...1 14594.224859: tracing_mark_write: B|1368|AssetManager::GetBag - <...>-1398 (-----) [002] ...1 14594.224864: tracing_mark_write: B|1368|AssetManager::GetBag - <...>-18150 (-----) [006] d..2 14594.228407: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98 - <...>-2738 (-----) [007] d..2 14594.228411: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=kworker/7:0H next_pid=76 next_prio=100 - <...>-1409 (-----) [004] ...1 14594.228417: tracing_mark_write: B|1368|Start proc: com.google.android.dialer - <...>-440 (-----) [006] d..2 14594.228418: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120 - <...>-76 (-----) [007] d..2 14594.228430: sched_switch: prev_comm=kworker/7:0H prev_pid=76 prev_prio=100 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98 - <...>-440 (-----) [007] d..2 14594.228434: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/7:0H next_pid=76 next_prio=100 - <...>-18150 (-----) [006] d..3 14594.228442: sched_blocked_reason: pid=1398 iowait=1 caller=wait_on_page_bit_common+0x2a8/0x5f8 - <...>-76 (-----) [007] d..2 14594.228442: sched_switch: prev_comm=kworker/7:0H prev_pid=76 prev_prio=100 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110 - <...>-2738 (-----) [007] ...2 14594.228446: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110 - <...>-18150 (-----) [006] d..2 14594.228447: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=110 - <...>-2738 (-----) [007] d..2 14594.228479: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110 - <...>-1409 (-----) [004] d..2 14594.228499: sched_switch: prev_comm=ActivityManager prev_pid=1409 prev_prio=118 prev_state=D ==> next_comm=Binder:965_2 next_pid=1041 next_prio=120 - <...>-625 (-----) [003] ...1 14594.229271: tracing_mark_write: B|625|handleTransaction - <...>-1773 (-----) [004] .... 14594.229285: binder_set_priority: proc=625 thread=1773 old=110 => new=120 desired=120 - <...>-440 (-----) [007] d..2 14594.229301: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=RenderThread next_pid=2738 next_prio=110 - <...>-2738 (-----) [007] ...1 14594.229318: tracing_mark_write: B|2007|HWC release fence 36028 has signaled - <...>-2738 (-----) [007] ...1 14594.229331: tracing_mark_write: B|2007|query - <...>-2738 (-----) [007] ...1 14594.229337: tracing_mark_write: B|2007|eglBeginFrame - <...>-2738 (-----) [007] ...1 14594.229352: tracing_mark_write: B|2007|query - <...>-2738 (-----) [007] ...1 14594.229354: tracing_mark_write: B|2007|query - <...>-791 (-----) [000] d..2 14594.229357: sched_switch: prev_comm=main prev_pid=791 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120 - <...>-625 (-----) [003] ...1 14594.229440: tracing_mark_write: B|625|doTransaction - <...>-13916 (-----) [002] d..2 14594.229482: sched_switch: prev_comm=HeapTaskDaemon prev_pid=13916 prev_prio=124 prev_state=D|K ==> next_comm=swapper/2 next_pid=0 next_prio=120 - <...>-13917 (-----) [001] d..2 14594.229492: sched_blocked_reason: pid=13916 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754 - <...>-625 (-----) [003] ...1 14594.229492: tracing_mark_write: B|625|doTransaction - <...>-625 (-----) [003] ...1 14594.229507: tracing_mark_write: B|625|doTransaction - <...>-13917 (-----) [001] d..2 14594.229523: sched_switch: prev_comm=ReferenceQueueD prev_pid=13917 prev_prio=124 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120 - <...>-13916 (-----) [002] d..2 14594.229535: sched_blocked_reason: pid=13917 iowait=0 caller=do_page_fault+0x550/0x5fc - <...>-625 (-----) [003] ...1 14594.229538: tracing_mark_write: B|625|doTransaction - <...>-2738 (-----) [007] ...1 14594.229543: tracing_mark_write: B|2007|flush commands - <...>-13916 (-----) [002] .... 14594.229562: sched_process_exit: comm=HeapTaskDaemon pid=13916 prio=124 - <...>-625 (-----) [003] ...1 14594.229567: tracing_mark_write: B|625|doTransaction - <...>-625 (-----) [003] ...1 14594.229588: tracing_mark_write: B|625|doTransaction - <...>-625 (-----) [003] ...1 14594.229628: tracing_mark_write: B|625|doTransaction - <...>-625 (-----) [003] ...1 14594.229652: tracing_mark_write: B|625|doTransaction - <...>-13916 (-----) [002] d..2 14594.229676: sched_switch: prev_comm=HeapTaskDaemon prev_pid=13916 prev_prio=124 prev_state=x ==> next_comm=swapper/2 next_pid=0 next_prio=120 - <...>-625 (-----) [003] ...1 14594.229676: tracing_mark_write: B|625|doTransaction - <...>-2007 (-----) [006] d..2 14594.229688: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120 - <...>-625 (-----) [003] ...1 14594.229703: tracing_mark_write: B|625|doTransaction - <...>-625 (-----) [003] ...1 14594.229725: tracing_mark_write: B|625|doTransaction - <...>-625 (-----) [003] ...1 14594.229750: tracing_mark_write: B|625|doTransaction - <...>-625 (-----) [003] ...1 14594.229772: tracing_mark_write: B|625|doTransaction - <...>-625 (-----) [003] ...1 14594.229792: tracing_mark_write: B|625|doTransaction - <...>-791 (-----) [000] d..2 14594.229811: sched_switch: prev_comm=main prev_pid=791 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120 - <...>-625 (-----) [003] ...1 14594.229824: tracing_mark_write: B|625|doTransaction - <...>-2738 (-----) [007] ...1 14594.229827: tracing_mark_write: B|2007|eglSwapBuffersWithDamageKHR - <...>-13917 (-----) [001] d..2 14594.229836: sched_switch: prev_comm=ReferenceQueueD prev_pid=13917 prev_prio=124 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120 - <...>-2738 (-----) [007] ...1 14594.229837: tracing_mark_write: B|2007|setSurfaceDamage - <...>-625 (-----) [003] ...1 14594.229850: tracing_mark_write: B|625|doTransaction - <...>-13918 (-----) [002] d..2 14594.229856: sched_blocked_reason: pid=13917 iowait=0 caller=SyS_madvise+0xd34/0xd3c - <...>-5281 (-----) [001] d..2 14594.229932: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120 - <...>-89 (-----) [006] d..2 14594.229951: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120 - <...>-625 (-----) [003] ...1 14594.229982: tracing_mark_write: B|625|handleMessageInvalidate - <...>-625 (-----) [003] ...1 14594.229984: tracing_mark_write: B|625|handlePageFlip - <...>-625 (-----) [003] ...1 14594.230013: tracing_mark_write: B|625|latchBuffer - <...>-13917 (-----) [000] .... 14594.230015: sched_process_exit: comm=ReferenceQueueD pid=13917 prio=124 - <...>-625 (-----) [003] ...1 14594.230020: tracing_mark_write: B|625|query - <...>-625 (-----) [003] ...1 14594.230028: tracing_mark_write: B|625|updateTexImage - <...>-625 (-----) [003] ...1 14594.230035: tracing_mark_write: B|625|acquireBuffer - <...>-625 (-----) [003] ...1 14594.230044: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2 - <...>-2738 (-----) [007] d..2 14594.230057: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=D ==> next_comm=smem_native_lpa next_pid=88 next_prio=120 - <...>-14607 (-----) [000] d..2 14594.259609: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754 - <...>-2738 (-----) [005] d..2 14594.259620: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120 - <...>-1773 (-----) [005] ...1 14594.259649: tracing_mark_write: B|625|query - <...>-2738 (-----) [005] ...1 14594.259714: tracing_mark_write: B|2007|query - <...>-2738 (-----) [005] d..2 14594.259743: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120 - <...>-1773 (-----) [005] ...1 14594.259757: tracing_mark_write: B|625|query - <...>-2738 (-----) [005] ...1 14594.259810: tracing_mark_write: B|2007|syncFrameState - <...>-2738 (-----) [005] ...1 14594.259856: tracing_mark_write: B|2007|prepareTree - Binder:14607_1-14624 (14607) [002] ...1 14594.259863: tracing_mark_write: B|14607|AttachCurrentThread - Binder:14607_1-14624 (14607) [002] ...1 14594.259869: tracing_mark_write: B|14607|Thread::Attach - Binder:14607_1-14624 (14607) [002] ...1 14594.259873: tracing_mark_write: B|14607|Thread birth - Binder:14607_1-14624 (14607) [002] ...1 14594.259916: tracing_mark_write: B|14607|Thread::Init - Binder:14607_1-14624 (14607) [002] ...1 14594.259920: tracing_mark_write: B|14607|InitStackHwm - <...>-14607 (-----) [000] d..2 14594.259932: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120 - Binder:14607_1-14624 (14607) [002] d..2 14594.259941: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc - <...>-3198 (-----) [001] ...1 14594.259942: tracing_mark_write: B|2007|Update SurfaceView position - Binder:14607_1-14624 (14607) [002] ...1 14594.259963: tracing_mark_write: B|14607|InitTlsEntryPoints - Binder:14607_1-14624 (14607) [002] ...1 14594.259974: tracing_mark_write: B|14607|InitInterpreterTls - <...>-14607 (-----) [000] d..2 14594.260005: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754 - <...>-3198 (-----) [001] d..2 14594.260007: sched_switch: prev_comm=hwuiTask1 prev_pid=3198 prev_prio=118 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120 - <...>-14607 (-----) [000] d..2 14594.260024: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120 - Binder:14607_1-14624 (14607) [002] d..2 14594.260038: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc - <...>-14607 (-----) [000] d..2 14594.260064: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754 - Binder:14607_1-14624 (14607) [002] ...1 14594.260101: tracing_mark_write: B|14607|ThreadList::Register - <...>-2738 (-----) [005] ...1 14594.260128: tracing_mark_write: B|2007|query - <...>-2738 (-----) [005] ...1 14594.260140: tracing_mark_write: B|2007|query - <...>-2738 (-----) [005] ...1 14594.260148: tracing_mark_write: B|2007|query - <...>-2738 (-----) [005] ...1 14594.260155: tracing_mark_write: B|2007|query - <...>-2738 (-----) [005] ...1 14594.260161: tracing_mark_write: B|2007|query - <...>-2738 (-----) [005] ...1 14594.260167: tracing_mark_write: B|2007|query - <...>-2738 (-----) [005] ...1 14594.260173: tracing_mark_write: B|2007|dequeueBuffer - <...>-2007 (-----) [001] d..2 14594.260201: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120 - <...>-2738 (-----) [005] d..2 14594.260214: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120 - <...>-1773 (-----) [005] ...1 14594.260236: tracing_mark_write: B|625|dequeueBuffer - <...>-1773 (-----) [005] ...1 14594.260249: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2 - <...>-14607 (-----) [000] d..2 14594.260334: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120 - Binder:14607_1-14624 (14607) [002] d..2 14594.260343: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc - <...>-14607 (-----) [000] d..2 14594.260376: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754 - <...>-14607 (-----) [000] d..2 14594.260387: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120 - <...>-2738 (-----) [005] ...1 14594.260401: tracing_mark_write: B|2007|HWC release fence 36030 has signaled - Binder:14607_1-14624 (14607) [002] d..2 14594.260407: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc - <...>-2738 (-----) [005] ...1 14594.260419: tracing_mark_write: B|2007|query - <...>-2738 (-----) [005] ...1 14594.260427: tracing_mark_write: B|2007|eglBeginFrame - <...>-2738 (-----) [005] ...1 14594.260445: tracing_mark_write: B|2007|query - <...>-2738 (-----) [005] ...1 14594.260450: tracing_mark_write: B|2007|query - Binder:14607_1-14624 (14607) [002] .... 14594.260472: task_newtask: pid=14625 comm=Binder:14607_1 clone_flags=3d0f00 oom_score_adj=-1000 - <...>-14607 (-----) [000] d..2 14594.260517: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120 - Binder:14607_2-14625 (14607) [001] d..2 14594.260525: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc - <...>-14607 (-----) [000] d..2 14594.260555: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754 - <...>-14607 (-----) [000] ...1 14594.260569: tracing_mark_write: B|14607|ActivityThreadMain - <...>-14607 (-----) [000] d..2 14594.260581: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120 - Binder:14607_2-14625 (14607) [001] d..2 14594.260588: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc - <...>-14607 (-----) [000] d..2 14594.260611: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754 - <...>-14607 (-----) [000] d..2 14594.260623: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120 - Binder:14607_2-14625 (14607) [001] d..2 14594.260636: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc - <...>-14607 (-----) [000] d..2 14594.260663: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754 - <...>-14607 (-----) [000] d..2 14594.260674: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120 - Binder:14607_2-14625 (14607) [001] d..2 14594.260694: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc - <...>-14607 (-----) [000] d..2 14594.260724: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754 - <...>-2738 (-----) [005] ...1 14594.260734: tracing_mark_write: B|2007|flush commands - <...>-14607 (-----) [000] d..2 14594.260735: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120 - Binder:14607_2-14625 (14607) [001] d..2 14594.260753: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc - Binder:14607_2-14625 (14607) [001] ...1 14594.260925: tracing_mark_write: B|14607|AttachCurrentThread - Binder:14607_2-14625 (14607) [001] ...1 14594.260930: tracing_mark_write: B|14607|Thread::Attach - Binder:14607_2-14625 (14607) [001] ...1 14594.260933: tracing_mark_write: B|14607|Thread birth - Binder:14607_2-14625 (14607) [001] ...1 14594.260973: tracing_mark_write: B|14607|Thread::Init - Binder:14607_2-14625 (14607) [001] ...1 14594.260977: tracing_mark_write: B|14607|InitStackHwm - <...>-14607 (-----) [000] d..2 14594.260990: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120 - Binder:14607_2-14625 (14607) [001] d..2 14594.260998: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc - Binder:14607_2-14625 (14607) [001] ...1 14594.261023: tracing_mark_write: B|14607|InitTlsEntryPoints - Binder:14607_2-14625 (14607) [001] ...1 14594.261034: tracing_mark_write: B|14607|InitInterpreterTls - <...>-14607 (-----) [000] d..2 14594.261064: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754 - <...>-14607 (-----) [000] d..2 14594.261075: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120 - Binder:14607_2-14625 (14607) [001] d..2 14594.261094: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc - <...>-14607 (-----) [000] d..2 14594.261120: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754 - <...>-14607 (-----) [000] d..2 14594.261132: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120 - Binder:14607_2-14625 (14607) [001] d..2 14594.261146: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc - Binder:14607_2-14625 (14607) [001] ...1 14594.261167: tracing_mark_write: B|14607|ThreadList::Register - <...>-14607 (-----) [000] d..2 14594.261209: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754 - <...>-2738 (-----) [005] ...1 14594.261212: tracing_mark_write: B|2007|waitOnFences - <...>-14607 (-----) [000] d..2 14594.261220: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120 - <...>-2738 (-----) [005] ...1 14594.261232: tracing_mark_write: B|2007|eglSwapBuffersWithDamageKHR - <...>-2738 (-----) [005] ...1 14594.261244: tracing_mark_write: B|2007|setSurfaceDamage - Binder:14607_2-14625 (14607) [001] d..2 14594.261246: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc - <...>-14607 (-----) [000] ...1 14594.261326: tracing_mark_write: B|14607|VerifyClass com.android.org.conscrypt.TrustedCertificateStore$PreloadHolder - <...>-2738 (-----) [005] .... 14594.261621: fence_init: driver=kgsl-timeline timeline=kgsl-3d0_13-s.nexuslauncher(200 context=27 seqno=78005 - <...>-625 (-----) [003] ...1 14594.263903: tracing_mark_write: B|625|resetIdleTimer - <...>-625 (-----) [003] ...1 14594.263912: tracing_mark_write: B|625|rebuildLayerStacks - <...>-625 (-----) [003] ...1 14594.263915: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty - <...>-625 (-----) [003] ...1 14594.263919: tracing_mark_write: B|625|computeVisibleRegions - <...>-1398 (-----) [006] d..2 14594.263966: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=110 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120 - <...>-1695 (-----) [001] d..2 14594.264086: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=Binder:1368_14 next_pid=3253 next_prio=120 - <...>-625 (-----) [003] ...1 14594.264293: tracing_mark_write: B|625|calculateWorkingSet - <...>-625 (-----) [003] ...1 14594.264500: tracing_mark_write: B|625|prepare - <...>-625 (-----) [003] ...1 14594.264513: tracing_mark_write: B|625|HIDL::IComposerClient::executeCommands_2_2::client - <...>-625 (-----) [003] ...2 14594.264584: binder_set_priority: proc=627 thread=627 old=97 => new=98 desired=98 - <...>-625 (-----) [003] d..2 14594.264617: sched_switch: prev_comm=surfaceflinger prev_pid=625 prev_prio=98 prev_state=S ==> next_comm=logd.writer next_pid=588 next_prio=130 - <...>-588 (-----) [003] d..2 14594.264851: sched_switch: prev_comm=logd.writer prev_pid=588 prev_prio=130 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120 - rcu_preempt-7 ( 7) [007] d..2 14594.265273: sched_switch: prev_comm=rcu_preempt prev_pid=7 prev_prio=120 prev_state=S ==> next_comm=kworker/u16:3 next_pid=18008 next_prio=120 - <...>-18008 (-----) [007] d..2 14594.265404: sched_switch: prev_comm=kworker/u16:3 prev_pid=18008 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120 - <...>-18008 (-----) [007] d..2 14594.265471: sched_switch: prev_comm=kworker/u16:3 prev_pid=18008 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120 - <...>-625 (-----) [003] ...1 14594.265496: tracing_mark_write: B|625|doComposition - <...>-625 (-----) [003] ...1 14594.265507: tracing_mark_write: B|625|doComposeSurfaces - <...>-625 (-----) [003] ...1 14594.265552: tracing_mark_write: B|625|acquireBuffer - <...>-625 (-----) [003] ...1 14594.265563: tracing_mark_write: B|625|postFramebuffer - <...>-625 (-----) [003] ...1 14594.265567: tracing_mark_write: B|625|presentAndGetReleaseFences - <...>-625 (-----) [003] d..1 14594.265601: fence_enable_signal: driver=sde_fence:crtc97:91650 timeline=crtc97 context=3 seqno=91650 - <...>-625 (-----) [003] ...1 14594.265735: tracing_mark_write: B|625|logLayerStats - <...>-625 (-----) [003] ...1 14594.265744: tracing_mark_write: B|625|postComposition - <...>-625 (-----) [003] ...1 14594.265749: tracing_mark_write: B|625|releaseBuffer - <...>-625 (-----) [003] ...1 14594.265753: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 1 - <...>-625 (-----) [003] ...1 14594.265791: tracing_mark_write: B|625|releaseBuffer - <...>-440 (-----) [007] d..2 14594.342366: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/u17:2 next_pid=1778 next_prio=100 - <...>-2007 (-----) [006] ...1 14594.342375: tracing_mark_write: B|2007|input - <...>-2007 (-----) [006] ...1 14594.342399: tracing_mark_write: B|2007|animation - <...>-625 (-----) [003] ...1 14594.342447: tracing_mark_write: B|625|doTransaction - <...>-625 (-----) [003] ...1 14594.342489: tracing_mark_write: B|625|doTransaction - kworker/u17:2-1778 ( 1778) [007] d..3 14594.342532: sched_blocked_reason: pid=14607 iowait=1 caller=wait_on_page_bit_common+0x2a8/0x5f8 - kworker/u17:2-1778 ( 1778) [007] d..2 14594.342544: sched_switch: prev_comm=kworker/u17:2 prev_pid=1778 prev_prio=100 prev_state=S ==> next_comm=kworker/u16:2 next_pid=27544 next_prio=120 - <...>-1773 (-----) [000] ...1 14594.342575: tracing_mark_write: B|625|requestNextVsync - <...>-1773 (-----) [000] ...1 14594.342579: tracing_mark_write: B|625|resetIdleTimer - <...>-27544 (-----) [007] d..2 14594.342589: sched_switch: prev_comm=kworker/u16:2 prev_pid=27544 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120 - <...>-656 (-----) [002] d.h3 14594.342604: sched_blocked_reason: pid=1233 iowait=0 caller=geni_i2c_xfer+0x4d8/0x1398 - <...>-1803 (-----) [001] d..2 14594.342605: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120 - <...>-625 (-----) [003] ...1 14594.342632: tracing_mark_write: B|625|handleMessageInvalidate - <...>-625 (-----) [003] ...1 14594.342634: tracing_mark_write: B|625|handlePageFlip - <...>-2738 (-----) [007] ...1 14594.342641: tracing_mark_write: B|2007|notifyFramePending - <...>-658 (-----) [002] d..2 14594.342653: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=120 - <...>-656 (-----) [002] ...1 14594.342656: tracing_mark_write: B|625|requestNextVsync - <...>-2738 (-----) [007] d..2 14594.342658: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120 - <...>-656 (-----) [002] ...1 14594.342660: tracing_mark_write: B|625|resetIdleTimer - <...>-660 (-----) [005] d..2 14594.342663: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120 - <...>-625 (-----) [003] ...1 14594.342665: tracing_mark_write: B|625|latchBuffer - <...>-625 (-----) [003] ...1 14594.342673: tracing_mark_write: B|625|query - <...>-625 (-----) [003] ...1 14594.342682: tracing_mark_write: B|625|updateTexImage - <...>-625 (-----) [003] ...1 14594.342693: tracing_mark_write: B|625|acquireBuffer - <...>-625 (-----) [003] ...1 14594.342703: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 1 - <...>-660 (-----) [005] d..2 14594.342709: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120 - <...>-2007 (-----) [006] ...1 14594.342733: tracing_mark_write: B|2007|traversal - <...>-2007 (-----) [006] ...1 14594.342776: tracing_mark_write: B|2007|draw - <...>-2007 (-----) [006] ...1 14594.342791: tracing_mark_write: B|2007|Record View#draw() - <...>-625 (-----) [003] ...1 14594.342849: tracing_mark_write: B|625|updateInputFlinger - <...>-2007 (-----) [006] d..2 14594.342903: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=kworker/6:2H next_pid=24261 next_prio=100 - <...>-2738 (-----) [007] ...1 14594.342910: tracing_mark_write: B|2007|DrawFrame - <...>-2738 (-----) [007] d..2 14594.342917: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98 - <...>-24261 (-----) [006] d..2 14594.342918: sched_switch: prev_comm=kworker/6:2H prev_pid=24261 prev_prio=100 prev_state=S ==> next_comm=.android.dialer next_pid=14607 next_prio=110 - <...>-440 (-----) [007] d..2 14594.342926: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=RenderThread next_pid=2738 next_prio=110 - <...>-2738 (-----) [007] ...1 14594.342927: tracing_mark_write: B|2007|query - <...>-2738 (-----) [007] ...2 14594.342959: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110 - <...>-2738 (-----) [007] d..2 14594.342975: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110 - <...>-656 (-----) [007] ...1 14594.343021: tracing_mark_write: B|625|query - <...>-656 (-----) [007] .... 14594.343033: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120 - <...>-2738 (-----) [007] ...1 14594.343070: tracing_mark_write: B|2007|query - <...>-1233 (-----) [004] d..2 14594.343074: sched_switch: prev_comm=sound trigger c prev_pid=1233 prev_prio=120 prev_state=R+ ==> next_comm=irq/144-1436400 next_pid=2522 next_prio=49 - <...>-2738 (-----) [007] ...2 14594.343078: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110 - <...>-625 (-----) [003] ...1 14594.343084: tracing_mark_write: B|625|onMessageReceived - <...>-625 (-----) [003] ...1 14594.343087: tracing_mark_write: B|625|handleMessageRefresh - <...>-625 (-----) [003] ...1 14594.343090: tracing_mark_write: B|625|preComposition - <...>-2738 (-----) [007] d..2 14594.343090: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110 - <...>-625 (-----) [003] ...1 14594.343122: tracing_mark_write: B|625|rebuildLayerStacks - <...>-625 (-----) [003] ...1 14594.343124: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty - <...>-89 (-----) [007] d..2 14594.343126: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110 - <...>-625 (-----) [003] ...1 14594.343129: tracing_mark_write: B|625|computeVisibleRegions - <...>-656 (-----) [007] ...1 14594.343136: tracing_mark_write: B|625|query - <...>-14607 (-----) [006] ...2 14594.343141: binder_set_priority: proc=1368 thread=3253 old=120 => new=110 desired=110 - <...>-2965 (-----) [001] .... 14596.746610: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000002ae8fcff pfn=1522884 ofs=188416 - <idle>-0 (-----) [002] d..2 14596.746619: sched_switch: prev_comm=swapper/2 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98 - <...>-2965 (-----) [001] .... 14596.746629: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000679ee1ec pfn=1299913 ofs=192512 - <...>-2965 (-----) [001] .... 14596.746664: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000006cd2fb7 pfn=1296251 ofs=196608 - <...>-2965 (-----) [001] .... 14596.746677: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000af82f3d6 pfn=1419330 ofs=200704 - <...>-2965 (-----) [001] .... 14596.746693: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000002840f054 pfn=1304928 ofs=204800 - <...>-2965 (-----) [001] .... 14596.746706: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000004a59da17 pfn=1288069 ofs=208896 - <...>-2965 (-----) [001] .... 14596.746717: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000023a80dca pfn=1419686 ofs=212992 - <...>-2965 (-----) [001] .... 14596.746730: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000001cf89eab pfn=1315372 ofs=217088 - <...>-2965 (-----) [001] .... 14596.746743: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000005b4c6cb6 pfn=1380698 ofs=221184 - <...>-2965 (-----) [001] .... 14596.746760: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f8304ae7 pfn=1206753 ofs=225280 - <...>-2965 (-----) [001] .... 14596.746773: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000cb912305 pfn=1325465 ofs=229376 - <...>-2965 (-----) [001] .... 14596.746785: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f16f3774 pfn=1408056 ofs=233472 - <...>-2965 (-----) [001] .... 14596.746801: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000056d4c926 pfn=1418352 ofs=237568 - <...>-2965 (-----) [001] .... 14596.746815: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f3eeb42c pfn=1320957 ofs=241664 - <...>-440 (-----) [002] d..2 14596.746916: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=swapper/2 next_pid=0 next_prio=120 - - <...>-656 (-----) [007] .... 14594.343145: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120 - <...>-14607 (-----) [006] d..2 14594.343164: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120 - <...>-5281 (-----) [002] d..2 14594.343177: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110 - irq/144-1436400-2522 ( 2522) [004] d..2 14594.343223: sched_switch: prev_comm=irq/144-1436400 prev_pid=2522 prev_prio=49 prev_state=D ==> next_comm=sound trigger c next_pid=1233 next_prio=120 - <...>-88 (-----) [006] d..2 14594.343240: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120 - <...>-1238 (-----) [001] d..2 14594.343243: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120 - <...>-2738 (-----) [002] ...1 14594.343244: tracing_mark_write: B|2007|syncFrameState - <...>-2738 (-----) [002] ...1 14594.343293: tracing_mark_write: B|2007|prepareTree - <...>-1695 (-----) [001] d..2 14594.343318: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96 - <...>-5281 (-----) [005] d..2 14594.343322: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:1368_14 next_pid=3253 next_prio=110 - <...>-1238 (-----) [001] d..2 14594.343442: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=InputDispatcher next_pid=1695 next_prio=112 - <...>-1695 (-----) [001] d..2 14594.343467: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120 - <...>-5281 (-----) [000] d..2 14594.343484: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120 - <...>-625 (-----) [003] ...1 14594.343519: tracing_mark_write: B|625|calculateWorkingSet - <...>-2738 (-----) [002] ...1 14594.343568: tracing_mark_write: B|2007|query - <...>-2738 (-----) [002] ...1 14594.343577: tracing_mark_write: B|2007|query - <...>-2738 (-----) [002] ...1 14594.343586: tracing_mark_write: B|2007|query - <...>-2738 (-----) [002] ...1 14594.343591: tracing_mark_write: B|2007|query - <...>-2738 (-----) [002] ...1 14594.343597: tracing_mark_write: B|2007|query - <...>-2738 (-----) [002] ...1 14594.343602: tracing_mark_write: B|2007|query - <...>-2738 (-----) [002] ...1 14594.343609: tracing_mark_write: B|2007|dequeueBuffer - <...>-2007 (-----) [006] d..2 14594.343612: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120 - <...>-2738 (-----) [002] ...2 14594.343633: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110 - <...>-2738 (-----) [002] d..2 14594.343683: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110 - <...>-625 (-----) [003] ...1 14594.343704: tracing_mark_write: B|625|prepare - <...>-656 (-----) [002] ...1 14594.343707: tracing_mark_write: B|625|dequeueBuffer - <...>-625 (-----) [004] ...1 14594.812869: tracing_mark_write: B|625|com.google.android.dialer/com.google.android.dialer.extensions.GoogleDialtactsActivity#0: 2 - <...>-2048 (-----) [000] d..2 14594.812895: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:625_3 next_pid=1431 next_prio=120 - <...>-1431 (-----) [000] ...1 14594.812911: tracing_mark_write: B|625|query - <...>-625 (-----) [004] ...1 14594.812914: tracing_mark_write: B|625|latchBuffer - <...>-625 (-----) [004] ...1 14594.812919: tracing_mark_write: B|625|query - <...>-625 (-----) [004] ...1 14594.812925: tracing_mark_write: B|625|updateTexImage - <...>-625 (-----) [004] ...1 14594.812928: tracing_mark_write: B|625|acquireBuffer - <...>-625 (-----) [004] ...1 14594.812934: tracing_mark_write: B|625|StatusBar#0: 1 - <...>-2048 (-----) [000] ...1 14594.812962: tracing_mark_write: B|1803|syncFrameState - <...>-656 (-----) [002] ...1 14594.813044: tracing_mark_write: B|625|setTransactionState - <...>-14607 (-----) [007] ...2 14594.813083: binder_set_priority: proc=10691 thread=18733 old=120 => new=110 desired=110 - <...>-14607 (-----) [007] d..2 14594.813114: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=kworker/7:1 next_pid=7092 next_prio=120 - <...>-14655 (-----) [006] d..2 14594.813128: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=lpass_smem_glin next_pid=89 next_prio=98 - <...>-89 (-----) [006] d..2 14594.813163: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130 - <...>-656 (-----) [002] ...1 14594.813218: tracing_mark_write: B|625|requestNextVsync - <...>-656 (-----) [002] ...1 14594.813222: tracing_mark_write: B|625|resetIdleTimer - kworker/7:1-7092 ( 7092) [007] d..2 14594.813239: sched_switch: prev_comm=kworker/7:1 prev_pid=7092 prev_prio=120 prev_state=R+ ==> next_comm=smem_native_lpa next_pid=88 next_prio=98 - <...>-5281 (-----) [001] d..2 14594.813245: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:10691_B next_pid=18733 next_prio=110 - <...>-88 (-----) [007] d..2 14594.813248: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=R ==> next_comm=kgsl_worker_thr next_pid=259 next_prio=97 - <...>-2048 (-----) [000] d..2 14594.813249: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96 - <...>-14655 (-----) [006] d..2 14594.813263: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R+ ==> next_comm=smem_native_lpa next_pid=88 next_prio=98 - <...>-661 (-----) [002] d..2 14594.813265: sched_switch: prev_comm=sf prev_pid=661 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116 - <...>-259 (-----) [007] d..2 14594.813265: sched_switch: prev_comm=kgsl_worker_thr prev_pid=259 prev_prio=97 prev_state=S ==> next_comm=kworker/7:1 next_pid=7092 next_prio=120 - kworker/7:1-7092 ( 7092) [007] d..2 14594.813271: sched_switch: prev_comm=kworker/7:1 prev_pid=7092 prev_prio=120 prev_state=S ==> next_comm=system next_pid=108 next_prio=120 - <...>-108 (-----) [007] .... 14594.813275: ion_heap_shrink: heap_name=system, len=9469952, total_allocated=189620224 - <...>-88 (-----) [006] d..2 14594.813294: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130 - <...>-625 (-----) [004] ...1 14594.813310: tracing_mark_write: B|625|updateInputFlinger - <...>-1238 (-----) [000] d..2 14594.813312: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120 - <...>-661 (-----) [002] d..2 14594.813317: sched_switch: prev_comm=sf prev_pid=661 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116 - <...>-14640 (-----) [005] d..2 14594.813319: sched_switch: prev_comm=DialerExecutors prev_pid=14640 prev_prio=130 prev_state=R ==> next_comm=DispSync next_pid=658 next_prio=97 - <...>-656 (-----) [002] ...1 14594.813336: tracing_mark_write: B|625|~GraphicBuffer - <...>-658 (-----) [005] d..2 14594.813345: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=DialerExecutors next_pid=14640 next_prio=130 - <...>-656 (-----) [002] ...1 14594.813345: tracing_mark_write: B|625|~GraphicBuffer - <...>-656 (-----) [002] ...1 14594.813353: tracing_mark_write: B|625|~GraphicBuffer - <...>-2048 (-----) [000] d..2 14594.813358: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96 - <...>-656 (-----) [002] ...1 14594.813364: tracing_mark_write: B|625|~GraphicBuffer - <...>-5281 (-----) [001] d..2 14594.813369: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:10691_B next_pid=18733 next_prio=110 - <...>-656 (-----) [002] ...1 14594.813372: tracing_mark_write: B|625|~GraphicBuffer - <...>-656 (-----) [002] ...1 14594.813380: tracing_mark_write: B|625|~GraphicBuffer - <...>-656 (-----) [002] ...1 14594.813391: tracing_mark_write: B|625|~GraphicBuffer - <...>-656 (-----) [002] ...1 14594.813398: tracing_mark_write: B|625|~GraphicBuffer - <...>-656 (-----) [002] ...1 14594.813408: tracing_mark_write: B|625|~GraphicBuffer - <...>-656 (-----) [002] ...1 14594.813416: tracing_mark_write: B|625|~GraphicBuffer - <...>-656 (-----) [002] ...1 14594.813424: tracing_mark_write: B|625|~GraphicBuffer - <...>-656 (-----) [002] ...1 14594.813432: tracing_mark_write: B|625|~GraphicBuffer - <...>-656 (-----) [002] .n.1 14594.813443: tracing_mark_write: B|625|~GraphicBuffer - <...>-1238 (-----) [000] d..2 14594.813464: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120 - <...>-5281 (-----) [002] d..2 14594.813525: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116 - <...>-656 (-----) [002] ...1 14594.813544: tracing_mark_write: B|625|~GraphicBuffer - <...>-656 (-----) [002] ...1 14594.813557: tracing_mark_write: B|625|~GraphicBuffer - <...>-2048 (-----) [000] d..2 14594.813594: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:1368_15 next_pid=3359 next_prio=120 - <...>-18733 (-----) [001] ...2 14594.813635: binder_set_priority: proc=1368 thread=3514 old=120 => new=110 desired=110 - <...>-656 (-----) [002] .... 14594.813637: binder_set_priority: proc=625 thread=656 old=116 => new=120 desired=120 - <...>-108 (-----) [007] d..2 14594.813646: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=116 - <...>-625 (-----) [004] ...1 14594.813646: tracing_mark_write: B|625|onMessageReceived - <...>-625 (-----) [004] ...1 14594.813649: tracing_mark_write: B|625|handleMessageRefresh - <...>-625 (-----) [004] ...1 14594.813651: tracing_mark_write: B|625|preComposition - <...>-625 (-----) [004] ...1 14594.813693: tracing_mark_write: B|625|rebuildLayerStacks - <...>-625 (-----) [004] ...1 14594.813696: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty - <...>-625 (-----) [004] ...1 14594.813701: tracing_mark_write: B|625|computeVisibleRegions - <...>-1398 (-----) [007] d..2 14594.813718: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=116 prev_state=S ==> next_comm=system next_pid=108 next_prio=120 - <...>-108 (-----) [007] d..2 14594.813739: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=116 - <...>-1695 (-----) [002] d..2 14594.813970: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=system next_pid=108 next_prio=120 - <...>-1398 (-----) [007] ...1 14594.814029: tracing_mark_write: B|1368|wmLayout - <...>-1398 (-----) [007] ...1 14594.814033: tracing_mark_write: B|1368|performSurfacePlacement - <...>-1398 (-----) [007] ...1 14594.814040: tracing_mark_write: B|1368|applySurfaceChanges - <...>-1398 (-----) [007] ...1 14594.814043: tracing_mark_write: B|1368|openSurfaceTransaction - <...>-1398 (-----) [007] ...1 14594.814063: tracing_mark_write: B|1368|performLayout - <...>-625 (-----) [004] ...1 14594.814119: tracing_mark_write: B|625|calculateWorkingSet - <...>-1398 (-----) [007] ...1 14594.814241: tracing_mark_write: B|1368|layoutInputConsumer - <...>-2048 (-----) [000] ...1 14594.814260: tracing_mark_write: B|1803|prepareTree - <...>-1398 (-----) [007] ...1 14594.814263: tracing_mark_write: B|1368|applyPostLayoutPolicy - <...>-2048 (-----) [000] d..2 14594.814408: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R ==> next_comm=Binder:1368_15 next_pid=3359 next_prio=120 - <...>-625 (-----) [004] ...1 14594.814411: tracing_mark_write: B|625|prepare - <...>-625 (-----) [004] ...1 14594.814428: tracing_mark_write: B|625|HIDL::IComposerClient::executeCommands_2_2::client - <...>-2048 (-----) [000] d..2 14594.814533: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120 - <...>-1803 (-----) [000] d..2 14594.814558: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120 - <...>-2048 (-----) [000] d..2 14594.814572: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120 - <...>-625 (-----) [004] ...2 14594.814589: binder_set_priority: proc=627 thread=627 old=97 => new=98 desired=98 - <...>-108 (-----) [002] d..2 14594.814650: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=composer@2.2-se next_pid=627 next_prio=98 - <...>-625 (-----) [004] d..2 14594.814664: sched_switch: prev_comm=surfaceflinger prev_pid=625 prev_prio=98 prev_state=S ==> next_comm=ashmemd next_pid=854 next_prio=129 - <...>-1398 (-----) [007] ...1 14594.814723: tracing_mark_write: B|1368|applyWindowSurfaceChanges - <...>-854 (-----) [004] .... 14594.814746: binder_set_priority: proc=854 thread=854 old=129 => new=120 desired=120 - <...>-854 (-----) [004] d..2 14594.814757: sched_switch: prev_comm=ashmemd prev_pid=854 prev_prio=120 prev_state=R+ ==> next_comm=highpool[0] next_pid=3493 next_prio=129 - <...>-1803 (-----) [000] d..2 14594.814763: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120 - <...>-18733 (-----) [001] d..1 14594.814819: mm_filemap_delete_from_page_cache: dev 0:1 ino 3ce5e7 page=0000000083f10c7a pfn=1298474 ofs=0 - <...>-2048 (-----) [000] ...1 14594.814842: tracing_mark_write: B|1803|dequeueBuffer - <...>-1398 (-----) [007] ...1 14594.814850: tracing_mark_write: F|1368|launching: com.google.android.dialer|0 - <...>-1398 (-----) [007] ...1 14594.814855: tracing_mark_write: B|1368|MetricsLogger:launchObserverNotifyActivityLaunchFinished - <...>-1398 (-----) [007] ...1 14594.814857: tracing_mark_write: B|1368|MetricsLogger:convertActivityRecordToProto - <...>-2048 (-----) [000] d..2 14594.814905: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=120 - <...>-1410 (-----) [006] .... 14592.997816: mm_filemap_add_to_page_cache: dev 253:6 ino b785 page=00000000615a8f24 pfn=1134764 ofs=0 - <...>-1410 (-----) [006] .... 14592.997831: mm_filemap_add_to_page_cache: dev 253:6 ino b785 page=000000008768a58f pfn=1134751 ofs=4096 - - <...>-18733 (-----) [001] .... 14594.814914: binder_set_priority: proc=10691 thread=18733 old=110 => new=120 desired=120 - <...>-14655 (-----) [006] d..2 14594.814932: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=.android.dialer next_pid=14607 next_prio=110 - <...>-656 (-----) [000] ...1 14594.814948: tracing_mark_write: B|625|dequeueBuffer - <...>-3514 (-----) [001] .... 14594.814954: binder_set_priority: proc=1368 thread=3514 old=110 => new=120 desired=120 - <...>-656 (-----) [000] ...1 14594.814963: tracing_mark_write: B|625|NavigationBar0#0: 2 - <...>-14607 (-----) [006] ...2 14594.815022: binder_set_priority: proc=1368 thread=3514 old=120 => new=110 desired=110 - <...>-1398 (-----) [007] ...1 14594.815039: tracing_mark_write: B|1368|prepareSurfaces - <...>-14607 (-----) [006] d..2 14594.815041: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130 - <...>-3493 (-----) [004] d..2 14594.815057: sched_switch: prev_comm=highpool[0] prev_pid=3493 prev_prio=129 prev_state=R ==> next_comm=Binder:1368_18 next_pid=3514 next_prio=110 - <...>-2048 (-----) [000] ...1 14594.815088: tracing_mark_write: B|1803|HWC release fence 45750 has signaled - <...>-2048 (-----) [000] ...1 14594.815119: tracing_mark_write: B|1803|eglBeginFrame - <...>-14655 (-----) [006] d..2 14594.815190: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=crtc_commit:97 next_pid=301 next_prio=83 - <...>-3514 (-----) [004] .... 14594.815193: binder_set_priority: proc=1368 thread=3514 old=110 => new=120 desired=120 - <...>-1398 (-----) [007] ...1 14594.815322: tracing_mark_write: B|1368|closeSurfaceTransaction - <...>-3493 (-----) [004] .... 14594.815353: mm_filemap_add_to_page_cache: dev 253:6 ino 113b page=0000000069e2b98a pfn=628464 ofs=2723840 - <...>-1398 (-----) [007] ...2 14594.815393: binder_set_priority: proc=625 thread=656 old=120 => new=116 desired=116 - rcu_sched-8 ( 8) [007] d..2 14594.815449: sched_switch: prev_comm=rcu_sched prev_pid=8 prev_prio=120 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116 diff --git a/startop/scripts/trace_analyzer/trace_analyzer b/startop/scripts/trace_analyzer/trace_analyzer deleted file mode 100755 index 8c0396430c40..000000000000 --- a/startop/scripts/trace_analyzer/trace_analyzer +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash -# Copyright (C) 2019 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. - -DIR="$( cd "$(dirname "$0")" ; pwd -P )" - -if [[ "$#" -lt 2 ]]; then - echo "Usage: $0 <filename.trace> <sqlite-filename.db>" >&2 - exit 1 -fi - -TRACE_FILENAME="$1" -SQLITE_FILENAME="$2" - -#echo "Trace filename: $TRACE_FILENAME" -#echo "SQLite filename: $SQLITE_FILENAME" - -if ! [[ -f "$TRACE_FILENAME" ]]; then - echo "Error: Trace '$TRACE_FILENAME' does not exist." >&2 - exit 1 -fi - -if ! "$DIR/trace_analyzer.py" "$SQLITE_FILENAME" "$TRACE_FILENAME" > /dev/null; then - echo "Fatal: trace_analyzer.py failed, aborting." >&2 - exit 1 -fi - -if ! "$DIR/run-sql-queries" "$SQLITE_FILENAME"; then - echo "Fatal: Failed to run sql queries, aborting." >&2 - exit 1 -fi diff --git a/startop/scripts/trace_analyzer/trace_analyzer.py b/startop/scripts/trace_analyzer/trace_analyzer.py deleted file mode 100755 index 62ae018a9986..000000000000 --- a/startop/scripts/trace_analyzer/trace_analyzer.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/python3 -# Copyright (C) 2019 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. - -import re -import sys -import argparse - -from lib.trace2db import Trace2Db - -# This script requires 'sqlalchemy' to access the sqlite3 database. -# -# $> sudo apt-get install python3-pip -# $> pip3 install --user sqlalchemy -# - -def main(argv): - parser = argparse.ArgumentParser(description='Convert ftrace/systrace file into sqlite3 db.') - parser.add_argument('db_filename', metavar='sql_filename.db', type=str, - help='path to sqlite3 db filename') - parser.add_argument('trace_filename', metavar='systrace.ftrace', type=str, - help='path to ftrace/systrace filename') - parser.add_argument('--limit', type=int, help='limit the number of entries parsed [for debugging]') - - args = parser.parse_args() - - db_filename = args.db_filename - trace_filename = args.trace_filename - - trace2db = Trace2Db(db_filename) - print("SQL Alchemy db initialized") - - # parse 'raw_ftrace_entries' table - count = trace2db.parse_file_into_db(trace_filename, limit=args.limit) - print("Count was ", count) - - return 0 - -if __name__ == '__main__': - main(sys.argv) diff --git a/startop/scripts/trace_analyzer/trace_analyzer_recursive b/startop/scripts/trace_analyzer/trace_analyzer_recursive deleted file mode 100755 index 4d9ee0eec9b0..000000000000 --- a/startop/scripts/trace_analyzer/trace_analyzer_recursive +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/bash -# Copyright (C) 2019 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. - -DIR="$( cd "$(dirname "$0")" ; pwd -P )" - -if [[ "$#" -lt 3 ]]; then - echo "Usage: $0 <trace-dir> <db-dir> <output.csv>" >&2 - exit 1 -fi - -simulate="n" - -TRACE_DIRNAME="$1" -SQLITE_DIRNAME="$2" -OUTPUT_FILENAME="$3" - -echo "Trace filename: $TRACE_DIRNAME" -echo "SQLite filename: $SQLITE_DIRNAME" - -if ! [[ -d "$TRACE_DIRNAME" ]]; then - echo "Error: Trace '$TRACE_DIRNAME' does not exist." >&2 - exit 1 -fi - -process_trace_file() { - local trace_filename="$1" - local db_dirname="$2" - local output_file="$3" - - local db_filename="$db_dirname/$(basename "$trace_filename").db" - - if [[ $simulate == y ]]; then - echo "$DIR/trace_analyzer.py" "$db_filename" "$trace_filename" "> /dev/null" - else - if ! "$DIR/trace_analyzer.py" "$db_filename" "$trace_filename" > /dev/null; then - echo "Fatal: trace_analyzer.py failed, aborting." >&2 - return 1 - fi - fi - - if [[ $simulate == y ]]; then - echo "$DIR/run-sql-queries" "$db_filename" ">> '$output_file'" - else - # append name of trace to CSV, so we can see where data came from - echo "; $trace_filename" >> "$output_file" - if ! "$DIR/run-sql-queries" "$db_filename" >> "$output_file"; then - echo "Fatal: Failed to run sql queries, aborting." >&2 - return 1 - fi - fi - - return 0 -} - -find "$TRACE_DIRNAME" -type f -name '*.trace' -print0 | -while IFS= read -r -d '' file; do - if [[ $file == *#*.trace && $file != *#1.trace ]]; then - echo "Skip $file" - continue - fi - - printf '%s\n' "$file" - process_trace_file "$file" "$SQLITE_DIRNAME" "$OUTPUT_FILENAME" -done - -echo "Done" diff --git a/startop/scripts/trace_analyzer/trace_analyzer_test.py b/startop/scripts/trace_analyzer/trace_analyzer_test.py deleted file mode 100644 index 579529c6f6d5..000000000000 --- a/startop/scripts/trace_analyzer/trace_analyzer_test.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019, 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. -# - -""" -Unit tests for trace_analyzer module. - -Install: - $> sudo apt-get install python3-pytest ## OR - $> pip install -U pytest -See also https://docs.pytest.org/en/latest/getting-started.html - -Usage: - $> pytest trace_analyzer_test.py - -See also https://docs.pytest.org/en/latest/usage.html -""" - -# global imports -import os -import sys - -DIR = os.path.abspath(os.path.dirname(__file__)) - -sys.path.append(os.path.dirname(DIR)) -import lib.cmd_utils as cmd_utils - -def test_trace_analyzer(tmpdir): - # Setup - bin = os.path.join(DIR, 'trace_analyzer') - systrace = os.path.join(DIR, 'test_fixtures/common_systrace') - db_file = tmpdir.mkdir('trace_analyzer').join('test.db') - - # Act - passed, output = cmd_utils.execute_arbitrary_command([bin, systrace, - str(db_file)], - timeout=300, - shell=False, - simulate=False) - - # Assert - assert passed - assert output == """\ -'blocked_iowait_duration_ms',\ -'process_name',\ -'launching_duration_ms',\ -'launching_started_timestamp_ms',\ -'launching_finished_timestamp_ms' -81.697999999960302375,\ -'com.google.android.dialer',\ -594.99400000095192808,\ -14594219.85600000061,\ -14594814.85000000149""" diff --git a/telephony/java/android/service/euicc/EuiccService.java b/telephony/java/android/service/euicc/EuiccService.java index fcbb008c79b3..7d857a2dc1b4 100644 --- a/telephony/java/android/service/euicc/EuiccService.java +++ b/telephony/java/android/service/euicc/EuiccService.java @@ -255,6 +255,12 @@ public abstract class EuiccService extends Service { public static final String EXTRA_RESOLUTION_CARD_ID = "android.service.euicc.extra.RESOLUTION_CARD_ID"; + /** + * Intent extra set for resolution requests containing an int indicating the current port index. + */ + public static final String EXTRA_RESOLUTION_PORT_INDEX = + "android.service.euicc.extra.RESOLUTION_PORT_INDEX"; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "RESULT_" }, value = { @@ -579,9 +585,32 @@ public abstract class EuiccService extends Service { * @return the result of the switch operation. May be one of the predefined {@code RESULT_} * constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}. * @see android.telephony.euicc.EuiccManager#switchToSubscription + * + * @deprecated prefer {@link #onSwitchToSubscriptionWithPort(int, int, String, boolean)} */ - public abstract @Result int onSwitchToSubscription(int slotId, @Nullable String iccid, - boolean forceDeactivateSim); + @Deprecated public abstract @Result int onSwitchToSubscription(int slotId, + @Nullable String iccid, boolean forceDeactivateSim); + + /** + * Switch to the given subscription. + * + * @param slotId ID of the SIM slot to use for the operation. + * @param portIndex which port on the eUICC to use + * @param iccid the ICCID of the subscription to enable. May be null, in which case the current + * profile should be deactivated and no profile should be activated to replace it - this is + * equivalent to a physical SIM being ejected. + * @param forceDeactivateSim If true, and if an active SIM must be deactivated to access the + * eUICC, perform this action automatically. Otherwise, {@link #RESULT_MUST_DEACTIVATE_SIM} + * should be returned to allow the user to consent to this operation first. + * @return the result of the switch operation. May be one of the predefined {@code RESULT_} + * constants or any implementation-specific code starting with {@link #RESULT_FIRST_USER}. + * @see android.telephony.euicc.EuiccManager#switchToSubscription + */ + public @Result int onSwitchToSubscriptionWithPort(int slotId, int portIndex, + @Nullable String iccid, boolean forceDeactivateSim) { + // stub implementation, LPA needs to implement this + throw new UnsupportedOperationException("LPA must override onSwitchToSubscriptionWithPort"); + } /** * Update the nickname of the given subscription. @@ -821,16 +850,15 @@ public abstract class EuiccService extends Service { } }); } - @Override - public void switchToSubscription(int slotId, String iccid, boolean forceDeactivateSim, - ISwitchToSubscriptionCallback callback) { + public void switchToSubscription(int slotId, int portIndex, String iccid, + boolean forceDeactivateSim, ISwitchToSubscriptionCallback callback) { mExecutor.execute(new Runnable() { @Override public void run() { int result = - EuiccService.this.onSwitchToSubscription( - slotId, iccid, forceDeactivateSim); + EuiccService.this.onSwitchToSubscriptionWithPort( + slotId, portIndex, iccid, forceDeactivateSim); try { callback.onComplete(result); } catch (RemoteException e) { diff --git a/telephony/java/android/service/euicc/IEuiccService.aidl b/telephony/java/android/service/euicc/IEuiccService.aidl index bb7b569f17f9..aa30c9e88462 100644 --- a/telephony/java/android/service/euicc/IEuiccService.aidl +++ b/telephony/java/android/service/euicc/IEuiccService.aidl @@ -48,7 +48,7 @@ oneway interface IEuiccService { in IGetDefaultDownloadableSubscriptionListCallback callback); void getEuiccInfo(int slotId, in IGetEuiccInfoCallback callback); void deleteSubscription(int slotId, String iccid, in IDeleteSubscriptionCallback callback); - void switchToSubscription(int slotId, String iccid, boolean forceDeactivateSim, + void switchToSubscription(int slotId, int portIndex, String iccid, boolean forceDeactivateSim, in ISwitchToSubscriptionCallback callback); void updateSubscriptionNickname(int slotId, String iccid, String nickname, in IUpdateSubscriptionNicknameCallback callback); diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 77e58aaeb284..ee646d9c9bdb 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -5641,6 +5641,13 @@ public class CarrierConfigManager { "telephony_data_handover_retry_rules_string_array"; /** + * Indicates whether delay tearing down IMS data network until voice call ends. + * @hide + */ + public static final String KEY_DELAY_IMS_TEAR_DOWN_UNTIL_CALL_END_BOOL = + "delay_ims_tear_down_until_call_end_bool"; + + /** * The patterns of missed incoming call sms. This is the regular expression used for * matching the missed incoming call's date, time, and caller id. The pattern should match * fields for at least month, day, hour, and minute. Year is optional although it is encouraged. @@ -6458,6 +6465,7 @@ public class CarrierConfigManager { KEY_TELEPHONY_DATA_HANDOVER_RETRY_RULES_STRING_ARRAY, new String[] { "retry_interval=1000|2000|4000|8000|16000, maximum_retries=5" }); + sDefaults.putBoolean(KEY_DELAY_IMS_TEAR_DOWN_UNTIL_CALL_END_BOOL, false); sDefaults.putStringArray(KEY_MISSED_INCOMING_CALL_SMS_PATTERN_STRING_ARRAY, new String[0]); sDefaults.putBoolean(KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL, false); sDefaults.putString(KEY_DEFAULT_PREFERRED_APN_NAME_STRING, ""); diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java index 957f683292f7..1d7c18fb0837 100644 --- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java +++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java @@ -22,6 +22,8 @@ import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import com.android.internal.annotations.VisibleForTesting; + import java.util.Objects; @@ -76,7 +78,8 @@ public final class DataSpecificRegistrationInfo implements Parcelable { /** * @hide */ - DataSpecificRegistrationInfo( + @VisibleForTesting + public DataSpecificRegistrationInfo( int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable, boolean isEnDcAvailable, @Nullable VopsSupportInfo vops) { this.maxDataCalls = maxDataCalls; @@ -186,7 +189,7 @@ public final class DataSpecificRegistrationInfo implements Parcelable { /** * @return The VOPS (Voice over Packet Switched) support information. * - * The instance of {@link LTEVopsSupportInfo}, or {@link NrVopsSupportInfo}, + * The instance of {@link LteVopsSupportInfo}, or {@link NrVopsSupportInfo}, * null if there is there is no VOPS support information available. */ @Nullable diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java index 6a807665a103..1a5a5ae4b218 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -242,13 +242,16 @@ public final class NetworkRegistrationInfo implements Parcelable { * @param cellIdentity The identity representing a unique cell or wifi AP. Set to null if the * information is not available. * @param rplmn the registered plmn or the last plmn for attempted registration if reg failed. + * @param voiceSpecificInfo Voice specific registration information. + * @param dataSpecificInfo Data specific registration information. */ private NetworkRegistrationInfo(@Domain int domain, @TransportType int transportType, - @RegistrationState int registrationState, - @NetworkType int accessNetworkTechnology, int rejectCause, - boolean emergencyOnly, - @Nullable @ServiceType List<Integer> availableServices, - @Nullable CellIdentity cellIdentity, @Nullable String rplmn) { + @RegistrationState int registrationState, + @NetworkType int accessNetworkTechnology, int rejectCause, + boolean emergencyOnly, @Nullable @ServiceType List<Integer> availableServices, + @Nullable CellIdentity cellIdentity, @Nullable String rplmn, + @Nullable VoiceSpecificRegistrationInfo voiceSpecificInfo, + @Nullable DataSpecificRegistrationInfo dataSpecificInfo) { mDomain = domain; mTransportType = transportType; mRegistrationState = registrationState; @@ -262,6 +265,10 @@ public final class NetworkRegistrationInfo implements Parcelable { mEmergencyOnly = emergencyOnly; mNrState = NR_STATE_NONE; mRplmn = rplmn; + mVoiceSpecificInfo = voiceSpecificInfo; + mDataSpecificInfo = dataSpecificInfo; + + updateNrState(); } /** @@ -276,10 +283,9 @@ public final class NetworkRegistrationInfo implements Parcelable { boolean cssSupported, int roamingIndicator, int systemIsInPrl, int defaultRoamingIndicator) { this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause, - emergencyOnly, availableServices, cellIdentity, rplmn); - - mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator, - systemIsInPrl, defaultRoamingIndicator); + emergencyOnly, availableServices, cellIdentity, rplmn, + new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator, + systemIsInPrl, defaultRoamingIndicator), null); } /** @@ -295,11 +301,9 @@ public final class NetworkRegistrationInfo implements Parcelable { boolean isNrAvailable, boolean isEndcAvailable, @Nullable VopsSupportInfo vopsSupportInfo) { this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause, - emergencyOnly, availableServices, cellIdentity, rplmn); - mDataSpecificInfo = new DataSpecificRegistrationInfo( - maxDataCalls, isDcNrRestricted, isNrAvailable, - isEndcAvailable, vopsSupportInfo); - updateNrState(); + emergencyOnly, availableServices, cellIdentity, rplmn, null, + new DataSpecificRegistrationInfo(maxDataCalls, isDcNrRestricted, isNrAvailable, + isEndcAvailable, vopsSupportInfo)); } private NetworkRegistrationInfo(Parcel source) { @@ -804,6 +808,12 @@ public final class NetworkRegistrationInfo implements Parcelable { @NonNull private String mRplmn = ""; + @Nullable + private DataSpecificRegistrationInfo mDataSpecificRegistrationInfo; + + @Nullable + private VoiceSpecificRegistrationInfo mVoiceSpecificRegistrationInfo; + /** * Default constructor for Builder. */ @@ -930,6 +940,30 @@ public final class NetworkRegistrationInfo implements Parcelable { } /** + * Set voice specific registration information. + * + * @param info The voice specific registration information. + * @return The builder. + * @hide + */ + public @NonNull Builder setVoiceSpecificInfo(@NonNull VoiceSpecificRegistrationInfo info) { + mVoiceSpecificRegistrationInfo = info; + return this; + } + + /** + * Set data specific registration information. + * + * @param info The data specific registration information. + * @return The builder. + * @hide + */ + public @NonNull Builder setDataSpecificInfo(@NonNull DataSpecificRegistrationInfo info) { + mDataSpecificRegistrationInfo = info; + return this; + } + + /** * Build the NetworkRegistrationInfo. * @return the NetworkRegistrationInfo object. * @hide @@ -938,7 +972,8 @@ public final class NetworkRegistrationInfo implements Parcelable { public @NonNull NetworkRegistrationInfo build() { return new NetworkRegistrationInfo(mDomain, mTransportType, mRegistrationState, mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices, - mCellIdentity, mRplmn); + mCellIdentity, mRplmn, mVoiceSpecificRegistrationInfo, + mDataSpecificRegistrationInfo); } } } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 8c8e2037d167..cdba6355e798 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -118,6 +118,7 @@ import com.android.internal.telephony.ISms; import com.android.internal.telephony.ISub; import com.android.internal.telephony.ITelephony; import com.android.internal.telephony.IUpdateAvailableNetworksCallback; +import com.android.internal.telephony.IccLogicalChannelRequest; import com.android.internal.telephony.OperatorInfo; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.RILConstants; @@ -6775,17 +6776,24 @@ public class TelephonyManager { * @param p2 P2 parameter (described in ISO 7816-4). * @return an IccOpenLogicalChannelResponse object. * @hide + * @deprecated instead use {@link #iccOpenLogicalChannelByPort(int, int, String, int)} */ @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) @SystemApi @Nullable + @Deprecated public IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(int slotIndex, @Nullable String aid, int p2) { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.iccOpenLogicalChannelBySlot(slotIndex, getOpPackageName(), aid, - p2); + IccLogicalChannelRequest request = new IccLogicalChannelRequest(); + request.slotIndex = slotIndex; + request.aid = aid; + request.p2 = p2; + request.callingPackage = getOpPackageName(); + request.binder = new Binder(); + return telephony.iccOpenLogicalChannel(request); } } catch (RemoteException ex) { } catch (NullPointerException ex) { @@ -6794,6 +6802,58 @@ public class TelephonyManager { } /** + * Opens a logical channel to the ICC card using the physical slot index and port index. + * + * Use this method when no subscriptions are available on the SIM and the operation must be + * performed using the physical slot index and port index. + * + * This operation wraps two APDU instructions: + * <ul> + * <li>MANAGE CHANNEL to open a logical channel</li> + * <li>SELECT the given {@code AID} using the given {@code p2}</li> + * </ul> + * + * Per Open Mobile API Specification v3.2 section 6.2.7.h, only p2 values of 0x00, 0x04, 0x08, + * and 0x0C are guaranteed to be supported. + * + * If the SELECT command's status word is not '9000', '62xx', or '63xx', the status word will be + * considered an error and the channel shall not be opened. + * + * Input parameters equivalent to TS 27.007 AT+CCHO command. + * + * @param slotIndex the physical slot index of the ICC card + * @param portIndex The port index is an enumeration of the ports available on the UICC. + * Use {@link UiccPortInfo#getPortIndex()} to get portIndex. + * @param aid Application id. See ETSI 102.221 and 101.220. + * @param p2 P2 parameter (described in ISO 7816-4). + * @return an IccOpenLogicalChannelResponse object. + * @hide + */ + @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) + @SystemApi + @NonNull + public IccOpenLogicalChannelResponse iccOpenLogicalChannelByPort(int slotIndex, + int portIndex, @Nullable String aid, int p2) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + IccLogicalChannelRequest request = new IccLogicalChannelRequest(); + request.slotIndex = slotIndex; + request.portIndex = portIndex; + request.aid = aid; + request.p2 = p2; + request.callingPackage = getOpPackageName(); + request.binder = new Binder(); + return telephony.iccOpenLogicalChannel(request); + } else { + throw new IllegalStateException("telephony service is null."); + } + } catch (RemoteException ex) { + throw ex.rethrowAsRuntimeException(); + } + } + + /** * Opens a logical channel to the ICC card. * * This operation wraps two APDU instructions: @@ -6852,8 +6912,15 @@ public class TelephonyManager { public IccOpenLogicalChannelResponse iccOpenLogicalChannel(int subId, String AID, int p2) { try { ITelephony telephony = getITelephony(); - if (telephony != null) - return telephony.iccOpenLogicalChannel(subId, getOpPackageName(), AID, p2); + if (telephony != null) { + IccLogicalChannelRequest request = new IccLogicalChannelRequest(); + request.subId = subId; + request.callingPackage = getOpPackageName(); + request.aid = AID; + request.p2 = p2; + request.binder = new Binder(); + return telephony.iccOpenLogicalChannel(request); + } } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -6876,14 +6943,19 @@ public class TelephonyManager { * iccOpenLogicalChannel. * @return true if the channel was closed successfully. * @hide + * @deprecated instead use {@link #iccCloseLogicalChannelByPort(int, int, int)} */ @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) @SystemApi + @Deprecated public boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel) { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.iccCloseLogicalChannelBySlot(slotIndex, channel); + IccLogicalChannelRequest request = new IccLogicalChannelRequest(); + request.slotIndex = slotIndex; + request.channel = channel; + return telephony.iccCloseLogicalChannel(request); } } catch (RemoteException ex) { } catch (NullPointerException ex) { @@ -6892,6 +6964,45 @@ public class TelephonyManager { } /** + * Closes a previously opened logical channel to the ICC card using the physical slot index and + * port index. + * + * Use this method when no subscriptions are available on the SIM and the operation must be + * performed using the physical slot index and port index. + * + * Input parameters equivalent to TS 27.007 AT+CCHC command. + * + * @param slotIndex the physical slot index of the ICC card + * @param portIndex The port index is an enumeration of the ports available on the UICC. + * Use {@link UiccPortInfo#getPortIndex()} to get portIndex. + * @param channel is the channel id to be closed as returned by a successful + * iccOpenLogicalChannel. + * + * @throws IllegalStateException if the Telephony process is not currently available or modem + * currently can't process this command. + * @throws IllegalArgumentException if invalid arguments are passed. + * @hide + */ + @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) + @SystemApi + public void iccCloseLogicalChannelByPort(int slotIndex, int portIndex, int channel) { + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + IccLogicalChannelRequest request = new IccLogicalChannelRequest(); + request.slotIndex = slotIndex; + request.portIndex = portIndex; + request.channel = channel; + telephony.iccCloseLogicalChannel(request); + } else { + throw new IllegalStateException("telephony service is null."); + } + } catch (RemoteException ex) { + throw ex.rethrowAsRuntimeException(); + } + } + + /** * Closes a previously opened logical channel to the ICC card. * * Input parameters equivalent to TS 27.007 AT+CCHC command. @@ -6926,8 +7037,12 @@ public class TelephonyManager { public boolean iccCloseLogicalChannel(int subId, int channel) { try { ITelephony telephony = getITelephony(); - if (telephony != null) - return telephony.iccCloseLogicalChannel(subId, channel); + if (telephony != null) { + IccLogicalChannelRequest request = new IccLogicalChannelRequest(); + request.subId = subId; + request.channel = channel; + return telephony.iccCloseLogicalChannel(request); + } } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -6958,17 +7073,20 @@ public class TelephonyManager { * @return The APDU response from the ICC card with the status appended at the end, or null if * there is an issue connecting to the Telephony service. * @hide + * @deprecated instead use + * {@link #iccTransmitApduLogicalChannelByPort(int, int, int, int, int, int, int, int, String)} */ @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) @SystemApi @Nullable + @Deprecated public String iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla, int instruction, int p1, int p2, int p3, @Nullable String data) { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.iccTransmitApduLogicalChannelBySlot(slotIndex, channel, cla, - instruction, p1, p2, p3, data); + return telephony.iccTransmitApduLogicalChannelByPort(slotIndex, DEFAULT_PORT_INDEX, + channel, cla, instruction, p1, p2, p3, data); } } catch (RemoteException ex) { } catch (NullPointerException ex) { @@ -6977,6 +7095,50 @@ public class TelephonyManager { } /** + * Transmit an APDU to the ICC card over a logical channel using the physical slot index. + * + * Use this method when no subscriptions are available on the SIM and the operation must be + * performed using the physical slot index. + * + * Input parameters equivalent to TS 27.007 AT+CGLA command. + * + * @param slotIndex the physical slot index of the ICC card + * @param portIndex The port index is an enumeration of the ports available on the UICC. + * Use {@link UiccPortInfo#getPortIndex()} to get portIndex. + * @param channel is the channel id to be closed as returned by a successful + * iccOpenLogicalChannel. + * @param cla Class of the APDU command. + * @param instruction Instruction of the APDU command. + * @param p1 P1 value of the APDU command. + * @param p2 P2 value of the APDU command. + * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU + * is sent to the SIM. + * @param data Data to be sent with the APDU. + * @return The APDU response from the ICC card with the status appended at the end, or null if + * there is an issue connecting to the Telephony service. + * @hide + */ + @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) + @SystemApi + @NonNull + public String iccTransmitApduLogicalChannelByPort(int slotIndex, int portIndex, int channel, + int cla, int instruction, int p1, int p2, int p3, @Nullable String data) { + String response; + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + response = telephony.iccTransmitApduLogicalChannelByPort(slotIndex, portIndex, + channel, cla, instruction, p1, p2, p3, data); + } else { + throw new IllegalStateException("telephony service is null."); + } + } catch (RemoteException ex) { + throw ex.rethrowAsRuntimeException(); + } + return response; + } + + /** * Transmit an APDU to the ICC card over a logical channel. * * Input parameters equivalent to TS 27.007 AT+CGLA command. @@ -7061,17 +7223,20 @@ public class TelephonyManager { * @return The APDU response from the ICC card with the status appended at * the end. * @hide + * @deprecated instead use + * {@link #iccTransmitApduBasicChannelByPort(int, int, int, int, int, int, int, String)} */ @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) @SystemApi @NonNull + @Deprecated public String iccTransmitApduBasicChannelBySlot(int slotIndex, int cla, int instruction, int p1, int p2, int p3, @Nullable String data) { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.iccTransmitApduBasicChannelBySlot(slotIndex, getOpPackageName(), - cla, instruction, p1, p2, p3, data); + return telephony.iccTransmitApduBasicChannelByPort(slotIndex, DEFAULT_PORT_INDEX, + getOpPackageName(), cla, instruction, p1, p2, p3, data); } } catch (RemoteException ex) { } catch (NullPointerException ex) { @@ -7080,6 +7245,47 @@ public class TelephonyManager { } /** + * Transmit an APDU to the ICC card over the basic channel using the physical slot index. + * + * Use this method when no subscriptions are available on the SIM and the operation must be + * performed using the physical slot index. + * + * Input parameters equivalent to TS 27.007 AT+CSIM command. + * + * @param slotIndex the physical slot index of the ICC card to target + * @param portIndex The port index is an enumeration of the ports available on the UICC. + * Use {@link UiccPortInfo#getPortIndex()} to get portIndex. + * @param cla Class of the APDU command. + * @param instruction Instruction of the APDU command. + * @param p1 P1 value of the APDU command. + * @param p2 P2 value of the APDU command. + * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU + * is sent to the SIM. + * @param data Data to be sent with the APDU. + * @return The APDU response from the ICC card with the status appended at + * the end. + * @hide + */ + @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) + @SystemApi + @NonNull + public String iccTransmitApduBasicChannelByPort(int slotIndex, int portIndex, int cla, + int instruction, int p1, int p2, int p3, @Nullable String data) { + String response; + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + response = telephony.iccTransmitApduBasicChannelByPort(slotIndex, portIndex, + getOpPackageName(), cla, instruction, p1, p2, p3, data); + } else { + throw new IllegalStateException("telephony service is null."); + } + } catch (RemoteException ex) { + throw ex.rethrowAsRuntimeException(); + } + return response; + } + /** * Transmit an APDU to the ICC card over the basic channel. * * Input parameters equivalent to TS 27.007 AT+CSIM command. @@ -9397,15 +9603,7 @@ public class TelephonyManager { @SystemApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public @Nullable String getCarrierServicePackageName() { - // TODO(b/205736323) plumb this through to CarrierPrivilegesTracker, which will cache the - // value instead of re-querying every time. - List<String> carrierServicePackages = - getCarrierPackageNamesForIntent( - new Intent(CarrierService.CARRIER_SERVICE_INTERFACE)); - if (carrierServicePackages != null && !carrierServicePackages.isEmpty()) { - return carrierServicePackages.get(0); - } - return null; + return getCarrierServicePackageNameForLogicalSlot(getPhoneId()); } /** @@ -9422,13 +9620,15 @@ public class TelephonyManager { @SystemApi @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public @Nullable String getCarrierServicePackageNameForLogicalSlot(int logicalSlotIndex) { - // TODO(b/205736323) plumb this through to CarrierPrivilegesTracker, which will cache the - // value instead of re-querying every time. - List<String> carrierServicePackages = - getCarrierPackageNamesForIntentAndPhone( - new Intent(CarrierService.CARRIER_SERVICE_INTERFACE), logicalSlotIndex); - if (carrierServicePackages != null && !carrierServicePackages.isEmpty()) { - return carrierServicePackages.get(0); + try { + ITelephony telephony = getITelephony(); + if (telephony != null) { + return telephony.getCarrierServicePackageNameForLogicalSlot(logicalSlotIndex); + } + } catch (RemoteException ex) { + Rlog.e(TAG, "getCarrierServicePackageNameForLogicalSlot RemoteException", ex); + } catch (NullPointerException ex) { + Rlog.e(TAG, "getCarrierServicePackageNameForLogicalSlot NPE", ex); } return null; } @@ -16232,6 +16432,7 @@ public class TelephonyManager { * @deprecated Use {@link CarrierPrivilegesCallback} instead. This API will be removed soon * prior to API finalization. */ + @Deprecated @SystemApi public interface CarrierPrivilegesListener { /** @@ -16369,8 +16570,17 @@ public class TelephonyManager { int logicalSlotIndex, @NonNull @CallbackExecutor Executor executor, @NonNull CarrierPrivilegesCallback callback) { - // TODO(b/216549778): cherry-pick implementation once merge conflict is resolved - throw new UnsupportedOperationException("Not implemented, yet"); + if (mContext == null) { + throw new IllegalStateException("Telephony service is null"); + } else if (executor == null || callback == null) { + throw new IllegalArgumentException( + "CarrierPrivilegesCallback and executor must be non-null"); + } + mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class); + if (mTelephonyRegistryMgr == null) { + throw new IllegalStateException("Telephony registry service is null"); + } + mTelephonyRegistryMgr.addCarrierPrivilegesCallback(logicalSlotIndex, executor, callback); } /** @@ -16381,7 +16591,15 @@ public class TelephonyManager { @SystemApi @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterCarrierPrivilegesCallback(@NonNull CarrierPrivilegesCallback callback) { - // TODO(b/216549778): cherry-pick implementation once merge conflict is resolved - throw new UnsupportedOperationException("Not implemented, yet"); + if (mContext == null) { + throw new IllegalStateException("Telephony service is null"); + } else if (callback == null) { + throw new IllegalArgumentException("CarrierPrivilegesCallback must be non-null"); + } + mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class); + if (mTelephonyRegistryMgr == null) { + throw new IllegalStateException("Telephony registry service is null"); + } + mTelephonyRegistryMgr.removeCarrierPrivilegesCallback(callback); } } diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index f8540202b3bf..281b018b3395 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -1272,24 +1272,34 @@ public class ApnSetting implements Parcelable { */ public boolean similar(ApnSetting other) { return (!this.canHandleType(TYPE_DUN) - && !other.canHandleType(TYPE_DUN) - && Objects.equals(this.mApnName, other.mApnName) - && !typeSameAny(this, other) - && xorEqualsString(this.mProxyAddress, other.mProxyAddress) - && xorEqualsInt(this.mProxyPort, other.mProxyPort) - && xorEquals(this.mProtocol, other.mProtocol) - && xorEquals(this.mRoamingProtocol, other.mRoamingProtocol) - && Objects.equals(this.mCarrierEnabled, other.mCarrierEnabled) - && Objects.equals(this.mProfileId, other.mProfileId) - && Objects.equals(this.mMvnoType, other.mMvnoType) - && Objects.equals(this.mMvnoMatchData, other.mMvnoMatchData) - && xorEquals(this.mMmsc, other.mMmsc) - && xorEqualsString(this.mMmsProxyAddress, other.mMmsProxyAddress) - && xorEqualsInt(this.mMmsProxyPort, other.mMmsProxyPort)) - && Objects.equals(this.mNetworkTypeBitmask, other.mNetworkTypeBitmask) - && Objects.equals(mApnSetId, other.mApnSetId) - && Objects.equals(mCarrierId, other.mCarrierId) - && Objects.equals(mSkip464Xlat, other.mSkip464Xlat); + && !other.canHandleType(TYPE_DUN) + && Objects.equals(this.mApnName, other.mApnName) + && xorEqualsString(this.mProxyAddress, other.mProxyAddress) + && xorEqualsInt(this.mProxyPort, other.mProxyPort) + && xorEquals(this.mMmsc, other.mMmsc) + && xorEqualsString(this.mMmsProxyAddress, other.mMmsProxyAddress) + && xorEqualsInt(this.mMmsProxyPort, other.mMmsProxyPort)) + && xorEqualsString(this.mUser, other.mUser) + && xorEqualsString(this.mPassword, other.mPassword) + && xorEqualsInt(this.mAuthType, other.mAuthType) + && !typeSameAny(this, other) + && Objects.equals(this.mOperatorNumeric, other.mOperatorNumeric) + && Objects.equals(this.mProtocol, other.mProtocol) + && Objects.equals(this.mRoamingProtocol, other.mRoamingProtocol) + && xorEqualsInt(this.mMtuV4, other.mMtuV4) + && xorEqualsInt(this.mMtuV6, other.mMtuV6) + && Objects.equals(this.mCarrierEnabled, other.mCarrierEnabled) + && Objects.equals(this.mNetworkTypeBitmask, other.mNetworkTypeBitmask) + && Objects.equals(this.mLingeringNetworkTypeBitmask, + other.mLingeringNetworkTypeBitmask) + && Objects.equals(this.mProfileId, other.mProfileId) + && Objects.equals(this.mPersistent, other.mPersistent) + && Objects.equals(this.mMvnoType, other.mMvnoType) + && Objects.equals(this.mMvnoMatchData, other.mMvnoMatchData) + && Objects.equals(this.mApnSetId, other.mApnSetId) + && Objects.equals(this.mCarrierId, other.mCarrierId) + && Objects.equals(this.mSkip464Xlat, other.mSkip464Xlat) + && Objects.equals(this.mAlwaysOn, other.mAlwaysOn); } // Equal or one is null. diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java index 45022a6e4d8c..aa514b99dad3 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -16,6 +16,7 @@ package android.telephony.euicc; import android.Manifest; +import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -28,6 +29,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentSender; import android.content.pm.PackageManager; +import android.os.Binder; import android.os.Bundle; import android.os.RemoteException; import android.telephony.TelephonyFrameworkInitializer; @@ -35,11 +37,13 @@ import android.telephony.TelephonyManager; import android.telephony.euicc.EuiccCardManager.ResetOption; import com.android.internal.telephony.euicc.IEuiccController; +import com.android.internal.telephony.euicc.IResultCallback; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Collections; import java.util.List; +import java.util.concurrent.Executor; import java.util.stream.Collectors; /** @@ -215,6 +219,20 @@ public class EuiccManager { "android.telephony.euicc.action.START_EUICC_ACTIVATION"; /** + * Result codes passed to the ResultListener by + * {@link #switchToSubscription(int, int, Executor, ResultListener)} + * + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"EMBEDDED_SUBSCRIPTION_RESULT_"}, value = { + EMBEDDED_SUBSCRIPTION_RESULT_OK, + EMBEDDED_SUBSCRIPTION_RESULT_ERROR, + EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR + }) + public @interface ResultCode{} + + /** * Result code for an operation indicating that the operation succeeded. */ public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0; @@ -1125,7 +1143,12 @@ public class EuiccManager { * permission, or the calling app must be authorized to manage the active subscription on * the target eUICC. * @param callbackIntent a PendingIntent to launch when the operation completes. + * + * @deprecated From T, callers should use + * {@link #switchToSubscription(int, int, Executor, ResultListener)} instead to specify a port + * index on the card to switch to. */ + @Deprecated @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) public void switchToSubscription(int subscriptionId, PendingIntent callbackIntent) { if (!isEnabled()) { @@ -1141,6 +1164,71 @@ public class EuiccManager { } /** + * Switch to (enable) the given subscription. + * + * <p>Requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission, + * or the calling app must be authorized to manage both the currently-active subscription and + * the subscription to be enabled according to the subscription metadata. Without the former, + * an {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback + * intent to prompt the user to accept the download. + * + * <p>On a multi-active SIM device, requires the + * {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} permission, or a calling app + * only if the targeted eUICC does not currently have an active subscription or the calling app + * is authorized to manage the active subscription on the target eUICC, and the calling app is + * authorized to manage any active subscription on any SIM. Without it, an + * {@link #EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR} will be returned in the callback + * intent to prompt the user to accept the download. The caller should also be authorized to + * manage the subscription to be enabled. + * + * @param subscriptionId the ID of the subscription to enable. May be + * {@link android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID} to deactivate the + * current profile without activating another profile to replace it. If it's a disable + * operation, requires the {@code android.Manifest.permission#WRITE_EMBEDDED_SUBSCRIPTIONS} + * permission, or the calling app must be authorized to manage the active subscription on + * the target eUICC. + * @param portIndex the index of the port to target for the enabled subscription + * @param executor an Executor on which to run the callback + * @param callback a {@link ResultListener} which will run when the operation completes + */ + @RequiresPermission(Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS) + public void switchToSubscription(int subscriptionId, int portIndex, + @NonNull @CallbackExecutor Executor executor, + @NonNull ResultListener callback) { + if (!isEnabled()) { + sendUnavailableErrorToCallback(executor, callback); + return; + } + try { + IResultCallback internalCallback = new IResultCallback.Stub() { + @Override + public void onComplete(int result, Intent resultIntent) { + executor.execute(() -> Binder.withCleanCallingIdentity( + () -> callback.onComplete(result, resultIntent))); + } + }; + getIEuiccController().switchToSubscriptionWithPort(mCardId, portIndex, + subscriptionId, mContext.getOpPackageName(), internalCallback); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Callback to receive the result of an EuiccManager API. + */ + public interface ResultListener { + /** + * Called on completion of some operation. + * @param resultCode representing success or specific failure of the operation + * (See {@link ResultCode}) + * @param resultIntent an intent used to start a resolution activity when an error + * occurs that can be resolved by the user + */ + void onComplete(@ResultCode int resultCode, @Nullable Intent resultIntent); + } + + /** * Update the nickname for the given subscription. * * <p>Requires that the calling app has carrier privileges according to the metadata of the @@ -1411,6 +1499,13 @@ public class EuiccManager { } } + private static void sendUnavailableErrorToCallback(@NonNull Executor executor, + ResultListener callback) { + Integer result = EMBEDDED_SUBSCRIPTION_RESULT_ERROR; + executor.execute(() -> + Binder.withCleanCallingIdentity(() -> callback.onComplete(result, null))); + } + private static IEuiccController getIEuiccController() { return IEuiccController.Stub.asInterface( TelephonyFrameworkInitializer diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java index b56aa9687aee..f5b158fedd37 100644 --- a/telephony/java/android/telephony/ims/feature/ImsFeature.java +++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java @@ -375,12 +375,16 @@ public abstract class ImsFeature { */ @SystemApi public final void setFeatureState(@ImsState int state) { + boolean isNotify = false; synchronized (mLock) { if (mState != state) { mState = state; - notifyFeatureState(state); + isNotify = true; } } + if (isNotify) { + notifyFeatureState(state); + } } /** @@ -412,14 +416,16 @@ public abstract class ImsFeature { * Internal method called by ImsFeature when setFeatureState has changed. */ private void notifyFeatureState(@ImsState int state) { - mStatusCallbacks.broadcastAction((c) -> { - try { - c.notifyImsFeatureStatus(state); - } catch (RemoteException e) { - Log.w(LOG_TAG, e + " notifyFeatureState() - Skipping " - + "callback."); - } - }); + synchronized (mStatusCallbacks) { + mStatusCallbacks.broadcastAction((c) -> { + try { + c.notifyImsFeatureStatus(state); + } catch (RemoteException e) { + Log.w(LOG_TAG, e + " notifyFeatureState() - Skipping " + + "callback."); + } + }); + } } /** @@ -491,14 +497,19 @@ public abstract class ImsFeature { synchronized (mLock) { mCapabilityStatus = caps.copy(); } - mCapabilityCallbacks.broadcastAction((callback) -> { - try { - callback.onCapabilitiesStatusChanged(caps.mCapabilities); - } catch (RemoteException e) { - Log.w(LOG_TAG, e + " notifyCapabilitiesStatusChanged() - Skipping " - + "callback."); - } - }); + + synchronized (mCapabilityCallbacks) { + mCapabilityCallbacks.broadcastAction((callback) -> { + try { + Log.d(LOG_TAG, "ImsFeature notifyCapabilitiesStatusChanged Capabilities = " + + caps.mCapabilities); + callback.onCapabilitiesStatusChanged(caps.mCapabilities); + } catch (RemoteException e) { + Log.w(LOG_TAG, e + " notifyCapabilitiesStatusChanged() - Skipping " + + "callback."); + } + }); + } } /** diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java index 11fc328a42c7..f371ec3a28a7 100644 --- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java @@ -587,13 +587,15 @@ public class ImsConfigImplBase { if (mCallbacks == null) { return; } - mCallbacks.broadcastAction(c -> { - try { - c.onIntConfigChanged(item, value); - } catch (RemoteException e) { - Log.w(TAG, "notifyConfigChanged(int): dead binder in notify, skipping."); - } - }); + synchronized (mCallbacks) { + mCallbacks.broadcastAction(c -> { + try { + c.onIntConfigChanged(item, value); + } catch (RemoteException e) { + Log.w(TAG, "notifyConfigChanged(int): dead binder in notify, skipping."); + } + }); + } } private void notifyConfigChanged(int item, String value) { @@ -601,13 +603,15 @@ public class ImsConfigImplBase { if (mCallbacks == null) { return; } - mCallbacks.broadcastAction(c -> { - try { - c.onStringConfigChanged(item, value); - } catch (RemoteException e) { - Log.w(TAG, "notifyConfigChanged(string): dead binder in notify, skipping."); - } - }); + synchronized (mCallbacks) { + mCallbacks.broadcastAction(c -> { + try { + c.onStringConfigChanged(item, value); + } catch (RemoteException e) { + Log.w(TAG, "notifyConfigChanged(string): dead binder in notify, skipping."); + } + }); + } } private void addRcsConfigCallback(IRcsConfigCallback c) { @@ -635,13 +639,15 @@ public class ImsConfigImplBase { // can be null in testing if (mRcsCallbacks != null) { - mRcsCallbacks.broadcastAction(c -> { - try { - c.onConfigurationChanged(mRcsConfigData); - } catch (RemoteException e) { - Log.w(TAG, "dead binder in notifyRcsAutoConfigurationReceived, skipping."); - } - }); + synchronized (mRcsCallbacks) { + mRcsCallbacks.broadcastAction(c -> { + try { + c.onConfigurationChanged(mRcsConfigData); + } catch (RemoteException e) { + Log.w(TAG, "dead binder in notifyRcsAutoConfigurationReceived, skipping."); + } + }); + } } notifyRcsAutoConfigurationReceived(config, isCompressed); } @@ -649,13 +655,15 @@ public class ImsConfigImplBase { private void onNotifyRcsAutoConfigurationRemoved() { mRcsConfigData = null; if (mRcsCallbacks != null) { - mRcsCallbacks.broadcastAction(c -> { - try { - c.onConfigurationReset(); - } catch (RemoteException e) { - Log.w(TAG, "dead binder in notifyRcsAutoConfigurationRemoved, skipping."); - } - }); + synchronized (mRcsCallbacks) { + mRcsCallbacks.broadcastAction(c -> { + try { + c.onConfigurationReset(); + } catch (RemoteException e) { + Log.w(TAG, "dead binder in notifyRcsAutoConfigurationRemoved, skipping."); + } + }); + } } notifyRcsAutoConfigurationRemoved(); } @@ -801,13 +809,15 @@ public class ImsConfigImplBase { if (mRcsCallbacks == null) { return; } - mRcsCallbacks.broadcastAction(c -> { - try { - c.onAutoConfigurationErrorReceived(errorCode, errorString); - } catch (RemoteException e) { - Log.w(TAG, "dead binder in notifyAutoConfigurationErrorReceived, skipping."); - } - }); + synchronized (mRcsCallbacks) { + mRcsCallbacks.broadcastAction(c -> { + try { + c.onAutoConfigurationErrorReceived(errorCode, errorString); + } catch (RemoteException e) { + Log.w(TAG, "dead binder in notifyAutoConfigurationErrorReceived, skipping."); + } + }); + } } /** @@ -825,13 +835,15 @@ public class ImsConfigImplBase { if (mRcsCallbacks == null) { return; } - mRcsCallbacks.broadcastAction(c -> { - try { - c.onPreProvisioningReceived(configXml); - } catch (RemoteException e) { - Log.w(TAG, "dead binder in notifyPreProvisioningReceived, skipping."); - } - }); + synchronized (mRcsCallbacks) { + mRcsCallbacks.broadcastAction(c -> { + try { + c.onPreProvisioningReceived(configXml); + } catch (RemoteException e) { + Log.w(TAG, "dead binder in notifyPreProvisioningReceived, skipping."); + } + }); + } } /** diff --git a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java index 2783e299236b..fb997d118419 100644 --- a/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java +++ b/telephony/java/android/telephony/ims/stub/ImsSmsImplBase.java @@ -219,22 +219,25 @@ public class ImsSmsImplBase { */ public final void onSmsReceived(int token, @SmsMessage.Format String format, byte[] pdu) throws RuntimeException { + IImsSmsListener listener = null; synchronized (mLock) { - if (mListener == null) { - throw new RuntimeException("Feature not ready."); - } - try { - mListener.onSmsReceived(token, format, pdu); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Can not deliver sms: " + e.getMessage()); - SmsMessage message = SmsMessage.createFromPdu(pdu, format); - if (message != null && message.mWrappedSmsMessage != null) { - acknowledgeSms(token, message.mWrappedSmsMessage.mMessageRef, - DELIVER_STATUS_ERROR_GENERIC); - } else { - Log.w(LOG_TAG, "onSmsReceived: Invalid pdu entered."); - acknowledgeSms(token, 0, DELIVER_STATUS_ERROR_GENERIC); - } + listener = mListener; + } + + if (listener == null) { + throw new RuntimeException("Feature not ready."); + } + try { + listener.onSmsReceived(token, format, pdu); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Can not deliver sms: " + e.getMessage()); + SmsMessage message = SmsMessage.createFromPdu(pdu, format); + if (message != null && message.mWrappedSmsMessage != null) { + acknowledgeSms(token, message.mWrappedSmsMessage.mMessageRef, + DELIVER_STATUS_ERROR_GENERIC); + } else { + Log.w(LOG_TAG, "onSmsReceived: Invalid pdu entered."); + acknowledgeSms(token, 0, DELIVER_STATUS_ERROR_GENERIC); } } } @@ -254,16 +257,19 @@ public class ImsSmsImplBase { */ public final void onSendSmsResultSuccess(int token, @IntRange(from = 0, to = 65535) int messageRef) throws RuntimeException { + IImsSmsListener listener = null; synchronized (mLock) { - if (mListener == null) { - throw new RuntimeException("Feature not ready."); - } - try { - mListener.onSendSmsResult(token, messageRef, SEND_STATUS_OK, - SmsManager.RESULT_ERROR_NONE, RESULT_NO_NETWORK_ERROR); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } + listener = mListener; + } + + if (listener == null) { + throw new RuntimeException("Feature not ready."); + } + try { + listener.onSendSmsResult(token, messageRef, SEND_STATUS_OK, + SmsManager.RESULT_ERROR_NONE, RESULT_NO_NETWORK_ERROR); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); } } @@ -288,16 +294,19 @@ public class ImsSmsImplBase { @Deprecated public final void onSendSmsResult(int token, @IntRange(from = 0, to = 65535) int messageRef, @SendStatusResult int status, @SmsManager.Result int reason) throws RuntimeException { + IImsSmsListener listener = null; synchronized (mLock) { - if (mListener == null) { - throw new RuntimeException("Feature not ready."); - } - try { - mListener.onSendSmsResult(token, messageRef, status, reason, - RESULT_NO_NETWORK_ERROR); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } + listener = mListener; + } + + if (listener == null) { + throw new RuntimeException("Feature not ready."); + } + try { + listener.onSendSmsResult(token, messageRef, status, reason, + RESULT_NO_NETWORK_ERROR); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); } } @@ -322,15 +331,18 @@ public class ImsSmsImplBase { public final void onSendSmsResultError(int token, @IntRange(from = 0, to = 65535) int messageRef, @SendStatusResult int status, @SmsManager.Result int reason, int networkErrorCode) throws RuntimeException { + IImsSmsListener listener = null; synchronized (mLock) { - if (mListener == null) { - throw new RuntimeException("Feature not ready."); - } - try { - mListener.onSendSmsResult(token, messageRef, status, reason, networkErrorCode); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } + listener = mListener; + } + + if (listener == null) { + throw new RuntimeException("Feature not ready."); + } + try { + listener.onSendSmsResult(token, messageRef, status, reason, networkErrorCode); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); } } @@ -357,16 +369,19 @@ public class ImsSmsImplBase { public final void onSmsStatusReportReceived(int token, @IntRange(from = 0, to = 65535) int messageRef, @SmsMessage.Format String format, byte[] pdu) throws RuntimeException { + IImsSmsListener listener = null; synchronized (mLock) { - if (mListener == null) { - throw new RuntimeException("Feature not ready."); - } - try { - mListener.onSmsStatusReportReceived(token, format, pdu); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Can not process sms status report: " + e.getMessage()); - acknowledgeSmsReport(token, messageRef, STATUS_REPORT_STATUS_ERROR); - } + listener = mListener; + } + + if (listener == null) { + throw new RuntimeException("Feature not ready."); + } + try { + listener.onSmsStatusReportReceived(token, format, pdu); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Can not process sms status report: " + e.getMessage()); + acknowledgeSmsReport(token, messageRef, STATUS_REPORT_STATUS_ERROR); } } @@ -386,24 +401,27 @@ public class ImsSmsImplBase { */ public final void onSmsStatusReportReceived(int token, @SmsMessage.Format String format, byte[] pdu) throws RuntimeException { + IImsSmsListener listener = null; synchronized (mLock) { - if (mListener == null) { - throw new RuntimeException("Feature not ready."); - } - try { - mListener.onSmsStatusReportReceived(token, format, pdu); - } catch (RemoteException e) { - Log.e(LOG_TAG, "Can not process sms status report: " + e.getMessage()); - SmsMessage message = SmsMessage.createFromPdu(pdu, format); - if (message != null && message.mWrappedSmsMessage != null) { - acknowledgeSmsReport( - token, - message.mWrappedSmsMessage.mMessageRef, - STATUS_REPORT_STATUS_ERROR); - } else { - Log.w(LOG_TAG, "onSmsStatusReportReceived: Invalid pdu entered."); - acknowledgeSmsReport(token, 0, STATUS_REPORT_STATUS_ERROR); - } + listener = mListener; + } + + if (listener == null) { + throw new RuntimeException("Feature not ready."); + } + try { + listener.onSmsStatusReportReceived(token, format, pdu); + } catch (RemoteException e) { + Log.e(LOG_TAG, "Can not process sms status report: " + e.getMessage()); + SmsMessage message = SmsMessage.createFromPdu(pdu, format); + if (message != null && message.mWrappedSmsMessage != null) { + acknowledgeSmsReport( + token, + message.mWrappedSmsMessage.mMessageRef, + STATUS_REPORT_STATUS_ERROR); + } else { + Log.w(LOG_TAG, "onSmsStatusReportReceived: Invalid pdu entered."); + acknowledgeSmsReport(token, 0, STATUS_REPORT_STATUS_ERROR); } } } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index e1da407cfabd..883e2ad9b76e 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -68,6 +68,7 @@ import com.android.ims.internal.IImsServiceFeatureCallback; import com.android.internal.telephony.CellNetworkScanResult; import com.android.internal.telephony.IBooleanConsumer; import com.android.internal.telephony.ICallForwardingInfoCallback; +import com.android.internal.telephony.IccLogicalChannelRequest; import com.android.internal.telephony.IImsStateCallback; import com.android.internal.telephony.IIntegerConsumer; import com.android.internal.telephony.INumberVerificationCallback; @@ -585,64 +586,32 @@ interface ITelephony { void setCellInfoListRate(int rateInMillis); /** - * Opens a logical channel to the ICC card using the physical slot index. - * - * Input parameters equivalent to TS 27.007 AT+CCHO command. - * - * @param slotIndex The physical slot index of the target ICC card - * @param callingPackage the name of the package making the call. - * @param AID Application id. See ETSI 102.221 and 101.220. - * @param p2 P2 parameter (described in ISO 7816-4). - * @return an IccOpenLogicalChannelResponse object. - */ - IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot( - int slotIndex, String callingPackage, String AID, int p2); - - /** * Opens a logical channel to the ICC card. * * Input parameters equivalent to TS 27.007 AT+CCHO command. * - * @param subId The subscription to use. - * @param callingPackage the name of the package making the call. - * @param AID Application id. See ETSI 102.221 and 101.220. - * @param p2 P2 parameter (described in ISO 7816-4). + * @param request the parcelable used to indicate how to open the logical channel. * @return an IccOpenLogicalChannelResponse object. */ - IccOpenLogicalChannelResponse iccOpenLogicalChannel( - int subId, String callingPackage, String AID, int p2); - - /** - * Closes a previously opened logical channel to the ICC card using the physical slot index. - * - * Input parameters equivalent to TS 27.007 AT+CCHC command. - * - * @param slotIndex The physical slot index of the target ICC card - * @param channel is the channel id to be closed as returned by a - * successful iccOpenLogicalChannel. - * @return true if the channel was closed successfully. - */ - boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel); + IccOpenLogicalChannelResponse iccOpenLogicalChannel(in IccLogicalChannelRequest request); /** * Closes a previously opened logical channel to the ICC card. * * Input parameters equivalent to TS 27.007 AT+CCHC command. * - * @param subId The subscription to use. - * @param channel is the channel id to be closed as returned by a - * successful iccOpenLogicalChannel. + * @param request the parcelable used to indicate how to close the logical channel. * @return true if the channel was closed successfully. */ - @UnsupportedAppUsage(trackingBug = 171933273) - boolean iccCloseLogicalChannel(int subId, int channel); + boolean iccCloseLogicalChannel(in IccLogicalChannelRequest request); /** - * Transmit an APDU to the ICC card over a logical channel using the physical slot index. + * Transmit an APDU to the ICC card over a logical channel using the physical slot index and port index. * * Input parameters equivalent to TS 27.007 AT+CGLA command. * * @param slotIndex The physical slot index of the target ICC card + * @param portIndex The unique index referring to a port belonging to the SIM slot * @param channel is the channel id to be closed as returned by a * successful iccOpenLogicalChannel. * @param cla Class of the APDU command. @@ -655,7 +624,7 @@ interface ITelephony { * @return The APDU response from the ICC card with the status appended at * the end. */ - String iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla, int instruction, + String iccTransmitApduLogicalChannelByPort(int slotIndex, int portIndex, int channel, int cla, int instruction, int p1, int p2, int p3, String data); /** @@ -681,11 +650,12 @@ interface ITelephony { int p1, int p2, int p3, String data); /** - * Transmit an APDU to the ICC card over the basic channel using the physical slot index. + * Transmit an APDU to the ICC card over the basic channel using the physical slot index and port index. * * Input parameters equivalent to TS 27.007 AT+CSIM command. * * @param slotIndex The physical slot index of the target ICC card + * @param portIndex The unique index referring to a port belonging to the SIM slot * @param callingPackage the name of the package making the call. * @param cla Class of the APDU command. * @param instruction Instruction of the APDU command. @@ -697,7 +667,7 @@ interface ITelephony { * @return The APDU response from the ICC card with the status appended at * the end. */ - String iccTransmitApduBasicChannelBySlot(int slotIndex, String callingPackage, int cla, + String iccTransmitApduBasicChannelByPort(int slotIndex, int portIndex, String callingPackage, int cla, int instruction, int p1, int p2, int p3, String data); /** @@ -2575,4 +2545,15 @@ interface ITelephony { * registration technology specified, false if it is not required. */ boolean isRcsProvisioningRequiredForCapability(int subId, int capability, int tech); + + /** + * Returns the package name that provides the {@link CarrierService} implementation for the + * specified {@code logicalSlotIndex}, or {@code null} if no package with carrier privileges + * declares one. + * + * @param logicalSlotIndex The slot index to fetch the {@link CarrierService} package for + * @return The system-selected package that provides the {@link CarrierService} implementation + * for the slot, or {@code null} if none is resolved + */ + String getCarrierServicePackageNameForLogicalSlot(int logicalSlotIndex); } diff --git a/telephony/java/com/android/internal/telephony/IccLogicalChannelRequest.aidl b/telephony/java/com/android/internal/telephony/IccLogicalChannelRequest.aidl new file mode 100644 index 000000000000..a84e752a98b3 --- /dev/null +++ b/telephony/java/com/android/internal/telephony/IccLogicalChannelRequest.aidl @@ -0,0 +1,52 @@ +/* +** Copyright 2007, 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.internal.telephony; + +import android.os.IBinder; + +/** + * A request to open or close a logical channel to the ICC card. + * + * @hide + */ +@JavaDerive(toString=true, equals=true) +parcelable IccLogicalChannelRequest { + + /** Subscription id. */ + int subId = -1; + + /** Physical slot index of the ICC card. */ + int slotIndex = -1; + + /** The unique index referring to a port belonging to the ICC card slot. */ + int portIndex = 0; + + /** Package name for the calling app, used only when open channel. */ + @nullable String callingPackage; + + /** Application id, used only when open channel. */ + @nullable String aid; + + /** The P2 parameter described in ISO 7816-4, used only when open channel. */ + int p2 = 0; + + /** Channel number */ + int channel = -1; + + /** A IBinder object for server side to check if the request client is still living. */ + @nullable IBinder binder; +} diff --git a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl index 944ce3486ca6..7f5982f128e3 100644 --- a/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl +++ b/telephony/java/com/android/internal/telephony/euicc/IEuiccController.aidl @@ -21,6 +21,9 @@ import android.content.Intent; import android.os.Bundle; import android.telephony.euicc.DownloadableSubscription; import android.telephony.euicc.EuiccInfo; + +import com.android.internal.telephony.euicc.IResultCallback; + import java.util.List; /** @hide */ @@ -42,6 +45,8 @@ interface IEuiccController { in PendingIntent callbackIntent); oneway void switchToSubscription(int cardId, int subscriptionId, String callingPackage, in PendingIntent callbackIntent); + oneway void switchToSubscriptionWithPort(int cardId, int portIndex, int subscriptionId, + String callingPackage, in IResultCallback callback); oneway void updateSubscriptionNickname(int cardId, int subscriptionId, String nickname, String callingPackage, in PendingIntent callbackIntent); oneway void eraseSubscriptions(int cardId, in PendingIntent callbackIntent); diff --git a/startop/scripts/trace_analyzer/queries_pretty_print_block_launch.sql b/telephony/java/com/android/internal/telephony/euicc/IResultCallback.aidl index bf5e3ccb4ac7..69f479c683d1 100644 --- a/startop/scripts/trace_analyzer/queries_pretty_print_block_launch.sql +++ b/telephony/java/com/android/internal/telephony/euicc/IResultCallback.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * 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. @@ -13,16 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +package com.android.internal.telephony.euicc; -.headers on -.mode quote +import android.content.Intent; -SELECT * FROM blocked_iowait_for_app_launches; - -/* -Output as CSV example: - -'blocked_iowait_duration_ms','process_name','launching_duration_ms','launching_started_timestamp_ms','launching_finished_timestamp_ms' -125.33199995596078224,'com.android.settings',1022.4840000009862706,17149896.822000000626,17150919.305999998003 - -*/ +/** @hide */ +oneway interface IResultCallback { + void onComplete(int resultCode, in Intent resultIntent); +} diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java index 7b1f7a599519..b67395735426 100644 --- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java +++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java @@ -60,7 +60,7 @@ import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; -import android.telephony.TelephonyManager.CarrierPrivilegesListener; +import android.telephony.TelephonyManager.CarrierPrivilegesCallback; import android.util.ArrayMap; import android.util.ArraySet; @@ -187,11 +187,11 @@ public class TelephonySubscriptionTrackerTest { return captor.getValue(); } - private List<CarrierPrivilegesListener> getCarrierPrivilegesListeners() { - final ArgumentCaptor<CarrierPrivilegesListener> captor = - ArgumentCaptor.forClass(CarrierPrivilegesListener.class); + private List<CarrierPrivilegesCallback> getCarrierPrivilegesCallbacks() { + final ArgumentCaptor<CarrierPrivilegesCallback> captor = + ArgumentCaptor.forClass(CarrierPrivilegesCallback.class); verify(mTelephonyManager, atLeastOnce()) - .addCarrierPrivilegesListener(anyInt(), any(), captor.capture()); + .registerCarrierPrivilegesCallback(anyInt(), any(), captor.capture()); return captor.getAllValues(); } @@ -270,12 +270,12 @@ public class TelephonySubscriptionTrackerTest { assertNotNull(getOnSubscriptionsChangedListener()); verify(mTelephonyManager, times(2)) - .addCarrierPrivilegesListener(anyInt(), any(HandlerExecutor.class), any()); + .registerCarrierPrivilegesCallback(anyInt(), any(HandlerExecutor.class), any()); verify(mTelephonyManager) - .addCarrierPrivilegesListener(eq(0), any(HandlerExecutor.class), any()); + .registerCarrierPrivilegesCallback(eq(0), any(HandlerExecutor.class), any()); verify(mTelephonyManager) - .addCarrierPrivilegesListener(eq(1), any(HandlerExecutor.class), any()); - assertEquals(2, getCarrierPrivilegesListeners().size()); + .registerCarrierPrivilegesCallback(eq(1), any(HandlerExecutor.class), any()); + assertEquals(2, getCarrierPrivilegesCallbacks().size()); } @Test @@ -287,10 +287,10 @@ public class TelephonySubscriptionTrackerTest { final OnSubscriptionsChangedListener listener = getOnSubscriptionsChangedListener(); verify(mSubscriptionManager).removeOnSubscriptionsChangedListener(eq(listener)); - for (CarrierPrivilegesListener carrierPrivilegesListener : - getCarrierPrivilegesListeners()) { + for (CarrierPrivilegesCallback carrierPrivilegesCallback : + getCarrierPrivilegesCallbacks()) { verify(mTelephonyManager) - .removeCarrierPrivilegesListener(eq(carrierPrivilegesListener)); + .unregisterCarrierPrivilegesCallback(eq(carrierPrivilegesCallback)); } } @@ -303,15 +303,15 @@ public class TelephonySubscriptionTrackerTest { mTelephonySubscriptionTracker.setReadySubIdsBySlotId(readySubIdsBySlotId); doReturn(1).when(mTelephonyManager).getActiveModemCount(); - List<CarrierPrivilegesListener> carrierPrivilegesListeners = - getCarrierPrivilegesListeners(); + List<CarrierPrivilegesCallback> carrierPrivilegesCallbacks = + getCarrierPrivilegesCallbacks(); mTelephonySubscriptionTracker.onReceive(mContext, buildTestMultiSimConfigBroadcastIntent()); mTestLooper.dispatchAll(); - for (CarrierPrivilegesListener carrierPrivilegesListener : carrierPrivilegesListeners) { + for (CarrierPrivilegesCallback carrierPrivilegesCallback : carrierPrivilegesCallbacks) { verify(mTelephonyManager) - .removeCarrierPrivilegesListener(eq(carrierPrivilegesListener)); + .unregisterCarrierPrivilegesCallback(eq(carrierPrivilegesCallback)); } // Expect cache cleared for inactive slots. @@ -323,9 +323,9 @@ public class TelephonySubscriptionTrackerTest { // Expect a new CarrierPrivilegesListener to have been registered for slot 0, and none other // (2 previously registered during startup, for slots 0 & 1) verify(mTelephonyManager, times(3)) - .addCarrierPrivilegesListener(anyInt(), any(HandlerExecutor.class), any()); + .registerCarrierPrivilegesCallback(anyInt(), any(HandlerExecutor.class), any()); verify(mTelephonyManager, times(2)) - .addCarrierPrivilegesListener(eq(0), any(HandlerExecutor.class), any()); + .registerCarrierPrivilegesCallback(eq(0), any(HandlerExecutor.class), any()); // Verify that this triggers a re-evaluation verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES))); @@ -391,8 +391,8 @@ public class TelephonySubscriptionTrackerTest { public void testOnCarrierPrivilegesChanged() throws Exception { setupReadySubIds(); - final CarrierPrivilegesListener listener = getCarrierPrivilegesListeners().get(0); - listener.onCarrierPrivilegesChanged(Collections.emptyList(), new int[] {}); + final CarrierPrivilegesCallback callback = getCarrierPrivilegesCallbacks().get(0); + callback.onCarrierPrivilegesChanged(Collections.emptySet(), Collections.emptySet()); mTestLooper.dispatchAll(); verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES))); diff --git a/tools/locked_region_code_injection/Android.bp b/tools/locked_region_code_injection/Android.bp index 3e1297190622..6efd1f64d8fe 100644 --- a/tools/locked_region_code_injection/Android.bp +++ b/tools/locked_region_code_injection/Android.bp @@ -12,10 +12,10 @@ java_binary_host { manifest: "manifest.txt", srcs: ["src/**/*.java"], static_libs: [ - "asm-7.0", - "asm-commons-7.0", - "asm-tree-7.0", - "asm-analysis-7.0", + "asm-9.2", + "asm-commons-9.2", + "asm-tree-9.2", + "asm-analysis-9.2", "guava-21.0", ], } diff --git a/tools/sdkparcelables/Android.bp b/tools/sdkparcelables/Android.bp index ec2bffdfaf57..6ebacd8a0b14 100644 --- a/tools/sdkparcelables/Android.bp +++ b/tools/sdkparcelables/Android.bp @@ -14,7 +14,7 @@ java_binary_host { "src/**/*.kt", ], static_libs: [ - "asm-7.0", + "asm-9.2", ], } diff --git a/tools/traceinjection/Android.bp b/tools/traceinjection/Android.bp index 1395c5f2e635..39d1b1c2defd 100644 --- a/tools/traceinjection/Android.bp +++ b/tools/traceinjection/Android.bp @@ -12,10 +12,10 @@ java_binary_host { manifest: "manifest.txt", srcs: ["src/**/*.java"], static_libs: [ - "asm-7.0", - "asm-commons-7.0", - "asm-tree-7.0", - "asm-analysis-7.0", + "asm-9.2", + "asm-commons-9.2", + "asm-tree-9.2", + "asm-analysis-9.2", "guava-21.0", ], } |