Merge "Changed the managed profile switching icon"
diff --git a/Android.bp b/Android.bp
index 838f304..e03f844 100644
--- a/Android.bp
+++ b/Android.bp
@@ -169,7 +169,6 @@
"framework-statsd.impl",
"framework-supplementalprocess.impl",
"framework-tethering.impl",
- "framework-nearby.impl",
"framework-uwb.impl",
"framework-wifi.impl",
"updatable-media",
diff --git a/apex/media/framework/lint-baseline.xml b/apex/media/framework/lint-baseline.xml
index e1b1450..95eea45 100644
--- a/apex/media/framework/lint-baseline.xml
+++ b/apex/media/framework/lint-baseline.xml
@@ -1,312 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+<issues format="6" by="lint 7.2.0-dev" type="baseline" client="" dependencies="true" name="" variant="all" version="7.2.0-dev">
<issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `new android.media.ApplicationMediaCapabilities.Builder`"
- errorLine1=" new ApplicationMediaCapabilities.Builder();"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ id="DefaultLocale"
+ message="Implicitly using the default locale is a common source of bugs: Use `toLowerCase(Locale)` instead. For strings meant to be internal use `Locale.ROOT`, otherwise `Locale.getDefault()`."
+ errorLine1=" if (mSupportedVideoMimeTypes.contains(videoMime.toLowerCase())) {"
+ errorLine2=" ~~~~~~~~~~~">
<location
file="frameworks/base/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java"
- line="208"
- column="29"/>
+ line="121"
+ column="57"/>
</issue>
<issue
- id="NewApi"
- message="Call requires API level 31 (current min is 29): `new android.media.ApplicationMediaCapabilities.Builder`"
- errorLine1=" ApplicationMediaCapabilities.Builder builder = new ApplicationMediaCapabilities.Builder();"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ id="DefaultLocale"
+ message="Implicitly using the default locale is a common source of bugs: Use `String.format(Locale, ...)` instead"
+ errorLine1=" return String.format(" session: {id: %d, status: %s, result: %s, progress: %d}","
+ errorLine2=" ^">
<location
- file="frameworks/base/apex/media/framework/java/android/media/ApplicationMediaCapabilities.java"
- line="314"
- column="56"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level R (current min is 29): `android.os.RemoteException#rethrowFromSystemServer`"
- errorLine1=" e.rethrowFromSystemServer();"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaCommunicationManager.java"
- line="110"
- column="15"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level R (current min is 29): `android.os.Parcel#writeParcelableCreator`"
- errorLine1=" dest.writeParcelableCreator((Parcelable) parcelable);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParceledListSlice.java"
- line="77"
- column="14"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level R (current min is 29): `android.os.Parcel#readParcelableCreator`"
- errorLine1=" return from.readParcelableCreator(loader);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParceledListSlice.java"
- line="82"
- column="21"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.TrackData#mediaFormat`"
- errorLine1=" this.mediaFormat = mediaFormat;"
- errorLine2=" ~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="273"
- column="13"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.TrackData#drmInitData`"
- errorLine1=" this.drmInitData = drmInitData;"
- errorLine2=" ~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="274"
- column="13"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
- errorLine1=" this.timeMicros = timeMicros;"
- errorLine2=" ~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="295"
- column="13"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
- errorLine1=" this.position = position;"
- errorLine2=" ~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="296"
- column="13"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
- errorLine1=" return "[timeMicros=" + timeMicros + ", position=" + position + "]";"
- errorLine2=" ~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="302"
- column="66"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
- errorLine1=" return "[timeMicros=" + timeMicros + ", position=" + position + "]";"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="302"
- column="37"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Class requires API level R (current min is 29): `android.media.MediaParser.SeekPoint`"
- errorLine1=" SeekPoint other = (SeekPoint) obj;"
- errorLine2=" ~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="313"
- column="32"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
- errorLine1=" return timeMicros == other.timeMicros && position == other.position;"
- errorLine2=" ~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="314"
- column="54"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
- errorLine1=" return timeMicros == other.timeMicros && position == other.position;"
- errorLine2=" ~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="314"
- column="66"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
- errorLine1=" return timeMicros == other.timeMicros && position == other.position;"
- errorLine2=" ~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="314"
+ file="frameworks/base/apex/media/framework/java/android/media/MediaTranscodingManager.java"
+ line="1651"
column="20"/>
</issue>
<issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
- errorLine1=" return timeMicros == other.timeMicros && position == other.position;"
- errorLine2=" ~~~~~~~~~~~~~~~~">
+ id="ParcelClassLoader"
+ message="Passing null here (to use the default class loader) will not work if you are restoring your own classes. Consider using for example `getClass().getClassLoader()` instead."
+ errorLine1=" Bundle out = parcel.readBundle(null);"
+ errorLine2=" ~~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="314"
- column="34"/>
+ file="frameworks/base/apex/media/framework/java/android/media/MediaSession2.java"
+ line="303"
+ column="33"/>
</issue>
<issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
- errorLine1=" int result = (int) timeMicros;"
- errorLine2=" ~~~~~~~~~~">
+ id="ParcelClassLoader"
+ message="Using the default class loader will not work if you are restoring your own classes. Consider using for example `readBundle(getClass().getClassLoader())` instead."
+ errorLine1=" mCustomExtras = in.readBundle();"
+ errorLine2=" ~~~~~~~~~~~~">
<location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="319"
- column="32"/>
+ file="frameworks/base/apex/media/framework/java/android/media/Session2Command.java"
+ line="104"
+ column="28"/>
</issue>
<issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
- errorLine1=" result = 31 * result + (int) position;"
- errorLine2=" ~~~~~~~~">
+ id="ParcelClassLoader"
+ message="Passing null here (to use the default class loader) will not work if you are restoring your own classes. Consider using for example `getClass().getClassLoader()` instead."
+ errorLine1=" mSessionLink = in.readParcelable(null);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
<location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="320"
- column="42"/>
+ file="frameworks/base/apex/media/framework/java/android/media/Session2Token.java"
+ line="141"
+ column="27"/>
</issue>
<issue
- id="NewApi"
- message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`"
- errorLine1=" public interface SeekableInputReader extends InputReader {"
- errorLine2=" ~~~~~~~~~~~">
+ id="ParcelClassLoader"
+ message="Using the default class loader will not work if you are restoring your own classes. Consider using for example `readBundle(getClass().getClassLoader())` instead."
+ errorLine1=" Bundle extras = in.readBundle();"
+ errorLine2=" ~~~~~~~~~~~~">
<location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="352"
- column="50"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level 31 (current min is 29): `android.media.metrics.LogSessionId#LOG_SESSION_ID_NONE`"
- errorLine1=" @NonNull private LogSessionId mLogSessionId = LogSessionId.LOG_SESSION_ID_NONE;"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="1071"
- column="51"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Cast from `SeekableInputReader` to `InputReader` requires API level 30 (current min is 29)"
- errorLine1=" mExoDataReader.mInputReader = seekableInputReader;"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="1201"
- column="39"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
- errorLine1=" mPendingSeekPosition = seekPoint.position;"
- errorLine2=" ~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="1287"
- column="36"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
- errorLine1=" mPendingSeekTimeMicros = seekPoint.timeMicros;"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="1288"
- column="38"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#position`"
- errorLine1=" mExtractor.seek(seekPoint.position, seekPoint.timeMicros);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="1290"
- column="29"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.MediaParser.SeekPoint#timeMicros`"
- errorLine1=" mExtractor.seek(seekPoint.position, seekPoint.timeMicros);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="1290"
- column="49"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Field requires API level R (current min is 29): `android.media.DrmInitData.SchemeInitData#uuid`"
- errorLine1=" if (schemeInitData.uuid.equals(schemeUuid)) {"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="1579"
- column="21"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`"
- errorLine1=" private static final class DataReaderAdapter implements InputReader {"
- errorLine2=" ~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="1872"
- column="61"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Class requires API level R (current min is 29): `android.media.MediaParser.InputReader`"
- errorLine1=" private static final class ParsableByteArrayAdapter implements InputReader {"
- errorLine2=" ~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/framework/java/android/media/MediaParser.java"
- line="1905"
- column="68"/>
+ file="frameworks/base/apex/media/framework/java/android/media/Session2Token.java"
+ line="144"
+ column="28"/>
</issue>
</issues>
diff --git a/apex/media/service/Android.bp b/apex/media/service/Android.bp
index cf384ac..2714809 100644
--- a/apex/media/service/Android.bp
+++ b/apex/media/service/Android.bp
@@ -39,6 +39,7 @@
":service-media-s-sources",
],
libs: [
+ "androidx.annotation_annotation",
"updatable-media",
"modules-annotation-minsdk",
"modules-utils-build",
diff --git a/apex/media/service/java/com/android/server/media/MediaCommunicationService.java b/apex/media/service/java/com/android/server/media/MediaCommunicationService.java
index 7d47e25..4223fa6 100644
--- a/apex/media/service/java/com/android/server/media/MediaCommunicationService.java
+++ b/apex/media/service/java/com/android/server/media/MediaCommunicationService.java
@@ -46,6 +46,8 @@
import android.util.SparseIntArray;
import android.view.KeyEvent;
+import androidx.annotation.RequiresApi;
+
import com.android.internal.annotations.GuardedBy;
import com.android.modules.annotation.MinSdk;
import com.android.server.SystemService;
@@ -63,6 +65,7 @@
* @hide
*/
@MinSdk(Build.VERSION_CODES.S)
+@RequiresApi(Build.VERSION_CODES.S)
public class MediaCommunicationService extends SystemService {
private static final String TAG = "MediaCommunicationSrv";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
diff --git a/apex/media/service/java/com/android/server/media/SessionPriorityList.java b/apex/media/service/java/com/android/server/media/SessionPriorityList.java
index 47b14b6..8145861 100644
--- a/apex/media/service/java/com/android/server/media/SessionPriorityList.java
+++ b/apex/media/service/java/com/android/server/media/SessionPriorityList.java
@@ -18,9 +18,13 @@
import android.annotation.Nullable;
import android.media.Session2Token;
+import android.os.Build;
import android.util.Log;
+import androidx.annotation.RequiresApi;
+
import com.android.internal.annotations.GuardedBy;
+import com.android.modules.annotation.MinSdk;
import com.android.server.media.MediaCommunicationService.Session2Record;
import java.util.ArrayList;
@@ -33,6 +37,8 @@
* Higher priority session has more chance to be selected as media button session,
* which receives the media button events.
*/
+@MinSdk(Build.VERSION_CODES.S)
+@RequiresApi(Build.VERSION_CODES.S)
class SessionPriorityList {
private static final String TAG = "SessionPriorityList";
private final Object mLock = new Object();
diff --git a/apex/media/service/lint-baseline.xml b/apex/media/service/lint-baseline.xml
index 05ce17c..def6baf 100644
--- a/apex/media/service/lint-baseline.xml
+++ b/apex/media/service/lint-baseline.xml
@@ -1,37 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
-<issues format="6" by="lint 7.1.0-dev" type="baseline" client="" dependencies="true" name="" variant="all" version="7.1.0-dev">
-
- <issue
- id="NewApi"
- message="Call requires API level S (current min is 29): `MediaParceledListSlice`"
- errorLine1=" new MediaParceledListSlice<>(getSession2TokensLocked(ALL.getIdentifier()));"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/service/java/com/android/server/media/MediaCommunicationService.java"
- line="242"
- column="21"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level S (current min is 29): `MediaParceledListSlice`"
- errorLine1=" userSession2Tokens = new MediaParceledListSlice<>(getSession2TokensLocked(userId));"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/service/java/com/android/server/media/MediaCommunicationService.java"
- line="243"
- column="34"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level S (current min is 29): `MediaParceledListSlice`"
- errorLine1=" MediaParceledListSlice parceledListSlice = new MediaParceledListSlice<>(result);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/base/apex/media/service/java/com/android/server/media/MediaCommunicationService.java"
- line="386"
- column="60"/>
- </issue>
+<issues format="6" by="lint 7.2.0-dev" type="baseline" client="" dependencies="true" name="" variant="all" version="7.2.0-dev">
</issues>
diff --git a/api/Android.bp b/api/Android.bp
index 3075d38..d57f5db 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -116,7 +116,6 @@
"framework-graphics",
"framework-media",
"framework-mediaprovider",
- "framework-nearby",
"framework-permission",
"framework-permission-s",
"framework-scheduling",
diff --git a/boot/Android.bp b/boot/Android.bp
index 8958d70..55ffe7c 100644
--- a/boot/Android.bp
+++ b/boot/Android.bp
@@ -80,10 +80,6 @@
module: "com.android.mediaprovider-bootclasspath-fragment",
},
{
- apex: "com.android.nearby",
- module: "com.android.nearby-bootclasspath-fragment",
- },
- {
apex: "com.android.os.statsd",
module: "com.android.os.statsd-bootclasspath-fragment",
},
diff --git a/core/api/current.txt b/core/api/current.txt
index f026116..19830c3 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -135,9 +135,6 @@
field public static final String READ_HOME_APP_SEARCH_DATA = "android.permission.READ_HOME_APP_SEARCH_DATA";
field @Deprecated public static final String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
field public static final String READ_LOGS = "android.permission.READ_LOGS";
- field public static final String READ_MEDIA_AUDIO = "android.permission.READ_MEDIA_AUDIO";
- field public static final String READ_MEDIA_IMAGE = "android.permission.READ_MEDIA_IMAGE";
- field public static final String READ_MEDIA_VIDEO = "android.permission.READ_MEDIA_VIDEO";
field public static final String READ_NEARBY_STREAMING_POLICY = "android.permission.READ_NEARBY_STREAMING_POLICY";
field public static final String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS";
field public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
@@ -223,8 +220,6 @@
field public static final String NEARBY_DEVICES = "android.permission-group.NEARBY_DEVICES";
field public static final String NOTIFICATIONS = "android.permission-group.NOTIFICATIONS";
field public static final String PHONE = "android.permission-group.PHONE";
- field public static final String READ_MEDIA_AURAL = "android.permission-group.READ_MEDIA_AURAL";
- field public static final String READ_MEDIA_VISUAL = "android.permission-group.READ_MEDIA_VISUAL";
field public static final String SENSORS = "android.permission-group.SENSORS";
field public static final String SMS = "android.permission-group.SMS";
field public static final String STORAGE = "android.permission-group.STORAGE";
@@ -12225,7 +12220,7 @@
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.SharedLibraryInfo> CREATOR;
field public static final int TYPE_BUILTIN = 0; // 0x0
field public static final int TYPE_DYNAMIC = 1; // 0x1
- field public static final int TYPE_SDK = 3; // 0x3
+ field public static final int TYPE_SDK_PACKAGE = 3; // 0x3
field public static final int TYPE_STATIC = 2; // 0x2
field public static final int VERSION_UNDEFINED = -1; // 0xffffffff
}
@@ -13988,6 +13983,7 @@
enum_constant @Deprecated public static final android.graphics.Bitmap.Config ARGB_4444;
enum_constant public static final android.graphics.Bitmap.Config ARGB_8888;
enum_constant public static final android.graphics.Bitmap.Config HARDWARE;
+ enum_constant public static final android.graphics.Bitmap.Config RGBA_1010102;
enum_constant public static final android.graphics.Bitmap.Config RGBA_F16;
enum_constant public static final android.graphics.Bitmap.Config RGB_565;
}
@@ -22727,6 +22723,7 @@
method public int describeContents();
method @Nullable public String getClientPackageName();
method public int getConnectionState();
+ method @NonNull public java.util.Set<java.lang.String> getDeduplicationIds();
method @Nullable public CharSequence getDescription();
method @Nullable public android.os.Bundle getExtras();
method @NonNull public java.util.List<java.lang.String> getFeatures();
@@ -22760,6 +22757,7 @@
method @NonNull public android.media.MediaRoute2Info.Builder clearFeatures();
method @NonNull public android.media.MediaRoute2Info.Builder setClientPackageName(@Nullable String);
method @NonNull public android.media.MediaRoute2Info.Builder setConnectionState(int);
+ method @NonNull public android.media.MediaRoute2Info.Builder setDeduplicationIds(@NonNull java.util.Set<java.lang.String>);
method @NonNull public android.media.MediaRoute2Info.Builder setDescription(@Nullable CharSequence);
method @NonNull public android.media.MediaRoute2Info.Builder setExtras(@Nullable android.os.Bundle);
method @NonNull public android.media.MediaRoute2Info.Builder setIconUri(@Nullable android.net.Uri);
@@ -23286,8 +23284,12 @@
public final class RouteDiscoveryPreference implements android.os.Parcelable {
method public int describeContents();
+ method @NonNull public java.util.List<java.lang.String> getAllowedPackages();
+ method @NonNull public java.util.List<java.lang.String> getDeduplicationPackageOrder();
method @NonNull public java.util.List<java.lang.String> getPreferredFeatures();
+ method @NonNull public java.util.List<java.lang.String> getRequiredFeatures();
method public boolean shouldPerformActiveScan();
+ method public boolean shouldRemoveDuplicates();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.media.RouteDiscoveryPreference> CREATOR;
}
@@ -23296,7 +23298,10 @@
ctor public RouteDiscoveryPreference.Builder(@NonNull java.util.List<java.lang.String>, boolean);
ctor public RouteDiscoveryPreference.Builder(@NonNull android.media.RouteDiscoveryPreference);
method @NonNull public android.media.RouteDiscoveryPreference build();
+ method @NonNull public android.media.RouteDiscoveryPreference.Builder setAllowedPackages(@NonNull java.util.List<java.lang.String>);
+ method @NonNull public android.media.RouteDiscoveryPreference.Builder setDeduplicationPackageOrder(@Nullable java.util.List<java.lang.String>);
method @NonNull public android.media.RouteDiscoveryPreference.Builder setPreferredFeatures(@NonNull java.util.List<java.lang.String>);
+ method @NonNull public android.media.RouteDiscoveryPreference.Builder setRequiredFeatures(@NonNull java.util.List<java.lang.String>);
method @NonNull public android.media.RouteDiscoveryPreference.Builder setShouldPerformActiveScan(boolean);
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 6a50670..90432fa 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -166,6 +166,7 @@
field public static final String MANAGE_DEBUGGING = "android.permission.MANAGE_DEBUGGING";
field public static final String MANAGE_DEVICE_ADMINS = "android.permission.MANAGE_DEVICE_ADMINS";
field public static final String MANAGE_FACTORY_RESET_PROTECTION = "android.permission.MANAGE_FACTORY_RESET_PROTECTION";
+ field public static final String MANAGE_GAME_ACTIVITY = "android.permission.MANAGE_GAME_ACTIVITY";
field public static final String MANAGE_GAME_MODE = "android.permission.MANAGE_GAME_MODE";
field public static final String MANAGE_HOTWORD_DETECTION = "android.permission.MANAGE_HOTWORD_DETECTION";
field public static final String MANAGE_IPSEC_TUNNELS = "android.permission.MANAGE_IPSEC_TUNNELS";
@@ -303,6 +304,7 @@
field public static final String SET_POINTER_SPEED = "android.permission.SET_POINTER_SPEED";
field public static final String SET_SCREEN_COMPATIBILITY = "android.permission.SET_SCREEN_COMPATIBILITY";
field public static final String SET_SYSTEM_AUDIO_CAPTION = "android.permission.SET_SYSTEM_AUDIO_CAPTION";
+ field public static final String SET_UNRESTRICTED_KEEP_CLEAR_AREAS = "android.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS";
field public static final String SET_VOLUME_KEY_LONG_PRESS_LISTENER = "android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER";
field public static final String SET_WALLPAPER_COMPONENT = "android.permission.SET_WALLPAPER_COMPONENT";
field public static final String SET_WALLPAPER_DIM_AMOUNT = "android.permission.SET_WALLPAPER_DIM_AMOUNT";
@@ -5873,6 +5875,7 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterAudioPolicyAsync(@NonNull android.media.audiopolicy.AudioPolicy);
method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void unregisterMuteAwaitConnectionCallback(@NonNull android.media.AudioManager.MuteAwaitConnectionCallback);
method public void unregisterVolumeGroupCallback(@NonNull android.media.AudioManager.VolumeGroupCallback);
+ field public static final String ACTION_VOLUME_CHANGED = "android.media.VOLUME_CHANGED_ACTION";
field public static final int AUDIOFOCUS_FLAG_DELAY_OK = 1; // 0x1
field public static final int AUDIOFOCUS_FLAG_LOCK = 4; // 0x4
field public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 2; // 0x2
@@ -5881,7 +5884,11 @@
field public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2; // 0x2
field public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1; // 0x1
field public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0; // 0x0
+ field public static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE";
+ field public static final String EXTRA_VOLUME_STREAM_VALUE = "android.media.EXTRA_VOLUME_STREAM_VALUE";
+ field public static final int FLAG_BLUETOOTH_ABS_VOLUME = 64; // 0x40
field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int STREAM_ASSISTANT = 11; // 0xb
+ field public static final int STREAM_BLUETOOTH_SCO = 6; // 0x6
field public static final int SUCCESS = 0; // 0x0
}
@@ -11055,7 +11062,7 @@
method public void onCreate();
method public void onDestroy();
method public void onGameTaskFocusChanged(boolean);
- method @RequiresPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) public final boolean restartGame();
+ method @RequiresPermission(android.Manifest.permission.MANAGE_GAME_ACTIVITY) public final boolean restartGame();
method public void setTaskOverlayView(@NonNull android.view.View, @NonNull android.view.ViewGroup.LayoutParams);
method public void takeScreenshot(@NonNull java.util.concurrent.Executor, @NonNull android.service.games.GameSession.ScreenshotCallback);
}
@@ -11850,6 +11857,7 @@
public abstract class ConnectionService extends android.app.Service {
method public final void addExistingConnection(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.Connection, @NonNull android.telecom.Conference);
+ method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telecom.Connection onCreateUnknownConnection(@NonNull android.telecom.PhoneAccountHandle, @NonNull android.telecom.ConnectionRequest);
}
public abstract class InCallService extends android.app.Service {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index c39394b..15148a9 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1104,7 +1104,7 @@
package android.hardware.devicestate {
public final class DeviceStateManager {
- method @RequiresPermission(value=android.Manifest.permission.CONTROL_DEVICE_STATE, conditional=true) public void cancelRequest(@NonNull android.hardware.devicestate.DeviceStateRequest);
+ method @RequiresPermission(value=android.Manifest.permission.CONTROL_DEVICE_STATE, conditional=true) public void cancelStateRequest();
method @NonNull public int[] getSupportedStates();
method public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.devicestate.DeviceStateManager.DeviceStateCallback);
method @RequiresPermission(value=android.Manifest.permission.CONTROL_DEVICE_STATE, conditional=true) public void requestState(@NonNull android.hardware.devicestate.DeviceStateRequest, @Nullable java.util.concurrent.Executor, @Nullable android.hardware.devicestate.DeviceStateRequest.Callback);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 876e401..3289304 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1005,6 +1005,11 @@
RemoteCallback finishCallback;
}
+ static final class DumpResourcesData {
+ public ParcelFileDescriptor fd;
+ public RemoteCallback finishCallback;
+ }
+
static final class UpdateCompatibilityData {
String pkg;
CompatibilityInfo info;
@@ -1316,6 +1321,20 @@
sendMessage(H.SCHEDULE_CRASH, args, typeId);
}
+ @Override
+ public void dumpResources(ParcelFileDescriptor fd, RemoteCallback callback) {
+ DumpResourcesData data = new DumpResourcesData();
+ try {
+ data.fd = fd.dup();
+ data.finishCallback = callback;
+ sendMessage(H.DUMP_RESOURCES, data, 0, 0, false /*async*/);
+ } catch (IOException e) {
+ Slog.w(TAG, "dumpResources failed", e);
+ } finally {
+ IoUtils.closeQuietly(fd);
+ }
+ }
+
public void dumpActivity(ParcelFileDescriptor pfd, IBinder activitytoken,
String prefix, String[] args) {
DumpComponentInfo data = new DumpComponentInfo();
@@ -2039,6 +2058,7 @@
public static final int UPDATE_UI_TRANSLATION_STATE = 163;
public static final int SET_CONTENT_CAPTURE_OPTIONS_CALLBACK = 164;
public static final int DUMP_GFXINFO = 165;
+ public static final int DUMP_RESOURCES = 166;
public static final int INSTRUMENT_WITHOUT_RESTART = 170;
public static final int FINISH_INSTRUMENTATION_WITHOUT_RESTART = 171;
@@ -2092,6 +2112,7 @@
case INSTRUMENT_WITHOUT_RESTART: return "INSTRUMENT_WITHOUT_RESTART";
case FINISH_INSTRUMENTATION_WITHOUT_RESTART:
return "FINISH_INSTRUMENTATION_WITHOUT_RESTART";
+ case DUMP_RESOURCES: return "DUMP_RESOURCES";
}
}
return Integer.toString(code);
@@ -2207,6 +2228,9 @@
case DUMP_HEAP:
handleDumpHeap((DumpHeapData) msg.obj);
break;
+ case DUMP_RESOURCES:
+ handleDumpResources((DumpResourcesData) msg.obj);
+ break;
case DUMP_ACTIVITY:
handleDumpActivity((DumpComponentInfo)msg.obj);
break;
@@ -4585,6 +4609,23 @@
}
}
+ private void handleDumpResources(DumpResourcesData info) {
+ final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
+ try {
+ PrintWriter pw = new FastPrintWriter(new FileOutputStream(
+ info.fd.getFileDescriptor()));
+
+ Resources.dumpHistory(pw, "");
+ pw.flush();
+ if (info.finishCallback != null) {
+ info.finishCallback.sendResult(null);
+ }
+ } finally {
+ IoUtils.closeQuietly(info.fd);
+ StrictMode.setThreadPolicy(oldPolicy);
+ }
+ }
+
private void handleDumpActivity(DumpComponentInfo info) {
final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
try {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 0d1bc05..fdf37f6 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2363,11 +2363,11 @@
Manifest.permission.USE_BIOMETRIC,
Manifest.permission.ACTIVITY_RECOGNITION,
Manifest.permission.SMS_FINANCIAL_TRANSACTIONS,
- Manifest.permission.READ_MEDIA_AUDIO,
+ null,
null, // no permission for OP_WRITE_MEDIA_AUDIO
- Manifest.permission.READ_MEDIA_VIDEO,
+ null,
null, // no permission for OP_WRITE_MEDIA_VIDEO
- Manifest.permission.READ_MEDIA_IMAGE,
+ null,
null, // no permission for OP_WRITE_MEDIA_IMAGES
null, // no permission for OP_LEGACY_STORAGE
null, // no permission for OP_ACCESS_ACCESSIBILITY
diff --git a/core/java/android/app/AsyncNotedAppOp.java b/core/java/android/app/AsyncNotedAppOp.java
index db58c21..7845b6a 100644
--- a/core/java/android/app/AsyncNotedAppOp.java
+++ b/core/java/android/app/AsyncNotedAppOp.java
@@ -37,7 +37,8 @@
@Immutable
@DataClass(genEqualsHashCode = true,
genAidl = true,
- genHiddenConstructor = true)
+ genHiddenConstructor = true,
+ genToString = true)
// - We don't expose the opCode, but rather the public name of the op, hence use a non-standard
// getter
@DataClass.Suppress({"getOpCode"})
@@ -70,9 +71,13 @@
Preconditions.checkArgumentInRange(mOpCode, 0, AppOpsManager._NUM_OP - 1, "opCode");
}
+ private String opCodeToString() {
+ return getOp();
+ }
- // Code below generated by codegen v1.0.20.
+
+ // Code below generated by codegen v1.0.23.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -160,6 +165,21 @@
@Override
@DataClass.Generated.Member
+ public String toString() {
+ // You can override field toString logic by defining methods like:
+ // String fieldNameToString() { ... }
+
+ return "AsyncNotedAppOp { " +
+ "opCode = " + opCodeToString() + ", " +
+ "notingUid = " + mNotingUid + ", " +
+ "attributionTag = " + mAttributionTag + ", " +
+ "message = " + mMessage + ", " +
+ "time = " + mTime +
+ " }";
+ }
+
+ @Override
+ @DataClass.Generated.Member
public boolean equals(@Nullable Object o) {
// You can override field equality logic by defining either of the methods like:
// boolean fieldNameEquals(AsyncNotedAppOp other) { ... }
@@ -261,10 +281,10 @@
};
@DataClass.Generated(
- time = 1604456255752L,
- codegenVersion = "1.0.20",
+ time = 1643320606160L,
+ codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/app/AsyncNotedAppOp.java",
- inputSignatures = "private final @android.annotation.IntRange int mOpCode\nprivate final @android.annotation.IntRange int mNotingUid\nprivate final @android.annotation.Nullable java.lang.String mAttributionTag\nprivate final @android.annotation.NonNull java.lang.String mMessage\nprivate final @android.annotation.CurrentTimeMillisLong long mTime\npublic @android.annotation.NonNull java.lang.String getOp()\nprivate void onConstructed()\nclass AsyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genAidl=true, genHiddenConstructor=true)")
+ inputSignatures = "private final @android.annotation.IntRange int mOpCode\nprivate final @android.annotation.IntRange int mNotingUid\nprivate final @android.annotation.Nullable java.lang.String mAttributionTag\nprivate final @android.annotation.NonNull java.lang.String mMessage\nprivate final @android.annotation.CurrentTimeMillisLong long mTime\npublic @android.annotation.NonNull java.lang.String getOp()\nprivate void onConstructed()\nprivate java.lang.String opCodeToString()\nclass AsyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genAidl=true, genHiddenConstructor=true, genToString=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 1714229..77657d5 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -113,6 +113,7 @@
in ParcelFileDescriptor fd, in RemoteCallback finishCallback);
void dumpActivity(in ParcelFileDescriptor fd, IBinder servicetoken, in String prefix,
in String[] args);
+ void dumpResources(in ParcelFileDescriptor fd, in RemoteCallback finishCallback);
void clearDnsCache();
void updateHttpProxy();
void setCoreSettings(in Bundle coreSettings);
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 14afd0f..5d1f4df 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -746,7 +746,7 @@
if (!hasPermission(Manifest.permission.SET_INITIAL_LOCK)) {
throw new SecurityException("Requires SET_INITIAL_LOCK permission.");
}
- return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+ return true;
}
private boolean hasPermission(String permission) {
@@ -814,6 +814,8 @@
/**
* Set the lockscreen password after validating against its expected complexity level.
*
+ * Below {@link android.os.Build.VERSION_CODES#S_V2}, this API will only work
+ * when {@link PackageManager.FEATURE_AUTOMOTIVE} is present.
* @param lockType - type of lock as specified in {@link LockTypes}
* @param password - password to validate; this has the same encoding
* as the output of String#getBytes
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 4e32e9a..56c725e 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -746,6 +746,10 @@
// default linker namespace.
continue;
}
+ if (info.isSdk()) {
+ // SDKs are not loaded automatically.
+ continue;
+ }
if (libsToLoadAfter.contains(info.getName())) {
if (DEBUG) {
Slog.v(ActivityThread.TAG,
diff --git a/core/java/android/app/SyncNotedAppOp.java b/core/java/android/app/SyncNotedAppOp.java
index 7c0c08a..f156b30 100644
--- a/core/java/android/app/SyncNotedAppOp.java
+++ b/core/java/android/app/SyncNotedAppOp.java
@@ -40,7 +40,8 @@
@DataClass(
genEqualsHashCode = true,
genAidl = true,
- genConstructor = false
+ genConstructor = false,
+ genToString = true
)
@DataClass.Suppress({"getOpCode", "getOpMode"})
public final class SyncNotedAppOp implements Parcelable {
@@ -118,6 +119,10 @@
return mOpMode;
}
+ private String opCodeToString() {
+ return getOp();
+ }
+
// Code below generated by codegen v1.0.23.
@@ -153,6 +158,20 @@
@Override
@DataClass.Generated.Member
+ public String toString() {
+ // You can override field toString logic by defining methods like:
+ // String fieldNameToString() { ... }
+
+ return "SyncNotedAppOp { " +
+ "opMode = " + mOpMode + ", " +
+ "opCode = " + opCodeToString() + ", " +
+ "attributionTag = " + mAttributionTag + ", " +
+ "packageName = " + mPackageName +
+ " }";
+ }
+
+ @Override
+ @DataClass.Generated.Member
public boolean equals(@Nullable Object o) {
// You can override field equality logic by defining either of the methods like:
// boolean fieldNameEquals(SyncNotedAppOp other) { ... }
@@ -245,10 +264,10 @@
};
@DataClass.Generated(
- time = 1619711733947L,
+ time = 1643320427700L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/app/SyncNotedAppOp.java",
- inputSignatures = "private final int mOpMode\nprivate final @android.annotation.IntRange int mOpCode\nprivate final @android.annotation.Nullable java.lang.String mAttributionTag\nprivate final @android.annotation.NonNull java.lang.String mPackageName\npublic @android.annotation.NonNull java.lang.String getOp()\npublic int getOpMode()\nclass SyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genAidl=true, genConstructor=false)")
+ inputSignatures = "private final int mOpMode\nprivate final @android.annotation.IntRange int mOpCode\nprivate final @android.annotation.Nullable java.lang.String mAttributionTag\nprivate final @android.annotation.NonNull java.lang.String mPackageName\npublic @android.annotation.NonNull java.lang.String getOp()\npublic int getOpMode()\nprivate java.lang.String opCodeToString()\nclass SyncNotedAppOp extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genAidl=true, genConstructor=false, genToString=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 18f9379..3d2c03d 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -214,6 +214,12 @@
public boolean topActivityInSizeCompat;
/**
+ * Whether the direct top activity is eligible for letterbox education.
+ * @hide
+ */
+ public boolean topActivityEligibleForLetterboxEducation;
+
+ /**
* Whether this task is resizable. Unlike {@link #resizeMode} (which is what the top activity
* supports), this is what the system actually uses for resizability based on other policy and
* developer options.
@@ -398,7 +404,8 @@
/** @hide */
public boolean hasCompatUI() {
- return hasCameraCompatControl() || topActivityInSizeCompat;
+ return hasCameraCompatControl() || topActivityInSizeCompat
+ || topActivityEligibleForLetterboxEducation;
}
/**
@@ -460,6 +467,8 @@
return displayId == that.displayId
&& taskId == that.taskId
&& topActivityInSizeCompat == that.topActivityInSizeCompat
+ && topActivityEligibleForLetterboxEducation
+ == that.topActivityEligibleForLetterboxEducation
&& cameraCompatControlState == that.cameraCompatControlState
// Bounds are important if top activity has compat controls.
&& (!hasCompatUI() || configuration.windowConfiguration.getBounds()
@@ -507,6 +516,7 @@
isVisible = source.readBoolean();
isSleeping = source.readBoolean();
topActivityInSizeCompat = source.readBoolean();
+ topActivityEligibleForLetterboxEducation = source.readBoolean();
mTopActivityLocusId = source.readTypedObject(LocusId.CREATOR);
displayAreaFeatureId = source.readInt();
cameraCompatControlState = source.readInt();
@@ -551,6 +561,7 @@
dest.writeBoolean(isVisible);
dest.writeBoolean(isSleeping);
dest.writeBoolean(topActivityInSizeCompat);
+ dest.writeBoolean(topActivityEligibleForLetterboxEducation);
dest.writeTypedObject(mTopActivityLocusId, flags);
dest.writeInt(displayAreaFeatureId);
dest.writeInt(cameraCompatControlState);
@@ -585,6 +596,8 @@
+ " isVisible=" + isVisible
+ " isSleeping=" + isSleeping
+ " topActivityInSizeCompat=" + topActivityInSizeCompat
+ + " topActivityEligibleForLetterboxEducation= "
+ + topActivityEligibleForLetterboxEducation
+ " locusId=" + mTopActivityLocusId
+ " displayAreaFeatureId=" + displayAreaFeatureId
+ " cameraCompatControlState="
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 9ac4030..75a00af 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -14991,8 +14991,8 @@
* <p>Also returns the drawable from {@code defaultDrawableLoader} if
* {@link DevicePolicyResources.Drawables#UNDEFINED} was passed.
*
- * <p>{@code defaultDrawableLoader} must return a non {@code null} {@link Drawable}, otherwise a
- * {@link NullPointerException} is thrown.
+ * <p>Calls to this API will not return {@code null} unless no updated drawable was found
+ * and the call to {@code defaultDrawableLoader} returned {@code null}.
*
* <p>This API uses the screen density returned from {@link Resources#getConfiguration()}, to
* set a different value use
@@ -15025,8 +15025,8 @@
* {@link #getDrawable(String, String, Callable)}
* if an override was set for that specific source.
*
- * <p>{@code defaultDrawableLoader} must return a non {@code null} {@link Drawable}, otherwise a
- * {@link NullPointerException} is thrown.
+ * <p>Calls to this API will not return {@code null} unless no updated drawable was found
+ * and the call to {@code defaultDrawableLoader} returned {@code null}.
*
* <p>Callers should register for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to get
* notified when a resource has been updated.
@@ -15080,8 +15080,8 @@
* Similar to {@link #getDrawable(String, String, Callable)}, but also accepts
* {@code density}. See {@link Resources#getDrawableForDensity(int, int, Resources.Theme)}.
*
- * <p>{@code defaultDrawableLoader} must return a non {@code null} {@link Drawable}, otherwise a
- * {@link NullPointerException} is thrown.
+ * <p>Calls to this API will not return {@code null} unless no updated drawable was found
+ * and the call to {@code defaultDrawableLoader} returned {@code null}.
*
* <p>Callers should register for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to get
* notified when a resource has been updated.
@@ -15112,8 +15112,8 @@
* Similar to {@link #getDrawable(String, String, String, Callable)}, but also accepts
* {@code density}. See {@link Resources#getDrawableForDensity(int, int, Resources.Theme)}.
*
- * <p>{@code defaultDrawableLoader} must return a non {@code null} {@link Drawable}, otherwise a
- * {@link NullPointerException} is thrown.
+ * <p>Calls to this API will not return {@code null} unless no updated drawable was found
+ * and the call to {@code defaultDrawableLoader} returned {@code null}.
*
* <p>Callers should register for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to get
* notified when a resource has been updated.
@@ -15166,7 +15166,7 @@
/**
* For each {@link DevicePolicyStringResource} item in {@code strings}, it updates the string
* resource for {@link DevicePolicyStringResource#getStringId()} to the string with ID
- * {@code callingPackageResourceId} (see {@link DevicePolicyResources.String}), meaning any
+ * {@code callingPackageResourceId} (see {@link DevicePolicyResources.Strings}), meaning any
* system UI surface calling {@link #getString} with {@code stringId} will get
* the new resource after this API is called.
*
@@ -15202,7 +15202,7 @@
/**
* Removes the updated strings for the list of {@code stringIds} (see
- * {@link DevicePolicyResources.String}) that was previously set by calling {@link #setStrings},
+ * {@link DevicePolicyResources.Strings}) that was previously set by calling {@link #setStrings},
* meaning any subsequent calls to {@link #getString} for the provided IDs will
* return the default string from {@code defaultStringLoader}.
*
@@ -15227,14 +15227,14 @@
/**
* Returns the appropriate updated string for the {@code stringId} (see
- * {@link DevicePolicyResources.String}) if one was set using
+ * {@link DevicePolicyResources.Strings}) if one was set using
* {@link #setStrings}, otherwise returns the string from {@code defaultStringLoader}.
*
* <p>Also returns the string from {@code defaultStringLoader} if
- * {@link DevicePolicyResources.String#INVALID_ID} was passed.
+ * {@link DevicePolicyResources.Strings#UNDEFINED} was passed.
*
- * <p>{@code defaultStringLoader} must return a non {@code null} {@link String}, otherwise a
- * {@link NullPointerException} is thrown.
+ * <p>Calls to this API will not return {@code null} unless no updated drawable was found
+ * and the call to {@code defaultStringLoader} returned {@code null}.
*
* <p>Callers should register for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to get
* notified when a resource has been updated.
@@ -15284,8 +15284,8 @@
* {@link java.util.Formatter} and {@link java.lang.String#format}, (see
* {@link Resources#getString(int, Object...)}).
*
- * <p>{@code defaultStringLoader} must return a non {@code null} {@link String}, otherwise a
- * {@link NullPointerException} is thrown.
+ * <p>Calls to this API will not return {@code null} unless no updated drawable was found
+ * and the call to {@code defaultStringLoader} returned {@code null}.
*
* @param stringId The IDs to get the updated resource for.
* @param defaultStringLoader To get the default string if no updated string was set for
diff --git a/core/java/android/app/admin/DevicePolicyResources.java b/core/java/android/app/admin/DevicePolicyResources.java
index 2ad2010..cf349b0 100644
--- a/core/java/android/app/admin/DevicePolicyResources.java
+++ b/core/java/android/app/admin/DevicePolicyResources.java
@@ -93,6 +93,167 @@
import static android.app.admin.DevicePolicyResources.Strings.MediaProvider.SWITCH_TO_PERSONAL_MESSAGE;
import static android.app.admin.DevicePolicyResources.Strings.MediaProvider.SWITCH_TO_WORK_MESSAGE;
import static android.app.admin.DevicePolicyResources.Strings.MediaProvider.WORK_PROFILE_PAUSED_MESSAGE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ACCESSIBILITY_CATEGORY_PERSONAL;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ACCESSIBILITY_CATEGORY_WORK;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ACCESSIBILITY_PERSONAL_ACCOUNT_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ACCESSIBILITY_WORK_ACCOUNT_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ACCOUNTS_SEARCH_KEYWORDS;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ACTIVATE_DEVICE_ADMIN_APP;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ACTIVATE_DEVICE_ADMIN_APP_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ACTIVATE_THIS_DEVICE_ADMIN_APP;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ACTIVE_DEVICE_ADMIN_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_ACTIONS_APPS_COUNT;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_ACTIONS_APPS_COUNT_MINIMUM;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_ACTION_ACCESS_CAMERA;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_ACTION_ACCESS_LOCATION;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_ACTION_ACCESS_MICROPHONE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_ACTION_APPS_COUNT_ESTIMATED;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_ACTION_APPS_INSTALLED;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_ACTION_NONE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_ACTION_SET_CURRENT_INPUT_METHOD;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_ACTION_SET_DEFAULT_APPS;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_ACTION_SET_HTTP_PROXY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_ACTION_SET_INPUT_METHOD_NAME;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_CAN_LOCK_DEVICE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_CAN_SEE_APPS_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_CAN_SEE_BUG_REPORT_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_CAN_SEE_SECURITY_LOGS_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_CAN_SEE_NETWORK_LOGS_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_CAN_SEE_USAGE_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_CAN_SEE_WORK_DATA_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_CAN_WIPE_DEVICE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_CONFIGURED_FAILED_PASSWORD_WIPE_DEVICE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ADMIN_CONFIGURED_FAILED_PASSWORD_WIPE_WORK_PROFILE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ALWAYS_ON_VPN_DEVICE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ALWAYS_ON_VPN_PERSONAL_PROFILE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ALWAYS_ON_VPN_WORK_PROFILE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.APP_CAN_ACCESS_PERSONAL_DATA;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.APP_CAN_ACCESS_PERSONAL_PERMISSIONS;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CA_CERTS_DEVICE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CA_CERTS_PERSONAL_PROFILE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CA_CERTS_WORK_PROFILE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CHANGES_MADE_BY_YOUR_ORGANIZATION_ADMIN_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CONFIRM_WORK_PROFILE_PASSWORD_HEADER;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CONFIRM_WORK_PROFILE_PATTERN_HEADER;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CONFIRM_WORK_PROFILE_PIN_HEADER;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CONNECTED_APPS_SEARCH_KEYWORDS;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CONNECTED_APPS_SHARE_PERMISSIONS_AND_DATA;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CONNECTED_WORK_AND_PERSONAL_APPS_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CONNECT_APPS_DIALOG_SUMMARY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CONNECT_APPS_DIALOG_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CONTACT_YOUR_IT_ADMIN;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CONTROLLED_BY_ADMIN_SUMMARY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CROSS_PROFILE_CALENDAR_SUMMARY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CROSS_PROFILE_CALENDAR_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.DEVICE_ADMIN_POLICIES_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.DEVICE_ADMIN_SETTINGS_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.DEVICE_MANAGED_WITHOUT_NAME;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.DEVICE_MANAGED_WITH_NAME;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.DEVICE_OWNER_INSTALLED_CERTIFICATE_AUTHORITY_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.DISABLED_BY_IT_ADMIN_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ENABLE_WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_DIALOG_MESSAGE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ENABLE_WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_DIALOG_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ENTERPRISE_PRIVACY_HEADER;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ERROR_MOVE_DEVICE_ADMIN;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.FACE_SETTINGS_FOR_WORK_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.FACE_UNLOCK_DISABLED;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.FINGERPRINT_FOR_WORK;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.FINGERPRINT_UNLOCK_DISABLED;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.FINGERPRINT_UNLOCK_DISABLED_EXPLANATION;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.FORGOT_PASSWORD_TEXT;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.FORGOT_PASSWORD_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.HOW_TO_DISCONNECT_APPS;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.INFORMATION_YOUR_ORGANIZATION_CAN_SEE_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.INSTALL_IN_PERSONAL_PROFILE_TO_CONNECT_PROMPT;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.INSTALL_IN_WORK_PROFILE_TO_CONNECT_PROMPT;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.IT_ADMIN_POLICY_DISABLING_INFO_URL;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.MANAGED_BY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.MANAGED_DEVICE_INFO;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.MANAGED_DEVICE_INFO_SUMMARY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.MANAGED_DEVICE_INFO_SUMMARY_WITH_NAME;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.MANAGED_PROFILE_SETTINGS_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.MANAGE_DEVICE_ADMIN_APPS;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.NEW_DEVICE_ADMIN_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.NEW_DEVICE_ADMIN_WARNING_SIMPLIFIED;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.NO_DEVICE_ADMINS;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.NUMBER_OF_DEVICE_ADMINS;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.NUMBER_OF_DEVICE_ADMINS_NONE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.ONLY_CONNECT_TRUSTED_APPS;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.OTHER_OPTIONS_DISABLED_BY_ADMIN;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.PASSWORD_RECENTLY_USED;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.PERSONAL_CATEGORY_HEADER;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.PERSONAL_PROFILE_APP_SUBTEXT;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.PIN_RECENTLY_USED;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.REENTER_WORK_PROFILE_PASSWORD_HEADER;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.REENTER_WORK_PROFILE_PIN_HEADER;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.REMOVE_ACCOUNT_FAILED_ADMIN_RESTRICTION;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.REMOVE_AND_UNINSTALL_DEVICE_ADMIN;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.REMOVE_DEVICE_ADMIN;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.REMOVE_WORK_PROFILE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.SELECT_DEVICE_ADMIN_APPS;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.SET_PROFILE_OWNER_DIALOG_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.SET_PROFILE_OWNER_POSTSETUP_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.SET_PROFILE_OWNER_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.SET_WORK_PROFILE_PASSWORD_HEADER;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.SET_WORK_PROFILE_PATTERN_HEADER;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.SET_WORK_PROFILE_PIN_HEADER;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.SHARE_REMOTE_BUGREPORT_DIALOG_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.SHARE_REMOTE_BUGREPORT_FINISHED_REQUEST_CONSENT;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.SHARE_REMOTE_BUGREPORT_NOT_FINISHED_REQUEST_CONSENT;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.SHARING_REMOTE_BUGREPORT_MESSAGE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.UNINSTALL_DEVICE_ADMIN;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.USER_ADMIN_POLICIES_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_APPS_CANNOT_ACCESS_NOTIFICATION_SETTINGS;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_CATEGORY_HEADER;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_ADMIN_POLICIES_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_ALARM_RINGTONE_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_APP_SUBTEXT;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_CONFIRM_PATTERN;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_CONFIRM_PIN;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_CONFIRM_REMOVE_MESSAGE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_CONFIRM_REMOVE_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_CONTACT_SEARCH_SUMMARY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_CONTACT_SEARCH_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_DISABLE_USAGE_ACCESS_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_FINGERPRINT_LAST_DELETE_MESSAGE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_INSTALLED_CERTIFICATE_AUTHORITY_WARNING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_IT_ADMIN_CANT_RESET_SCREEN_LOCK;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_KEYBOARDS_AND_TOOLS;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_LAST_PASSWORD_ATTEMPT_BEFORE_WIPE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_LAST_PATTERN_ATTEMPT_BEFORE_WIPE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_LAST_PIN_ATTEMPT_BEFORE_WIPE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_LOCATION_SWITCH_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_LOCKED_NOTIFICATION_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_LOCK_ATTEMPTS_FAILED;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_LOCK_SCREEN_REDACT_NOTIFICATION_SUMMARY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_LOCK_SCREEN_REDACT_NOTIFICATION_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_MANAGED_BY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_NOTIFICATIONS_SECTION_HEADER;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_NOTIFICATION_LISTENER_BLOCKED;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_NOTIFICATION_RINGTONE_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_NOT_AVAILABLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_OFF_CONDITION_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_PASSWORD_REQUIRED;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_PRIVACY_POLICY_INFO;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_PRIVACY_POLICY_INFO_SUMMARY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_RINGTONE_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SCREEN_LOCK_SETUP_MESSAGE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SECURITY_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SETTING;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SETTING_OFF_SUMMARY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SETTING_ON_SUMMARY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SET_UNLOCK_LAUNCH_PICKER_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SOUND_SETTINGS_SECTION_HEADER;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_ACTIVE_SUMMARY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_UNIFICATION_SEARCH_KEYWORDS;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_UNIFY_LOCKS_DETAIL;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_UNIFY_LOCKS_NONCOMPLIANT;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_UNIFY_LOCKS_SUMMARY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_UNIFY_LOCKS_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_USER_LABEL;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_USE_PERSONAL_SOUNDS_SUMMARY;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_USE_PERSONAL_SOUNDS_TITLE;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.YOUR_ACCESS_TO_THIS_DEVICE_TITLE;
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.BIOMETRIC_DIALOG_WORK_LOCK_FAILED_ATTEMPTS;
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.BIOMETRIC_DIALOG_WORK_PASSWORD_LAST_ATTEMPT;
import static android.app.admin.DevicePolicyResources.Strings.SystemUi.BIOMETRIC_DIALOG_WORK_PATTERN_LAST_ATTEMPT;
@@ -159,7 +320,8 @@
Drawables.WORK_PROFILE_OFF_ICON,
Drawables.WORK_PROFILE_USER_ICON
})
- public @interface UpdatableDrawableId {}
+ public @interface UpdatableDrawableId {
+ }
/**
* Identifiers to specify the desired style for the updatable device management system
@@ -174,7 +336,8 @@
Drawables.Style.OUTLINE,
Drawables.Style.DEFAULT
})
- public @interface UpdatableDrawableStyle {}
+ public @interface UpdatableDrawableStyle {
+ }
/**
* Identifiers to specify the location if the updatable device management system resource.
@@ -191,7 +354,8 @@
Drawables.Source.QUICK_SETTINGS,
Drawables.Source.STATUS_BAR
})
- public @interface UpdatableDrawableSource {}
+ public @interface UpdatableDrawableSource {
+ }
/**
* Resource identifiers used to update device management-related string resources.
@@ -231,7 +395,7 @@
PERSONAL_APP_SUSPENSION_TITLE, PERSONAL_APP_SUSPENSION_MESSAGE,
PERSONAL_APP_SUSPENSION_SOON_MESSAGE, PERSONAL_APP_SUSPENSION_TURN_ON_PROFILE,
PRINTING_DISABLED_NAMED_ADMIN, LOCATION_CHANGED_TITLE, LOCATION_CHANGED_MESSAGE,
- NETWORK_LOGGING_TITLE, NETWORK_LOGGING_MESSAGE,
+ NETWORK_LOGGING_TITLE, NETWORK_LOGGING_MESSAGE,
NOTIFICATION_WORK_PROFILE_CONTENT_DESCRIPTION, NOTIFICATION_CHANNEL_DEVICE_ADMIN,
SWITCH_TO_WORK_LABEL, SWITCH_TO_PERSONAL_LABEL, FORWARD_INTENT_TO_WORK,
FORWARD_INTENT_TO_PERSONAL, RESOLVER_WORK_PROFILE_NOT_SUPPORTED, RESOLVER_PERSONAL_TAB,
@@ -257,7 +421,86 @@
SWITCH_TO_WORK_MESSAGE, SWITCH_TO_PERSONAL_MESSAGE, BLOCKED_BY_ADMIN_TITLE,
BLOCKED_FROM_PERSONAL_MESSAGE, BLOCKED_FROM_PERSONAL_MESSAGE,
BLOCKED_FROM_WORK_MESSAGE, Strings.MediaProvider.WORK_PROFILE_PAUSED_TITLE,
- WORK_PROFILE_PAUSED_MESSAGE
+ WORK_PROFILE_PAUSED_MESSAGE,
+
+ // Settings Strings
+ FACE_SETTINGS_FOR_WORK_TITLE, WORK_PROFILE_FINGERPRINT_LAST_DELETE_MESSAGE,
+ WORK_PROFILE_IT_ADMIN_CANT_RESET_SCREEN_LOCK, WORK_PROFILE_SCREEN_LOCK_SETUP_MESSAGE,
+ WORK_PROFILE_SET_UNLOCK_LAUNCH_PICKER_TITLE,
+ WORK_PROFILE_LAST_PATTERN_ATTEMPT_BEFORE_WIPE,
+ WORK_PROFILE_LAST_PIN_ATTEMPT_BEFORE_WIPE,
+ WORK_PROFILE_LAST_PASSWORD_ATTEMPT_BEFORE_WIPE, WORK_PROFILE_LOCK_ATTEMPTS_FAILED,
+ ACCESSIBILITY_CATEGORY_WORK, ACCESSIBILITY_CATEGORY_PERSONAL,
+ ACCESSIBILITY_WORK_ACCOUNT_TITLE, ACCESSIBILITY_PERSONAL_ACCOUNT_TITLE,
+ WORK_PROFILE_LOCATION_SWITCH_TITLE, SET_WORK_PROFILE_PASSWORD_HEADER,
+ SET_WORK_PROFILE_PIN_HEADER, SET_WORK_PROFILE_PATTERN_HEADER,
+ CONFIRM_WORK_PROFILE_PASSWORD_HEADER, CONFIRM_WORK_PROFILE_PIN_HEADER,
+ CONFIRM_WORK_PROFILE_PATTERN_HEADER, REENTER_WORK_PROFILE_PASSWORD_HEADER,
+ REENTER_WORK_PROFILE_PIN_HEADER, WORK_PROFILE_CONFIRM_PATTERN, WORK_PROFILE_CONFIRM_PIN,
+ WORK_PROFILE_PASSWORD_REQUIRED, WORK_PROFILE_SECURITY_TITLE,
+ WORK_PROFILE_UNIFY_LOCKS_TITLE, WORK_PROFILE_UNIFY_LOCKS_SUMMARY,
+ WORK_PROFILE_UNIFY_LOCKS_DETAIL, WORK_PROFILE_UNIFY_LOCKS_NONCOMPLIANT,
+ WORK_PROFILE_KEYBOARDS_AND_TOOLS, WORK_PROFILE_NOT_AVAILABLE, WORK_PROFILE_SETTING,
+ WORK_PROFILE_SETTING_ON_SUMMARY, WORK_PROFILE_SETTING_OFF_SUMMARY, REMOVE_WORK_PROFILE,
+ DEVICE_OWNER_INSTALLED_CERTIFICATE_AUTHORITY_WARNING,
+ WORK_PROFILE_INSTALLED_CERTIFICATE_AUTHORITY_WARNING, WORK_PROFILE_CONFIRM_REMOVE_TITLE,
+ WORK_PROFILE_CONFIRM_REMOVE_MESSAGE, WORK_APPS_CANNOT_ACCESS_NOTIFICATION_SETTINGS,
+ WORK_PROFILE_SOUND_SETTINGS_SECTION_HEADER, WORK_PROFILE_USE_PERSONAL_SOUNDS_TITLE,
+ WORK_PROFILE_USE_PERSONAL_SOUNDS_SUMMARY, WORK_PROFILE_RINGTONE_TITLE,
+ WORK_PROFILE_NOTIFICATION_RINGTONE_TITLE, WORK_PROFILE_ALARM_RINGTONE_TITLE,
+ WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_ACTIVE_SUMMARY,
+ ENABLE_WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_DIALOG_TITLE,
+ ENABLE_WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_DIALOG_MESSAGE,
+ WORK_PROFILE_NOTIFICATIONS_SECTION_HEADER, WORK_PROFILE_LOCKED_NOTIFICATION_TITLE,
+ WORK_PROFILE_LOCK_SCREEN_REDACT_NOTIFICATION_TITLE,
+ WORK_PROFILE_LOCK_SCREEN_REDACT_NOTIFICATION_SUMMARY,
+ WORK_PROFILE_NOTIFICATION_LISTENER_BLOCKED, CONNECTED_WORK_AND_PERSONAL_APPS_TITLE,
+ CONNECTED_APPS_SHARE_PERMISSIONS_AND_DATA, ONLY_CONNECT_TRUSTED_APPS,
+ HOW_TO_DISCONNECT_APPS, CONNECT_APPS_DIALOG_TITLE, CONNECT_APPS_DIALOG_SUMMARY,
+ APP_CAN_ACCESS_PERSONAL_DATA, APP_CAN_ACCESS_PERSONAL_PERMISSIONS,
+ INSTALL_IN_WORK_PROFILE_TO_CONNECT_PROMPT,
+ INSTALL_IN_PERSONAL_PROFILE_TO_CONNECT_PROMPT, WORK_PROFILE_MANAGED_BY, MANAGED_BY,
+ WORK_PROFILE_DISABLE_USAGE_ACCESS_WARNING, DISABLED_BY_IT_ADMIN_TITLE,
+ CONTACT_YOUR_IT_ADMIN, WORK_PROFILE_ADMIN_POLICIES_WARNING, USER_ADMIN_POLICIES_WARNING,
+ DEVICE_ADMIN_POLICIES_WARNING, WORK_PROFILE_OFF_CONDITION_TITLE,
+ MANAGED_PROFILE_SETTINGS_TITLE, WORK_PROFILE_CONTACT_SEARCH_TITLE,
+ WORK_PROFILE_CONTACT_SEARCH_SUMMARY, CROSS_PROFILE_CALENDAR_TITLE,
+ CROSS_PROFILE_CALENDAR_SUMMARY, ALWAYS_ON_VPN_PERSONAL_PROFILE, ALWAYS_ON_VPN_DEVICE,
+ ALWAYS_ON_VPN_WORK_PROFILE, CA_CERTS_PERSONAL_PROFILE, CA_CERTS_WORK_PROFILE,
+ CA_CERTS_DEVICE, ADMIN_CAN_LOCK_DEVICE, ADMIN_CAN_WIPE_DEVICE,
+ ADMIN_CONFIGURED_FAILED_PASSWORD_WIPE_DEVICE,
+ ADMIN_CONFIGURED_FAILED_PASSWORD_WIPE_WORK_PROFILE, DEVICE_MANAGED_WITHOUT_NAME,
+ DEVICE_MANAGED_WITH_NAME, WORK_PROFILE_APP_SUBTEXT, PERSONAL_PROFILE_APP_SUBTEXT,
+ FINGERPRINT_FOR_WORK, FACE_UNLOCK_DISABLED, FINGERPRINT_UNLOCK_DISABLED,
+ FINGERPRINT_UNLOCK_DISABLED_EXPLANATION, PIN_RECENTLY_USED, PASSWORD_RECENTLY_USED,
+ MANAGE_DEVICE_ADMIN_APPS, NUMBER_OF_DEVICE_ADMINS_NONE, NUMBER_OF_DEVICE_ADMINS,
+ FORGOT_PASSWORD_TITLE, FORGOT_PASSWORD_TEXT, ERROR_MOVE_DEVICE_ADMIN,
+ DEVICE_ADMIN_SETTINGS_TITLE, REMOVE_DEVICE_ADMIN, UNINSTALL_DEVICE_ADMIN,
+ REMOVE_AND_UNINSTALL_DEVICE_ADMIN, SELECT_DEVICE_ADMIN_APPS, NO_DEVICE_ADMINS,
+ ACTIVATE_DEVICE_ADMIN_APP, ACTIVATE_THIS_DEVICE_ADMIN_APP,
+ ACTIVATE_DEVICE_ADMIN_APP_TITLE, NEW_DEVICE_ADMIN_WARNING,
+ NEW_DEVICE_ADMIN_WARNING_SIMPLIFIED, ACTIVE_DEVICE_ADMIN_WARNING,
+ SET_PROFILE_OWNER_TITLE, SET_PROFILE_OWNER_DIALOG_TITLE,
+ SET_PROFILE_OWNER_POSTSETUP_WARNING, OTHER_OPTIONS_DISABLED_BY_ADMIN,
+ REMOVE_ACCOUNT_FAILED_ADMIN_RESTRICTION, IT_ADMIN_POLICY_DISABLING_INFO_URL,
+ SHARE_REMOTE_BUGREPORT_DIALOG_TITLE, SHARE_REMOTE_BUGREPORT_FINISHED_REQUEST_CONSENT,
+ SHARE_REMOTE_BUGREPORT_NOT_FINISHED_REQUEST_CONSENT, SHARING_REMOTE_BUGREPORT_MESSAGE,
+ MANAGED_DEVICE_INFO, MANAGED_DEVICE_INFO_SUMMARY, MANAGED_DEVICE_INFO_SUMMARY_WITH_NAME,
+ ENTERPRISE_PRIVACY_HEADER, INFORMATION_YOUR_ORGANIZATION_CAN_SEE_TITLE,
+ CHANGES_MADE_BY_YOUR_ORGANIZATION_ADMIN_TITLE, YOUR_ACCESS_TO_THIS_DEVICE_TITLE,
+ ADMIN_CAN_SEE_WORK_DATA_WARNING, ADMIN_CAN_SEE_APPS_WARNING,
+ ADMIN_CAN_SEE_USAGE_WARNING, ADMIN_CAN_SEE_NETWORK_LOGS_WARNING,
+ ADMIN_CAN_SEE_BUG_REPORT_WARNING, ADMIN_CAN_SEE_SECURITY_LOGS_WARNING,
+ ADMIN_ACTION_NONE, ADMIN_ACTION_APPS_INSTALLED, ADMIN_ACTION_APPS_COUNT_ESTIMATED,
+ ADMIN_ACTIONS_APPS_COUNT_MINIMUM, ADMIN_ACTION_ACCESS_LOCATION,
+ ADMIN_ACTION_ACCESS_MICROPHONE, ADMIN_ACTION_ACCESS_CAMERA,
+ ADMIN_ACTION_SET_DEFAULT_APPS, ADMIN_ACTIONS_APPS_COUNT,
+ ADMIN_ACTION_SET_CURRENT_INPUT_METHOD, ADMIN_ACTION_SET_INPUT_METHOD_NAME,
+ ADMIN_ACTION_SET_HTTP_PROXY, WORK_PROFILE_PRIVACY_POLICY_INFO_SUMMARY,
+ WORK_PROFILE_PRIVACY_POLICY_INFO, CONNECTED_APPS_SEARCH_KEYWORDS,
+ WORK_PROFILE_UNIFICATION_SEARCH_KEYWORDS, ACCOUNTS_SEARCH_KEYWORDS,
+ CONTROLLED_BY_ADMIN_SUMMARY, WORK_PROFILE_USER_LABEL, WORK_CATEGORY_HEADER,
+ PERSONAL_CATEGORY_HEADER
})
public @interface UpdatableStringId {
}
@@ -432,7 +675,8 @@
@SystemApi
public static final class Strings {
- private Strings() {}
+ private Strings() {
+ }
/**
* An ID for any string that can't be updated.
@@ -456,13 +700,1209 @@
/**
* Class containing the identifiers used to update device management-related system strings
+ * in the Settings package
+ *
+ * @hide
+ */
+ public static final class Settings {
+
+ private Settings() {
+ }
+
+ private static final String PREFIX = "Settings.";
+
+ /**
+ * Title shown for menu item that launches face settings or enrollment, for work profile
+ */
+ public static final String FACE_SETTINGS_FOR_WORK_TITLE =
+ PREFIX + "FACE_SETTINGS_FOR_WORK_TITLE";
+
+ /**
+ * Warning when removing the last fingerprint on a work profile
+ */
+ public static final String WORK_PROFILE_FINGERPRINT_LAST_DELETE_MESSAGE =
+ PREFIX + "WORK_PROFILE_FINGERPRINT_LAST_DELETE_MESSAGE";
+
+ /**
+ * Text letting the user know that their IT admin can't reset their screen lock if they
+ * forget it, and they can choose to set another lock that would be specifically for
+ * their work apps
+ */
+ public static final String WORK_PROFILE_IT_ADMIN_CANT_RESET_SCREEN_LOCK =
+ PREFIX + "WORK_PROFILE_IT_ADMIN_CANT_RESET_SCREEN_LOCK";
+
+ /**
+ * Message shown in screen lock picker for setting up a work profile screen lock
+ */
+ public static final String WORK_PROFILE_SCREEN_LOCK_SETUP_MESSAGE =
+ PREFIX + "WORK_PROFILE_SCREEN_LOCK_SETUP_MESSAGE";
+
+ /**
+ * Title for PreferenceScreen to launch picker for security method for the managed
+ * profile when there is none
+ */
+ public static final String WORK_PROFILE_SET_UNLOCK_LAUNCH_PICKER_TITLE =
+ PREFIX + "WORK_PROFILE_SET_UNLOCK_LAUNCH_PICKER_TITLE";
+
+ /**
+ * Content of the dialog shown when the user only has one attempt left to provide the
+ * work lock pattern before the work profile is removed
+ */
+ public static final String WORK_PROFILE_LAST_PATTERN_ATTEMPT_BEFORE_WIPE =
+ PREFIX + "WORK_PROFILE_LAST_PATTERN_ATTEMPT_BEFORE_WIPE";
+
+ /**
+ * Content of the dialog shown when the user only has one attempt left to provide the
+ * work lock pattern before the work profile is removed
+ */
+ public static final String WORK_PROFILE_LAST_PIN_ATTEMPT_BEFORE_WIPE =
+ PREFIX + "WORK_PROFILE_LAST_PIN_ATTEMPT_BEFORE_WIPE";
+
+ /**
+ * Content of the dialog shown when the user only has one attempt left to provide the
+ * work lock pattern before the work profile is removed
+ */
+ public static final String WORK_PROFILE_LAST_PASSWORD_ATTEMPT_BEFORE_WIPE =
+ PREFIX + "WORK_PROFILE_LAST_PASSWORD_ATTEMPT_BEFORE_WIPE";
+
+ /**
+ * Content of the dialog shown when the user has failed to provide the device lock too
+ * many times and the device is wiped
+ */
+ public static final String WORK_PROFILE_LOCK_ATTEMPTS_FAILED =
+ PREFIX + "WORK_PROFILE_LOCK_ATTEMPTS_FAILED";
+
+ /**
+ * Content description for work profile accounts group
+ */
+ public static final String ACCESSIBILITY_CATEGORY_WORK =
+ PREFIX + "ACCESSIBILITY_CATEGORY_WORK";
+
+ /**
+ * Content description for personal profile accounts group
+ */
+ public static final String ACCESSIBILITY_CATEGORY_PERSONAL =
+ PREFIX + "ACCESSIBILITY_CATEGORY_PERSONAL";
+
+ /**
+ * Content description for work profile details page title
+ */
+ public static final String ACCESSIBILITY_WORK_ACCOUNT_TITLE =
+ PREFIX + "ACCESSIBILITY_WORK_ACCOUNT_TITLE";
+
+ /**
+ * Content description for personal profile details page title
+ */
+ public static final String ACCESSIBILITY_PERSONAL_ACCOUNT_TITLE =
+ PREFIX + "ACCESSIBILITY_PERSONAL_ACCOUNT_TITLE";
+
+ /**
+ * Title for work profile location switch
+ */
+ public static final String WORK_PROFILE_LOCATION_SWITCH_TITLE =
+ PREFIX + "WORK_PROFILE_LOCATION_SWITCH_TITLE";
+
+ /**
+ * Header when setting work profile password
+ */
+ public static final String SET_WORK_PROFILE_PASSWORD_HEADER =
+ PREFIX + "SET_WORK_PROFILE_PASSWORD_HEADER";
+
+ /**
+ * Header when setting work profile PIN
+ */
+ public static final String SET_WORK_PROFILE_PIN_HEADER =
+ PREFIX + "SET_WORK_PROFILE_PIN_HEADER";
+
+ /**
+ * Header when setting work profile pattern
+ */
+ public static final String SET_WORK_PROFILE_PATTERN_HEADER =
+ PREFIX + "SET_WORK_PROFILE_PATTERN_HEADER";
+
+ /**
+ * Header when confirming work profile password
+ */
+ public static final String CONFIRM_WORK_PROFILE_PASSWORD_HEADER =
+ PREFIX + "CONFIRM_WORK_PROFILE_PASSWORD_HEADER";
+
+ /**
+ * Header when confirming work profile pin
+ */
+ public static final String CONFIRM_WORK_PROFILE_PIN_HEADER =
+ PREFIX + "CONFIRM_WORK_PROFILE_PIN_HEADER";
+
+ /**
+ * Header when confirming work profile pattern
+ */
+ public static final String CONFIRM_WORK_PROFILE_PATTERN_HEADER =
+ PREFIX + "CONFIRM_WORK_PROFILE_PATTERN_HEADER";
+
+ /**
+ * Header when re-entering work profile password
+ */
+ public static final String REENTER_WORK_PROFILE_PASSWORD_HEADER =
+ PREFIX + "REENTER_WORK_PROFILE_PASSWORD_HEADER";
+
+ /**
+ * Header when re-entering work profile pin
+ */
+ public static final String REENTER_WORK_PROFILE_PIN_HEADER =
+ PREFIX + "REENTER_WORK_PROFILE_PIN_HEADER";
+
+ /**
+ * Message to be used to explain the users that they need to enter their work pattern to
+ * continue a particular operation
+ */
+ public static final String WORK_PROFILE_CONFIRM_PATTERN =
+ PREFIX + "WORK_PROFILE_CONFIRM_PATTERN";
+
+ /**
+ * Message to be used to explain the users that they need to enter their work pin to
+ * continue a particular operation
+ */
+ public static final String WORK_PROFILE_CONFIRM_PIN =
+ PREFIX + "WORK_PROFILE_CONFIRM_PIN";
+
+ /**
+ * Message to be used to explain the users that they need to enter their work password
+ * to
+ * continue a particular operation
+ */
+ public static final String WORK_PROFILE_CONFIRM_PASSWORD =
+ PREFIX + "WORK_PROFILE_CONFIRM_PASSWORD";
+
+ /**
+ * This string shows = PREFIX + "shows"; up on a screen where a user can enter a pattern
+ * that lets them access
+ * their work profile. This is an extra security measure that's required for them to
+ * continue
+ */
+ public static final String WORK_PROFILE_PATTERN_REQUIRED =
+ PREFIX + "WORK_PROFILE_PATTERN_REQUIRED";
+
+ /**
+ * This string shows = PREFIX + "shows"; up on a screen where a user can enter a pin
+ * that lets them access
+ * their work profile. This is an extra security measure that's required for them to
+ * continue
+ */
+ public static final String WORK_PROFILE_PIN_REQUIRED =
+ PREFIX + "WORK_PROFILE_PIN_REQUIRED";
+
+ /**
+ * This string shows = PREFIX + "shows"; up on a screen where a user can enter a
+ * password that lets them access
+ * their work profile. This is an extra security measure that's required for them to
+ * continue
+ */
+ public static final String WORK_PROFILE_PASSWORD_REQUIRED =
+ PREFIX + "WORK_PROFILE_PASSWORD_REQUIRED";
+
+ /**
+ * Header for Work Profile security settings
+ */
+ public static final String WORK_PROFILE_SECURITY_TITLE =
+ PREFIX + "WORK_PROFILE_SECURITY_TITLE";
+
+ /**
+ * Header for Work Profile unify locks settings
+ */
+ public static final String WORK_PROFILE_UNIFY_LOCKS_TITLE =
+ PREFIX + "WORK_PROFILE_UNIFY_LOCKS_TITLE";
+
+ /**
+ * Setting option explanation to unify work and personal locks
+ */
+ public static final String WORK_PROFILE_UNIFY_LOCKS_SUMMARY =
+ PREFIX + "WORK_PROFILE_UNIFY_LOCKS_SUMMARY";
+
+ /**
+ * Further explanation when the user wants to unify work and personal locks
+ */
+ public static final String WORK_PROFILE_UNIFY_LOCKS_DETAIL =
+ PREFIX + "WORK_PROFILE_UNIFY_LOCKS_DETAIL";
+
+ /**
+ * Ask if the user wants to create a new lock for personal and work as the current work
+ * lock is not enough for the device
+ */
+ public static final String WORK_PROFILE_UNIFY_LOCKS_NONCOMPLIANT =
+ PREFIX + "WORK_PROFILE_UNIFY_LOCKS_NONCOMPLIANT";
+
+ /**
+ * Title of 'Work profile keyboards & tools' preference category
+ */
+ public static final String WORK_PROFILE_KEYBOARDS_AND_TOOLS =
+ PREFIX + "WORK_PROFILE_KEYBOARDS_AND_TOOLS";
+
+ /**
+ * Label for state when work profile is not available
+ */
+ public static final String WORK_PROFILE_NOT_AVAILABLE =
+ PREFIX + "WORK_PROFILE_NOT_AVAILABLE";
+
+ /**
+ * Label for work profile setting (to allow turning work profile on and off)
+ */
+ public static final String WORK_PROFILE_SETTING = PREFIX + "WORK_PROFILE_SETTING";
+
+ /**
+ * Description of the work profile setting when the work profile is on
+ */
+ public static final String WORK_PROFILE_SETTING_ON_SUMMARY =
+ PREFIX + "WORK_PROFILE_SETTING_ON_SUMMARY";
+
+ /**
+ * Description of the work profile setting when the work profile is off
+ */
+ public static final String WORK_PROFILE_SETTING_OFF_SUMMARY =
+ PREFIX + "WORK_PROFILE_SETTING_OFF_SUMMARY";
+
+ /**
+ * Button text to remove work profile
+ */
+ public static final String REMOVE_WORK_PROFILE = PREFIX + "REMOVE_WORK_PROFILE";
+
+ /**
+ * Text of message to show to device owner user whose administrator has installed a SSL
+ * CA Cert
+ */
+ public static final String DEVICE_OWNER_INSTALLED_CERTIFICATE_AUTHORITY_WARNING =
+ PREFIX + "DEVICE_OWNER_INSTALLED_CERTIFICATE_AUTHORITY_WARNING";
+
+ /**
+ * Text of message to show to work profile users whose administrator has installed a SSL
+ * CA Cert
+ */
+ public static final String WORK_PROFILE_INSTALLED_CERTIFICATE_AUTHORITY_WARNING =
+ PREFIX + "WORK_PROFILE_INSTALLED_CERTIFICATE_AUTHORITY_WARNING";
+
+ /**
+ * Work profile removal confirmation title
+ */
+ public static final String WORK_PROFILE_CONFIRM_REMOVE_TITLE =
+ PREFIX + "WORK_PROFILE_CONFIRM_REMOVE_TITLE";
+
+ /**
+ * Work profile removal confirmation message
+ */
+ public static final String WORK_PROFILE_CONFIRM_REMOVE_MESSAGE =
+ PREFIX + "WORK_PROFILE_CONFIRM_REMOVE_MESSAGE";
+
+ /**
+ * Toast shown when an app in the work profile attempts to open notification settings
+ * and apps in the work profile cannot access notification settings
+ */
+ public static final String WORK_APPS_CANNOT_ACCESS_NOTIFICATION_SETTINGS =
+ PREFIX + "WORK_APPS_CANNOT_ACCESS_NOTIFICATION_SETTINGS";
+
+ /**
+ * Work sound settings section header
+ */
+ public static final String WORK_PROFILE_SOUND_SETTINGS_SECTION_HEADER =
+ PREFIX + "WORK_PROFILE_SOUND_SETTINGS_SECTION_HEADER";
+
+ /**
+ * Title for the switch that enables syncing of personal ringtones to work profile
+ */
+ public static final String WORK_PROFILE_USE_PERSONAL_SOUNDS_TITLE =
+ PREFIX + "WORK_PROFILE_USE_PERSONAL_SOUNDS_TITLE";
+
+ /**
+ * Summary for the switch that enables syncing of personal ringtones to work profile
+ */
+ public static final String WORK_PROFILE_USE_PERSONAL_SOUNDS_SUMMARY =
+ PREFIX + "WORK_PROFILE_USE_PERSONAL_SOUNDS_SUMMARY";
+
+ /**
+ * Title for the option defining the work profile phone ringtone
+ */
+ public static final String WORK_PROFILE_RINGTONE_TITLE =
+ PREFIX + "WORK_PROFILE_RINGTONE_TITLE";
+
+ /**
+ * Title for the option defining the default work profile notification ringtone
+ */
+ public static final String WORK_PROFILE_NOTIFICATION_RINGTONE_TITLE =
+ PREFIX + "WORK_PROFILE_NOTIFICATION_RINGTONE_TITLE";
+
+ /**
+ * Title for the option defining the default work alarm ringtone
+ */
+ public static final String WORK_PROFILE_ALARM_RINGTONE_TITLE =
+ PREFIX + "WORK_PROFILE_ALARM_RINGTONE_TITLE";
+
+ /**
+ * Summary for sounds when sync with personal sounds is active
+ */
+ public static final String WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_ACTIVE_SUMMARY =
+ PREFIX + "WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_ACTIVE_SUMMARY";
+
+ /**
+ * Title for dialog shown when enabling sync with personal sounds
+ */
+ public static final String
+ ENABLE_WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_DIALOG_TITLE =
+ PREFIX + "ENABLE_WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_DIALOG_TITLE";
+
+ /**
+ * Message for dialog shown when using the same sounds for work events as for personal
+ * events
+ */
+ public static final String
+ ENABLE_WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_DIALOG_MESSAGE =
+ PREFIX + "ENABLE_WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_DIALOG_MESSAGE";
+
+ /**
+ * Work profile notifications section header
+ */
+ public static final String WORK_PROFILE_NOTIFICATIONS_SECTION_HEADER =
+ PREFIX + "WORK_PROFILE_NOTIFICATIONS_SECTION_HEADER";
+
+ /**
+ * Title for the option controlling notifications for work profile
+ */
+ public static final String WORK_PROFILE_LOCKED_NOTIFICATION_TITLE =
+ PREFIX + "WORK_PROFILE_LOCKED_NOTIFICATION_TITLE";
+
+ /**
+ * Title for redacting sensitive content on lockscreen for work profiles
+ */
+ public static final String WORK_PROFILE_LOCK_SCREEN_REDACT_NOTIFICATION_TITLE =
+ PREFIX + "WORK_PROFILE_LOCK_SCREEN_REDACT_NOTIFICATION_TITLE";
+
+ /**
+ * Summary for redacting sensitive content on lockscreen for work profiles
+ */
+ public static final String WORK_PROFILE_LOCK_SCREEN_REDACT_NOTIFICATION_SUMMARY =
+ PREFIX + "WORK_PROFILE_LOCK_SCREEN_REDACT_NOTIFICATION_SUMMARY";
+
+ /**
+ * Indicates that the work profile admin doesn't allow this notification listener to
+ * access
+ * work profile notifications
+ */
+ public static final String WORK_PROFILE_NOTIFICATION_LISTENER_BLOCKED =
+ PREFIX + "WORK_PROFILE_NOTIFICATION_LISTENER_BLOCKED";
+
+ /**
+ * This setting shows a user's connected work and personal apps.
+ */
+ public static final String CONNECTED_WORK_AND_PERSONAL_APPS_TITLE =
+ PREFIX + "CONNECTED_WORK_AND_PERSONAL_APPS_TITLE";
+
+ /**
+ * This text lets a user know that if they connect work and personal apps,
+ * they will share permissions and can access each other's data
+ */
+ public static final String CONNECTED_APPS_SHARE_PERMISSIONS_AND_DATA =
+ PREFIX + "CONNECTED_APPS_SHARE_PERMISSIONS_AND_DATA";
+
+ /**
+ * This text lets a user know that they should only connect work and personal apps if
+ * they
+ * trust the work app with their personal data
+ */
+ public static final String ONLY_CONNECT_TRUSTED_APPS =
+ PREFIX + "ONLY_CONNECT_TRUSTED_APPS";
+
+ /**
+ * This text lets a user know how to disconnect work and personal apps
+ */
+ public static final String HOW_TO_DISCONNECT_APPS = PREFIX + "HOW_TO_DISCONNECT_APPS";
+
+ /**
+ * Title of confirmation dialog when connecting work and personal apps
+ */
+ public static final String CONNECT_APPS_DIALOG_TITLE =
+ PREFIX + "CONNECT_APPS_DIALOG_TITLE";
+
+ /**
+ * This dialog is shown when a user tries to connect a work app to a personal
+ * app
+ */
+ public static final String CONNECT_APPS_DIALOG_SUMMARY =
+ PREFIX + "CONNECT_APPS_DIALOG_SUMMARY";
+
+ /**
+ * This text lets the user know that their work app will be able to access data in their
+ * personal app
+ */
+ public static final String APP_CAN_ACCESS_PERSONAL_DATA =
+ PREFIX + "APP_CAN_ACCESS_PERSONAL_DATA";
+
+ /**
+ * This text lets the user know that their work app will be able to use permissions in
+ * their personal app
+ */
+ public static final String APP_CAN_ACCESS_PERSONAL_PERMISSIONS =
+ PREFIX + "APP_CAN_ACCESS_PERSONAL_PERMISSIONS";
+
+ /**
+ * lets a user know that they need to install an app in their work profile in order to
+ * connect it to the corresponding personal app
+ */
+ public static final String INSTALL_IN_WORK_PROFILE_TO_CONNECT_PROMPT =
+ PREFIX + "INSTALL_IN_WORK_PROFILE_TO_CONNECT_PROMPT";
+
+ /**
+ * lets a user know that they need to install an app in their personal profile in order
+ * to
+ * connect it to the corresponding work app
+ */
+ public static final String INSTALL_IN_PERSONAL_PROFILE_TO_CONNECT_PROMPT =
+ PREFIX + "INSTALL_IN_PERSONAL_PROFILE_TO_CONNECT_PROMPT";
+
+ /**
+ * Header for showing the organisation managing the work profile
+ */
+ public static final String WORK_PROFILE_MANAGED_BY = PREFIX + "WORK_PROFILE_MANAGED_BY";
+
+ /**
+ * Summary showing the enterprise who manages the device or profile.
+ */
+ public static final String MANAGED_BY = PREFIX + "MANAGED_BY";
+
+ /**
+ * Warning message about disabling usage access on profile owner
+ */
+ public static final String WORK_PROFILE_DISABLE_USAGE_ACCESS_WARNING =
+ PREFIX + "WORK_PROFILE_DISABLE_USAGE_ACCESS_WARNING";
+
+ /**
+ * Title for dialog displayed when user taps a setting on their phone that's blocked by
+ * their IT admin
+ */
+ public static final String DISABLED_BY_IT_ADMIN_TITLE =
+ PREFIX + "DISABLED_BY_IT_ADMIN_TITLE";
+
+ /**
+ * Shown when the user tries to change phone settings that are blocked by their IT admin
+ */
+ public static final String CONTACT_YOUR_IT_ADMIN = PREFIX + "CONTACT_YOUR_IT_ADMIN";
+
+ /**
+ * warn user about policies the admin can set in a work profile
+ */
+ public static final String WORK_PROFILE_ADMIN_POLICIES_WARNING =
+ PREFIX + "WORK_PROFILE_ADMIN_POLICIES_WARNING";
+
+ /**
+ * warn user about policies the admin can set on a user
+ */
+ public static final String USER_ADMIN_POLICIES_WARNING =
+ PREFIX + "USER_ADMIN_POLICIES_WARNING";
+
+ /**
+ * warn user about policies the admin can set on a device
+ */
+ public static final String DEVICE_ADMIN_POLICIES_WARNING =
+ PREFIX + "DEVICE_ADMIN_POLICIES_WARNING";
+
+ /**
+ * Condition that work profile is off
+ */
+ public static final String WORK_PROFILE_OFF_CONDITION_TITLE =
+ PREFIX + "WORK_PROFILE_OFF_CONDITION_TITLE";
+
+ /**
+ * Title of work profile setting page
+ */
+ public static final String MANAGED_PROFILE_SETTINGS_TITLE =
+ PREFIX + "MANAGED_PROFILE_SETTINGS_TITLE";
+
+ /**
+ * Setting that lets a user's personal apps identify contacts using the user's work
+ * directory
+ */
+ public static final String WORK_PROFILE_CONTACT_SEARCH_TITLE =
+ PREFIX + "WORK_PROFILE_CONTACT_SEARCH_TITLE";
+
+ /**
+ * This setting lets a user's personal apps identify contacts using the user's work
+ * directory
+ */
+ public static final String WORK_PROFILE_CONTACT_SEARCH_SUMMARY =
+ PREFIX + "WORK_PROFILE_CONTACT_SEARCH_SUMMARY";
+
+ /**
+ * This setting lets the user show their work events on their personal calendar
+ */
+ public static final String CROSS_PROFILE_CALENDAR_TITLE =
+ PREFIX + "CROSS_PROFILE_CALENDAR_TITLE";
+
+ /**
+ * Setting description. If the user turns on this setting, they can see their work
+ * events on their personal calendar
+ */
+ public static final String CROSS_PROFILE_CALENDAR_SUMMARY =
+ PREFIX + "CROSS_PROFILE_CALENDAR_SUMMARY";
+
+ /**
+ * Label explaining that an always-on VPN was set by the admin in the personal profile
+ */
+ public static final String ALWAYS_ON_VPN_PERSONAL_PROFILE =
+ PREFIX + "ALWAYS_ON_VPN_PERSONAL_PROFILE";
+
+ /**
+ * Label explaining that an always-on VPN was set by the admin for the entire device
+ */
+ public static final String ALWAYS_ON_VPN_DEVICE = PREFIX + "ALWAYS_ON_VPN_DEVICE";
+
+ /**
+ * Label explaining that an always-on VPN was set by the admin in the work profile
+ */
+ public static final String ALWAYS_ON_VPN_WORK_PROFILE =
+ PREFIX + "ALWAYS_ON_VPN_WORK_PROFILE";
+
+ /**
+ * Label explaining that the admin installed trusted CA certificates in personal profile
+ */
+ public static final String CA_CERTS_PERSONAL_PROFILE =
+ PREFIX + "CA_CERTS_PERSONAL_PROFILE";
+
+ /**
+ * Label explaining that the admin installed trusted CA certificates in work profile
+ */
+ public static final String CA_CERTS_WORK_PROFILE = PREFIX + "CA_CERTS_WORK_PROFILE";
+
+ /**
+ * Label explaining that the admin installed trusted CA certificates for the entire
+ * device
+ */
+ public static final String CA_CERTS_DEVICE = PREFIX + "CA_CERTS_DEVICE";
+
+ /**
+ * Label explaining that the admin can lock the device and change the user's password
+ */
+ public static final String ADMIN_CAN_LOCK_DEVICE = PREFIX + "ADMIN_CAN_LOCK_DEVICE";
+
+ /**
+ * Label explaining that the admin can wipe the device remotely
+ */
+ public static final String ADMIN_CAN_WIPE_DEVICE = PREFIX + "ADMIN_CAN_WIPE_DEVICE";
+
+ /**
+ * Label explaining that the admin configured the device to wipe itself when the
+ * password is mistyped too many times
+ */
+ public static final String ADMIN_CONFIGURED_FAILED_PASSWORD_WIPE_DEVICE =
+ PREFIX + "ADMIN_CONFIGURED_FAILED_PASSWORD_WIPE_DEVICE";
+
+ /**
+ * Label explaining that the admin configured the work profile to wipe itself when the
+ * password is mistyped too many times
+ */
+ public static final String ADMIN_CONFIGURED_FAILED_PASSWORD_WIPE_WORK_PROFILE =
+ PREFIX + "ADMIN_CONFIGURED_FAILED_PASSWORD_WIPE_WORK_PROFILE";
+
+ /**
+ * Message indicating that the device is enterprise-managed by a Device Owner
+ */
+ public static final String DEVICE_MANAGED_WITHOUT_NAME =
+ PREFIX + "DEVICE_MANAGED_WITHOUT_NAME";
+
+ /**
+ * Message indicating that the device is enterprise-managed by a Device Owner
+ */
+ public static final String DEVICE_MANAGED_WITH_NAME =
+ PREFIX + "DEVICE_MANAGED_WITH_NAME";
+
+ /**
+ * Subtext of work profile app for current setting
+ */
+ public static final String WORK_PROFILE_APP_SUBTEXT =
+ PREFIX + "WORK_PROFILE_APP_SUBTEXT";
+
+ /**
+ * Subtext of personal profile app for current setting
+ */
+ public static final String PERSONAL_PROFILE_APP_SUBTEXT =
+ PREFIX + "PERSONAL_PROFILE_APP_SUBTEXT";
+
+ /**
+ * Title shown for work menu item that launches fingerprint settings or enrollment
+ */
+ public static final String FINGERPRINT_FOR_WORK = PREFIX + "FINGERPRINT_FOR_WORK";
+
+ /**
+ * Message shown in face enrollment dialog, when face unlock is disabled by device admin
+ */
+ public static final String FACE_UNLOCK_DISABLED = PREFIX + "FACE_UNLOCK_DISABLED";
+
+ /**
+ * message shown in fingerprint enrollment dialog, when fingerprint unlock is disabled
+ * by device admin
+ */
+ public static final String FINGERPRINT_UNLOCK_DISABLED =
+ PREFIX + "FINGERPRINT_UNLOCK_DISABLED";
+
+ /**
+ * Text shown in fingerprint settings explaining what the fingerprint can be used for in
+ * the case unlocking is disabled
+ */
+ public static final String FINGERPRINT_UNLOCK_DISABLED_EXPLANATION =
+ PREFIX + "FINGERPRINT_UNLOCK_DISABLED_EXPLANATION";
+
+ /**
+ * Error shown when in PIN mode and PIN has been used recently
+ */
+ public static final String PIN_RECENTLY_USED = PREFIX + "PIN_RECENTLY_USED";
+
+ /**
+ * Error shown when in PASSWORD mode and password has been used recently
+ */
+ public static final String PASSWORD_RECENTLY_USED = PREFIX + "PASSWORD_RECENTLY_USED";
+
+ /**
+ * Title of preference to manage device admin apps
+ */
+ public static final String MANAGE_DEVICE_ADMIN_APPS =
+ PREFIX + "MANAGE_DEVICE_ADMIN_APPS";
+
+ /**
+ * Inform the user that currently no device admin apps are installed and active
+ */
+ public static final String NUMBER_OF_DEVICE_ADMINS_NONE =
+ PREFIX + "NUMBER_OF_DEVICE_ADMINS_NONE";
+
+ /**
+ * Inform the user how many device admin apps are installed and active
+ */
+ public static final String NUMBER_OF_DEVICE_ADMINS = PREFIX + "NUMBER_OF_DEVICE_ADMINS";
+
+ /**
+ * Title that asks the user to contact the IT admin to reset password
+ */
+ public static final String FORGOT_PASSWORD_TITLE = PREFIX + "FORGOT_PASSWORD_TITLE";
+
+ /**
+ * Content that asks the user to contact the IT admin to reset password
+ */
+ public static final String FORGOT_PASSWORD_TEXT = PREFIX + "FORGOT_PASSWORD_TEXT";
+
+ /**
+ * Error message shown when trying to move device administrators to external disks, such
+ * as SD card
+ */
+ public static final String ERROR_MOVE_DEVICE_ADMIN = PREFIX + "ERROR_MOVE_DEVICE_ADMIN";
+
+ /**
+ * Device admin app settings title
+ */
+ public static final String DEVICE_ADMIN_SETTINGS_TITLE =
+ PREFIX + "DEVICE_ADMIN_SETTINGS_TITLE";
+
+ /**
+ * Button to remove the active device admin app
+ */
+ public static final String REMOVE_DEVICE_ADMIN = PREFIX + "REMOVE_DEVICE_ADMIN";
+
+ /**
+ * Button to uninstall the device admin app
+ */
+ public static final String UNINSTALL_DEVICE_ADMIN = PREFIX + "UNINSTALL_DEVICE_ADMIN";
+
+ /**
+ * Button to deactivate and uninstall the device admin app
+ */
+ public static final String REMOVE_AND_UNINSTALL_DEVICE_ADMIN =
+ PREFIX + "REMOVE_AND_UNINSTALL_DEVICE_ADMIN";
+
+ /**
+ * Title for selecting device admin apps
+ */
+ public static final String SELECT_DEVICE_ADMIN_APPS =
+ PREFIX + "SELECT_DEVICE_ADMIN_APPS";
+
+ /**
+ * Message when there are no available device admin apps to display
+ */
+ public static final String NO_DEVICE_ADMINS = PREFIX + "NO_DEVICE_ADMINS";
+
+ /**
+ * Title for screen to add a device admin app
+ */
+ public static final String ACTIVATE_DEVICE_ADMIN_APP =
+ PREFIX + "ACTIVATE_DEVICE_ADMIN_APP";
+
+ /**
+ * Label for button to set the active device admin
+ */
+ public static final String ACTIVATE_THIS_DEVICE_ADMIN_APP =
+ PREFIX + "ACTIVATE_THIS_DEVICE_ADMIN_APP";
+
+ /**
+ * Activate a specific device admin app title
+ */
+ public static final String ACTIVATE_DEVICE_ADMIN_APP_TITLE =
+ PREFIX + "ACTIVATE_DEVICE_ADMIN_APP_TITLE";
+
+ /**
+ * Device admin warning message about policies a not active admin can use
+ */
+ public static final String NEW_DEVICE_ADMIN_WARNING =
+ PREFIX + "NEW_DEVICE_ADMIN_WARNING";
+
+ /**
+ * Simplified device admin warning message
+ */
+ public static final String NEW_DEVICE_ADMIN_WARNING_SIMPLIFIED =
+ PREFIX + "NEW_DEVICE_ADMIN_WARNING_SIMPLIFIED";
+
+ /**
+ * Device admin warning message about policies the active admin can use
+ */
+ public static final String ACTIVE_DEVICE_ADMIN_WARNING =
+ PREFIX + "ACTIVE_DEVICE_ADMIN_WARNING";
+
+ /**
+ * Title for screen to set a profile owner
+ */
+ public static final String SET_PROFILE_OWNER_TITLE = PREFIX + "SET_PROFILE_OWNER_TITLE";
+
+ /**
+ * Simplified title for dialog to set a profile owner
+ */
+ public static final String SET_PROFILE_OWNER_DIALOG_TITLE =
+ PREFIX + "SET_PROFILE_OWNER_DIALOG_TITLE";
+
+ /**
+ * Warning when trying to add a profile owner admin after setup has completed
+ */
+ public static final String SET_PROFILE_OWNER_POSTSETUP_WARNING =
+ PREFIX + "SET_PROFILE_OWNER_POSTSETUP_WARNING";
+
+ /**
+ * Message displayed to let the user know that some of the options are disabled by admin
+ */
+ public static final String OTHER_OPTIONS_DISABLED_BY_ADMIN =
+ PREFIX + "OTHER_OPTIONS_DISABLED_BY_ADMIN";
+
+ /**
+ * This is shown if the authenticator for a given account fails to remove it due to
+ * admin restrictions
+ */
+ public static final String REMOVE_ACCOUNT_FAILED_ADMIN_RESTRICTION =
+ PREFIX + "REMOVE_ACCOUNT_FAILED_ADMIN_RESTRICTION";
+
+ /**
+ * Url for learning more about IT admin policy disabling
+ */
+ public static final String IT_ADMIN_POLICY_DISABLING_INFO_URL =
+ PREFIX + "IT_ADMIN_POLICY_DISABLING_INFO_URL";
+
+ /**
+ * Title of dialog shown to ask for user consent for sharing a bugreport that was
+ * requested
+ * remotely by the IT administrator
+ */
+ public static final String SHARE_REMOTE_BUGREPORT_DIALOG_TITLE =
+ PREFIX + "SHARE_REMOTE_BUGREPORT_DIALOG_TITLE";
+
+ /**
+ * Message of a dialog shown to ask for user consent for sharing a bugreport that was
+ * requested remotely by the IT administrator
+ */
+ public static final String SHARE_REMOTE_BUGREPORT_FINISHED_REQUEST_CONSENT =
+ PREFIX + "SHARE_REMOTE_BUGREPORT_FINISHED_REQUEST_CONSENT";
+
+ /**
+ * Message of a dialog shown to ask for user consent for sharing a bugreport that was
+ * requested remotely by the IT administrator and it's still being taken
+ */
+ public static final String SHARE_REMOTE_BUGREPORT_NOT_FINISHED_REQUEST_CONSENT =
+ PREFIX + "SHARE_REMOTE_BUGREPORT_NOT_FINISHED_REQUEST_CONSENT";
+
+ /**
+ * Message of a dialog shown to inform that the remote bugreport that was requested
+ * remotely by the IT administrator is still being taken and will be shared when
+ * finished
+ */
+ public static final String SHARING_REMOTE_BUGREPORT_MESSAGE =
+ PREFIX + "SHARING_REMOTE_BUGREPORT_MESSAGE";
+
+ /**
+ * Managed device information screen title
+ */
+ public static final String MANAGED_DEVICE_INFO = PREFIX + "MANAGED_DEVICE_INFO";
+
+ /**
+ * Summary for managed device info section
+ */
+ public static final String MANAGED_DEVICE_INFO_SUMMARY =
+ PREFIX + "MANAGED_DEVICE_INFO_SUMMARY";
+
+ /**
+ * Summary for managed device info section including organization name
+ */
+ public static final String MANAGED_DEVICE_INFO_SUMMARY_WITH_NAME =
+ PREFIX + "MANAGED_DEVICE_INFO_SUMMARY_WITH_NAME";
+
+ /**
+ * Enterprise Privacy settings header, summarizing the powers that the admin has
+ */
+ public static final String ENTERPRISE_PRIVACY_HEADER =
+ PREFIX + "ENTERPRISE_PRIVACY_HEADER";
+
+ /**
+ * Types of information your organization can see section title
+ */
+ public static final String INFORMATION_YOUR_ORGANIZATION_CAN_SEE_TITLE =
+ PREFIX + "INFORMATION_YOUR_ORGANIZATION_CAN_SEE_TITLE";
+
+ /**
+ * Changes made by your organization's admin section title
+ */
+ public static final String CHANGES_MADE_BY_YOUR_ORGANIZATION_ADMIN_TITLE =
+ PREFIX + "CHANGES_MADE_BY_YOUR_ORGANIZATION_ADMIN_TITLE";
+
+ /**
+ * Your access to this device section title
+ */
+ public static final String YOUR_ACCESS_TO_THIS_DEVICE_TITLE =
+ PREFIX + "YOUR_ACCESS_TO_THIS_DEVICE_TITLE";
+
+ /**
+ * Things the admin can see: data associated with the work account
+ */
+ public static final String ADMIN_CAN_SEE_WORK_DATA_WARNING =
+ PREFIX + "ADMIN_CAN_SEE_WORK_DATA_WARNING";
+
+ /**
+ * Things the admin can see: Apps installed on the device
+ */
+ public static final String ADMIN_CAN_SEE_APPS_WARNING =
+ PREFIX + "ADMIN_CAN_SEE_APPS_WARNING";
+
+ /**
+ * Things the admin can see: Amount of time and data spent in each app
+ */
+ public static final String ADMIN_CAN_SEE_USAGE_WARNING =
+ PREFIX + "ADMIN_CAN_SEE_USAGE_WARNING";
+
+ /**
+ * Things the admin can see: Most recent network traffic log
+ */
+ public static final String ADMIN_CAN_SEE_NETWORK_LOGS_WARNING =
+ PREFIX + "ADMIN_CAN_SEE_NETWORK_LOGS_WARNING";
+ /**
+ * Things the admin can see: Most recent bug report
+ */
+ public static final String ADMIN_CAN_SEE_BUG_REPORT_WARNING =
+ PREFIX + "ADMIN_CAN_SEE_BUG_REPORT_WARNING";
+
+ /**
+ * Things the admin can see: Security logs
+ */
+ public static final String ADMIN_CAN_SEE_SECURITY_LOGS_WARNING =
+ PREFIX + "ADMIN_CAN_SEE_SECURITY_LOGS_WARNING";
+
+ /**
+ * Indicate that the admin never took a given action so far (e.g. did not retrieve
+ * security logs or request bug reports).
+ */
+ public static final String ADMIN_ACTION_NONE = PREFIX + "ADMIN_ACTION_NONE";
+
+ /**
+ * Indicate that the admin installed one or more apps on the device
+ */
+ public static final String ADMIN_ACTION_APPS_INSTALLED =
+ PREFIX + "ADMIN_ACTION_APPS_INSTALLED";
+
+ /**
+ * Explaining that the number of apps is an estimation
+ */
+ public static final String ADMIN_ACTION_APPS_COUNT_ESTIMATED =
+ PREFIX + "ADMIN_ACTION_APPS_COUNT_ESTIMATED";
+
+ /**
+ * Indicating the minimum number of apps that a label refers to
+ */
+ public static final String ADMIN_ACTIONS_APPS_COUNT_MINIMUM =
+ PREFIX + "ADMIN_ACTIONS_APPS_COUNT_MINIMUM";
+
+ /**
+ * Indicate that the admin granted one or more apps access to the device's location
+ */
+ public static final String ADMIN_ACTION_ACCESS_LOCATION =
+ PREFIX + "ADMIN_ACTION_ACCESS_LOCATION";
+
+ /**
+ * Indicate that the admin granted one or more apps access to the microphone
+ */
+ public static final String ADMIN_ACTION_ACCESS_MICROPHONE =
+ PREFIX + "ADMIN_ACTION_ACCESS_MICROPHONE";
+
+ /**
+ * Indicate that the admin granted one or more apps access to the camera
+ */
+ public static final String ADMIN_ACTION_ACCESS_CAMERA =
+ PREFIX + "ADMIN_ACTION_ACCESS_CAMERA";
+
+ /**
+ * Indicate that the admin set one or more apps as defaults for common actions
+ */
+ public static final String ADMIN_ACTION_SET_DEFAULT_APPS =
+ PREFIX + "ADMIN_ACTION_SET_DEFAULT_APPS";
+
+ /**
+ * Indicate the number of apps that a label refers to
+ */
+ public static final String ADMIN_ACTIONS_APPS_COUNT =
+ PREFIX + "ADMIN_ACTIONS_APPS_COUNT";
+
+ /**
+ * Indicate that the current input method was set by the admin
+ */
+ public static final String ADMIN_ACTION_SET_CURRENT_INPUT_METHOD =
+ PREFIX + "ADMIN_ACTION_SET_CURRENT_INPUT_METHOD";
+
+ /**
+ * The input method set by the admin
+ */
+ public static final String ADMIN_ACTION_SET_INPUT_METHOD_NAME =
+ PREFIX + "ADMIN_ACTION_SET_INPUT_METHOD_NAME";
+
+ /**
+ * Indicate that a global HTTP proxy was set by the admin
+ */
+ public static final String ADMIN_ACTION_SET_HTTP_PROXY =
+ PREFIX + "ADMIN_ACTION_SET_HTTP_PROXY";
+
+ /**
+ * Summary for Enterprise Privacy settings, explaining what the user can expect to find
+ * under it
+ */
+ public static final String WORK_PROFILE_PRIVACY_POLICY_INFO_SUMMARY =
+ PREFIX + "WORK_PROFILE_PRIVACY_POLICY_INFO_SUMMARY";
+
+ /**
+ * Setting on privacy settings screen that will show work policy info
+ */
+ public static final String WORK_PROFILE_PRIVACY_POLICY_INFO =
+ PREFIX + "WORK_PROFILE_PRIVACY_POLICY_INFO";
+
+ /**
+ * Search keywords for connected work and personal apps
+ */
+ public static final String CONNECTED_APPS_SEARCH_KEYWORDS =
+ PREFIX + "CONNECTED_APPS_SEARCH_KEYWORDS";
+
+ /**
+ * Work profile unification keywords
+ */
+ public static final String WORK_PROFILE_UNIFICATION_SEARCH_KEYWORDS =
+ PREFIX + "WORK_PROFILE_UNIFICATION_SEARCH_KEYWORDS";
+
+ /**
+ * Accounts keywords
+ */
+ public static final String ACCOUNTS_SEARCH_KEYWORDS =
+ PREFIX + "ACCOUNTS_SEARCH_KEYWORDS";
+
+ /**
+ * Summary for settings preference disabled by administrator
+ */
+ public static final String CONTROLLED_BY_ADMIN_SUMMARY =
+ PREFIX + "CONTROLLED_BY_ADMIN_SUMMARY";
+
+ /**
+ * User label for a work profile
+ */
+ public static final String WORK_PROFILE_USER_LABEL = PREFIX + "WORK_PROFILE_USER_LABEL";
+
+ /**
+ * Header for items under the work user
+ */
+ public static final String WORK_CATEGORY_HEADER = PREFIX + "WORK_CATEGORY_HEADER";
+
+ /**
+ * Header for items under the personal user
+ */
+ public static final String PERSONAL_CATEGORY_HEADER = PREFIX + "category_personal";
+
+ /**
+ * @hide
+ */
+ static Set<String> buildStringsSet() {
+ Set<String> strings = new HashSet<>();
+ strings.add(FACE_SETTINGS_FOR_WORK_TITLE);
+ strings.add(WORK_PROFILE_FINGERPRINT_LAST_DELETE_MESSAGE);
+ strings.add(WORK_PROFILE_IT_ADMIN_CANT_RESET_SCREEN_LOCK);
+ strings.add(WORK_PROFILE_SCREEN_LOCK_SETUP_MESSAGE);
+ strings.add(WORK_PROFILE_SET_UNLOCK_LAUNCH_PICKER_TITLE);
+ strings.add(WORK_PROFILE_LAST_PATTERN_ATTEMPT_BEFORE_WIPE);
+ strings.add(WORK_PROFILE_LAST_PIN_ATTEMPT_BEFORE_WIPE);
+ strings.add(WORK_PROFILE_LAST_PASSWORD_ATTEMPT_BEFORE_WIPE);
+ strings.add(WORK_PROFILE_LOCK_ATTEMPTS_FAILED);
+ strings.add(ACCESSIBILITY_CATEGORY_WORK);
+ strings.add(ACCESSIBILITY_CATEGORY_PERSONAL);
+ strings.add(ACCESSIBILITY_WORK_ACCOUNT_TITLE);
+ strings.add(ACCESSIBILITY_PERSONAL_ACCOUNT_TITLE);
+ strings.add(WORK_PROFILE_LOCATION_SWITCH_TITLE);
+ strings.add(SET_WORK_PROFILE_PASSWORD_HEADER);
+ strings.add(SET_WORK_PROFILE_PIN_HEADER);
+ strings.add(SET_WORK_PROFILE_PATTERN_HEADER);
+ strings.add(CONFIRM_WORK_PROFILE_PASSWORD_HEADER);
+ strings.add(CONFIRM_WORK_PROFILE_PIN_HEADER);
+ strings.add(CONFIRM_WORK_PROFILE_PATTERN_HEADER);
+ strings.add(REENTER_WORK_PROFILE_PASSWORD_HEADER);
+ strings.add(REENTER_WORK_PROFILE_PIN_HEADER);
+ strings.add(WORK_PROFILE_CONFIRM_PATTERN);
+ strings.add(WORK_PROFILE_CONFIRM_PIN);
+ strings.add(WORK_PROFILE_PASSWORD_REQUIRED);
+ strings.add(WORK_PROFILE_SECURITY_TITLE);
+ strings.add(WORK_PROFILE_UNIFY_LOCKS_TITLE);
+ strings.add(WORK_PROFILE_UNIFY_LOCKS_SUMMARY);
+ strings.add(WORK_PROFILE_UNIFY_LOCKS_DETAIL);
+ strings.add(WORK_PROFILE_UNIFY_LOCKS_NONCOMPLIANT);
+ strings.add(WORK_PROFILE_KEYBOARDS_AND_TOOLS);
+ strings.add(WORK_PROFILE_NOT_AVAILABLE);
+ strings.add(WORK_PROFILE_SETTING);
+ strings.add(WORK_PROFILE_SETTING_ON_SUMMARY);
+ strings.add(WORK_PROFILE_SETTING_OFF_SUMMARY);
+ strings.add(REMOVE_WORK_PROFILE);
+ strings.add(DEVICE_OWNER_INSTALLED_CERTIFICATE_AUTHORITY_WARNING);
+ strings.add(WORK_PROFILE_INSTALLED_CERTIFICATE_AUTHORITY_WARNING);
+ strings.add(WORK_PROFILE_CONFIRM_REMOVE_TITLE);
+ strings.add(WORK_PROFILE_CONFIRM_REMOVE_MESSAGE);
+ strings.add(WORK_APPS_CANNOT_ACCESS_NOTIFICATION_SETTINGS);
+ strings.add(WORK_PROFILE_SOUND_SETTINGS_SECTION_HEADER);
+ strings.add(WORK_PROFILE_USE_PERSONAL_SOUNDS_TITLE);
+ strings.add(WORK_PROFILE_USE_PERSONAL_SOUNDS_SUMMARY);
+ strings.add(WORK_PROFILE_RINGTONE_TITLE);
+ strings.add(WORK_PROFILE_NOTIFICATION_RINGTONE_TITLE);
+ strings.add(WORK_PROFILE_ALARM_RINGTONE_TITLE);
+ strings.add(WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_ACTIVE_SUMMARY);
+ strings.add(ENABLE_WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_DIALOG_TITLE);
+ strings.add(ENABLE_WORK_PROFILE_SYNC_WITH_PERSONAL_SOUNDS_DIALOG_MESSAGE);
+ strings.add(WORK_PROFILE_NOTIFICATIONS_SECTION_HEADER);
+ strings.add(WORK_PROFILE_LOCKED_NOTIFICATION_TITLE);
+ strings.add(WORK_PROFILE_LOCK_SCREEN_REDACT_NOTIFICATION_TITLE);
+ strings.add(WORK_PROFILE_LOCK_SCREEN_REDACT_NOTIFICATION_SUMMARY);
+ strings.add(WORK_PROFILE_NOTIFICATION_LISTENER_BLOCKED);
+ strings.add(CONNECTED_WORK_AND_PERSONAL_APPS_TITLE);
+ strings.add(CONNECTED_APPS_SHARE_PERMISSIONS_AND_DATA);
+ strings.add(ONLY_CONNECT_TRUSTED_APPS);
+ strings.add(HOW_TO_DISCONNECT_APPS);
+ strings.add(CONNECT_APPS_DIALOG_TITLE);
+ strings.add(CONNECT_APPS_DIALOG_SUMMARY);
+ strings.add(APP_CAN_ACCESS_PERSONAL_DATA);
+ strings.add(APP_CAN_ACCESS_PERSONAL_PERMISSIONS);
+ strings.add(INSTALL_IN_WORK_PROFILE_TO_CONNECT_PROMPT);
+ strings.add(INSTALL_IN_PERSONAL_PROFILE_TO_CONNECT_PROMPT);
+ strings.add(WORK_PROFILE_MANAGED_BY);
+ strings.add(MANAGED_BY);
+ strings.add(WORK_PROFILE_DISABLE_USAGE_ACCESS_WARNING);
+ strings.add(DISABLED_BY_IT_ADMIN_TITLE);
+ strings.add(CONTACT_YOUR_IT_ADMIN);
+ strings.add(WORK_PROFILE_ADMIN_POLICIES_WARNING);
+ strings.add(USER_ADMIN_POLICIES_WARNING);
+ strings.add(DEVICE_ADMIN_POLICIES_WARNING);
+ strings.add(WORK_PROFILE_OFF_CONDITION_TITLE);
+ strings.add(MANAGED_PROFILE_SETTINGS_TITLE);
+ strings.add(WORK_PROFILE_CONTACT_SEARCH_TITLE);
+ strings.add(WORK_PROFILE_CONTACT_SEARCH_SUMMARY);
+ strings.add(CROSS_PROFILE_CALENDAR_TITLE);
+ strings.add(CROSS_PROFILE_CALENDAR_SUMMARY);
+ strings.add(ALWAYS_ON_VPN_PERSONAL_PROFILE);
+ strings.add(ALWAYS_ON_VPN_DEVICE);
+ strings.add(ALWAYS_ON_VPN_WORK_PROFILE);
+ strings.add(CA_CERTS_PERSONAL_PROFILE);
+ strings.add(CA_CERTS_WORK_PROFILE);
+ strings.add(CA_CERTS_DEVICE);
+ strings.add(ADMIN_CAN_LOCK_DEVICE);
+ strings.add(ADMIN_CAN_WIPE_DEVICE);
+ strings.add(ADMIN_CONFIGURED_FAILED_PASSWORD_WIPE_DEVICE);
+ strings.add(ADMIN_CONFIGURED_FAILED_PASSWORD_WIPE_WORK_PROFILE);
+ strings.add(DEVICE_MANAGED_WITHOUT_NAME);
+ strings.add(DEVICE_MANAGED_WITH_NAME);
+ strings.add(WORK_PROFILE_APP_SUBTEXT);
+ strings.add(PERSONAL_PROFILE_APP_SUBTEXT);
+ strings.add(FINGERPRINT_FOR_WORK);
+ strings.add(FACE_UNLOCK_DISABLED);
+ strings.add(FINGERPRINT_UNLOCK_DISABLED);
+ strings.add(FINGERPRINT_UNLOCK_DISABLED_EXPLANATION);
+ strings.add(PIN_RECENTLY_USED);
+ strings.add(PASSWORD_RECENTLY_USED);
+ strings.add(MANAGE_DEVICE_ADMIN_APPS);
+ strings.add(NUMBER_OF_DEVICE_ADMINS_NONE);
+ strings.add(NUMBER_OF_DEVICE_ADMINS);
+ strings.add(FORGOT_PASSWORD_TITLE);
+ strings.add(FORGOT_PASSWORD_TEXT);
+ strings.add(ERROR_MOVE_DEVICE_ADMIN);
+ strings.add(DEVICE_ADMIN_SETTINGS_TITLE);
+ strings.add(REMOVE_DEVICE_ADMIN);
+ strings.add(UNINSTALL_DEVICE_ADMIN);
+ strings.add(REMOVE_AND_UNINSTALL_DEVICE_ADMIN);
+ strings.add(SELECT_DEVICE_ADMIN_APPS);
+ strings.add(NO_DEVICE_ADMINS);
+ strings.add(ACTIVATE_DEVICE_ADMIN_APP);
+ strings.add(ACTIVATE_THIS_DEVICE_ADMIN_APP);
+ strings.add(ACTIVATE_DEVICE_ADMIN_APP_TITLE);
+ strings.add(NEW_DEVICE_ADMIN_WARNING);
+ strings.add(NEW_DEVICE_ADMIN_WARNING_SIMPLIFIED);
+ strings.add(ACTIVE_DEVICE_ADMIN_WARNING);
+ strings.add(SET_PROFILE_OWNER_TITLE);
+ strings.add(SET_PROFILE_OWNER_DIALOG_TITLE);
+ strings.add(SET_PROFILE_OWNER_POSTSETUP_WARNING);
+ strings.add(OTHER_OPTIONS_DISABLED_BY_ADMIN);
+ strings.add(REMOVE_ACCOUNT_FAILED_ADMIN_RESTRICTION);
+ strings.add(IT_ADMIN_POLICY_DISABLING_INFO_URL);
+ strings.add(SHARE_REMOTE_BUGREPORT_DIALOG_TITLE);
+ strings.add(SHARE_REMOTE_BUGREPORT_FINISHED_REQUEST_CONSENT);
+ strings.add(SHARE_REMOTE_BUGREPORT_NOT_FINISHED_REQUEST_CONSENT);
+ strings.add(SHARING_REMOTE_BUGREPORT_MESSAGE);
+ strings.add(MANAGED_DEVICE_INFO);
+ strings.add(MANAGED_DEVICE_INFO_SUMMARY);
+ strings.add(MANAGED_DEVICE_INFO_SUMMARY_WITH_NAME);
+ strings.add(ENTERPRISE_PRIVACY_HEADER);
+ strings.add(INFORMATION_YOUR_ORGANIZATION_CAN_SEE_TITLE);
+ strings.add(CHANGES_MADE_BY_YOUR_ORGANIZATION_ADMIN_TITLE);
+ strings.add(YOUR_ACCESS_TO_THIS_DEVICE_TITLE);
+ strings.add(ADMIN_CAN_SEE_WORK_DATA_WARNING);
+ strings.add(ADMIN_CAN_SEE_APPS_WARNING);
+ strings.add(ADMIN_CAN_SEE_USAGE_WARNING);
+ strings.add(ADMIN_CAN_SEE_NETWORK_LOGS_WARNING);
+ strings.add(ADMIN_CAN_SEE_BUG_REPORT_WARNING);
+ strings.add(ADMIN_CAN_SEE_SECURITY_LOGS_WARNING);
+ strings.add(ADMIN_ACTION_NONE);
+ strings.add(ADMIN_ACTION_APPS_INSTALLED);
+ strings.add(ADMIN_ACTION_APPS_COUNT_ESTIMATED);
+ strings.add(ADMIN_ACTIONS_APPS_COUNT_MINIMUM);
+ strings.add(ADMIN_ACTION_ACCESS_LOCATION);
+ strings.add(ADMIN_ACTION_ACCESS_MICROPHONE);
+ strings.add(ADMIN_ACTION_ACCESS_CAMERA);
+ strings.add(ADMIN_ACTION_SET_DEFAULT_APPS);
+ strings.add(ADMIN_ACTIONS_APPS_COUNT);
+ strings.add(ADMIN_ACTION_SET_CURRENT_INPUT_METHOD);
+ strings.add(ADMIN_ACTION_SET_INPUT_METHOD_NAME);
+ strings.add(ADMIN_ACTION_SET_HTTP_PROXY);
+ strings.add(WORK_PROFILE_PRIVACY_POLICY_INFO_SUMMARY);
+ strings.add(WORK_PROFILE_PRIVACY_POLICY_INFO);
+ strings.add(CONNECTED_APPS_SEARCH_KEYWORDS);
+ strings.add(WORK_PROFILE_UNIFICATION_SEARCH_KEYWORDS);
+ strings.add(ACCOUNTS_SEARCH_KEYWORDS);
+ strings.add(CONTROLLED_BY_ADMIN_SUMMARY);
+ strings.add(WORK_PROFILE_USER_LABEL);
+ strings.add(WORK_CATEGORY_HEADER);
+ strings.add(PERSONAL_CATEGORY_HEADER);
+ return strings;
+ }
+ }
+
+ /**
+ * Class containing the identifiers used to update device management-related system strings
* in the Launcher package.
*
* @hide
*/
public static final class Launcher {
- private Launcher(){}
+ private Launcher() {
+ }
private static final String PREFIX = "Launcher.";
@@ -576,6 +2016,7 @@
private SystemUi() {
}
+
private static final String PREFIX = "SystemUi.";
/**
@@ -649,9 +2090,9 @@
PREFIX + "QS_MSG_NAMED_WORK_PROFILE_MONITORING";
/**
- * Disclosure at the bottom of Quick Settings to indicate network activity is visible to
+ * Disclosure at the bottom of Quick Settings to indicate network activity is visible to
* admin.
- */
+ */
public static final String QS_MSG_WORK_PROFILE_NETWORK =
PREFIX + "QS_MSG_WORK_PROFILE_NETWORK";
diff --git a/core/java/android/app/admin/ParcelableResource.java b/core/java/android/app/admin/ParcelableResource.java
index dba3628..0b1b166 100644
--- a/core/java/android/app/admin/ParcelableResource.java
+++ b/core/java/android/app/admin/ParcelableResource.java
@@ -175,7 +175,7 @@
* <p>Returns the default drawable by calling the {@code defaultDrawableLoader} if the updated
* drawable was not found or could not be loaded.</p>
*/
- @NonNull
+ @Nullable
public Drawable getDrawable(
Context context,
int density,
@@ -200,7 +200,7 @@
* <p>Returns the default string by calling {@code defaultStringLoader} if the updated
* string was not found or could not be loaded.</p>
*/
- @NonNull
+ @Nullable
public String getString(
Context context,
@NonNull Callable<String> defaultStringLoader) {
@@ -267,17 +267,11 @@
/**
* returns the {@link Drawable} loaded from calling {@code defaultDrawableLoader}.
*/
- @NonNull
+ @Nullable
public static Drawable loadDefaultDrawable(@NonNull Callable<Drawable> defaultDrawableLoader) {
try {
Objects.requireNonNull(defaultDrawableLoader, "defaultDrawableLoader can't be null");
-
- Drawable drawable = defaultDrawableLoader.call();
- Objects.requireNonNull(drawable, "defaultDrawable can't be null");
-
- return drawable;
- } catch (NullPointerException rethrown) {
- throw rethrown;
+ return defaultDrawableLoader.call();
} catch (Exception e) {
throw new RuntimeException("Couldn't load default drawable: ", e);
}
@@ -286,17 +280,11 @@
/**
* returns the {@link String} loaded from calling {@code defaultStringLoader}.
*/
- @NonNull
+ @Nullable
public static String loadDefaultString(@NonNull Callable<String> defaultStringLoader) {
try {
Objects.requireNonNull(defaultStringLoader, "defaultStringLoader can't be null");
-
- String string = defaultStringLoader.call();
- Objects.requireNonNull(string, "defaultString can't be null");
-
- return string;
- } catch (NullPointerException rethrown) {
- throw rethrown;
+ return defaultStringLoader.call();
} catch (Exception e) {
throw new RuntimeException("Couldn't load default string: ", e);
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 0b8a8a2..2f06083 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5636,6 +5636,15 @@
public static final String OVERLAY_SERVICE = "overlay";
/**
+ * Use with {@link #getSystemService(String)} to manage resources.
+ *
+ * @see #getSystemService(String)
+ * @see com.android.server.resources.ResourcesManagerService
+ * @hide
+ */
+ public static final String RESOURCES_SERVICE = "resources";
+
+ /**
* Use with {@link #getSystemService(String)} to retrieve a
* {android.os.IIdmap2} for managing idmap files (used by overlay
* packages).
diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java
index 43a4b17..4c0e2e6 100644
--- a/core/java/android/content/pm/SharedLibraryInfo.java
+++ b/core/java/android/content/pm/SharedLibraryInfo.java
@@ -46,7 +46,7 @@
TYPE_BUILTIN,
TYPE_DYNAMIC,
TYPE_STATIC,
- TYPE_SDK,
+ TYPE_SDK_PACKAGE,
})
@Retention(RetentionPolicy.SOURCE)
@interface Type{}
@@ -68,15 +68,21 @@
* Shared library type: this library is <strong>not</strong> backwards
* -compatible, can be updated and updates can be uninstalled. Clients
* link against a specific version of the library.
+ *
+ * Static shared libraries simulate static linking while allowing for
+ * multiple clients to reuse the same instance of the library.
*/
public static final int TYPE_STATIC = 2;
/**
- * SDK library type: this library is <strong>not</strong> backwards
- * -compatible, can be updated and updates can be uninstalled. Clients
- * depend on a specific version of the library.
+ * SDK package shared library type: this library is <strong>not</strong>
+ * compatible between versions, can be updated and updates can be
+ * uninstalled. Clients depend on a specific version of the library.
+ *
+ * SDK packages are not loaded automatically by the OS and rely
+ * e.g. on 3P libraries to make them available for the clients.
*/
- public static final int TYPE_SDK = 3;
+ public static final int TYPE_SDK_PACKAGE = 3;
/**
* Constant for referring to an undefined version.
@@ -301,7 +307,7 @@
* @hide
*/
public boolean isSdk() {
- return mType == TYPE_SDK;
+ return mType == TYPE_SDK_PACKAGE;
}
/**
@@ -367,7 +373,7 @@
case TYPE_STATIC: {
return "static";
}
- case TYPE_SDK: {
+ case TYPE_SDK_PACKAGE: {
return "sdk";
}
default: {
diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING
index a503d14..dea0834 100644
--- a/core/java/android/content/pm/TEST_MAPPING
+++ b/core/java/android/content/pm/TEST_MAPPING
@@ -162,5 +162,68 @@
{
"name": "CtsInstallHostTestCases"
}
+ ],
+ "staged-platinum-postsubmit": [
+ {
+ "name": "CtsIncrementalInstallHostTestCases"
+ },
+ {
+ "name": "CtsInstallHostTestCases"
+ },
+ {
+ "name": "CtsStagedInstallHostTestCases"
+ },
+ {
+ "name": "CtsExtractNativeLibsHostTestCases"
+ },
+ {
+ "name": "CtsAppSecurityHostTestCases",
+ "options": [
+ {
+ "include-filter": "com.android.cts.splitapp.SplitAppTest"
+ },
+ {
+ "include-filter": "android.appsecurity.cts.EphemeralTest"
+ }
+ ]
+ },
+ {
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.pm.PackageParserTest"
+ }
+ ]
+ },
+ {
+ "name": "CtsRollbackManagerHostTestCases"
+ },
+ {
+ "name": "CtsOsHostTestCases",
+ "options": [
+ {
+ "include-filter": "com.android.server.pm.PackageParserTest"
+ }
+ ]
+ },
+ {
+ "name": "CtsContentTestCases",
+ "options": [
+ {
+ "include-filter": "android.content.cts.IntentFilterTest"
+ }
+ ]
+ },
+ {
+ "name": "CtsAppEnumerationTestCases"
+ },
+ {
+ "name": "PackageManagerServiceUnitTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.pm.test.verify.domain"
+ }
+ ]
+ }
]
}
diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java
index 6fd2d05..7a5ac8e 100644
--- a/core/java/android/content/res/ApkAssets.java
+++ b/core/java/android/content/res/ApkAssets.java
@@ -28,6 +28,7 @@
import java.io.FileDescriptor;
import java.io.IOException;
+import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
@@ -438,6 +439,12 @@
}
}
+ void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + "class=" + getClass());
+ pw.println(prefix + "debugName=" + getDebugName());
+ pw.println(prefix + "assetPath=" + getAssetPath());
+ }
+
private static native long nativeLoad(@FormatType int format, @NonNull String path,
@PropertyFlags int flags, @Nullable AssetsProvider asset) throws IOException;
private static native long nativeLoadEmpty(@PropertyFlags int flags,
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index bfd9fd0..a05f5c9 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -43,6 +43,7 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.io.PrintWriter;
import java.lang.ref.Reference;
import java.util.ArrayList;
import java.util.Arrays;
@@ -1531,6 +1532,15 @@
}
}
+ synchronized void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + "class=" + getClass());
+ pw.println(prefix + "apkAssets=");
+ for (int i = 0; i < mApkAssets.length; i++) {
+ pw.println(prefix + i);
+ mApkAssets[i].dump(pw, prefix + " ");
+ }
+ }
+
// AssetManager setup native methods.
private static native long nativeCreate();
private static native void nativeDestroy(long ptr);
diff --git a/core/java/android/content/res/IResourcesManager.aidl b/core/java/android/content/res/IResourcesManager.aidl
new file mode 100644
index 0000000..d137378
--- /dev/null
+++ b/core/java/android/content/res/IResourcesManager.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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 android.content.res;
+
+import android.os.RemoteCallback;
+
+/**
+ * Api for getting information about resources.
+ *
+ * {@hide}
+ */
+interface IResourcesManager {
+ boolean dumpResources(in String process,
+ in ParcelFileDescriptor fd,
+ in RemoteCallback finishCallback);
+}
\ No newline at end of file
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 5fd0d84..ebef053 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -53,6 +53,7 @@
import android.graphics.drawable.DrawableInflater;
import android.os.Build;
import android.os.Bundle;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -78,11 +79,15 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
/**
* Class for accessing an application's resources. This sits on top of the
@@ -172,6 +177,11 @@
private int mBaseApkAssetsSize;
+ /** @hide */
+ private static Set<Resources> sResourcesHistory = Collections.synchronizedSet(
+ Collections.newSetFromMap(
+ new WeakHashMap<>()));
+
/**
* Returns the most appropriate default theme for the specified target SDK version.
* <ul>
@@ -318,6 +328,7 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public Resources(@Nullable ClassLoader classLoader) {
mClassLoader = classLoader == null ? ClassLoader.getSystemClassLoader() : classLoader;
+ sResourcesHistory.add(this);
}
/**
@@ -2649,4 +2660,29 @@
}
}
}
+
+ /** @hide */
+ public void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + "class=" + getClass());
+ pw.println(prefix + "resourcesImpl");
+ mResourcesImpl.dump(pw, prefix + " ");
+ }
+
+ /** @hide */
+ public static void dumpHistory(PrintWriter pw, String prefix) {
+ pw.println(prefix + "history");
+ // Putting into a map keyed on the apk assets to deduplicate resources that are different
+ // objects but ultimately represent the same assets
+ Map<List<ApkAssets>, Resources> history = new ArrayMap<>();
+ for (Resources r : sResourcesHistory) {
+ history.put(Arrays.asList(r.mResourcesImpl.mAssets.getApkAssets()), r);
+ }
+ int i = 0;
+ for (Resources r : history.values()) {
+ if (r != null) {
+ pw.println(prefix + i++);
+ r.dump(pw, prefix + " ");
+ }
+ }
+ }
}
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index 4d850b0c..ff07291 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -61,6 +61,7 @@
import java.io.IOException;
import java.io.InputStream;
+import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Locale;
@@ -1271,6 +1272,12 @@
NativeAllocationRegistry.createMalloced(ResourcesImpl.class.getClassLoader(),
AssetManager.getThemeFreeFunction());
+ void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + "class=" + getClass());
+ pw.println(prefix + "assets");
+ mAssets.dump(pw, prefix + " ");
+ }
+
public class ThemeImpl {
/**
* Unique key for the series of styles applied to this theme.
diff --git a/core/java/android/hardware/devicestate/DeviceStateManager.java b/core/java/android/hardware/devicestate/DeviceStateManager.java
index b06d076..30aa4db 100644
--- a/core/java/android/hardware/devicestate/DeviceStateManager.java
+++ b/core/java/android/hardware/devicestate/DeviceStateManager.java
@@ -79,9 +79,9 @@
* <ul>
* <li>The system deems the request can no longer be honored, for example if the requested
* state becomes unsupported.
- * <li>A call to {@link #cancelRequest(DeviceStateRequest)}.
+ * <li>A call to {@link #cancelStateRequest}.
* <li>Another processes submits a request succeeding this request in which case the request
- * will be suspended until the interrupting request is canceled.
+ * will be canceled.
* </ul>
* However, this behavior can be changed by setting flags on the {@link DeviceStateRequest}.
*
@@ -100,19 +100,18 @@
}
/**
- * Cancels a {@link DeviceStateRequest request} previously submitted with a call to
+ * Cancels the active {@link DeviceStateRequest} previously submitted with a call to
* {@link #requestState(DeviceStateRequest, Executor, DeviceStateRequest.Callback)}.
* <p>
- * This method is noop if the {@code request} has not been submitted with a call to
- * {@link #requestState(DeviceStateRequest, Executor, DeviceStateRequest.Callback)}.
+ * This method is noop if there is no request currently active.
*
* @throws SecurityException if the caller is neither the current top-focused activity nor if
* the {@link android.Manifest.permission#CONTROL_DEVICE_STATE} permission is held.
*/
@RequiresPermission(value = android.Manifest.permission.CONTROL_DEVICE_STATE,
conditional = true)
- public void cancelRequest(@NonNull DeviceStateRequest request) {
- mGlobal.cancelRequest(request);
+ public void cancelStateRequest() {
+ mGlobal.cancelStateRequest();
}
/**
diff --git a/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java b/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java
index 85e70b0..aba538f 100644
--- a/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java
+++ b/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java
@@ -151,20 +151,14 @@
* Cancels a {@link DeviceStateRequest request} previously submitted with a call to
* {@link #requestState(DeviceStateRequest, Executor, DeviceStateRequest.Callback)}.
*
- * @see DeviceStateManager#cancelRequest(DeviceStateRequest)
+ * @see DeviceStateManager#cancelStateRequest
*/
- public void cancelRequest(@NonNull DeviceStateRequest request) {
+ public void cancelStateRequest() {
synchronized (mLock) {
registerCallbackIfNeededLocked();
- final IBinder token = findRequestTokenLocked(request);
- if (token == null) {
- // This request has not been submitted.
- return;
- }
-
try {
- mDeviceStateManager.cancelRequest(token);
+ mDeviceStateManager.cancelStateRequest();
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
@@ -299,20 +293,6 @@
/**
* Handles a call from the server that a request for the supplied {@code token} has become
- * suspended.
- */
- private void handleRequestSuspended(IBinder token) {
- DeviceStateRequestWrapper request;
- synchronized (mLock) {
- request = mRequests.get(token);
- }
- if (request != null) {
- request.notifyRequestSuspended();
- }
- }
-
- /**
- * Handles a call from the server that a request for the supplied {@code token} has become
* canceled.
*/
private void handleRequestCanceled(IBinder token) {
@@ -337,11 +317,6 @@
}
@Override
- public void onRequestSuspended(IBinder token) {
- handleRequestSuspended(token);
- }
-
- @Override
public void onRequestCanceled(IBinder token) {
handleRequestCanceled(token);
}
@@ -395,14 +370,6 @@
mExecutor.execute(() -> mCallback.onRequestActivated(mRequest));
}
- void notifyRequestSuspended() {
- if (mCallback == null) {
- return;
- }
-
- mExecutor.execute(() -> mCallback.onRequestSuspended(mRequest));
- }
-
void notifyRequestCanceled() {
if (mCallback == null) {
return;
diff --git a/core/java/android/hardware/devicestate/DeviceStateRequest.java b/core/java/android/hardware/devicestate/DeviceStateRequest.java
index df488d2..893d765 100644
--- a/core/java/android/hardware/devicestate/DeviceStateRequest.java
+++ b/core/java/android/hardware/devicestate/DeviceStateRequest.java
@@ -32,8 +32,7 @@
* DeviceStateRequest.Callback)}.
* <p>
* By default, the request is kept active until a call to
- * {@link DeviceStateManager#cancelRequest(DeviceStateRequest)} or until one of the following
- * occurs:
+ * {@link DeviceStateManager#cancelStateRequest} or until one of the following occurs:
* <ul>
* <li>Another processes submits a request succeeding this request in which case the request
* will be suspended until the interrupting request is canceled.
diff --git a/core/java/android/hardware/devicestate/IDeviceStateManager.aidl b/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
index 14ed03d..e450e42 100644
--- a/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
+++ b/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
@@ -41,8 +41,9 @@
* previously registered with {@link #registerCallback(IDeviceStateManagerCallback)} before a
* call to this method.
*
- * @param token the request token previously registered with
- * {@link #requestState(IBinder, int, int)}
+ * @param token the request token provided
+ * @param state the state of device the request is asking for
+ * @param flags any flags that correspond to the request
*
* @throws IllegalStateException if a callback has not yet been registered for the calling
* process.
@@ -52,14 +53,11 @@
void requestState(IBinder token, int state, int flags);
/**
- * Cancels a request previously submitted with a call to
+ * Cancels the active request previously submitted with a call to
* {@link #requestState(IBinder, int, int)}.
*
- * @param token the request token previously registered with
- * {@link #requestState(IBinder, int, int)}
- *
- * @throws IllegalStateException if the supplied {@code token} has not been previously
- * requested.
+ * @throws IllegalStateException if a callback has not yet been registered for the calling
+ * process.
*/
- void cancelRequest(IBinder token);
+ void cancelStateRequest();
}
diff --git a/core/java/android/hardware/devicestate/IDeviceStateManagerCallback.aidl b/core/java/android/hardware/devicestate/IDeviceStateManagerCallback.aidl
index efb9888..348690f 100644
--- a/core/java/android/hardware/devicestate/IDeviceStateManagerCallback.aidl
+++ b/core/java/android/hardware/devicestate/IDeviceStateManagerCallback.aidl
@@ -41,16 +41,6 @@
oneway void onRequestActive(IBinder token);
/**
- * Called to notify the callback that a request has become suspended. Guaranteed to be called
- * before a subsequent call to {@link #onDeviceStateInfoChanged(DeviceStateInfo)} if the request
- * becoming suspended resulted in a change of device state info.
- *
- * @param token the request token previously registered with
- * {@link IDeviceStateManager#requestState(IBinder, int, int)}
- */
- oneway void onRequestSuspended(IBinder token);
-
- /**
* Called to notify the callback that a request has become canceled. No further callbacks will
* be triggered for this request. Guaranteed to be called before a subsequent call to
* {@link #onDeviceStateInfoChanged(DeviceStateInfo)} if the request becoming canceled resulted
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 60f5135..7ff74c6 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -1341,7 +1341,6 @@
*
* @hide
*/
- @SystemApi
@RequiresPermission(Manifest.permission.MANAGE_USB)
boolean resetUsbPort(@NonNull UsbPort port, int operationId,
IUsbOperationInternal callback) {
diff --git a/core/java/android/os/VibrationAttributes.java b/core/java/android/os/VibrationAttributes.java
index 49c0520..d223a19 100644
--- a/core/java/android/os/VibrationAttributes.java
+++ b/core/java/android/os/VibrationAttributes.java
@@ -106,20 +106,28 @@
public static final int USAGE_NOTIFICATION = 0x30 | USAGE_CLASS_ALARM;
/**
* Usage value to use for vibrations which mean a request to enter/end a
- * communication, such as a VoIP communication or video-conference.
+ * communication with the user, such as a voice prompt.
*/
public static final int USAGE_COMMUNICATION_REQUEST = 0x40 | USAGE_CLASS_ALARM;
/**
* Usage value to use for touch vibrations.
+ *
+ * <p>Most typical haptic feedback should be classed as <em>touch</em> feedback. Examples
+ * include vibrations for tap, long press, drag and scroll.
*/
public static final int USAGE_TOUCH = 0x10 | USAGE_CLASS_FEEDBACK;
/**
- * Usage value to use for vibrations which emulate physical effects, such as edge squeeze.
+ * Usage value to use for vibrations which emulate physical hardware reactions,
+ * such as edge squeeze.
+ *
+ * <p>Note that normal screen-touch feedback "click" effects would typically be
+ * classed as {@link #USAGE_TOUCH}, and that on-screen "physical" animations
+ * like bouncing would be {@link #USAGE_MEDIA}.
*/
public static final int USAGE_PHYSICAL_EMULATION = 0x20 | USAGE_CLASS_FEEDBACK;
/**
- * Usage value to use for vibrations which provide a feedback for hardware interaction,
- * such as a fingerprint sensor.
+ * Usage value to use for vibrations which provide a feedback for hardware
+ * component interaction, such as a fingerprint sensor.
*/
public static final int USAGE_HARDWARE_FEEDBACK = 0x30 | USAGE_CLASS_FEEDBACK;
/**
@@ -183,7 +191,6 @@
/**
* Return the vibration usage class.
- * @return USAGE_CLASS_ALARM, USAGE_CLASS_FEEDBACK or USAGE_CLASS_UNKNOWN
*/
@UsageClass
public int getUsageClass() {
@@ -192,7 +199,6 @@
/**
* Return the vibration usage.
- * @return one of the values that can be set in {@link Builder#setUsage(int)}
*/
@Usage
public int getUsage() {
@@ -429,16 +435,8 @@
}
/**
- * Sets the attribute describing the type of corresponding vibration.
- * @param usage one of {@link VibrationAttributes#USAGE_ALARM},
- * {@link VibrationAttributes#USAGE_RINGTONE},
- * {@link VibrationAttributes#USAGE_NOTIFICATION},
- * {@link VibrationAttributes#USAGE_COMMUNICATION_REQUEST},
- * {@link VibrationAttributes#USAGE_TOUCH},
- * {@link VibrationAttributes#USAGE_PHYSICAL_EMULATION},
- * {@link VibrationAttributes#USAGE_HARDWARE_FEEDBACK}.
- * {@link VibrationAttributes#USAGE_ACCESSIBILITY}.
- * {@link VibrationAttributes#USAGE_MEDIA}.
+ * Sets the attribute describing the type of the corresponding vibration.
+ * @param usage The type of usage for the vibration
* @return the same Builder instance.
*/
public @NonNull Builder setUsage(@Usage int usage) {
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index f490587..9598410 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -194,27 +194,27 @@
}
/**
- * Create a waveform vibration.
+ * Create a waveform vibration, using only off/on transitions at the provided time intervals,
+ * and potentially repeating.
*
- * <p>Waveform vibrations are a potentially repeating series of timing and amplitude pairs. For
- * each pair, the value in the amplitude array determines the strength of the vibration and the
- * value in the timing array determines how long it vibrates for. An amplitude of 0 implies no
- * vibration (i.e. off), and any pairs with a timing value of 0 will be ignored.
+ * <p>In effect, the timings array represents the number of milliseconds <em>before</em> turning
+ * the vibrator on, followed by the number of milliseconds to keep the vibrator on, then
+ * the number of milliseconds turned off, and so on. Consequently, the first timing value will
+ * often be 0, so that the effect will start vibrating immediately.
*
- * <p>The amplitude array of the generated waveform will be the same size as the given
- * timing array with alternating values of 0 (i.e. off) and {@link #DEFAULT_AMPLITUDE},
- * starting with 0. Therefore the first timing value will be the period to wait before turning
- * the vibrator on, the second value will be how long to vibrate at {@link #DEFAULT_AMPLITUDE}
- * strength, etc.
+ * <p>This method is equivalent to calling {@link #createWaveform(long[], int[], int)} with
+ * corresponding amplitude values alternating between 0 and {@link #DEFAULT_AMPLITUDE},
+ * beginning with 0.
*
* <p>To cause the pattern to repeat, pass the index into the timings array at which to start
* the repetition, or -1 to disable repeating. Repeating effects will be played indefinitely
* and should be cancelled via {@link Vibrator#cancel()}.
*
- * @param timings The pattern of alternating on-off timings, starting with off. Timing values
- * of 0 will cause the timing / amplitude pair to be ignored.
- * @param repeat The index into the timings array at which to repeat, or -1 if you you don't
- * want to repeat.
+ * @param timings The pattern of alternating on-off timings, starting with an 'off' timing, and
+ * representing the length of time to sustain the individual item (not
+ * cumulative).
+ * @param repeat The index into the timings array at which to repeat, or -1 if you don't
+ * want to repeat indefinitely.
*
* @return The desired effect.
*/
@@ -229,11 +229,10 @@
/**
* Create a waveform vibration.
*
- * <p>Waveform vibrations are a potentially repeating series of timing and amplitude pairs. For
- * each pair, the value in the amplitude array determines the strength of the vibration and the
- * value in the timing array determines how long it vibrates for, in milliseconds. Amplitude
- * values must be between 0 and 255, and an amplitude of 0 implies no vibration (i.e. off). Any
- * pairs with a timing value of 0 will be ignored.
+ * <p>Waveform vibrations are a potentially repeating series of timing and amplitude pairs,
+ * provided in separate arrays. For each pair, the value in the amplitude array determines
+ * the strength of the vibration and the value in the timing array determines how long it
+ * vibrates for, in milliseconds.
*
* <p>To cause the pattern to repeat, pass the index into the timings array at which to start
* the repetition, or -1 to disable repeating. Repeating effects will be played indefinitely
@@ -244,8 +243,8 @@
* @param amplitudes The amplitude values of the timing / amplitude pairs. Amplitude values
* must be between 0 and 255, or equal to {@link #DEFAULT_AMPLITUDE}. An
* amplitude value of 0 implies the motor is off.
- * @param repeat The index into the timings array at which to repeat, or -1 if you you don't
- * want to repeat.
+ * @param repeat The index into the timings array at which to repeat, or -1 if you don't
+ * want to repeat indefinitely.
*
* @return The desired effect.
*/
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 23baa5d..8f50860 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -98,7 +98,8 @@
/**
* Vibration effect support: unsupported
*
- * This effect is <b>not</b> supported by the underlying hardware.
+ * This effect is <b>not</b> natively supported by the underlying hardware, although
+ * the system may still play a fallback vibration.
*/
public static final int VIBRATION_EFFECT_SUPPORT_NO = 2;
@@ -485,20 +486,25 @@
String reason, @NonNull VibrationAttributes attributes);
/**
- * Query whether the vibrator supports the given effects.
+ * Query whether the vibrator natively supports the given effects.
*
- * Not all hardware reports its effect capabilities, so the system may not necessarily know
- * whether an effect is supported or not.
+ * <p>If an effect is not supported, the system may still automatically fall back to playing
+ * a simpler vibration instead, which is not optimised for the specific device. This includes
+ * the unknown case, which can't be determined in advance, that will dynamically attempt to
+ * fall back if the optimised effect fails to play.
*
- * The returned array will be the same length as the query array and the value at a given index
- * will contain {@link #VIBRATION_EFFECT_SUPPORT_YES} if the effect at that same index in the
- * querying array is supported, {@link #VIBRATION_EFFECT_SUPPORT_NO} if it isn't supported, or
- * {@link #VIBRATION_EFFECT_SUPPORT_UNKNOWN} if the system can't determine whether it's
- * supported or not.
+ * <p>The returned array will be the same length as the query array and the value at a given
+ * index will contain {@link #VIBRATION_EFFECT_SUPPORT_YES} if the effect at that same index
+ * in the querying array is supported, {@link #VIBRATION_EFFECT_SUPPORT_NO} if it isn't
+ * supported, or {@link #VIBRATION_EFFECT_SUPPORT_UNKNOWN} if the system can't determine whether
+ * it's supported or not, as some hardware doesn't report its effect capabilities.
+ *
+ * <p>Use {@link #areAllEffectsSupported(int...)} to get a single combined result,
+ * or for convenience when querying exactly one effect.
*
* @param effectIds Which effects to query for.
* @return An array containing the systems current knowledge about whether the given effects
- * are supported or not.
+ * are natively supported by the device, or not.
*/
@NonNull
@VibrationEffectSupport
@@ -515,23 +521,27 @@
/**
* Query whether the vibrator supports all of the given effects.
*
- * Not all hardware reports its effect capabilities, so the system may not necessarily know
- * whether an effect is supported or not.
+ * <p>If an effect is not supported, the system may still automatically fall back to a simpler
+ * vibration instead, which is not optimised for the specific device, however vibration isn't
+ * guaranteed in this case.
*
- * If the result is {@link #VIBRATION_EFFECT_SUPPORT_YES}, all effects in the query are
+ * <p>If the result is {@link #VIBRATION_EFFECT_SUPPORT_YES}, all effects in the query are
* supported by the hardware.
*
- * If the result is {@link #VIBRATION_EFFECT_SUPPORT_NO}, at least one of the effects in the
- * query is not supported.
+ * <p>If the result is {@link #VIBRATION_EFFECT_SUPPORT_NO}, at least one of the effects in the
+ * query is not supported, and using them may fall back to an un-optimized vibration or no
+ * vibration.
*
- * If the result is {@link #VIBRATION_EFFECT_SUPPORT_UNKNOWN}, the system doesn't know whether
- * all of the effects are supported. It may support any or all of the queried effects,
+ * <p>If the result is {@link #VIBRATION_EFFECT_SUPPORT_UNKNOWN}, the system doesn't know
+ * whether all of the effects are supported. It may support any or all of the queried effects,
* but there's no way to programmatically know whether a {@link #vibrate} call will successfully
* cause a vibration. It's guaranteed, however, that none of the queried effects are
* definitively unsupported by the hardware.
*
+ * <p>Use {@link #areEffectsSupported(int...)} to get individual results for each effect.
+ *
* @param effectIds Which effects to query for.
- * @return Whether all of the effects are supported.
+ * @return Whether all of the effects are natively supported by the device.
*/
@VibrationEffectSupport
public final int areAllEffectsSupported(
@@ -555,6 +565,12 @@
* will contain whether the effect at that same index in the querying array is supported or
* not.
*
+ * <p>If a primitive is not supported by the device, then <em>no vibration</em> will occur if
+ * it is played.
+ *
+ * <p>Use {@link #areAllPrimitivesSupported(int...)} to get a single combined result,
+ * or for convenience when querying exactly one primitive.
+ *
* @param primitiveIds Which primitives to query for.
* @return Whether the primitives are supported.
*/
@@ -572,8 +588,13 @@
/**
* Query whether the vibrator supports all of the given primitives.
*
+ * <p>If a primitive is not supported by the device, then <em>no vibration</em> will occur if
+ * it is played.
+ *
+ * <p>Use {@link #arePrimitivesSupported(int...)} to get individual results for each primitive.
+ *
* @param primitiveIds Which primitives to query for.
- * @return Whether primitives effects are supported.
+ * @return Whether all specified primitives are supported.
*/
public final boolean areAllPrimitivesSupported(
@NonNull @VibrationEffect.Composition.PrimitiveType int... primitiveIds) {
diff --git a/core/java/android/service/games/GameSession.java b/core/java/android/service/games/GameSession.java
index f4baedc..9590933 100644
--- a/core/java/android/service/games/GameSession.java
+++ b/core/java/android/service/games/GameSession.java
@@ -278,7 +278,7 @@
*
* @return {@code true} if the game was successfully restarted; otherwise, {@code false}.
*/
- @RequiresPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
+ @RequiresPermission(android.Manifest.permission.MANAGE_GAME_ACTIVITY)
public final boolean restartGame() {
try {
mGameSessionController.restartGame(mTaskId);
diff --git a/core/java/android/view/IDisplayWindowListener.aidl b/core/java/android/view/IDisplayWindowListener.aidl
index 449e9b3..67ae743 100644
--- a/core/java/android/view/IDisplayWindowListener.aidl
+++ b/core/java/android/view/IDisplayWindowListener.aidl
@@ -63,5 +63,5 @@
/**
* Called when the keep clear ares on a display have changed.
*/
- void onKeepClearAreasChanged(int displayId, in List<Rect> keepClearAreas);
+ void onKeepClearAreasChanged(int displayId, in List<Rect> restricted, in List<Rect> unrestricted);
}
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index 9552691..2134d81 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -291,6 +291,8 @@
* <p>Typically used to change the context associated with the default session from an activity.
*/
public final void setContentCaptureContext(@Nullable ContentCaptureContext context) {
+ if (!isContentCaptureEnabled()) return;
+
mClientContext = context;
updateContentCaptureContext(context);
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 41c5401..7c939ac 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4461,7 +4461,7 @@
* pixel" units. This size is adjusted based on the current density and
* user font size preference.
*
- * <p>Note: if this TextView has the auto-size feature enabled than this function is no-op.
+ * <p>Note: if this TextView has the auto-size feature enabled, then this function is no-op.
*
* @param size The scaled pixel size.
*
@@ -4476,7 +4476,7 @@
* Set the default text size to a given unit and value. See {@link
* TypedValue} for the possible dimension units.
*
- * <p>Note: if this TextView has the auto-size feature enabled than this function is no-op.
+ * <p>Note: if this TextView has the auto-size feature enabled, then this function is no-op.
*
* @param unit The desired dimension unit.
* @param size The desired size in the given units.
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 4fc977f..c0fec62 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -2013,17 +2013,15 @@
private final TimeBase mTimeBase;
private final LongArrayMultiStateCounter mCounter;
- private TimeInFreqMultiStateCounter(TimeBase timeBase, Parcel in, long timestampMs) {
- mTimeBase = timeBase;
- mCounter = LongArrayMultiStateCounter.CREATOR.createFromParcel(in);
- mCounter.setEnabled(mTimeBase.isRunning(), timestampMs);
- timeBase.add(this);
- }
-
private TimeInFreqMultiStateCounter(TimeBase timeBase, int stateCount, int cpuFreqCount,
long timestampMs) {
+ this(timeBase, new LongArrayMultiStateCounter(stateCount, cpuFreqCount), timestampMs);
+ }
+
+ private TimeInFreqMultiStateCounter(TimeBase timeBase, LongArrayMultiStateCounter counter,
+ long timestampMs) {
mTimeBase = timeBase;
- mCounter = new LongArrayMultiStateCounter(stateCount, cpuFreqCount);
+ mCounter = counter;
mCounter.setEnabled(mTimeBase.isRunning(), timestampMs);
timeBase.add(this);
}
@@ -2032,6 +2030,19 @@
mCounter.writeToParcel(out, 0);
}
+ @Nullable
+ private static TimeInFreqMultiStateCounter readFromParcel(Parcel in, TimeBase timeBase,
+ int stateCount, int cpuFreqCount, long timestampMs) {
+ // Read the object from the Parcel, whether it's usable or not
+ LongArrayMultiStateCounter counter =
+ LongArrayMultiStateCounter.CREATOR.createFromParcel(in);
+ if (counter.getStateCount() != stateCount
+ || counter.getArrayLength() != cpuFreqCount) {
+ return null;
+ }
+ return new TimeInFreqMultiStateCounter(timeBase, counter, timestampMs);
+ }
+
@Override
public void onTimeStarted(long elapsedRealtimeUs, long baseUptimeUs, long baseRealtimeUs) {
mCounter.setEnabled(true, elapsedRealtimeUs / 1000);
@@ -10784,25 +10795,18 @@
stateCount = in.readInt();
if (stateCount != 0) {
- // Read the object from the Parcel, whether it's usable or not
- TimeInFreqMultiStateCounter counter = new TimeInFreqMultiStateCounter(
- mBsi.mOnBatteryTimeBase, in, timestampMs);
- if (stateCount == PROC_STATE_TIME_COUNTER_STATE_COUNT) {
- mProcStateTimeMs = counter;
- }
+ mProcStateTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in,
+ mBsi.mOnBatteryTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT,
+ mBsi.getCpuFreqCount(), mBsi.mClock.elapsedRealtime());
} else {
mProcStateTimeMs = null;
}
stateCount = in.readInt();
if (stateCount != 0) {
- // Read the object from the Parcel, whether it's usable or not
- TimeInFreqMultiStateCounter counter =
- new TimeInFreqMultiStateCounter(
- mBsi.mOnBatteryScreenOffTimeBase, in, timestampMs);
- if (stateCount == PROC_STATE_TIME_COUNTER_STATE_COUNT) {
- mProcStateScreenOffTimeMs = counter;
- }
+ mProcStateScreenOffTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in,
+ mBsi.mOnBatteryScreenOffTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT,
+ mBsi.getCpuFreqCount(), mBsi.mClock.elapsedRealtime());
} else {
mProcStateScreenOffTimeMs = null;
}
@@ -16361,6 +16365,11 @@
BATTERY_CHARGED_DELAY_MS = delay >= 0 ? delay : mParser.getInt(
KEY_BATTERY_CHARGED_DELAY_MS,
DEFAULT_BATTERY_CHARGED_DELAY_MS);
+
+ if (mHandler.hasCallbacks(mDeferSetCharging)) {
+ mHandler.removeCallbacks(mDeferSetCharging);
+ mHandler.postDelayed(mDeferSetCharging, BATTERY_CHARGED_DELAY_MS);
+ }
}
private void updateKernelUidReadersThrottleTime(long oldTimeMs, long newTimeMs) {
@@ -17160,12 +17169,10 @@
stateCount = in.readInt();
if (stateCount != 0) {
- // Read the object from the Parcel, whether it's usable or not
- TimeInFreqMultiStateCounter counter = new TimeInFreqMultiStateCounter(
- mOnBatteryTimeBase, in, mClock.elapsedRealtime());
- if (stateCount == PROC_STATE_TIME_COUNTER_STATE_COUNT) {
- u.mProcStateTimeMs = counter;
- }
+ detachIfNotNull(u.mProcStateTimeMs);
+ u.mProcStateTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in,
+ mOnBatteryTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT,
+ getCpuFreqCount(), mClock.elapsedRealtime());
}
detachIfNotNull(u.mProcStateScreenOffTimeMs);
@@ -17174,13 +17181,9 @@
stateCount = in.readInt();
if (stateCount != 0) {
detachIfNotNull(u.mProcStateScreenOffTimeMs);
- // Read the object from the Parcel, whether it's usable or not
- TimeInFreqMultiStateCounter counter =
- new TimeInFreqMultiStateCounter(
- mOnBatteryScreenOffTimeBase, in, mClock.elapsedRealtime());
- if (stateCount == PROC_STATE_TIME_COUNTER_STATE_COUNT) {
- u.mProcStateScreenOffTimeMs = counter;
- }
+ u.mProcStateScreenOffTimeMs = TimeInFreqMultiStateCounter.readFromParcel(in,
+ mOnBatteryScreenOffTimeBase, PROC_STATE_TIME_COUNTER_STATE_COUNT,
+ getCpuFreqCount(), mClock.elapsedRealtime());
}
if (in.readInt() != 0) {
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 430d84e..8bb9a0a 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -195,7 +195,6 @@
"android_util_FileObserver.cpp",
"android/opengl/poly_clip.cpp", // TODO: .arm
"android/opengl/util.cpp",
- "android_server_NetworkManagementSocketTagger.cpp",
"android_ddm_DdmHandleNativeHeap.cpp",
"android_backup_BackupDataInput.cpp",
"android_backup_BackupDataOutput.cpp",
@@ -310,6 +309,8 @@
"libdl_android",
"libtimeinstate",
"server_configurable_flags",
+ // TODO: delete when ConnectivityT moves to APEX.
+ "libframework-connectivity-tiramisu-jni",
],
export_shared_lib_headers: [
// our headers include libnativewindow's public headers
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index f4296be..cde71cf 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -164,7 +164,6 @@
extern int register_android_text_Hyphenator(JNIEnv *env);
extern int register_android_opengl_classes(JNIEnv *env);
extern int register_android_ddm_DdmHandleNativeHeap(JNIEnv *env);
-extern int register_android_server_NetworkManagementSocketTagger(JNIEnv* env);
extern int register_android_backup_BackupDataInput(JNIEnv *env);
extern int register_android_backup_BackupDataOutput(JNIEnv *env);
extern int register_android_backup_FileBackupHelperBase(JNIEnv *env);
@@ -1623,7 +1622,6 @@
REG_JNI(register_android_media_midi),
REG_JNI(register_android_opengl_classes),
- REG_JNI(register_android_server_NetworkManagementSocketTagger),
REG_JNI(register_android_ddm_DdmHandleNativeHeap),
REG_JNI(register_android_backup_BackupDataInput),
REG_JNI(register_android_backup_BackupDataOutput),
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 82601ba..d852265 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -643,6 +643,8 @@
return (type == GL_UNSIGNED_SHORT_5_6_5 && internalformat == GL_RGB);
case ANDROID_BITMAP_FORMAT_RGBA_F16:
return (type == GL_HALF_FLOAT && internalformat == GL_RGBA16F);
+ case ANDROID_BITMAP_FORMAT_RGBA_1010102:
+ return (type == GL_UNSIGNED_INT_2_10_10_10_REV && internalformat == GL_RGB10_A2);
default:
break;
}
@@ -676,6 +678,8 @@
return GL_RGB;
case ANDROID_BITMAP_FORMAT_RGBA_F16:
return GL_RGBA16F;
+ case ANDROID_BITMAP_FORMAT_RGBA_1010102:
+ return GL_RGB10_A2;
default:
return -1;
}
@@ -693,6 +697,8 @@
return GL_UNSIGNED_SHORT_5_6_5;
case ANDROID_BITMAP_FORMAT_RGBA_F16:
return GL_HALF_FLOAT;
+ case ANDROID_BITMAP_FORMAT_RGBA_1010102:
+ return GL_UNSIGNED_INT_2_10_10_10_REV;
default:
return -1;
}
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 6b82ba8..edc8c5b 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -204,6 +204,12 @@
jclass gAudioProfileClass;
jmethodID gAudioProfileCstor;
+static struct {
+ jfieldID mSamplingRates;
+ jfieldID mChannelMasks;
+ jfieldID mChannelIndexMasks;
+ jfieldID mEncapsulationType;
+} gAudioProfileFields;
jclass gVibratorClass;
static struct {
@@ -1340,81 +1346,50 @@
jStatus = (jint)AUDIO_JAVA_ERROR;
goto exit;
}
+
for (size_t i = 0; i < nAudioPort->num_audio_profiles; ++i) {
- size_t numPositionMasks = 0;
- size_t numIndexMasks = 0;
- // count up how many masks are positional and indexed
- for (size_t index = 0; index < nAudioPort->audio_profiles[i].num_channel_masks; index++) {
- const audio_channel_mask_t mask = nAudioPort->audio_profiles[i].channel_masks[index];
- if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
- numIndexMasks++;
- } else {
- numPositionMasks++;
- }
- }
-
- ScopedLocalRef<jintArray> jSamplingRates(env,
- env->NewIntArray(nAudioPort->audio_profiles[i]
- .num_sample_rates));
- ScopedLocalRef<jintArray> jChannelMasks(env, env->NewIntArray(numPositionMasks));
- ScopedLocalRef<jintArray> jChannelIndexMasks(env, env->NewIntArray(numIndexMasks));
- if (!jSamplingRates.get() || !jChannelMasks.get() || !jChannelIndexMasks.get()) {
+ jobject jAudioProfile = nullptr;
+ jStatus = convertAudioProfileFromNative(env, &jAudioProfile, &nAudioPort->audio_profiles[i],
+ useInMask);
+ if (jStatus != NO_ERROR) {
jStatus = (jint)AUDIO_JAVA_ERROR;
goto exit;
}
+ env->CallBooleanMethod(jAudioProfiles, gArrayListMethods.add, jAudioProfile);
- if (nAudioPort->audio_profiles[i].num_sample_rates) {
- env->SetIntArrayRegion(jSamplingRates.get(), 0 /*start*/,
- nAudioPort->audio_profiles[i].num_sample_rates,
- (jint *)nAudioPort->audio_profiles[i].sample_rates);
- }
-
- // put the masks in the output arrays
- for (size_t maskIndex = 0, posMaskIndex = 0, indexedMaskIndex = 0;
- maskIndex < nAudioPort->audio_profiles[i].num_channel_masks; maskIndex++) {
- const audio_channel_mask_t mask =
- nAudioPort->audio_profiles[i].channel_masks[maskIndex];
- if (audio_channel_mask_get_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_INDEX) {
- jint jMask = audio_channel_mask_get_bits(mask);
- env->SetIntArrayRegion(jChannelIndexMasks.get(), indexedMaskIndex++, 1, &jMask);
- } else {
- jint jMask =
- useInMask ? inChannelMaskFromNative(mask) : outChannelMaskFromNative(mask);
- env->SetIntArrayRegion(jChannelMasks.get(), posMaskIndex++, 1, &jMask);
- }
- }
-
- int encapsulationType;
- if (audioEncapsulationTypeFromNative(nAudioPort->audio_profiles[i].encapsulation_type,
- &encapsulationType) != NO_ERROR) {
- ALOGW("Unknown encapsualtion type for JAVA API: %u",
- nAudioPort->audio_profiles[i].encapsulation_type);
- continue;
- }
-
- ScopedLocalRef<jobject>
- jAudioProfile(env,
- env->NewObject(gAudioProfileClass, gAudioProfileCstor,
- audioFormatFromNative(
- nAudioPort->audio_profiles[i].format),
- jSamplingRates.get(), jChannelMasks.get(),
- jChannelIndexMasks.get(), encapsulationType));
- if (jAudioProfile == nullptr) {
- jStatus = (jint)AUDIO_JAVA_ERROR;
- goto exit;
- }
- env->CallBooleanMethod(jAudioProfiles, gArrayListMethods.add, jAudioProfile.get());
if (nAudioPort->audio_profiles[i].format == AUDIO_FORMAT_PCM_FLOAT) {
hasFloat = true;
} else if (jPcmFloatProfileFromExtendedInteger.get() == nullptr &&
audio_is_linear_pcm(nAudioPort->audio_profiles[i].format) &&
audio_bytes_per_sample(nAudioPort->audio_profiles[i].format) > 2) {
+ ScopedLocalRef<jintArray>
+ jSamplingRates(env,
+ (jintArray)
+ env->GetObjectField(jAudioProfile,
+ gAudioProfileFields.mSamplingRates));
+ ScopedLocalRef<jintArray>
+ jChannelMasks(env,
+ (jintArray)
+ env->GetObjectField(jAudioProfile,
+ gAudioProfileFields.mChannelMasks));
+ ScopedLocalRef<jintArray>
+ jChannelIndexMasks(env,
+ (jintArray)env->GetObjectField(jAudioProfile,
+ gAudioProfileFields
+ .mChannelIndexMasks));
+ int encapsulationType =
+ env->GetIntField(jAudioProfile, gAudioProfileFields.mEncapsulationType);
+
jPcmFloatProfileFromExtendedInteger.reset(
env->NewObject(gAudioProfileClass, gAudioProfileCstor,
audioFormatFromNative(AUDIO_FORMAT_PCM_FLOAT),
jSamplingRates.get(), jChannelMasks.get(),
jChannelIndexMasks.get(), encapsulationType));
}
+
+ if (jAudioProfile != nullptr) {
+ env->DeleteLocalRef(jAudioProfile);
+ }
}
if (!hasFloat && jPcmFloatProfileFromExtendedInteger.get() != nullptr) {
// R and earlier compatibility - add ENCODING_PCM_FLOAT to the end
@@ -3285,6 +3260,14 @@
jclass audioProfileClass = FindClassOrDie(env, "android/media/AudioProfile");
gAudioProfileClass = MakeGlobalRefOrDie(env, audioProfileClass);
gAudioProfileCstor = GetMethodIDOrDie(env, audioProfileClass, "<init>", "(I[I[I[II)V");
+ gAudioProfileFields.mSamplingRates =
+ GetFieldIDOrDie(env, audioProfileClass, "mSamplingRates", "[I");
+ gAudioProfileFields.mChannelMasks =
+ GetFieldIDOrDie(env, audioProfileClass, "mChannelMasks", "[I");
+ gAudioProfileFields.mChannelIndexMasks =
+ GetFieldIDOrDie(env, audioProfileClass, "mChannelIndexMasks", "[I");
+ gAudioProfileFields.mEncapsulationType =
+ GetFieldIDOrDie(env, audioProfileClass, "mEncapsulationType", "I");
jclass audioDescriptorClass = FindClassOrDie(env, "android/media/AudioDescriptor");
gAudioDescriptorClass = MakeGlobalRefOrDie(env, audioDescriptorClass);
diff --git a/core/jni/android_server_NetworkManagementSocketTagger.cpp b/core/jni/android_server_NetworkManagementSocketTagger.cpp
deleted file mode 100644
index 9734ab9..0000000
--- a/core/jni/android_server_NetworkManagementSocketTagger.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2011, 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.
- */
-
-#define LOG_TAG "NMST_QTagUidNative"
-
-#include <android/multinetwork.h>
-#include <cutils/qtaguid.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <nativehelper/JNIPlatformHelp.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <utils/Log.h>
-#include <utils/misc.h>
-
-#include "jni.h"
-
-namespace android {
-
-static jint tagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor,
- jint tagNum, jint uid) {
- int userFd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
- if (env->ExceptionCheck()) {
- ALOGE("Can't get FileDescriptor num");
- return (jint)-1;
- }
-
- int res = android_tag_socket_with_uid(userFd, tagNum, uid);
- if (res < 0) {
- return (jint)-errno;
- }
- return (jint)res;
-}
-
-static jint untagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor) {
- int userFd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-
- if (env->ExceptionCheck()) {
- ALOGE("Can't get FileDescriptor num");
- return (jint)-1;
- }
-
- int res = android_untag_socket(userFd);
- if (res < 0) {
- return (jint)-errno;
- }
- return (jint)res;
-}
-
-static const JNINativeMethod gQTagUidMethods[] = {
- { "native_tagSocketFd", "(Ljava/io/FileDescriptor;II)I", (void*)tagSocketFd},
- { "native_untagSocketFd", "(Ljava/io/FileDescriptor;)I", (void*)untagSocketFd},
-};
-
-int register_android_server_NetworkManagementSocketTagger(JNIEnv* env) {
- return jniRegisterNativeMethods(env, "com/android/server/NetworkManagementSocketTagger", gQTagUidMethods, NELEM(gQTagUidMethods));
-}
-
-};
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6e54197..b1ad3ca 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -977,61 +977,6 @@
android:permissionFlags="softRestricted|immutablyRestricted"
android:protectionLevel="dangerous" />
- <!-- Required to be able to read audio files from shared storage.
- <p>Protection level: dangerous -->
- <permission-group android:name="android.permission-group.READ_MEDIA_AURAL"
- android:icon="@drawable/perm_group_read_media_aural"
- android:label="@string/permgrouplab_readMediaAural"
- android:description="@string/permgroupdesc_readMediaAural"
- android:priority="950" />
-
- <!-- Allows an application to read audio files from external storage.
- <p>This permission is enforced starting in API level
- {@link android.os.Build.VERSION_CODES#TIRAMISU}.
- For apps with a <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
- targetSdkVersion}</a> of {@link android.os.Build.VERSION_CODES#S} or lower, this permission
- must not be used and the READ_EXTERNAL_STORAGE permission must be used instead.
- <p>Protection level: dangerous -->
- <permission android:name="android.permission.READ_MEDIA_AUDIO"
- android:permissionGroup="android.permission-group.UNDEFINED"
- android:label="@string/permlab_readMediaAudio"
- android:description="@string/permdesc_readMediaAudio"
- android:protectionLevel="dangerous" />
-
- <!-- Required to be able to read image and video files from shared storage.
- <p>Protection level: dangerous -->
- <permission-group android:name="android.permission-group.READ_MEDIA_VISUAL"
- android:icon="@drawable/perm_group_read_media_visual"
- android:label="@string/permgrouplab_readMediaVisual"
- android:description="@string/permgroupdesc_readMediaVisual"
- android:priority="1000" />
-
- <!-- Allows an application to read audio files from external storage.
- <p>This permission is enforced starting in API level
- {@link android.os.Build.VERSION_CODES#TIRAMISU}.
- For apps with a <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
- targetSdkVersion}</a> of {@link android.os.Build.VERSION_CODES#S} or lower, this permission
- must not be used and the READ_EXTERNAL_STORAGE permission must be used instead.
- <p>Protection level: dangerous -->
- <permission android:name="android.permission.READ_MEDIA_VIDEO"
- android:permissionGroup="android.permission-group.UNDEFINED"
- android:label="@string/permlab_readMediaVideo"
- android:description="@string/permdesc_readMediaVideo"
- android:protectionLevel="dangerous" />
-
- <!-- Allows an application to read image files from external storage.
- <p>This permission is enforced starting in API level
- {@link android.os.Build.VERSION_CODES#TIRAMISU}.
- For apps with a <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
- targetSdkVersion}</a> of {@link android.os.Build.VERSION_CODES#S} or lower, this permission
- must not be used and the READ_EXTERNAL_STORAGE permission must be used instead.
- <p>Protection level: dangerous -->
- <permission android:name="android.permission.READ_MEDIA_IMAGE"
- android:permissionGroup="android.permission-group.UNDEFINED"
- android:label="@string/permlab_readMediaImage"
- android:description="@string/permdesc_readMediaImage"
- android:protectionLevel="dangerous" />
-
<!-- Allows an application to write to external storage.
<p class="note"><strong>Note:</strong> If <em>both</em> your <a
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
@@ -6174,6 +6119,12 @@
<permission android:name="android.permission.ACCESS_FPS_COUNTER"
android:protectionLevel="signature|privileged" />
+ <!-- @SystemApi Allows the GameService provider to create GameSession and call GameSession
+ APIs and overlay a view on top of the game's Activity.
+ @hide -->
+ <permission android:name="android.permission.MANAGE_GAME_ACTIVITY"
+ android:protectionLevel="signature|privileged" />
+
<!-- @SystemApi Allows the holder to register callbacks to inform the RebootReadinessManager
when they are performing reboot-blocking work.
@hide -->
@@ -6300,6 +6251,15 @@
<permission android:name="android.permission.BIND_AMBIENT_CONTEXT_DETECTION_SERVICE"
android:protectionLevel="signature" />
+ <!-- @SystemApi Allows an app to set keep-clear areas without restrictions on the size or
+ number of keep-clear areas (see {@link android.view.View#setPreferKeepClearRects}).
+ When the system arranges floating windows onscreen, it might decide to ignore keep-clear
+ areas from windows, whose owner does not have this permission.
+ @hide
+ -->
+ <permission android:name="android.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS"
+ android:protectionLevel="signature|privileged" />
+
<!-- Attribution for Geofencing service. -->
<attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
<!-- Attribution for Country Detector. -->
@@ -6794,10 +6754,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/res/res/drawable/perm_group_read_media_aural.xml b/core/res/res/drawable/perm_group_read_media_aural.xml
deleted file mode 100644
index 6fc9c69..0000000
--- a/core/res/res/drawable/perm_group_read_media_aural.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24"
- android:tint="?attr/colorControlNormal">
- <path
- android:fillColor="@android:color/white"
- android:pathData="M10,21q-1.65,0 -2.825,-1.175Q6,18.65 6,17q0,-1.65 1.175,-2.825Q8.35,13 10,13q0.575,0 1.063,0.137 0.487,0.138 0.937,0.413V3h6v4h-4v10q0,1.65 -1.175,2.825Q11.65,21 10,21z"/>
-</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/perm_group_read_media_visual.xml b/core/res/res/drawable/perm_group_read_media_visual.xml
deleted file mode 100644
index a5db271..0000000
--- a/core/res/res/drawable/perm_group_read_media_visual.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2015 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24"
- android:tint="?attr/colorControlNormal">
- <path
- android:fillColor="@android:color/white"
- android:pathData="M9,14h10l-3.45,-4.5 -2.3,3 -1.55,-2zM8,18q-0.825,0 -1.412,-0.587Q6,16.825 6,16L6,4q0,-0.825 0.588,-1.413Q7.175,2 8,2h12q0.825,0 1.413,0.587Q22,3.175 22,4v12q0,0.825 -0.587,1.413Q20.825,18 20,18zM8,16h12L20,4L8,4v12zM4,22q-0.825,0 -1.413,-0.587Q2,20.825 2,20L2,6h2v14h14v2zM8,4v12L8,4z"/>
-</vector>
\ No newline at end of file
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 0edc0d6..1997e91 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2612,6 +2612,10 @@
will be locked. -->
<bool name="config_multiuserDelayUserDataLocking">false</bool>
+ <!-- Whether to automatically switch a non-primary user back to the primary user after a
+ timeout when the device is docked. -->
+ <bool name="config_enableTimeoutToUserZeroWhenDocked">false</bool>
+
<!-- Whether to only install system packages on a user if they're allowlisted for that user
type. These are flags and can be freely combined.
0 - disable allowlist (install all system packages; no logging)
@@ -5136,6 +5140,9 @@
If given value is outside of this range, the option 1 (center) is assummed. -->
<integer name="config_letterboxDefaultPositionForReachability">1</integer>
+ <!-- Whether displaying letterbox education is enabled for letterboxed fullscreen apps. -->
+ <bool name="config_letterboxIsEducationEnabled">false</bool>
+
<!-- Whether a camera compat controller is enabled to allow the user to apply or revert
treatment for stretched issues in camera viewfinder. -->
<bool name="config_isCameraCompatControlForStretchedIssuesEnabled">false</bool>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 49a12d1..610c6a6 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -880,16 +880,6 @@
<!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgroupdesc_storage">access photos, media, and files on your device</string>
- <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=40]-->
- <string name="permgrouplab_readMediaAural">Music & other audio</string>
- <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE]-->
- <string name="permgroupdesc_readMediaAural">access audio files on your device</string>
-
- <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=40]-->
- <string name="permgrouplab_readMediaVisual">Photos & videos</string>
- <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE]-->
- <string name="permgroupdesc_readMediaVisual">access images and video files on your device</string>
-
<!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgrouplab_microphone">Microphone</string>
<!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1903,21 +1893,6 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can read from. [CHAR LIMIT=none] -->
<string name="permdesc_sdcardRead">Allows the app to read the contents of your shared storage.</string>
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can read from. [CHAR LIMIT=none] -->
- <string name="permlab_readMediaAudio">read audio files from shared storage</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can read from. [CHAR LIMIT=none] -->
- <string name="permdesc_readMediaAudio">Allows the app to read audio files from your shared storage.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can read from. [CHAR LIMIT=none] -->
- <string name="permlab_readMediaVideo">read video files from shared storage</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can read from. [CHAR LIMIT=none] -->
- <string name="permdesc_readMediaVideo">Allows the app to read video files from your shared storage.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can read from. [CHAR LIMIT=none] -->
- <string name="permlab_readMediaImage">read image files from shared storage</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can read from. [CHAR LIMIT=none] -->
- <string name="permdesc_readMediaImage">Allows the app to read image files from your shared storage.</string>
-
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can write to. [CHAR LIMIT=none] -->
<string name="permlab_sdcardWrite">modify or delete the contents of your shared storage</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. "shared storage" refers to a storage space on the device that all apps with this permission can write to. [CHAR LIMIT=none] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 602d5f9..1884467 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -465,6 +465,7 @@
<java-symbol type="integer" name="config_multiuserMaximumUsers" />
<java-symbol type="integer" name="config_multiuserMaxRunningUsers" />
<java-symbol type="bool" name="config_multiuserDelayUserDataLocking" />
+ <java-symbol type="bool" name="config_enableTimeoutToUserZeroWhenDocked" />
<java-symbol type="integer" name="config_userTypePackageWhitelistMode"/>
<java-symbol type="xml" name="config_user_types" />
<java-symbol type="integer" name="config_safe_media_volume_index" />
@@ -4329,6 +4330,7 @@
<java-symbol type="dimen" name="config_letterboxHorizontalPositionMultiplier" />
<java-symbol type="bool" name="config_letterboxIsReachabilityEnabled" />
<java-symbol type="integer" name="config_letterboxDefaultPositionForReachability" />
+ <java-symbol type="bool" name="config_letterboxIsEducationEnabled" />
<java-symbol type="bool" name="config_isCameraCompatControlForStretchedIssuesEnabled" />
<java-symbol type="bool" name="config_hideDisplayCutoutWithDisplayArea" />
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index b2c4274..5c9044c 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -646,6 +646,10 @@
}
@Override
+ public void dumpResources(ParcelFileDescriptor fd, RemoteCallback finishCallback) {
+ }
+
+ @Override
public final void runIsolatedEntryPoint(String entryPoint, String[] entryPointArgs) {
}
diff --git a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java
index db63e6e..4c247427 100644
--- a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java
+++ b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java
@@ -38,7 +38,6 @@
import org.junit.runners.JUnit4;
import org.mockito.Mockito;
-import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
@@ -155,7 +154,7 @@
verify(callback).onStateChanged(eq(OTHER_DEVICE_STATE));
Mockito.reset(callback);
- mDeviceStateManagerGlobal.cancelRequest(request);
+ mDeviceStateManagerGlobal.cancelStateRequest();
verify(callback).onStateChanged(eq(mService.getBaseState()));
}
@@ -172,7 +171,7 @@
verify(callback).onRequestActivated(eq(request));
Mockito.reset(callback);
- mDeviceStateManagerGlobal.cancelRequest(request);
+ mDeviceStateManagerGlobal.cancelStateRequest();
verify(callback).onRequestCanceled(eq(request));
}
@@ -203,13 +202,13 @@
private int[] mSupportedStates = new int[] { DEFAULT_DEVICE_STATE, OTHER_DEVICE_STATE };
private int mBaseState = DEFAULT_DEVICE_STATE;
- private ArrayList<Request> mRequests = new ArrayList<>();
+ private Request mRequest;
private Set<IDeviceStateManagerCallback> mCallbacks = new HashSet<>();
private DeviceStateInfo getInfo() {
- final int mergedState = mRequests.isEmpty()
- ? mBaseState : mRequests.get(mRequests.size() - 1).state;
+ final int mergedState = mRequest == null
+ ? mBaseState : mRequest.state;
return new DeviceStateInfo(mSupportedStates, mBaseState, mergedState);
}
@@ -245,11 +244,10 @@
@Override
public void requestState(IBinder token, int state, int flags) {
- if (!mRequests.isEmpty()) {
- final Request topRequest = mRequests.get(mRequests.size() - 1);
+ if (mRequest != null) {
for (IDeviceStateManagerCallback callback : mCallbacks) {
try {
- callback.onRequestSuspended(topRequest.token);
+ callback.onRequestCanceled(mRequest.token);
} catch (RemoteException e) {
// Do nothing. Should never happen.
}
@@ -257,7 +255,7 @@
}
final Request request = new Request(token, state, flags);
- mRequests.add(request);
+ mRequest = request;
notifyDeviceStateInfoChanged();
for (IDeviceStateManagerCallback callback : mCallbacks) {
@@ -270,20 +268,9 @@
}
@Override
- public void cancelRequest(IBinder token) {
- int index = -1;
- for (int i = 0; i < mRequests.size(); i++) {
- if (mRequests.get(i).token.equals(token)) {
- index = i;
- break;
- }
- }
-
- if (index == -1) {
- throw new IllegalArgumentException("Unknown request: " + token);
- }
-
- mRequests.remove(index);
+ public void cancelStateRequest() {
+ IBinder token = mRequest.token;
+ mRequest = null;
for (IDeviceStateManagerCallback callback : mCallbacks) {
try {
callback.onRequestCanceled(token);
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 88920c8..92fca36 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -231,18 +231,6 @@
targetSdk="29">
<new-permission name="android.permission.ACCESS_MEDIA_LOCATION" />
</split-permission>
- <split-permission name="android.permission.READ_EXTERNAL_STORAGE"
- targetSdk="33">
- <new-permission name="android.permission.READ_MEDIA_AUDIO" />
- </split-permission>
- <split-permission name="android.permission.READ_EXTERNAL_STORAGE"
- targetSdk="33">
- <new-permission name="android.permission.READ_MEDIA_VIDEO" />
- </split-permission>
- <split-permission name="android.permission.READ_EXTERNAL_STORAGE"
- targetSdk="33">
- <new-permission name="android.permission.READ_MEDIA_IMAGE" />
- </split-permission>
<split-permission name="android.permission.BLUETOOTH"
targetSdk="31">
<new-permission name="android.permission.BLUETOOTH_SCAN" />
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 055e5ad..857af11 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -458,7 +458,7 @@
* No color information is stored.
* With this configuration, each pixel requires 1 byte of memory.
*/
- ALPHA_8 (1),
+ ALPHA_8(1),
/**
* Each pixel is stored on 2 bytes and only the RGB channels are
@@ -479,7 +479,7 @@
* short color = (R & 0x1f) << 11 | (G & 0x3f) << 5 | (B & 0x1f);
* </pre>
*/
- RGB_565 (3),
+ RGB_565(3),
/**
* Each pixel is stored on 2 bytes. The three RGB color channels
@@ -501,7 +501,7 @@
* it is advised to use {@link #ARGB_8888} instead.
*/
@Deprecated
- ARGB_4444 (4),
+ ARGB_4444(4),
/**
* Each pixel is stored on 4 bytes. Each channel (RGB and alpha
@@ -516,10 +516,10 @@
* int color = (A & 0xff) << 24 | (B & 0xff) << 16 | (G & 0xff) << 8 | (R & 0xff);
* </pre>
*/
- ARGB_8888 (5),
+ ARGB_8888(5),
/**
- * Each pixels is stored on 8 bytes. Each channel (RGB and alpha
+ * Each pixel is stored on 8 bytes. Each channel (RGB and alpha
* for translucency) is stored as a
* {@link android.util.Half half-precision floating point value}.
*
@@ -531,7 +531,7 @@
* long color = (A & 0xffff) << 48 | (B & 0xffff) << 32 | (G & 0xffff) << 16 | (R & 0xffff);
* </pre>
*/
- RGBA_F16 (6),
+ RGBA_F16(6),
/**
* Special configuration, when bitmap is stored only in graphic memory.
@@ -540,13 +540,29 @@
* It is optimal for cases, when the only operation with the bitmap is to draw it on a
* screen.
*/
- HARDWARE (7);
+ HARDWARE(7),
+
+ /**
+ * Each pixel is stored on 4 bytes. Each RGB channel is stored with 10 bits of precision
+ * (1024 possible values). There is an additional alpha channel that is stored with 2 bits
+ * of precision (4 possible values).
+ *
+ * This configuration is suited for wide-gamut and HDR content which does not require alpha
+ * blending, such that the memory cost is the same as ARGB_8888 while enabling higher color
+ * precision.
+ *
+ * <p>Use this formula to pack into 32 bits:</p>
+ * <pre class="prettyprint">
+ * int color = (A & 0x3) << 30 | (B & 0x3ff) << 20 | (G & 0x3ff) << 10 | (R & 0x3ff);
+ * </pre>
+ */
+ RGBA_1010102(8);
@UnsupportedAppUsage
final int nativeInt;
private static Config sConfigs[] = {
- null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888, RGBA_F16, HARDWARE
+ null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888, RGBA_F16, HARDWARE, RGBA_1010102
};
Config(int ni) {
@@ -1000,8 +1016,8 @@
* @param width The width of the bitmap
* @param height The height of the bitmap
* @param config The bitmap config to create.
- * @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to
- * mark the bitmap as opaque. Doing so will clear the bitmap in black
+ * @param hasAlpha If the bitmap is ARGB_8888, RGBA_16F, or RGBA_1010102 this flag can be
+ * used to mark the bitmap as opaque. Doing so will clear the bitmap in black
* instead of transparent.
*
* @throws IllegalArgumentException if the width or height are <= 0, or if
@@ -1019,8 +1035,8 @@
* @param width The width of the bitmap
* @param height The height of the bitmap
* @param config The bitmap config to create.
- * @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to
- * mark the bitmap as opaque. Doing so will clear the bitmap in black
+ * @param hasAlpha If the bitmap is ARGB_8888, RGBA_16F, or RGBA_1010102 this flag can be
+ * used to mark the bitmap as opaque. Doing so will clear the bitmap in black
* instead of transparent.
* @param colorSpace The color space of the bitmap. If the config is {@link Config#RGBA_F16}
* and {@link ColorSpace.Named#SRGB sRGB} or
@@ -1050,8 +1066,8 @@
* @param width The width of the bitmap
* @param height The height of the bitmap
* @param config The bitmap config to create.
- * @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to
- * mark the bitmap as opaque. Doing so will clear the bitmap in black
+ * @param hasAlpha If the bitmap is ARGB_8888, RGBA_16F, or RGBA_1010102 this flag can be
+ * used to mark the bitmap as opaque. Doing so will clear the bitmap in black
* instead of transparent.
*
* @throws IllegalArgumentException if the width or height are <= 0, or if
@@ -1074,8 +1090,8 @@
* @param width The width of the bitmap
* @param height The height of the bitmap
* @param config The bitmap config to create.
- * @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to
- * mark the bitmap as opaque. Doing so will clear the bitmap in black
+ * @param hasAlpha If the bitmap is ARGB_8888, RGBA_16F, or RGBA_1010102 this flag can be
+ * used to mark the bitmap as opaque. Doing so will clear the bitmap in black
* instead of transparent.
* @param colorSpace The color space of the bitmap. If the config is {@link Config#RGBA_F16}
* and {@link ColorSpace.Named#SRGB sRGB} or
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
index e2bc360..9384e2b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java
@@ -245,7 +245,8 @@
}
}
- private void onKeepClearAreasChanged(int displayId, List<Rect> keepClearAreas) {
+ private void onKeepClearAreasChanged(int displayId, List<Rect> restricted,
+ List<Rect> unrestricted) {
synchronized (mDisplays) {
if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) {
Slog.w(TAG, "Skipping onKeepClearAreasChanged on unknown"
@@ -253,7 +254,8 @@
return;
}
for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) {
- mDisplayChangedListeners.get(i).onKeepClearAreasChanged(displayId, keepClearAreas);
+ mDisplayChangedListeners.get(i)
+ .onKeepClearAreasChanged(displayId, restricted, unrestricted);
}
}
}
@@ -318,9 +320,10 @@
}
@Override
- public void onKeepClearAreasChanged(int displayId, List<Rect> keepClearAreas) {
+ public void onKeepClearAreasChanged(int displayId, List<Rect> restricted,
+ List<Rect> unrestricted) {
mMainExecutor.execute(() -> {
- DisplayController.this.onKeepClearAreasChanged(displayId, keepClearAreas);
+ DisplayController.this.onKeepClearAreasChanged(displayId, restricted, unrestricted);
});
}
}
@@ -361,6 +364,7 @@
/**
* Called when keep-clear areas on a display have changed.
*/
- default void onKeepClearAreasChanged(int displayId, List<Rect> keepClearAreas) {}
+ default void onKeepClearAreasChanged(int displayId, List<Rect> restricted,
+ List<Rect> unrestricted) {}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
index d44db49..7307ba3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
@@ -102,7 +102,7 @@
MATCH_PARENT));
((LayoutParams) mDropZoneView1.getLayoutParams()).weight = 1;
((LayoutParams) mDropZoneView2.getLayoutParams()).weight = 1;
- updateContainerMargins();
+ updateContainerMargins(getResources().getConfiguration().orientation);
}
@Override
@@ -127,20 +127,18 @@
}
public void onConfigChanged(Configuration newConfig) {
- final int orientation = getResources().getConfiguration().orientation;
- if (orientation == Configuration.ORIENTATION_LANDSCAPE
+ if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE
&& getOrientation() != HORIZONTAL) {
setOrientation(LinearLayout.HORIZONTAL);
- updateContainerMargins();
- } else if (orientation == Configuration.ORIENTATION_PORTRAIT
+ updateContainerMargins(newConfig.orientation);
+ } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT
&& getOrientation() != VERTICAL) {
setOrientation(LinearLayout.VERTICAL);
- updateContainerMargins();
+ updateContainerMargins(newConfig.orientation);
}
}
- private void updateContainerMargins() {
- final int orientation = getResources().getConfiguration().orientation;
+ private void updateContainerMargins(int orientation) {
final float halfMargin = mDisplayMargin / 2f;
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
mDropZoneView1.setContainerMargin(
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
index 825320b..a6caefe 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/ShellTaskOrganizerTests.java
@@ -363,6 +363,45 @@
}
@Test
+ public void testOnEligibleForLetterboxEducationActivityChanged() {
+ final RunningTaskInfo taskInfo1 = createTaskInfo(12, WINDOWING_MODE_FULLSCREEN);
+ taskInfo1.displayId = DEFAULT_DISPLAY;
+ taskInfo1.topActivityEligibleForLetterboxEducation = false;
+ final TrackingTaskListener taskListener = new TrackingTaskListener();
+ mOrganizer.addListenerForType(taskListener, TASK_LISTENER_TYPE_FULLSCREEN);
+ mOrganizer.onTaskAppeared(taskInfo1, null);
+
+ // Task listener sent to compat UI is null if top activity isn't eligible for letterbox
+ // education.
+ verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
+
+ // Task listener is non-null if top activity is eligible for letterbox education and task
+ // is visible.
+ clearInvocations(mCompatUI);
+ final RunningTaskInfo taskInfo2 =
+ createTaskInfo(taskInfo1.taskId, WINDOWING_MODE_FULLSCREEN);
+ taskInfo2.displayId = taskInfo1.displayId;
+ taskInfo2.topActivityEligibleForLetterboxEducation = true;
+ taskInfo2.isVisible = true;
+ mOrganizer.onTaskInfoChanged(taskInfo2);
+ verify(mCompatUI).onCompatInfoChanged(taskInfo2, taskListener);
+
+ // Task listener is null if task is invisible.
+ clearInvocations(mCompatUI);
+ final RunningTaskInfo taskInfo3 =
+ createTaskInfo(taskInfo1.taskId, WINDOWING_MODE_FULLSCREEN);
+ taskInfo3.displayId = taskInfo1.displayId;
+ taskInfo3.topActivityEligibleForLetterboxEducation = true;
+ taskInfo3.isVisible = false;
+ mOrganizer.onTaskInfoChanged(taskInfo3);
+ verify(mCompatUI).onCompatInfoChanged(taskInfo3, null /* taskListener */);
+
+ clearInvocations(mCompatUI);
+ mOrganizer.onTaskVanished(taskInfo1);
+ verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
+ }
+
+ @Test
public void testOnCameraCompatActivityChanged() {
final RunningTaskInfo taskInfo1 = createTaskInfo(1, WINDOWING_MODE_FULLSCREEN);
taskInfo1.displayId = DEFAULT_DISPLAY;
@@ -375,7 +414,7 @@
// compat control.
verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
- // Task linster is non-null when request a camera compat control for a visible task.
+ // Task listener is non-null when request a camera compat control for a visible task.
clearInvocations(mCompatUI);
final RunningTaskInfo taskInfo2 =
createTaskInfo(taskInfo1.taskId, taskInfo1.getWindowingMode());
diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp
index db3a108..dd272cd 100644
--- a/libs/hwui/HardwareBitmapUploader.cpp
+++ b/libs/hwui/HardwareBitmapUploader.cpp
@@ -287,29 +287,29 @@
std::mutex mVkLock;
};
+static bool checkSupport(AHardwareBuffer_Format format) {
+ AHardwareBuffer_Desc desc = {
+ .width = 1,
+ .height = 1,
+ .layers = 1,
+ .format = format,
+ .usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER | AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER |
+ AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE,
+ };
+ UniqueAHardwareBuffer buffer = allocateAHardwareBuffer(desc);
+ return buffer != nullptr;
+}
+
bool HardwareBitmapUploader::hasFP16Support() {
- static std::once_flag sOnce;
- static bool hasFP16Support = false;
-
- // Gralloc shouldn't let us create a USAGE_HW_TEXTURE if GLES is unable to consume it, so
- // we don't need to double-check the GLES version/extension.
- std::call_once(sOnce, []() {
- AHardwareBuffer_Desc desc = {
- .width = 1,
- .height = 1,
- .layers = 1,
- .format = AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT,
- .usage = AHARDWAREBUFFER_USAGE_CPU_READ_NEVER |
- AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER |
- AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE,
- };
- UniqueAHardwareBuffer buffer = allocateAHardwareBuffer(desc);
- hasFP16Support = buffer != nullptr;
- });
-
+ static bool hasFP16Support = checkSupport(AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT);
return hasFP16Support;
}
+bool HardwareBitmapUploader::has1010102Support() {
+ static bool has101012Support = checkSupport(AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM);
+ return has101012Support;
+}
+
static FormatInfo determineFormat(const SkBitmap& skBitmap, bool usingGL) {
FormatInfo formatInfo;
switch (skBitmap.info().colorType()) {
@@ -350,6 +350,19 @@
formatInfo.type = GL_UNSIGNED_BYTE;
formatInfo.vkFormat = VK_FORMAT_R8G8B8A8_UNORM;
break;
+ case kRGBA_1010102_SkColorType:
+ formatInfo.isSupported = HardwareBitmapUploader::has1010102Support();
+ if (formatInfo.isSupported) {
+ formatInfo.type = GL_UNSIGNED_INT_2_10_10_10_REV;
+ formatInfo.bufferFormat = AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
+ formatInfo.vkFormat = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
+ } else {
+ formatInfo.type = GL_UNSIGNED_BYTE;
+ formatInfo.bufferFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
+ formatInfo.vkFormat = VK_FORMAT_R8G8B8A8_UNORM;
+ }
+ formatInfo.format = GL_RGBA;
+ break;
default:
ALOGW("unable to create hardware bitmap of colortype: %d", skBitmap.info().colorType());
formatInfo.valid = false;
diff --git a/libs/hwui/HardwareBitmapUploader.h b/libs/hwui/HardwareBitmapUploader.h
index ad7a95a..34f43cd 100644
--- a/libs/hwui/HardwareBitmapUploader.h
+++ b/libs/hwui/HardwareBitmapUploader.h
@@ -29,10 +29,12 @@
#ifdef __ANDROID__
static bool hasFP16Support();
+ static bool has1010102Support();
#else
static bool hasFP16Support() {
return true;
}
+ static bool has1010102Support() { return true; }
#endif
};
diff --git a/libs/hwui/apex/android_bitmap.cpp b/libs/hwui/apex/android_bitmap.cpp
index 3780ba0..bc6bc45 100644
--- a/libs/hwui/apex/android_bitmap.cpp
+++ b/libs/hwui/apex/android_bitmap.cpp
@@ -57,6 +57,8 @@
return ANDROID_BITMAP_FORMAT_A_8;
case kRGBA_F16_SkColorType:
return ANDROID_BITMAP_FORMAT_RGBA_F16;
+ case kRGBA_1010102_SkColorType:
+ return ANDROID_BITMAP_FORMAT_RGBA_1010102;
default:
return ANDROID_BITMAP_FORMAT_NONE;
}
@@ -74,6 +76,8 @@
return kAlpha_8_SkColorType;
case ANDROID_BITMAP_FORMAT_RGBA_F16:
return kRGBA_F16_SkColorType;
+ case ANDROID_BITMAP_FORMAT_RGBA_1010102:
+ return kRGBA_1010102_SkColorType;
default:
return kUnknown_SkColorType;
}
@@ -249,6 +253,9 @@
case ANDROID_BITMAP_FORMAT_RGBA_F16:
colorType = kRGBA_F16_SkColorType;
break;
+ case ANDROID_BITMAP_FORMAT_RGBA_1010102:
+ colorType = kRGBA_1010102_SkColorType;
+ break;
default:
return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
}
diff --git a/libs/hwui/hwui/ImageDecoder.cpp b/libs/hwui/hwui/ImageDecoder.cpp
index fc542c8..dd68f82 100644
--- a/libs/hwui/hwui/ImageDecoder.cpp
+++ b/libs/hwui/hwui/ImageDecoder.cpp
@@ -159,6 +159,8 @@
break;
case kRGBA_F16_SkColorType:
break;
+ case kRGBA_1010102_SkColorType:
+ break;
default:
return false;
}
diff --git a/libs/hwui/jni/BitmapRegionDecoder.cpp b/libs/hwui/jni/BitmapRegionDecoder.cpp
index 4cc05ef..1c20415 100644
--- a/libs/hwui/jni/BitmapRegionDecoder.cpp
+++ b/libs/hwui/jni/BitmapRegionDecoder.cpp
@@ -137,9 +137,16 @@
auto* brd = reinterpret_cast<skia::BitmapRegionDecoder*>(brdHandle);
SkColorType decodeColorType = brd->computeOutputColorType(colorType);
- if (decodeColorType == kRGBA_F16_SkColorType && isHardware &&
+
+ if (isHardware) {
+ if (decodeColorType == kRGBA_F16_SkColorType &&
!uirenderer::HardwareBitmapUploader::hasFP16Support()) {
- decodeColorType = kN32_SkColorType;
+ decodeColorType = kN32_SkColorType;
+ }
+ if (decodeColorType == kRGBA_1010102_SkColorType &&
+ !uirenderer::HardwareBitmapUploader::has1010102Support()) {
+ decodeColorType = kN32_SkColorType;
+ }
}
// Set up the pixel allocator
diff --git a/libs/hwui/jni/Graphics.cpp b/libs/hwui/jni/Graphics.cpp
index 77f46be..33669ac 100644
--- a/libs/hwui/jni/Graphics.cpp
+++ b/libs/hwui/jni/Graphics.cpp
@@ -365,6 +365,8 @@
return kRGB_565_LegacyBitmapConfig;
case kAlpha_8_SkColorType:
return kA8_LegacyBitmapConfig;
+ case kRGBA_1010102_SkColorType:
+ return kRGBA_1010102_LegacyBitmapConfig;
case kUnknown_SkColorType:
default:
break;
@@ -374,14 +376,10 @@
SkColorType GraphicsJNI::legacyBitmapConfigToColorType(jint legacyConfig) {
const uint8_t gConfig2ColorType[] = {
- kUnknown_SkColorType,
- kAlpha_8_SkColorType,
- kUnknown_SkColorType, // Previously kIndex_8_SkColorType,
- kRGB_565_SkColorType,
- kARGB_4444_SkColorType,
- kN32_SkColorType,
- kRGBA_F16_SkColorType,
- kN32_SkColorType
+ kUnknown_SkColorType, kAlpha_8_SkColorType,
+ kUnknown_SkColorType, // Previously kIndex_8_SkColorType,
+ kRGB_565_SkColorType, kARGB_4444_SkColorType, kN32_SkColorType,
+ kRGBA_F16_SkColorType, kN32_SkColorType, kRGBA_1010102_SkColorType,
};
if (legacyConfig < 0 || legacyConfig > kLastEnum_LegacyBitmapConfig) {
@@ -399,15 +397,12 @@
jint javaConfigId = env->GetIntField(jconfig, gBitmapConfig_nativeInstanceID);
const AndroidBitmapFormat config2BitmapFormat[] = {
- ANDROID_BITMAP_FORMAT_NONE,
- ANDROID_BITMAP_FORMAT_A_8,
- ANDROID_BITMAP_FORMAT_NONE, // Previously Config.Index_8
- ANDROID_BITMAP_FORMAT_RGB_565,
- ANDROID_BITMAP_FORMAT_RGBA_4444,
- ANDROID_BITMAP_FORMAT_RGBA_8888,
- ANDROID_BITMAP_FORMAT_RGBA_F16,
- ANDROID_BITMAP_FORMAT_NONE // Congfig.HARDWARE
- };
+ ANDROID_BITMAP_FORMAT_NONE, ANDROID_BITMAP_FORMAT_A_8,
+ ANDROID_BITMAP_FORMAT_NONE, // Previously Config.Index_8
+ ANDROID_BITMAP_FORMAT_RGB_565, ANDROID_BITMAP_FORMAT_RGBA_4444,
+ ANDROID_BITMAP_FORMAT_RGBA_8888, ANDROID_BITMAP_FORMAT_RGBA_F16,
+ ANDROID_BITMAP_FORMAT_NONE, // Congfig.HARDWARE
+ ANDROID_BITMAP_FORMAT_RGBA_1010102};
return config2BitmapFormat[javaConfigId];
}
@@ -430,6 +425,9 @@
case ANDROID_BITMAP_FORMAT_RGBA_F16:
configId = kRGBA_16F_LegacyBitmapConfig;
break;
+ case ANDROID_BITMAP_FORMAT_RGBA_1010102:
+ configId = kRGBA_1010102_LegacyBitmapConfig;
+ break;
default:
break;
}
diff --git a/libs/hwui/jni/GraphicsJNI.h b/libs/hwui/jni/GraphicsJNI.h
index ba407f2..085a905 100644
--- a/libs/hwui/jni/GraphicsJNI.h
+++ b/libs/hwui/jni/GraphicsJNI.h
@@ -34,16 +34,17 @@
// This enum must keep these int values, to match the int values
// in the java Bitmap.Config enum.
enum LegacyBitmapConfig {
- kNo_LegacyBitmapConfig = 0,
- kA8_LegacyBitmapConfig = 1,
- kIndex8_LegacyBitmapConfig = 2,
- kRGB_565_LegacyBitmapConfig = 3,
- kARGB_4444_LegacyBitmapConfig = 4,
- kARGB_8888_LegacyBitmapConfig = 5,
- kRGBA_16F_LegacyBitmapConfig = 6,
- kHardware_LegacyBitmapConfig = 7,
+ kNo_LegacyBitmapConfig = 0,
+ kA8_LegacyBitmapConfig = 1,
+ kIndex8_LegacyBitmapConfig = 2,
+ kRGB_565_LegacyBitmapConfig = 3,
+ kARGB_4444_LegacyBitmapConfig = 4,
+ kARGB_8888_LegacyBitmapConfig = 5,
+ kRGBA_16F_LegacyBitmapConfig = 6,
+ kHardware_LegacyBitmapConfig = 7,
+ kRGBA_1010102_LegacyBitmapConfig = 8,
- kLastEnum_LegacyBitmapConfig = kHardware_LegacyBitmapConfig
+ kLastEnum_LegacyBitmapConfig = kRGBA_1010102_LegacyBitmapConfig
};
static void setJavaVM(JavaVM* javaVM);
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index a2704f9..15a398d 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -181,6 +181,22 @@
public static final String VOLUME_CHANGED_ACTION = "android.media.VOLUME_CHANGED_ACTION";
/**
+ * @hide Broadcast intent when the volume for a particular stream type changes.
+ * Includes the stream, the new volume and previous volumes.
+ * Notes:
+ * - for internal platform use only, do not make public,
+ * - never used for "remote" volume changes
+ *
+ * @see #EXTRA_VOLUME_STREAM_TYPE
+ * @see #EXTRA_VOLUME_STREAM_VALUE
+ * @see #EXTRA_PREV_VOLUME_STREAM_VALUE
+ */
+ @SystemApi
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @SuppressLint("ActionValue")
+ public static final String ACTION_VOLUME_CHANGED = "android.media.VOLUME_CHANGED_ACTION";
+
+ /**
* @hide Broadcast intent when the devices for a particular stream type changes.
* Includes the stream, the new devices and previous devices.
* Notes:
@@ -244,7 +260,8 @@
/**
* @hide The stream type for the volume changed intent.
*/
- @UnsupportedAppUsage
+ @SystemApi
+ @SuppressLint("ActionValue")
public static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE";
/**
@@ -261,7 +278,8 @@
/**
* @hide The volume associated with the stream for the volume changed intent.
*/
- @UnsupportedAppUsage
+ @SystemApi
+ @SuppressLint("ActionValue")
public static final String EXTRA_VOLUME_STREAM_VALUE =
"android.media.EXTRA_VOLUME_STREAM_VALUE";
@@ -368,7 +386,7 @@
public static final int STREAM_NOTIFICATION = AudioSystem.STREAM_NOTIFICATION;
/** @hide Used to identify the volume of audio streams for phone calls when connected
* to bluetooth */
- @UnsupportedAppUsage
+ @SystemApi
public static final int STREAM_BLUETOOTH_SCO = AudioSystem.STREAM_BLUETOOTH_SCO;
/** @hide Used to identify the volume of audio streams for enforced system sounds
* in certain countries (e.g camera in Japan) */
@@ -544,6 +562,7 @@
* Indicates the volume set/adjust call is for Bluetooth absolute volume
* @hide
*/
+ @SystemApi
public static final int FLAG_BLUETOOTH_ABS_VOLUME = 1 << 6;
/**
diff --git a/media/java/android/media/IMediaRouter2Manager.aidl b/media/java/android/media/IMediaRouter2Manager.aidl
index 5113dc2..71dc2a7 100644
--- a/media/java/android/media/IMediaRouter2Manager.aidl
+++ b/media/java/android/media/IMediaRouter2Manager.aidl
@@ -18,6 +18,7 @@
import android.media.MediaRoute2ProviderInfo;
import android.media.MediaRoute2Info;
+import android.media.RouteDiscoveryPreference;
import android.media.RoutingSessionInfo;
/**
@@ -27,7 +28,8 @@
void notifySessionCreated(int requestId, in RoutingSessionInfo session);
void notifySessionUpdated(in RoutingSessionInfo session);
void notifySessionReleased(in RoutingSessionInfo session);
- void notifyPreferredFeaturesChanged(String packageName, in List<String> preferredFeatures);
+ void notifyDiscoveryPreferenceChanged(String packageName,
+ in RouteDiscoveryPreference discoveryPreference);
void notifyRoutesAdded(in List<MediaRoute2Info> routes);
void notifyRoutesRemoved(in List<MediaRoute2Info> routes);
void notifyRoutesChanged(in List<MediaRoute2Info> routes);
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index 2427fa6..ee0293d 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -34,6 +34,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
/**
* Describes the properties of a route.
@@ -340,10 +341,12 @@
@ConnectionState
final int mConnectionState;
final String mClientPackageName;
+ final String mPackageName;
final int mVolumeHandling;
final int mVolumeMax;
final int mVolume;
final String mAddress;
+ final Set<String> mDeduplicationIds;
final Bundle mExtras;
final String mProviderId;
@@ -357,10 +360,12 @@
mDescription = builder.mDescription;
mConnectionState = builder.mConnectionState;
mClientPackageName = builder.mClientPackageName;
+ mPackageName = builder.mPackageName;
mVolumeHandling = builder.mVolumeHandling;
mVolumeMax = builder.mVolumeMax;
mVolume = builder.mVolume;
mAddress = builder.mAddress;
+ mDeduplicationIds = builder.mDeduplicationIds;
mExtras = builder.mExtras;
mProviderId = builder.mProviderId;
}
@@ -375,10 +380,12 @@
mDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
mConnectionState = in.readInt();
mClientPackageName = in.readString();
+ mPackageName = in.readString();
mVolumeHandling = in.readInt();
mVolumeMax = in.readInt();
mVolume = in.readInt();
mAddress = in.readString();
+ mDeduplicationIds = Set.of(in.readStringArray());
mExtras = in.readBundle();
mProviderId = in.readString();
}
@@ -486,6 +493,17 @@
}
/**
+ * Gets the package name of the provider that published the route.
+ * <p>
+ * It is set by the system service.
+ * @hide
+ */
+ @Nullable
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ /**
* Gets information about how volume is handled on the route.
*
* @return {@link #PLAYBACK_VOLUME_FIXED} or {@link #PLAYBACK_VOLUME_VARIABLE}
@@ -518,6 +536,18 @@
return mAddress;
}
+ /**
+ * Gets the Deduplication ID of the route if available.
+ * @see RouteDiscoveryPreference#shouldRemoveDuplicates()
+ */
+ @NonNull
+ public Set<String> getDeduplicationIds() {
+ return mDeduplicationIds;
+ }
+
+ /**
+ * Gets an optional bundle with extra data.
+ */
@Nullable
public Bundle getExtras() {
return mExtras == null ? null : new Bundle(mExtras);
@@ -549,7 +579,7 @@
* Returns if the route has at least one of the specified route features.
*
* @param features the list of route features to consider
- * @return true if the route has at least one feature in the list
+ * @return {@code true} if the route has at least one feature in the list
* @hide
*/
public boolean hasAnyFeatures(@NonNull Collection<String> features) {
@@ -563,6 +593,21 @@
}
/**
+ * Returns if the route has all the specified route features.
+ *
+ * @hide
+ */
+ public boolean hasAllFeatures(@NonNull Collection<String> features) {
+ Objects.requireNonNull(features, "features must not be null");
+ for (String feature : features) {
+ if (!getFeatures().contains(feature)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
* Returns true if the route info has all of the required field.
* A route is valid if and only if it is obtained from
* {@link com.android.server.media.MediaRouterService}.
@@ -596,10 +641,12 @@
&& Objects.equals(mDescription, other.mDescription)
&& (mConnectionState == other.mConnectionState)
&& Objects.equals(mClientPackageName, other.mClientPackageName)
+ && Objects.equals(mPackageName, other.mPackageName)
&& (mVolumeHandling == other.mVolumeHandling)
&& (mVolumeMax == other.mVolumeMax)
&& (mVolume == other.mVolume)
&& Objects.equals(mAddress, other.mAddress)
+ && Objects.equals(mDeduplicationIds, other.mDeduplicationIds)
&& Objects.equals(mProviderId, other.mProviderId);
}
@@ -607,8 +654,8 @@
public int hashCode() {
// Note: mExtras is not included.
return Objects.hash(mId, mName, mFeatures, mType, mIsSystem, mIconUri, mDescription,
- mConnectionState, mClientPackageName, mVolumeHandling, mVolumeMax, mVolume,
- mAddress, mProviderId);
+ mConnectionState, mClientPackageName, mPackageName, mVolumeHandling, mVolumeMax,
+ mVolume, mAddress, mDeduplicationIds, mProviderId);
}
@Override
@@ -626,6 +673,7 @@
.append(", volumeHandling=").append(getVolumeHandling())
.append(", volumeMax=").append(getVolumeMax())
.append(", volume=").append(getVolume())
+ .append(", deduplicationIds=").append(String.join(",", getDeduplicationIds()))
.append(", providerId=").append(getProviderId())
.append(" }");
return result.toString();
@@ -647,10 +695,12 @@
TextUtils.writeToParcel(mDescription, dest, flags);
dest.writeInt(mConnectionState);
dest.writeString(mClientPackageName);
+ dest.writeString(mPackageName);
dest.writeInt(mVolumeHandling);
dest.writeInt(mVolumeMax);
dest.writeInt(mVolume);
dest.writeString(mAddress);
+ dest.writeStringArray(mDeduplicationIds.toArray(new String[mDeduplicationIds.size()]));
dest.writeBundle(mExtras);
dest.writeString(mProviderId);
}
@@ -671,10 +721,12 @@
@ConnectionState
int mConnectionState;
String mClientPackageName;
+ String mPackageName;
int mVolumeHandling = PLAYBACK_VOLUME_FIXED;
int mVolumeMax;
int mVolume;
String mAddress;
+ Set<String> mDeduplicationIds;
Bundle mExtras;
String mProviderId;
@@ -698,6 +750,7 @@
mId = id;
mName = name;
mFeatures = new ArrayList<>();
+ mDeduplicationIds = Set.of();
}
/**
@@ -733,10 +786,12 @@
mDescription = routeInfo.mDescription;
mConnectionState = routeInfo.mConnectionState;
mClientPackageName = routeInfo.mClientPackageName;
+ mPackageName = routeInfo.mPackageName;
mVolumeHandling = routeInfo.mVolumeHandling;
mVolumeMax = routeInfo.mVolumeMax;
mVolume = routeInfo.mVolume;
mAddress = routeInfo.mAddress;
+ mDeduplicationIds = Set.copyOf(routeInfo.mDeduplicationIds);
if (routeInfo.mExtras != null) {
mExtras = new Bundle(routeInfo.mExtras);
}
@@ -860,6 +915,16 @@
}
/**
+ * Sets the package name of the route.
+ * @hide
+ */
+ @NonNull
+ public Builder setPackageName(@NonNull String packageName) {
+ mPackageName = packageName;
+ return this;
+ }
+
+ /**
* Sets the route's volume handling.
*/
@NonNull
@@ -897,6 +962,20 @@
}
/**
+ * Sets the deduplication ID of the route.
+ * Routes have the same ID could be removed even when
+ * they are from different providers.
+ * <p>
+ * If it's {@code null}, the route will not be removed.
+ * @see RouteDiscoveryPreference#shouldRemoveDuplicates()
+ */
+ @NonNull
+ public Builder setDeduplicationIds(@NonNull Set<String> id) {
+ mDeduplicationIds = Set.copyOf(id);
+ return this;
+ }
+
+ /**
* Sets a bundle of extras for the route.
* <p>
* Note: The extras will not affect the result of {@link MediaRoute2Info#equals(Object)}.
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 4b32dbf..b485eb5 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -34,15 +34,18 @@
import android.os.ServiceManager;
import android.text.TextUtils;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
@@ -302,8 +305,7 @@
mSystemController = new SystemRoutingController(
ensureClientPackageNameForSystemSession(
sManager.getSystemRoutingSession(clientPackageName)));
- mDiscoveryPreference = new RouteDiscoveryPreference.Builder(
- sManager.getPreferredFeatures(clientPackageName), true).build();
+ mDiscoveryPreference = sManager.getDiscoveryPreference(clientPackageName);
updateAllRoutesFromManager();
// Only used by non-system MediaRouter2.
@@ -1060,11 +1062,48 @@
.build();
}
+ private List<MediaRoute2Info> getSortedRoutes(List<MediaRoute2Info> routes,
+ RouteDiscoveryPreference preference) {
+ if (!preference.shouldRemoveDuplicates()) {
+ return routes;
+ }
+ Map<String, Integer> packagePriority = new ArrayMap<>();
+ int count = preference.getDeduplicationPackageOrder().size();
+ for (int i = 0; i < count; i++) {
+ // the last package will have 1 as the priority
+ packagePriority.put(preference.getDeduplicationPackageOrder().get(i), count - i);
+ }
+ ArrayList<MediaRoute2Info> sortedRoutes = new ArrayList<>(routes);
+ // take the negative for descending order
+ sortedRoutes.sort(Comparator.comparingInt(
+ r -> -packagePriority.getOrDefault(r.getPackageName(), 0)));
+ return sortedRoutes;
+ }
+
private List<MediaRoute2Info> filterRoutes(List<MediaRoute2Info> routes,
- RouteDiscoveryPreference discoveryRequest) {
- return routes.stream()
- .filter(route -> route.hasAnyFeatures(discoveryRequest.getPreferredFeatures()))
- .collect(Collectors.toList());
+ RouteDiscoveryPreference discoveryPreference) {
+
+ Set<String> deduplicationIdSet = new ArraySet<>();
+
+ List<MediaRoute2Info> filteredRoutes = new ArrayList<>();
+ for (MediaRoute2Info route : getSortedRoutes(routes, discoveryPreference)) {
+ if (!route.hasAllFeatures(discoveryPreference.getRequiredFeatures())
+ || !route.hasAnyFeatures(discoveryPreference.getPreferredFeatures())) {
+ continue;
+ }
+ if (!discoveryPreference.getAllowedPackages().isEmpty()
+ && !discoveryPreference.getAllowedPackages().contains(route.getPackageName())) {
+ continue;
+ }
+ if (discoveryPreference.shouldRemoveDuplicates()) {
+ if (Collections.disjoint(deduplicationIdSet, route.getDeduplicationIds())) {
+ continue;
+ }
+ deduplicationIdSet.addAll(route.getDeduplicationIds());
+ }
+ filteredRoutes.add(route);
+ }
+ return filteredRoutes;
}
private void updateAllRoutesFromManager() {
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
index 83fa7c2..8635c0e 100644
--- a/media/java/android/media/MediaRouter2Manager.java
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -29,6 +29,8 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
@@ -36,15 +38,18 @@
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -84,7 +89,8 @@
@GuardedBy("mRoutesLock")
private final Map<String, MediaRoute2Info> mRoutes = new HashMap<>();
@NonNull
- final ConcurrentMap<String, List<String>> mPreferredFeaturesMap = new ConcurrentHashMap<>();
+ final ConcurrentMap<String, RouteDiscoveryPreference> mDiscoveryPreferenceMap =
+ new ConcurrentHashMap<>();
private final AtomicInteger mNextRequestId = new AtomicInteger(1);
private final CopyOnWriteArrayList<TransferRequest> mTransferRequests =
@@ -247,25 +253,8 @@
*/
@NonNull
public List<MediaRoute2Info> getAvailableRoutes(@NonNull RoutingSessionInfo sessionInfo) {
- Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
-
- List<MediaRoute2Info> routes = new ArrayList<>();
-
- String packageName = sessionInfo.getClientPackageName();
- List<String> preferredFeatures = mPreferredFeaturesMap.get(packageName);
- if (preferredFeatures == null) {
- preferredFeatures = Collections.emptyList();
- }
- synchronized (mRoutesLock) {
- for (MediaRoute2Info route : mRoutes.values()) {
- if (route.hasAnyFeatures(preferredFeatures)
- || sessionInfo.getSelectedRoutes().contains(route.getId())
- || sessionInfo.getTransferableRoutes().contains(route.getId())) {
- routes.add(route);
- }
- }
- }
- return routes;
+ return getFilteredRoutes(sessionInfo, /*includeSelectedRoutes=*/true,
+ null);
}
/**
@@ -281,27 +270,70 @@
*/
@NonNull
public List<MediaRoute2Info> getTransferableRoutes(@NonNull RoutingSessionInfo sessionInfo) {
+ return getFilteredRoutes(sessionInfo, /*includeSelectedRoutes=*/false,
+ (route) -> sessionInfo.isSystemSession() ^ route.isSystemRoute());
+ }
+
+ private List<MediaRoute2Info> getSortedRoutes(RouteDiscoveryPreference preference) {
+ if (!preference.shouldRemoveDuplicates()) {
+ synchronized (mRoutesLock) {
+ return List.copyOf(mRoutes.values());
+ }
+ }
+ Map<String, Integer> packagePriority = new ArrayMap<>();
+ int count = preference.getDeduplicationPackageOrder().size();
+ for (int i = 0; i < count; i++) {
+ // the last package will have 1 as the priority
+ packagePriority.put(preference.getDeduplicationPackageOrder().get(i), count - i);
+ }
+ ArrayList<MediaRoute2Info> routes;
+ synchronized (mRoutesLock) {
+ routes = new ArrayList<>(mRoutes.values());
+ }
+ // take the negative for descending order
+ routes.sort(Comparator.comparingInt(
+ r -> -packagePriority.getOrDefault(r.getPackageName(), 0)));
+ return routes;
+ }
+
+ private List<MediaRoute2Info> getFilteredRoutes(@NonNull RoutingSessionInfo sessionInfo,
+ boolean includeSelectedRoutes,
+ @Nullable Predicate<MediaRoute2Info> additionalFilter) {
Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
List<MediaRoute2Info> routes = new ArrayList<>();
+ Set<String> deduplicationIdSet = new ArraySet<>();
String packageName = sessionInfo.getClientPackageName();
- List<String> preferredFeatures = mPreferredFeaturesMap.get(packageName);
- if (preferredFeatures == null) {
- preferredFeatures = Collections.emptyList();
- }
- synchronized (mRoutesLock) {
- for (MediaRoute2Info route : mRoutes.values()) {
- if (sessionInfo.getTransferableRoutes().contains(route.getId())) {
- routes.add(route);
+ RouteDiscoveryPreference discoveryPreference =
+ mDiscoveryPreferenceMap.getOrDefault(packageName, RouteDiscoveryPreference.EMPTY);
+
+ for (MediaRoute2Info route : getSortedRoutes(discoveryPreference)) {
+ if (sessionInfo.getTransferableRoutes().contains(route.getId())
+ || (includeSelectedRoutes
+ && sessionInfo.getSelectedRoutes().contains(route.getId()))) {
+ routes.add(route);
+ continue;
+ }
+ if (!route.hasAllFeatures(discoveryPreference.getRequiredFeatures())
+ || !route.hasAnyFeatures(discoveryPreference.getPreferredFeatures())) {
+ continue;
+ }
+ if (!discoveryPreference.getAllowedPackages().isEmpty()
+ && !discoveryPreference.getAllowedPackages()
+ .contains(route.getPackageName())) {
+ continue;
+ }
+ if (additionalFilter != null && !additionalFilter.test(route)) {
+ continue;
+ }
+ if (discoveryPreference.shouldRemoveDuplicates()) {
+ if (Collections.disjoint(deduplicationIdSet, route.getDeduplicationIds())) {
continue;
}
- // Add Phone -> Cast and Cast -> Phone
- if (route.hasAnyFeatures(preferredFeatures)
- && (sessionInfo.isSystemSession() ^ route.isSystemRoute())) {
- routes.add(route);
- }
+ deduplicationIdSet.addAll(route.getDeduplicationIds());
}
+ routes.add(route);
}
return routes;
}
@@ -310,44 +342,10 @@
* Returns the preferred features of the specified package name.
*/
@NonNull
- public List<String> getPreferredFeatures(@NonNull String packageName) {
+ public RouteDiscoveryPreference getDiscoveryPreference(@NonNull String packageName) {
Objects.requireNonNull(packageName, "packageName must not be null");
- List<String> preferredFeatures = mPreferredFeaturesMap.get(packageName);
- if (preferredFeatures == null) {
- preferredFeatures = Collections.emptyList();
- }
- return preferredFeatures;
- }
-
- /**
- * Returns a list of routes which are related to the given package name in the given route list.
- */
- @NonNull
- public List<MediaRoute2Info> filterRoutesForPackage(@NonNull List<MediaRoute2Info> routes,
- @NonNull String packageName) {
- Objects.requireNonNull(routes, "routes must not be null");
- Objects.requireNonNull(packageName, "packageName must not be null");
-
- List<RoutingSessionInfo> sessions = getRoutingSessions(packageName);
- RoutingSessionInfo sessionInfo = sessions.get(sessions.size() - 1);
-
- List<MediaRoute2Info> result = new ArrayList<>();
- List<String> preferredFeatures = mPreferredFeaturesMap.get(packageName);
- if (preferredFeatures == null) {
- preferredFeatures = Collections.emptyList();
- }
-
- synchronized (mRoutesLock) {
- for (MediaRoute2Info route : routes) {
- if (route.hasAnyFeatures(preferredFeatures)
- || sessionInfo.getSelectedRoutes().contains(route.getId())
- || sessionInfo.getTransferableRoutes().contains(route.getId())) {
- result.add(route);
- }
- }
- }
- return result;
+ return mDiscoveryPreferenceMap.getOrDefault(packageName, RouteDiscoveryPreference.EMPTY);
}
/**
@@ -713,19 +711,19 @@
}
}
- void updatePreferredFeatures(String packageName, List<String> preferredFeatures) {
- if (preferredFeatures == null) {
- mPreferredFeaturesMap.remove(packageName);
+ void updateDiscoveryPreference(String packageName, RouteDiscoveryPreference preference) {
+ if (preference == null) {
+ mDiscoveryPreferenceMap.remove(packageName);
return;
}
- List<String> prevFeatures = mPreferredFeaturesMap.put(packageName, preferredFeatures);
- if ((prevFeatures == null && preferredFeatures.size() == 0)
- || Objects.equals(preferredFeatures, prevFeatures)) {
+ RouteDiscoveryPreference prevPreference =
+ mDiscoveryPreferenceMap.put(packageName, preference);
+ if (Objects.equals(preference, prevPreference)) {
return;
}
for (CallbackRecord record : mCallbackRecords) {
record.mExecutor.execute(() -> record.mCallback
- .onPreferredFeaturesChanged(packageName, preferredFeatures));
+ .onDiscoveryPreferenceChanged(packageName, preference));
}
}
@@ -1047,6 +1045,17 @@
@NonNull List<String> preferredFeatures) {}
/**
+ * Called when the preferred route features of an app is changed.
+ *
+ * @param packageName the package name of the application
+ * @param discoveryPreference the new discovery preference set by the application.
+ */
+ default void onDiscoveryPreferenceChanged(@NonNull String packageName,
+ @NonNull RouteDiscoveryPreference discoveryPreference) {
+ onPreferredFeaturesChanged(packageName, discoveryPreference.getPreferredFeatures());
+ }
+
+ /**
* Called when a previous request has failed.
*
* @param reason the reason that the request has failed. Can be one of followings:
@@ -1125,9 +1134,10 @@
}
@Override
- public void notifyPreferredFeaturesChanged(String packageName, List<String> features) {
- mHandler.sendMessage(obtainMessage(MediaRouter2Manager::updatePreferredFeatures,
- MediaRouter2Manager.this, packageName, features));
+ public void notifyDiscoveryPreferenceChanged(String packageName,
+ RouteDiscoveryPreference discoveryPreference) {
+ mHandler.sendMessage(obtainMessage(MediaRouter2Manager::updateDiscoveryPreference,
+ MediaRouter2Manager.this, packageName, discoveryPreference));
}
@Override
diff --git a/media/java/android/media/RouteDiscoveryPreference.java b/media/java/android/media/RouteDiscoveryPreference.java
index 37fee84..06dc498 100644
--- a/media/java/android/media/RouteDiscoveryPreference.java
+++ b/media/java/android/media/RouteDiscoveryPreference.java
@@ -64,6 +64,10 @@
@NonNull
private final List<String> mPreferredFeatures;
+ private final List<String> mRequiredFeatures;
+ private final List<String> mPackagesOrder;
+ private final List<String> mAllowedPackages;
+
private final boolean mShouldPerformActiveScan;
@Nullable
private final Bundle mExtras;
@@ -78,12 +82,18 @@
RouteDiscoveryPreference(@NonNull Builder builder) {
mPreferredFeatures = builder.mPreferredFeatures;
+ mRequiredFeatures = builder.mRequiredFeatures;
+ mPackagesOrder = builder.mPackageOrder;
+ mAllowedPackages = builder.mAllowedPackages;
mShouldPerformActiveScan = builder.mActiveScan;
mExtras = builder.mExtras;
}
RouteDiscoveryPreference(@NonNull Parcel in) {
mPreferredFeatures = in.createStringArrayList();
+ mRequiredFeatures = in.createStringArrayList();
+ mPackagesOrder = in.createStringArrayList();
+ mAllowedPackages = in.createStringArrayList();
mShouldPerformActiveScan = in.readBoolean();
mExtras = in.readBundle();
}
@@ -96,6 +106,8 @@
* {@link MediaRoute2Info#FEATURE_LIVE_AUDIO}, {@link MediaRoute2Info#FEATURE_LIVE_VIDEO},
* or {@link MediaRoute2Info#FEATURE_REMOTE_PLAYBACK} or custom features defined by a provider.
* </p>
+ *
+ * @see #getRequiredFeatures()
*/
@NonNull
public List<String> getPreferredFeatures() {
@@ -103,6 +115,44 @@
}
/**
+ * Gets the required features of routes that media router would like to discover.
+ * <p>
+ * Routes that have all the required features will be discovered.
+ * This precedes {@link #getPreferredFeatures()}.
+ * They may include predefined features such as
+ * {@link MediaRoute2Info#FEATURE_LIVE_AUDIO}, {@link MediaRoute2Info#FEATURE_LIVE_VIDEO},
+ * or {@link MediaRoute2Info#FEATURE_REMOTE_PLAYBACK} or custom features defined by a provider.
+ *
+ * @see #getPreferredFeatures()
+ */
+ @NonNull
+ public List<String> getRequiredFeatures() {
+ return mRequiredFeatures;
+ }
+
+ /**
+ * Gets the ordered list of package names used to remove duplicate routes.
+ * <p>
+ * When the app enables duplicate removal, all the routes that have the same deduplication ID
+ * except one from the provider whose package name appears first in the list will be removed.
+ */
+ @NonNull
+ public List<String> getDeduplicationPackageOrder() {
+ return mPackagesOrder == null ? List.of() : mPackagesOrder;
+ }
+
+ /**
+ * Gets the list of allowed packages.
+ * <p>
+ * If it's not empty, it will only discover routes from the provider whose package name
+ * belongs to the list.
+ */
+ @NonNull
+ public List<String> getAllowedPackages() {
+ return mAllowedPackages;
+ }
+
+ /**
* Gets whether active scanning should be performed.
* <p>
* If any of discovery preferences sets this as {@code true}, active scanning will
@@ -114,6 +164,16 @@
}
/**
+ * Gets whether duplicate routes should be removed.
+ * <p>
+ * If it is {@code true}, only one of routes that have
+ * the same deduplication ID will be obtained.
+ */
+ public boolean shouldRemoveDuplicates() {
+ return !mPackagesOrder.isEmpty();
+ }
+
+ /**
* @hide
*/
public Bundle getExtras() {
@@ -128,6 +188,9 @@
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeStringList(mPreferredFeatures);
+ dest.writeStringList(mRequiredFeatures);
+ dest.writeStringList(mPackagesOrder);
+ dest.writeStringList(mAllowedPackages);
dest.writeBoolean(mShouldPerformActiveScan);
dest.writeBundle(mExtras);
}
@@ -155,14 +218,17 @@
return false;
}
RouteDiscoveryPreference other = (RouteDiscoveryPreference) o;
- //TODO: Make this order-free
return Objects.equals(mPreferredFeatures, other.mPreferredFeatures)
+ && Objects.equals(mRequiredFeatures, other.mRequiredFeatures)
+ && Objects.equals(mPackagesOrder, other.mPackagesOrder)
+ && Objects.equals(mAllowedPackages, other.mAllowedPackages)
&& mShouldPerformActiveScan == other.mShouldPerformActiveScan;
}
@Override
public int hashCode() {
- return Objects.hash(mPreferredFeatures, mShouldPerformActiveScan);
+ return Objects.hash(mPreferredFeatures, mRequiredFeatures, mPackagesOrder, mAllowedPackages,
+ mShouldPerformActiveScan);
}
/**
@@ -170,13 +236,21 @@
*/
public static final class Builder {
List<String> mPreferredFeatures;
+ List<String> mRequiredFeatures;
+ List<String> mPackageOrder;
+ List<String> mAllowedPackages;
+
boolean mActiveScan;
+
Bundle mExtras;
public Builder(@NonNull List<String> preferredFeatures, boolean activeScan) {
Objects.requireNonNull(preferredFeatures, "preferredFeatures must not be null");
mPreferredFeatures = preferredFeatures.stream().filter(str -> !TextUtils.isEmpty(str))
.collect(Collectors.toList());
+ mRequiredFeatures = List.of();
+ mPackageOrder = List.of();
+ mAllowedPackages = List.of();
mActiveScan = activeScan;
}
@@ -184,12 +258,15 @@
Objects.requireNonNull(preference, "preference must not be null");
mPreferredFeatures = preference.getPreferredFeatures();
+ mRequiredFeatures = preference.getRequiredFeatures();
+ mPackageOrder = preference.getDeduplicationPackageOrder();
+ mAllowedPackages = preference.getAllowedPackages();
mActiveScan = preference.shouldPerformActiveScan();
mExtras = preference.getExtras();
}
/**
- * A constructor to combine all of the preferences into a single preference.
+ * A constructor to combine all the preferences into a single preference.
* It ignores extras of preferences.
*
* @hide
@@ -224,6 +301,30 @@
}
/**
+ * Sets the required route features to discover.
+ */
+ @NonNull
+ public Builder setRequiredFeatures(@NonNull List<String> requiredFeatures) {
+ Objects.requireNonNull(requiredFeatures, "preferredFeatures must not be null");
+ mRequiredFeatures = requiredFeatures.stream().filter(str -> !TextUtils.isEmpty(str))
+ .collect(Collectors.toList());
+ return this;
+ }
+
+ /**
+ * Sets the list of package names of providers that media router would like to discover.
+ * <p>
+ * If it's non-empty, media router only discovers route from the provider in the list.
+ * The default value is empty, which discovers routes from all providers.
+ */
+ @NonNull
+ public Builder setAllowedPackages(@NonNull List<String> allowedPackages) {
+ Objects.requireNonNull(allowedPackages, "allowedPackages must not be null");
+ mAllowedPackages = List.copyOf(allowedPackages);
+ return this;
+ }
+
+ /**
* Sets if active scanning should be performed.
* <p>
* Since active scanning uses more system resources, set this as {@code true} only
@@ -237,6 +338,27 @@
}
/**
+ * Sets the order of packages when removing duplicate routes.
+ * <p>
+ * Routes are removed based on its
+ * {@link MediaRoute2Info#getDeduplicationIds() deduplication ID}.
+ * If two routes have the same ID, even if they are from different providers,
+ * one of them is removed from the list.
+ * <p>
+ * Routes from the provider whose package name appears first in the given package order
+ * will remain.
+ * If unspecified, any route can be selected.
+ *
+ * @param packageOrder list of package names for choosing routes to be removed or
+ * {@code null} not to remove duplicate routes.
+ */
+ @NonNull
+ public Builder setDeduplicationPackageOrder(@Nullable List<String> packageOrder) {
+ mPackageOrder = (packageOrder == null) ? null : List.copyOf(packageOrder);
+ return this;
+ }
+
+ /**
* Sets the extras of the route.
* @hide
*/
diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp
index a0f3098..bb25274 100644
--- a/native/graphics/jni/imagedecoder.cpp
+++ b/native/graphics/jni/imagedecoder.cpp
@@ -198,14 +198,16 @@
return kGray_8_SkColorType;
case ANDROID_BITMAP_FORMAT_RGBA_F16:
return kRGBA_F16_SkColorType;
+ case ANDROID_BITMAP_FORMAT_RGBA_1010102:
+ return kRGBA_1010102_SkColorType;
default:
return kUnknown_SkColorType;
}
}
int AImageDecoder_setAndroidBitmapFormat(AImageDecoder* decoder, int32_t format) {
- if (!decoder || format < ANDROID_BITMAP_FORMAT_NONE
- || format > ANDROID_BITMAP_FORMAT_RGBA_F16) {
+ if (!decoder || format < ANDROID_BITMAP_FORMAT_NONE ||
+ format > ANDROID_BITMAP_FORMAT_RGBA_1010102) {
return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
}
@@ -290,6 +292,8 @@
return ANDROID_BITMAP_FORMAT_A_8;
case kRGBA_F16_SkColorType:
return ANDROID_BITMAP_FORMAT_RGBA_F16;
+ case kRGBA_1010102_SkColorType:
+ return ANDROID_BITMAP_FORMAT_RGBA_1010102;
default:
return ANDROID_BITMAP_FORMAT_NONE;
}
diff --git a/packages/ConnectivityT/framework-t/Android.bp b/packages/ConnectivityT/framework-t/Android.bp
index 223bdcdd..327b1fb 100644
--- a/packages/ConnectivityT/framework-t/Android.bp
+++ b/packages/ConnectivityT/framework-t/Android.bp
@@ -39,7 +39,6 @@
"src/android/net/TrafficStats.java",
"src/android/net/UnderlyingNetworkInfo.*",
"src/android/net/netstats/**/*.*",
- "src/com/android/server/NetworkManagementSocketTagger.java",
],
path: "src",
visibility: [
@@ -176,3 +175,34 @@
"//packages/modules/Connectivity:__subpackages__",
],
}
+
+cc_library_shared {
+ name: "libframework-connectivity-tiramisu-jni",
+ min_sdk_version: "30",
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-unused-parameter",
+ // Don't warn about S API usage even with
+ // min_sdk 30: the library is only loaded
+ // on S+ devices
+ "-Wno-unguarded-availability",
+ "-Wthread-safety",
+ ],
+ srcs: [
+ "jni/android_net_TrafficStats.cpp",
+ "jni/onload.cpp",
+ ],
+ shared_libs: [
+ "liblog",
+ ],
+ static_libs: [
+ "libnativehelper_compat_libc++",
+ ],
+ stl: "none",
+ apex_available: [
+ "com.android.tethering",
+ // TODO: remove when ConnectivityT moves to APEX.
+ "//apex_available:platform",
+ ],
+}
diff --git a/packages/ConnectivityT/framework-t/jni/android_net_TrafficStats.cpp b/packages/ConnectivityT/framework-t/jni/android_net_TrafficStats.cpp
new file mode 100644
index 0000000..f3c58b1
--- /dev/null
+++ b/packages/ConnectivityT/framework-t/jni/android_net_TrafficStats.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#include <android/file_descriptor_jni.h>
+#include <android/multinetwork.h>
+#include <nativehelper/JNIHelp.h>
+
+namespace android {
+
+static jint tagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor, jint tag, jint uid) {
+ int fd = AFileDescriptor_getFd(env, fileDescriptor);
+ if (fd == -1) return -EBADF;
+ return android_tag_socket_with_uid(fd, tag, uid);
+}
+
+static jint untagSocketFd(JNIEnv* env, jclass, jobject fileDescriptor) {
+ int fd = AFileDescriptor_getFd(env, fileDescriptor);
+ if (fd == -1) return -EBADF;
+ return android_untag_socket(fd);
+}
+
+static const JNINativeMethod gMethods[] = {
+ /* name, signature, funcPtr */
+ { "native_tagSocketFd", "(Ljava/io/FileDescriptor;II)I", (void*) tagSocketFd },
+ { "native_untagSocketFd", "(Ljava/io/FileDescriptor;)I", (void*) untagSocketFd },
+};
+
+int register_android_net_TrafficStats(JNIEnv* env) {
+ return jniRegisterNativeMethods(env, "android/net/TrafficStats", gMethods, NELEM(gMethods));
+}
+
+}; // namespace android
+
diff --git a/packages/ConnectivityT/framework-t/jni/onload.cpp b/packages/ConnectivityT/framework-t/jni/onload.cpp
new file mode 100644
index 0000000..1fb42c6
--- /dev/null
+++ b/packages/ConnectivityT/framework-t/jni/onload.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "FrameworkConnectivityJNI"
+
+#include <log/log.h>
+#include <nativehelper/JNIHelp.h>
+
+namespace android {
+
+int register_android_net_TrafficStats(JNIEnv* env);
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
+ JNIEnv *env;
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "ERROR: GetEnv failed");
+ return JNI_ERR;
+ }
+
+ if (register_android_net_TrafficStats(env) < 0) return JNI_ERR;
+
+ return JNI_VERSION_1_6;
+}
+
+}; // namespace android
+
diff --git a/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java b/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java
index c2f0cdf..bc836d8 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/TrafficStats.java
@@ -31,12 +31,9 @@
import android.os.Binder;
import android.os.Build;
import android.os.RemoteException;
+import android.os.StrictMode;
import android.util.Log;
-import com.android.server.NetworkManagementSocketTagger;
-
-import dalvik.system.SocketTagger;
-
import java.io.FileDescriptor;
import java.io.IOException;
import java.net.DatagramSocket;
@@ -56,6 +53,10 @@
* use {@link NetworkStatsManager} instead.
*/
public class TrafficStats {
+ static {
+ System.loadLibrary("framework-connectivity-tiramisu-jni");
+ }
+
private static final String TAG = TrafficStats.class.getSimpleName();
/**
* The return value to indicate that the device does not support the statistic.
@@ -232,9 +233,68 @@
*/
@SystemApi(client = MODULE_LIBRARIES)
public static void attachSocketTagger() {
- NetworkManagementSocketTagger.install();
+ dalvik.system.SocketTagger.set(new SocketTagger());
}
+ private static class SocketTagger extends dalvik.system.SocketTagger {
+
+ // TODO: set to false
+ private static final boolean LOGD = true;
+
+ SocketTagger() {
+ }
+
+ @Override
+ public void tag(FileDescriptor fd) throws SocketException {
+ final UidTag tagInfo = sThreadUidTag.get();
+ if (LOGD) {
+ Log.d(TAG, "tagSocket(" + fd.getInt$() + ") with statsTag=0x"
+ + Integer.toHexString(tagInfo.tag) + ", statsUid=" + tagInfo.uid);
+ }
+ if (tagInfo.tag == -1) {
+ StrictMode.noteUntaggedSocket();
+ }
+
+ if (tagInfo.tag == -1 && tagInfo.uid == -1) return;
+ final int errno = native_tagSocketFd(fd, tagInfo.tag, tagInfo.uid);
+ if (errno < 0) {
+ Log.i(TAG, "tagSocketFd(" + fd.getInt$() + ", "
+ + tagInfo.tag + ", "
+ + tagInfo.uid + ") failed with errno" + errno);
+ }
+ }
+
+ @Override
+ public void untag(FileDescriptor fd) throws SocketException {
+ if (LOGD) {
+ Log.i(TAG, "untagSocket(" + fd.getInt$() + ")");
+ }
+
+ final UidTag tagInfo = sThreadUidTag.get();
+ if (tagInfo.tag == -1 && tagInfo.uid == -1) return;
+
+ final int errno = native_untagSocketFd(fd);
+ if (errno < 0) {
+ Log.w(TAG, "untagSocket(" + fd.getInt$() + ") failed with errno " + errno);
+ }
+ }
+ }
+
+ private static native int native_tagSocketFd(FileDescriptor fd, int tag, int uid);
+ private static native int native_untagSocketFd(FileDescriptor fd);
+
+ private static class UidTag {
+ public int tag = -1;
+ public int uid = -1;
+ }
+
+ private static ThreadLocal<UidTag> sThreadUidTag = new ThreadLocal<UidTag>() {
+ @Override
+ protected UidTag initialValue() {
+ return new UidTag();
+ }
+ };
+
/**
* Set active tag to use when accounting {@link Socket} traffic originating
* from the current thread. Only one active tag per thread is supported.
@@ -249,7 +309,7 @@
* @see #clearThreadStatsTag()
*/
public static void setThreadStatsTag(int tag) {
- NetworkManagementSocketTagger.setThreadSocketStatsTag(tag);
+ getAndSetThreadStatsTag(tag);
}
/**
@@ -267,7 +327,9 @@
* restore any existing values after a nested operation is finished
*/
public static int getAndSetThreadStatsTag(int tag) {
- return NetworkManagementSocketTagger.setThreadSocketStatsTag(tag);
+ final int old = sThreadUidTag.get().tag;
+ sThreadUidTag.get().tag = tag;
+ return old;
}
/**
@@ -327,7 +389,7 @@
* @see #setThreadStatsTag(int)
*/
public static int getThreadStatsTag() {
- return NetworkManagementSocketTagger.getThreadSocketStatsTag();
+ return sThreadUidTag.get().tag;
}
/**
@@ -337,7 +399,7 @@
* @see #setThreadStatsTag(int)
*/
public static void clearThreadStatsTag() {
- NetworkManagementSocketTagger.setThreadSocketStatsTag(-1);
+ sThreadUidTag.get().tag = -1;
}
/**
@@ -357,7 +419,7 @@
*/
@SuppressLint("RequiresPermission")
public static void setThreadStatsUid(int uid) {
- NetworkManagementSocketTagger.setThreadSocketStatsUid(uid);
+ sThreadUidTag.get().uid = uid;
}
/**
@@ -368,7 +430,7 @@
* @see #setThreadStatsUid(int)
*/
public static int getThreadStatsUid() {
- return NetworkManagementSocketTagger.getThreadSocketStatsUid();
+ return sThreadUidTag.get().uid;
}
/**
@@ -395,7 +457,7 @@
*/
@SuppressLint("RequiresPermission")
public static void clearThreadStatsUid() {
- NetworkManagementSocketTagger.setThreadSocketStatsUid(-1);
+ setThreadStatsUid(-1);
}
/**
diff --git a/packages/ConnectivityT/framework-t/src/com/android/server/NetworkManagementSocketTagger.java b/packages/ConnectivityT/framework-t/src/com/android/server/NetworkManagementSocketTagger.java
index 8bb12a6d..8aca1d6 100644
--- a/packages/ConnectivityT/framework-t/src/com/android/server/NetworkManagementSocketTagger.java
+++ b/packages/ConnectivityT/framework-t/src/com/android/server/NetworkManagementSocketTagger.java
@@ -111,19 +111,6 @@
public int statsUid = -1;
}
- /**
- * Convert {@code /proc/} tag format to {@link Integer}. Assumes incoming
- * format like {@code 0x7fffffff00000000}.
- */
- public static int kernelToTag(String string) {
- int length = string.length();
- if (length > 10) {
- return Long.decode(string.substring(0, length - 8)).intValue();
- } else {
- return 0;
- }
- }
-
private static native int native_tagSocketFd(FileDescriptor fd, int tag, int uid);
private static native int native_untagSocketFd(FileDescriptor fd);
}
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
index 17f3455..668d1cb 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
@@ -22,8 +22,6 @@
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
-import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
@@ -470,6 +468,19 @@
}
/**
+ * Convert {@code /proc/} tag format to {@link Integer}. Assumes incoming
+ * format like {@code 0x7fffffff00000000}.
+ */
+ public static int kernelToTag(String string) {
+ int length = string.length();
+ if (length > 10) {
+ return Long.decode(string.substring(0, length - 8)).intValue();
+ } else {
+ return 0;
+ }
+ }
+
+ /**
* Parse statistics from file into given {@link NetworkStats} object. Values
* are expected to monotonically increase since device boot.
*/
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 45f8f1d..af6a658 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1549,6 +1549,17 @@
<!-- Content description of the no calling for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_no_calling">No calling.</string>
+ <!-- Screensaver overlay which displays the time. [CHAR LIMIT=20] -->
+ <string name="dream_complication_title_time">Time</string>
+ <!-- Screensaver overlay which displays the date. [CHAR LIMIT=20] -->
+ <string name="dream_complication_title_date">Date</string>
+ <!-- Screensaver overlay which displays the weather. [CHAR LIMIT=20] -->
+ <string name="dream_complication_title_weather">Weather</string>
+ <!-- Screensaver overlay which displays air quality. [CHAR LIMIT=20] -->
+ <string name="dream_complication_title_aqi">Air Quality</string>
+ <!-- Screensaver overlay which displays cast info. [CHAR LIMIT=20] -->
+ <string name="dream_complication_title_cast_info">Cast Info</string>
+
<!-- Title for a screen allowing the user to choose a profile picture. [CHAR LIMIT=NONE] -->
<string name="avatar_picker_title">Choose a profile picture</string>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 3f322d6..f7b2974 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -16,8 +16,11 @@
package com.android.settingslib;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.CONTROLLED_BY_ADMIN_SUMMARY;
+
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
@@ -102,8 +105,11 @@
if (mDisabledSummary) {
final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
if (summaryView != null) {
- final CharSequence disabledText = summaryView.getContext().getText(
- R.string.disabled_by_admin_summary_text);
+ final CharSequence disabledText = mContext
+ .getSystemService(DevicePolicyManager.class)
+ .getString(CONTROLLED_BY_ADMIN_SUMMARY,
+ () -> summaryView.getContext().getString(
+ R.string.disabled_by_admin_summary_text));
if (mDisabledByAdmin) {
summaryView.setText(disabledText);
} else if (mDisabledByAppOps) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index d73e45e..883e080 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -1,7 +1,10 @@
package com.android.settingslib;
+import static android.app.admin.DevicePolicyResources.Strings.Settings.WORK_PROFILE_USER_LABEL;
+
import android.annotation.ColorInt;
import android.annotation.Nullable;
+import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -124,7 +127,8 @@
String name = info != null ? info.name : null;
if (info.isManagedProfile()) {
// We use predefined values for managed profiles
- return context.getString(R.string.managed_user_title);
+ return context.getSystemService(DevicePolicyManager.class).getString(
+ WORK_PROFILE_USER_LABEL, () -> context.getString(R.string.managed_user_title));
} else if (info.isGuest()) {
name = context.getString(R.string.user_guest);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
index 46e31ce..6bf43e5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
@@ -34,6 +34,7 @@
import android.provider.Settings;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
@@ -50,6 +51,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -292,6 +294,11 @@
}
}
+ /** Returns whether a particular complication is enabled */
+ public boolean isComplicationEnabled(@ComplicationType int complication) {
+ return getEnabledComplications().contains(complication);
+ }
+
/** Gets all complications which have been enabled by the user. */
public Set<Integer> getEnabledComplications() {
final String enabledComplications = Settings.Secure.getString(
@@ -331,6 +338,35 @@
convertToString(enabledComplications));
}
+ /**
+ * Gets the title of a particular complication type to be displayed to the user. If there
+ * is no title, null is returned.
+ */
+ @Nullable
+ public CharSequence getComplicationTitle(@ComplicationType int complicationType) {
+ int res = 0;
+ switch (complicationType) {
+ case COMPLICATION_TYPE_TIME:
+ res = R.string.dream_complication_title_time;
+ break;
+ case COMPLICATION_TYPE_DATE:
+ res = R.string.dream_complication_title_date;
+ break;
+ case COMPLICATION_TYPE_WEATHER:
+ res = R.string.dream_complication_title_weather;
+ break;
+ case COMPLICATION_TYPE_AIR_QUALITY:
+ res = R.string.dream_complication_title_aqi;
+ break;
+ case COMPLICATION_TYPE_CAST_INFO:
+ res = R.string.dream_complication_title_cast_info;
+ break;
+ default:
+ return null;
+ }
+ return mContext.getString(res);
+ }
+
private static String convertToString(Set<Integer> set) {
return set.stream()
.map(String::valueOf)
@@ -338,6 +374,9 @@
}
private static Set<Integer> parseFromString(String string) {
+ if (TextUtils.isEmpty(string)) {
+ return new HashSet<>();
+ }
return Arrays.stream(string.split(","))
.map(Integer::parseInt)
.collect(Collectors.toSet());
diff --git a/packages/SystemUI/res/layout/dream_overlay_complications_layer.xml b/packages/SystemUI/res/layout/dream_overlay_complications_layer.xml
index aaff3f9..2d565a1 100644
--- a/packages/SystemUI/res/layout/dream_overlay_complications_layer.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_complications_layer.xml
@@ -20,6 +20,34 @@
android:id="@+id/dream_overlay_complications_layer"
android:layout_width="match_parent"
android:layout_height="match_parent">
+ <TextClock
+ android:id="@+id/time_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="sans-serif-thin"
+ android:format12Hour="h:mm"
+ android:format24Hour="kk:mm"
+ android:shadowColor="#B2000000"
+ android:shadowRadius="2.0"
+ android:singleLine="true"
+ android:textSize="72sp"
+ android:textColor="@android:color/white"
+ app:layout_constraintBottom_toTopOf="@+id/date_view"
+ app:layout_constraintStart_toStartOf="parent" />
+ <TextClock
+ android:id="@+id/date_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:shadowColor="#B2000000"
+ android:shadowRadius="2.0"
+ android:format12Hour="EEE, MMM d"
+ android:format24Hour="EEE, MMM d"
+ android:singleLine="true"
+ android:textSize="18sp"
+ android:textColor="@android:color/white"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="@+id/time_view"
+ app:layout_constraintStart_toStartOf="@+id/time_view" />
<androidx.constraintlayout.widget.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -44,30 +72,4 @@
android:id="@+id/complication_start_guide"
app:layout_constraintGuide_percent="@dimen/dream_overlay_complication_guide_start_percent"
android:orientation="vertical"/>
- <TextClock
- android:id="@+id/time_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:fontFamily="sans-serif-thin"
- android:format12Hour="h:mm"
- android:format24Hour="kk:mm"
- android:shadowColor="#B2000000"
- android:shadowRadius="2.0"
- android:singleLine="true"
- android:textSize="72sp"
- app:layout_constraintBottom_toTopOf="@+id/date_view"
- app:layout_constraintStart_toStartOf="parent" />
- <TextClock
- android:id="@+id/date_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:shadowColor="#B2000000"
- android:shadowRadius="2.0"
- android:format12Hour="EEE, MMM d"
- android:format24Hour="EEE, MMM d"
- android:singleLine="true"
- android:textSize="18sp"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="@+id/time_view"
- app:layout_constraintStart_toStartOf="@+id/time_view" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index fc5edf3..9d24e9b 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -66,4 +66,6 @@
<dimen name="controls_management_favorites_top_margin">8dp</dimen>
<dimen name="wallet_card_carousel_container_top_margin">24dp</dimen>
+
+ <dimen name="large_dialog_width">348dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 7d03301..a66ed15 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -69,5 +69,5 @@
<dimen name="qs_detail_margin_top">0dp</dimen>
<!-- The width of large/content heavy dialogs (e.g. Internet, Media output, etc) -->
- <dimen name="large_dialog_width">504dp</dimen>
+ <dimen name="large_dialog_width">472dp</dimen>
</resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/communal/ICommunalHost.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/communal/ICommunalHost.aidl
deleted file mode 100644
index b76be4f..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/communal/ICommunalHost.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.shared.communal;
-
-import com.android.systemui.shared.communal.ICommunalSource;
-
-/**
-* An interface, implemented by SystemUI, for hosting a shared, communal surface on the lock
-* screen. Clients declare themselves sources (as defined by ICommunalSource). ICommunalHost is
-* meant only for the input of said sources. The lifetime scope and interactions that follow after
-* are bound to source.
-*/
-oneway interface ICommunalHost {
- /**
- * Invoked to specify the CommunalSource that should be consulted for communal surfaces to be
- * displayed.
- */
- void setSource(in ICommunalSource source) = 1;
-}
\ No newline at end of file
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/communal/ICommunalSource.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/communal/ICommunalSource.aidl
deleted file mode 100644
index 7ef403b..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/communal/ICommunalSource.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.shared.communal;
-
-import com.android.systemui.shared.communal.ICommunalSurfaceCallback;
-
-/**
- * An interface, implemented by clients of CommunalHost, to provide communal surfaces for SystemUI.
- * The associated binder proxy will be retained by SystemUI and called on-demand when a communal
- * surface is needed (either new instantiation or update).
- */
-oneway interface ICommunalSource {
- /**
- * Called by the CommunalHost when a new communal surface is needed. The provided arguments
- * match the arguments necessary to construct a SurfaceControlViewHost for producing a
- * SurfacePackage to return.
- */
- void getCommunalSurface(in IBinder hostToken, in int width, in int height, in int displayId,
- in ICommunalSurfaceCallback callback) = 1;
-}
\ No newline at end of file
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/communal/ICommunalSurfaceCallback.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/communal/ICommunalSurfaceCallback.aidl
deleted file mode 100644
index 3d5998b..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/communal/ICommunalSurfaceCallback.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.shared.communal;
-
-import android.view.SurfaceControlViewHost.SurfacePackage;
-
-/**
-* An interface for receiving the result of a surface request. ICommunalSurfaceCallback is
-* implemented by the CommunalHost (SystemUI) to process the results of a new communal surface.
-*/
-interface ICommunalSurfaceCallback {
- /**
- * Invoked when the CommunalSurface has generated the SurfacePackage to be displayed.
- */
- void onSurface(in SurfacePackage surfacePackage) = 1;
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index 96e2302..41287b6 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -26,10 +26,12 @@
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.clipboardoverlay.ClipboardListener;
import com.android.systemui.dreams.DreamOverlayRegistrant;
+import com.android.systemui.dreams.SmartSpaceComplication;
import com.android.systemui.globalactions.GlobalActionsComponent;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.dagger.KeyguardModule;
import com.android.systemui.log.SessionTracker;
+import com.android.systemui.media.dream.MediaDreamSentinel;
import com.android.systemui.media.systemsounds.HomeSoundEffectController;
import com.android.systemui.power.PowerUI;
import com.android.systemui.privacy.television.TvOngoingPrivacyChip;
@@ -218,4 +220,18 @@
@ClassKey(DreamOverlayRegistrant.class)
public abstract CoreStartable bindDreamOverlayRegistrant(
DreamOverlayRegistrant dreamOverlayRegistrant);
+
+ /** Inject into SmartSpaceComplication.Registrant */
+ @Binds
+ @IntoMap
+ @ClassKey(SmartSpaceComplication.Registrant.class)
+ public abstract CoreStartable bindSmartSpaceComplicationRegistrant(
+ SmartSpaceComplication.Registrant registrant);
+
+ /** Inject into MediaDreamSentinel. */
+ @Binds
+ @IntoMap
+ @ClassKey(MediaDreamSentinel.class)
+ public abstract CoreStartable bindMediaDreamSentinel(
+ MediaDreamSentinel sentinel);
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
index 3e4ae57..ac7457d 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
@@ -33,6 +33,7 @@
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
import javax.inject.Inject;
@@ -69,11 +70,20 @@
*/
default void onStateChanged() {
}
+
+ /**
+ * Called when the available complication types changes.
+ */
+ default void onAvailableComplicationTypesChanged() {
+ }
}
private final Executor mExecutor;
private final ArrayList<Callback> mCallbacks = new ArrayList<>();
+ @Complication.ComplicationType
+ private int mAvailableComplicationTypes = Complication.COMPLICATION_TYPE_NONE;
+
private final Collection<Complication> mComplications = new HashSet();
@VisibleForTesting
@@ -108,7 +118,25 @@
* Returns collection of present {@link Complication}.
*/
public Collection<Complication> getComplications() {
- return Collections.unmodifiableCollection(mComplications);
+ return getComplications(true);
+ }
+
+ /**
+ * Returns collection of present {@link Complication}.
+ */
+ public Collection<Complication> getComplications(boolean filterByAvailability) {
+ return Collections.unmodifiableCollection(filterByAvailability
+ ? mComplications
+ .stream()
+ .filter(complication -> {
+ @Complication.ComplicationType
+ final int requiredTypes = complication.getRequiredTypeAvailability();
+
+ return requiredTypes == Complication.COMPLICATION_TYPE_NONE
+ || (requiredTypes & getAvailableComplicationTypes()) == requiredTypes;
+ })
+ .collect(Collectors.toCollection(HashSet::new))
+ : mComplications);
}
private void notifyCallbacks(Consumer<Callback> callbackConsumer) {
@@ -180,4 +208,22 @@
public void setOverlayActive(boolean active) {
modifyState(active ? OP_SET_STATE : OP_CLEAR_STATE, STATE_DREAM_OVERLAY_ACTIVE);
}
+
+ /**
+ * Returns the available complication types.
+ */
+ @Complication.ComplicationType
+ public int getAvailableComplicationTypes() {
+ return mAvailableComplicationTypes;
+ }
+
+ /**
+ * Sets the available complication types for the dream overlay.
+ */
+ public void setAvailableComplicationTypes(@Complication.ComplicationType int types) {
+ mExecutor.execute(() -> {
+ mAvailableComplicationTypes = types;
+ mCallbacks.forEach(callback -> callback.onAvailableComplicationTypesChanged());
+ });
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
new file mode 100644
index 0000000..09221b4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
@@ -0,0 +1,113 @@
+/*
+ * 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.systemui.dreams;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import com.android.systemui.CoreStartable;
+import com.android.systemui.dreams.complication.Complication;
+import com.android.systemui.dreams.complication.ComplicationLayoutParams;
+import com.android.systemui.dreams.complication.ComplicationViewModel;
+import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
+
+import javax.inject.Inject;
+
+/**
+ * {@link SmartSpaceComplication} embodies the SmartSpace view found on the lockscreen as a
+ * {@link Complication}
+ */
+public class SmartSpaceComplication implements Complication {
+ /**
+ * {@link CoreStartable} responsbile for registering {@link SmartSpaceComplication} with
+ * SystemUI.
+ */
+ public static class Registrant extends CoreStartable {
+ private final LockscreenSmartspaceController mSmartSpaceController;
+ private final DreamOverlayStateController mDreamOverlayStateController;
+ private final SmartSpaceComplication mComplication;
+
+ /**
+ * Default constructor for {@link SmartSpaceComplication}.
+ */
+ @Inject
+ public Registrant(Context context,
+ DreamOverlayStateController dreamOverlayStateController,
+ SmartSpaceComplication smartSpaceComplication,
+ LockscreenSmartspaceController smartSpaceController) {
+ super(context);
+ mDreamOverlayStateController = dreamOverlayStateController;
+ mComplication = smartSpaceComplication;
+ mSmartSpaceController = smartSpaceController;
+ }
+
+ @Override
+ public void start() {
+ if (mSmartSpaceController.isEnabled()) {
+ mDreamOverlayStateController.addComplication(mComplication);
+ }
+ }
+ }
+
+ private static class SmartSpaceComplicationViewHolder implements ViewHolder {
+ private final LockscreenSmartspaceController mSmartSpaceController;
+ private final Context mContext;
+
+ protected SmartSpaceComplicationViewHolder(
+ Context context,
+ LockscreenSmartspaceController smartSpaceController) {
+ mSmartSpaceController = smartSpaceController;
+ mContext = context;
+ }
+
+ @Override
+ public View getView() {
+ final FrameLayout smartSpaceContainer = new FrameLayout(mContext);
+ smartSpaceContainer.addView(
+ mSmartSpaceController.buildAndConnectView(smartSpaceContainer),
+ new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+
+ return smartSpaceContainer;
+ }
+
+ @Override
+ public ComplicationLayoutParams getLayoutParams() {
+ return new ComplicationLayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT,
+ ComplicationLayoutParams.POSITION_TOP | ComplicationLayoutParams.POSITION_START,
+ ComplicationLayoutParams.DIRECTION_DOWN,
+ 0, true);
+ }
+ }
+
+ private final LockscreenSmartspaceController mSmartSpaceController;
+ private final Context mContext;
+
+ @Inject
+ public SmartSpaceComplication(Context context,
+ LockscreenSmartspaceController smartSpaceController) {
+ mContext = context;
+ mSmartSpaceController = smartSpaceController;
+ }
+
+ @Override
+ public ViewHolder createView(ComplicationViewModel model) {
+ return new SmartSpaceComplicationViewHolder(mContext, mSmartSpaceController);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/Complication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/Complication.java
index 4332f58..fe458f4 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/Complication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/Complication.java
@@ -228,4 +228,15 @@
* @return a {@link ViewHolder} for this {@link Complication} instance.
*/
ViewHolder createView(ComplicationViewModel model);
+
+ /**
+ * Returns the types that must be present in order for this complication to participate on
+ * the dream overlay. By default, this method returns
+ * {@code Complication.COMPLICATION_TYPE_NONE} to indicate no types are required.
+ * @return
+ */
+ @Complication.ComplicationType
+ default int getRequiredTypeAvailability() {
+ return Complication.COMPLICATION_TYPE_NONE;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationCollectionLiveData.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationCollectionLiveData.java
index 76818fa..f6fe8d2 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationCollectionLiveData.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationCollectionLiveData.java
@@ -42,6 +42,10 @@
setValue(mDreamOverlayStateController.getComplications());
}
+ @Override
+ public void onAvailableComplicationTypesChanged() {
+ setValue(mDreamOverlayStateController.getComplications());
+ }
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index c8cd432..64ebe56 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -31,6 +31,7 @@
import com.android.systemui.R
import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dreams.DreamOverlayStateController
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.CrossFadeHelper
@@ -82,7 +83,8 @@
private val notifLockscreenUserManager: NotificationLockscreenUserManager,
configurationController: ConfigurationController,
wakefulnessLifecycle: WakefulnessLifecycle,
- private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager
+ private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager,
+ private val dreamOverlayStateController: DreamOverlayStateController
) {
/**
@@ -167,7 +169,7 @@
})
}
- private val mediaHosts = arrayOfNulls<MediaHost>(LOCATION_LOCKSCREEN + 1)
+ private val mediaHosts = arrayOfNulls<MediaHost>(LOCATION_DREAM_OVERLAY + 1)
/**
* The last location where this view was at before going to the desired location. This is
* useful for guided transitions.
@@ -349,6 +351,17 @@
}
/**
+ * Is the doze animation currently Running
+ */
+ private var dreamOverlayActive: Boolean = false
+ private set(value) {
+ if (field != value) {
+ field = value
+ updateDesiredLocation(forceNoAnimation = true)
+ }
+ }
+
+ /**
* The current cross fade progress. 0.5f means it's just switching
* between the start and the end location and the content is fully faded, while 0.75f means
* that we're halfway faded in again in the target state.
@@ -444,6 +457,12 @@
}
})
+ dreamOverlayStateController.addCallback(object : DreamOverlayStateController.Callback {
+ override fun onStateChanged() {
+ dreamOverlayStateController.isOverlayActive.also { dreamOverlayActive = it }
+ }
+ })
+
wakefulnessLifecycle.addObserver(object : WakefulnessLifecycle.Observer {
override fun onFinishedGoingToSleep() {
goingToSleep = false
@@ -940,6 +959,7 @@
statusbarState == StatusBarState.FULLSCREEN_USER_SWITCHER))
val allowedOnLockscreen = notifLockscreenUserManager.shouldShowLockscreenNotifications()
val location = when {
+ dreamOverlayActive -> LOCATION_DREAM_OVERLAY
(qsExpansion > 0.0f || inSplitShade) && !onLockscreen -> LOCATION_QS
qsExpansion > 0.4f && onLockscreen -> LOCATION_QS
!hasActiveMedia -> LOCATION_QS
@@ -1035,6 +1055,11 @@
const val LOCATION_LOCKSCREEN = 2
/**
+ * Attached on the dream overlay
+ */
+ const val LOCATION_DREAM_OVERLAY = 3
+
+ /**
* Attached at the root of the hierarchy in an overlay
*/
const val IN_OVERLAY = -1000
diff --git a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
index 4baef3a..2bc910e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
@@ -25,6 +25,7 @@
import com.android.systemui.media.MediaHierarchyManager;
import com.android.systemui.media.MediaHost;
import com.android.systemui.media.MediaHostStatesManager;
+import com.android.systemui.media.dream.dagger.MediaComplicationComponent;
import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper;
import com.android.systemui.media.taptotransfer.MediaTttFlags;
import com.android.systemui.media.taptotransfer.receiver.MediaTttChipControllerReceiver;
@@ -43,11 +44,14 @@
import dagger.multibindings.IntoMap;
/** Dagger module for the media package. */
-@Module
+@Module(subcomponents = {
+ MediaComplicationComponent.class,
+})
public interface MediaModule {
String QS_PANEL = "media_qs_panel";
String QUICK_QS_PANEL = "media_quick_qs_panel";
String KEYGUARD = "media_keyguard";
+ String DREAM = "dream";
/** */
@Provides
@@ -82,6 +86,16 @@
/** */
@Provides
@SysUISingleton
+ @Named(DREAM)
+ static MediaHost providesDreamMediaHost(MediaHost.MediaHostStateHolder stateHolder,
+ MediaHierarchyManager hierarchyManager, MediaDataManager dataManager,
+ MediaHostStatesManager statesManager) {
+ return new MediaHost(stateHolder, hierarchyManager, dataManager, statesManager);
+ }
+
+ /** */
+ @Provides
+ @SysUISingleton
static Optional<MediaTttChipControllerSender> providesMediaTttChipControllerSender(
MediaTttFlags mediaTttFlags,
Context context,
diff --git a/packages/SystemUI/src/com/android/systemui/media/dream/MediaComplicationViewController.java b/packages/SystemUI/src/com/android/systemui/media/dream/MediaComplicationViewController.java
new file mode 100644
index 0000000..65c5bc7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/dream/MediaComplicationViewController.java
@@ -0,0 +1,68 @@
+/*
+ * 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.systemui.media.dream;
+
+import static com.android.systemui.media.dagger.MediaModule.DREAM;
+import static com.android.systemui.media.dream.dagger.MediaComplicationComponent.MediaComplicationModule.MEDIA_COMPLICATION_CONTAINER;
+
+import android.widget.FrameLayout;
+
+import com.android.systemui.media.MediaHierarchyManager;
+import com.android.systemui.media.MediaHost;
+import com.android.systemui.media.MediaHostState;
+import com.android.systemui.util.ViewController;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/**
+ * {@link MediaComplicationViewController} handles connecting the
+ * {@link com.android.systemui.dreams.complication.Complication} view to the {@link MediaHost}.
+ */
+public class MediaComplicationViewController extends ViewController<FrameLayout> {
+ private final MediaHost mMediaHost;
+
+ @Inject
+ public MediaComplicationViewController(
+ @Named(MEDIA_COMPLICATION_CONTAINER) FrameLayout view,
+ @Named(DREAM) MediaHost mediaHost) {
+ super(view);
+ mMediaHost = mediaHost;
+ }
+
+ @Override
+ protected void onInit() {
+ super.onInit();
+ mMediaHost.setExpansion(MediaHostState.COLLAPSED);
+ mMediaHost.setShowsOnlyActiveMedia(true);
+ mMediaHost.setFalsingProtectionNeeded(true);
+ mMediaHost.init(MediaHierarchyManager.LOCATION_DREAM_OVERLAY);
+ }
+
+ @Override
+ protected void onViewAttached() {
+ mMediaHost.hostView.setLayoutParams(new FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.WRAP_CONTENT));
+ mView.addView(mMediaHost.hostView);
+ }
+
+ @Override
+ protected void onViewDetached() {
+ mView.removeView(mMediaHost.hostView);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamComplication.java b/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamComplication.java
new file mode 100644
index 0000000..2c35db3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamComplication.java
@@ -0,0 +1,43 @@
+/*
+ * 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.systemui.media.dream;
+
+import com.android.systemui.dreams.complication.Complication;
+import com.android.systemui.dreams.complication.ComplicationViewModel;
+import com.android.systemui.media.dream.dagger.MediaComplicationComponent;
+
+import javax.inject.Inject;
+
+/**
+ * Media control complication for dream overlay.
+ */
+public class MediaDreamComplication implements Complication {
+ MediaComplicationComponent.Factory mComponentFactory;
+
+ /**
+ * Default constructor for {@link MediaDreamComplication}.
+ */
+ @Inject
+ public MediaDreamComplication(MediaComplicationComponent.Factory componentFactory) {
+ mComponentFactory = componentFactory;
+ }
+
+ @Override
+ public ViewHolder createView(ComplicationViewModel model) {
+ return mComponentFactory.create().getViewHolder();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamSentinel.java b/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamSentinel.java
new file mode 100644
index 0000000..8934cd10
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/dream/MediaDreamSentinel.java
@@ -0,0 +1,97 @@
+/*
+ * 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.systemui.media.dream;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.systemui.CoreStartable;
+import com.android.systemui.dreams.DreamOverlayStateController;
+import com.android.systemui.media.MediaData;
+import com.android.systemui.media.MediaDataManager;
+import com.android.systemui.media.SmartspaceMediaData;
+
+import javax.inject.Inject;
+
+/**
+ * {@link MediaDreamSentinel} is responsible for tracking media state and registering/unregistering
+ * the media complication as appropriate
+ */
+public class MediaDreamSentinel extends CoreStartable {
+ private MediaDataManager.Listener mListener = new MediaDataManager.Listener() {
+ private boolean mAdded;
+ @Override
+ public void onSmartspaceMediaDataRemoved(@NonNull String key, boolean immediately) {
+ }
+
+ @Override
+ public void onMediaDataRemoved(@NonNull String key) {
+ if (!mAdded) {
+ return;
+ }
+
+ if (mMediaDataManager.hasActiveMedia()) {
+ return;
+ }
+
+ mAdded = false;
+ mDreamOverlayStateController.removeComplication(mComplication);
+ }
+
+ @Override
+ public void onSmartspaceMediaDataLoaded(@NonNull String key,
+ @NonNull SmartspaceMediaData data, boolean shouldPrioritize,
+ boolean isSsReactivated) {
+ }
+
+ @Override
+ public void onMediaDataLoaded(@NonNull String key, @Nullable String oldKey,
+ @NonNull MediaData data, boolean immediately, int receivedSmartspaceCardLatency) {
+ if (mAdded) {
+ return;
+ }
+
+ if (!mMediaDataManager.hasActiveMedia()) {
+ return;
+ }
+
+ mAdded = true;
+ mDreamOverlayStateController.addComplication(mComplication);
+ }
+ };
+
+ private final MediaDataManager mMediaDataManager;
+ private final DreamOverlayStateController mDreamOverlayStateController;
+ private final MediaDreamComplication mComplication;
+
+ @Inject
+ public MediaDreamSentinel(Context context, MediaDataManager mediaDataManager,
+ DreamOverlayStateController dreamOverlayStateController,
+ MediaDreamComplication complication) {
+ super(context);
+ mMediaDataManager = mediaDataManager;
+ mDreamOverlayStateController = dreamOverlayStateController;
+ mComplication = complication;
+ }
+
+ @Override
+ public void start() {
+ mMediaDataManager.addListener(mListener);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dream/MediaViewHolder.java b/packages/SystemUI/src/com/android/systemui/media/dream/MediaViewHolder.java
new file mode 100644
index 0000000..128a38c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/dream/MediaViewHolder.java
@@ -0,0 +1,58 @@
+/*
+ * 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.systemui.media.dream;
+
+import static com.android.systemui.media.dream.dagger.MediaComplicationComponent.MediaComplicationModule.MEDIA_COMPLICATION_CONTAINER;
+import static com.android.systemui.media.dream.dagger.MediaComplicationComponent.MediaComplicationModule.MEDIA_COMPLICATION_LAYOUT_PARAMS;
+
+import android.view.View;
+import android.widget.FrameLayout;
+
+import com.android.systemui.dreams.complication.Complication;
+import com.android.systemui.dreams.complication.ComplicationLayoutParams;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/**
+ * {@link Complication.ViewHolder} implementation for media control.
+ */
+public class MediaViewHolder implements Complication.ViewHolder {
+ private final FrameLayout mContainer;
+ private final MediaComplicationViewController mViewController;
+ private final ComplicationLayoutParams mLayoutParams;
+
+ @Inject
+ MediaViewHolder(@Named(MEDIA_COMPLICATION_CONTAINER) FrameLayout container,
+ MediaComplicationViewController controller,
+ @Named(MEDIA_COMPLICATION_LAYOUT_PARAMS) ComplicationLayoutParams layoutParams) {
+ mContainer = container;
+ mViewController = controller;
+ mViewController.init();
+ mLayoutParams = layoutParams;
+ }
+
+ @Override
+ public View getView() {
+ return mContainer;
+ }
+
+ @Override
+ public ComplicationLayoutParams getLayoutParams() {
+ return mLayoutParams;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dream/dagger/MediaComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/media/dream/dagger/MediaComplicationComponent.java
new file mode 100644
index 0000000..3372899
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/dream/dagger/MediaComplicationComponent.java
@@ -0,0 +1,100 @@
+/*
+ * 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.systemui.media.dream.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import android.content.Context;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import com.android.systemui.dreams.complication.ComplicationLayoutParams;
+import com.android.systemui.media.dream.MediaViewHolder;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Named;
+import javax.inject.Scope;
+
+import dagger.Module;
+import dagger.Provides;
+import dagger.Subcomponent;
+
+/**
+ * {@link MediaComplicationComponent} is responsible for generating dependencies surrounding the
+ * media {@link com.android.systemui.dreams.complication.Complication}, such as view controllers
+ * and layout details.
+ */
+@Subcomponent(modules = {
+ MediaComplicationComponent.MediaComplicationModule.class,
+})
+@MediaComplicationComponent.MediaComplicationScope
+public interface MediaComplicationComponent {
+ @Documented
+ @Retention(RUNTIME)
+ @Scope
+ @interface MediaComplicationScope {}
+
+ /**
+ * Generates {@link MediaComplicationComponent}.
+ */
+ @Subcomponent.Factory
+ interface Factory {
+ MediaComplicationComponent create();
+ }
+
+ /**
+ * Creates {@link MediaViewHolder}.
+ */
+ MediaViewHolder getViewHolder();
+
+ /**
+ * Scoped values for {@link MediaComplicationComponent}.
+ */
+ @Module
+ interface MediaComplicationModule {
+ String MEDIA_COMPLICATION_CONTAINER = "media_complication_container";
+ String MEDIA_COMPLICATION_LAYOUT_PARAMS = "media_complication_layout_params";
+
+ /**
+ * Provides the complication view.
+ */
+ @Provides
+ @MediaComplicationScope
+ @Named(MEDIA_COMPLICATION_CONTAINER)
+ static FrameLayout provideComplicationContainer(Context context) {
+ return new FrameLayout(context);
+ }
+
+ /**
+ * Provides the layout parameters for the complication view.
+ */
+ @Provides
+ @MediaComplicationScope
+ @Named(MEDIA_COMPLICATION_LAYOUT_PARAMS)
+ static ComplicationLayoutParams provideLayoutParams() {
+ return new ComplicationLayoutParams(0,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ComplicationLayoutParams.POSITION_BOTTOM
+ | ComplicationLayoutParams.POSITION_END,
+ ComplicationLayoutParams.DIRECTION_UP,
+ 0,
+ true);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 4f4bd1e..90ed3c6 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -318,7 +318,11 @@
String recentsPackageName = recentsComponentName.getPackageName();
PackageManager manager = context.getPackageManager();
try {
- Resources resources = manager.getResourcesForApplication(recentsPackageName);
+ Resources resources = manager.getResourcesForApplication(
+ manager.getApplicationInfo(recentsPackageName,
+ PackageManager.MATCH_UNINSTALLED_PACKAGES
+ | PackageManager.MATCH_DISABLED_COMPONENTS
+ | PackageManager.GET_SHARED_LIBRARY_FILES));
int resId = resources.getIdentifier(
"gesture_blocking_activities", "array", recentsPackageName);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index bd948ece..f56602e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -518,6 +518,7 @@
}
private void recordHistoricalState(int newState, int lastState, boolean upcoming) {
+ Trace.traceCounter(Trace.TRACE_TAG_APP, "statusBarState", newState);
mHistoryIndex = (mHistoryIndex + 1) % HISTORY_SIZE;
HistoricalState state = mHistoricalRecords[mHistoryIndex];
state.mNewState = newState;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index febf2b5..ebfed1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -135,7 +135,7 @@
}
}.setDuration(CONTENT_FADE_DURATION);
- private static final int MAX_ICONS_ON_AOD = 5;
+ private static final int MAX_ICONS_ON_AOD = 3;
public static final int MAX_ICONS_ON_LOCKSCREEN = 3;
public static final int MAX_STATIC_ICONS = 4;
private static final int MAX_DOTS = 1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index a144533..2f3300a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -2987,6 +2987,7 @@
}
public void showKeyguardImpl() {
+ Trace.beginSection("StatusBar#showKeyguard");
mIsKeyguard = true;
// In case we're locking while a smartspace transition is in progress, reset it.
mKeyguardUnlockAnimationController.resetSmartspaceTransition();
@@ -3001,6 +3002,7 @@
mStatusBarStateController.setState(StatusBarState.KEYGUARD);
}
updatePanelExpansionForKeyguard();
+ Trace.endSection();
}
private void updatePanelExpansionForKeyguard() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index b203496..b833c89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -29,6 +29,7 @@
import android.hardware.biometrics.BiometricSourceType;
import android.os.Bundle;
import android.os.SystemClock;
+import android.os.Trace;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@@ -374,6 +375,7 @@
*/
@Override
public void show(Bundle options) {
+ Trace.beginSection("StatusBarKeyguardViewManager#show");
mShowing = true;
mNotificationShadeWindowController.setKeyguardShowing(true);
mKeyguardStateController.notifyKeyguardState(mShowing,
@@ -381,6 +383,7 @@
reset(true /* hideBouncerWhenShowing */);
SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_STATE_CHANGED,
SysUiStatsLog.KEYGUARD_STATE_CHANGED__STATE__SHOWN);
+ Trace.endSection();
}
/**
@@ -715,6 +718,7 @@
@Override
public void hide(long startTime, long fadeoutDuration) {
+ Trace.beginSection("StatusBarKeyguardViewManager#hide");
mShowing = false;
mKeyguardStateController.notifyKeyguardState(mShowing,
mKeyguardStateController.isOccluded());
@@ -814,6 +818,7 @@
}
SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_STATE_CHANGED,
SysUiStatsLog.KEYGUARD_STATE_CHANGED__STATE__HIDDEN);
+ Trace.endSection();
}
private boolean needsBypassFading() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index e3b4caa..d6fc0a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -23,6 +23,8 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
+import android.graphics.Insets;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -87,11 +89,8 @@
this(context, theme, dismissOnDeviceLock, null);
}
- /**
- * @param udfpsDialogManager If set, UDFPS will hide if this dialog is showing.
- */
public SystemUIDialog(Context context, int theme, boolean dismissOnDeviceLock,
- SystemUIDialogManager dialogManager) {
+ @Nullable SystemUIDialogManager dialogManager) {
super(context, theme);
mContext = context;
@@ -148,7 +147,7 @@
* the device configuration changes, and the result will be used to resize this dialog window.
*/
protected int getWidth() {
- return getDefaultDialogWidth(mContext);
+ return getDefaultDialogWidth(this);
}
/**
@@ -279,36 +278,53 @@
// We need to create the dialog first, otherwise the size will be overridden when it is
// created.
dialog.create();
- dialog.getWindow().setLayout(getDefaultDialogWidth(dialog.getContext()),
- getDefaultDialogHeight());
+ dialog.getWindow().setLayout(getDefaultDialogWidth(dialog), getDefaultDialogHeight());
}
- private static int getDefaultDialogWidth(Context context) {
- boolean isOnTablet = context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
- if (!isOnTablet) {
- return ViewGroup.LayoutParams.MATCH_PARENT;
- }
-
+ private static int getDefaultDialogWidth(Dialog dialog) {
+ Context context = dialog.getContext();
int flagValue = SystemProperties.getInt(FLAG_TABLET_DIALOG_WIDTH, 0);
if (flagValue == -1) {
// The width of bottom sheets (624dp).
- return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 624,
- context.getResources().getDisplayMetrics()));
+ return calculateDialogWidthWithInsets(dialog, 624);
} else if (flagValue == -2) {
// The suggested small width for all dialogs (348dp)
- return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 348,
- context.getResources().getDisplayMetrics()));
+ return calculateDialogWidthWithInsets(dialog, 348);
} else if (flagValue > 0) {
// Any given width.
- return Math.round(
- TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, flagValue,
- context.getResources().getDisplayMetrics()));
+ return calculateDialogWidthWithInsets(dialog, flagValue);
} else {
- // By default we use the same width as the notification shade in portrait mode (504dp).
- return context.getResources().getDimensionPixelSize(R.dimen.large_dialog_width);
+ // By default we use the same width as the notification shade in portrait mode.
+ int width = context.getResources().getDimensionPixelSize(R.dimen.large_dialog_width);
+ if (width > 0) {
+ // If we are neither WRAP_CONTENT or MATCH_PARENT, add the background insets so that
+ // the dialog is the desired width.
+ width += getHorizontalInsets(dialog);
+ }
+ return width;
}
}
+ /**
+ * Return the pixel width {@param dialog} should be so that it is {@param widthInDp} wide,
+ * taking its background insets into consideration.
+ */
+ private static int calculateDialogWidthWithInsets(Dialog dialog, int widthInDp) {
+ float widthInPixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, widthInDp,
+ dialog.getContext().getResources().getDisplayMetrics());
+ return Math.round(widthInPixels + getHorizontalInsets(dialog));
+ }
+
+ private static int getHorizontalInsets(Dialog dialog) {
+ if (dialog.getWindow().getDecorView() == null) {
+ return 0;
+ }
+
+ Drawable background = dialog.getWindow().getDecorView().getBackground();
+ Insets insets = background != null ? background.getOpticalInsets() : Insets.NONE;
+ return insets.left + insets.right;
+ }
+
private static int getDefaultDialogHeight() {
return ViewGroup.LayoutParams.WRAP_CONTENT;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
index 1859569..627da3c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
@@ -24,6 +24,7 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
@@ -120,4 +121,43 @@
mExecutor.runAllReady();
verify(mCallback, times(1)).onComplicationsChanged();
}
+
+ @Test
+ public void testComplicationFiltering() {
+ final DreamOverlayStateController stateController =
+ new DreamOverlayStateController(mExecutor);
+
+ final Complication alwaysAvailableComplication = Mockito.mock(Complication.class);
+ final Complication weatherComplication = Mockito.mock(Complication.class);
+ when(alwaysAvailableComplication.getRequiredTypeAvailability())
+ .thenReturn(Complication.COMPLICATION_TYPE_NONE);
+ when(weatherComplication.getRequiredTypeAvailability())
+ .thenReturn(Complication.COMPLICATION_TYPE_WEATHER);
+
+ stateController.addComplication(alwaysAvailableComplication);
+ stateController.addComplication(weatherComplication);
+
+ final DreamOverlayStateController.Callback callback =
+ Mockito.mock(DreamOverlayStateController.Callback.class);
+
+ stateController.addCallback(callback);
+ mExecutor.runAllReady();
+
+ {
+ final Collection<Complication> complications = stateController.getComplications();
+ assertThat(complications.contains(alwaysAvailableComplication)).isTrue();
+ assertThat(complications.contains(weatherComplication)).isFalse();
+ }
+
+ stateController.setAvailableComplicationTypes(Complication.COMPLICATION_TYPE_WEATHER);
+ mExecutor.runAllReady();
+ verify(callback).onAvailableComplicationTypesChanged();
+
+ {
+ final Collection<Complication> complications = stateController.getComplications();
+ assertThat(complications.contains(alwaysAvailableComplication)).isTrue();
+ assertThat(complications.contains(weatherComplication)).isTrue();
+ }
+
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
new file mode 100644
index 0000000..3b17a80
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/SmartSpaceComplicationTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.systemui.dreams;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class SmartSpaceComplicationTest extends SysuiTestCase {
+ @Mock
+ private Context mContext;
+
+ @Mock
+ private LockscreenSmartspaceController mSmartspaceController;
+
+ @Mock
+ private DreamOverlayStateController mDreamOverlayStateController;
+
+ @Mock
+ private SmartSpaceComplication mComplication;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ /**
+ * Ensures {@link SmartSpaceComplication} is only registered when it is available.
+ */
+ @Test
+ public void testAvailability() {
+ when(mSmartspaceController.isEnabled()).thenReturn(false);
+
+ final SmartSpaceComplication.Registrant registrant = new SmartSpaceComplication.Registrant(
+ mContext,
+ mDreamOverlayStateController,
+ mComplication,
+ mSmartspaceController);
+ registrant.start();
+ verify(mDreamOverlayStateController, never()).addComplication(any());
+
+ when(mSmartspaceController.isEnabled()).thenReturn(true);
+ registrant.start();
+ verify(mDreamOverlayStateController).addComplication(eq(mComplication));
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationCollectionLiveDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationCollectionLiveDataTest.java
index feeea5d..5fcf414 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationCollectionLiveDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationCollectionLiveDataTest.java
@@ -75,6 +75,10 @@
callbackCaptor.getValue().onComplicationsChanged();
verifyUpdate(observer, complications);
+
+ callbackCaptor.getValue().onAvailableComplicationTypesChanged();
+
+ verifyUpdate(observer, complications);
});
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
index a3ffb2f..97b3b10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
@@ -25,6 +25,7 @@
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.controls.controller.ControlsControllerImplTest.Companion.eq
+import com.android.systemui.dreams.DreamOverlayStateController
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.NotificationLockscreenUserManager
@@ -85,6 +86,8 @@
private lateinit var configurationController: ConfigurationController
@Mock
private lateinit var uniqueObjectHostView: UniqueObjectHostView
+ @Mock
+ private lateinit var dreamOverlayStateController: DreamOverlayStateController
@Captor
private lateinit var wakefullnessObserver: ArgumentCaptor<(WakefulnessLifecycle.Observer)>
@Captor
@@ -110,7 +113,8 @@
notificationLockscreenUserManager,
configurationController,
wakefulnessLifecycle,
- statusBarKeyguardViewManager)
+ statusBarKeyguardViewManager,
+ dreamOverlayStateController)
verify(wakefulnessLifecycle).addObserver(wakefullnessObserver.capture())
verify(statusBarStateController).addCallback(statusBarCallback.capture())
setupHost(lockHost, MediaHierarchyManager.LOCATION_LOCKSCREEN)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaComplicationViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaComplicationViewControllerTest.java
new file mode 100644
index 0000000..29188da
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaComplicationViewControllerTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.systemui.media.dream;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+
+import android.testing.AndroidTestingRunner;
+import android.widget.FrameLayout;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.media.MediaHost;
+import com.android.systemui.util.animation.UniqueObjectHostView;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class MediaComplicationViewControllerTest extends SysuiTestCase {
+ @Mock
+ private MediaHost mMediaHost;
+
+ @Mock
+ private UniqueObjectHostView mView;
+
+ @Mock
+ private FrameLayout mComplicationContainer;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mMediaHost.hostView = mView;
+ }
+
+ @Test
+ public void testMediaHostViewInteraction() {
+ final MediaComplicationViewController controller = new MediaComplicationViewController(
+ mComplicationContainer, mMediaHost);
+
+ controller.init();
+
+ controller.onViewAttached();
+ verify(mComplicationContainer).addView(eq(mView));
+
+ controller.onViewDetached();
+ verify(mComplicationContainer).removeView(eq(mView));
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaDreamSentinelTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaDreamSentinelTest.java
new file mode 100644
index 0000000..114fc90
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dream/MediaDreamSentinelTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.systemui.media.dream;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dreams.DreamOverlayStateController;
+import com.android.systemui.media.MediaData;
+import com.android.systemui.media.MediaDataManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class MediaDreamSentinelTest extends SysuiTestCase {
+ @Mock
+ MediaDataManager mMediaDataManager;
+
+ @Mock
+ DreamOverlayStateController mDreamOverlayStateController;
+
+ @Mock
+ MediaDreamComplication mComplication;
+
+ final String mKey = "key";
+ final String mOldKey = "old_key";
+
+ @Mock
+ MediaData mData;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testComplicationAddition() {
+ final MediaDreamSentinel sentinel = new MediaDreamSentinel(mContext, mMediaDataManager,
+ mDreamOverlayStateController, mComplication);
+
+ sentinel.start();
+
+ ArgumentCaptor<MediaDataManager.Listener> listenerCaptor =
+ ArgumentCaptor.forClass(MediaDataManager.Listener.class);
+ verify(mMediaDataManager).addListener(listenerCaptor.capture());
+
+ final MediaDataManager.Listener listener = listenerCaptor.getValue();
+
+ when(mMediaDataManager.hasActiveMedia()).thenReturn(false);
+ listener.onMediaDataLoaded(mKey, mOldKey, mData, true, 0);
+ verify(mDreamOverlayStateController, never()).addComplication(any());
+
+ when(mMediaDataManager.hasActiveMedia()).thenReturn(true);
+ listener.onMediaDataLoaded(mKey, mOldKey, mData, true, 0);
+ verify(mDreamOverlayStateController).addComplication(eq(mComplication));
+
+ listener.onMediaDataRemoved(mKey);
+ verify(mDreamOverlayStateController, never()).removeComplication(any());
+
+ when(mMediaDataManager.hasActiveMedia()).thenReturn(false);
+ listener.onMediaDataRemoved(mKey);
+ verify(mDreamOverlayStateController).removeComplication(eq(mComplication));
+ }
+
+}
diff --git a/services/Android.bp b/services/Android.bp
index af70692..7e00986 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -95,7 +95,6 @@
":services.selectiontoolbar-sources",
":services.smartspace-sources",
":services.speech-sources",
- ":services.startop.iorap-sources",
":services.systemcaptions-sources",
":services.translation-sources",
":services.texttospeech-sources",
@@ -151,7 +150,6 @@
"services.selectiontoolbar",
"services.smartspace",
"services.speech",
- "services.startop",
"services.systemcaptions",
"services.translation",
"services.texttospeech",
@@ -207,7 +205,6 @@
" --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/companion/java/com/android/server/companion/AssociationStoreImpl.java b/services/companion/java/com/android/server/companion/AssociationStoreImpl.java
index cda554e..3ccabaa 100644
--- a/services/companion/java/com/android/server/companion/AssociationStoreImpl.java
+++ b/services/companion/java/com/android/server/companion/AssociationStoreImpl.java
@@ -125,7 +125,7 @@
// Update the MacAddress-to-List<Association> map if needed.
final MacAddress updatedAddress = updated.getDeviceMacAddress();
final MacAddress currentAddress = current.getDeviceMacAddress();
- macAddressChanged = Objects.equals(currentAddress, updatedAddress);
+ macAddressChanged = !Objects.equals(currentAddress, updatedAddress);
if (macAddressChanged) {
if (currentAddress != null) {
mAddressMap.get(currentAddress).remove(id);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 902659c..7e90383 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -256,6 +256,7 @@
import android.os.BugreportParams;
import android.os.Build;
import android.os.Bundle;
+import android.os.ConditionVariable;
import android.os.Debug;
import android.os.DropBoxManager;
import android.os.FactoryTest;
@@ -15478,6 +15479,62 @@
}
}
+ /**
+ * Dump the resources structure for the given process
+ *
+ * @param process The process to dump resource info for
+ * @param fd The FileDescriptor to dump it into
+ * @throws RemoteException
+ */
+ public boolean dumpResources(String process, ParcelFileDescriptor fd, RemoteCallback callback)
+ throws RemoteException {
+ synchronized (this) {
+ ProcessRecord proc = findProcessLOSP(process, UserHandle.USER_CURRENT, "dumpResources");
+ IApplicationThread thread;
+ if (proc == null || (thread = proc.getThread()) == null) {
+ throw new IllegalArgumentException("Unknown process: " + process);
+ }
+ thread.dumpResources(fd, callback);
+ return true;
+ }
+ }
+
+ /**
+ * Dump the resources structure for all processes
+ *
+ * @param fd The FileDescriptor to dump it into
+ * @throws RemoteException
+ */
+ public void dumpAllResources(ParcelFileDescriptor fd, PrintWriter pw) throws RemoteException {
+ synchronized (mProcLock) {
+ mProcessList.forEachLruProcessesLOSP(true, app -> {
+ ConditionVariable lock = new ConditionVariable();
+ RemoteCallback
+ finishCallback = new RemoteCallback(result -> lock.open(), null);
+
+ pw.println(String.format("------ DUMP RESOURCES %s (%s) ------",
+ app.processName,
+ app.info.packageName));
+ pw.flush();
+ try {
+ app.getThread().dumpResources(fd.dup(), finishCallback);
+ lock.block(2000);
+ } catch (Exception e) {
+ pw.println(String.format(
+ "------ EXCEPTION DUMPING RESOURCES for %s (%s): %s ------",
+ app.processName,
+ app.info.packageName,
+ e.getMessage()));
+ pw.flush();
+ }
+ pw.println(String.format("------ END DUMP RESOURCES %s (%s) ------",
+ app.processName,
+ app.info.packageName));
+ pw.flush();
+ });
+ }
+ }
+
@Override
public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
String reportPackage) {
diff --git a/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java b/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
index 9136219..ec37134 100644
--- a/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
+++ b/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
@@ -116,9 +116,10 @@
});
}
- @RequiresPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
+ @Override
+ @RequiresPermission(Manifest.permission.MANAGE_GAME_ACTIVITY)
public void restartGame(int taskId) {
- mContext.enforceCallingPermission(Manifest.permission.FORCE_STOP_PACKAGES,
+ mContext.enforceCallingPermission(Manifest.permission.MANAGE_GAME_ACTIVITY,
"restartGame()");
mBackgroundExecutor.execute(() -> {
GameServiceProviderInstanceImpl.this.restartGame(taskId);
@@ -372,12 +373,12 @@
}, mBackgroundExecutor);
AndroidFuture<Void> unusedPostCreateGameSessionFuture =
- mGameSessionServiceConnector.post(gameService -> {
+ mGameSessionServiceConnector.post(gameSessionService -> {
CreateGameSessionRequest createGameSessionRequest =
new CreateGameSessionRequest(
taskId,
existingGameSessionRecord.getComponentName().getPackageName());
- gameService.create(
+ gameSessionService.create(
mGameSessionController,
createGameSessionRequest,
gameSessionViewHostConfiguration,
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index 1e00ea9..1b0341c 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -308,7 +308,8 @@
public void onFixedRotationFinished(int displayId) { }
@Override
- public void onKeepClearAreasChanged(int displayId, List<Rect> keepClearArea) { }
+ public void onKeepClearAreasChanged(int displayId, List<Rect> restricted,
+ List<Rect> unrestricted) { }
}
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index c2ca3a5..d0e39cc 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -23,7 +23,6 @@
import static com.android.server.devicestate.DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS;
import static com.android.server.devicestate.OverrideRequestController.STATUS_ACTIVE;
import static com.android.server.devicestate.OverrideRequestController.STATUS_CANCELED;
-import static com.android.server.devicestate.OverrideRequestController.STATUS_SUSPENDED;
import android.annotation.IntDef;
import android.annotation.IntRange;
@@ -348,7 +347,7 @@
mBaseState = Optional.of(baseState);
if (baseState.hasFlag(FLAG_CANCEL_OVERRIDE_REQUESTS)) {
- mOverrideRequestController.cancelOverrideRequests();
+ mOverrideRequestController.cancelOverrideRequest();
}
mOverrideRequestController.handleBaseStateChanged();
updatePendingStateLocked();
@@ -503,7 +502,7 @@
@OverrideRequestController.RequestStatus int status) {
if (status == STATUS_ACTIVE) {
mActiveOverride = Optional.of(request);
- } else if (status == STATUS_SUSPENDED || status == STATUS_CANCELED) {
+ } else if (status == STATUS_CANCELED) {
if (mActiveOverride.isPresent() && mActiveOverride.get() == request) {
mActiveOverride = Optional.empty();
}
@@ -528,8 +527,6 @@
// Schedule the notification now.
processRecord.notifyRequestActiveAsync(request.getToken());
}
- } else if (status == STATUS_SUSPENDED) {
- processRecord.notifyRequestSuspendedAsync(request.getToken());
} else {
processRecord.notifyRequestCanceledAsync(request.getToken());
}
@@ -595,15 +592,14 @@
}
}
- private void cancelRequestInternal(int callingPid, @NonNull IBinder token) {
+ private void cancelStateRequestInternal(int callingPid) {
synchronized (mLock) {
final ProcessRecord processRecord = mProcessRecords.get(callingPid);
if (processRecord == null) {
throw new IllegalStateException("Process " + callingPid
+ " has no registered callback.");
}
-
- mOverrideRequestController.cancelRequest(token);
+ mActiveOverride.ifPresent(mOverrideRequestController::cancelRequest);
}
}
@@ -628,6 +624,23 @@
}
}
+ /**
+ * Allow top processes to request or cancel a device state change. If the calling process ID is
+ * not the top app, then check if this process holds the CONTROL_DEVICE_STATE permission.
+ * @param callingPid
+ */
+ private void checkCanControlDeviceState(int callingPid) {
+ // Allow top processes to request a device state change
+ // If the calling process ID is not the top app, then we check if this process
+ // holds a permission to CONTROL_DEVICE_STATE
+ final WindowProcessController topApp = mActivityTaskManagerInternal.getTopApp();
+ if (topApp == null || topApp.getPid() != callingPid) {
+ getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE,
+ "Permission required to request device state, "
+ + "or the call must come from the top focused app.");
+ }
+ }
+
private final class DeviceStateProviderListener implements DeviceStateProvider.Listener {
@Override
public void onSupportedDeviceStatesChanged(DeviceState[] newDeviceStates) {
@@ -716,24 +729,6 @@
});
}
- public void notifyRequestSuspendedAsync(IBinder token) {
- @RequestStatus Integer lastStatus = mLastNotifiedStatus.get(token);
- if (lastStatus != null
- && (lastStatus == STATUS_SUSPENDED || lastStatus == STATUS_CANCELED)) {
- return;
- }
-
- mLastNotifiedStatus.put(token, STATUS_SUSPENDED);
- mHandler.post(() -> {
- try {
- mCallback.onRequestSuspended(token);
- } catch (RemoteException ex) {
- Slog.w(TAG, "Failed to notify process " + mPid + " that request state changed.",
- ex);
- }
- });
- }
-
public void notifyRequestCanceledAsync(IBinder token) {
@RequestStatus Integer lastStatus = mLastNotifiedStatus.get(token);
if (lastStatus != null && lastStatus == STATUS_CANCELED) {
@@ -782,12 +777,7 @@
// Allow top processes to request a device state change
// If the calling process ID is not the top app, then we check if this process
// holds a permission to CONTROL_DEVICE_STATE
- final WindowProcessController topApp = mActivityTaskManagerInternal.getTopApp();
- if (topApp.getPid() != callingPid) {
- getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE,
- "Permission required to request device state, "
- + "or the call must come from the top focused app.");
- }
+ checkCanControlDeviceState(callingPid);
if (token == null) {
throw new IllegalArgumentException("Request token must not be null.");
@@ -802,25 +792,16 @@
}
@Override // Binder call
- public void cancelRequest(IBinder token) {
+ public void cancelStateRequest() {
final int callingPid = Binder.getCallingPid();
// Allow top processes to cancel a device state change
// If the calling process ID is not the top app, then we check if this process
// holds a permission to CONTROL_DEVICE_STATE
- final WindowProcessController topApp = mActivityTaskManagerInternal.getTopApp();
- if (topApp.getPid() != callingPid) {
- getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE,
- "Permission required to cancel device state, "
- + "or the call must come from the top focused app.");
- }
-
- if (token == null) {
- throw new IllegalArgumentException("Request token must not be null.");
- }
+ checkCanControlDeviceState(callingPid);
final long callingIdentity = Binder.clearCallingIdentity();
try {
- cancelRequestInternal(callingPid, token);
+ cancelStateRequestInternal(callingPid);
} finally {
Binder.restoreCallingIdentity(callingIdentity);
}
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java
index eed68f8..659ee75 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java
@@ -97,7 +97,7 @@
try {
if ("reset".equals(nextArg)) {
if (sLastRequest != null) {
- mClient.cancelRequest(sLastRequest);
+ mClient.cancelStateRequest();
sLastRequest = null;
}
} else {
@@ -105,9 +105,6 @@
DeviceStateRequest request = DeviceStateRequest.newBuilder(requestedState).build();
mClient.requestState(request, null /* executor */, null /* callback */);
- if (sLastRequest != null) {
- mClient.cancelRequest(sLastRequest);
- }
sLastRequest = request;
}
diff --git a/services/core/java/com/android/server/devicestate/OverrideRequestController.java b/services/core/java/com/android/server/devicestate/OverrideRequestController.java
index 36cb416..01f5a09 100644
--- a/services/core/java/com/android/server/devicestate/OverrideRequestController.java
+++ b/services/core/java/com/android/server/devicestate/OverrideRequestController.java
@@ -18,15 +18,13 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.hardware.devicestate.DeviceStateRequest;
import android.os.IBinder;
+import android.util.Slog;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
/**
* Manages the lifecycle of override requests.
@@ -36,29 +34,26 @@
* <ul>
* <li>A new request is added with {@link #addRequest(OverrideRequest)}, in which case the
* request will become suspended.</li>
- * <li>The request is cancelled with {@link #cancelRequest(IBinder)} or as a side effect
+ * <li>The request is cancelled with {@link #cancelRequest} or as a side effect
* of other methods calls, such as {@link #handleProcessDied(int)}.</li>
* </ul>
*/
final class OverrideRequestController {
+ private static final String TAG = "OverrideRequestController";
+
static final int STATUS_UNKNOWN = 0;
/**
* The request is the top-most request.
*/
static final int STATUS_ACTIVE = 1;
/**
- * The request is still present but is being superseded by another request.
- */
- static final int STATUS_SUSPENDED = 2;
- /**
* The request is not longer valid.
*/
- static final int STATUS_CANCELED = 3;
+ static final int STATUS_CANCELED = 2;
@IntDef(prefix = {"STATUS_"}, value = {
STATUS_UNKNOWN,
STATUS_ACTIVE,
- STATUS_SUSPENDED,
STATUS_CANCELED
})
@Retention(RetentionPolicy.SOURCE)
@@ -68,8 +63,6 @@
switch (status) {
case STATUS_ACTIVE:
return "ACTIVE";
- case STATUS_SUSPENDED:
- return "SUSPENDED";
case STATUS_CANCELED:
return "CANCELED";
case STATUS_UNKNOWN:
@@ -79,15 +72,13 @@
}
private final StatusChangeListener mListener;
- private final List<OverrideRequest> mTmpRequestsToCancel = new ArrayList<>();
- // List of override requests with the most recent override request at the end.
- private final ArrayList<OverrideRequest> mRequests = new ArrayList<>();
+ // Handle to the current override request, null if none.
+ private OverrideRequest mRequest;
private boolean mStickyRequestsAllowed;
- // List of override requests that have outlived their process and will only be cancelled through
- // a call to cancelStickyRequests().
- private final ArrayList<OverrideRequest> mStickyRequests = new ArrayList<>();
+ // The current request has outlived their process.
+ private boolean mStickyRequest;
OverrideRequestController(@NonNull StatusChangeListener listener) {
mListener = listener;
@@ -97,26 +88,26 @@
* Sets sticky requests as either allowed or disallowed. When sticky requests are allowed a call
* to {@link #handleProcessDied(int)} will not result in the request being cancelled
* immediately. Instead, the request will be marked sticky and must be cancelled with a call
- * to {@link #cancelStickyRequests()}.
+ * to {@link #cancelStickyRequest()}.
*/
void setStickyRequestsAllowed(boolean stickyRequestsAllowed) {
mStickyRequestsAllowed = stickyRequestsAllowed;
if (!mStickyRequestsAllowed) {
- cancelStickyRequests();
+ cancelStickyRequest();
}
}
/**
- * Adds a request to the top of the stack and notifies the listener of all changes to request
- * status as a result of this operation.
+ * Sets the new request as active and cancels the previous override request, notifies the
+ * listener of all changes to request status as a result of this operation.
*/
void addRequest(@NonNull OverrideRequest request) {
- mRequests.add(request);
+ OverrideRequest previousRequest = mRequest;
+ mRequest = request;
mListener.onStatusChanged(request, STATUS_ACTIVE);
- if (mRequests.size() > 1) {
- OverrideRequest prevRequest = mRequests.get(mRequests.size() - 2);
- mListener.onStatusChanged(prevRequest, STATUS_SUSPENDED);
+ if (previousRequest != null) {
+ cancelRequestLocked(previousRequest);
}
}
@@ -124,42 +115,32 @@
* Cancels the request with the specified {@code token} and notifies the listener of all changes
* to request status as a result of this operation.
*/
- void cancelRequest(@NonNull IBinder token) {
- int index = getRequestIndex(token);
- if (index == -1) {
+ void cancelRequest(@NonNull OverrideRequest request) {
+ // Either don't have a current request or attempting to cancel an already cancelled request
+ if (!hasRequest(request.getToken())) {
return;
}
-
- OverrideRequest request = mRequests.remove(index);
- if (index == mRequests.size() && mRequests.size() > 0) {
- // We removed the current active request so we need to set the new active request
- // before cancelling this request.
- OverrideRequest newTop = getLast(mRequests);
- mListener.onStatusChanged(newTop, STATUS_ACTIVE);
- }
- mListener.onStatusChanged(request, STATUS_CANCELED);
+ cancelCurrentRequestLocked();
}
/**
- * Cancels all requests that are currently marked sticky and notifies the listener of all
+ * Cancels a request that is currently marked sticky and notifies the listener of all
* changes to request status as a result of this operation.
*
* @see #setStickyRequestsAllowed(boolean)
*/
- void cancelStickyRequests() {
- mTmpRequestsToCancel.clear();
- mTmpRequestsToCancel.addAll(mStickyRequests);
- cancelRequestsLocked(mTmpRequestsToCancel);
+ void cancelStickyRequest() {
+ if (mStickyRequest) {
+ cancelCurrentRequestLocked();
+ }
}
/**
- * Cancels all override requests, this could be due to the device being put
+ * Cancels the current override request, this could be due to the device being put
* into a hardware state that declares the flag "FLAG_CANCEL_OVERRIDE_REQUESTS"
*/
- void cancelOverrideRequests() {
- mTmpRequestsToCancel.clear();
- mTmpRequestsToCancel.addAll(mRequests);
- cancelRequestsLocked(mTmpRequestsToCancel);
+ void cancelOverrideRequest() {
+ cancelCurrentRequestLocked();
}
/**
@@ -167,7 +148,7 @@
* {@code token}, {@code false} otherwise.
*/
boolean hasRequest(@NonNull IBinder token) {
- return getRequestIndex(token) != -1;
+ return mRequest != null && token == mRequest.getToken();
}
/**
@@ -176,139 +157,79 @@
* operation.
*/
void handleProcessDied(int pid) {
- if (mRequests.isEmpty()) {
+ if (mRequest == null) {
return;
}
- mTmpRequestsToCancel.clear();
- OverrideRequest prevActiveRequest = getLast(mRequests);
- for (OverrideRequest request : mRequests) {
- if (request.getPid() == pid) {
- mTmpRequestsToCancel.add(request);
+ if (mRequest.getPid() == pid) {
+ if (mStickyRequestsAllowed) {
+ // Do not cancel the requests now because sticky requests are allowed. These
+ // requests will be cancelled on a call to cancelStickyRequests().
+ mStickyRequest = true;
+ return;
}
+ cancelCurrentRequestLocked();
}
-
- if (mStickyRequestsAllowed) {
- // Do not cancel the requests now because sticky requests are allowed. These
- // requests will be cancelled on a call to cancelStickyRequests().
- mStickyRequests.addAll(mTmpRequestsToCancel);
- return;
- }
-
- cancelRequestsLocked(mTmpRequestsToCancel);
}
/**
* Notifies the controller that the base state has changed. The controller will notify the
* listener of all changes to request status as a result of this change.
- *
- * @return {@code true} if calling this method has lead to a new active request, {@code false}
- * otherwise.
*/
- boolean handleBaseStateChanged() {
- if (mRequests.isEmpty()) {
- return false;
+ void handleBaseStateChanged() {
+ if (mRequest == null) {
+ return;
}
- mTmpRequestsToCancel.clear();
- OverrideRequest prevActiveRequest = getLast(mRequests);
- for (int i = 0; i < mRequests.size(); i++) {
- OverrideRequest request = mRequests.get(i);
- if ((request.getFlags() & DeviceStateRequest.FLAG_CANCEL_WHEN_BASE_CHANGES) != 0) {
- mTmpRequestsToCancel.add(request);
- }
+ if ((mRequest.getFlags()
+ & DeviceStateRequest.FLAG_CANCEL_WHEN_BASE_CHANGES) != 0) {
+ cancelCurrentRequestLocked();
}
-
- final boolean newActiveRequest = cancelRequestsLocked(mTmpRequestsToCancel);
- return newActiveRequest;
}
/**
* Notifies the controller that the set of supported states has changed. The controller will
* notify the listener of all changes to request status as a result of this change.
- *
- * @return {@code true} if calling this method has lead to a new active request, {@code false}
- * otherwise.
*/
- boolean handleNewSupportedStates(int[] newSupportedStates) {
- if (mRequests.isEmpty()) {
- return false;
+ void handleNewSupportedStates(int[] newSupportedStates) {
+ if (mRequest == null) {
+ return;
}
- mTmpRequestsToCancel.clear();
- for (int i = 0; i < mRequests.size(); i++) {
- OverrideRequest request = mRequests.get(i);
- if (!contains(newSupportedStates, request.getRequestedState())) {
- mTmpRequestsToCancel.add(request);
- }
+ if (!contains(newSupportedStates, mRequest.getRequestedState())) {
+ cancelCurrentRequestLocked();
}
-
- final boolean newActiveRequest = cancelRequestsLocked(mTmpRequestsToCancel);
- return newActiveRequest;
}
void dumpInternal(PrintWriter pw) {
- final int requestCount = mRequests.size();
+ OverrideRequest overrideRequest = mRequest;
+ final boolean requestActive = overrideRequest != null;
pw.println();
- pw.println("Override requests: size=" + requestCount);
- for (int i = 0; i < requestCount; i++) {
- OverrideRequest overrideRequest = mRequests.get(i);
- int status = (i == requestCount - 1) ? STATUS_ACTIVE : STATUS_SUSPENDED;
- pw.println(" " + i + ": mPid=" + overrideRequest.getPid()
+ pw.println("Override Request active: " + requestActive);
+ if (requestActive) {
+ pw.println("Request: mPid=" + overrideRequest.getPid()
+ ", mRequestedState=" + overrideRequest.getRequestedState()
+ ", mFlags=" + overrideRequest.getFlags()
- + ", mStatus=" + statusToString(status));
+ + ", mStatus=" + statusToString(STATUS_ACTIVE));
}
}
+ private void cancelRequestLocked(@NonNull OverrideRequest requestToCancel) {
+ mListener.onStatusChanged(requestToCancel, STATUS_CANCELED);
+ }
+
/**
- * Handles cancelling a set of requests. If the set of requests to cancel will lead to a new
- * request becoming active this request will also be notified of its change in state.
- *
- * @return {@code true} if calling this method has lead to a new active request, {@code false}
- * otherwise.
+ * Handles cancelling {@code mRequest}.
+ * Notifies the listener of the canceled status as well.
*/
- private boolean cancelRequestsLocked(List<OverrideRequest> requestsToCancel) {
- if (requestsToCancel.isEmpty()) {
- return false;
+ private void cancelCurrentRequestLocked() {
+ if (mRequest == null) {
+ Slog.w(TAG, "Attempted to cancel a null OverrideRequest");
+ return;
}
-
- OverrideRequest prevActiveRequest = getLast(mRequests);
- boolean causedNewRequestToBecomeActive = false;
- mRequests.removeAll(requestsToCancel);
- mStickyRequests.removeAll(requestsToCancel);
- if (!mRequests.isEmpty()) {
- OverrideRequest newActiveRequest = getLast(mRequests);
- if (newActiveRequest != prevActiveRequest) {
- mListener.onStatusChanged(newActiveRequest, STATUS_ACTIVE);
- causedNewRequestToBecomeActive = true;
- }
- }
-
- for (int i = 0; i < requestsToCancel.size(); i++) {
- mListener.onStatusChanged(requestsToCancel.get(i), STATUS_CANCELED);
- }
- return causedNewRequestToBecomeActive;
- }
-
- private int getRequestIndex(@NonNull IBinder token) {
- final int numberOfRequests = mRequests.size();
- if (numberOfRequests == 0) {
- return -1;
- }
-
- for (int i = 0; i < numberOfRequests; i++) {
- OverrideRequest request = mRequests.get(i);
- if (request.getToken() == token) {
- return i;
- }
- }
- return -1;
- }
-
- @Nullable
- private static <T> T getLast(List<T> list) {
- return list.size() > 0 ? list.get(list.size() - 1) : null;
+ mStickyRequest = false;
+ mListener.onStatusChanged(mRequest, STATUS_CANCELED);
+ mRequest = null;
}
private static boolean contains(int[] array, int value) {
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 611b288..f0a6af3 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -416,13 +416,14 @@
mCurrentDreamCanDoze = canDoze;
mCurrentDreamUserId = userId;
+ if (!mCurrentDreamName.equals(mAmbientDisplayComponent)) {
+ mUiEventLogger.log(DreamManagerEvent.DREAM_START);
+ }
+
PowerManager.WakeLock wakeLock = mPowerManager
.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "startDream");
mHandler.post(wakeLock.wrap(() -> {
mAtmInternal.notifyDreamStateChanged(true);
- if (!mCurrentDreamName.equals(mAmbientDisplayComponent)) {
- mUiEventLogger.log(DreamManagerEvent.DREAM_START);
- }
mController.startDream(newToken, name, isTest, canDoze, userId, wakeLock,
mDreamOverlayServiceName);
}));
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 8f05130..2d2edfa 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -20,6 +20,7 @@
import static android.Manifest.permission.MANAGE_BIOMETRIC;
import static android.Manifest.permission.READ_CONTACTS;
import static android.Manifest.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS;
+import static android.Manifest.permission.SET_INITIAL_LOCK;
import static android.app.admin.DevicePolicyResources.Strings.Core.PROFILE_ENCRYPTED_DETAIL;
import static android.app.admin.DevicePolicyResources.Strings.Core.PROFILE_ENCRYPTED_MESSAGE;
import static android.app.admin.DevicePolicyResources.Strings.Core.PROFILE_ENCRYPTED_TITLE;
@@ -1650,9 +1651,13 @@
"This operation requires secure lock screen feature");
}
if (!hasPermission(PERMISSION) && !hasPermission(SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS)) {
- throw new SecurityException(
- "setLockCredential requires SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS or "
- + PERMISSION);
+ if (hasPermission(SET_INITIAL_LOCK) && savedCredential.isNone()) {
+ // SET_INITIAL_LOCK can only be used if credential is not set.
+ } else {
+ throw new SecurityException(
+ "setLockCredential requires SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS or "
+ + PERMISSION);
+ }
}
final long identity = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 303ab46..7f997df 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -677,9 +677,9 @@
UserRecord userRecord = routerRecord.mUserRecord;
userRecord.mRouterRecords.remove(routerRecord);
routerRecord.mUserRecord.mHandler.sendMessage(
- obtainMessage(UserHandler::notifyPreferredFeaturesChangedToManagers,
+ obtainMessage(UserHandler::notifyDiscoveryPreferenceChangedToManagers,
routerRecord.mUserRecord.mHandler,
- routerRecord.mPackageName, /* preferredFeatures=*/ null));
+ routerRecord.mPackageName, null));
userRecord.mHandler.sendMessage(
obtainMessage(UserHandler::updateDiscoveryPreferenceOnHandler,
userRecord.mHandler));
@@ -694,10 +694,10 @@
}
routerRecord.mDiscoveryPreference = discoveryRequest;
routerRecord.mUserRecord.mHandler.sendMessage(
- obtainMessage(UserHandler::notifyPreferredFeaturesChangedToManagers,
+ obtainMessage(UserHandler::notifyDiscoveryPreferenceChangedToManagers,
routerRecord.mUserRecord.mHandler,
routerRecord.mPackageName,
- routerRecord.mDiscoveryPreference.getPreferredFeatures()));
+ routerRecord.mDiscoveryPreference));
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::updateDiscoveryPreferenceOnHandler,
routerRecord.mUserRecord.mHandler));
@@ -921,7 +921,7 @@
// TODO: UserRecord <-> routerRecord, why do they reference each other?
// How about removing mUserRecord from routerRecord?
routerRecord.mUserRecord.mHandler.sendMessage(
- obtainMessage(UserHandler::notifyPreferredFeaturesChangedToManager,
+ obtainMessage(UserHandler::notifyDiscoveryPreferenceChangedToManager,
routerRecord.mUserRecord.mHandler, routerRecord, manager));
}
@@ -2118,19 +2118,19 @@
}
}
- private void notifyPreferredFeaturesChangedToManager(@NonNull RouterRecord routerRecord,
+ private void notifyDiscoveryPreferenceChangedToManager(@NonNull RouterRecord routerRecord,
@NonNull IMediaRouter2Manager manager) {
try {
- manager.notifyPreferredFeaturesChanged(routerRecord.mPackageName,
- routerRecord.mDiscoveryPreference.getPreferredFeatures());
+ manager.notifyDiscoveryPreferenceChanged(routerRecord.mPackageName,
+ routerRecord.mDiscoveryPreference);
} catch (RemoteException ex) {
Slog.w(TAG, "Failed to notify preferred features changed."
+ " Manager probably died.", ex);
}
}
- private void notifyPreferredFeaturesChangedToManagers(@NonNull String routerPackageName,
- @Nullable List<String> preferredFeatures) {
+ private void notifyDiscoveryPreferenceChangedToManagers(@NonNull String routerPackageName,
+ @Nullable RouteDiscoveryPreference discoveryPreference) {
MediaRouter2ServiceImpl service = mServiceRef.get();
if (service == null) {
return;
@@ -2143,7 +2143,8 @@
}
for (IMediaRouter2Manager manager : managers) {
try {
- manager.notifyPreferredFeaturesChanged(routerPackageName, preferredFeatures);
+ manager.notifyDiscoveryPreferenceChanged(routerPackageName,
+ discoveryPreference);
} catch (RemoteException ex) {
Slog.w(TAG, "Failed to notify preferred features changed."
+ " Manager probably died.", ex);
diff --git a/services/core/java/com/android/server/notification/ZenModeFiltering.java b/services/core/java/com/android/server/notification/ZenModeFiltering.java
index b186f61..29aad63 100644
--- a/services/core/java/com/android/server/notification/ZenModeFiltering.java
+++ b/services/core/java/com/android/server/notification/ZenModeFiltering.java
@@ -24,11 +24,14 @@
import android.content.ComponentName;
import android.content.Context;
import android.media.AudioAttributes;
+import android.net.Uri;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.Settings.Global;
import android.service.notification.ZenModeConfig;
import android.telecom.TelecomManager;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.util.Slog;
@@ -36,6 +39,8 @@
import com.android.internal.util.NotificationMessagingUtil;
import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
import java.util.Date;
public class ZenModeFiltering {
@@ -64,13 +69,22 @@
pw.print(prefix); pw.print("RepeatCallers.mThresholdMinutes=");
pw.println(REPEAT_CALLERS.mThresholdMinutes);
synchronized (REPEAT_CALLERS) {
- if (!REPEAT_CALLERS.mCalls.isEmpty()) {
- pw.print(prefix); pw.println("RepeatCallers.mCalls=");
- for (int i = 0; i < REPEAT_CALLERS.mCalls.size(); i++) {
+ if (!REPEAT_CALLERS.mTelCalls.isEmpty()) {
+ pw.print(prefix); pw.println("RepeatCallers.mTelCalls=");
+ for (int i = 0; i < REPEAT_CALLERS.mTelCalls.size(); i++) {
pw.print(prefix); pw.print(" ");
- pw.print(REPEAT_CALLERS.mCalls.keyAt(i));
+ pw.print(REPEAT_CALLERS.mTelCalls.keyAt(i));
pw.print(" at ");
- pw.println(ts(REPEAT_CALLERS.mCalls.valueAt(i)));
+ pw.println(ts(REPEAT_CALLERS.mTelCalls.valueAt(i)));
+ }
+ }
+ if (!REPEAT_CALLERS.mOtherCalls.isEmpty()) {
+ pw.print(prefix); pw.println("RepeatCallers.mOtherCalls=");
+ for (int i = 0; i < REPEAT_CALLERS.mOtherCalls.size(); i++) {
+ pw.print(prefix); pw.print(" ");
+ pw.print(REPEAT_CALLERS.mOtherCalls.keyAt(i));
+ pw.print(" at ");
+ pw.println(ts(REPEAT_CALLERS.mOtherCalls.valueAt(i)));
}
}
}
@@ -330,34 +344,39 @@
}
private static class RepeatCallers {
- // Person : time
- private final ArrayMap<String, Long> mCalls = new ArrayMap<>();
+ // We keep a separate map per uri scheme to do more generous number-matching
+ // handling on telephone numbers specifically. For other inputs, we
+ // simply match directly on the string.
+ private final ArrayMap<String, Long> mTelCalls = new ArrayMap<>();
+ private final ArrayMap<String, Long> mOtherCalls = new ArrayMap<>();
private int mThresholdMinutes;
private synchronized void recordCall(Context context, Bundle extras) {
setThresholdMinutes(context);
if (mThresholdMinutes <= 0 || extras == null) return;
- final String peopleString = peopleString(extras);
- if (peopleString == null) return;
+ final String[] extraPeople = ValidateNotificationPeople.getExtraPeople(extras);
+ if (extraPeople == null || extraPeople.length == 0) return;
final long now = System.currentTimeMillis();
- cleanUp(mCalls, now);
- mCalls.put(peopleString, now);
+ cleanUp(mTelCalls, now);
+ cleanUp(mOtherCalls, now);
+ recordCallers(extraPeople, now);
}
private synchronized boolean isRepeat(Context context, Bundle extras) {
setThresholdMinutes(context);
if (mThresholdMinutes <= 0 || extras == null) return false;
- final String peopleString = peopleString(extras);
- if (peopleString == null) return false;
+ final String[] extraPeople = ValidateNotificationPeople.getExtraPeople(extras);
+ if (extraPeople == null || extraPeople.length == 0) return false;
final long now = System.currentTimeMillis();
- cleanUp(mCalls, now);
- return mCalls.containsKey(peopleString);
+ cleanUp(mTelCalls, now);
+ cleanUp(mOtherCalls, now);
+ return checkCallers(context, extraPeople);
}
private synchronized void cleanUp(ArrayMap<String, Long> calls, long now) {
final int N = calls.size();
for (int i = N - 1; i >= 0; i--) {
- final long time = mCalls.valueAt(i);
+ final long time = calls.valueAt(i);
if (time > now || (now - time) > mThresholdMinutes * 1000 * 60) {
calls.removeAt(i);
}
@@ -367,10 +386,16 @@
// Clean up all calls that occurred after the given time.
// Used only for tests, to clean up after testing.
private synchronized void cleanUpCallsAfter(long timeThreshold) {
- for (int i = mCalls.size() - 1; i >= 0; i--) {
- final long time = mCalls.valueAt(i);
+ for (int i = mTelCalls.size() - 1; i >= 0; i--) {
+ final long time = mTelCalls.valueAt(i);
if (time > timeThreshold) {
- mCalls.removeAt(i);
+ mTelCalls.removeAt(i);
+ }
+ }
+ for (int j = mOtherCalls.size() - 1; j >= 0; j--) {
+ final long time = mOtherCalls.valueAt(j);
+ if (time > timeThreshold) {
+ mOtherCalls.removeAt(j);
}
}
}
@@ -382,21 +407,65 @@
}
}
- private static String peopleString(Bundle extras) {
- final String[] extraPeople = ValidateNotificationPeople.getExtraPeople(extras);
- if (extraPeople == null || extraPeople.length == 0) return null;
- final StringBuilder sb = new StringBuilder();
- for (int i = 0; i < extraPeople.length; i++) {
- String extraPerson = extraPeople[i];
- if (extraPerson == null) continue;
- extraPerson = extraPerson.trim();
- if (extraPerson.isEmpty()) continue;
- if (sb.length() > 0) {
- sb.append('|');
+ private synchronized void recordCallers(String[] people, long now) {
+ for (int i = 0; i < people.length; i++) {
+ String person = people[i];
+ if (person == null) continue;
+ final Uri uri = Uri.parse(person);
+ if ("tel".equals(uri.getScheme())) {
+ String tel = uri.getSchemeSpecificPart();
+ // while ideally we should not need to do this, sometimes we have seen tel
+ // numbers given in a url-encoded format
+ try {
+ tel = URLDecoder.decode(tel, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // ignore, keep the original tel string
+ Slog.w(TAG, "unsupported encoding in tel: uri input");
+ }
+ mTelCalls.put(tel, now);
+ } else {
+ // for non-tel calls, store the entire string, uri-component and all
+ mOtherCalls.put(person, now);
}
- sb.append(extraPerson);
}
- return sb.length() == 0 ? null : sb.toString();
+ }
+
+ private synchronized boolean checkCallers(Context context, String[] people) {
+ // get the default country code for checking telephone numbers
+ final String defaultCountryCode =
+ context.getSystemService(TelephonyManager.class).getNetworkCountryIso();
+ for (int i = 0; i < people.length; i++) {
+ String person = people[i];
+ if (person == null) continue;
+ final Uri uri = Uri.parse(person);
+ if ("tel".equals(uri.getScheme())) {
+ String number = uri.getSchemeSpecificPart();
+ if (mTelCalls.containsKey(number)) {
+ // check directly via map first
+ return true;
+ } else {
+ // see if a number that matches via areSameNumber exists
+ String numberToCheck = number;
+ try {
+ numberToCheck = URLDecoder.decode(number, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // ignore, continue to use the original string
+ Slog.w(TAG, "unsupported encoding in tel: uri input");
+ }
+ for (String prev : mTelCalls.keySet()) {
+ if (PhoneNumberUtils.areSamePhoneNumber(
+ numberToCheck, prev, defaultCountryCode)) {
+ return true;
+ }
+ }
+ }
+ } else {
+ if (mOtherCalls.containsKey(person)) {
+ return true;
+ }
+ }
+ }
+ return false;
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 99f70b2..4b59206 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -922,7 +922,7 @@
final List<SharedLibraryInfo> libs = libsSlice.getList();
for (int l = 0, lsize = libs.size(); l < lsize; ++l) {
SharedLibraryInfo lib = libs.get(l);
- if (lib.getType() == SharedLibraryInfo.TYPE_SDK) {
+ if (lib.getType() == SharedLibraryInfo.TYPE_SDK_PACKAGE) {
name = lib.getName() + ":" + lib.getLongVersion();
break;
}
diff --git a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
index 7e59bd6..f2b1a71 100644
--- a/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/pkg/AndroidPackageUtils.java
@@ -92,7 +92,7 @@
AndroidPackageUtils.getAllCodePaths(pkg),
pkg.getSdkLibName(),
pkg.getSdkLibVersionMajor(),
- SharedLibraryInfo.TYPE_SDK,
+ SharedLibraryInfo.TYPE_SDK_PACKAGE,
new VersionedPackage(pkg.getManifestPackageName(),
pkg.getLongVersionCode()),
null, null, false /* isNative */);
diff --git a/services/core/java/com/android/server/resources/ResourcesManagerService.java b/services/core/java/com/android/server/resources/ResourcesManagerService.java
new file mode 100644
index 0000000..cc27546
--- /dev/null
+++ b/services/core/java/com/android/server/resources/ResourcesManagerService.java
@@ -0,0 +1,102 @@
+/*
+ * 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.resources;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.IResourcesManager;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+
+import com.android.server.SystemService;
+import com.android.server.am.ActivityManagerService;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * A service for managing information about ResourcesManagers
+ */
+public class ResourcesManagerService extends SystemService {
+ private ActivityManagerService mActivityManagerService;
+
+ /**
+ * 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 ResourcesManagerService(@NonNull Context context) {
+ super(context);
+ publishBinderService(Context.RESOURCES_SERVICE, mService);
+ }
+
+ @Override
+ public void onStart() {
+ // Intentionally left empty.
+ }
+
+ private final IBinder mService = new IResourcesManager.Stub() {
+ @Override
+ public boolean dumpResources(String process, ParcelFileDescriptor fd,
+ RemoteCallback callback) throws RemoteException {
+ final int callingUid = Binder.getCallingUid();
+ if (callingUid != Process.ROOT_UID && callingUid != Process.SHELL_UID) {
+ callback.sendResult(null);
+ throw new SecurityException("dump should only be called by shell");
+ }
+ return mActivityManagerService.dumpResources(process, fd, callback);
+ }
+
+ @Override
+ protected void dump(@NonNull FileDescriptor fd,
+ @NonNull PrintWriter pw, @Nullable String[] args) {
+ try {
+ mActivityManagerService.dumpAllResources(ParcelFileDescriptor.dup(fd), pw);
+ } catch (Exception e) {
+ pw.println("Exception while trying to dump all resources: " + e.getMessage());
+ e.printStackTrace(pw);
+ }
+ }
+
+ @Override
+ public int handleShellCommand(@NonNull ParcelFileDescriptor in,
+ @NonNull ParcelFileDescriptor out,
+ @NonNull ParcelFileDescriptor err,
+ @NonNull String[] args) {
+ return (new ResourcesManagerShellCommand(this)).exec(
+ this,
+ in.getFileDescriptor(),
+ out.getFileDescriptor(),
+ err.getFileDescriptor(),
+ args);
+ }
+ };
+
+ public void setActivityManagerService(
+ ActivityManagerService activityManagerService) {
+ mActivityManagerService = activityManagerService;
+ }
+}
diff --git a/services/core/java/com/android/server/resources/ResourcesManagerShellCommand.java b/services/core/java/com/android/server/resources/ResourcesManagerShellCommand.java
new file mode 100644
index 0000000..7d8336a
--- /dev/null
+++ b/services/core/java/com/android/server/resources/ResourcesManagerShellCommand.java
@@ -0,0 +1,94 @@
+/*
+ * 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.resources;
+
+import android.content.res.IResourcesManager;
+import android.os.ConditionVariable;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+import android.os.ShellCommand;
+import android.util.Slog;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * Shell command handler for resources related commands
+ */
+public class ResourcesManagerShellCommand extends ShellCommand {
+ private static final String TAG = "ResourcesManagerShellCommand";
+
+ private final IResourcesManager mInterface;
+
+ public ResourcesManagerShellCommand(IResourcesManager anInterface) {
+ mInterface = anInterface;
+ }
+
+ @Override
+ public int onCommand(String cmd) {
+ if (cmd == null) {
+ return handleDefaultCommands(cmd);
+ }
+ final PrintWriter err = getErrPrintWriter();
+ try {
+ switch (cmd) {
+ case "dump":
+ return dumpResources();
+ default:
+ return handleDefaultCommands(cmd);
+ }
+ } catch (IllegalArgumentException e) {
+ err.println("Error: " + e.getMessage());
+ } catch (RemoteException e) {
+ err.println("Remote exception: " + e);
+ }
+ return -1;
+ }
+
+ private int dumpResources() throws RemoteException {
+ String processId = getNextArgRequired();
+ try {
+ ConditionVariable lock = new ConditionVariable();
+ RemoteCallback
+ finishCallback = new RemoteCallback(result -> lock.open(), null);
+
+ if (!mInterface.dumpResources(processId,
+ ParcelFileDescriptor.dup(getOutFileDescriptor()), finishCallback)) {
+ getErrPrintWriter().println("RESOURCES DUMP FAILED on process " + processId);
+ return -1;
+ }
+ lock.block(5000);
+ return 0;
+ } catch (IOException e) {
+ Slog.e(TAG, "Exception while dumping resources", e);
+ getErrPrintWriter().println("Exception while dumping resources: " + e.getMessage());
+ }
+ return -1;
+ }
+
+ @Override
+ public void onHelp() {
+ final PrintWriter out = getOutPrintWriter();
+ out.println("Resources manager commands:");
+ out.println(" help");
+ out.println(" Print this help text.");
+ out.println(" dump <PROCESS>");
+ out.println(" Dump the Resources objects in use as well as the history of Resources");
+
+ }
+}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index f8d7b78..3fe6166 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -716,6 +716,11 @@
@Nullable
private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio;
+ // Whether the activity is eligible to be letterboxed for fixed orientation with respect to its
+ // requested orientation, even when it's letterbox for another reason (e.g., size compat mode)
+ // and therefore #isLetterboxedForFixedOrientationAndAspectRatio returns false.
+ private boolean mIsEligibleForFixedOrientationLetterbox;
+
// State of the Camera app compat control which is used to correct stretched viewfinder
// in apps that don't handle all possible configurations and changes between them correctly.
@CameraCompatControlState
@@ -7627,6 +7632,24 @@
}
/**
+ * Whether this activity is eligible for letterbox eduction.
+ *
+ * <p>Conditions that need to be met:
+ *
+ * <ul>
+ * <li>{@link LetterboxConfiguration#getIsEducationEnabled} is true.
+ * <li>The activity is eligible for fixed orientation letterbox.
+ * <li>The activity is in fullscreen.
+ * </ul>
+ */
+ // TODO(b/215316431): Add tests
+ boolean isEligibleForLetterboxEducation() {
+ return mWmService.mLetterboxConfiguration.getIsEducationEnabled()
+ && mIsEligibleForFixedOrientationLetterbox
+ && getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
+ }
+
+ /**
* In some cases, applying insets to bounds changes the orientation. For example, if a
* close-to-square display rotates to portrait to respect a portrait orientation activity, after
* insets such as the status and nav bars are applied, the activity may actually have a
@@ -7688,6 +7711,7 @@
private void resolveFixedOrientationConfiguration(@NonNull Configuration newParentConfig,
int windowingMode) {
mLetterboxBoundsForFixedOrientationAndAspectRatio = null;
+ mIsEligibleForFixedOrientationLetterbox = false;
final Rect parentBounds = newParentConfig.windowConfiguration.getBounds();
final Rect stableBounds = new Rect();
// If orientation is respected when insets are applied, then stableBounds will be empty.
@@ -7727,8 +7751,11 @@
// make it fit the available bounds by scaling down its bounds.
final int forcedOrientation = getRequestedConfigurationOrientation();
- if (forcedOrientation == ORIENTATION_UNDEFINED
- || (forcedOrientation == parentOrientation && orientationRespectedWithInsets)) {
+ mIsEligibleForFixedOrientationLetterbox = forcedOrientation != ORIENTATION_UNDEFINED
+ && forcedOrientation != parentOrientation;
+
+ if (!mIsEligibleForFixedOrientationLetterbox && (forcedOrientation == ORIENTATION_UNDEFINED
+ || orientationRespectedWithInsets)) {
return;
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 4009220..c87027d 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5486,26 +5486,46 @@
}
void updateKeepClearAreas() {
+ final List<Rect> restrictedKeepClearAreas = new ArrayList();
+ final List<Rect> unrestrictedKeepClearAreas = new ArrayList();
+ getKeepClearAreas(restrictedKeepClearAreas, unrestrictedKeepClearAreas);
mWmService.mDisplayNotificationController.dispatchKeepClearAreasChanged(
- this, getKeepClearAreas());
+ this, restrictedKeepClearAreas, unrestrictedKeepClearAreas);
}
/**
- * Returns all keep-clear areas from visible windows on this display.
+ * Fills {@param outRestricted} with all keep-clear areas from visible, relevant windows
+ * on this display, which set restricted keep-clear areas.
+ * Fills {@param outUnrestricted} with keep-clear areas from visible, relevant windows on this
+ * display, which set unrestricted keep-clear areas.
+ *
+ * For context on restricted vs unrestricted keep-clear areas, see
+ * {@link android.Manifest.permission.USE_UNRESTRICTED_KEEP_CLEAR_AREAS}.
*/
- ArrayList<Rect> getKeepClearAreas() {
- final ArrayList<Rect> keepClearAreas = new ArrayList<Rect>();
+ void getKeepClearAreas(List<Rect> outRestricted, List<Rect> outUnrestricted) {
final Matrix tmpMatrix = new Matrix();
final float[] tmpFloat9 = new float[9];
forAllWindows(w -> {
if (w.isVisible() && !w.inPinnedWindowingMode()) {
- keepClearAreas.addAll(w.getKeepClearAreas(tmpMatrix, tmpFloat9));
+ if (w.mSession.mSetsUnrestrictedKeepClearAreas) {
+ outUnrestricted.addAll(w.getKeepClearAreas(tmpMatrix, tmpFloat9));
+ } else {
+ outRestricted.addAll(w.getKeepClearAreas(tmpMatrix, tmpFloat9));
+ }
}
// We stop traversing when we reach the base of a fullscreen app.
return w.getWindowType() == TYPE_BASE_APPLICATION
&& w.getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
}, true);
+ }
+
+ /**
+ * Returns all keep-clear areas from visible, relevant windows on this display.
+ */
+ ArrayList<Rect> getKeepClearAreas() {
+ final ArrayList<Rect> keepClearAreas = new ArrayList<Rect>();
+ getKeepClearAreas(keepClearAreas, keepClearAreas);
return keepClearAreas;
}
diff --git a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
index 276dbe9..e18d539 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
@@ -120,12 +120,13 @@
mDisplayListeners.finishBroadcast();
}
- void dispatchKeepClearAreasChanged(DisplayContent display, List<Rect> keepClearAreas) {
+ void dispatchKeepClearAreasChanged(DisplayContent display, List<Rect> restricted,
+ List<Rect> unrestricted) {
int count = mDisplayListeners.beginBroadcast();
for (int i = 0; i < count; ++i) {
try {
mDisplayListeners.getBroadcastItem(i).onKeepClearAreasChanged(
- display.mDisplayId, keepClearAreas);
+ display.mDisplayId, restricted, unrestricted);
} catch (RemoteException e) {
}
}
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index 1955e30..ad2767c 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -126,6 +126,9 @@
@LetterboxReachabilityPosition
private volatile int mLetterboxPositionForReachability;
+ // Whether education is allowed for letterboxed fullscreen apps.
+ private boolean mIsEducationEnabled;
+
LetterboxConfiguration(Context systemUiContext) {
mContext = systemUiContext;
mFixedOrientationLetterboxAspectRatio = mContext.getResources().getFloat(
@@ -143,6 +146,8 @@
R.bool.config_letterboxIsReachabilityEnabled);
mDefaultPositionForReachability = readLetterboxReachabilityPositionFromConfig(mContext);
mLetterboxPositionForReachability = mDefaultPositionForReachability;
+ mIsEducationEnabled = mContext.getResources().getBoolean(
+ R.bool.config_letterboxIsEducationEnabled);
}
/**
@@ -501,4 +506,27 @@
mLetterboxPositionForReachability = Math.max(mLetterboxPositionForReachability - 1, 0);
}
+ /**
+ * Whether education is allowed for letterboxed fullscreen apps.
+ */
+ boolean getIsEducationEnabled() {
+ return mIsEducationEnabled;
+ }
+
+ /**
+ * Overrides whether education is allowed for letterboxed fullscreen apps.
+ */
+ void setIsEducationEnabled(boolean enabled) {
+ mIsEducationEnabled = enabled;
+ }
+
+ /**
+ * Resets whether education is allowed for letterboxed fullscreen apps to
+ * {@link R.bool.config_letterboxIsEducationEnabled}.
+ */
+ void resetIsEducationEnabled() {
+ mIsEducationEnabled = mContext.getResources().getBoolean(
+ R.bool.config_letterboxIsEducationEnabled);
+ }
+
}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 98acc46..2ae2b43 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -19,6 +19,7 @@
import static android.Manifest.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
import static android.Manifest.permission.HIDE_OVERLAY_WINDOWS;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
+import static android.Manifest.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.Manifest.permission.SYSTEM_APPLICATION_OVERLAY;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
@@ -114,6 +115,7 @@
private String mRelayoutTag;
private final InsetsVisibilities mDummyRequestedVisibilities = new InsetsVisibilities();
private final InsetsSourceControl[] mDummyControls = new InsetsSourceControl[0];
+ final boolean mSetsUnrestrictedKeepClearAreas;
public Session(WindowManagerService service, IWindowSessionCallback callback) {
mService = service;
@@ -132,6 +134,9 @@
== PERMISSION_GRANTED;
mCanStartTasksFromRecents = service.mContext.checkCallingOrSelfPermission(
START_TASKS_FROM_RECENTS) == PERMISSION_GRANTED;
+ mSetsUnrestrictedKeepClearAreas =
+ service.mContext.checkCallingOrSelfPermission(SET_UNRESTRICTED_KEEP_CLEAR_AREAS)
+ == PERMISSION_GRANTED;
mShowingAlertWindowNotificationAllowed = mService.mShowAlertWindowNotifications;
mDragDropController = mService.mDragDropController;
StringBuilder sb = new StringBuilder();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 7d06526..97735a2 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -3434,6 +3434,9 @@
// Whether the direct top activity is in size compat mode on foreground.
info.topActivityInSizeCompat = isTopActivityResumed
&& mReuseActivitiesReport.top.inSizeCompatMode();
+ // Whether the direct top activity is eligible for letterbox education.
+ info.topActivityEligibleForLetterboxEducation = isTopActivityResumed
+ && mReuseActivitiesReport.top.isEligibleForLetterboxEducation();
// Whether the direct top activity requested showing camera compat control.
info.cameraCompatControlState = isTopActivityResumed
? mReuseActivitiesReport.top.getCameraCompatControlState()
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 0f8587c..1cf4c1b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -822,6 +822,29 @@
return 0;
}
+ private int runSetLetterboxIsEducationEnabled(PrintWriter pw) throws RemoteException {
+ String arg = getNextArg();
+ final boolean enabled;
+ switch (arg) {
+ case "true":
+ case "1":
+ enabled = true;
+ break;
+ case "false":
+ case "0":
+ enabled = false;
+ break;
+ default:
+ getErrPrintWriter().println("Error: expected true, 1, false, 0, but got " + arg);
+ return -1;
+ }
+
+ synchronized (mInternal.mGlobalLock) {
+ mLetterboxConfiguration.setIsEducationEnabled(enabled);
+ }
+ return 0;
+ }
+
private int runSetLetterboxStyle(PrintWriter pw) throws RemoteException {
if (peekNextArg() == null) {
getErrPrintWriter().println("Error: No arguments provided.");
@@ -859,6 +882,9 @@
case "--defaultPositionForReachability":
runSetLetterboxDefaultPositionForReachability(pw);
break;
+ case "--isEducationEnabled":
+ runSetLetterboxIsEducationEnabled(pw);
+ break;
default:
getErrPrintWriter().println(
"Error: Unrecognized letterbox style option: " + arg);
@@ -903,6 +929,9 @@
case "defaultPositionForReachability":
mLetterboxConfiguration.getDefaultPositionForReachability();
break;
+ case "isEducationEnabled":
+ mLetterboxConfiguration.getIsEducationEnabled();
+ break;
default:
getErrPrintWriter().println(
"Error: Unrecognized letterbox style option: " + arg);
@@ -998,6 +1027,7 @@
mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
mLetterboxConfiguration.resetIsReachabilityEnabled();
mLetterboxConfiguration.resetDefaultPositionForReachability();
+ mLetterboxConfiguration.resetIsEducationEnabled();
}
}
@@ -1014,6 +1044,8 @@
pw.println("Default position for reachability: "
+ LetterboxConfiguration.letterboxReachabilityPositionToString(
mLetterboxConfiguration.getDefaultPositionForReachability()));
+ pw.println("Is education enabled: "
+ + mLetterboxConfiguration.getIsEducationEnabled());
pw.println("Background type: "
+ LetterboxConfiguration.letterboxBackgroundTypeToString(
@@ -1154,10 +1186,12 @@
pw.println(" --defaultPositionForReachability [left|center|right]");
pw.println(" Default horizontal position of app window when reachability is.");
pw.println(" enabled.");
+ pw.println(" --isEducationEnabled [true|1|false|0]");
+ pw.println(" Whether education is allowed for letterboxed fullscreen apps.");
pw.println(" reset-letterbox-style [aspectRatio|cornerRadius|backgroundType");
pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha");
pw.println(" |horizontalPositionMultiplier|isReachabilityEnabled");
- pw.println(" |defaultPositionMultiplierForReachability]");
+ pw.println(" isEducationEnabled||defaultPositionMultiplierForReachability]");
pw.println(" Resets overrides to default values for specified properties separated");
pw.println(" by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'.");
pw.println(" If no arguments provided, all values will be reset.");
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 74e04ed..6577fbd 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -176,6 +176,7 @@
import com.android.server.powerstats.PowerStatsService;
import com.android.server.profcollect.ProfcollectForwardingService;
import com.android.server.recoverysystem.RecoverySystemService;
+import com.android.server.resources.ResourcesManagerService;
import com.android.server.restrictions.RestrictionsManagerService;
import com.android.server.role.RoleServicePlatformHelper;
import com.android.server.rotationresolver.RotationResolverManagerService;
@@ -213,8 +214,6 @@
import dalvik.system.VMRuntime;
-import com.google.android.startop.iorap.IorapForwardingService;
-
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -265,8 +264,6 @@
"/apex/com.android.os.statsd/javalib/service-statsd.jar";
private static final String CONNECTIVITY_SERVICE_APEX_PATH =
"/apex/com.android.tethering/javalib/service-connectivity.jar";
- private static final String NEARBY_SERVICE_APEX_PATH =
- "/apex/com.android.nearby/javalib/service-nearby.jar";
private static final String STATS_COMPANION_LIFECYCLE_CLASS =
"com.android.server.stats.StatsCompanion$Lifecycle";
private static final String STATS_PULL_ATOM_SERVICE_CLASS =
@@ -277,8 +274,6 @@
"com.android.server.usb.UsbService$Lifecycle";
private static final String MIDI_SERVICE_CLASS =
"com.android.server.midi.MidiService$Lifecycle";
- private static final String NEARBY_SERVICE_CLASS =
- "com.android.server.nearby.NearbyService";
private static final String WIFI_APEX_SERVICE_JAR_PATH =
"/apex/com.android.wifi/javalib/service-wifi.jar";
private static final String WIFI_SERVICE_CLASS =
@@ -1289,6 +1284,13 @@
mSystemServiceManager.startService(new OverlayManagerService(mSystemContext));
t.traceEnd();
+ // Manages Resources packages
+ t.traceBegin("StartResourcesManagerService");
+ ResourcesManagerService resourcesService = new ResourcesManagerService(mSystemContext);
+ resourcesService.setActivityManagerService(mActivityManagerService);
+ mSystemServiceManager.startService(resourcesService);
+ t.traceEnd();
+
t.traceBegin("StartSensorPrivacyService");
mSystemServiceManager.startService(new SensorPrivacyService(mSystemContext));
t.traceEnd();
@@ -1621,10 +1623,6 @@
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);
@@ -2000,16 +1998,6 @@
}
t.traceEnd();
- // Start Nearby Service.
- t.traceBegin("StartNearbyService");
- try {
- mSystemServiceManager.startServiceFromJar(NEARBY_SERVICE_CLASS,
- NEARBY_SERVICE_APEX_PATH);
- } catch (Throwable e) {
- reportWtf("starting NearbyService", e);
- }
- t.traceEnd();
-
t.traceBegin("StartConnectivityService");
// This has to be called after NetworkManagementService, NetworkStatsService
// and NetworkPolicyManager because ConnectivityService needs to take these
diff --git a/services/startop/Android.bp b/services/startop/Android.bp
deleted file mode 100644
index c56c463..0000000
--- 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/app/GameServiceProviderInstanceImplTest.java b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
index d5e4710..b0ffcf3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
@@ -26,6 +26,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -33,6 +34,7 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
+import android.Manifest;
import android.annotation.Nullable;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityTaskManager;
@@ -83,6 +85,7 @@
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Objects;
/**
@@ -121,7 +124,7 @@
private WindowManagerInternal mMockWindowManagerInternal;
@Mock
private IActivityManager mMockActivityManager;
- private FakeContext mFakeContext;
+ private MockContext mMockContext;
private FakeGameClassifier mFakeGameClassifier;
private FakeGameService mFakeGameService;
private FakeServiceConnector<IGameService> mFakeGameServiceConnector;
@@ -140,7 +143,7 @@
.strictness(Strictness.LENIENT)
.startMocking();
- mFakeContext = new FakeContext(InstrumentationRegistry.getInstrumentation().getContext());
+ mMockContext = new MockContext(InstrumentationRegistry.getInstrumentation().getContext());
mFakeGameClassifier = new FakeGameClassifier();
mFakeGameClassifier.recordGamePackage(GAME_A_PACKAGE);
@@ -169,7 +172,7 @@
mGameServiceProviderInstance = new GameServiceProviderInstanceImpl(
new UserHandle(USER_ID),
ConcurrentUtils.DIRECT_EXECUTOR,
- mFakeContext,
+ mMockContext,
mFakeGameClassifier,
mMockActivityManager,
mMockActivityTaskManager,
@@ -683,6 +686,7 @@
@Test
public void restartGame_taskIdAssociatedWithGame_restartsTargetGame() throws Exception {
+ mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
Intent launchIntent = new Intent("com.test.ACTION_LAUNCH_GAME_PACKAGE")
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
when(mMockPackageManager.getLaunchIntentForPackage(GAME_A_PACKAGE))
@@ -710,11 +714,12 @@
.mGameSessionController.restartGame(10);
verify(mMockActivityManager).forceStopPackage(GAME_A_PACKAGE, UserHandle.USER_CURRENT);
- assertThat(mFakeContext.getLastStartedIntent()).isEqualTo(launchIntent);
+ assertThat(mMockContext.getLastStartedIntent()).isEqualTo(launchIntent);
}
@Test
public void restartGame_taskIdNotAssociatedWithGame_noOp() throws Exception {
+ mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
@@ -730,7 +735,19 @@
.mGameSessionController.restartGame(11);
verifyZeroInteractions(mMockActivityManager);
- assertThat(mFakeContext.getLastStartedIntent()).isNull();
+ assertThat(mMockContext.getLastStartedIntent()).isNull();
+ }
+
+ @Test
+ public void restartGame_failurePermissionDenied() throws Exception {
+ mGameServiceProviderInstance.start();
+ startTask(10, GAME_A_MAIN_ACTIVITY);
+ mFakeGameService.requestCreateGameSession(10);
+
+ IGameSessionController gameSessionController = Objects.requireNonNull(getOnlyElement(
+ mFakeGameSessionService.getCapturedCreateInvocations())).mGameSessionController;
+ assertThrows(SecurityException.class,
+ () -> gameSessionController.restartGame(10));
}
private void startTask(int taskId, ComponentName componentName) {
@@ -774,6 +791,14 @@
}
}
+ private void mockPermissionGranted(String permission) {
+ mMockContext.setPermission(permission, PackageManager.PERMISSION_GRANTED);
+ }
+
+ private void mockPermissionDenied(String permission) {
+ mMockContext.setPermission(permission, PackageManager.PERMISSION_DENIED);
+ }
+
static final class FakeGameService extends IGameService.Stub {
private IGameServiceController mGameServiceController;
@@ -900,13 +925,28 @@
}
}
- private final class FakeContext extends ContextWrapper {
+ private final class MockContext extends ContextWrapper {
private Intent mLastStartedIntent;
+ // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant
+ private final HashMap<String, Integer> mMockedPermissions = new HashMap<>();
- FakeContext(Context base) {
+ MockContext(Context base) {
super(base);
}
+ /**
+ * Mock checks for the specified permission, and have them behave as per {@code granted}.
+ *
+ * <p>Passing null reverts to default behavior, which does a real permission check on the
+ * test package.
+ *
+ * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or
+ * {@link PackageManager#PERMISSION_DENIED}.
+ */
+ public void setPermission(String permission, Integer granted) {
+ mMockedPermissions.put(permission, granted);
+ }
+
@Override
public PackageManager getPackageManager() {
return mMockPackageManager;
@@ -919,7 +959,15 @@
@Override
public void enforceCallingPermission(String permission, @Nullable String message) {
- // Do nothing.
+ final Integer granted = mMockedPermissions.get(permission);
+ if (granted == null) {
+ super.enforceCallingOrSelfPermission(permission, message);
+ return;
+ }
+
+ if (!granted.equals(PackageManager.PERMISSION_GRANTED)) {
+ throw new SecurityException("[Test] permission denied: " + permission);
+ }
}
Intent getLastStartedIntent() {
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
index d2cff0e..fe3034d 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
@@ -326,7 +326,7 @@
assertEquals(callback.getLastNotifiedInfo().currentState,
OTHER_DEVICE_STATE.getIdentifier());
- mService.getBinderService().cancelRequest(token);
+ mService.getBinderService().cancelStateRequest();
flushHandler();
assertEquals(callback.getLastNotifiedStatus(token),
@@ -378,9 +378,9 @@
mPolicy.resumeConfigureOnce();
flushHandler();
- // First request status is now suspended as there is another pending request.
+ // First request status is now canceled as there is another pending request.
assertEquals(callback.getLastNotifiedStatus(firstRequestToken),
- TestDeviceStateManagerCallback.STATUS_SUSPENDED);
+ TestDeviceStateManagerCallback.STATUS_CANCELED);
// Second request status still unknown because the service is still awaiting policy
// callback.
assertEquals(callback.getLastNotifiedStatus(secondRequestToken),
@@ -402,19 +402,19 @@
DEFAULT_DEVICE_STATE.getIdentifier());
// Now cancel the second request to make the first request active.
- mService.getBinderService().cancelRequest(secondRequestToken);
+ mService.getBinderService().cancelStateRequest();
flushHandler();
assertEquals(callback.getLastNotifiedStatus(firstRequestToken),
- TestDeviceStateManagerCallback.STATUS_ACTIVE);
+ TestDeviceStateManagerCallback.STATUS_CANCELED);
assertEquals(callback.getLastNotifiedStatus(secondRequestToken),
TestDeviceStateManagerCallback.STATUS_CANCELED);
- assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE));
+ assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE));
assertEquals(mService.getPendingState(), Optional.empty());
assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE));
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
- OTHER_DEVICE_STATE.getIdentifier());
+ DEFAULT_DEVICE_STATE.getIdentifier());
}
@Test
@@ -656,11 +656,6 @@
}
@Override
- public void onRequestSuspended(IBinder token) {
- mLastNotifiedStatus.put(token, STATUS_SUSPENDED);
- }
-
- @Override
public void onRequestCanceled(IBinder token) {
mLastNotifiedStatus.put(token, STATUS_CANCELED);
}
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/OverrideRequestControllerTest.java b/services/tests/servicestests/src/com/android/server/devicestate/OverrideRequestControllerTest.java
index b94fc43..2297c91 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/OverrideRequestControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/OverrideRequestControllerTest.java
@@ -18,7 +18,6 @@
import static com.android.server.devicestate.OverrideRequestController.STATUS_ACTIVE;
import static com.android.server.devicestate.OverrideRequestController.STATUS_CANCELED;
-import static com.android.server.devicestate.OverrideRequestController.STATUS_SUSPENDED;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
@@ -66,7 +65,7 @@
}
@Test
- public void addRequest_suspendExistingRequest() {
+ public void addRequest_cancelExistingRequestThroughNewRequest() {
OverrideRequest firstRequest = new OverrideRequest(new Binder(), 0 /* pid */,
0 /* requestedState */, 0 /* flags */);
assertNull(mStatusListener.getLastStatus(firstRequest));
@@ -75,92 +74,52 @@
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_ACTIVE);
OverrideRequest secondRequest = new OverrideRequest(new Binder(), 0 /* pid */,
- 0 /* requestedState */, 0 /* flags */);
+ 1 /* requestedState */, 0 /* flags */);
assertNull(mStatusListener.getLastStatus(secondRequest));
mController.addRequest(secondRequest);
assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_ACTIVE);
- assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_SUSPENDED);
+ assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_CANCELED);
}
@Test
public void addRequest_cancelActiveRequest() {
OverrideRequest firstRequest = new OverrideRequest(new Binder(), 0 /* pid */,
0 /* requestedState */, 0 /* flags */);
- OverrideRequest secondRequest = new OverrideRequest(new Binder(), 0 /* pid */,
- 0 /* requestedState */, 0 /* flags */);
mController.addRequest(firstRequest);
- mController.addRequest(secondRequest);
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_ACTIVE);
- assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_SUSPENDED);
-
- mController.cancelRequest(secondRequest.getToken());
-
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_CANCELED);
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_ACTIVE);
- }
- @Test
- public void addRequest_cancelSuspendedRequest() {
- OverrideRequest firstRequest = new OverrideRequest(new Binder(), 0 /* pid */,
- 0 /* requestedState */, 0 /* flags */);
- OverrideRequest secondRequest = new OverrideRequest(new Binder(), 0 /* pid */,
- 0 /* requestedState */, 0 /* flags */);
+ mController.cancelOverrideRequest();
- mController.addRequest(firstRequest);
- mController.addRequest(secondRequest);
-
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_ACTIVE);
- assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_SUSPENDED);
-
- mController.cancelRequest(firstRequest.getToken());
-
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_ACTIVE);
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_CANCELED);
}
@Test
public void handleBaseStateChanged() {
OverrideRequest firstRequest = new OverrideRequest(new Binder(), 0 /* pid */,
- 0 /* requestedState */, 0 /* flags */);
- OverrideRequest secondRequest = new OverrideRequest(new Binder(), 0 /* pid */,
0 /* requestedState */,
DeviceStateRequest.FLAG_CANCEL_WHEN_BASE_CHANGES /* flags */);
mController.addRequest(firstRequest);
- mController.addRequest(secondRequest);
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_ACTIVE);
- assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_SUSPENDED);
+ assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_ACTIVE);
mController.handleBaseStateChanged();
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_CANCELED);
- assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_ACTIVE);
+ assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_CANCELED);
}
@Test
public void handleProcessDied() {
OverrideRequest firstRequest = new OverrideRequest(new Binder(), 0 /* pid */,
0 /* requestedState */, 0 /* flags */);
- OverrideRequest secondRequest = new OverrideRequest(new Binder(), 1 /* pid */,
- 0 /* requestedState */, 0 /* flags */);
mController.addRequest(firstRequest);
- mController.addRequest(secondRequest);
-
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_ACTIVE);
- assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_SUSPENDED);
-
- mController.handleProcessDied(1);
-
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_CANCELED);
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_ACTIVE);
mController.handleProcessDied(0);
-
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_CANCELED);
}
@@ -170,46 +129,29 @@
OverrideRequest firstRequest = new OverrideRequest(new Binder(), 0 /* pid */,
0 /* requestedState */, 0 /* flags */);
- OverrideRequest secondRequest = new OverrideRequest(new Binder(), 1 /* pid */,
- 0 /* requestedState */, 0 /* flags */);
mController.addRequest(firstRequest);
- mController.addRequest(secondRequest);
-
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_ACTIVE);
- assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_SUSPENDED);
-
- mController.handleProcessDied(1);
-
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_ACTIVE);
- assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_SUSPENDED);
-
- mController.cancelStickyRequests();
-
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_CANCELED);
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_ACTIVE);
+
+ mController.handleProcessDied(0);
+ assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_ACTIVE);
+
+ mController.cancelStickyRequest();
+ assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_CANCELED);
}
@Test
public void handleNewSupportedStates() {
OverrideRequest firstRequest = new OverrideRequest(new Binder(), 0 /* pid */,
1 /* requestedState */, 0 /* flags */);
- OverrideRequest secondRequest = new OverrideRequest(new Binder(), 0 /* pid */,
- 2 /* requestedState */, 0 /* flags */);
mController.addRequest(firstRequest);
- mController.addRequest(secondRequest);
-
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_ACTIVE);
- assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_SUSPENDED);
+ assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_ACTIVE);
mController.handleNewSupportedStates(new int[]{ 0, 1 });
-
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_CANCELED);
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_ACTIVE);
mController.handleNewSupportedStates(new int[]{ 0 });
-
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_CANCELED);
}
@@ -217,18 +159,11 @@
public void cancelOverrideRequestsTest() {
OverrideRequest firstRequest = new OverrideRequest(new Binder(), 0 /* pid */,
1 /* requestedState */, 0 /* flags */);
- OverrideRequest secondRequest = new OverrideRequest(new Binder(), 0 /* pid */,
- 2 /* requestedState */, 0 /* flags */);
mController.addRequest(firstRequest);
- mController.addRequest(secondRequest);
+ assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_ACTIVE);
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_ACTIVE);
- assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_SUSPENDED);
-
- mController.cancelOverrideRequests();
-
- assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_CANCELED);
+ mController.cancelOverrideRequest();
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_CANCELED);
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
index 4a24bbd..8e53ca1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
@@ -17,7 +17,7 @@
package com.android.server.pm;
import static android.content.pm.SharedLibraryInfo.TYPE_DYNAMIC;
-import static android.content.pm.SharedLibraryInfo.TYPE_SDK;
+import static android.content.pm.SharedLibraryInfo.TYPE_SDK_PACKAGE;
import static android.content.pm.SharedLibraryInfo.TYPE_STATIC;
import static android.content.pm.SharedLibraryInfo.VERSION_UNDEFINED;
@@ -258,7 +258,7 @@
assertThat(scanResult.mSdkSharedLibraryInfo.getPackageName(), is("ogl.sdk_123"));
assertThat(scanResult.mSdkSharedLibraryInfo.getName(), is("ogl.sdk"));
assertThat(scanResult.mSdkSharedLibraryInfo.getLongVersion(), is(123L));
- assertThat(scanResult.mSdkSharedLibraryInfo.getType(), is(TYPE_SDK));
+ assertThat(scanResult.mSdkSharedLibraryInfo.getType(), is(TYPE_SDK_PACKAGE));
assertThat(scanResult.mSdkSharedLibraryInfo.getDeclaringPackage().getPackageName(),
is("ogl.sdk_123"));
assertThat(scanResult.mSdkSharedLibraryInfo.getDeclaringPackage().getLongVersionCode(),
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
index fb15088..0f18cc6 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
@@ -17,7 +17,6 @@
package com.android.server.notification;
import static android.app.Notification.CATEGORY_CALL;
-import static android.app.Notification.CATEGORY_MESSAGE;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
@@ -25,6 +24,7 @@
import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CALLS;
import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS;
import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_MESSAGES;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_REPEAT_CALLERS;
import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
@@ -43,8 +43,10 @@
import android.app.NotificationChannel;
import android.app.NotificationManager.Policy;
import android.media.AudioAttributes;
+import android.os.Bundle;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
+import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -68,10 +70,15 @@
private NotificationMessagingUtil mMessagingUtil;
private ZenModeFiltering mZenModeFiltering;
+ @Mock private TelephonyManager mTelephonyManager;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mZenModeFiltering = new ZenModeFiltering(mContext, mMessagingUtil);
+
+ // for repeat callers / matchesCallFilter
+ mContext.addMockSystemService(TelephonyManager.class, mTelephonyManager);
}
private NotificationRecord getNotificationRecord() {
@@ -95,6 +102,23 @@
return r;
}
+ private Bundle makeExtrasBundleWithPeople(String[] people) {
+ Bundle extras = new Bundle();
+ extras.putObject(Notification.EXTRA_PEOPLE_LIST, people);
+ return extras;
+ }
+
+ private NotificationRecord getNotificationRecordWithPeople(String[] people) {
+ // set up notification record
+ NotificationRecord r = mock(NotificationRecord.class);
+ StatusBarNotification sbn = mock(StatusBarNotification.class);
+ Notification notification = mock(Notification.class);
+ notification.extras = makeExtrasBundleWithPeople(people);
+ when(sbn.getNotification()).thenReturn(notification);
+ when(r.getSbn()).thenReturn(sbn);
+ return r;
+ }
+
@Test
public void testIsMessage() {
NotificationRecord r = getNotificationRecord();
@@ -309,4 +333,111 @@
assertFalse(mZenModeFiltering.shouldIntercept(ZEN_MODE_IMPORTANT_INTERRUPTIONS, policy, r));
}
+
+ @Test
+ public void testMatchesCallFilter_repeatCallers_directMatch() {
+ // after calls given an email with an exact string match, make sure that
+ // matchesCallFilter returns the right thing
+ String[] mailSource = new String[]{"mailto:hello.world"};
+ mZenModeFiltering.recordCall(getNotificationRecordWithPeople(mailSource));
+
+ // set up policy to only allow repeat callers
+ Policy policy = new Policy(
+ PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0, CONVERSATION_SENDERS_NONE);
+
+ // check whether matchesCallFilter returns the right thing
+ Bundle inputMatches = makeExtrasBundleWithPeople(new String[]{"mailto:hello.world"});
+ Bundle inputWrong = makeExtrasBundleWithPeople(new String[]{"mailto:nope"});
+ assertTrue(ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ inputMatches, null, 0, 0));
+ assertFalse(ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ inputWrong, null, 0, 0));
+ }
+
+ @Test
+ public void testMatchesCallFilter_repeatCallers_telephoneVariants() {
+ // set up telephony manager behavior
+ when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
+
+ String[] telSource = new String[]{"tel:+1-617-555-1212"};
+ mZenModeFiltering.recordCall(getNotificationRecordWithPeople(telSource));
+
+ // set up policy to only allow repeat callers
+ Policy policy = new Policy(
+ PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0, CONVERSATION_SENDERS_NONE);
+
+ // cases to test:
+ // - identical number
+ // - same number, different formatting
+ // - different number
+ // - garbage
+ Bundle identical = makeExtrasBundleWithPeople(new String[]{"tel:+1-617-555-1212"});
+ Bundle same = makeExtrasBundleWithPeople(new String[]{"tel:16175551212"});
+ Bundle different = makeExtrasBundleWithPeople(new String[]{"tel:123-456-7890"});
+ Bundle garbage = makeExtrasBundleWithPeople(new String[]{"asdfghjkl;"});
+
+ assertTrue("identical numbers should match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ identical, null, 0, 0));
+ assertTrue("equivalent but non-identical numbers should match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ same, null, 0, 0));
+ assertFalse("non-equivalent numbers should not match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ different, null, 0, 0));
+ assertFalse("non-tel strings should not match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ garbage, null, 0, 0));
+ }
+
+ @Test
+ public void testMatchesCallFilter_repeatCallers_urlEncodedTels() {
+ // this is not intended to be a supported case but is one that we have seen
+ // sometimes in the wild, so make sure we handle url-encoded telephone numbers correctly
+ // when somebody provides one.
+
+ // set up telephony manager behavior
+ when(mTelephonyManager.getNetworkCountryIso()).thenReturn("us");
+
+ String[] telSource = new String[]{"tel:%2B16175551212"};
+ mZenModeFiltering.recordCall(getNotificationRecordWithPeople(telSource));
+
+ // set up policy to only allow repeat callers
+ Policy policy = new Policy(
+ PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0, 0, CONVERSATION_SENDERS_NONE);
+
+ // test cases for various forms of the same phone number and different ones
+ Bundle same1 = makeExtrasBundleWithPeople(new String[]{"tel:+1-617-555-1212"});
+ Bundle same2 = makeExtrasBundleWithPeople(new String[]{"tel:%2B1-617-555-1212"});
+ Bundle same3 = makeExtrasBundleWithPeople(new String[]{"tel:6175551212"});
+ Bundle different1 = makeExtrasBundleWithPeople(new String[]{"tel:%2B16175553434"});
+ Bundle different2 = makeExtrasBundleWithPeople(new String[]{"tel:+16175553434"});
+
+ assertTrue("same number should match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ same1, null, 0, 0));
+ assertTrue("same number should match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ same2, null, 0, 0));
+ assertTrue("same number should match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ same3, null, 0, 0));
+ assertFalse("different number should not match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ different1, null, 0, 0));
+ assertFalse("different number should not match",
+ ZenModeFiltering.matchesCallFilter(mContext, ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+ policy, UserHandle.SYSTEM,
+ different2, null, 0, 0));
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 7c340ec..8ada971 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -191,7 +191,8 @@
public void onFixedRotationFinished(int displayId) {}
@Override
- public void onKeepClearAreasChanged(int displayId, List<Rect> keepClearAreas) {}
+ public void onKeepClearAreasChanged(int displayId, List<Rect> restricted,
+ List<Rect> unrestricted) {}
};
int[] displayIds = mAtm.mWindowManager.registerDisplayWindowListener(listener);
for (int i = 0; i < displayIds.length; i++) {
diff --git a/startop/iorap/Android.bp b/startop/iorap/Android.bp
deleted file mode 100644
index 4fdf34c..0000000
--- 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 8c9d4df..0000000
--- 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 43c6155..0000000
--- 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 6bddc4a3..0000000
--- 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 31d4f6c..0000000
--- 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 5352be6..0000000
--- 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 1d38f4c..0000000
--- 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 f47a42c..0000000
--- 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 1cd37b5..0000000
--- 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 8263e0a..0000000
--- 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 34aedd7..0000000
--- 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 72c5eaa..0000000
--- 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 dcaff26..0000000
--- 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 77046f2..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
+++ /dev/null
@@ -1,806 +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.JobScheduler;
-import android.app.job.JobService;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.IBinder.DeathRecipient;
-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.ActivityMetricsLaunchObserverRegistry;
-import com.android.server.wm.ActivityTaskManagerInternal;
-
-import java.time.Duration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.BooleanSupplier;
-
-/**
- * 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.getService().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.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 b91dd71..0000000
--- 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 aa4eea7..0000000
--- 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 503e1c6..0000000
--- 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 75d47f9..0000000
--- 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 2e7bafe..0000000
--- 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 b5fd6d8..0000000
--- 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 6e8725d..0000000
--- 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 1f26861..0000000
--- 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 ad3d001..0000000
--- 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 b967e72..0000000
--- 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 6102c44..0000000
--- 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 51e407d..0000000
--- 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 18c2491..0000000
--- 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 150577a..0000000
--- 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 d74d6f6..0000000
--- 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 25ee6f7..0000000
--- 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 0c2bbea..0000000
--- 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 08f983d..0000000
--- 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 6704a5a..0000000
--- 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 3cebc9a..0000000
--- 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 e590fed..0000000
--- 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 78873fa..0000000
--- 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 33d233b..0000000
--- 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 080f3b5..0000000
--- 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 4b7e0fa..0000000
--- 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 bedaa1e..0000000
--- 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 20a2308..0000000
--- 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 1cbc1cb..0000000
--- 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 9ffb349..0000000
--- 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 8d94fc5..0000000
--- 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 3fa1462..0000000
--- 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 ea14264..0000000
--- 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 a751a43..0000000
--- 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 31f6253..0000000
--- 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 2f1eff2..0000000
--- 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 8a588e4..0000000
--- 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 478294c..0000000
--- 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 343cd54..0000000
--- 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 3dc080a..0000000
--- 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 387e45d..0000000
--- 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 6dbbeaf..0000000
--- 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 1426d34..0000000
--- 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 d941cd9..0000000
--- 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 90fc8a8..0000000
--- 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 b8de701..0000000
--- 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 ad26a7d..0000000
--- 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 bcec4a5..0000000
--- 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 f005bed..0000000
--- 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 5688711..0000000
--- 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 2e71393..0000000
--- 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 1224c61..0000000
--- 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 f6f21fd..0000000
--- 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 0554426..0000000
--- 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
deleted file mode 100644
index a47ad3d..0000000
--- a/startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pb
+++ /dev/null
Binary files differ
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 4573738..0000000
--- 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 da03004..0000000
--- 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 59ff753..0000000
--- 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
deleted file mode 100644
index ab3df45..0000000
--- a/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb
+++ /dev/null
Binary files differ
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
deleted file mode 100644
index 17cb116..0000000
--- a/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb
+++ /dev/null
Binary files differ
diff --git a/startop/scripts/lib/cmd_utils.py b/startop/scripts/lib/cmd_utils.py
deleted file mode 100644
index 6071f14..0000000
--- 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 8a3d00b..0000000
--- 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 ab82515..0000000
--- 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 8c5999d..0000000
--- 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 42a33af..0000000
--- 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 3b326f0..0000000
--- 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 41d1c08..0000000
--- 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 c28475e..0000000
--- 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 34e5f03..0000000
--- 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 788d0da..0000000
--- 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 0c166b0..0000000
--- 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 06871c6..0000000
--- 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 876e50e..0000000
--- 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 100f0740..0000000
--- 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/queries_pretty_print_block_launch.sql b/startop/scripts/trace_analyzer/queries_pretty_print_block_launch.sql
deleted file mode 100644
index bf5e3cc..0000000
--- a/startop/scripts/trace_analyzer/queries_pretty_print_block_launch.sql
+++ /dev/null
@@ -1,28 +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.
- */
-
-.headers on
-.mode quote
-
-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
-
-*/
diff --git a/startop/scripts/trace_analyzer/run-sql-queries b/startop/scripts/trace_analyzer/run-sql-queries
deleted file mode 100755
index 61a0ad4..0000000
--- 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 802cb55..0000000
--- 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 8c03964..0000000
--- 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 62ae018..0000000
--- 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 4d9ee0e..0000000
--- 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 579529c..0000000
--- 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/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index c5fc436..27d423b 100755
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
import android.annotation.TestApi;
@@ -3156,15 +3157,27 @@
}
/**
- * Create a {@code Connection} for a new unknown call. An unknown call is a call originating
- * from the ConnectionService that was neither a user-initiated outgoing call, nor an incoming
- * call created using
- * {@code TelecomManager#addNewIncomingCall(PhoneAccountHandle, android.os.Bundle)}.
+ * Calls of this type are created using
+ * {@link TelecomManager#addNewUnknownCall(PhoneAccountHandle, Bundle)}. Unknown calls
+ * are used for representing calls which become known to the {@link ConnectionService}
+ * midway through the call.
+ *
+ * For example, a call transferred from one device to answer would surface as an active
+ * call in Telecom instead of going through a typical Ringing to Active transition, or
+ * Dialing to Active transition.
+ *
+ * A {@link ConnectionService} can return {@code null} (the default behavior)
+ * if it is not able to handle a request for the requested unknown connection.
+ *
+ * {@link TelecomManager#addNewIncomingCall(PhoneAccountHandle, android.os.Bundle)}.
*
* @hide
*/
- public Connection onCreateUnknownConnection(PhoneAccountHandle connectionManagerPhoneAccount,
- ConnectionRequest request) {
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ public @Nullable Connection onCreateUnknownConnection(
+ @NonNull PhoneAccountHandle connectionManagerPhoneAccount,
+ @NonNull ConnectionRequest request) {
return null;
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index a74930b..e0e7913 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -8920,7 +8920,7 @@
sDefaults.putBoolean(KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL, true);
sDefaults.putBoolean(KEY_HIDE_ENABLE_2G, false);
sDefaults.putStringArray(KEY_ALLOWED_INITIAL_ATTACH_APN_TYPES_STRING_ARRAY,
- new String[]{"ia", "default", "mms", "dun"});
+ new String[]{"ia", "default"});
sDefaults.putBoolean(KEY_CARRIER_PROVISIONS_WIFI_MERGED_NETWORKS_BOOL, false);
sDefaults.putBoolean(KEY_USE_IP_FOR_CALLING_INDICATOR_BOOL, false);
sDefaults.putBoolean(KEY_DISPLAY_CALL_STRENGTH_INDICATOR_BOOL, true);
diff --git a/tools/lint/README.md b/tools/lint/README.md
index 2b6d65b..b534b62 100644
--- a/tools/lint/README.md
+++ b/tools/lint/README.md
@@ -40,6 +40,9 @@
- If you want to build lint reports for more than 1 module and they include a common module in their
`defaults` field, e.g. `platform_service_defaults`, you can add the `lint` property to that common
module instead of adding it in every module.
+- If you want to run a single lint type, use the `ANDROID_LINT_CHECK`
+ environment variable with the id of the lint. For example:
+ `ANDROID_LINT_CHECK=UnusedTokenOfOriginalCallingIdentity m out/[...]/lint-report.html`
## Create or update a baseline